forked from github/dataease
Merge branch 'dev-v2' into pr@dev-v2_export_data
This commit is contained in:
commit
563f23dd07
@ -7,7 +7,7 @@ import java.util.Optional;
|
||||
*/
|
||||
public class SQLUtils {
|
||||
public static String transKeyword(String value) {
|
||||
return Optional.ofNullable(value).orElse("").replaceAll("'", "\\\\'");
|
||||
return Optional.ofNullable(value).orElse("").replaceAll("'", "''");
|
||||
}
|
||||
|
||||
public static String buildOriginPreviewSql(String sql, int limit, int offset) {
|
||||
|
@ -1391,6 +1391,7 @@ onMounted(() => {
|
||||
if (isMainCanvas(canvasId.value)) {
|
||||
initSnapshotTimer()
|
||||
initWatermark()
|
||||
dvMainStore.setEditMode('edit')
|
||||
}
|
||||
// 获取编辑器元素
|
||||
composeStore.getEditor(canvasId.value)
|
||||
|
@ -319,13 +319,13 @@ const scrollSpeedList = [
|
||||
{ name: '1', value: 80 },
|
||||
{ name: '2', value: 60 },
|
||||
{ name: '3', value: 40 },
|
||||
{ name: '4', value: 20 },
|
||||
{ name: '5', value: 10 },
|
||||
{ name: '6', value: 8 },
|
||||
{ name: '7', value: 6 },
|
||||
{ name: '8', value: 4 },
|
||||
{ name: '9', value: 2 },
|
||||
{ name: '10', value: 1 }
|
||||
{ name: '4', value: 30 },
|
||||
{ name: '5', value: 20 },
|
||||
{ name: '6', value: 15 },
|
||||
{ name: '7', value: 10 },
|
||||
{ name: '8', value: 8 },
|
||||
{ name: '9', value: 6 },
|
||||
{ name: '10', value: 3 }
|
||||
]
|
||||
|
||||
const opacitySizeList = [
|
||||
|
@ -78,8 +78,6 @@ const clearStyle = e => {
|
||||
if (text !== '') {
|
||||
document.execCommand('insertText', false, text)
|
||||
}
|
||||
|
||||
emit('input', element.value, e.target.innerHTML)
|
||||
}
|
||||
|
||||
const handleBlur = e => {
|
||||
@ -141,11 +139,12 @@ const textStyle = computed(() => {
|
||||
@mousedown="handleMousedown"
|
||||
@blur="handleBlur"
|
||||
@input="handleInput"
|
||||
v-html="element['propValue']"
|
||||
></div>
|
||||
>
|
||||
{{ element['propValue'] }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="v-text preview">
|
||||
<div class="marquee-txt" :style="textStyle" v-html="element['propValue']"></div>
|
||||
<div v-else class="v-text preview" :style="varStyle">
|
||||
<div class="marquee-txt" :style="textStyle">{{ element['propValue'] }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -1165,7 +1165,9 @@ export default {
|
||||
top_n_input_2: ', 其余合并至其他',
|
||||
top_n_label: '其他项名称',
|
||||
progress_target: '目标值',
|
||||
progress_current: '实际值'
|
||||
progress_current: '实际值',
|
||||
gauge_axis_label: '显示刻度',
|
||||
gauge_percentage_tick: '百分比刻度'
|
||||
},
|
||||
dataset: {
|
||||
scope_edit: '仅编辑时生效',
|
||||
|
@ -104,6 +104,14 @@ declare interface ChartBasicStyle {
|
||||
* 仪表盘样式
|
||||
*/
|
||||
gaugeStyle: string
|
||||
/**
|
||||
* 仪表盘刻度显示
|
||||
*/
|
||||
gaugeAxisLine: boolean
|
||||
/**
|
||||
* 仪表盘百分比刻度
|
||||
*/
|
||||
gaugePercentLabel: boolean
|
||||
/**
|
||||
* 配色方案
|
||||
*/
|
||||
|
@ -33,9 +33,9 @@ const winMsgHandle = event => {
|
||||
const msgInfo = event.data
|
||||
// 校验targetSourceId
|
||||
if (msgInfo && msgInfo.type === 'attachParams' && msgInfo.targetSourceId === state.chartId + '') {
|
||||
const attachParam = msgInfo.params
|
||||
if (attachParam) {
|
||||
dvMainStore.addOuterParamsFilter(attachParam, state.canvasDataPreview, 'outer')
|
||||
const attachParams = msgInfo.params
|
||||
if (attachParams) {
|
||||
dvMainStore.addOuterParamsFilter(attachParams, state.canvasDataPreview, 'outer')
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -58,7 +58,7 @@ onBeforeMount(async () => {
|
||||
window.addEventListener('message', winMsgHandle)
|
||||
|
||||
// 添加外部参数
|
||||
let attachParam
|
||||
let attachParams
|
||||
await getOuterParamsInfo(embeddedStore.dvId).then(rsp => {
|
||||
dvMainStore.setNowPanelOuterParamsInfo(rsp.data)
|
||||
})
|
||||
@ -67,7 +67,7 @@ onBeforeMount(async () => {
|
||||
if (embeddedStore.outerParams) {
|
||||
try {
|
||||
const outerPramsParse = JSON.parse(embeddedStore.outerParams)
|
||||
attachParam = outerPramsParse.attachParam
|
||||
attachParams = outerPramsParse.attachParams
|
||||
dvMainStore.setEmbeddedCallBack(outerPramsParse.callBackFlag || 'no')
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
@ -90,8 +90,8 @@ onBeforeMount(async () => {
|
||||
state.canvasViewInfoPreview = canvasViewInfoPreview
|
||||
state.dvInfo = dvInfo
|
||||
state.curPreviewGap = curPreviewGap
|
||||
if (attachParam) {
|
||||
dvMainStore.addOuterParamsFilter(attachParam, canvasDataResult)
|
||||
if (attachParams) {
|
||||
dvMainStore.addOuterParamsFilter(attachParams, canvasDataResult)
|
||||
}
|
||||
|
||||
viewInfo.value = canvasViewInfoPreview[embeddedStore.chartId]
|
||||
|
@ -33,7 +33,7 @@ export const dvMainStore = defineStore('dataVisualization', {
|
||||
datasetAreaCollapse: false
|
||||
},
|
||||
embeddedCallBack: 'no', // 嵌入模式是否允许反馈参数
|
||||
editMode: 'edit', // 编辑器模式 edit preview
|
||||
editMode: 'preview', // 编辑器模式 edit preview
|
||||
mobileInPc: false,
|
||||
firstLoadMap: [],
|
||||
canvasStyleData: { ...deepCopy(DEFAULT_CANVAS_STYLE_DATA_DARK), backgroundColor: null },
|
||||
|
@ -231,7 +231,12 @@ init()
|
||||
<div @keydown.stop @keyup.stop style="width: 100%; margin-bottom: 16px">
|
||||
<!--仪表盘-->
|
||||
<el-col v-show="showProperty('gaugeThreshold')">
|
||||
<el-form ref="thresholdForm" :model="state.thresholdForm" label-position="top">
|
||||
<el-form
|
||||
:model="state.thresholdForm"
|
||||
ref="thresholdForm"
|
||||
label-position="top"
|
||||
@submit.prevent
|
||||
>
|
||||
<el-form-item
|
||||
:label="t('chart.threshold_range') + '(%)'"
|
||||
class="form-item"
|
||||
@ -261,7 +266,12 @@ init()
|
||||
</el-form>
|
||||
</el-col>
|
||||
<el-col v-show="showProperty('liquidThreshold')">
|
||||
<el-form ref="thresholdForm" :model="state.thresholdForm" label-position="top">
|
||||
<el-form
|
||||
:model="state.thresholdForm"
|
||||
ref="thresholdForm"
|
||||
label-position="top"
|
||||
@submit.prevent
|
||||
>
|
||||
<el-form-item
|
||||
:label="t('chart.threshold_range') + '(%)'"
|
||||
class="form-item"
|
||||
|
@ -777,6 +777,34 @@ onMounted(() => {
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="showProperty('gaugeAxisLine')"
|
||||
class="form-item"
|
||||
:class="'form-item-' + themes"
|
||||
>
|
||||
<el-checkbox
|
||||
v-model="state.basicStyleForm.gaugeAxisLine"
|
||||
:effect="themes"
|
||||
size="small"
|
||||
@change="changeBasicStyle('gaugeAxisLine')"
|
||||
>
|
||||
{{ t('chart.gauge_axis_label') }}</el-checkbox
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="showProperty('gaugePercentLabel') && state.basicStyleForm.gaugeAxisLine"
|
||||
class="form-item"
|
||||
:class="'form-item-' + themes"
|
||||
>
|
||||
<el-checkbox
|
||||
v-model="state.basicStyleForm.gaugePercentLabel"
|
||||
:effect="themes"
|
||||
size="small"
|
||||
@change="changeBasicStyle('gaugePercentLabel')"
|
||||
>
|
||||
{{ t('chart.gauge_percentage_tick') }}</el-checkbox
|
||||
>
|
||||
</el-form-item>
|
||||
<!--gauge end-->
|
||||
<!--bar start-->
|
||||
<el-form-item
|
||||
|
@ -3291,7 +3291,7 @@ span {
|
||||
}
|
||||
|
||||
:deep(.ed-tabs__content) {
|
||||
height: calc(100% - 33px);
|
||||
height: calc(100% - 35px);
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
@ -1435,7 +1435,9 @@ export const DEFAULT_BASIC_STYLE: ChartBasicStyle = {
|
||||
tableLayoutMode: 'grid',
|
||||
calcTopN: false,
|
||||
topN: 5,
|
||||
topNLabel: '其他'
|
||||
topNLabel: '其他',
|
||||
gaugeAxisLine: true,
|
||||
gaugePercentLabel: true
|
||||
}
|
||||
|
||||
export const BASE_VIEW_CONFIG = {
|
||||
|
@ -95,7 +95,8 @@ export class BubbleMap extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
||||
// 禁用线上地图数据
|
||||
customFetchGeoData: () => null
|
||||
}
|
||||
options = this.setupOptions(chart, options, drawOption, geoJson)
|
||||
const context = { drawOption, geoJson }
|
||||
options = this.setupOptions(chart, options, context)
|
||||
const view = new Choropleth(container, options)
|
||||
const dotLayer = this.getDotLayer(chart, geoJson, drawOption)
|
||||
this.configZoomButton(chart, view)
|
||||
@ -170,10 +171,10 @@ export class BubbleMap extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
||||
private configBasicStyle(
|
||||
chart: Chart,
|
||||
options: ChoroplethOptions,
|
||||
extra: any[]
|
||||
context: Record<string, any>
|
||||
): ChoroplethOptions {
|
||||
const { areaId }: L7PlotDrawOptions<any> = extra[0]
|
||||
const geoJson: FeatureCollection = extra[1]
|
||||
const { areaId }: L7PlotDrawOptions<any> = context.drawOption
|
||||
const geoJson: FeatureCollection = context.geoJson
|
||||
const { basicStyle, label } = parseJson(chart.customAttr)
|
||||
const senior = parseJson(chart.senior)
|
||||
const curAreaNameMapping = senior.areaMapping?.[areaId]
|
||||
@ -208,7 +209,7 @@ export class BubbleMap extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
||||
protected setupOptions(
|
||||
chart: Chart,
|
||||
options: ChoroplethOptions,
|
||||
...extra: any[]
|
||||
context: Record<string, any>
|
||||
): ChoroplethOptions {
|
||||
return flow(
|
||||
this.configEmptyDataStrategy,
|
||||
@ -216,6 +217,6 @@ export class BubbleMap extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
||||
this.configStyle,
|
||||
this.configTooltip,
|
||||
this.configBasicStyle
|
||||
)(chart, options, extra)
|
||||
)(chart, options, context)
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,8 @@ export class Map extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
||||
// 禁用线上地图数据
|
||||
customFetchGeoData: () => null
|
||||
}
|
||||
options = this.setupOptions(chart, options, drawOption, geoJson)
|
||||
const context = { drawOption, geoJson }
|
||||
options = this.setupOptions(chart, options, context)
|
||||
const view = new Choropleth(container, options)
|
||||
this.configZoomButton(chart, view)
|
||||
view.once('loaded', () => {
|
||||
@ -120,10 +121,10 @@ export class Map extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
||||
private configBasicStyle(
|
||||
chart: Chart,
|
||||
options: ChoroplethOptions,
|
||||
extra: any[]
|
||||
context: Record<string, any>
|
||||
): ChoroplethOptions {
|
||||
const { areaId }: L7PlotDrawOptions<any> = extra[0]
|
||||
const geoJson: FeatureCollection = extra[1]
|
||||
const { areaId }: L7PlotDrawOptions<any> = context.drawOption
|
||||
const geoJson: FeatureCollection = context.geoJson
|
||||
const { basicStyle, label } = parseJson(chart.customAttr)
|
||||
const senior = parseJson(chart.senior)
|
||||
const curAreaNameMapping = senior.areaMapping?.[areaId]
|
||||
@ -176,7 +177,7 @@ export class Map extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
||||
protected setupOptions(
|
||||
chart: Chart,
|
||||
options: ChoroplethOptions,
|
||||
...extra: any[]
|
||||
context: Record<string, any>
|
||||
): ChoroplethOptions {
|
||||
return flow(
|
||||
this.configEmptyDataStrategy,
|
||||
@ -185,6 +186,6 @@ export class Map extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
||||
this.configTooltip,
|
||||
this.configBasicStyle,
|
||||
this.configLegend
|
||||
)(chart, options, extra)
|
||||
)(chart, options, context)
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import {
|
||||
import { valueFormatter } from '@/views/chart/components/js/formatter'
|
||||
import { getPadding, setGradientColor } from '@/views/chart/components/js/panel/common/common_antv'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { merge } from 'lodash-es'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
@ -28,7 +29,7 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
|
||||
]
|
||||
propertyInner: EditorPropertyInner = {
|
||||
'background-overall-component': ['all'],
|
||||
'basic-style-selector': ['colors', 'alpha', 'gaugeStyle', 'gradient'],
|
||||
'basic-style-selector': ['colors', 'alpha', 'gradient', 'gaugeAxisLine', 'gaugePercentLabel'],
|
||||
'label-selector': ['fontSize', 'color', 'labelFormatter'],
|
||||
'title-selector': [
|
||||
'title',
|
||||
@ -77,10 +78,6 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
|
||||
label: {
|
||||
style: {
|
||||
fontSize: getScaleValue(12, scale) // 刻度值字体大小
|
||||
},
|
||||
formatter: function (v) {
|
||||
const r = parseFloat(v)
|
||||
return v === '0' || !r ? v : r * 100 + '%'
|
||||
}
|
||||
},
|
||||
tickLine: {
|
||||
@ -98,11 +95,15 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
|
||||
}
|
||||
}
|
||||
}
|
||||
const options = this.setupOptions(chart, initOptions, scale)
|
||||
const options = this.setupOptions(chart, initOptions, { scale })
|
||||
return new G2Gauge(container, options)
|
||||
}
|
||||
|
||||
protected configMisc(chart: Chart, options: GaugeOptions): GaugeOptions {
|
||||
protected configMisc(
|
||||
chart: Chart,
|
||||
options: GaugeOptions,
|
||||
context: Record<string, any>
|
||||
): GaugeOptions {
|
||||
const customAttr = parseJson(chart.customAttr)
|
||||
const data = chart.data.series[0].data[0]
|
||||
let min, max, startAngle, endAngle
|
||||
@ -123,6 +124,8 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
|
||||
}
|
||||
startAngle = (misc.gaugeStartAngle * Math.PI) / 180
|
||||
endAngle = (misc.gaugeEndAngle * Math.PI) / 180
|
||||
context.min = min
|
||||
context.max = max
|
||||
}
|
||||
const percent = (parseFloat(data) - parseFloat(min)) / (parseFloat(max) - parseFloat(min))
|
||||
const tmp = {
|
||||
@ -133,8 +136,12 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
|
||||
return { ...options, ...tmp }
|
||||
}
|
||||
|
||||
private configRange(chart: Chart, options: GaugeOptions, extra: any[]): GaugeOptions {
|
||||
const [scale] = extra
|
||||
private configRange(
|
||||
chart: Chart,
|
||||
options: GaugeOptions,
|
||||
context: Record<string, any>
|
||||
): GaugeOptions {
|
||||
const { scale } = context
|
||||
const range = [0]
|
||||
let index = 0
|
||||
let flag = false
|
||||
@ -216,36 +223,55 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
|
||||
return { ...options, ...rangOptions }
|
||||
}
|
||||
|
||||
protected configLabel(chart: Chart, options: GaugeOptions): GaugeOptions {
|
||||
protected configLabel(
|
||||
chart: Chart,
|
||||
options: GaugeOptions,
|
||||
context?: Record<string, any>
|
||||
): GaugeOptions {
|
||||
const customAttr = parseJson(chart.customAttr)
|
||||
const data = chart.data.series[0].data[0]
|
||||
let labelContent
|
||||
if (customAttr.label) {
|
||||
const label = customAttr.label
|
||||
const labelFormatter = label.labelFormatter ?? DEFAULT_LABEL.labelFormatter
|
||||
if (label.show) {
|
||||
labelContent = {
|
||||
style: () => ({
|
||||
fontSize: label.fontSize,
|
||||
color: label.color
|
||||
}),
|
||||
formatter: function () {
|
||||
let value
|
||||
if (labelFormatter.type === 'percent') {
|
||||
value = options.percent
|
||||
} else {
|
||||
value = data
|
||||
}
|
||||
return valueFormatter(value, labelFormatter)
|
||||
let labelContent: GaugeOptions['statistic']['content'] = false
|
||||
const label = customAttr.label
|
||||
const labelFormatter = label.labelFormatter ?? DEFAULT_LABEL.labelFormatter
|
||||
if (label.show) {
|
||||
labelContent = {
|
||||
style: {
|
||||
fontSize: `${label.fontSize}`,
|
||||
color: label.color
|
||||
},
|
||||
formatter: function () {
|
||||
let value
|
||||
if (labelFormatter.type === 'percent') {
|
||||
value = options.percent
|
||||
} else {
|
||||
value = data
|
||||
}
|
||||
return valueFormatter(value, labelFormatter)
|
||||
}
|
||||
} else {
|
||||
labelContent = false
|
||||
}
|
||||
} as GaugeOptions['statistic']['content']
|
||||
}
|
||||
const statistic = {
|
||||
content: labelContent
|
||||
}
|
||||
const { gaugeAxisLine, gaugePercentLabel } = customAttr.basicStyle
|
||||
const { min, max } = context
|
||||
const tmp = {
|
||||
axis: {
|
||||
label: {
|
||||
formatter: v => {
|
||||
if (gaugeAxisLine === false) {
|
||||
return ''
|
||||
}
|
||||
if (gaugePercentLabel === false) {
|
||||
const val = v === '0' ? min : v === '1' ? max : min + (max - min) * v
|
||||
return valueFormatter(val, labelFormatter)
|
||||
}
|
||||
return v === '0' ? v : v * 100 + '%'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
options = merge(options, tmp)
|
||||
return { ...options, statistic }
|
||||
}
|
||||
|
||||
@ -263,13 +289,17 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
|
||||
return chart
|
||||
}
|
||||
|
||||
protected setupOptions(chart: Chart, options: GaugeOptions, ...extra: any[]): GaugeOptions {
|
||||
protected setupOptions(
|
||||
chart: Chart,
|
||||
options: GaugeOptions,
|
||||
context: Record<string, any>
|
||||
): GaugeOptions {
|
||||
return flow(
|
||||
this.configTheme,
|
||||
this.configMisc,
|
||||
this.configLabel,
|
||||
this.configRange
|
||||
)(chart, options, extra)
|
||||
)(chart, options, context)
|
||||
}
|
||||
constructor() {
|
||||
super('gauge', DEFAULT_DATA)
|
||||
|
@ -139,7 +139,7 @@ export abstract class G2PlotChartView<
|
||||
* @param chart 数据库图表对象。
|
||||
* @param options 各个图表的参数,泛化的 Options,可以自行扩展,比如加个扩展 X 轴或者扩展 Y 轴字段。
|
||||
*/
|
||||
protected abstract setupOptions(chart: Chart, options: O): O
|
||||
protected abstract setupOptions(chart: Chart, options: O, context?: Record<string, any>): O
|
||||
protected constructor(name: string, defaultData: any[]) {
|
||||
super(ChartLibraryType.G2_PLOT, name, defaultData)
|
||||
}
|
||||
|
@ -81,5 +81,5 @@ export abstract class L7PlotChartView<
|
||||
super(ChartLibraryType.L7_PLOT, name)
|
||||
this.defaultData = defaultData
|
||||
}
|
||||
protected abstract setupOptions(chart: Chart, options: O): O
|
||||
protected abstract setupOptions(chart: Chart, options: O, context?: Record<string, any>): O
|
||||
}
|
||||
|
@ -388,12 +388,12 @@ export function parseJson<T>(str: T | JSONString<T>): T {
|
||||
return JSON.parse(str) as T
|
||||
}
|
||||
|
||||
type FlowFunction<P, R> = (param: P, result: R, extra?: any[]) => R
|
||||
type FlowFunction<P, R> = (param: P, result: R, context?: Record<string, any>) => R
|
||||
|
||||
export function flow<P, R>(...flows: FlowFunction<P, R>[]): FlowFunction<P, R> {
|
||||
return (param: P, result: R, extra?: any[]) => {
|
||||
return (param: P, result: R, context?: Record<string, any>) => {
|
||||
return flows.reduce((result: R, flow: FlowFunction<P, R>) => {
|
||||
return flow(param, result, extra)
|
||||
return flow(param, result, context)
|
||||
}, result)
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,19 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { ref, computed, onMounted, watch } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
import treeSort from '@/utils/treeSortUtils'
|
||||
import { BusiTreeRequest } from '@/models/tree/TreeNode'
|
||||
import { interactiveStoreWithOut } from '@/store/modules/interactive'
|
||||
import DashboardCell from '@/views/mobile/components/DashboardCell.vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
import VanSticky from 'vant/es/sticky'
|
||||
import VanNavBar from 'vant/es/nav-bar'
|
||||
import 'vant/es/nav-bar/style'
|
||||
import 'vant/es/sticky/style'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
const anyManage = ref(false)
|
||||
const rootManage = ref(false)
|
||||
const tableData = ref([])
|
||||
@ -21,6 +24,7 @@ const interactiveStore = interactiveStoreWithOut()
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { dvInfo } = storeToRefs(dvMainStore)
|
||||
const { wsCache } = useCache('sessionStorage')
|
||||
const { t } = useI18n()
|
||||
|
||||
const dfsTree = (ids, arr) => {
|
||||
const id = ids.shift()
|
||||
@ -36,6 +40,8 @@ const dfsTree = (ids, arr) => {
|
||||
}, [])
|
||||
}
|
||||
|
||||
let rawTableData = []
|
||||
|
||||
const activeTableData = computed(() => {
|
||||
return directId.value.length ? dfsTree([...directId.value], tableData.value) : tableData.value
|
||||
})
|
||||
@ -46,6 +52,7 @@ const onClickLeft = () => {
|
||||
activeDirectName.value = directName.value[directName.value.length - 1]
|
||||
directId.value.pop()
|
||||
if (!!directName.value.length) {
|
||||
tableData.value = cloneDeep(rawTableData)
|
||||
emits('hiddenTabbar', false)
|
||||
}
|
||||
}
|
||||
@ -70,7 +77,50 @@ const handleCellClick = ele => {
|
||||
})
|
||||
}
|
||||
|
||||
const filterText = ref('')
|
||||
const curSortType = ref('time_desc')
|
||||
const sortList = [
|
||||
{
|
||||
name: '按创建时间升序',
|
||||
value: 'time_asc'
|
||||
},
|
||||
{
|
||||
name: '按创建时间降序',
|
||||
value: 'time_desc',
|
||||
divided: true
|
||||
},
|
||||
{
|
||||
name: '按照名称升序',
|
||||
value: 'name_asc'
|
||||
},
|
||||
{
|
||||
name: '按照名称降序',
|
||||
value: 'name_desc'
|
||||
}
|
||||
]
|
||||
const sortTypeChange = sortType => {
|
||||
tableData.value = treeSort(cloneDeep(rawTableData), sortType)
|
||||
curSortType.value = sortType
|
||||
}
|
||||
|
||||
const searchTree = (tree, val) => {
|
||||
return tree.filter(ele => {
|
||||
if (ele.name?.toLocaleLowerCase().includes(val.toLocaleLowerCase())) {
|
||||
return true
|
||||
} else if (!!ele.children?.length) {
|
||||
ele.children = searchTree(ele.children, val)
|
||||
return !!ele.children.length
|
||||
}
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
watch(filterText, val => {
|
||||
tableData.value = searchTree(cloneDeep(rawTableData), val)
|
||||
})
|
||||
|
||||
const dataClick = val => {
|
||||
filterText.value = ''
|
||||
if (val.leaf) {
|
||||
emits('hiddenTabbar', true)
|
||||
handleCellClick(val)
|
||||
@ -109,9 +159,11 @@ const getTree = async () => {
|
||||
}
|
||||
if (nodeData.length && nodeData[0]['id'] === '0' && nodeData[0]['name'] === 'root') {
|
||||
tableData.value = dfsTableData(nodeData[0]['children'] || [])
|
||||
rawTableData = cloneDeep(tableData.value)
|
||||
return
|
||||
}
|
||||
tableData.value = dfsTableData(nodeData)
|
||||
rawTableData = cloneDeep(tableData.value)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
@ -154,6 +206,41 @@ onMounted(() => {
|
||||
</div>
|
||||
</van-sticky>
|
||||
<div :class="!!directName.length && 'dashboard-cell-group-tab'" class="dashboard-cell-group">
|
||||
<div class="dashboard-cell-group_filter" v-if="!directName.length">
|
||||
<el-input
|
||||
:placeholder="t('commons.search')"
|
||||
v-model="filterText"
|
||||
clearable
|
||||
class="search-bar"
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon>
|
||||
<Icon name="icon_search-outline_outlined"></Icon>
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-dropdown @command="sortTypeChange" trigger="click">
|
||||
<el-icon class="filter-icon-span">
|
||||
<Icon v-if="curSortType.includes('asc')" name="dv-sort-asc" class="opt-icon"></Icon>
|
||||
<Icon v-show="curSortType.includes('desc')" name="dv-sort-desc" class="opt-icon"></Icon>
|
||||
</el-icon>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu style="width: 246px">
|
||||
<template :key="ele.value" v-for="ele in sortList">
|
||||
<el-dropdown-item
|
||||
class="ed-select-dropdown__item"
|
||||
:class="ele.value === curSortType && 'selected'"
|
||||
:command="ele.value"
|
||||
>
|
||||
{{ ele.name }}
|
||||
</el-dropdown-item>
|
||||
<li v-if="ele.divided" class="ed-dropdown-menu__item--divided"></li>
|
||||
</template>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
|
||||
<DashboardCell
|
||||
v-for="ele in activeTableData"
|
||||
:key="ele.id"
|
||||
@ -175,6 +262,37 @@ onMounted(() => {
|
||||
height: calc(100vh - 102px);
|
||||
margin-top: 8px;
|
||||
|
||||
.dashboard-cell-group_filter {
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
padding-bottom: 8px;
|
||||
width: calc(100% - 40px);
|
||||
}
|
||||
.filter-icon-span {
|
||||
border: 1px solid #bbbfc4;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
color: #1f2329;
|
||||
padding: 8px;
|
||||
margin-left: 8px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
|
||||
.opt-icon:focus {
|
||||
outline: none !important;
|
||||
}
|
||||
&:hover {
|
||||
background: #f5f6f7;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: #eff0f1;
|
||||
}
|
||||
}
|
||||
|
||||
&.dashboard-cell-group-tab {
|
||||
margin-top: 0;
|
||||
height: calc(100vh - 146px);
|
||||
|
2
de-xpack
2
de-xpack
@ -1 +1 @@
|
||||
Subproject commit bb62e69151febc7a98ed7865298cddbadb072248
|
||||
Subproject commit 4f83c4df67befbd90eb219b2d6d04c04e213179f
|
Loading…
Reference in New Issue
Block a user