123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- <template lang='pug'>
- v-card
- v-toolbar(flat, color='primary', dark, dense)
- .subtitle-1 {{ $t('admin:utilities.exportTitle') }}
- v-card-text
- .text-center
- img.animated.fadeInUp.wait-p1s(src='/_assets/svg/icon-big-parcel.svg')
- .body-2 Export to tarball / file system
- v-divider.my-4
- .body-2 What do you want to export?
- v-checkbox(
- v-for='choice of entityChoices'
- :key='choice.key'
- :label='choice.label'
- :value='choice.key'
- color='deep-orange darken-2'
- hide-details
- v-model='entities'
- )
- template(v-slot:label)
- div
- strong.deep-orange--text.text--darken-2 {{choice.label}}
- .text-caption {{choice.hint}}
- v-text-field.mt-7(
- outlined
- label='Target Folder Path'
- hint='Either an absolute path or relative to the Wiki.js installation folder, where exported content will be saved to. Note that the folder MUST be empty!'
- persistent-hint
- v-model='filePath'
- )
- v-alert.mt-3(color='deep-orange', outlined, icon='mdi-alert', prominent)
- .body-2 Depending on your selection, the archive could contain sensitive data such as site configuration keys and hashed user passwords. Ensure the exported archive is treated accordingly.
- .body-2 For example, you may want to encrypt the archive if stored for backup purposes.
- v-card-chin
- v-btn.px-3(depressed, color='deep-orange darken-2', :disabled='entities.length < 1', @click='startExport').ml-0
- v-icon(left, color='white') mdi-database-export
- span.white--text Start Export
- v-dialog(
- v-model='isLoading'
- persistent
- max-width='350'
- )
- v-card(color='deep-orange darken-2', dark)
- v-card-text.pa-10.text-center
- self-building-square-spinner.animated.fadeIn(
- :animation-duration='4500'
- :size='40'
- color='#FFF'
- style='margin: 0 auto;'
- )
- .mt-5.body-1.white--text Exporting...
- .caption Please wait, this may take a while
- v-progress-linear.mt-5(
- color='white'
- :value='progress'
- stream
- rounded
- :buffer-value='0'
- )
- v-dialog(
- v-model='isSuccess'
- persistent
- max-width='350'
- )
- v-card(color='green darken-2', dark)
- v-card-text.pa-10.text-center
- v-icon(size='60') mdi-check-circle-outline
- .my-5.body-1.white--text Export completed
- v-card-actions.green.darken-1
- v-spacer
- v-btn.px-5(
- color='white'
- outlined
- @click='isSuccess = false'
- ) Close
- v-spacer
- v-dialog(
- v-model='isFailed'
- persistent
- max-width='800'
- )
- v-card(color='red darken-2', dark)
- v-toolbar(color='red darken-2', dense)
- v-icon mdi-alert
- .body-2.pl-3 Export failed
- v-spacer
- v-btn.px-5(
- color='white'
- text
- @click='isFailed = false'
- ) Close
- v-card-text.pa-5.red.darken-4.white--text
- span {{errorMessage}}
- </template>
- <script>
- import { SelfBuildingSquareSpinner } from 'epic-spinners'
- import gql from 'graphql-tag'
- import _get from 'lodash/get'
- export default {
- components: {
- SelfBuildingSquareSpinner
- },
- data() {
- return {
- entities: [],
- filePath: './data/export',
- isLoading: false,
- isSuccess: false,
- isFailed: false,
- errorMessage: '',
- progress: 0
- }
- },
- computed: {
- entityChoices () {
- return [
- {
- key: 'assets',
- label: 'Assets',
- hint: 'Media files such as images, documents, etc.'
- },
- {
- key: 'comments',
- label: 'Comments',
- hint: 'Comments made using the default comment module only.'
- },
- {
- key: 'navigation',
- label: 'Navigation',
- hint: 'Sidebar links when using Static or Custom Navigation.'
- },
- {
- key: 'pages',
- label: 'Pages',
- hint: 'Page content, tags and related metadata.'
- },
- {
- key: 'history',
- label: 'Pages History',
- hint: 'All previous versions of pages and their related metadata.'
- },
- {
- key: 'settings',
- label: 'Settings',
- hint: 'Site configuration and modules settings.'
- },
- {
- key: 'groups',
- label: 'User Groups',
- hint: 'Group permissions and page rules.'
- },
- {
- key: 'users',
- label: 'Users',
- hint: 'Users metadata and their group memberships.'
- }
- ]
- }
- },
- methods: {
- async checkProgress () {
- try {
- const respStatus = await this.$apollo.query({
- query: gql`
- {
- system {
- exportStatus {
- status
- progress
- message
- startedAt
- }
- }
- }
- `,
- fetchPolicy: 'network-only'
- })
- const respStatusObj = _get(respStatus, 'data.system.exportStatus', {})
- if (!respStatusObj) {
- throw new Error('An unexpected error occured.')
- } else {
- switch (respStatusObj.status) {
- case 'error': {
- throw new Error(respStatusObj.message || 'An unexpected error occured.')
- }
- case 'running': {
- this.progress = respStatusObj.progress || 0
- window.requestAnimationFrame(() => {
- setTimeout(() => {
- this.checkProgress()
- }, 5000)
- })
- break
- }
- case 'success': {
- this.isLoading = false
- this.isSuccess = true
- break
- }
- default: {
- throw new Error('Invalid export status.')
- }
- }
- }
- } catch (err) {
- this.errorMessage = err.message
- this.isLoading = false
- this.isFailed = true
- }
- },
- async startExport () {
- this.isFailed = false
- this.isSuccess = false
- this.isLoading = true
- this.progress = 0
- setTimeout(async () => {
- try {
- // -> Initiate export
- const respExport = await this.$apollo.mutate({
- mutation: gql`
- mutation (
- $entities: [String]!
- $path: String!
- ) {
- system {
- export (
- entities: $entities
- path: $path
- ) {
- responseResult {
- succeeded
- message
- }
- }
- }
- }
- `,
- variables: {
- entities: this.entities,
- path: this.filePath
- }
- })
- const respExportObj = _get(respExport, 'data.system.export', {})
- if (!_get(respExportObj, 'responseResult.succeeded', false)) {
- this.errorMessage = _get(respExportObj, 'responseResult.message', 'An unexpected error occurred')
- this.isLoading = false
- this.isFailed = true
- return
- }
- // -> Check for progress
- this.checkProgress()
- } catch (err) {
- this.$store.commit('pushGraphError', err)
- this.isLoading = false
- }
- }, 1500)
- }
- }
- }
- </script>
- <style lang='scss'>
- </style>
|