| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 | <template lang="pug">  v-app.editor(:dark='darkMode')    nav-header(dense)      template(slot='mid')        v-spacer        .subheading.grey--text {{currentPageTitle}}        v-spacer      template(slot='actions')        v-btn.animated.fadeInDown(          flat          color='green'          @click.native.stop='save'          :class='{ "is-icon": $vuetify.breakpoint.mdAndDown }'          )          v-icon(color='green', :left='$vuetify.breakpoint.lgAndUp') check          span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ mode === 'create' ? $t('common:actions.create') : $t('common:actions.save') }}        v-btn.animated.fadeInDown.wait-p1s(          flat          color='blue'          @click.native.stop='openPropsModal'          :class='{ "is-icon": $vuetify.breakpoint.mdAndDown, "mx-0": !welcomeMode, "ml-0": welcomeMode }'          )          v-icon(color='blue', :left='$vuetify.breakpoint.lgAndUp') sort_by_alpha          span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ $t('common:actions.page') }}        v-btn.animated.fadeInDown.wait-p2s(          v-if='!welcomeMode'          flat          color='red'          :class='{ "is-icon": $vuetify.breakpoint.mdAndDown }'          @click.native.stop='exit'          )          v-icon(color='red', :left='$vuetify.breakpoint.lgAndUp') close          span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ $t('common:actions.close') }}    v-content      component(:is='currentEditor', :save='save')      editor-modal-properties(v-model='dialogProps')      editor-modal-editorselect(v-model='dialogEditorSelector')      editor-modal-unsaved(v-model='dialogUnsaved', @discard='exitGo')      component(:is='activeModal')    loader(v-model='dialogProgress', :title='$t(`editor:save.processing`)', :subtitle='$t(`editor:save.pleaseWait`)')    notify</template><script>import _ from 'lodash'import { get, sync } from 'vuex-pathify'import { AtomSpinner } from 'epic-spinners'import { Base64 } from 'js-base64'import createPageMutation from 'gql/editor/create.gql'import updatePageMutation from 'gql/editor/update.gql'import editorStore from '@/store/editor'/* global WIKI */WIKI.$store.registerModule('editor', editorStore)export default {  i18nOptions: { namespaces: 'editor' },  components: {    AtomSpinner,    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'),    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'),    editorModalMedia: () => import(/* webpackChunkName: "editor", webpackMode: "eager" */ './editor/editor-modal-media.vue'),    editorModalBlocks: () => import(/* webpackChunkName: "editor", webpackMode: "eager" */ './editor/editor-modal-blocks.vue')  },  props: {    locale: {      type: String,      default: 'en'    },    path: {      type: String,      default: 'home'    },    title: {      type: String,      default: 'Untitled Page'    },    description: {      type: String,      default: ''    },    tags: {      type: Array,      default: () => ([])    },    isPublished: {      type: Boolean,      default: true    },    initEditor: {      type: String,      default: null    },    initMode: {      type: String,      default: 'create'    },    initContent: {      type: String,      default: null    },    pageId: {      type: Number,      default: 0    }  },  data() {    return {      dialogProps: false,      dialogProgress: false,      dialogEditorSelector: false,      dialogUnsaved: false,      exitConfirmed: false,      initContentParsed: ''    }  },  computed: {    currentEditor: sync('editor/editor'),    darkMode: get('site/dark'),    activeModal: sync('editor/activeModal'),    mode: get('editor/mode'),    welcomeMode() { return this.mode === `create` && this.path === `home` },    currentPageTitle: get('page/title')  },  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)    this.$store.commit('page/SET_IS_PUBLISHED', this.isPublished)    this.$store.commit('page/SET_LOCALE', this.locale)    this.$store.commit('page/SET_PATH', this.path)    this.$store.commit('page/SET_TAGS', this.tags)    this.$store.commit('page/SET_TITLE', this.title)    this.$store.commit('page/SET_MODE', 'edit')  },  mounted() {    this.$store.set('editor/mode', this.initMode || 'create')    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.currentEditor = `editor${_.startCase(this.initEditor || 'markdown')}`    }    window.onbeforeunload = () => {      if (!this.exitConfirmed && this.initContentParsed !== this.$store.get('editor/content')) {        return 'You have unsaved edits. Are you sure you want to leave the editor?'      } else {        return undefined      }    }  },  methods: {    openPropsModal(name) {      this.dialogProps = true    },    showProgressDialog(textKey) {      this.dialogProgress = true    },    hideProgressDialog() {      this.dialogProgress = false    },    async save() {      this.showProgressDialog('saving')      try {        if (this.$store.get('editor/mode') === 'create') {          // --------------------------------------------          // -> CREATE PAGE          // --------------------------------------------          let resp = await this.$apollo.mutate({            mutation: createPageMutation,            variables: {              content: this.$store.get('editor/content'),              description: this.$store.get('page/description'),              editor: 'markdown',              locale: this.$store.get('page/locale'),              isPrivate: false,              isPublished: this.$store.get('page/isPublished'),              path: this.$store.get('page/path'),              publishEndDate: this.$store.get('page/publishEndDate') || '',              publishStartDate: this.$store.get('page/publishStartDate') || '',              tags: this.$store.get('page/tags'),              title: this.$store.get('page/title')            }          })          resp = _.get(resp, 'data.pages.create', {})          if (_.get(resp, 'responseResult.succeeded')) {            this.$store.commit('showNotification', {              message: this.$t('editor:save.createSuccess'),              style: 'success',              icon: 'check'            })            this.$store.set('editor/id', _.get(resp, 'page.id'))            this.$store.set('editor/mode', 'update')            window.location.assign(`/${this.$store.get('page/locale')}/${this.$store.get('page/path')}`)          } else {            throw new Error(_.get(resp, 'responseResult.message'))          }        } else {          // --------------------------------------------          // -> UPDATE EXISTING PAGE          // --------------------------------------------          let resp = await this.$apollo.mutate({            mutation: updatePageMutation,            variables: {              id: this.$store.get('page/id'),              content: this.$store.get('editor/content'),              description: this.$store.get('page/description'),              editor: 'markdown',              locale: this.$store.get('page/locale'),              isPrivate: false,              isPublished: this.$store.get('page/isPublished'),              path: this.$store.get('page/path'),              publishEndDate: this.$store.get('page/publishEndDate') || '',              publishStartDate: this.$store.get('page/publishStartDate') || '',              tags: this.$store.get('page/tags'),              title: this.$store.get('page/title')            }          })          resp = _.get(resp, 'data.pages.update', {})          if (_.get(resp, 'responseResult.succeeded')) {            this.$store.commit('showNotification', {              message: this.$t('editor:save.updateSuccess'),              style: 'success',              icon: 'check'            })          } else {            throw new Error(_.get(resp, 'responseResult.message'))          }        }        this.initContentParsed = this.$store.get('editor/content')      } catch (err) {        this.$store.commit('showNotification', {          message: err.message,          style: 'error',          icon: 'warning'        })      }      this.hideProgressDialog()    },    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 = ''      this.exitConfirmed = true      _.delay(() => {        if (this.$store.get('editor/mode') === 'create') {          window.location.assign(`/`)        } else {          window.location.assign(`/${this.$store.get('page/locale')}/${this.$store.get('page/path')}`)        }      }, 500)    }  }}</script><style lang='scss'>  .editor {    background-color: mc('grey', '900') !important;    min-height: 100vh;    .application--wrap {      background-color: mc('grey', '900');    }  }  .atom-spinner.is-inline {    display: inline-block;  }</style>
 |