diff --git a/frontend/src/components/ElTreeSelect/index.vue b/frontend/src/components/ElTreeSelect/index.vue index c135597b03..86bcb61a68 100644 --- a/frontend/src/components/ElTreeSelect/index.vue +++ b/frontend/src/components/ElTreeSelect/index.vue @@ -562,6 +562,7 @@ export default { // 显示弹出框的时候容错,查看是否和el宽度一致 _popoverShowFun(val) { this._updateH() + this.$emit('onFoucs') }, // 判断是否隐藏弹出框 _popoverHideFun(e) { diff --git a/frontend/src/components/dataease/DeOutWidget.vue b/frontend/src/components/dataease/DeOutWidget.vue index 8735cb4f8b..5cb6289de0 100644 --- a/frontend/src/components/dataease/DeOutWidget.vue +++ b/frontend/src/components/dataease/DeOutWidget.vue @@ -19,6 +19,7 @@
@@ -27,6 +28,7 @@ v-if="element.type==='custom'" :id="'component' + element.id" class="component-custom" + ref="deOutWidget" :out-style="element.style" :element="element" :in-draw="inDraw" @@ -44,8 +46,10 @@ - diff --git a/frontend/src/components/widget/DeWidget/DeInputSearch.vue b/frontend/src/components/widget/DeWidget/DeInputSearch.vue index f38ddef05c..56987e306c 100644 --- a/frontend/src/components/widget/DeWidget/DeInputSearch.vue +++ b/frontend/src/components/widget/DeWidget/DeInputSearch.vue @@ -6,6 +6,8 @@ resize="vertical" :placeholder="$t(element.options.attrs.placeholder)" :size="size" + class="de-range-tag" + ref="de-input-search" @input="valueChange" @keypress.enter.native="search" @dblclick="setEdit" @@ -111,6 +113,10 @@ export default { } - diff --git a/frontend/src/components/widget/DeWidget/DeNumberRange.vue b/frontend/src/components/widget/DeWidget/DeNumberRange.vue index c98a430b30..fcdde09fb5 100644 --- a/frontend/src/components/widget/DeWidget/DeNumberRange.vue +++ b/frontend/src/components/widget/DeWidget/DeNumberRange.vue @@ -3,11 +3,11 @@
- + {{ $t('denumberrange.split_placeholder') }} - +
diff --git a/frontend/src/components/widget/DeWidget/DeSelect.vue b/frontend/src/components/widget/DeWidget/DeSelect.vue index 04668dc91f..749ad44920 100644 --- a/frontend/src/components/widget/DeWidget/DeSelect.vue +++ b/frontend/src/components/widget/DeWidget/DeSelect.vue @@ -11,6 +11,8 @@ :popper-append-to-body="inScreen" :size="size" :filterable="true" + class="de-select-tag" + popper-class="coustom-de-select" @change="changeValue" @focus="setOptionWidth" @blur="onBlur" @@ -32,8 +34,10 @@ import { multFieldValues, linkMultFieldValues } from '@/api/dataset/dataset' import bus from '@/utils/bus' import { getLinkToken, getToken } from '@/utils/auth' -export default { +import customInput from '@/components/widget/DeWidget/customInput' +export default { + mixins: [customInput], props: { element: { type: Object, @@ -120,6 +124,7 @@ export default { this.show = false this.$nextTick(() => { this.show = true + this.handleCoustomStyle() }) }, 'element.options.attrs.sort': function(value, old) { @@ -253,6 +258,7 @@ export default { this.$nextTick(() => { // this.selectOptionWidth = event.srcElement.offsetWidth + 'px' this.selectOptionWidth = event.srcElement.parentElement.parentElement.offsetWidth + 'px' + this.handleCoustomStyle() }) } @@ -261,6 +267,45 @@ export default { } - + .popper__arrow, + .popper__arrow::after { + display: none !important; + } + + .el-select-dropdown__item { + color: var(--SelectColor, #606266); + } + + .el-select-dropdown__item.selected { + color: #409eff; + background-color: rgb(245, 247, 250, .5); + } + + .el-select-dropdown__item.hover { + background-color: rgb(245, 247, 250, .5); + } +} +.de-select-tag { + .el-select__tags { + .el-tag { + background-color: var(--BgSelectColor, #f4f4f5) !important; + border-color: var(--BrSelectColor, #e9e9eb) !important; + color: var(--SelectColor, #909399) !important; + + i { + color: var(--SelectColor, #909399) !important; + } + } + .el-icon-close { + background-color: var(--BgSelectColor, #C0C4CC) !important; + } + } +} + \ No newline at end of file diff --git a/frontend/src/components/widget/DeWidget/DeSelectGrid.vue b/frontend/src/components/widget/DeWidget/DeSelectGrid.vue index 1ca3012362..20c7e5885a 100644 --- a/frontend/src/components/widget/DeWidget/DeSelectGrid.vue +++ b/frontend/src/components/widget/DeWidget/DeSelectGrid.vue @@ -6,6 +6,7 @@ v-model="keyWord" :placeholder="$t('deinputsearch.placeholder')" :size="size" + ref="de-select-grid" prefix-icon="el-icon-search" clearable /> @@ -39,8 +40,9 @@ import { multFieldValues, linkMultFieldValues } from '@/api/dataset/dataset' import { getLinkToken, getToken } from '@/utils/auth' import bus from '@/utils/bus' -export default { +import { attrsMap, styleAttrs, textSelectGridWidget } from '@/components/widget/DeWidget/serviceNameFn.js' +export default { props: { element: { type: Object, @@ -76,7 +78,7 @@ export default { show: true, datas: [], isIndeterminate: false, - checkAll: false + checkAll: false, } }, computed: { @@ -96,6 +98,10 @@ export default { }, panelInfo() { return this.$store.state.panel.panelInfo + }, + cssArr() { + const { brColor, wordColor, innerBgColor } = this.element.style; + return { brColor, wordColor, innerBgColor } } }, watch: { @@ -130,6 +136,7 @@ export default { this.element.options.attrs.fieldId.length > 0 && method(param).then(res => { this.datas = this.optionDatas(res.data) + this.changeInputStyle() }) || (this.element.options.value = '') }, 'element.options.attrs.multiple': function(value, old) { @@ -148,6 +155,7 @@ export default { this.checkAll = this.value.length === this.datas.length this.isIndeterminate = this.value.length > 0 && this.value.length < this.datas.length } + this.changeInputStyle(); }) }, 'element.options.attrs.sort': function(value, old) { @@ -167,8 +175,14 @@ export default { this.element.options.attrs.fieldId.length > 0 && method(param).then(res => { this.datas = this.optionDatas(res.data) + this.changeInputStyle() }) || (this.element.options.value = '') - } + }, + cssArr: { + handler: 'changeInputStyle', + deep: true + }, + keyWord: 'changeInputStyle' }, created() { if (!this.element.options.attrs.sort) { @@ -191,6 +205,24 @@ export default { }, methods: { + changeInputStyle() { + if (!this.$parent.handlerInputStyle) return; + this.$nextTick(() => { + this.handlerInputStyle(this.element.style) + }) + }, + handlerInputStyle(newValue) { + let nodeCache = ''; + if (!this.$refs['de-select-grid']) return + styleAttrs.forEach(ele => { + if (!nodeCache) { + nodeCache = this.$refs['de-select-grid'].$el.querySelector('.el-input__inner') + } + nodeCache.style[attrsMap[ele]] = newValue[ele]; + this.textSelectGridWidget(this.$el, ele, newValue[ele]) + }) + }, + textSelectGridWidget: textSelectGridWidget, initLoad() { this.value = this.element.options.attrs.multiple ? [] : null if (this.element.options.attrs.fieldId) { @@ -202,6 +234,7 @@ export default { } method({ fieldIds: this.element.options.attrs.fieldId.split(','), sort: this.element.options.attrs.sort }).then(res => { this.datas = this.optionDatas(res.data) + this.changeInputStyle() if (this.element.options.attrs.multiple) { this.checkAll = this.value.length === this.datas.length this.isIndeterminate = this.value.length > 0 && this.value.length < this.datas.length diff --git a/frontend/src/components/widget/DeWidget/DeSelectTree.vue b/frontend/src/components/widget/DeWidget/DeSelectTree.vue index a7f29ed2d7..b08009db08 100644 --- a/frontend/src/components/widget/DeWidget/DeSelectTree.vue +++ b/frontend/src/components/widget/DeWidget/DeSelectTree.vue @@ -15,6 +15,7 @@ @removeTag="changeNodeIds" @check="changeCheckNode" @select-clear="selectClear" + @onFoucs="onFoucs" /> @@ -24,8 +25,11 @@ import { mappingFieldValues, linkMappingFieldValues } from '@/api/dataset/datase import bus from '@/utils/bus' import { getLinkToken, getToken } from '@/utils/auth' import ElTreeSelect from '@/components/ElTreeSelect' +import customInput from '@/components/widget/DeWidget/customInput' + export default { components: { ElTreeSelect }, + mixins: [customInput], props: { element: { type: Object, @@ -208,6 +212,11 @@ export default { }, methods: { + onFoucs() { + this.$nextTick(() => { + this.handleCoustomStyle() + }) + }, selectClear() { this.changeValue(this.value) }, @@ -354,6 +363,33 @@ export default { } - diff --git a/frontend/src/components/widget/DeWidget/customInput.js b/frontend/src/components/widget/DeWidget/customInput.js new file mode 100644 index 0000000000..a33343629d --- /dev/null +++ b/frontend/src/components/widget/DeWidget/customInput.js @@ -0,0 +1,39 @@ +// 通过控制css变量控制过滤组件弹框样式 de-select-grid除外 +import { attrsMap, styleAttrs } from '@/components/widget/DeWidget/serviceNameFn.js' + +export default { + data() { + return { + attrsMap, + styleAttrs, + // 过滤组件名css变量映射 + refComNameMap: { + 'de-date': ['--BgDateColor', '--DateColor', '--BrDateColor'], + 'de-select': ['--BgSelectColor', '--SelectColor', '--BrSelectColor'], + 'de-select-tree': ['--BgSelectTreeColor', '--SelectTreeColor', '--BrSelectTreeColor'], + "de-input-search": ['--BgSearchColor', '--SearchColor', '--BrSearchColor'], + "de-number-range": ['--BgRangeColor', '--RangeColor', '--BrRangeColor'] + } + } + }, + mounted() { + this.handleCoustomStyle() + }, + methods: { + typeTransform() { + let refNode = this.refComNameMap[this.element.component]; + if (!refNode) return []; + return refNode + }, + handleCoustomStyle() { + // 判断组件是否是在仪表板内部 否则css样式取默认值 + const isPanelDe = this.$parent.handlerInputStyle; + const { brColor, wordColor, innerBgColor } = this.element.style; + const newValue = { brColor, wordColor, innerBgColor }; + const cssVar = this.typeTransform(); + this.styleAttrs.forEach((ele, index) => { + document.documentElement.style.setProperty(cssVar[index], !isPanelDe ? '' : newValue[ele]) + }) + }, + } +} \ No newline at end of file diff --git a/frontend/src/components/widget/DeWidget/inputStyleMixin.js b/frontend/src/components/widget/DeWidget/inputStyleMixin.js new file mode 100644 index 0000000000..5c9b52d6cb --- /dev/null +++ b/frontend/src/components/widget/DeWidget/inputStyleMixin.js @@ -0,0 +1,74 @@ +// 通过控制 js 控制过滤组件输入框样式 如需额外处理 声明组件serviceName同名函数处理 +import { timeDateRangeWidget, textInputWidget, attrsMap, styleAttrs } from '@/components/widget/DeWidget/serviceNameFn.js' +export default { + data() { + return { + attrsMap, + styleAttrs, + // 过滤组件名ref映射 + refComNameMap: { + 'de-date': 'dateRef', + 'de-select-grid': 'de-select-grid', + 'de-select': 'deSelect', + 'de-select-tree': 'deSelectTree', + "de-input-search": "de-input-search", + "de-number-range": ['de-number-range-min', 'de-number-range-max'] + } + } + }, + watch: { + cssArr: { + handler(newValue) { + if (!this.isFilterComponent) return; + this.typeTransform().forEach(ele => { + this.handlerInputStyle(ele, newValue) + }) + }, + deep: true + }, + }, + computed: { + cssArr() { + const { brColor, wordColor, innerBgColor } = this.element.style; + return { brColor, wordColor, innerBgColor } + } + }, + mounted() { + if (!this.isFilterComponent) return; + this.typeTransform().forEach(item => { + const nodeCache = this.$refs.deOutWidget.$refs[item].$el.querySelector('.el-input__inner') || this.$refs.deOutWidget.$refs[item].$el + this.styleAttrs.forEach(ele => { + nodeCache.style[this.attrsMap[ele]] = this.element.style[ele]; + this[this.element.serviceName] && this[this.element.serviceName](this.selectRange(item), ele, this.element.style[ele]) + }) + }) + }, + methods: { + handlerInputStyle(type, newValue) { + let nodeCache = ''; + this.styleAttrs.forEach(ele => { + if (!nodeCache) { + nodeCache = this.$refs.deOutWidget.$refs[type].$el.querySelector('.el-input__inner') || this.$refs.deOutWidget.$refs[type].$el + } + nodeCache.style[this.attrsMap[ele]] = newValue[ele]; + this[this.element.serviceName] && this[this.element.serviceName](this.selectRange(type), ele, newValue[ele]) + }) + }, + selectRange(item) { + if (this.element.component === 'de-select-grid') { + return this.$refs.deOutWidget.$el; + } + return this.$refs.deOutWidget.$refs[item].$el; + }, + timeDateRangeWidget: timeDateRangeWidget, + textInputWidget: textInputWidget, + typeTransform() { + let refNode = this.refComNameMap[this.element.component]; + if (!refNode) return []; + if (!Array.isArray(refNode)) { + refNode = [refNode] + } + return refNode + } + } +} \ No newline at end of file diff --git a/frontend/src/components/widget/DeWidget/serviceNameFn.js b/frontend/src/components/widget/DeWidget/serviceNameFn.js new file mode 100644 index 0000000000..da8a9faacc --- /dev/null +++ b/frontend/src/components/widget/DeWidget/serviceNameFn.js @@ -0,0 +1,46 @@ +const attrsMap = { brColor: 'borderColor', wordColor: 'color', innerBgColor: 'backgroundColor' } +const styleAttrs = ['innerBgColor', 'wordColor', 'brColor'] +function timeDateRangeWidget (nodeCache, name, value) { + const classList = ['.el-range-input', '.el-range-separator'] + classList.forEach(ele => { + let nodeList = nodeCache.querySelectorAll(ele); + if (!nodeList.length) return; + nodeList.forEach(ele => { + ele.style[attrsMap[name]] = value; + }) + }) +} +function textInputWidget (nodeCache, name, value) { + let groupAppend = nodeCache.querySelector('.el-input-group__append'); + groupAppend.style[attrsMap[name]] = value; + if (name === 'brColor') { + groupAppend.style.borderLeft = 'none' + } +} + +function textSelectGridWidget (nodeCache, name, value) { + if (name === 'innerBgColor') { + nodeCache.querySelector('.list').style.backgroundColor = value; + } + if (name === 'wordColor') { + let elRadio = nodeCache.querySelectorAll('.el-radio') + let elCheckbox = nodeCache.querySelectorAll('.el-checkbox') + if (elRadio.length) { + elRadio.forEach(ele => { + ele.style.color = value; + }); + } + if (elCheckbox.length) { + elCheckbox.forEach(ele => { + ele.style.color = value; + }); + } + } +} +export { + attrsMap, + styleAttrs, + timeDateRangeWidget, + textInputWidget, + textSelectGridWidget, +} \ No newline at end of file diff --git a/frontend/src/styles/theme/dark.scss b/frontend/src/styles/theme/dark.scss index 9f81402905..ba6728df40 100644 --- a/frontend/src/styles/theme/dark.scss +++ b/frontend/src/styles/theme/dark.scss @@ -22,6 +22,32 @@ $--color-black: #FFFFFF; $--background-color-base: #171b22; +/* 定义全局变量 */ +:root{ + --BgSelectColor: #ffffff; + --SelectColor: #fff; + --BrSelectColor: #fff; + + --BgSelectTreeColor: #ffffff; + --SelectTreeColor: #fff; + --BrSelectTreeColor: #fff; + + --BgDateColor: #ffffff; + --DateColor: #fff; + --BrDateColor: #fff; + + --BgRangeColor: #ffffff; + --RangeColor: #fff; + --BrRangeColor: #fff; + + --BgSerachColor: #ffffff; + --SerachColor: #fff; + --BrSerachColor: #fff; + + --BgSelectGridColor: #ffffff; + --SelectGridColor: #fff; + --BrSelectGridColor: #fff; +} // 与CSS原生变量映射 #app { @@ -56,3 +82,4 @@ $--background-color-base: #171b22; } + diff --git a/frontend/src/views/background/index.vue b/frontend/src/views/background/index.vue index d47352fb5c..8f433ad1a9 100644 --- a/frontend/src/views/background/index.vue +++ b/frontend/src/views/background/index.vue @@ -93,6 +93,29 @@ + + + 输入框样式(颜色): + + + 边框 + + + + + + 文字 + + + + + + 背景 + + + + + @@ -139,7 +162,10 @@ export default { ...mapState([ 'curComponent', 'componentData' - ]) + ]), + isFilterComponent() { + return ['de-select', 'de-select-grid', 'de-date', "de-input-search", "de-number-range", "de-select-tree"].includes(this.curComponent.component) + } }, methods: { init() {