| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 | <template lang='pug'>  v-card    v-toolbar(flat, color='primary', dark, dense)      .subtitle-1 {{ $t('admin:utilities.contentTitle') }}    v-card-text      .subtitle-1.pb-3.primary--text Rebuild Page Tree      .body-2 The virtual structure of your wiki is automatically inferred from all page paths. You can trigger a full rebuild of the tree if some virtual folders are missing or not valid anymore.      v-btn(outlined, color='primary', @click='rebuildTree', :disabled='loading').ml-0.mt-3        v-icon(left) mdi-gesture-double-tap        span Proceed      v-divider.my-5      .subtitle-1.pb-3.primary--text Rerender All Pages      .body-2 All pages will be rendered again. Useful if internal links are broken or the rendering pipeline has changed.      v-btn(outlined, color='primary', @click='rerenderPages', :disabled='loading', :loading='isRerendering').ml-0.mt-3        v-icon(left) mdi-gesture-double-tap        span Proceed      v-dialog(        v-model='isRerendering'        persistent        max-width='450'        )        v-card(color='blue darken-2', dark)          v-card-text.pa-10.text-center            semipolar-spinner.animated.fadeIn(              :animation-duration='1500'              :size='65'              color='#FFF'              style='margin: 0 auto;'            )            .mt-5.body-1.white--text Rendering all pages...            .caption(v-if='renderIndex > 0') Rendering {{renderCurrentPath}}... ({{renderIndex}}/{{renderTotal}}, {{renderProgress}}%)            .caption.mt-4 Do not leave this page.            v-progress-linear.mt-5(              color='white'              :value='renderProgress'              stream              rounded              :buffer-value='0'            )      v-divider.my-5      .subtitle-1.pb-3.pl-0.primary--text Migrate all pages to target locale      .body-2 If you created content before selecting a different locale and activating the namespacing capabilities, you may want to transfer all content to the base locale.      .body-2.red--text: strong This operation is destructive and cannot be reversed! Make sure you have proper backups!      v-toolbar.radius-7.mt-5(flat, :color='$vuetify.theme.dark ? `grey darken-3-d5` : `grey lighten-4`', height='80')        v-select(          label='Source Locale'          outlined          hide-details          :items='locales'          item-text='name'          item-value='code'          v-model='sourceLocale'        )        v-icon.mx-3(large) mdi-chevron-right-box-outline        v-select(          label='Target Locale'          outlined          hide-details          :items='locales'          item-text='name'          item-value='code'          v-model='targetLocale'        )      .body-2.mt-5 Pages that are already in the target locale will not be touched. If a page already exists at the target, the source page will not be modified as it would create a conflict. If you want to overwrite the target page, you must first delete it.      v-btn(outlined, color='primary', @click='migrateToLocale', :disabled='loading').ml-0.mt-3        v-icon(left) mdi-gesture-double-tap        span Proceed      v-divider.my-5      .subtitle-1.pb-3.pl-0.primary--text Purge Page History      .body-2 You may want to purge old history for pages to reduce database usage.      .body-2 This operation only affects the database and not any history saved by a storage module (e.g. git version history)      v-toolbar.radius-7.mt-5(flat, :color='$vuetify.theme.dark ? `grey darken-3-d5` : `grey lighten-4`', height='80')        v-select(          label='Delete history older than...'          outlined          hide-details          :items='purgeHistoryOptions'          item-text='title'          item-value='key'          v-model='purgeHistorySelection'        )      v-btn(outlined, color='primary', @click='purgeHistory', :disabled='loading').ml-0.mt-3        v-icon(left) mdi-gesture-double-tap        span Proceed</template><script>import _ from 'lodash'import gql from 'graphql-tag'import utilityContentMigrateLocaleMutation from 'gql/admin/utilities/utilities-mutation-content-migratelocale.gql'import utilityContentRebuildTreeMutation from 'gql/admin/utilities/utilities-mutation-content-rebuildtree.gql'import { SemipolarSpinner } from 'epic-spinners'/* global siteLangs, siteConfig */export default {  components: {    SemipolarSpinner  },  data: () => {    return {      isRerendering: false,      loading: false,      renderProgress: 0,      renderIndex: 0,      renderTotal: 0,      renderCurrentPath: '',      sourceLocale: '',      targetLocale: '',      purgeHistorySelection: 'P1Y',      purgeHistoryOptions: [        { key: 'P1D', title: 'Today' },        { key: 'P1M', title: '1 month' },        { key: 'P3M', title: '3 months' },        { key: 'P6M', title: '6 months' },        { key: 'P1Y', title: '1 year' },        { key: 'P2Y', title: '2 years' },        { key: 'P3Y', title: '3 years' },        { key: 'P5Y', title: '5 years' }      ]    }  },  computed: {    currentLocale () {      return siteConfig.lang    },    locales () {      return siteLangs    }  },  methods: {    async rebuildTree () {      this.loading = true      this.$store.commit(`loadingStart`, 'admin-utilities-content-rebuildtree')      try {        const respRaw = await this.$apollo.mutate({          mutation: utilityContentRebuildTreeMutation        })        const resp = _.get(respRaw, 'data.pages.rebuildTree.responseResult', {})        if (resp.succeeded) {          this.$store.commit('showNotification', {            message: 'Page Tree rebuilt successfully.',            style: 'success',            icon: 'check'          })        } else {          throw new Error(resp.message)        }      } catch (err) {        this.$store.commit('pushGraphError', err)      }      this.$store.commit(`loadingStop`, 'admin-utilities-content-rebuildtree')      this.loading = false    },    async rerenderPages () {      this.loading = true      this.isRerendering = true      this.$store.commit(`loadingStart`, 'admin-utilities-content-rerender')      try {        const pagesRaw = await this.$apollo.query({          query: gql`            {              pages {                list {                  id                  path                  locale                }              }            }          `,          fetchPolicy: 'network-only'        })        if (_.get(pagesRaw, 'data.pages.list', []).length < 1) {          throw new Error('Could not find any page to render!')        }        this.renderIndex = 0        this.renderTotal = pagesRaw.data.pages.list.length        let failed = 0        for (const page of pagesRaw.data.pages.list) {          this.renderCurrentPath = `${page.locale}/${page.path}`          this.renderIndex++          this.renderProgress = Math.round(this.renderIndex / this.renderTotal * 100)          const respRaw = await this.$apollo.mutate({            mutation: gql`              mutation($id: Int!) {                pages {                  render(id: $id) {                    responseResult {                      succeeded                      errorCode                      slug                      message                    }                  }                }              }            `,            variables: {              id: page.id            }          })          const resp = _.get(respRaw, 'data.pages.render.responseResult', {})          if (!resp.succeeded) {            failed++          }        }        if (failed > 0) {          this.$store.commit('showNotification', {            message: `Completed with ${failed} pages that failed to render. Check server logs for details.`,            style: 'error',            icon: 'alert'          })        } else {          this.$store.commit('showNotification', {            message: 'All pages have been rendered successfully.',            style: 'success',            icon: 'check'          })        }      } catch (err) {        this.$store.commit('pushGraphError', err)      }      this.$store.commit(`loadingStop`, 'admin-utilities-content-rerender')      this.isRerendering = false      this.loading = false    },    async migrateToLocale () {      this.loading = true      this.$store.commit(`loadingStart`, 'admin-utilities-content-migratelocale')      try {        const respRaw = await this.$apollo.mutate({          mutation: utilityContentMigrateLocaleMutation,          variables: {            sourceLocale: this.sourceLocale,            targetLocale: this.targetLocale          }        })        const resp = _.get(respRaw, 'data.pages.migrateToLocale.responseResult', {})        if (resp.succeeded) {          this.$store.commit('showNotification', {            message: `Migrated ${_.get(respRaw, 'data.pages.migrateToLocale.count', 0)} page(s) to target locale successfully.`,            style: 'success',            icon: 'check'          })        } else {          throw new Error(resp.message)        }      } catch (err) {        this.$store.commit('pushGraphError', err)      }      this.$store.commit(`loadingStop`, 'admin-utilities-content-migratelocale')      this.loading = false    },    async purgeHistory () {      this.loading = true      this.$store.commit(`loadingStart`, 'admin-utilities-content-purgehistory')      try {        const respRaw = await this.$apollo.mutate({          mutation: gql`            mutation ($olderThan: String!) {              pages {                purgeHistory (                  olderThan: $olderThan                ) {                  responseResult {                    errorCode                    message                    slug                    succeeded                  }                }              }            }          `,          variables: {            olderThan: this.purgeHistorySelection          }        })        const resp = _.get(respRaw, 'data.pages.purgeHistory.responseResult', {})        if (resp.succeeded) {          this.$store.commit('showNotification', {            message: `Purged history successfully.`,            style: 'success',            icon: 'check'          })        } else {          throw new Error(resp.message)        }      } catch (err) {        this.$store.commit('pushGraphError', err)      }      this.$store.commit(`loadingStop`, 'admin-utilities-content-purgehistory')      this.loading = false    }  }}</script><style lang='scss'></style>
 |