feat: unsaved changes prompt + beta preparations UI
This commit is contained in:
		| @@ -61,31 +61,36 @@ | |||||||
|                       persistent-hint |                       persistent-hint | ||||||
|                       ) |                       ) | ||||||
|                   v-divider |                   v-divider | ||||||
|                   v-subheader Analytics |                   v-subheader Analytics #[v-chip.ml-2(label, color='grey', small, outline) coming soon] | ||||||
|                   .px-3.pb-3 |                   .px-3.pb-3 | ||||||
|                     v-text-field( |                     v-select.mt-2( | ||||||
|                       outline |                       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' |                       :counter='255' | ||||||
|                       v-model='config.ga' |                       v-model='config.analyticsId' | ||||||
|                       prepend-icon='timeline' |                       prepend-icon='timeline' | ||||||
|                       persistent-hint |                       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-flex(lg6 xs12) | ||||||
|               v-card.wiki-form |               v-card.wiki-form | ||||||
|                 v-toolbar(color='primary', dark, dense, flat) |                 v-toolbar(color='primary', dark, dense, flat) | ||||||
|                   v-toolbar-title |                   v-toolbar-title | ||||||
|                     .subheading {{ $t('admin:general.siteBranding') }} |                     .subheading {{ $t('admin:general.siteBranding') }} | ||||||
|                   v-spacer |                 v-subheader Logo #[v-chip.ml-2(label, color='grey', small, outline) coming soon] | ||||||
|                   v-chip(label, color='white', small).primary--text coming soon |  | ||||||
|                 v-subheader Logo |  | ||||||
|                 v-card-text |                 v-card-text | ||||||
|                   v-layout.px-3(row, align-center) |                   v-layout.px-3(row, align-center) | ||||||
|                     v-avatar(size='120', :color='$vuetify.dark ? `grey darken-2` : `grey lighten-3`', :tile='config.logoIsSquare') |                     v-avatar(size='120', :color='$vuetify.dark ? `grey darken-2` : `grey lighten-3`', :tile='config.logoIsSquare') | ||||||
|                     .ml-4 |                     .ml-4 | ||||||
|                       v-layout(row, align-center) |                       v-btn.mx-0(color='teal', depressed, disabled) | ||||||
|                         v-btn(color='teal', depressed, dark) |  | ||||||
|                         v-icon(left) cloud_upload |                         v-icon(left) cloud_upload | ||||||
|                         span Upload Logo |                         span Upload Logo | ||||||
|                       v-btn(color='teal', depressed, disabled) |                       v-btn(color='teal', depressed, disabled) | ||||||
| @@ -117,6 +122,8 @@ | |||||||
|                 v-toolbar(color='primary', dark, dense, flat) |                 v-toolbar(color='primary', dark, dense, flat) | ||||||
|                   v-toolbar-title |                   v-toolbar-title | ||||||
|                     .subheading Features |                     .subheading Features | ||||||
|  |                   v-spacer | ||||||
|  |                   v-chip(label, color='white', small).primary--text coming soon | ||||||
|                 v-card-text |                 v-card-text | ||||||
|                   v-switch( |                   v-switch( | ||||||
|                     label='Page Ratings' |                     label='Page Ratings' | ||||||
| @@ -153,6 +160,11 @@ import siteUpdateConfigMutation from 'gql/admin/site/site-mutation-save-config.g | |||||||
| export default { | export default { | ||||||
|   data() { |   data() { | ||||||
|     return { |     return { | ||||||
|  |       analyticsServices: [ | ||||||
|  |         { text: 'None', value: '' }, | ||||||
|  |         { text: 'Google Analytics', value: 'ga' }, | ||||||
|  |         { text: 'Google Tag Manager', value: 'gtm' }, | ||||||
|  |       ], | ||||||
|       metaRobots: [ |       metaRobots: [ | ||||||
|         { text: 'Index', value: 'index' }, |         { text: 'Index', value: 'index' }, | ||||||
|         { text: 'Follow', value: 'follow' }, |         { text: 'Follow', value: 'follow' }, | ||||||
| @@ -164,7 +176,8 @@ export default { | |||||||
|         title: '', |         title: '', | ||||||
|         description: '', |         description: '', | ||||||
|         robots: [], |         robots: [], | ||||||
|         ga: '', |         analyticsService: '', | ||||||
|  |         analyticsId: '', | ||||||
|         company: '', |         company: '', | ||||||
|         hasLogo: false, |         hasLogo: false, | ||||||
|         logoIsSquare: false, |         logoIsSquare: false, | ||||||
| @@ -189,7 +202,8 @@ export default { | |||||||
|             title: this.config.title || '', |             title: this.config.title || '', | ||||||
|             description: this.config.description || '', |             description: this.config.description || '', | ||||||
|             robots: this.config.robots || [], |             robots: this.config.robots || [], | ||||||
|             ga: this.config.ga || '', |             analyticsService: this.config.analyticsService || '', | ||||||
|  |             analyticsId: this.config.analyticsId || '', | ||||||
|             company: this.config.company || '', |             company: this.config.company || '', | ||||||
|             hasLogo: this.config.hasLogo || false, |             hasLogo: this.config.hasLogo || false, | ||||||
|             logoIsSquare: this.config.logoIsSquare || false, |             logoIsSquare: this.config.logoIsSquare || false, | ||||||
|   | |||||||
| @@ -54,7 +54,7 @@ | |||||||
|                     span System Group |                     span System Group | ||||||
|             template(slot='no-data') |             template(slot='no-data') | ||||||
|               v-alert.ma-3(icon='warning', :value='true', outline) No groups to display. |               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') |             v-pagination(v-model='pagination.page', :length='pages') | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,11 +6,11 @@ | |||||||
|           img(src='/svg/icon-file.svg', alt='Page', style='width: 80px;') |           img(src='/svg/icon-file.svg', alt='Page', style='width: 80px;') | ||||||
|           .admin-header-title |           .admin-header-title | ||||||
|             .headline.blue--text.text--darken-2 Pages |             .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-spacer | ||||||
|           v-btn(color='grey', outline, @click='refresh', large) |           v-btn(color='grey', outline, @click='refresh', large, disabled) | ||||||
|             v-icon.grey--text refresh |             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 |             v-icon(left) add | ||||||
|             span New Page |             span New Page | ||||||
|         v-card.mt-3 |         v-card.mt-3 | ||||||
| @@ -31,7 +31,7 @@ | |||||||
|                 td {{ props.item.updatedAt | moment('calendar') }} |                 td {{ props.item.updatedAt | moment('calendar') }} | ||||||
|             template(slot='no-data') |             template(slot='no-data') | ||||||
|               v-alert.ma-3(icon='warning', :value='true', outline) No pages to display. |               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') |             v-pagination(v-model='pagination.page', :length='pages') | ||||||
|  |  | ||||||
|     page-selector(v-model='pageSelectorShown', mode='new') |     page-selector(v-model='pageSelectorShown', mode='new') | ||||||
|   | |||||||
| @@ -35,6 +35,7 @@ | |||||||
|                       :value='engine.key' |                       :value='engine.key' | ||||||
|                       color='primary' |                       color='primary' | ||||||
|                       hide-details |                       hide-details | ||||||
|  |                       disabled | ||||||
|                     ) |                     ) | ||||||
|  |  | ||||||
|             v-tab-item(v-for='(engine, n) in activeEngines', :key='engine.key', :transition='false', :reverse-transition='false') |             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"> | <template lang="pug"> | ||||||
|   v-dialog(v-model='isShown', max-width='550') |   v-dialog(v-model='isShown', max-width='550') | ||||||
|     v-card.wiki-form |     v-card.wiki-form | ||||||
|       .dialog-header.is-short New Local User |       .dialog-header.is-short | ||||||
|  |         span New User | ||||||
|       v-card-text |       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( |         v-text-field.md2( | ||||||
|           outline |           outline | ||||||
|           prepend-icon='email' |           prepend-icon='email' | ||||||
| @@ -11,12 +21,7 @@ | |||||||
|           ref='emailInput' |           ref='emailInput' | ||||||
|           ) |           ) | ||||||
|         v-text-field.md2( |         v-text-field.md2( | ||||||
|           outline |           v-if='provider === `local`' | ||||||
|           prepend-icon='person' |  | ||||||
|           v-model='name' |  | ||||||
|           label='Name' |  | ||||||
|           ) |  | ||||||
|         v-text-field.md2( |  | ||||||
|           outline |           outline | ||||||
|           prepend-icon='lock' |           prepend-icon='lock' | ||||||
|           append-icon='casino' |           append-icon='casino' | ||||||
| @@ -25,15 +30,24 @@ | |||||||
|           counter='255' |           counter='255' | ||||||
|           @click:append='generatePwd' |           @click:append='generatePwd' | ||||||
|           ) |           ) | ||||||
|  |         v-text-field.md2( | ||||||
|  |           outline | ||||||
|  |           prepend-icon='person' | ||||||
|  |           v-model='name' | ||||||
|  |           label='Name' | ||||||
|  |           ) | ||||||
|       v-card-chin |       v-card-chin | ||||||
|         v-spacer |         v-spacer | ||||||
|         v-btn(flat, @click='isShown = false') Cancel |         v-btn(flat, @click='isShown = false') Cancel | ||||||
|         v-btn(color='primary', @click='createUser') Create User |         v-btn(color='primary', @click='newUser') Create | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script> | <script> | ||||||
|  | import _ from 'lodash' | ||||||
| import uuidv4 from 'uuid/v4' | import uuidv4 from 'uuid/v4' | ||||||
|  |  | ||||||
|  | import providersQuery from 'gql/admin/users/users-query-strategies.gql' | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   props: { |   props: { | ||||||
|     value: { |     value: { | ||||||
| @@ -43,11 +57,11 @@ export default { | |||||||
|   }, |   }, | ||||||
|   data() { |   data() { | ||||||
|     return { |     return { | ||||||
|  |       providers: [], | ||||||
|  |       provider: 'local', | ||||||
|       email: '', |       email: '', | ||||||
|       name: '', |  | ||||||
|       password: '', |       password: '', | ||||||
|       jobTitle: '', |       name: '' | ||||||
|       location: '' |  | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   computed: { |   computed: { | ||||||
| @@ -66,12 +80,22 @@ export default { | |||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   methods: { |   methods: { | ||||||
|     async createUser() { |     async newUser() { | ||||||
|  |  | ||||||
|     }, |     }, | ||||||
|     generatePwd() { |     generatePwd() { | ||||||
|       this.password = uuidv4().slice(-12) |       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> | </script> | ||||||
|   | |||||||
| @@ -10,12 +10,9 @@ | |||||||
|           v-spacer |           v-spacer | ||||||
|           v-btn(outline, color='grey', large, @click='refresh') |           v-btn(outline, color='grey', large, @click='refresh') | ||||||
|             v-icon 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-btn(color='primary', large, depressed, @click='createUser') | ||||||
|             v-icon(left) add |             v-icon(left) add | ||||||
|             span New Local User |             span New User | ||||||
|         v-card.mt-3 |         v-card.mt-3 | ||||||
|           v-data-table( |           v-data-table( | ||||||
|             v-model='selected' |             v-model='selected' | ||||||
| @@ -54,24 +51,21 @@ | |||||||
|             template(slot='no-data') |             template(slot='no-data') | ||||||
|               .pa-3 |               .pa-3 | ||||||
|                 v-alert(icon='warning', :value='true', outline) No users to display! |                 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-spacer | ||||||
|             v-pagination(v-model='pagination.page', :length='pages') |             v-pagination(v-model='pagination.page', :length='pages') | ||||||
|             v-spacer |             v-spacer | ||||||
|  |  | ||||||
|     user-authorize(v-model='isAuthorizeDialogShown') |  | ||||||
|     user-create(v-model='isCreateDialogShown') |     user-create(v-model='isCreateDialogShown') | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script> | <script> | ||||||
| import usersQuery from 'gql/admin/users/users-query-list.gql' | import usersQuery from 'gql/admin/users/users-query-list.gql' | ||||||
|  |  | ||||||
| import UserAuthorize from './admin-users-authorize.vue' |  | ||||||
| import UserCreate from './admin-users-create.vue' | import UserCreate from './admin-users-create.vue' | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   components: { |   components: { | ||||||
|     UserAuthorize, |  | ||||||
|     UserCreate |     UserCreate | ||||||
|   }, |   }, | ||||||
|   data() { |   data() { | ||||||
| @@ -88,7 +82,6 @@ export default { | |||||||
|         { text: '', value: 'actions', sortable: false, width: 50 } |         { text: '', value: 'actions', sortable: false, width: 50 } | ||||||
|       ], |       ], | ||||||
|       search: '', |       search: '', | ||||||
|       isAuthorizeDialogShown: false, |  | ||||||
|       isCreateDialogShown: false |       isCreateDialogShown: false | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
| @@ -102,9 +95,6 @@ export default { | |||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   methods: { |   methods: { | ||||||
|     authorizeUser() { |  | ||||||
|       this.isAuthorizeDialogShown = true |  | ||||||
|     }, |  | ||||||
|     createUser() { |     createUser() { | ||||||
|       this.isCreateDialogShown = true |       this.isCreateDialogShown = true | ||||||
|     }, |     }, | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ | |||||||
|           v-icon(color='blue', :left='$vuetify.breakpoint.lgAndUp') sort_by_alpha |           v-icon(color='blue', :left='$vuetify.breakpoint.lgAndUp') sort_by_alpha | ||||||
|           span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ $t('editor:page') }} |           span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ $t('editor:page') }} | ||||||
|         v-btn( |         v-btn( | ||||||
|           v-if='mode === `create`' |           v-if='mode === `create` && path !== `home`' | ||||||
|           outline |           outline | ||||||
|           color='red' |           color='red' | ||||||
|           :class='{ "is-icon": $vuetify.breakpoint.mdAndDown }' |           :class='{ "is-icon": $vuetify.breakpoint.mdAndDown }' | ||||||
| @@ -29,74 +29,12 @@ | |||||||
|           span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ $t('common:actions.discard') }} |           span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ $t('common:actions.discard') }} | ||||||
|     v-content |     v-content | ||||||
|       component(:is='currentEditor') |       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') |       editor-modal-properties(v-model='dialogProps') | ||||||
|       v-dialog(v-model='dialogEditorSelector', persistent, max-width='700') |       editor-modal-editorselect(v-model='dialogEditorSelector') | ||||||
|         v-card.radius-7(color='blue darken-3', dark) |       editor-modal-unsaved(v-model='dialogUnsaved', @discard='exitGo') | ||||||
|           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. |  | ||||||
|  |  | ||||||
|     loader(v-model='dialogProgress', :title='$t(`editor:save.processing`)', :subtitle='$t(`editor:save.pleaseWait`)') |     loader(v-model='dialogProgress', :title='$t(`editor:save.processing`)', :subtitle='$t(`editor:save.pleaseWait`)') | ||||||
|     v-snackbar( |     v-snackbar( | ||||||
| @@ -132,7 +70,9 @@ export default { | |||||||
|     editorCode: () => import(/* webpackChunkName: "editor-code", webpackMode: "lazy" */ './editor/editor-code.vue'), |     editorCode: () => import(/* webpackChunkName: "editor-code", webpackMode: "lazy" */ './editor/editor-code.vue'), | ||||||
|     editorMarkdown: () => import(/* webpackChunkName: "editor-markdown", webpackMode: "lazy" */ './editor/editor-markdown.vue'), |     editorMarkdown: () => import(/* webpackChunkName: "editor-markdown", webpackMode: "lazy" */ './editor/editor-markdown.vue'), | ||||||
|     editorWysiwyg: () => import(/* webpackChunkName: "editor-wysiwyg", webpackMode: "lazy" */ './editor/editor-wysiwyg.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: { |   props: { | ||||||
|     locale: { |     locale: { | ||||||
| @@ -178,18 +118,29 @@ export default { | |||||||
|   }, |   }, | ||||||
|   data() { |   data() { | ||||||
|     return { |     return { | ||||||
|       currentEditor: '', |  | ||||||
|       dialogProps: false, |       dialogProps: false, | ||||||
|       dialogProgress: false, |       dialogProgress: false, | ||||||
|       dialogEditorSelector: false |       dialogEditorSelector: false, | ||||||
|  |       dialogUnsaved: false, | ||||||
|  |       initContentParsed: '' | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   computed: { |   computed: { | ||||||
|  |     currentEditor: sync('editor/editor'), | ||||||
|     darkMode: get('site/dark'), |     darkMode: get('site/dark'), | ||||||
|     mode: get('editor/mode'), |     mode: get('editor/mode'), | ||||||
|     notification: get('notification'), |     notification: get('notification'), | ||||||
|     notificationState: sync('notification@isActive') |     notificationState: sync('notification@isActive') | ||||||
|   }, |   }, | ||||||
|  |   watch: { | ||||||
|  |     currentEditor(newValue, oldValue) { | ||||||
|  |       if (newValue !== '' && this.mode === 'create') { | ||||||
|  |         _.delay(() => { | ||||||
|  |           this.dialogProps = true | ||||||
|  |         }, 500) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|   created() { |   created() { | ||||||
|     this.$store.commit('page/SET_ID', this.pageId) |     this.$store.commit('page/SET_ID', this.pageId) | ||||||
|     this.$store.commit('page/SET_DESCRIPTION', this.description) |     this.$store.commit('page/SET_DESCRIPTION', this.description) | ||||||
| @@ -203,25 +154,18 @@ export default { | |||||||
|   }, |   }, | ||||||
|   mounted() { |   mounted() { | ||||||
|     this.$store.set('editor/mode', this.initMode || 'create') |     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') { |     if (this.mode === 'create') { | ||||||
|       _.delay(() => { |       _.delay(() => { | ||||||
|         this.dialogEditorSelector = true |         this.dialogEditorSelector = true | ||||||
|       }, 500) |       }, 500) | ||||||
|     } else { |     } else { | ||||||
|       this.selectEditor(this.initEditor || 'markdown') |       this.currentEditor = `editor${_.startCase(this.initEditor || 'markdown')}` | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   methods: { |   methods: { | ||||||
|     selectEditor(name) { |  | ||||||
|       this.currentEditor = `editor${_.startCase(name)}` |  | ||||||
|       this.dialogEditorSelector = false |  | ||||||
|       if (this.mode === 'create') { |  | ||||||
|         _.delay(() => { |  | ||||||
|           this.dialogProps = true |  | ||||||
|         }, 500) |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     openPropsModal(name) { |     openPropsModal(name) { | ||||||
|       this.dialogProps = true |       this.dialogProps = true | ||||||
|     }, |     }, | ||||||
| @@ -310,8 +254,19 @@ export default { | |||||||
|       } |       } | ||||||
|       this.hideProgressDialog() |       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! |   $title: String! | ||||||
|   $description: String! |   $description: String! | ||||||
|   $robots: [String]! |   $robots: [String]! | ||||||
|   $ga: String! |   $analyticsService: String! | ||||||
|  |   $analyticsId: String! | ||||||
|   $company: String! |   $company: String! | ||||||
|   $hasLogo: Boolean! |   $hasLogo: Boolean! | ||||||
|   $logoIsSquare: Boolean! |   $logoIsSquare: Boolean! | ||||||
| @@ -17,7 +18,8 @@ mutation ( | |||||||
|       title: $title, |       title: $title, | ||||||
|       description: $description, |       description: $description, | ||||||
|       robots: $robots, |       robots: $robots, | ||||||
|       ga: $ga, |       analyticsService: $analyticsService, | ||||||
|  |       analyticsId: $analyticsId, | ||||||
|       company: $company, |       company: $company, | ||||||
|       hasLogo: $hasLogo, |       hasLogo: $hasLogo, | ||||||
|       logoIsSquare: $logoIsSquare, |       logoIsSquare: $logoIsSquare, | ||||||
|   | |||||||
| @@ -5,7 +5,8 @@ | |||||||
|       title |       title | ||||||
|       description |       description | ||||||
|       robots |       robots | ||||||
|       ga |       analyticsService | ||||||
|  |       analyticsId | ||||||
|       company |       company | ||||||
|       hasLogo |       hasLogo | ||||||
|       logoIsSquare |       logoIsSquare | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| import { make } from 'vuex-pathify' | import { make } from 'vuex-pathify' | ||||||
|  |  | ||||||
| const state = { | const state = { | ||||||
|  |   editor: '', | ||||||
|   content: '', |   content: '', | ||||||
|   mode: 'create' |   mode: 'create' | ||||||
| } | } | ||||||
|   | |||||||
| @@ -31,7 +31,8 @@ module.exports = { | |||||||
|         WIKI.config.seo = { |         WIKI.config.seo = { | ||||||
|           description: args.description, |           description: args.description, | ||||||
|           robots: args.robots, |           robots: args.robots, | ||||||
|           ga: args.ga |           analyticsService: args.analyticsService, | ||||||
|  |           analyticsId: args.analyticsId | ||||||
|         } |         } | ||||||
|         WIKI.config.logo = { |         WIKI.config.logo = { | ||||||
|           hasLogo: args.hasLogo, |           hasLogo: args.hasLogo, | ||||||
|   | |||||||
| @@ -28,7 +28,8 @@ type SiteMutation { | |||||||
|     title: String! |     title: String! | ||||||
|     description: String! |     description: String! | ||||||
|     robots: [String]! |     robots: [String]! | ||||||
|     ga: String! |     analyticsService: String! | ||||||
|  |     analyticsId: String! | ||||||
|     company: String! |     company: String! | ||||||
|     hasLogo: Boolean! |     hasLogo: Boolean! | ||||||
|     logoIsSquare: Boolean! |     logoIsSquare: Boolean! | ||||||
| @@ -47,7 +48,8 @@ type SiteConfig { | |||||||
|   title: String! |   title: String! | ||||||
|   description: String! |   description: String! | ||||||
|   robots: [String]! |   robots: [String]! | ||||||
|   ga: String! |   analyticsService: String! | ||||||
|  |     analyticsId: String! | ||||||
|   company: String! |   company: String! | ||||||
|   hasLogo: Boolean! |   hasLogo: Boolean! | ||||||
|   logoIsSquare: Boolean! |   logoIsSquare: Boolean! | ||||||
|   | |||||||
| @@ -140,7 +140,8 @@ module.exports = () => { | |||||||
|       _.set(WIKI.config, 'seo', { |       _.set(WIKI.config, 'seo', { | ||||||
|         description: '', |         description: '', | ||||||
|         robots: ['index', 'follow'], |         robots: ['index', 'follow'], | ||||||
|         ga: '' |         analyticsService: '', | ||||||
|  |         analyticsId: '' | ||||||
|       }) |       }) | ||||||
|       _.set(WIKI.config, 'sessionSecret', (await crypto.randomBytesAsync(32)).toString('hex')) |       _.set(WIKI.config, 'sessionSecret', (await crypto.randomBytesAsync(32)).toString('hex')) | ||||||
|       _.set(WIKI.config, 'telemetry', { |       _.set(WIKI.config, 'telemetry', { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user