mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-05-02 15:35:00 +00:00
feat: add content decorations to Table and Card widgets (#419)
This commit is contained in:
parent
a92365efcf
commit
61449f4b17
@ -386,5 +386,6 @@ const msg = {
|
|||||||
tabExpressions: "Tab Expressions",
|
tabExpressions: "Tab Expressions",
|
||||||
hierarchyNodeMetrics: "Metrics for Hierarchy Graph Node",
|
hierarchyNodeMetrics: "Metrics for Hierarchy Graph Node",
|
||||||
hierarchyNodeDashboard: "As dashboard for Hierarchy Graph Node",
|
hierarchyNodeDashboard: "As dashboard for Hierarchy Graph Node",
|
||||||
|
contentDecorations: "Content Decorations",
|
||||||
};
|
};
|
||||||
export default msg;
|
export default msg;
|
||||||
|
@ -386,5 +386,6 @@ const msg = {
|
|||||||
tabExpressions: "Tab Expressions",
|
tabExpressions: "Tab Expressions",
|
||||||
hierarchyNodeMetrics: "Metrics for Hierarchy Graph Node",
|
hierarchyNodeMetrics: "Metrics for Hierarchy Graph Node",
|
||||||
hierarchyNodeDashboard: "As dashboard for Hierarchy Graph Node",
|
hierarchyNodeDashboard: "As dashboard for Hierarchy Graph Node",
|
||||||
|
contentDecorations: "Content Decorations",
|
||||||
};
|
};
|
||||||
export default msg;
|
export default msg;
|
||||||
|
@ -384,5 +384,6 @@ const msg = {
|
|||||||
tabExpressions: "Tab表达式",
|
tabExpressions: "Tab表达式",
|
||||||
hierarchyNodeMetrics: "层次图节点的指标",
|
hierarchyNodeMetrics: "层次图节点的指标",
|
||||||
hierarchyNodeDashboard: "作为层次图节点的dashboard",
|
hierarchyNodeDashboard: "作为层次图节点的dashboard",
|
||||||
|
contentDecorations: "内容装饰",
|
||||||
};
|
};
|
||||||
export default msg;
|
export default msg;
|
||||||
|
1
src/types/dashboard.d.ts
vendored
1
src/types/dashboard.d.ts
vendored
@ -123,6 +123,7 @@ export interface CardConfig {
|
|||||||
fontSize?: number;
|
fontSize?: number;
|
||||||
showUnit?: boolean;
|
showUnit?: boolean;
|
||||||
textAlign?: "center" | "right" | "left";
|
textAlign?: "center" | "right" | "left";
|
||||||
|
decorations?: { [key: string]: string };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TextConfig {
|
export interface TextConfig {
|
||||||
|
@ -32,6 +32,7 @@ limitations under the License. -->
|
|||||||
:config="{
|
:config="{
|
||||||
i: 0,
|
i: 0,
|
||||||
...graph,
|
...graph,
|
||||||
|
decorations: graph?.decorations,
|
||||||
metricConfig: config.metricConfig,
|
metricConfig: config.metricConfig,
|
||||||
expressions: config.expressions || [],
|
expressions: config.expressions || [],
|
||||||
typesOfMQE: typesOfMQE || [],
|
typesOfMQE: typesOfMQE || [],
|
||||||
|
@ -32,7 +32,8 @@ limitations under the License. -->
|
|||||||
:data="states.source"
|
:data="states.source"
|
||||||
:config="{
|
:config="{
|
||||||
...graph,
|
...graph,
|
||||||
legend: (dashboardStore.selectedGrid.graph || {}).legend,
|
decorations: dashboardStore.selectedGrid.graph?.decorations,
|
||||||
|
legend: dashboardStore.selectedGrid.graph?.legend,
|
||||||
i: dashboardStore.selectedGrid.i,
|
i: dashboardStore.selectedGrid.i,
|
||||||
metricConfig: dashboardStore.selectedGrid.metricConfig,
|
metricConfig: dashboardStore.selectedGrid.metricConfig,
|
||||||
relatedTrace: dashboardStore.selectedGrid.relatedTrace,
|
relatedTrace: dashboardStore.selectedGrid.relatedTrace,
|
||||||
|
@ -13,6 +13,10 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License. -->
|
limitations under the License. -->
|
||||||
<template>
|
<template>
|
||||||
|
<div>
|
||||||
|
<span class="label">{{ t("contentDecorations") }}</span>
|
||||||
|
<content-decorations />
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span class="label">{{ t("fontSize") }}</span>
|
<span class="label">{{ t("fontSize") }}</span>
|
||||||
<el-slider
|
<el-slider
|
||||||
@ -26,7 +30,7 @@ limitations under the License. -->
|
|||||||
@change="updateConfig({ fontSize })"
|
@change="updateConfig({ fontSize })"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div>
|
||||||
<span class="label">{{ t("showUnit") }}</span>
|
<span class="label">{{ t("showUnit") }}</span>
|
||||||
<el-switch v-model="showUnit" active-text="Yes" inactive-text="No" @change="updateConfig({ showUnit })" />
|
<el-switch v-model="showUnit" active-text="Yes" inactive-text="No" @change="updateConfig({ showUnit })" />
|
||||||
</div>
|
</div>
|
||||||
@ -35,6 +39,7 @@ limitations under the License. -->
|
|||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
|
import ContentDecorations from "./components/ContentDecorations.vue";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const dashboardStore = useDashboardStore();
|
const dashboardStore = useDashboardStore();
|
||||||
|
@ -14,6 +14,10 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License. -->
|
limitations under the License. -->
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
<span class="label">{{ t("contentDecorations") }}</span>
|
||||||
|
<content-decorations />
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
<span class="label">{{ t("showValues") }}</span>
|
<span class="label">{{ t("showValues") }}</span>
|
||||||
<el-switch
|
<el-switch
|
||||||
v-model="showTableValues"
|
v-model="showTableValues"
|
||||||
@ -37,6 +41,7 @@ limitations under the License. -->
|
|||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
|
import ContentDecorations from "./components/ContentDecorations.vue";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const dashboardStore = useDashboardStore();
|
const dashboardStore = useDashboardStore();
|
||||||
|
@ -0,0 +1,100 @@
|
|||||||
|
<!-- 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 v-for="(key, index) in keys" :key="index" class="mb-10 flex-h">
|
||||||
|
<div class="content-decoration" contenteditable="true" @blur="changeKeys($event, index)">
|
||||||
|
{{ key }}
|
||||||
|
</div>
|
||||||
|
<div class="ml-5 mr-10">:</div>
|
||||||
|
<div class="content-decoration" contenteditable="true" @blur="changeValues($event, key)">
|
||||||
|
{{ decorations[key] }}
|
||||||
|
</div>
|
||||||
|
<div v-if="index === keys.length - 1">
|
||||||
|
<Icon class="cp mr-5" iconName="add_circle_outlinecontrol_point" size="middle" @click="addDecoration" />
|
||||||
|
<Icon
|
||||||
|
v-if="index !== 0"
|
||||||
|
class="cp"
|
||||||
|
iconName="remove_circle_outline"
|
||||||
|
size="middle"
|
||||||
|
@click="deleteDecoration(index)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from "vue";
|
||||||
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
|
|
||||||
|
const dashboardStore = useDashboardStore();
|
||||||
|
const graph = dashboardStore.selectedGrid.graph;
|
||||||
|
const decorations = ref<{ [key: string]: string }>(graph?.decorations || {});
|
||||||
|
const keys = ref<string[]>(graph.decorations ? Object.keys(decorations.value) : [""]);
|
||||||
|
|
||||||
|
function changeKeys(event: any, index: number) {
|
||||||
|
const params = event.target.textContent || "";
|
||||||
|
const list = Object.keys(decorations.value);
|
||||||
|
if (params) {
|
||||||
|
decorations.value[params] = decorations.value[list[index]];
|
||||||
|
}
|
||||||
|
delete decorations.value[list[index]];
|
||||||
|
keys.value = Object.keys(decorations.value);
|
||||||
|
updateConfig({ decorations: decorations.value });
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeValues(event: any, key: string) {
|
||||||
|
decorations.value[key] = event.target.textContent || "";
|
||||||
|
updateConfig({ decorations: decorations.value });
|
||||||
|
}
|
||||||
|
|
||||||
|
function addDecoration() {
|
||||||
|
keys.value.push("");
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteDecoration(index: number) {
|
||||||
|
if (!keys.value.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!keys.value[index]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
delete decorations.value[keys.value[index]];
|
||||||
|
keys.value.splice(index, 1);
|
||||||
|
updateConfig({ decorations: decorations.value });
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateConfig(param: { [key: string]: unknown }) {
|
||||||
|
const graph = {
|
||||||
|
...dashboardStore.selectedGrid.graph,
|
||||||
|
...param,
|
||||||
|
};
|
||||||
|
dashboardStore.selectWidget({ ...dashboardStore.selectedGrid, graph });
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.content-decoration {
|
||||||
|
width: 200px;
|
||||||
|
border: 1px solid $border-color;
|
||||||
|
cursor: text;
|
||||||
|
padding: 0 5px;
|
||||||
|
border-radius: 3px;
|
||||||
|
outline: none;
|
||||||
|
margin-right: 5px;
|
||||||
|
min-height: 26px;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: $active-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -22,7 +22,7 @@ limitations under the License. -->
|
|||||||
justifyContent: config.textAlign || 'center',
|
justifyContent: config.textAlign || 'center',
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ singleVal }}
|
{{ decorations[singleVal] || singleVal }}
|
||||||
<span class="unit" v-show="config.showUnit && unit">
|
<span class="unit" v-show="config.showUnit && unit">
|
||||||
{{ decodeURIComponent(unit) }}
|
{{ decodeURIComponent(unit) }}
|
||||||
</span>
|
</span>
|
||||||
@ -48,11 +48,13 @@ limitations under the License. -->
|
|||||||
showUnit: true,
|
showUnit: true,
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
metricConfig: [],
|
metricConfig: [],
|
||||||
|
decorations: {},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const metricConfig = computed(() => props.config.metricConfig || []);
|
const metricConfig = computed(() => props.config.metricConfig || []);
|
||||||
|
const decorations = computed(() => props.config.decorations || {});
|
||||||
const key = computed(() => Object.keys(props.data)[0]);
|
const key = computed(() => Object.keys(props.data)[0]);
|
||||||
const singleVal = computed(() =>
|
const singleVal = computed(() =>
|
||||||
Array.isArray(props.data[key.value]) ? props.data[key.value][0] : props.data[key.value],
|
Array.isArray(props.data[key.value]) ? props.data[key.value][0] : props.data[key.value],
|
||||||
|
@ -37,7 +37,7 @@ limitations under the License. -->
|
|||||||
>{{ k.split("=")[1] }}</div
|
>{{ k.split("=")[1] }}</div
|
||||||
>
|
>
|
||||||
<div class="value-col" v-if="config.showTableValues">
|
<div class="value-col" v-if="config.showTableValues">
|
||||||
{{ data[(keys as string[]).join(",")][data[(keys as string[]).join(",")].length - 1 || 0] }}
|
{{ getColValue(keys) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -58,12 +58,14 @@ limitations under the License. -->
|
|||||||
showTableValues: boolean;
|
showTableValues: boolean;
|
||||||
tableHeaderCol2: string;
|
tableHeaderCol2: string;
|
||||||
typesOfMQE: string[];
|
typesOfMQE: string[];
|
||||||
|
decorations: {};
|
||||||
}>,
|
}>,
|
||||||
default: () => ({ showTableValues: true }),
|
default: () => ({ showTableValues: true }),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const decorations = computed<{ [key: number]: string }>(() => props.config.decorations || {});
|
||||||
const nameWidth = computed(() => (props.config.showTableValues ? 80 : 100));
|
const nameWidth = computed(() => (props.config.showTableValues ? 80 : 100));
|
||||||
const dataKeys = computed(() => {
|
const dataKeys = computed(() => {
|
||||||
const keys = Object.keys(props.data || {}).filter(
|
const keys = Object.keys(props.data || {}).filter(
|
||||||
@ -73,6 +75,10 @@ limitations under the License. -->
|
|||||||
|
|
||||||
return list;
|
return list;
|
||||||
});
|
});
|
||||||
|
function getColValue(keys: string[]) {
|
||||||
|
const val = props.data[(keys as string[]).join(",")][props.data[(keys as string[]).join(",")].length - 1 || 0];
|
||||||
|
return decorations.value[val] || val;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.chart-table {
|
.chart-table {
|
||||||
|
Loading…
Reference in New Issue
Block a user