feat: update

This commit is contained in:
Fine 2024-01-11 16:07:38 +08:00
parent 6c4144a5ef
commit b86184731e
5 changed files with 106 additions and 46 deletions

View File

@ -23,6 +23,7 @@ export type DashboardItem = {
name: string; name: string;
isDefault: boolean; isDefault: boolean;
expressions?: string[]; expressions?: string[];
expressionsConfig?: MetricConfigOpt[];
}; };
export interface LayoutConfig { export interface LayoutConfig {
x: number; x: number;

View File

@ -147,7 +147,22 @@ limitations under the License. -->
/> />
</div> </div>
<el-dialog v-model="MQEVisible" title="Edit MQE" width="400px"> <el-dialog v-model="MQEVisible" title="Edit MQE" width="400px">
<div>{{ t("hierarchyNodeMetrics") }}</div> <div>
<span>{{ t("hierarchyNodeMetrics") }}</span>
<el-popover placement="left" :width="400" trigger="click">
<template #reference>
<span>
<Icon class="cp ml-5" iconName="mode_edit" size="middle" />
</span>
</template>
<Metrics
:type="'hierarchyServicesConfig'"
:expressions="currentRow.expressions"
:layer="currentRow.layer"
@update="updateSettings"
/>
</el-popover>
</div>
<div class="mt-10 expressions"> <div class="mt-10 expressions">
<Tags <Tags
:tags="currentRow.expressions || []" :tags="currentRow.expressions || []"
@ -158,7 +173,7 @@ limitations under the License. -->
</div> </div>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="MQEVisible = false">Cancel</el-button> <el-button @click="MQEVisible = false"> Cancel </el-button>
<el-button type="primary" @click="saveMQE"> Confirm </el-button> <el-button type="primary" @click="saveMQE"> Confirm </el-button>
</span> </span>
</template> </template>
@ -178,6 +193,7 @@ limitations under the License. -->
import { EntityType } from "./data"; import { EntityType } from "./data";
import { isEmptyObject } from "@/utils/is"; import { isEmptyObject } from "@/utils/is";
import { WidgetType } from "@/views/dashboard/data"; import { WidgetType } from "@/views/dashboard/data";
import Metrics from "@/views/dashboard/related/topology/config/Metrics.vue";
/*global Nullable*/ /*global Nullable*/
const { t } = useI18n(); const { t } = useI18n();
@ -207,6 +223,13 @@ limitations under the License. -->
currentRow.value.expressions = params; currentRow.value.expressions = params;
} }
function updateSettings(config: any) {
currentRow.value = {
...currentRow.value,
expressionsConfig: config.hierarchyServicesConfig,
};
}
function handleEditMQE(row: DashboardItem) { function handleEditMQE(row: DashboardItem) {
MQEVisible.value = !MQEVisible.value; MQEVisible.value = !MQEVisible.value;
currentRow.value = row; currentRow.value = row;
@ -218,6 +241,7 @@ limitations under the License. -->
for (const d of dashboardStore.dashboards) { for (const d of dashboardStore.dashboards) {
if (d.id === currentRow.value.id) { if (d.id === currentRow.value.id) {
d.expressions = currentRow.value.expressions; d.expressions = currentRow.value.expressions;
d.expressionsConfig = currentRow.value.expressionsConfig;
const key = [d.layer, d.entity, d.name].join("_"); const key = [d.layer, d.entity, d.name].join("_");
const layout = sessionStorage.getItem(key) || "{}"; const layout = sessionStorage.getItem(key) || "{}";
const c = { const c = {
@ -247,8 +271,9 @@ limitations under the License. -->
items.push(d); items.push(d);
} }
dashboardStore.resetDashboards(items); dashboardStore.resetDashboards(items);
searchDashboards(1); searchDashboards(currentPage.value);
loading.value = false; loading.value = false;
MQEVisible.value = false;
} }
async function importTemplates(event: any) { async function importTemplates(event: any) {
@ -467,7 +492,7 @@ limitations under the License. -->
items.push(d); items.push(d);
} }
dashboardStore.resetDashboards(items); dashboardStore.resetDashboards(items);
searchDashboards(1); searchDashboards(currentPage.value);
loading.value = false; loading.value = false;
} }
async function handleTopLevel(row: DashboardItem) { async function handleTopLevel(row: DashboardItem) {
@ -532,7 +557,7 @@ limitations under the License. -->
items.push(d); items.push(d);
} }
dashboardStore.resetDashboards(items); dashboardStore.resetDashboards(items);
searchDashboards(1); searchDashboards(currentPage.value);
loading.value = false; loading.value = false;
} }
function handleRename(row: DashboardItem) { function handleRename(row: DashboardItem) {

View File

@ -15,9 +15,12 @@ limitations under the License. -->
<template> <template>
<div class="config-panel"> <div class="config-panel">
<div class="item mb-10"> <div class="item mb-10">
<span class="label">{{ <span class="label" v-if="type === 'hierarchyServicesConfig'">
t(dashboardStore.selectedGrid.metricMode === MetricModes.General ? "metrics" : "expressions") {{ t("expressions") }}
}}</span> </span>
<span class="label" v-else>
{{ t(dashboardStore.selectedGrid.metricMode === MetricModes.General ? "metrics" : "expressions") }}
</span>
<SelectSingle :value="currentMetric" :options="metricList" @change="changeMetric" class="selectors" /> <SelectSingle :value="currentMetric" :options="metricList" @change="changeMetric" class="selectors" />
</div> </div>
<div class="item mb-10"> <div class="item mb-10">
@ -40,7 +43,10 @@ limitations under the License. -->
@change="changeConfigs({ label: currentConfig.label })" @change="changeConfigs({ label: currentConfig.label })"
/> />
</div> </div>
<div class="item mb-10" v-if="dashboardStore.selectedGrid.metricMode === MetricModes.General"> <div
class="item mb-10"
v-if="type !== 'hierarchyServicesConfig' && dashboardStore.selectedGrid.metricMode === MetricModes.General"
>
<span class="label">{{ t("aggregation") }}</span> <span class="label">{{ t("aggregation") }}</span>
<SelectSingle <SelectSingle
:value="currentConfig.calculation" :value="currentConfig.calculation"
@ -55,21 +61,26 @@ limitations under the License. -->
<script lang="ts" setup> <script lang="ts" setup>
import { ref, computed, watch } from "vue"; import { ref, computed, watch } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { CalculationOpts, MetricModes } from "@/views/dashboard/data"; import type { Option } from "@/types/app";
import { CalculationOpts, MetricModes, EntityType, ConfigFieldTypes } from "@/views/dashboard/data";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import type { Option } from "element-plus/es/components/select-v2/src/select.types"; import getDashboard from "@/hooks/useDashboardsSession";
/*global defineEmits, defineProps */ /*global defineEmits, defineProps */
const props = defineProps({ const props = defineProps({
type: { type: String, default: "" }, type: { type: String, default: "" },
isExpression: { type: Boolean, default: true }, isExpression: { type: Boolean, default: true },
layer: { type: String, default: "" }, layer: { type: String, default: "" },
expressions: { type: Array<string>, default: () => [] },
}); });
const { t } = useI18n(); const { t } = useI18n();
const emit = defineEmits(["update"]); const emit = defineEmits(["update"]);
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const getMetrics = computed(() => { const getMetrics = computed(() => {
let metrics = []; if (props.type === "hierarchyServicesConfig") {
return props.expressions || [];
}
let metrics: string[] = [];
const { const {
linkServerExpressions, linkServerExpressions,
linkServerMetrics, linkServerMetrics,
@ -77,12 +88,7 @@ limitations under the License. -->
linkClientMetrics, linkClientMetrics,
nodeExpressions, nodeExpressions,
nodeMetrics, nodeMetrics,
hierarchyServicesConfig,
} = dashboardStore.selectedGrid; } = dashboardStore.selectedGrid;
let item: any = {};
if (hierarchyServicesConfig && props.layer) {
item = hierarchyServicesConfig.find((d: any) => d.layer === props.layer) || {};
}
switch (props.type) { switch (props.type) {
case "linkServerMetricConfig": case "linkServerMetricConfig":
metrics = props.isExpression ? linkServerExpressions : linkServerMetrics; metrics = props.isExpression ? linkServerExpressions : linkServerMetrics;
@ -93,9 +99,6 @@ limitations under the License. -->
case "nodeMetricConfig": case "nodeMetricConfig":
metrics = props.isExpression ? nodeExpressions : nodeMetrics; metrics = props.isExpression ? nodeExpressions : nodeMetrics;
break; break;
case "hierarchyServicesConfig":
metrics = item.nodeExpressions || [];
break;
} }
return metrics || []; return metrics || [];
}); });
@ -113,12 +116,18 @@ limitations under the License. -->
}); });
const currentIndex = ref<number>(0); const currentIndex = ref<number>(0);
const getMetricConfig = computed(() => { const getMetricConfig = computed(() => {
let config = []; if (props.type === "hierarchyServicesConfig") {
const { hierarchyServicesConfig } = dashboardStore.selectedGrid; const { dashboard } = getDashboard(
let item: any = {}; {
if (hierarchyServicesConfig && props.layer) { layer: props.layer || "",
item = hierarchyServicesConfig.find((d: any) => d.layer === props.layer) || {}; entity: EntityType[0].value,
},
ConfigFieldTypes.ISDEFAULT,
);
return (dashboard && dashboard.expressionsConfig) || [];
} }
let config = [];
switch (props.type) { switch (props.type) {
case "linkServerMetricConfig": case "linkServerMetricConfig":
config = dashboardStore.selectedGrid.linkServerMetricConfig; config = dashboardStore.selectedGrid.linkServerMetricConfig;
@ -129,9 +138,6 @@ limitations under the License. -->
case "nodeMetricConfig": case "nodeMetricConfig":
config = dashboardStore.selectedGrid.nodeMetricConfig; config = dashboardStore.selectedGrid.nodeMetricConfig;
break; break;
case "hierarchyServicesConfig":
config = item.expressionsConfig || [];
break;
} }
return config || []; return config || [];
}); });

