feat: unsaved changes prompt + beta preparations UI
This commit is contained in:
		| @@ -61,36 +61,41 @@ | ||||
|                       persistent-hint | ||||
|                       ) | ||||
|                   v-divider | ||||
|                   v-subheader Analytics | ||||
|                   v-subheader Analytics #[v-chip.ml-2(label, color='grey', small, outline) coming soon] | ||||
|                   .px-3.pb-3 | ||||
|                     v-text-field( | ||||
|                     v-select.mt-2( | ||||
|                       outline | ||||
|                       label='Google Analytics ID' | ||||
|                       label='Analytics Service Provider' | ||||
|                       :items='analyticsServices' | ||||
|                       v-model='config.analyticsService' | ||||
|                       prepend-icon='timeline' | ||||
|                       ) | ||||
|                     v-text-field.mt-2( | ||||
|                       v-if='config.analyticsService !== ``' | ||||
|                       outline | ||||
|                       label='Property Tracking ID' | ||||
|                       :counter='255' | ||||
|                       v-model='config.ga' | ||||
|                       v-model='config.analyticsId' | ||||
|                       prepend-icon='timeline' | ||||
|                       persistent-hint | ||||
|                       hint='Property tracking ID for Google Analytics. Leave empty to disable.' | ||||
|                       hint='A unique identifier provided by your analytics service provider.' | ||||
|                       ) | ||||
|             v-flex(lg6 xs12) | ||||
|               v-card.wiki-form | ||||
|                 v-toolbar(color='primary', dark, dense, flat) | ||||
|                   v-toolbar-title | ||||
|                     .subheading {{ $t('admin:general.siteBranding') }} | ||||
|                   v-spacer | ||||
|                   v-chip(label, color='white', small).primary--text coming soon | ||||
|                 v-subheader Logo | ||||
|                 v-subheader Logo #[v-chip.ml-2(label, color='grey', small, outline) coming soon] | ||||
|                 v-card-text | ||||
|                   v-layout.px-3(row, align-center) | ||||
|                     v-avatar(size='120', :color='$vuetify.dark ? `grey darken-2` : `grey lighten-3`', :tile='config.logoIsSquare') | ||||
|                     .ml-4 | ||||
|                       v-layout(row, align-center) | ||||
|                         v-btn(color='teal', depressed, dark) | ||||
|                           v-icon(left) cloud_upload | ||||
|                           span Upload Logo | ||||
|                         v-btn(color='teal', depressed, disabled) | ||||
|                           v-icon(left) clear | ||||
|                           span Clear | ||||
|                       v-btn.mx-0(color='teal', depressed, disabled) | ||||
|                         v-icon(left) cloud_upload | ||||
|                         span Upload Logo | ||||
|                       v-btn(color='teal', depressed, disabled) | ||||
|                         v-icon(left) clear | ||||
|                         span Clear | ||||
|                       .caption.grey--text An image of 120x120 pixels is recommended for best results. | ||||
|                       .caption.grey--text SVG, PNG or JPG files only. | ||||
|                   v-switch( | ||||
| @@ -117,6 +122,8 @@ | ||||
|                 v-toolbar(color='primary', dark, dense, flat) | ||||
|                   v-toolbar-title | ||||
|                     .subheading Features | ||||
|                   v-spacer | ||||
|                   v-chip(label, color='white', small).primary--text coming soon | ||||
|                 v-card-text | ||||
|                   v-switch( | ||||
|                     label='Page Ratings' | ||||
| @@ -153,6 +160,11 @@ import siteUpdateConfigMutation from 'gql/admin/site/site-mutation-save-config.g | ||||
| export default { | ||||
|   data() { | ||||
|     return { | ||||
|       analyticsServices: [ | ||||
|         { text: 'None', value: '' }, | ||||
|         { text: 'Google Analytics', value: 'ga' }, | ||||
|         { text: 'Google Tag Manager', value: 'gtm' }, | ||||
|       ], | ||||
|       metaRobots: [ | ||||
|         { text: 'Index', value: 'index' }, | ||||
|         { text: 'Follow', value: 'follow' }, | ||||
| @@ -164,7 +176,8 @@ export default { | ||||
|         title: '', | ||||
|         description: '', | ||||
|         robots: [], | ||||
|         ga: '', | ||||
|         analyticsService: '', | ||||
|         analyticsId: '', | ||||
|         company: '', | ||||
|         hasLogo: false, | ||||
|         logoIsSquare: false, | ||||
| @@ -189,7 +202,8 @@ export default { | ||||
|             title: this.config.title || '', | ||||
|             description: this.config.description || '', | ||||
|             robots: this.config.robots || [], | ||||
|             ga: this.config.ga || '', | ||||
|             analyticsService: this.config.analyticsService || '', | ||||
|             analyticsId: this.config.analyticsId || '', | ||||
|             company: this.config.company || '', | ||||
|             hasLogo: this.config.hasLogo || false, | ||||
|             logoIsSquare: this.config.logoIsSquare || false, | ||||
|   | ||||
| @@ -54,7 +54,7 @@ | ||||
|                     span System Group | ||||
|             template(slot='no-data') | ||||
|               v-alert.ma-3(icon='warning', :value='true', outline) No groups to display. | ||||
|           .text-xs-center.py-2(v-if='groups.length > 15') | ||||
|           .text-xs-center.py-2(v-if='this.pages > 0') | ||||
|             v-pagination(v-model='pagination.page', :length='pages') | ||||
| </template> | ||||
|  | ||||
|   | ||||
| @@ -6,11 +6,11 @@ | ||||
|           img(src='/svg/icon-file.svg', alt='Page', style='width: 80px;') | ||||
|           .admin-header-title | ||||
|             .headline.blue--text.text--darken-2 Pages | ||||
|             .subheading.grey--text Manage pages | ||||
|             .subheading.grey--text Manage pages #[v-chip(label, color='primary', small).white--text coming soon] | ||||
|           v-spacer | ||||
|           v-btn(color='grey', outline, @click='refresh', large) | ||||
|           v-btn(color='grey', outline, @click='refresh', large, disabled) | ||||
|             v-icon.grey--text refresh | ||||
|           v-btn(color='primary', depressed, large, @click='newpage') | ||||
|           v-btn(color='primary', depressed, large, @click='newpage', disabled) | ||||
|             v-icon(left) add | ||||
|             span New Page | ||||
|         v-card.mt-3 | ||||
| @@ -31,7 +31,7 @@ | ||||
|                 td {{ props.item.updatedAt | moment('calendar') }} | ||||
|             template(slot='no-data') | ||||
|               v-alert.ma-3(icon='warning', :value='true', outline) No pages to display. | ||||
|           .text-xs-center.py-2(v-if='groups.length > 15') | ||||
|           .text-xs-center.py-2(v-if='this.pages > 0') | ||||
|             v-pagination(v-model='pagination.page', :length='pages') | ||||
|  | ||||
|     page-selector(v-model='pageSelectorShown', mode='new') | ||||
|   | ||||
| @@ -35,6 +35,7 @@ | ||||
|                       :value='engine.key' | ||||
|                       color='primary' | ||||
|                       hide-details | ||||
|                       disabled | ||||
|                     ) | ||||
|  | ||||
|             v-tab-item(v-for='(engine, n) in activeEngines', :key='engine.key', :transition='false', :reverse-transition='false') | ||||
|   | ||||
| @@ -1,95 +0,0 @@ | ||||
| <template lang="pug"> | ||||
|   v-dialog(v-model='isShown', max-width='550') | ||||
|     v-card.wiki-form | ||||
|       .dialog-header.is-short | ||||
|         span Authorize Social User | ||||
|         v-spacer | ||||
|         v-chip(label, color='white', small).primary--text coming soon | ||||
|       v-card-text | ||||
|         v-alert.mb-4.deep-orange.lighten-5.radius-7( | ||||
|           v-if='providers.length < 1' | ||||
|           color='deep-orange' | ||||
|           icon='warning' | ||||
|           outline | ||||
|           :value='true' | ||||
|           ) You must enable at least 1 social strategy first. | ||||
|         v-select.md2( | ||||
|           :items='providers' | ||||
|           item-text='title' | ||||
|           item-value='key' | ||||
|           outline | ||||
|           prepend-icon='business' | ||||
|           v-model='provider' | ||||
|           label='Provider' | ||||
|           ) | ||||
|         v-text-field.md2( | ||||
|           outline | ||||
|           prepend-icon='email' | ||||
|           v-model='email' | ||||
|           label='Email Address' | ||||
|           ref='emailInput' | ||||
|           ) | ||||
|         v-text-field.md2( | ||||
|           outline | ||||
|           prepend-icon='person' | ||||
|           v-model='name' | ||||
|           label='Name' | ||||
|           ) | ||||
|       v-card-chin | ||||
|         v-spacer | ||||
|         v-btn(flat, @click='isShown = false') Cancel | ||||
|         v-btn(color='primary', @click='authorizeUser', :disabled='providers.length < 1 || true') Authorize | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import _ from 'lodash' | ||||
|  | ||||
| import providersQuery from 'gql/admin/users/users-query-strategies.gql' | ||||
|  | ||||
| export default { | ||||
|   props: { | ||||
|     value: { | ||||
|       type: Boolean, | ||||
|       default: false | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       providers: [], | ||||
|       provider: '', | ||||
|       email: '', | ||||
|       name: '' | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     isShown: { | ||||
|       get() { return this.value }, | ||||
|       set(val) { this.$emit('input', val) } | ||||
|     } | ||||
|   }, | ||||
|   watch: { | ||||
|     value(newValue, oldValue) { | ||||
|       if (newValue) { | ||||
|         this.$nextTick(() => { | ||||
|           this.$refs.emailInput.focus() | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     async authorizeUser() { | ||||
|  | ||||
|     } | ||||
|   }, | ||||
|   apollo: { | ||||
|     providers: { | ||||
|       query: providersQuery, | ||||
|       fetchPolicy: 'network-only', | ||||
|       update: (data) => _.reject(data.authentication.strategies, ['key', 'local']), | ||||
|       watchLoading (isLoading) { | ||||
|         this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-users-strategies-refresh') | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
| @@ -1,8 +1,18 @@ | ||||
| <template lang="pug"> | ||||
|   v-dialog(v-model='isShown', max-width='550') | ||||
|     v-card.wiki-form | ||||
|       .dialog-header.is-short New Local User | ||||
|       .dialog-header.is-short | ||||
|         span New User | ||||
|       v-card-text | ||||
|         v-select.md2( | ||||
|           :items='providers' | ||||
|           item-text='title' | ||||
|           item-value='key' | ||||
|           outline | ||||
|           prepend-icon='business' | ||||
|           v-model='provider' | ||||
|           label='Provider' | ||||
|           ) | ||||
|         v-text-field.md2( | ||||
|           outline | ||||
|           prepend-icon='email' | ||||
| @@ -11,12 +21,7 @@ | ||||
|           ref='emailInput' | ||||
|           ) | ||||
|         v-text-field.md2( | ||||
|           outline | ||||
|           prepend-icon='person' | ||||
|           v-model='name' | ||||
|           label='Name' | ||||
|           ) | ||||
|         v-text-field.md2( | ||||
|           v-if='provider === `local`' | ||||
|           outline | ||||
|           prepend-icon='lock' | ||||
|           append-icon='casino' | ||||
| @@ -25,15 +30,24 @@ | ||||
|           counter='255' | ||||
|           @click:append='generatePwd' | ||||
|           ) | ||||
|         v-text-field.md2( | ||||
|           outline | ||||
|           prepend-icon='person' | ||||
|           v-model='name' | ||||
|           label='Name' | ||||
|           ) | ||||
|       v-card-chin | ||||
|         v-spacer | ||||
|         v-btn(flat, @click='isShown = false') Cancel | ||||
|         v-btn(color='primary', @click='createUser') Create User | ||||
|         v-btn(color='primary', @click='newUser') Create | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import _ from 'lodash' | ||||
| import uuidv4 from 'uuid/v4' | ||||
|  | ||||
| import providersQuery from 'gql/admin/users/users-query-strategies.gql' | ||||
|  | ||||
| export default { | ||||
|   props: { | ||||
|     value: { | ||||
| @@ -43,11 +57,11 @@ export default { | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       providers: [], | ||||
|       provider: 'local', | ||||
|       email: '', | ||||
|       name: '', | ||||
|       password: '', | ||||
|       jobTitle: '', | ||||
|       location: '' | ||||
|       name: '' | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
| @@ -66,12 +80,22 @@ export default { | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     async createUser() { | ||||
|     async newUser() { | ||||
|  | ||||
|     }, | ||||
|     generatePwd() { | ||||
|       this.password = uuidv4().slice(-12) | ||||
|     } | ||||
|   }, | ||||
|   apollo: { | ||||
|     providers: { | ||||
|       query: providersQuery, | ||||
|       fetchPolicy: 'network-only', | ||||
|       update: (data) => data.authentication.strategies, | ||||
|       watchLoading (isLoading) { | ||||
|         this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-users-strategies-refresh') | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|   | ||||
| @@ -10,12 +10,9 @@ | ||||
|           v-spacer | ||||
|           v-btn(outline, color='grey', large, @click='refresh') | ||||
|             v-icon refresh | ||||
|           v-btn(color='primary', large, outline, @click='authorizeUser') | ||||
|             v-icon(left) lock_outline | ||||
|             span Authorize Social User | ||||
|           v-btn(color='primary', large, depressed, @click='createUser') | ||||
|             v-icon(left) add | ||||
|             span New Local User | ||||
|             span New User | ||||
|         v-card.mt-3 | ||||
|           v-data-table( | ||||
|             v-model='selected' | ||||
| @@ -54,24 +51,21 @@ | ||||
|             template(slot='no-data') | ||||
|               .pa-3 | ||||
|                 v-alert(icon='warning', :value='true', outline) No users to display! | ||||
|           v-card-chin | ||||
|           v-card-chin(v-if='this.pages > 0') | ||||
|             v-spacer | ||||
|             v-pagination(v-model='pagination.page', :length='pages') | ||||
|             v-spacer | ||||
|  | ||||
|     user-authorize(v-model='isAuthorizeDialogShown') | ||||
|     user-create(v-model='isCreateDialogShown') | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import usersQuery from 'gql/admin/users/users-query-list.gql' | ||||
|  | ||||
| import UserAuthorize from './admin-users-authorize.vue' | ||||
| import UserCreate from './admin-users-create.vue' | ||||
|  | ||||
| export default { | ||||
|   components: { | ||||
|     UserAuthorize, | ||||
|     UserCreate | ||||
|   }, | ||||
|   data() { | ||||
| @@ -88,7 +82,6 @@ export default { | ||||
|         { text: '', value: 'actions', sortable: false, width: 50 } | ||||
|       ], | ||||
|       search: '', | ||||
|       isAuthorizeDialogShown: false, | ||||
|       isCreateDialogShown: false | ||||
|     } | ||||
|   }, | ||||
| @@ -102,9 +95,6 @@ export default { | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     authorizeUser() { | ||||
|       this.isAuthorizeDialogShown = true | ||||
|     }, | ||||
|     createUser() { | ||||
|       this.isCreateDialogShown = true | ||||
|     }, | ||||
|   | ||||
| @@ -19,7 +19,7 @@ | ||||
|           v-icon(color='blue', :left='$vuetify.breakpoint.lgAndUp') sort_by_alpha | ||||
|           span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ $t('editor:page') }} | ||||
|         v-btn( | ||||
|           v-if='mode === `create`' | ||||
|           v-if='mode === `create` && path !== `home`' | ||||
|           outline | ||||
|           color='red' | ||||
|           :class='{ "is-icon": $vuetify.breakpoint.mdAndDown }' | ||||
| @@ -29,74 +29,12 @@ | ||||
|           span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ $t('common:actions.discard') }} | ||||
|     v-content | ||||
|       component(:is='currentEditor') | ||||
|       v-btn(fixed, bottom, right, color='red', round, @click='exit', dark) | ||||
|         v-icon(left) close | ||||
|         span Close Editor | ||||
|       editor-modal-properties(v-model='dialogProps') | ||||
|       v-dialog(v-model='dialogEditorSelector', persistent, max-width='700') | ||||
|         v-card.radius-7(color='blue darken-3', dark) | ||||
|           v-card-text.text-xs-center.py-4 | ||||
|             .subheading Which editor do you want to use for this page? | ||||
|             v-container(grid-list-lg, fluid) | ||||
|               v-layout(row, wrap, justify-center) | ||||
|                 v-flex(xs4) | ||||
|                   v-card.radius-7.grey( | ||||
|                     hover | ||||
|                     light | ||||
|                     ripple | ||||
|                     ) | ||||
|                     v-card-text.text-xs-center(@click='selectEditor("api")') | ||||
|                       img(src='/svg/icon-rest-api.svg', alt='API', style='width: 36px;') | ||||
|                       .body-2.mt-2.grey--text.text--darken-2 API Docs | ||||
|                       .caption.grey--text.text--darken-1 REST / GraphQL | ||||
|                 v-flex(xs4) | ||||
|                   v-card.radius-7( | ||||
|                     hover | ||||
|                     light | ||||
|                     ripple | ||||
|                     ) | ||||
|                     v-card-text.text-xs-center(@click='selectEditor("code")') | ||||
|                       img(src='/svg/icon-source-code.svg', alt='Code', style='width: 36px;') | ||||
|                       .body-2.mt-2 Code | ||||
|                       .caption.grey--text Raw HTML | ||||
|                 v-flex(xs4) | ||||
|                   v-card.radius-7( | ||||
|                     hover | ||||
|                     light | ||||
|                     ripple | ||||
|                     ) | ||||
|                     v-card-text.text-xs-center(@click='selectEditor("markdown")') | ||||
|                       img(src='/svg/icon-markdown.svg', alt='Markdown', style='width: 36px;') | ||||
|                       .body-2.mt-2 Markdown | ||||
|                       .caption.grey--text Default | ||||
|                 v-flex(xs4) | ||||
|                   v-card.radius-7.grey( | ||||
|                     hover | ||||
|                     light | ||||
|                     ripple | ||||
|                     ) | ||||
|                     v-card-text.text-xs-center(@click='selectEditor("tabular")') | ||||
|                       img(src='/svg/icon-table.svg', alt='Tabular', style='width: 36px;') | ||||
|                       .body-2.grey--text.mt-2.text--darken-2 Tabular | ||||
|                       .caption.grey--text.text--darken-1 Excel-like | ||||
|                 v-flex(xs4) | ||||
|                   v-card.radius-7.grey( | ||||
|                     hover | ||||
|                     light | ||||
|                     ripple | ||||
|                     ) | ||||
|                     v-card-text.text-xs-center(@click='selectEditor("wysiwyg")') | ||||
|                       img(src='/svg/icon-open-in-browser.svg', alt='Visual Builder', style='width: 36px;') | ||||
|                       .body-2.mt-2.grey--text.text--darken-2 Visual Builder | ||||
|                       .caption.grey--text.text--darken-1 Drag-n-drop | ||||
|                 v-flex(xs4) | ||||
|                   v-card.radius-7.grey( | ||||
|                     hover | ||||
|                     light | ||||
|                     ripple | ||||
|                     ) | ||||
|                     v-card-text.text-xs-center(@click='selectEditor("wikitext")') | ||||
|                       img(src='/svg/icon-news.svg', alt='WikiText', style='width: 36px;') | ||||
|                       .body-2.grey--text.mt-2.text--darken-2 WikiText | ||||
|                       .caption.grey--text.text--darken-1 MediaWiki Format | ||||
|             .caption.blue--text.text--lighten-2 This cannot be changed once the page is created. | ||||
|       editor-modal-editorselect(v-model='dialogEditorSelector') | ||||
|       editor-modal-unsaved(v-model='dialogUnsaved', @discard='exitGo') | ||||
|  | ||||
|     loader(v-model='dialogProgress', :title='$t(`editor:save.processing`)', :subtitle='$t(`editor:save.pleaseWait`)') | ||||
|     v-snackbar( | ||||
| @@ -132,7 +70,9 @@ export default { | ||||
|     editorCode: () => import(/* webpackChunkName: "editor-code", webpackMode: "lazy" */ './editor/editor-code.vue'), | ||||
|     editorMarkdown: () => import(/* webpackChunkName: "editor-markdown", webpackMode: "lazy" */ './editor/editor-markdown.vue'), | ||||
|     editorWysiwyg: () => import(/* webpackChunkName: "editor-wysiwyg", webpackMode: "lazy" */ './editor/editor-wysiwyg.vue'), | ||||
|     editorModalProperties: () => import(/* webpackChunkName: "editor", webpackMode: "eager" */ './editor/editor-modal-properties.vue') | ||||
|     editorModalEditorselect: () => import(/* webpackChunkName: "editor", webpackMode: "eager" */ './editor/editor-modal-editorselect.vue'), | ||||
|     editorModalProperties: () => import(/* webpackChunkName: "editor", webpackMode: "eager" */ './editor/editor-modal-properties.vue'), | ||||
|     editorModalUnsaved: () => import(/* webpackChunkName: "editor", webpackMode: "eager" */ './editor/editor-modal-unsaved.vue') | ||||
|   }, | ||||
|   props: { | ||||
|     locale: { | ||||
| @@ -178,18 +118,29 @@ export default { | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       currentEditor: '', | ||||
|       dialogProps: false, | ||||
|       dialogProgress: false, | ||||
|       dialogEditorSelector: false | ||||
|       dialogEditorSelector: false, | ||||
|       dialogUnsaved: false, | ||||
|       initContentParsed: '' | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     currentEditor: sync('editor/editor'), | ||||
|     darkMode: get('site/dark'), | ||||
|     mode: get('editor/mode'), | ||||
|     notification: get('notification'), | ||||
|     notificationState: sync('notification@isActive') | ||||
|   }, | ||||
|   watch: { | ||||
|     currentEditor(newValue, oldValue) { | ||||
|       if (newValue !== '' && this.mode === 'create') { | ||||
|         _.delay(() => { | ||||
|           this.dialogProps = true | ||||
|         }, 500) | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   created() { | ||||
|     this.$store.commit('page/SET_ID', this.pageId) | ||||
|     this.$store.commit('page/SET_DESCRIPTION', this.description) | ||||
| @@ -203,25 +154,18 @@ export default { | ||||
|   }, | ||||
|   mounted() { | ||||
|     this.$store.set('editor/mode', this.initMode || 'create') | ||||
|     this.$store.set('editor/content', this.initContent ? Base64.decode(this.initContent) : '# Header\n\nYour content here') | ||||
|  | ||||
|     this.initContentParsed = this.initContent ? Base64.decode(this.initContent) : '# Header\n\nYour content here' | ||||
|     this.$store.set('editor/content', this.initContentParsed) | ||||
|     if (this.mode === 'create') { | ||||
|       _.delay(() => { | ||||
|         this.dialogEditorSelector = true | ||||
|       }, 500) | ||||
|     } else { | ||||
|       this.selectEditor(this.initEditor || 'markdown') | ||||
|       this.currentEditor = `editor${_.startCase(this.initEditor || 'markdown')}` | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     selectEditor(name) { | ||||
|       this.currentEditor = `editor${_.startCase(name)}` | ||||
|       this.dialogEditorSelector = false | ||||
|       if (this.mode === 'create') { | ||||
|         _.delay(() => { | ||||
|           this.dialogProps = true | ||||
|         }, 500) | ||||
|       } | ||||
|     }, | ||||
|     openPropsModal(name) { | ||||
|       this.dialogProps = true | ||||
|     }, | ||||
| @@ -310,8 +254,19 @@ export default { | ||||
|       } | ||||
|       this.hideProgressDialog() | ||||
|     }, | ||||
|     exit() { | ||||
|  | ||||
|     async exit() { | ||||
|       if (this.initContentParsed !== this.$store.get('editor/content')) { | ||||
|         this.dialogUnsaved = true | ||||
|       } else { | ||||
|         this.exitGo() | ||||
|       } | ||||
|     }, | ||||
|     exitGo() { | ||||
|       this.$store.commit(`loadingStart`, 'editor-close') | ||||
|       this.currentEditor = '' | ||||
|       _.delay(() => { | ||||
|         window.location.assign(`/${this.$store.get('page/path')}`) | ||||
|       }, 500) | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										103
									
								
								client/components/editor/editor-modal-editorselect.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								client/components/editor/editor-modal-editorselect.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | ||||
| <template lang='pug'> | ||||
|   v-dialog(v-model='isShown', persistent, max-width='700') | ||||
|     v-card.radius-7(color='blue darken-3', dark) | ||||
|       v-card-text.text-xs-center.py-4 | ||||
|         .subheading Which editor do you want to use for this page? | ||||
|         v-container(grid-list-lg, fluid) | ||||
|           v-layout(row, wrap, justify-center) | ||||
|             v-flex(xs4) | ||||
|               v-card.radius-7.grey( | ||||
|                 hover | ||||
|                 light | ||||
|                 ripple | ||||
|                 ) | ||||
|                 v-card-text.text-xs-center(@click='selectEditor("api")') | ||||
|                   img(src='/svg/icon-rest-api.svg', alt='API', style='width: 36px;') | ||||
|                   .body-2.mt-2.grey--text.text--darken-2 API Docs | ||||
|                   .caption.grey--text.text--darken-1 REST / GraphQL | ||||
|             v-flex(xs4) | ||||
|               v-card.radius-7( | ||||
|                 hover | ||||
|                 light | ||||
|                 ripple | ||||
|                 ) | ||||
|                 v-card-text.text-xs-center(@click='selectEditor("code")') | ||||
|                   img(src='/svg/icon-source-code.svg', alt='Code', style='width: 36px;') | ||||
|                   .body-2.mt-2 Code | ||||
|                   .caption.grey--text Raw HTML | ||||
|             v-flex(xs4) | ||||
|               v-card.radius-7( | ||||
|                 hover | ||||
|                 light | ||||
|                 ripple | ||||
|                 ) | ||||
|                 v-card-text.text-xs-center(@click='selectEditor("markdown")') | ||||
|                   img(src='/svg/icon-markdown.svg', alt='Markdown', style='width: 36px;') | ||||
|                   .body-2.mt-2 Markdown | ||||
|                   .caption.grey--text Default | ||||
|             v-flex(xs4) | ||||
|               v-card.radius-7.grey( | ||||
|                 hover | ||||
|                 light | ||||
|                 ripple | ||||
|                 ) | ||||
|                 v-card-text.text-xs-center(@click='selectEditor("tabular")') | ||||
|                   img(src='/svg/icon-table.svg', alt='Tabular', style='width: 36px;') | ||||
|                   .body-2.grey--text.mt-2.text--darken-2 Tabular | ||||
|                   .caption.grey--text.text--darken-1 Excel-like | ||||
|             v-flex(xs4) | ||||
|               v-card.radius-7.grey( | ||||
|                 hover | ||||
|                 light | ||||
|                 ripple | ||||
|                 ) | ||||
|                 v-card-text.text-xs-center(@click='selectEditor("wysiwyg")') | ||||
|                   img(src='/svg/icon-open-in-browser.svg', alt='Visual Builder', style='width: 36px;') | ||||
|                   .body-2.mt-2.grey--text.text--darken-2 Visual Builder | ||||
|                   .caption.grey--text.text--darken-1 Drag-n-drop | ||||
|             v-flex(xs4) | ||||
|               v-card.radius-7.grey( | ||||
|                 hover | ||||
|                 light | ||||
|                 ripple | ||||
|                 ) | ||||
|                 v-card-text.text-xs-center(@click='selectEditor("wikitext")') | ||||
|                   img(src='/svg/icon-news.svg', alt='WikiText', style='width: 36px;') | ||||
|                   .body-2.grey--text.mt-2.text--darken-2 WikiText | ||||
|                   .caption.grey--text.text--darken-1 MediaWiki Format | ||||
|         .caption.blue--text.text--lighten-2 This cannot be changed once the page is created. | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import _ from 'lodash' | ||||
| import { sync } from 'vuex-pathify' | ||||
|  | ||||
| export default { | ||||
|   props: { | ||||
|     value: { | ||||
|       type: Boolean, | ||||
|       default: false | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     return { } | ||||
|   }, | ||||
|   computed: { | ||||
|     isShown: { | ||||
|       get() { return this.value }, | ||||
|       set(val) { this.$emit('input', val) } | ||||
|     }, | ||||
|     currentEditor: sync('editor/editor'), | ||||
|   }, | ||||
|   methods: { | ||||
|     selectEditor(name) { | ||||
|       this.currentEditor = `editor${_.startCase(name)}` | ||||
|       this.isShown = false | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang='scss'> | ||||
|  | ||||
| </style> | ||||
							
								
								
									
										40
									
								
								client/components/editor/editor-modal-unsaved.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								client/components/editor/editor-modal-unsaved.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| <template lang="pug"> | ||||
|   v-dialog(v-model='isShown', max-width='550') | ||||
|     v-card.wiki-form | ||||
|       .dialog-header.is-short.is-red | ||||
|         v-icon.mr-2(color='white') warning | ||||
|         span Discard Unsaved Changes? | ||||
|       v-card-text | ||||
|         .body-2 You have unsaved changes. Are you sure you want to leave the editor and discard any modifications you made since the last save? | ||||
|       v-card-chin | ||||
|         v-spacer | ||||
|         v-btn(flat, @click='isShown = false') Cancel | ||||
|         v-btn(color='red', @click='discard', dark) Discard Changes | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|  | ||||
| export default { | ||||
|   props: { | ||||
|     value: { | ||||
|       type: Boolean, | ||||
|       default: false | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     return { } | ||||
|   }, | ||||
|   computed: { | ||||
|     isShown: { | ||||
|       get() { return this.value }, | ||||
|       set(val) { this.$emit('input', val) } | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     async discard() { | ||||
|       this.isShown = false | ||||
|       this.$emit('discard', true) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
| @@ -3,7 +3,8 @@ mutation ( | ||||
|   $title: String! | ||||
|   $description: String! | ||||
|   $robots: [String]! | ||||
|   $ga: String! | ||||
|   $analyticsService: String! | ||||
|   $analyticsId: String! | ||||
|   $company: String! | ||||
|   $hasLogo: Boolean! | ||||
|   $logoIsSquare: Boolean! | ||||
| @@ -17,7 +18,8 @@ mutation ( | ||||
|       title: $title, | ||||
|       description: $description, | ||||
|       robots: $robots, | ||||
|       ga: $ga, | ||||
|       analyticsService: $analyticsService, | ||||
|       analyticsId: $analyticsId, | ||||
|       company: $company, | ||||
|       hasLogo: $hasLogo, | ||||
|       logoIsSquare: $logoIsSquare, | ||||
|   | ||||
| @@ -5,7 +5,8 @@ | ||||
|       title | ||||
|       description | ||||
|       robots | ||||
|       ga | ||||
|       analyticsService | ||||
|       analyticsId | ||||
|       company | ||||
|       hasLogo | ||||
|       logoIsSquare | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| import { make } from 'vuex-pathify' | ||||
|  | ||||
| const state = { | ||||
|   editor: '', | ||||
|   content: '', | ||||
|   mode: 'create' | ||||
| } | ||||
|   | ||||
| @@ -31,7 +31,8 @@ module.exports = { | ||||
|         WIKI.config.seo = { | ||||
|           description: args.description, | ||||
|           robots: args.robots, | ||||
|           ga: args.ga | ||||
|           analyticsService: args.analyticsService, | ||||
|           analyticsId: args.analyticsId | ||||
|         } | ||||
|         WIKI.config.logo = { | ||||
|           hasLogo: args.hasLogo, | ||||
|   | ||||
| @@ -28,7 +28,8 @@ type SiteMutation { | ||||
|     title: String! | ||||
|     description: String! | ||||
|     robots: [String]! | ||||
|     ga: String! | ||||
|     analyticsService: String! | ||||
|     analyticsId: String! | ||||
|     company: String! | ||||
|     hasLogo: Boolean! | ||||
|     logoIsSquare: Boolean! | ||||
| @@ -47,7 +48,8 @@ type SiteConfig { | ||||
|   title: String! | ||||
|   description: String! | ||||
|   robots: [String]! | ||||
|   ga: String! | ||||
|   analyticsService: String! | ||||
|     analyticsId: String! | ||||
|   company: String! | ||||
|   hasLogo: Boolean! | ||||
|   logoIsSquare: Boolean! | ||||
|   | ||||
| @@ -140,7 +140,8 @@ module.exports = () => { | ||||
|       _.set(WIKI.config, 'seo', { | ||||
|         description: '', | ||||
|         robots: ['index', 'follow'], | ||||
|         ga: '' | ||||
|         analyticsService: '', | ||||
|         analyticsId: '' | ||||
|       }) | ||||
|       _.set(WIKI.config, 'sessionSecret', (await crypto.randomBytesAsync(32)).toString('hex')) | ||||
|       _.set(WIKI.config, 'telemetry', { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user