blob: 4987a0bd61216ae22310507591310835bb67986a [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
<template>
<div class="side-setting">
<setting-item :title="$t('label.theme.page.style.setting')" view-type="item">
<a-radio-group
class="setting-group"
name="themeGroup"
v-model:value="layoutMode"
@change="switchLayoutMode">
<setting-item
view-type="radio-group"
:items="pageStyles"
:checked="layoutMode"></setting-item>
</a-radio-group>
</setting-item>
<setting-item :title="$t('label.theme.color')" view-type="item" style="display: block;">
<a-radio-group
class="setting-group"
name="colorGroup"
:default-value="colorPick"
@change="switchColor">
<setting-item
view-type="radio-group"
:items="colors"
:checked="colorPick"></setting-item>
</a-radio-group>
<a-divider style="margin-top: 45px;" />
</setting-item>
<setting-item
v-if="!projectView"
:title="$t('label.theme.navigation.setting')"
view-type="item">
<a-list :split="false">
<a-list-item>
<div class="input-group">
<label>{{ $t('label.theme.navigation.bgColor') }}</label>
<div class="color-picker" :style="{ backgroundColor: navBgColorPick }">
<a-input
:disabled="layoutMode === 'dark'"
type="color"
v-model:value="navBgColorPick"
@blur="(e) => updateSetting('@navigation-background-color', e.target.value)" />
</div>
</div>
</a-list-item>
<a-list-item>
<div class="input-group">
<label>{{ $t('label.theme.navigation.txtColor') }}</label>
<div class="color-picker" :style="{ backgroundColor: navTextColorPick }">
<a-input
:disabled="layoutMode === 'dark'"
type="color"
v-model:value="navTextColorPick"
@blur="(e) => updateSetting('@navigation-text-color', e.target.value)" />
</div>
</div>
</a-list-item>
</a-list>
</setting-item>
<setting-item
v-if="projectView"
:title="$t('label.theme.project.navigation.setting')"
view-type="item">
<a-list :split="false">
<a-list-item>
<div class="input-group">
<label>{{ $t('label.theme.navigation.bgColor') }}</label>
<div class="color-picker" :style="{ backgroundColor: projectNavBgColorPick }">
<a-input
type="color"
v-model:value="projectNavBgColorPick"
@blur="(e) => updateSetting('@project-nav-background-color', e.target.value)" />
</div>
</div>
</a-list-item>
<a-list-item>
<div class="input-group">
<label>{{ $t('label.theme.navigation.txtColor') }}</label>
<div class="color-picker" :style="{ backgroundColor: projectNavTextColorPick }">
<a-input
type="color"
v-model:value="projectNavTextColorPick"
@blur="(e) => updateSetting('@project-nav-text-color', e.target.value)" />
</div>
</div>
</a-list-item>
</a-list>
</setting-item>
<div class="setting-action">
<a-divider style="margin: 15px 0;" />
<a-alert class="setting-action-alert" :message="$t('label.theme.alert')" type="warning" show-icon />
<a-button
class="setting-action-btn"
@click="downloadSetting">
<template #icon><download-outlined /></template>
{{ $t('label.download.setting') }}
</a-button>
<a-button
class="setting-action-btn"
@click="resetSetting">
<template #icon><undo-outlined /></template>
{{ $t('label.reset.to.default') }}
</a-button>
</div>
</div>
</template>
<script>
import SettingItem from '@/components/view/SettingItem'
export default {
name: 'Setting',
components: {
SettingItem
},
props: {
visible: {
type: Boolean,
default: false
}
},
data () {
return {
layoutMode: this.$config.theme['@layout-mode'] || 'light',
colorPick: this.$config.theme['@primary-color'],
navBgColorPick: this.$config.theme['@navigation-background-color'],
navTextColorPick: this.$config.theme['@navigation-text-color'],
projectNavBgColorPick: this.$config.theme['@project-nav-background-color'],
projectNavTextColorPick: this.$config.theme['@project-nav-text-color'],
uiSettings: {},
originalSetting: {}
}
},
computed: {
projectView () {
return Boolean(this.$store.getters.project && this.$store.getters.project.id)
},
pageStyles () {
const arrStyle = [
{
name: 'light',
type: 'image-checkbox',
icon: 'light'
},
{
name: 'dark',
type: 'image-checkbox',
icon: 'dark'
}
]
return arrStyle
},
colors () {
return [
{
name: 'daybreak.blue',
type: 'color-checkbox',
color: '#1890ff'
},
{
name: 'dust.red',
type: 'color-checkbox',
color: '#f5222d'
},
{
name: 'volcano',
type: 'color-checkbox',
color: '#fa541c'
},
{
name: 'sunset.orange',
type: 'color-checkbox',
color: '#faad14'
},
{
name: 'cyan',
type: 'color-checkbox',
color: '#13c2c2'
},
{
name: 'polar.green',
type: 'color-checkbox',
color: '#52c41a'
},
{
name: 'geek.blue',
type: 'color-checkbox',
color: '#2f54eb'
},
{
name: 'golden.purple',
type: 'color-checkbox',
color: '#722ed1'
}
]
}
},
inject: ['parentToggleSetting'],
watch: {
projectView () {
this.fetchData()
}
},
created () {
this.fetchData()
},
methods: {
fetchData () {
this.originalSetting = Object.assign({}, this.$config.theme)
this.layoutMode = this.$config.theme['@layout-mode'] || 'light'
this.uiSettings = this.$config.theme
},
switchLayoutMode () {
this.$store.dispatch('SetDarkMode', (this.layoutMode === 'dark'))
this.updateSetting('@layout-mode', this.layoutMode)
},
switchColor (e) {
this.colorPick = e.target.value
this.updateSetting('@primary-color', this.colorPick)
},
updateSetting (name, value) {
this.uiSettings[name] = value
if (['@navigation-background-color'].includes(name)) {
this.uiSettings['@logo-background-color'] = value
}
window.less.modifyVars(this.uiSettings)
},
onClose () {
this.parentToggleSetting(false)
},
downloadSetting () {
this.downloadObjectAsJson(this.uiSettings)
},
resetSetting () {
this.uiSettings = {}
this.layoutMode = 'light'
this.colorPick = this.originalSetting['@primary-color']
this.navBgColorPick = this.originalSetting['@navigation-background-color']
this.navTextColorPick = this.originalSetting['@navigation-text-color']
this.projectNavBgColorPick = this.originalSetting['@project-nav-background-color']
this.projectNavTextColorPick = this.originalSetting['@project-nav-text-color']
this.switchLayoutMode()
this.$config.theme = this.originalSetting
window.less.modifyVars(this.$config.theme)
this.$message.success(this.$t('label.success'))
},
downloadObjectAsJson (exportObj) {
const dataStr = 'data:text/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(exportObj, null, 2))
const downloadAnchorNode = document.createElement('a')
downloadAnchorNode.setAttribute('href', dataStr)
downloadAnchorNode.setAttribute('download', 'theme.json')
document.body.appendChild(downloadAnchorNode)
downloadAnchorNode.click()
downloadAnchorNode.remove()
}
}
}
</script>
<style lang="less" scoped>
.side-setting {
min-height: 100%;
font-size: 14px;
line-height: 1.5;
word-wrap: break-word;
position: relative;
padding: 20px 0;
.flex{
display: flex;
}
.select-item{
width: 80px;
}
}
.setting-group {
width: 100%;
}
.input-group {
display: inline-flex;
width: 100%;
position: relative;
.color-picker {
position: absolute;
width: 20px;
height: 20px;
overflow: hidden;
top: 0;
right: 0;
border: 1px solid;
cursor: pointer;
.ant-input {
opacity: 0;
height: 20px;
width: 20px;
position: absolute;
top: 0;
left: 0;
cursor: pointer;
}
}
}
.setting-action {
width: 100%;
padding: 0 24px;
&-alert {
display: flex;
flex-direction: row;
align-items: baseline;
margin: 20px 0 8px;
word-break: break-word;
position: relative;
:deep(.ant-alert-icon) {
}
}
&-btn {
width: 100%;
margin-bottom: 5px;
}
}
</style>