View File

@ -163,7 +163,31 @@ limitations under the License. -->
} }
async function update() { async function update() {
topologyStore.queryHierarchyNodeExpressions(settings.value.hierarchyServicesConfig || []); const layerList = [];
const layerMap = new Map();
for (const n of topologyStore.hierarchyServiceNodes) {
if (layerMap.get(n.layer)) {
const arr = layerMap.get(n.layer);
arr.push(n);
layerMap.set(n.layer, arr);
} else {
layerMap.set(n.layer, [n]);
}
}
for (const d of layerMap.values()) {
layerList.push(d);
}
for (const list of layerList) {
const { dashboard } = getDashboard(
{
layer: list[0].layer || "",
entity: EntityType[0].value,
},
ConfigFieldTypes.ISDEFAULT,
);
const exp = (dashboard && dashboard.expressions) || [];
await topologyStore.queryHierarchyNodeExpressions(exp, list[0].layer);
}
draw(); draw();
popover.value = d3.select("#popover"); popover.value = d3.select("#popover");
} }
@ -209,15 +233,16 @@ limitations under the License. -->
return Number(d[item.legendMQE]) && d.isReal ? icons.CUBEERROR : icons.CUBE; return Number(d[item.legendMQE]) && d.isReal ? icons.CUBEERROR : icons.CUBE;
} }
function showNodeTip(event: MouseEvent, data: Node) { function showNodeTip(event: MouseEvent, data: Node) {
const { dashboard } = getDashboard( const dashboard =
{ getDashboard(
layer: data.layer || "", {
entity: EntityType[0].value, layer: data.layer || "",
}, entity: EntityType[0].value,
ConfigFieldTypes.ISDEFAULT, },
); ConfigFieldTypes.ISDEFAULT,
const exprssions = dashboard.nodeExpressions || []; ).dashboard || {};
const nodeMetricConfig = dashboard.nodeExpressionsConfig || []; const exprssions = dashboard.expressions || [];
const nodeMetricConfig = dashboard.expressionsConfig || [];
const html = exprssions.map((m: string, index: number) => { const html = exprssions.map((m: string, index: number) => {
const metric = const metric =
topologyStore.hierarchyNodeMetrics[data.layer || ""][m].values.find( topologyStore.hierarchyNodeMetrics[data.layer || ""][m].values.find(
@ -247,13 +272,14 @@ limitations under the License. -->
event.stopPropagation(); event.stopPropagation();
hideTip(); hideTip();
// topologyStore.setHierarchyServiceNode(d); // topologyStore.setHierarchyServiceNode(d);
const { dashboard } = getDashboard( const dashboard =
{ getDashboard(
layer: d.layer || "", {
entity: EntityType[0].value, layer: d.layer || "",
}, entity: EntityType[0].value,
ConfigFieldTypes.ISDEFAULT, },
); ConfigFieldTypes.ISDEFAULT,
).dashboard || {};
const name = dashboard.name; const name = dashboard.name;
const path = `/dashboard/${dashboardStore.layerId}/${EntityType[0].value}/${topologyStore.node.id}/${name}`; const path = `/dashboard/${dashboardStore.layerId}/${EntityType[0].value}/${topologyStore.node.id}/${name}`;
const routeUrl = router.resolve({ path }); const routeUrl = router.resolve({ path });

View File

@ -336,7 +336,9 @@ limitations under the License. -->
const nodeMetricConfig = settings.value.nodeMetricConfig || []; const nodeMetricConfig = settings.value.nodeMetricConfig || [];
const html = nodeMetrics.map((m, index) => { const html = nodeMetrics.map((m, index) => {
const metric = const metric =
topologyStore.nodeMetricValue[m].values.find((val: { id: string; value: unknown }) => val.id === data.id) || {}; (topologyStore.nodeMetricValue[m] &&
topologyStore.nodeMetricValue[m].values.find((val: { id: string; value: unknown }) => val.id === data.id)) ||
{};
const opt: MetricConfigOpt = nodeMetricConfig[index] || {}; const opt: MetricConfigOpt = nodeMetricConfig[index] || {};
const v = aggregation(metric.value, opt); const v = aggregation(metric.value, opt);
return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${v} ${opt.unit || "unknown"}</div>`; return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${v} ${opt.unit || "unknown"}</div>`;