admin-utilities-content.vue 10.5 KB
Newer Older
1 2 3
<template lang='pug'>
  v-card
    v-toolbar(flat, color='primary', dark, dense)
4
      .subtitle-1 {{ $t('admin:utilities.contentTitle') }}
5
    v-card-text
NGPixel's avatar
NGPixel committed
6 7 8 9 10
      .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
NGPixel's avatar
NGPixel committed
11

NGPixel's avatar
NGPixel committed
12
      v-divider.my-5
NGPixel's avatar
NGPixel committed
13

14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
      .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'
            )
NGPixel's avatar
NGPixel committed
42

43
      v-divider.my-5
NGPixel's avatar
NGPixel committed
44

45 46 47
      .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!
48
      v-toolbar.radius-7.mt-5(flat, :color='$vuetify.theme.dark ? `grey darken-3-d5` : `grey lighten-4`', height='80')
Nick's avatar
Nick committed
49 50
        v-select(
          label='Source Locale'
51
          outlined
Nick's avatar
Nick committed
52 53 54 55 56 57
          hide-details
          :items='locales'
          item-text='name'
          item-value='code'
          v-model='sourceLocale'
        )
58
        v-icon.mx-3(large) mdi-chevron-right-box-outline
Nick's avatar
Nick committed
59 60
        v-select(
          label='Target Locale'
61
          outlined
Nick's avatar
Nick committed
62 63 64 65 66 67
          hide-details
          :items='locales'
          item-text='name'
          item-value='code'
          v-model='targetLocale'
        )
68 69 70
      .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
71
        span Proceed
NGPixel's avatar
NGPixel committed
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90

      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
91 92 93 94
</template>

<script>
import _ from 'lodash'
95
import gql from 'graphql-tag'
96
import utilityContentMigrateLocaleMutation from 'gql/admin/utilities/utilities-mutation-content-migratelocale.gql'
NGPixel's avatar
NGPixel committed
97
import utilityContentRebuildTreeMutation from 'gql/admin/utilities/utilities-mutation-content-rebuildtree.gql'
98

99 100
import { SemipolarSpinner } from 'epic-spinners'

Nick's avatar
Nick committed
101
/* global siteLangs, siteConfig */
102 103

export default {
104 105 106
  components: {
    SemipolarSpinner
  },
107 108
  data: () => {
    return {
109
      isRerendering: false,
Nick's avatar
Nick committed
110
      loading: false,
111 112 113 114
      renderProgress: 0,
      renderIndex: 0,
      renderTotal: 0,
      renderCurrentPath: '',
Nick's avatar
Nick committed
115
      sourceLocale: '',
NGPixel's avatar
NGPixel committed
116 117 118 119 120 121 122 123 124 125 126 127
      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' }
      ]
128 129 130
    }
  },
  computed: {
Nick's avatar
Nick committed
131
    currentLocale () {
132
      return siteConfig.lang
Nick's avatar
Nick committed
133 134 135
    },
    locales () {
      return siteLangs
136 137 138
    }
  },
  methods: {
NGPixel's avatar
NGPixel committed
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
    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
    },
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
    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
    },
NGPixel's avatar
NGPixel committed
240
    async migrateToLocale () {
241 242 243 244 245 246 247
      this.loading = true
      this.$store.commit(`loadingStart`, 'admin-utilities-content-migratelocale')

      try {
        const respRaw = await this.$apollo.mutate({
          mutation: utilityContentMigrateLocaleMutation,
          variables: {
Nick's avatar
Nick committed
248 249
            sourceLocale: this.sourceLocale,
            targetLocale: this.targetLocale
250 251 252 253 254
          }
        })
        const resp = _.get(respRaw, 'data.pages.migrateToLocale.responseResult', {})
        if (resp.succeeded) {
          this.$store.commit('showNotification', {
255
            message: `Migrated ${_.get(respRaw, 'data.pages.migrateToLocale.count', 0)} page(s) to target locale successfully.`,
256 257 258 259 260 261 262 263 264 265 266 267
            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
NGPixel's avatar
NGPixel committed
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
    },
    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
311 312 313 314 315 316 317 318
    }
  }
}
</script>

<style lang='scss'>

</style>