Merge branch 'settings-import-export' into 'develop'
Settings backup/restore + small fixes See merge request pleroma/pleroma-fe!1372
This commit is contained in:
commit
8b96ea9377
14 changed files with 396 additions and 194 deletions
|
@ -2,10 +2,55 @@ import Modal from 'src/components/modal/modal.vue'
|
|||
import PanelLoading from 'src/components/panel_loading/panel_loading.vue'
|
||||
import AsyncComponentError from 'src/components/async_component_error/async_component_error.vue'
|
||||
import getResettableAsyncComponent from 'src/services/resettable_async_component.js'
|
||||
import Popover from '../popover/popover.vue'
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import { cloneDeep } from 'lodash'
|
||||
import {
|
||||
newImporter,
|
||||
newExporter
|
||||
} from 'src/services/export_import/export_import.js'
|
||||
import {
|
||||
faTimes,
|
||||
faFileUpload,
|
||||
faFileDownload,
|
||||
faChevronDown
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
import {
|
||||
faWindowMinimize
|
||||
} from '@fortawesome/free-regular-svg-icons'
|
||||
|
||||
const PLEROMAFE_SETTINGS_MAJOR_VERSION = 1
|
||||
const PLEROMAFE_SETTINGS_MINOR_VERSION = 0
|
||||
|
||||
library.add(
|
||||
faTimes,
|
||||
faWindowMinimize,
|
||||
faFileUpload,
|
||||
faFileDownload,
|
||||
faChevronDown
|
||||
)
|
||||
|
||||
const SettingsModal = {
|
||||
data () {
|
||||
return {
|
||||
dataImporter: newImporter({
|
||||
validator: this.importValidator,
|
||||
onImport: this.onImport,
|
||||
onImportFailure: this.onImportFailure
|
||||
}),
|
||||
dataThemeExporter: newExporter({
|
||||
filename: 'pleromafe_settings.full',
|
||||
getExportedObject: () => this.generateExport(true)
|
||||
}),
|
||||
dataExporter: newExporter({
|
||||
filename: 'pleromafe_settings',
|
||||
getExportedObject: () => this.generateExport()
|
||||
})
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Modal,
|
||||
Popover,
|
||||
SettingsModalContent: getResettableAsyncComponent(
|
||||
() => import('./settings_modal_content.vue'),
|
||||
{
|
||||
|
@ -21,6 +66,85 @@ const SettingsModal = {
|
|||
},
|
||||
peekModal () {
|
||||
this.$store.dispatch('togglePeekSettingsModal')
|
||||
},
|
||||
importValidator (data) {
|
||||
if (!Array.isArray(data._pleroma_settings_version)) {
|
||||
return {
|
||||
messageKey: 'settings.file_import_export.invalid_file'
|
||||
}
|
||||
}
|
||||
|
||||
const [major, minor] = data._pleroma_settings_version
|
||||
|
||||
if (major > PLEROMAFE_SETTINGS_MAJOR_VERSION) {
|
||||
return {
|
||||
messageKey: 'settings.file_export_import.errors.file_too_new',
|
||||
messageArgs: {
|
||||
fileMajor: major,
|
||||
feMajor: PLEROMAFE_SETTINGS_MAJOR_VERSION
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (major < PLEROMAFE_SETTINGS_MAJOR_VERSION) {
|
||||
return {
|
||||
messageKey: 'settings.file_export_import.errors.file_too_old',
|
||||
messageArgs: {
|
||||
fileMajor: major,
|
||||
feMajor: PLEROMAFE_SETTINGS_MAJOR_VERSION
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (minor > PLEROMAFE_SETTINGS_MINOR_VERSION) {
|
||||
this.$store.dispatch('pushGlobalNotice', {
|
||||
level: 'warning',
|
||||
messageKey: 'settings.file_export_import.errors.file_slightly_new'
|
||||
})
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
onImportFailure (result) {
|
||||
if (result.error) {
|
||||
this.$store.dispatch('pushGlobalNotice', { messageKey: 'settings.invalid_settings_imported', level: 'error' })
|
||||
} else {
|
||||
this.$store.dispatch('pushGlobalNotice', { ...result.validationResult, level: 'error' })
|
||||
}
|
||||
},
|
||||
onImport (data) {
|
||||
if (data) { this.$store.dispatch('loadSettings', data) }
|
||||
},
|
||||
restore () {
|
||||
this.dataImporter.importData()
|
||||
},
|
||||
backup () {
|
||||
this.dataExporter.exportData()
|
||||
},
|
||||
backupWithTheme () {
|
||||
this.dataThemeExporter.exportData()
|
||||
},
|
||||
generateExport (theme = false) {
|
||||
const { config } = this.$store.state
|
||||
let sample = config
|
||||
if (!theme) {
|
||||
const ignoreList = new Set([
|
||||
'customTheme',
|
||||
'customThemeSource',
|
||||
'colors'
|
||||
])
|
||||
sample = Object.fromEntries(
|
||||
Object
|
||||
.entries(sample)
|
||||
.filter(([key]) => !ignoreList.has(key))
|
||||
)
|
||||
}
|
||||
const clone = cloneDeep(sample)
|
||||
clone._pleroma_settings_version = [
|
||||
PLEROMAFE_SETTINGS_MAJOR_VERSION,
|
||||
PLEROMAFE_SETTINGS_MINOR_VERSION
|
||||
]
|
||||
return clone
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
|
|
@ -31,20 +31,86 @@
|
|||
</transition>
|
||||
<button
|
||||
class="btn button-default"
|
||||
:title="$t('general.peek')"
|
||||
@click="peekModal"
|
||||
>
|
||||
{{ $t('general.peek') }}
|
||||
<FAIcon
|
||||
:icon="['far', 'window-minimize']"
|
||||
fixed-width
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
class="btn button-default"
|
||||
:title="$t('general.close')"
|
||||
@click="closeModal"
|
||||
>
|
||||
{{ $t('general.close') }}
|
||||
<FAIcon
|
||||
icon="times"
|
||||
fixed-width
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<SettingsModalContent v-if="modalOpenedOnce" />
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
<Popover
|
||||
class="export"
|
||||
trigger="click"
|
||||
placement="top"
|
||||
:offset="{ y: 5, x: 5 }"
|
||||
:bound-to="{ x: 'container' }"
|
||||
remove-padding
|
||||
>
|
||||
<button
|
||||
slot="trigger"
|
||||
class="btn button-default"
|
||||
:title="$t('general.close')"
|
||||
>
|
||||
<span>{{ $t("settings.file_export_import.backup_restore") }}</span>
|
||||
<FAIcon
|
||||
icon="chevron-down"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
slot="content"
|
||||
slot-scope="{close}"
|
||||
>
|
||||
<div class="dropdown-menu">
|
||||
<button
|
||||
class="button-default dropdown-item dropdown-item-icon"
|
||||
@click.prevent="backup"
|
||||
@click="close"
|
||||
>
|
||||
<FAIcon
|
||||
icon="file-download"
|
||||
fixed-width
|
||||
/><span>{{ $t("settings.file_export_import.backup_settings") }}</span>
|
||||
</button>
|
||||
<button
|
||||
class="button-default dropdown-item dropdown-item-icon"
|
||||
@click.prevent="backupWithTheme"
|
||||
@click="close"
|
||||
>
|
||||
<FAIcon
|
||||
icon="file-download"
|
||||
fixed-width
|
||||
/><span>{{ $t("settings.file_export_import.backup_settings_theme") }}</span>
|
||||
</button>
|
||||
<button
|
||||
class="button-default dropdown-item dropdown-item-icon"
|
||||
@click.prevent="restore"
|
||||
@click="close"
|
||||
>
|
||||
<FAIcon
|
||||
icon="file-upload"
|
||||
fixed-width
|
||||
/><span>{{ $t("settings.file_export_import.restore_settings") }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
|
|
|
@ -15,6 +15,10 @@ import {
|
|||
shadows2to3,
|
||||
colors2to3
|
||||
} from 'src/services/style_setter/style_setter.js'
|
||||
import {
|
||||
newImporter,
|
||||
newExporter
|
||||
} from 'src/services/export_import/export_import.js'
|
||||
import {
|
||||
SLOT_INHERITANCE
|
||||
} from 'src/services/theme_data/pleromafe.js'
|
||||
|
@ -31,7 +35,6 @@ import ShadowControl from 'src/components/shadow_control/shadow_control.vue'
|
|||
import FontControl from 'src/components/font_control/font_control.vue'
|
||||
import ContrastRatio from 'src/components/contrast_ratio/contrast_ratio.vue'
|
||||
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.js'
|
||||
import ExportImport from 'src/components/export_import/export_import.vue'
|
||||
import Checkbox from 'src/components/checkbox/checkbox.vue'
|
||||
|
||||
import Preview from './preview.vue'
|
||||
|
@ -67,6 +70,15 @@ const colorConvert = (color) => {
|
|||
export default {
|
||||
data () {
|
||||
return {
|
||||
themeImporter: newImporter({
|
||||
validator: this.importValidator,
|
||||
onImport: this.onImport,
|
||||
onImportFailure: this.onImportFailure
|
||||
}),
|
||||
themeExporter: newExporter({
|
||||
filename: 'pleroma_theme',
|
||||
getExportedObject: () => this.exportedTheme
|
||||
}),
|
||||
availableStyles: [],
|
||||
selected: this.$store.getters.mergedConfig.theme,
|
||||
themeWarning: undefined,
|
||||
|
@ -383,7 +395,6 @@ export default {
|
|||
FontControl,
|
||||
TabSwitcher,
|
||||
Preview,
|
||||
ExportImport,
|
||||
Checkbox
|
||||
},
|
||||
methods: {
|
||||
|
@ -528,10 +539,15 @@ export default {
|
|||
this.previewColors.mod
|
||||
)
|
||||
},
|
||||
importTheme () { this.themeImporter.importData() },
|
||||
exportTheme () { this.themeExporter.exportData() },
|
||||
onImport (parsed, forceSource = false) {
|
||||
this.tempImportFile = parsed
|
||||
this.loadTheme(parsed, 'file', forceSource)
|
||||
},
|
||||
onImportFailure (result) {
|
||||
this.$store.dispatch('pushGlobalNotice', { messageKey: 'settings.invalid_theme_imported', level: 'error' })
|
||||
},
|
||||
importValidator (parsed) {
|
||||
const version = parsed._pleroma_theme_version
|
||||
return version >= 1 || version <= 2
|
||||
|
|
|
@ -48,46 +48,51 @@
|
|||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<ExportImport
|
||||
:export-object="exportedTheme"
|
||||
:export-label="$t("settings.export_theme")"
|
||||
:import-label="$t("settings.import_theme")"
|
||||
:import-failed-text="$t("settings.invalid_theme_imported")"
|
||||
:on-import="onImport"
|
||||
:validator="importValidator"
|
||||
>
|
||||
<template slot="before">
|
||||
<div class="presets">
|
||||
{{ $t('settings.presets') }}
|
||||
<label
|
||||
for="preset-switcher"
|
||||
class="select"
|
||||
<div class="top">
|
||||
<div class="presets">
|
||||
{{ $t('settings.presets') }}
|
||||
<label
|
||||
for="preset-switcher"
|
||||
class="select"
|
||||
>
|
||||
<select
|
||||
id="preset-switcher"
|
||||
v-model="selected"
|
||||
class="preset-switcher"
|
||||
>
|
||||
<select
|
||||
id="preset-switcher"
|
||||
v-model="selected"
|
||||
class="preset-switcher"
|
||||
<option
|
||||
v-for="style in availableStyles"
|
||||
:key="style.name"
|
||||
:value="style"
|
||||
:style="{
|
||||
backgroundColor: style[1] || (style.theme || style.source).colors.bg,
|
||||
color: style[3] || (style.theme || style.source).colors.text
|
||||
}"
|
||||
>
|
||||
<option
|
||||
v-for="style in availableStyles"
|
||||
:key="style.name"
|
||||
:value="style"
|
||||
:style="{
|
||||
backgroundColor: style[1] || (style.theme || style.source).colors.bg,
|
||||
color: style[3] || (style.theme || style.source).colors.text
|
||||
}"
|
||||
>
|
||||
{{ style[0] || style.name }}
|
||||
</option>
|
||||
</select>
|
||||
<FAIcon
|
||||
class="select-down-icon"
|
||||
icon="chevron-down"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
</ExportImport>
|
||||
{{ style[0] || style.name }}
|
||||
</option>
|
||||
</select>
|
||||
<FAIcon
|
||||
class="select-down-icon"
|
||||
icon="chevron-down"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div class="export-import">
|
||||
<button
|
||||
class="btn button-default"
|
||||
@click="importTheme"
|
||||
>
|
||||
{{ $t("settings.import_theme") }}
|
||||
</button>
|
||||
<button
|
||||
class="btn button-default"
|
||||
@click="exportTheme"
|
||||
>
|
||||
{{ $t("settings.export_theme") }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="save-load-options">
|
||||
<span class="keep-option">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue