Refactor empty/placeholder states with new component
This commit is contained in:
parent
feb5ba09be
commit
92cb70f1a4
|
@ -45,6 +45,10 @@ ul.no {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.relative {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
section {
|
section {
|
||||||
&.wrap {
|
&.wrap {
|
||||||
max-width: 1100px;
|
max-width: 1100px;
|
||||||
|
@ -250,10 +254,6 @@ section.dashboard {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tile {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.charts {
|
.charts {
|
||||||
min-height: 200px;
|
min-height: 200px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,19 +57,16 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Vue from 'vue';
|
|
||||||
import 'quill/dist/quill.snow.css';
|
import 'quill/dist/quill.snow.css';
|
||||||
import 'quill/dist/quill.core.css';
|
import 'quill/dist/quill.core.css';
|
||||||
import { quillEditor } from 'vue-quill-editor';
|
import { quillEditor } from 'vue-quill-editor';
|
||||||
// import Delta from 'quill-delta';
|
|
||||||
import CampaignPreview from './CampaignPreview.vue';
|
import CampaignPreview from './CampaignPreview.vue';
|
||||||
import Media from '../views/Media.vue';
|
import Media from '../views/Media.vue';
|
||||||
|
|
||||||
Vue.component('media', Media);
|
|
||||||
Vue.component('campaign-preview', CampaignPreview);
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
Media,
|
||||||
|
CampaignPreview,
|
||||||
quillEditor,
|
quillEditor,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,10 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'EmptyPlaceholder',
|
name: 'EmptyPlaceholder',
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
icon: String,
|
icon: String,
|
||||||
label: String,
|
label: String,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
</script>
|
||||||
|
|
|
@ -141,11 +141,11 @@ import dayjs from 'dayjs';
|
||||||
import ListSelector from '../components/ListSelector.vue';
|
import ListSelector from '../components/ListSelector.vue';
|
||||||
import Editor from '../components/Editor.vue';
|
import Editor from '../components/Editor.vue';
|
||||||
|
|
||||||
Vue.component('list-selector', ListSelector);
|
|
||||||
Vue.component('editor', Editor);
|
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
name: 'Campaign',
|
components: {
|
||||||
|
ListSelector,
|
||||||
|
Editor,
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -171,15 +171,8 @@
|
||||||
</a>
|
</a>
|
||||||
</b-table-column>
|
</b-table-column>
|
||||||
</template>
|
</template>
|
||||||
<template slot="empty" v-if="!loading.lists">
|
<template slot="empty" v-if="!loading.campaigns">
|
||||||
<section class="section">
|
<empty-placeholder />
|
||||||
<div class="content has-text-grey has-text-centered">
|
|
||||||
<p>
|
|
||||||
<b-icon icon="plus" size="is-large" />
|
|
||||||
</p>
|
|
||||||
<p>Nothing here.</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</template>
|
</template>
|
||||||
</b-table>
|
</b-table>
|
||||||
|
|
||||||
|
@ -197,12 +190,16 @@ import { mapState } from 'vuex';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||||
import CampaignPreview from '../components/CampaignPreview.vue';
|
import CampaignPreview from '../components/CampaignPreview.vue';
|
||||||
|
import EmptyPlaceholder from '../components/EmptyPlaceholder.vue';
|
||||||
Vue.component('campaign-preview', CampaignPreview);
|
|
||||||
|
|
||||||
dayjs.extend(relativeTime);
|
dayjs.extend(relativeTime);
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
|
components: {
|
||||||
|
CampaignPreview,
|
||||||
|
EmptyPlaceholder,
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
previewItem: null,
|
previewItem: null,
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<div class="tile is-ancestor">
|
<div class="tile is-ancestor">
|
||||||
<div class="tile is-vertical is-12">
|
<div class="tile is-vertical is-12">
|
||||||
<div class="tile">
|
<div class="tile">
|
||||||
<div class="tile is-parent is-vertical">
|
<div class="tile is-parent is-vertical relative">
|
||||||
<b-loading v-if="isCountsLoading" active :is-full-page="false" />
|
<b-loading v-if="isCountsLoading" active :is-full-page="false" />
|
||||||
<article class="tile is-child notification">
|
<article class="tile is-child notification">
|
||||||
<div class="columns is-mobile">
|
<div class="columns is-mobile">
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
</article><!-- campaigns -->
|
</article><!-- campaigns -->
|
||||||
</div><!-- block -->
|
</div><!-- block -->
|
||||||
|
|
||||||
<div class="tile is-parent">
|
<div class="tile is-parent relative">
|
||||||
<b-loading v-if="isCountsLoading" active :is-full-page="false" />
|
<b-loading v-if="isCountsLoading" active :is-full-page="false" />
|
||||||
<article class="tile is-child notification">
|
<article class="tile is-child notification">
|
||||||
<div class="columns is-mobile">
|
<div class="columns is-mobile">
|
||||||
|
@ -87,7 +87,7 @@
|
||||||
</article><!-- subscribers -->
|
</article><!-- subscribers -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tile is-parent">
|
<div class="tile is-parent relative">
|
||||||
<b-loading v-if="isChartsLoading" active :is-full-page="false" />
|
<b-loading v-if="isChartsLoading" active :is-full-page="false" />
|
||||||
<article class="tile is-child notification charts">
|
<article class="tile is-child notification charts">
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
<template>
|
<template>
|
||||||
<section class="forms content">
|
<section class="forms content relative">
|
||||||
<h1 class="title is-4">Forms</h1>
|
<h1 class="title is-4">Forms</h1>
|
||||||
<hr />
|
<hr />
|
||||||
<div class="columns">
|
<b-loading v-if="loading.lists" :active="loading.lists" :is-full-page="false" />
|
||||||
|
<div class="columns" v-else-if="publicLists.length > 0">
|
||||||
<div class="column is-4">
|
<div class="column is-4">
|
||||||
<h4>Public lists</h4>
|
<h4>Public lists</h4>
|
||||||
<p>Select lists to add to the form.</p>
|
<p>Select lists to add to the form.</p>
|
||||||
|
|
||||||
|
<b-loading :active="loading.lists" :is-full-page="false" />
|
||||||
<ul class="no">
|
<ul class="no">
|
||||||
<li v-for="l in lists" :key="l.id">
|
<li v-for="l in publicLists" :key="l.id">
|
||||||
<b-checkbox v-model="checked" :native-value="l.uuid">{{ l.name }}</b-checkbox>
|
<b-checkbox v-model="checked"
|
||||||
|
:native-value="l.uuid">{{ l.name }}</b-checkbox>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -27,7 +31,7 @@
|
||||||
<h3>Subscribe</h3>
|
<h3>Subscribe</h3>
|
||||||
<p><input type="text" name="email" placeholder="E-mail" /></p>
|
<p><input type="text" name="email" placeholder="E-mail" /></p>
|
||||||
<p><input type="text" name="name" placeholder="Name (optional)" /></p>
|
<p><input type="text" name="name" placeholder="Name (optional)" /></p>
|
||||||
<template v-for="l in lists"><span v-if="l.uuid in selected" :key="l.id" :set="id = l.uuid.substr(0, 5)">
|
<template v-for="l in publicLists"><span v-if="l.uuid in selected" :key="l.id" :set="id = l.uuid.substr(0, 5)">
|
||||||
<p>
|
<p>
|
||||||
<input id="{{ id }}" type="checkbox" name="l" value="{{ uuid }}" />
|
<input id="{{ id }}" type="checkbox" name="l" value="{{ uuid }}" />
|
||||||
<label for="{{ id }}">{{ l.name }}</label>
|
<label for="{{ id }}">{{ l.name }}</label>
|
||||||
|
@ -36,12 +40,15 @@
|
||||||
</div>
|
</div>
|
||||||
</form></pre>
|
</form></pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div><!-- columns -->
|
||||||
|
|
||||||
|
<p v-else>There are no public lists to create forms.</p>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import { mapState } from 'vuex';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
name: 'ListForm',
|
name: 'ListForm',
|
||||||
|
@ -52,13 +59,23 @@ export default Vue.extend({
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getPublicLists(lists) {
|
||||||
|
console.log(lists.filter((l) => l.type === 'public'));
|
||||||
|
return lists.filter((l) => l.type === 'public');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
lists() {
|
...mapState(['lists', 'loading']),
|
||||||
if (!this.$store.state.lists.results) {
|
|
||||||
|
publicLists() {
|
||||||
|
if (!this.lists.results) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return this.$store.state.lists.results.filter((l) => l.type === 'public');
|
return this.lists.results.filter((l) => l.type === 'public');
|
||||||
},
|
},
|
||||||
|
|
||||||
selected() {
|
selected() {
|
||||||
const sel = [];
|
const sel = [];
|
||||||
this.checked.forEach((uuid) => {
|
this.checked.forEach((uuid) => {
|
||||||
|
@ -67,9 +84,5 @@ export default Vue.extend({
|
||||||
return sel;
|
return sel;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
|
||||||
this.$api.getLists();
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -129,10 +129,10 @@ import Vue from 'vue';
|
||||||
import { mapState } from 'vuex';
|
import { mapState } from 'vuex';
|
||||||
import ListSelector from '../components/ListSelector.vue';
|
import ListSelector from '../components/ListSelector.vue';
|
||||||
|
|
||||||
Vue.component('list-selector', ListSelector);
|
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
name: 'Import',
|
components: {
|
||||||
|
ListSelector,
|
||||||
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
data: {},
|
data: {},
|
||||||
|
|
|
@ -73,14 +73,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template slot="empty" v-if="!loading.lists">
|
<template slot="empty" v-if="!loading.lists">
|
||||||
<section class="section">
|
<empty-placeholder />
|
||||||
<div class="content has-text-grey has-text-centered">
|
|
||||||
<p>
|
|
||||||
<b-icon icon="plus" size="is-large" />
|
|
||||||
</p>
|
|
||||||
<p>Nothing here yet.</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</template>
|
</template>
|
||||||
</b-table>
|
</b-table>
|
||||||
|
|
||||||
|
@ -95,12 +88,12 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { mapState } from 'vuex';
|
import { mapState } from 'vuex';
|
||||||
import ListForm from './ListForm.vue';
|
import ListForm from './ListForm.vue';
|
||||||
|
import EmptyPlaceholder from '../components/EmptyPlaceholder.vue';
|
||||||
Vue.component('list-form', ListForm);
|
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
ListForm,
|
ListForm,
|
||||||
|
EmptyPlaceholder,
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -42,10 +42,10 @@ import Vue from 'vue';
|
||||||
import { mapState } from 'vuex';
|
import { mapState } from 'vuex';
|
||||||
import ListSelector from '../components/ListSelector.vue';
|
import ListSelector from '../components/ListSelector.vue';
|
||||||
|
|
||||||
Vue.component('list-selector', ListSelector);
|
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
name: 'SubscriberBulkList',
|
components: {
|
||||||
|
ListSelector,
|
||||||
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
numSubscribers: Number,
|
numSubscribers: Number,
|
||||||
|
|
|
@ -61,10 +61,10 @@ import Vue from 'vue';
|
||||||
import { mapState } from 'vuex';
|
import { mapState } from 'vuex';
|
||||||
import ListSelector from '../components/ListSelector.vue';
|
import ListSelector from '../components/ListSelector.vue';
|
||||||
|
|
||||||
Vue.component('list-selector', ListSelector);
|
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
name: 'SubscriberForm',
|
components: {
|
||||||
|
ListSelector,
|
||||||
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
data: {
|
data: {
|
||||||
|
|
|
@ -159,14 +159,7 @@
|
||||||
</b-table-column>
|
</b-table-column>
|
||||||
</template>
|
</template>
|
||||||
<template slot="empty" v-if="!loading.subscribers">
|
<template slot="empty" v-if="!loading.subscribers">
|
||||||
<section class="section">
|
<empty-placeholder />
|
||||||
<div class="content has-text-grey has-text-centered">
|
|
||||||
<p>
|
|
||||||
<b-icon icon="plus" size="is-large" />
|
|
||||||
</p>
|
|
||||||
<p>No subscribers.</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</template>
|
</template>
|
||||||
</b-table>
|
</b-table>
|
||||||
|
|
||||||
|
@ -189,13 +182,13 @@ import Vue from 'vue';
|
||||||
import { mapState } from 'vuex';
|
import { mapState } from 'vuex';
|
||||||
import SubscriberForm from './SubscriberForm.vue';
|
import SubscriberForm from './SubscriberForm.vue';
|
||||||
import SubscriberBulkList from './SubscriberBulkList.vue';
|
import SubscriberBulkList from './SubscriberBulkList.vue';
|
||||||
|
import EmptyPlaceholder from '../components/EmptyPlaceholder.vue';
|
||||||
Vue.component('subscriber-form', SubscriberForm);
|
|
||||||
Vue.component('subscriber-bulk-list', SubscriberBulkList);
|
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
SubscriberForm,
|
SubscriberForm,
|
||||||
|
SubscriberBulkList,
|
||||||
|
EmptyPlaceholder,
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -46,10 +46,10 @@ import Vue from 'vue';
|
||||||
import { mapState } from 'vuex';
|
import { mapState } from 'vuex';
|
||||||
import CampaignPreview from '../components/CampaignPreview.vue';
|
import CampaignPreview from '../components/CampaignPreview.vue';
|
||||||
|
|
||||||
Vue.component('campaign-preview', CampaignPreview);
|
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
name: 'TemplateForm',
|
components: {
|
||||||
|
CampaignPreview,
|
||||||
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
data: Object,
|
data: Object,
|
||||||
|
|
|
@ -55,14 +55,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template slot="empty" v-if="!loading.templates">
|
<template slot="empty" v-if="!loading.templates">
|
||||||
<section class="section">
|
<empty-placeholder />
|
||||||
<div class="content has-text-grey has-text-centered">
|
|
||||||
<p>
|
|
||||||
<b-icon icon="plus" size="is-large" />
|
|
||||||
</p>
|
|
||||||
<p>Nothing here.</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</template>
|
</template>
|
||||||
</b-table>
|
</b-table>
|
||||||
|
|
||||||
|
@ -86,13 +79,13 @@ import Vue from 'vue';
|
||||||
import { mapState } from 'vuex';
|
import { mapState } from 'vuex';
|
||||||
import TemplateForm from './TemplateForm.vue';
|
import TemplateForm from './TemplateForm.vue';
|
||||||
import CampaignPreview from '../components/CampaignPreview.vue';
|
import CampaignPreview from '../components/CampaignPreview.vue';
|
||||||
|
import EmptyPlaceholder from '../components/EmptyPlaceholder.vue';
|
||||||
Vue.component('campaign-preview', CampaignPreview);
|
|
||||||
Vue.component('template-form', TemplateForm);
|
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
|
CampaignPreview,
|
||||||
TemplateForm,
|
TemplateForm,
|
||||||
|
EmptyPlaceholder,
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -134,7 +134,7 @@ func handleQuerySubscribers(c echo.Context) error {
|
||||||
defer tx.Rollback()
|
defer tx.Rollback()
|
||||||
|
|
||||||
// Run the query.
|
// Run the query.
|
||||||
if err := tx.Select(&out.Results, stmt, listIDs, "id", pg.Offset, pg.Limit); err != nil {
|
if err := tx.Select(&out.Results, stmt, listIDs, "updaated_at", pg.Offset, pg.Limit); err != nil {
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError,
|
return echo.NewHTTPError(http.StatusInternalServerError,
|
||||||
fmt.Sprintf("Error querying subscribers: %v", pqErrMsg(err)))
|
fmt.Sprintf("Error querying subscribers: %v", pqErrMsg(err)))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue