mirror of https://github.com/halo-dev/halo-admin
feat: theme supports preview after setting (#502)
Signed-off-by: Ryan Wang <i@ryanc.cc>pull/505/head
parent
bb28b3ff2f
commit
c7e872d812
|
@ -222,6 +222,13 @@ export const asyncRouterMap = [
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/interface/themes/setting/visual',
|
||||||
|
name: 'ThemeVisualSetting',
|
||||||
|
hidden: true,
|
||||||
|
component: () => import('@/views/interface/ThemeVisualSetting'),
|
||||||
|
meta: { title: '主题设置', hiddenHeaderContent: false }
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '*',
|
path: '*',
|
||||||
redirect: '/404',
|
redirect: '/404',
|
||||||
|
|
|
@ -17,6 +17,24 @@
|
||||||
<a-icon type="down" />
|
<a-icon type="down" />
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-dropdown>
|
</a-dropdown>
|
||||||
|
<a-dropdown>
|
||||||
|
<template #overlay>
|
||||||
|
<a-menu>
|
||||||
|
<a-menu-item :disabled="theme.current.activated" @click="handleActiveTheme">
|
||||||
|
<a-icon type="lock" />
|
||||||
|
启用
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item :disabled="!theme.current.activated" @click="handleRouteToThemeVisualSetting">
|
||||||
|
<a-icon type="eye" />
|
||||||
|
预览模式
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</template>
|
||||||
|
<a-button icon="more">
|
||||||
|
更多
|
||||||
|
<a-icon type="down" />
|
||||||
|
</a-button>
|
||||||
|
</a-dropdown>
|
||||||
<a-button
|
<a-button
|
||||||
:disabled="theme.current.activated"
|
:disabled="theme.current.activated"
|
||||||
icon="delete"
|
icon="delete"
|
||||||
|
@ -26,135 +44,9 @@
|
||||||
删除
|
删除
|
||||||
</a-button>
|
</a-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<a-spin :spinning="theme.loading">
|
<a-spin :spinning="theme.loading">
|
||||||
<div v-if="theme.current.id" class="card-container">
|
<ThemeSettingForm :theme="theme.current" />
|
||||||
<a-tabs defaultActiveKey="0" type="card">
|
|
||||||
<a-tab-pane :key="0" tab="关于">
|
|
||||||
<div v-if="theme.current.logo">
|
|
||||||
<a-avatar :alt="theme.current.name" :size="72" :src="theme.current.logo" shape="square" />
|
|
||||||
<a-divider />
|
|
||||||
</div>
|
|
||||||
<a-descriptions :column="1" layout="horizontal">
|
|
||||||
<a-descriptions-item label="作者">
|
|
||||||
<a class="text-inherit" :href="theme.current.author.website || '#'" target="_blank">
|
|
||||||
{{ theme.current.author.name }}
|
|
||||||
</a>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="介绍">
|
|
||||||
{{ theme.current.description || '-' }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="官网">
|
|
||||||
<a class="text-inherit" :href="theme.current.website || '#'" target="_blank">
|
|
||||||
{{ theme.current.website || '-' }}
|
|
||||||
</a>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="Git 仓库">
|
|
||||||
<a class="text-inherit" :href="theme.current.repo || '#'" target="_blank">
|
|
||||||
{{ theme.current.repo || '-' }}
|
|
||||||
</a>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="主题标识">
|
|
||||||
{{ theme.current.id }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="当前版本">
|
|
||||||
{{ theme.current.version }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="存储位置">
|
|
||||||
{{ theme.current.themePath }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
</a-descriptions>
|
|
||||||
</a-tab-pane>
|
|
||||||
<a-tab-pane v-for="(group, index) in theme.configurations" :key="index + 1" :tab="group.label">
|
|
||||||
<a-form
|
|
||||||
:wrapperCol="{
|
|
||||||
xl: { span: 8 },
|
|
||||||
lg: { span: 8 },
|
|
||||||
sm: { span: 12 },
|
|
||||||
xs: { span: 24 }
|
|
||||||
}"
|
|
||||||
layout="vertical"
|
|
||||||
>
|
|
||||||
<a-form-item v-for="(item, formItemIndex) in group.items" :key="formItemIndex" :label="item.label + ':'">
|
|
||||||
<p v-if="item.description && item.description !== ''" slot="help" v-html="item.description"></p>
|
|
||||||
<a-input
|
|
||||||
v-if="item.type === 'TEXT'"
|
|
||||||
v-model="theme.settings[item.name]"
|
|
||||||
:defaultValue="item.defaultValue"
|
|
||||||
:placeholder="item.placeholder"
|
|
||||||
/>
|
|
||||||
<a-input
|
|
||||||
v-else-if="item.type === 'TEXTAREA'"
|
|
||||||
v-model="theme.settings[item.name]"
|
|
||||||
:autoSize="{ minRows: 5 }"
|
|
||||||
:placeholder="item.placeholder"
|
|
||||||
type="textarea"
|
|
||||||
/>
|
|
||||||
<a-radio-group
|
|
||||||
v-else-if="item.type === 'RADIO'"
|
|
||||||
v-model="theme.settings[item.name]"
|
|
||||||
:defaultValue="item.defaultValue"
|
|
||||||
>
|
|
||||||
<a-radio v-for="(option, radioIndex) in item.options" :key="radioIndex" :value="option.value">
|
|
||||||
{{ option.label }}
|
|
||||||
</a-radio>
|
|
||||||
</a-radio-group>
|
|
||||||
<a-select
|
|
||||||
v-else-if="item.type === 'SELECT'"
|
|
||||||
v-model="theme.settings[item.name]"
|
|
||||||
:defaultValue="item.defaultValue"
|
|
||||||
>
|
|
||||||
<a-select-option v-for="option in item.options" :key="option.value" :value="option.value">
|
|
||||||
{{ option.label }}
|
|
||||||
</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
<verte
|
|
||||||
v-else-if="item.type === 'COLOR'"
|
|
||||||
v-model="theme.settings[item.name]"
|
|
||||||
:defaultValue="item.defaultValue"
|
|
||||||
model="hex"
|
|
||||||
picker="square"
|
|
||||||
style="display: inline-block; height: 24px"
|
|
||||||
></verte>
|
|
||||||
<AttachmentInput
|
|
||||||
v-else-if="item.type === 'ATTACHMENT'"
|
|
||||||
v-model="theme.settings[item.name]"
|
|
||||||
:defaultValue="item.defaultValue"
|
|
||||||
:placeholder="item.placeholder"
|
|
||||||
/>
|
|
||||||
<a-input-number
|
|
||||||
v-else-if="item.type === 'NUMBER'"
|
|
||||||
v-model="theme.settings[item.name]"
|
|
||||||
:defaultValue="item.defaultValue"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
<a-switch
|
|
||||||
v-else-if="item.type === 'SWITCH'"
|
|
||||||
v-model="theme.settings[item.name]"
|
|
||||||
:defaultChecked="item.defaultValue"
|
|
||||||
/>
|
|
||||||
<a-input
|
|
||||||
v-else
|
|
||||||
v-model="theme.settings[item.name]"
|
|
||||||
:defaultValue="item.defaultValue"
|
|
||||||
:placeholder="item.placeholder"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item>
|
|
||||||
<ReactiveButton
|
|
||||||
:errored="theme.saveErrored"
|
|
||||||
:loading="theme.saving"
|
|
||||||
erroredText="保存失败"
|
|
||||||
loadedText="保存成功"
|
|
||||||
text="保存"
|
|
||||||
type="primary"
|
|
||||||
@callback="theme.saveErrored = false"
|
|
||||||
@click="handleSaveSettings"
|
|
||||||
></ReactiveButton>
|
|
||||||
</a-form-item>
|
|
||||||
</a-form>
|
|
||||||
</a-tab-pane>
|
|
||||||
</a-tabs>
|
|
||||||
</div>
|
|
||||||
</a-spin>
|
</a-spin>
|
||||||
|
|
||||||
<ThemeDeleteConfirmModal
|
<ThemeDeleteConfirmModal
|
||||||
|
@ -172,11 +64,10 @@
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
// components
|
// components
|
||||||
import Verte from 'verte'
|
|
||||||
import 'verte/dist/verte.css'
|
|
||||||
import { PageView } from '@/layouts'
|
import { PageView } from '@/layouts'
|
||||||
import ThemeDeleteConfirmModal from './components/ThemeDeleteConfirmModal'
|
import ThemeDeleteConfirmModal from './components/ThemeDeleteConfirmModal'
|
||||||
import ThemeLocalUpgradeModal from './components/ThemeLocalUpgradeModal'
|
import ThemeLocalUpgradeModal from './components/ThemeLocalUpgradeModal'
|
||||||
|
import ThemeSettingForm from './components/ThemeSettingForm'
|
||||||
|
|
||||||
// utils
|
// utils
|
||||||
import apiClient from '@/utils/api-client'
|
import apiClient from '@/utils/api-client'
|
||||||
|
@ -185,19 +76,15 @@ export default {
|
||||||
name: 'ThemeSetting',
|
name: 'ThemeSetting',
|
||||||
components: {
|
components: {
|
||||||
PageView,
|
PageView,
|
||||||
Verte,
|
|
||||||
ThemeDeleteConfirmModal,
|
ThemeDeleteConfirmModal,
|
||||||
ThemeLocalUpgradeModal
|
ThemeLocalUpgradeModal,
|
||||||
|
ThemeSettingForm
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
theme: {
|
theme: {
|
||||||
current: {},
|
current: {},
|
||||||
settings: [],
|
loading: false
|
||||||
configurations: [],
|
|
||||||
loading: false,
|
|
||||||
saving: false,
|
|
||||||
saveErrored: false
|
|
||||||
},
|
},
|
||||||
themeDeleteModal: {
|
themeDeleteModal: {
|
||||||
visible: false
|
visible: false
|
||||||
|
@ -225,41 +112,10 @@ export default {
|
||||||
const { data } = await apiClient.theme.getActivatedTheme()
|
const { data } = await apiClient.theme.getActivatedTheme()
|
||||||
this.theme.current = data
|
this.theme.current = data
|
||||||
}
|
}
|
||||||
await this.handleGetConfigurations()
|
|
||||||
await this.handleGetSettings()
|
|
||||||
} finally {
|
} finally {
|
||||||
this.theme.loading = false
|
this.theme.loading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async handleGetConfigurations() {
|
|
||||||
try {
|
|
||||||
const { data } = await apiClient.theme.listConfigurations(this.theme.current.id)
|
|
||||||
this.theme.configurations = data
|
|
||||||
} catch (error) {
|
|
||||||
this.$log.error(error)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async handleGetSettings() {
|
|
||||||
try {
|
|
||||||
const { data } = await apiClient.theme.listSettings(this.theme.current.id)
|
|
||||||
this.theme.settings = data
|
|
||||||
} catch (error) {
|
|
||||||
this.$log.error(error)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async handleSaveSettings() {
|
|
||||||
try {
|
|
||||||
this.theme.saving = true
|
|
||||||
await apiClient.theme.saveSettings(this.theme.current.id, this.theme.settings)
|
|
||||||
} catch (error) {
|
|
||||||
this.$log.error(error)
|
|
||||||
this.theme.saveErrored = true
|
|
||||||
} finally {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.theme.saving = false
|
|
||||||
}, 400)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onThemeDeleteSucceed() {
|
onThemeDeleteSucceed() {
|
||||||
this.$router.replace({ name: 'ThemeList' })
|
this.$router.replace({ name: 'ThemeList' })
|
||||||
},
|
},
|
||||||
|
@ -268,7 +124,7 @@ export default {
|
||||||
_this.$confirm({
|
_this.$confirm({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
maskClosable: true,
|
maskClosable: true,
|
||||||
content: '确定更新【' + _this.theme.current.name + '】主题?',
|
content: '确定更新【' + _this.theme.current.name + '】主题吗?',
|
||||||
async onOk() {
|
async onOk() {
|
||||||
const hideLoading = _this.$message.loading('更新中...', 0)
|
const hideLoading = _this.$message.loading('更新中...', 0)
|
||||||
try {
|
try {
|
||||||
|
@ -282,6 +138,27 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
handleRouteToThemeVisualSetting() {
|
||||||
|
this.$router.push({ name: 'ThemeVisualSetting', query: { themeId: this.theme.current.id } })
|
||||||
|
},
|
||||||
|
handleActiveTheme() {
|
||||||
|
const _this = this
|
||||||
|
_this.$confirm({
|
||||||
|
title: '提示',
|
||||||
|
maskClosable: true,
|
||||||
|
content: '确定启用【' + _this.theme.current.name + '】主题吗?',
|
||||||
|
async onOk() {
|
||||||
|
try {
|
||||||
|
await apiClient.theme.active(_this.theme.current.id)
|
||||||
|
_this.$message.success('启用成功!')
|
||||||
|
} catch (e) {
|
||||||
|
_this.$log.error('Failed active theme', e)
|
||||||
|
} finally {
|
||||||
|
await _this.handleGetTheme(_this.theme.current.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
<template>
|
||||||
|
<a-row :gutter="0">
|
||||||
|
<a-col :md="6" :sm="24" class="h-screen" style="border-right: 1px solid #f2f2f2">
|
||||||
|
<a-spin :spinning="theme.loading" class="h-full">
|
||||||
|
<ThemeSettingForm :theme="theme.data" :wrapperCol="{ span: 24 }" @saved="onSettingsSaved" />
|
||||||
|
</a-spin>
|
||||||
|
</a-col>
|
||||||
|
<a-col :md="18" :sm="24" class="h-screen">
|
||||||
|
<iframe
|
||||||
|
id="themeViewIframe"
|
||||||
|
:src="options.blog_url"
|
||||||
|
frameborder="0"
|
||||||
|
height="100%"
|
||||||
|
scrolling="auto"
|
||||||
|
width="100%"
|
||||||
|
/>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
// components
|
||||||
|
import ThemeSettingForm from './components/ThemeSettingForm'
|
||||||
|
|
||||||
|
import apiClient from '@/utils/api-client'
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ThemeVisualSetting',
|
||||||
|
components: {
|
||||||
|
ThemeSettingForm
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
theme: {
|
||||||
|
data: {},
|
||||||
|
loading: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['options'])
|
||||||
|
},
|
||||||
|
beforeRouteEnter(to, from, next) {
|
||||||
|
// Get theme id from query
|
||||||
|
const themeId = to.query.themeId
|
||||||
|
next(async vm => {
|
||||||
|
await vm.handleGetTheme(themeId)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async handleGetTheme(themeId) {
|
||||||
|
try {
|
||||||
|
this.theme.loading = true
|
||||||
|
const { data } = await apiClient.theme.get(themeId)
|
||||||
|
this.theme.data = data
|
||||||
|
} finally {
|
||||||
|
this.theme.loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSettingsSaved() {
|
||||||
|
document.getElementById('themeViewIframe').contentWindow.location.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
::v-deep .ant-spin-container {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .ant-tabs-content {
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,212 @@
|
||||||
|
<template>
|
||||||
|
<div v-if="theme.id" class="card-container h-full">
|
||||||
|
<a-tabs class="h-full" defaultActiveKey="0" type="card">
|
||||||
|
<a-tab-pane :key="0" tab="关于">
|
||||||
|
<div v-if="theme.logo">
|
||||||
|
<a-avatar :alt="theme.name" :size="72" :src="theme.logo" shape="square" />
|
||||||
|
<a-divider />
|
||||||
|
</div>
|
||||||
|
<a-descriptions :column="1" layout="horizontal">
|
||||||
|
<a-descriptions-item label="作者">
|
||||||
|
<a :href="theme.author.website || '#'" class="text-inherit" target="_blank">
|
||||||
|
{{ theme.author.name }}
|
||||||
|
</a>
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="介绍">
|
||||||
|
{{ theme.description || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="官网">
|
||||||
|
<a :href="theme.website || '#'" class="text-inherit" target="_blank">
|
||||||
|
{{ theme.website || '-' }}
|
||||||
|
</a>
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="Git 仓库">
|
||||||
|
<a :href="theme.repo || '#'" class="text-inherit" target="_blank">
|
||||||
|
{{ theme.repo || '-' }}
|
||||||
|
</a>
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="主题标识">
|
||||||
|
{{ theme.id }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="当前版本">
|
||||||
|
{{ theme.version }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="存储位置">
|
||||||
|
{{ theme.themePath }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
</a-descriptions>
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane v-for="(group, index) in form.configurations" :key="index + 1" :tab="group.label">
|
||||||
|
<a-form :wrapperCol="wrapperCol" layout="vertical">
|
||||||
|
<a-form-item v-for="(item, formItemIndex) in group.items" :key="formItemIndex" :label="item.label + ':'">
|
||||||
|
<p v-if="item.description && item.description !== ''" slot="help" v-html="item.description"></p>
|
||||||
|
<a-input
|
||||||
|
v-if="item.type === 'TEXT'"
|
||||||
|
v-model="form.settings[item.name]"
|
||||||
|
:defaultValue="item.defaultValue"
|
||||||
|
:placeholder="item.placeholder"
|
||||||
|
/>
|
||||||
|
<a-input
|
||||||
|
v-else-if="item.type === 'TEXTAREA'"
|
||||||
|
v-model="form.settings[item.name]"
|
||||||
|
:autoSize="{ minRows: 5 }"
|
||||||
|
:placeholder="item.placeholder"
|
||||||
|
type="textarea"
|
||||||
|
/>
|
||||||
|
<a-radio-group
|
||||||
|
v-else-if="item.type === 'RADIO'"
|
||||||
|
v-model="form.settings[item.name]"
|
||||||
|
:defaultValue="item.defaultValue"
|
||||||
|
>
|
||||||
|
<a-radio v-for="(option, radioIndex) in item.options" :key="radioIndex" :value="option.value">
|
||||||
|
{{ option.label }}
|
||||||
|
</a-radio>
|
||||||
|
</a-radio-group>
|
||||||
|
<a-select
|
||||||
|
v-else-if="item.type === 'SELECT'"
|
||||||
|
v-model="form.settings[item.name]"
|
||||||
|
:defaultValue="item.defaultValue"
|
||||||
|
>
|
||||||
|
<a-select-option v-for="option in item.options" :key="option.value" :value="option.value">
|
||||||
|
{{ option.label }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
<verte
|
||||||
|
v-else-if="item.type === 'COLOR'"
|
||||||
|
v-model="form.settings[item.name]"
|
||||||
|
:defaultValue="item.defaultValue"
|
||||||
|
model="hex"
|
||||||
|
picker="square"
|
||||||
|
style="display: inline-block; height: 24px"
|
||||||
|
></verte>
|
||||||
|
<AttachmentInput
|
||||||
|
v-else-if="item.type === 'ATTACHMENT'"
|
||||||
|
v-model="form.settings[item.name]"
|
||||||
|
:defaultValue="item.defaultValue"
|
||||||
|
:placeholder="item.placeholder"
|
||||||
|
/>
|
||||||
|
<a-input-number
|
||||||
|
v-else-if="item.type === 'NUMBER'"
|
||||||
|
v-model="form.settings[item.name]"
|
||||||
|
:defaultValue="item.defaultValue"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
<a-switch
|
||||||
|
v-else-if="item.type === 'SWITCH'"
|
||||||
|
v-model="form.settings[item.name]"
|
||||||
|
:defaultChecked="item.defaultValue"
|
||||||
|
/>
|
||||||
|
<a-input
|
||||||
|
v-else
|
||||||
|
v-model="form.settings[item.name]"
|
||||||
|
:defaultValue="item.defaultValue"
|
||||||
|
:placeholder="item.placeholder"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item>
|
||||||
|
<ReactiveButton
|
||||||
|
:errored="form.saveErrored"
|
||||||
|
:loading="form.saving"
|
||||||
|
erroredText="保存失败"
|
||||||
|
loadedText="保存成功"
|
||||||
|
text="保存"
|
||||||
|
type="primary"
|
||||||
|
@callback="handleSaveSettingsCallback"
|
||||||
|
@click="handleSaveSettings"
|
||||||
|
></ReactiveButton>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-tab-pane>
|
||||||
|
</a-tabs>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
// components
|
||||||
|
import Verte from 'verte'
|
||||||
|
import 'verte/dist/verte.css'
|
||||||
|
|
||||||
|
import apiClient from '@/utils/api-client'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ThemeSettingForm',
|
||||||
|
components: {
|
||||||
|
Verte
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
theme: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
xl: { span: 8 },
|
||||||
|
lg: { span: 8 },
|
||||||
|
sm: { span: 12 },
|
||||||
|
xs: { span: 24 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
form: {
|
||||||
|
settings: [],
|
||||||
|
configurations: [],
|
||||||
|
loading: false,
|
||||||
|
saving: false,
|
||||||
|
saveErrored: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
theme(value) {
|
||||||
|
if (value) {
|
||||||
|
this.handleGetConfigurations()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async handleGetConfigurations() {
|
||||||
|
try {
|
||||||
|
const { data } = await apiClient.theme.listConfigurations(this.theme.id)
|
||||||
|
this.form.configurations = data
|
||||||
|
|
||||||
|
await this.handleGetSettings()
|
||||||
|
} catch (error) {
|
||||||
|
this.$log.error(error)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async handleGetSettings() {
|
||||||
|
try {
|
||||||
|
const { data } = await apiClient.theme.listSettings(this.theme.id)
|
||||||
|
this.form.settings = data
|
||||||
|
} catch (error) {
|
||||||
|
this.$log.error(error)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async handleSaveSettings() {
|
||||||
|
try {
|
||||||
|
this.form.saving = true
|
||||||
|
await apiClient.theme.saveSettings(this.theme.id, this.form.settings)
|
||||||
|
} catch (error) {
|
||||||
|
this.$log.error(error)
|
||||||
|
this.form.saveErrored = true
|
||||||
|
} finally {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.form.saving = false
|
||||||
|
}, 400)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleSaveSettingsCallback() {
|
||||||
|
if (this.form.saveErrored) {
|
||||||
|
this.form.saveErrored = false
|
||||||
|
} else {
|
||||||
|
this.handleGetSettings()
|
||||||
|
this.$emit('saved')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
Loading…
Reference in New Issue