mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-10-15 12:49:17 +00:00
refactor: remove the General
metric mode and related logical code (#384)
This commit is contained in:
@@ -19,7 +19,7 @@ limitations under the License. -->
|
||||
{{ t("expressions") }}
|
||||
</span>
|
||||
<span class="label" v-else>
|
||||
{{ t(dashboardStore.selectedGrid.metricMode === MetricModes.General ? "metrics" : "expressions") }}
|
||||
{{ t("expressions") }}
|
||||
</span>
|
||||
<SelectSingle :value="currentMetric" :options="metricList" @change="changeMetric" class="selectors" />
|
||||
</div>
|
||||
@@ -43,33 +43,19 @@ limitations under the License. -->
|
||||
@change="changeConfigs({ label: currentConfig.label })"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="item mb-10"
|
||||
v-if="type !== 'hierarchyServicesConfig' && dashboardStore.selectedGrid.metricMode === MetricModes.General"
|
||||
>
|
||||
<span class="label">{{ t("aggregation") }}</span>
|
||||
<SelectSingle
|
||||
:value="currentConfig.calculation"
|
||||
:options="CalculationOpts"
|
||||
@change="changeConfigs({ calculation: $event })"
|
||||
class="selectors"
|
||||
:clearable="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import type { Option } from "@/types/app";
|
||||
import { CalculationOpts, MetricModes, EntityType, ConfigFieldTypes } from "@/views/dashboard/data";
|
||||
import { EntityType, ConfigFieldTypes } from "@/views/dashboard/data";
|
||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||
import getDashboard from "@/hooks/useDashboardsSession";
|
||||
|
||||
/*global defineEmits, defineProps */
|
||||
const props = defineProps({
|
||||
type: { type: String, default: "" },
|
||||
isExpression: { type: Boolean, default: true },
|
||||
layer: { type: String, default: "" },
|
||||
expressions: { type: Array<string>, default: () => [] },
|
||||
entity: { type: String, default: EntityType[0].value },
|
||||
@@ -82,23 +68,16 @@ limitations under the License. -->
|
||||
return props.expressions || [];
|
||||
}
|
||||
let metrics: string[] = [];
|
||||
const {
|
||||
linkServerExpressions,
|
||||
linkServerMetrics,
|
||||
linkClientExpressions,
|
||||
linkClientMetrics,
|
||||
nodeExpressions,
|
||||
nodeMetrics,
|
||||
} = dashboardStore.selectedGrid;
|
||||
const { linkServerExpressions, linkClientExpressions, nodeExpressions } = dashboardStore.selectedGrid;
|
||||
switch (props.type) {
|
||||
case "linkServerMetricConfig":
|
||||
metrics = props.isExpression ? linkServerExpressions : linkServerMetrics;
|
||||
metrics = linkServerExpressions;
|
||||
break;
|
||||
case "linkClientMetricConfig":
|
||||
metrics = props.isExpression ? linkClientExpressions : linkClientMetrics;
|
||||
metrics = linkClientExpressions;
|
||||
break;
|
||||
case "nodeMetricConfig":
|
||||
metrics = props.isExpression ? nodeExpressions : nodeMetrics;
|
||||
metrics = nodeExpressions;
|
||||
break;
|
||||
}
|
||||
return metrics || [];
|
||||
|
@@ -13,17 +13,6 @@ 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="mt-20">
|
||||
<h5 class="title">{{ t("metricMode") }}</h5>
|
||||
<el-switch
|
||||
v-model="isExpression"
|
||||
class="mt-5"
|
||||
active-text="Expressions"
|
||||
inactive-text="General"
|
||||
size="small"
|
||||
@change="changeMetricMode"
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-20">
|
||||
<h5 class="title">{{ t("callSettings") }}</h5>
|
||||
<div class="label">{{ t("linkDashboard") }}</div>
|
||||
@@ -38,21 +27,16 @@ limitations under the License. -->
|
||||
/>
|
||||
<div class="label">
|
||||
<span>{{ t("linkServerMetrics") }}</span>
|
||||
<el-popover
|
||||
placement="left"
|
||||
:width="400"
|
||||
trigger="click"
|
||||
v-if="isExpression ? states.linkServerExpressions.length : states.linkServerMetrics.length"
|
||||
>
|
||||
<el-popover placement="left" :width="400" trigger="click" v-if="states.linkServerExpressions.length">
|
||||
<template #reference>
|
||||
<span @click="setConfigType('linkServerMetricConfig')">
|
||||
<Icon class="cp ml-5" iconName="mode_edit" size="middle" />
|
||||
</span>
|
||||
</template>
|
||||
<Metrics :type="configType" :isExpression="isExpression" @update="updateSettings" />
|
||||
<Metrics :type="configType" @update="updateSettings" />
|
||||
</el-popover>
|
||||
</div>
|
||||
<div v-if="isExpression">
|
||||
<div>
|
||||
<Tags
|
||||
:tags="states.linkServerExpressions"
|
||||
:vertical="true"
|
||||
@@ -60,34 +44,19 @@ limitations under the License. -->
|
||||
@change="(param: string[]) => changeLinkServerExpressions(param)"
|
||||
/>
|
||||
</div>
|
||||
<Selector
|
||||
v-else
|
||||
class="inputs"
|
||||
:multiple="true"
|
||||
:value="states.linkServerMetrics"
|
||||
:options="states.linkMetricList"
|
||||
size="small"
|
||||
placeholder="Select metrics"
|
||||
@change="updateLinkServerMetrics"
|
||||
/>
|
||||
<span v-show="dashboardStore.entity !== EntityType[2].value">
|
||||
<div class="label">
|
||||
<span>{{ t("linkClientMetrics") }}</span>
|
||||
<el-popover
|
||||
placement="left"
|
||||
:width="400"
|
||||
trigger="click"
|
||||
v-if="isExpression ? states.linkClientExpressions.length : states.linkClientMetrics.length"
|
||||
>
|
||||
<el-popover placement="left" :width="400" trigger="click" v-if="states.linkClientExpressions.length">
|
||||
<template #reference>
|
||||
<span @click="setConfigType('linkClientMetricConfig')">
|
||||
<Icon class="cp ml-5" iconName="mode_edit" size="middle" />
|
||||
</span>
|
||||
</template>
|
||||
<Metrics :type="configType" :isExpression="isExpression" @update="updateSettings" />
|
||||
<Metrics :type="configType" @update="updateSettings" />
|
||||
</el-popover>
|
||||
</div>
|
||||
<div v-if="isExpression">
|
||||
<div>
|
||||
<Tags
|
||||
:tags="states.linkClientExpressions"
|
||||
:vertical="true"
|
||||
@@ -95,16 +64,6 @@ limitations under the License. -->
|
||||
@change="(param: string[]) => changeLinkClientExpressions(param)"
|
||||
/>
|
||||
</div>
|
||||
<Selector
|
||||
v-else
|
||||
class="inputs"
|
||||
:multiple="true"
|
||||
:value="states.linkClientMetrics"
|
||||
:options="states.linkMetricList"
|
||||
size="small"
|
||||
placeholder="Select metrics"
|
||||
@change="updateLinkClientMetrics"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
@@ -149,21 +108,16 @@ limitations under the License. -->
|
||||
</div>
|
||||
<div class="label">
|
||||
<span>{{ t("nodeMetrics") }}</span>
|
||||
<el-popover
|
||||
placement="left"
|
||||
:width="400"
|
||||
trigger="click"
|
||||
v-if="isExpression ? states.nodeExpressions.length : states.nodeMetrics.length"
|
||||
>
|
||||
<el-popover placement="left" :width="400" trigger="click" v-if="states.nodeExpressions.length">
|
||||
<template #reference>
|
||||
<span @click="setConfigType('nodeMetricConfig')">
|
||||
<Icon class="cp ml-5" iconName="mode_edit" size="middle" />
|
||||
</span>
|
||||
</template>
|
||||
<Metrics :type="configType" :isExpression="isExpression" @update="updateSettings" />
|
||||
<Metrics :type="configType" @update="updateSettings" />
|
||||
</el-popover>
|
||||
</div>
|
||||
<div v-if="isExpression">
|
||||
<div>
|
||||
<Tags
|
||||
:tags="states.nodeExpressions"
|
||||
:vertical="true"
|
||||
@@ -171,28 +125,17 @@ limitations under the License. -->
|
||||
@change="(param: string[]) => changeNodeExpressions(param)"
|
||||
/>
|
||||
</div>
|
||||
<Selector
|
||||
v-else
|
||||
class="inputs"
|
||||
:multiple="true"
|
||||
:value="states.nodeMetrics"
|
||||
:options="states.nodeMetricList"
|
||||
size="small"
|
||||
placeholder="Select metrics"
|
||||
@change="updateNodeMetrics"
|
||||
/>
|
||||
</div>
|
||||
<div v-show="isService">
|
||||
<h5 class="title">{{ t("legendSettings") }}</h5>
|
||||
<span v-if="isExpression">
|
||||
<span>
|
||||
<div class="label">Healthy Description</div>
|
||||
<el-input v-model="description.healthy" placeholder="Please input description" size="small" class="mt-5" />
|
||||
</span>
|
||||
<div class="label">
|
||||
<span>{{ t(isExpression ? "unhealthyExpression" : "conditions") }}</span>
|
||||
<span>{{ t("unhealthyExpression") }}</span>
|
||||
<el-tooltip
|
||||
class="cp"
|
||||
v-if="isExpression"
|
||||
content="The node would be red to indicate unhealthy status when the expression return greater than 0"
|
||||
>
|
||||
<span>
|
||||
@@ -200,50 +143,9 @@ limitations under the License. -->
|
||||
</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div v-if="isExpression">
|
||||
<div>
|
||||
<el-input v-model="legendMQE.expression" placeholder="Please input a expression" size="small" class="inputs" />
|
||||
</div>
|
||||
<div v-for="(metric, index) of legend" :key="index" v-else>
|
||||
<Selector
|
||||
class="item"
|
||||
:value="metric.name"
|
||||
:options="states.nodeMetricList"
|
||||
size="small"
|
||||
placeholder="Select a metric"
|
||||
@change="changeLegend(LegendOpt.NAME, $event, index)"
|
||||
/>
|
||||
<Selector
|
||||
class="input-small"
|
||||
:value="metric.condition"
|
||||
:options="MetricConditions"
|
||||
size="small"
|
||||
placeholder="Select a condition"
|
||||
@change="changeLegend(LegendOpt.CONDITION, $event, index)"
|
||||
/>
|
||||
<el-input
|
||||
v-model="metric.value"
|
||||
placeholder="Please input a value"
|
||||
type="number"
|
||||
@change="changeLegend(LegendOpt.VALUE, $event, index)"
|
||||
size="small"
|
||||
class="item"
|
||||
/>
|
||||
<span>
|
||||
<Icon class="cp delete" iconName="remove_circle_outline" size="middle" @click="deleteMetric(index)" />
|
||||
<Icon
|
||||
class="cp"
|
||||
iconName="add_circle_outlinecontrol_point"
|
||||
size="middle"
|
||||
v-show="index === legend.length - 1 && legend.length < 5"
|
||||
@click="addMetric"
|
||||
/>
|
||||
</span>
|
||||
<div v-show="index !== legend.length - 1">&&</div>
|
||||
</div>
|
||||
<span v-if="!isExpression">
|
||||
<div class="label">Healthy Description</div>
|
||||
<el-input v-model="description.healthy" placeholder="Please input description" size="small" class="mt-5" />
|
||||
</span>
|
||||
<div class="label">Unhealthy Description</div>
|
||||
<el-input v-model="description.unhealthy" placeholder="Please input description" size="small" class="mt-5" />
|
||||
<el-button @click="setLegend" class="mt-20" size="small" type="primary">
|
||||
@@ -257,20 +159,9 @@ limitations under the License. -->
|
||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||
import { useTopologyStore } from "@/store/modules/topology";
|
||||
import { ElMessage } from "element-plus";
|
||||
import {
|
||||
MetricCatalog,
|
||||
ScopeType,
|
||||
MetricConditions,
|
||||
EntityType,
|
||||
LegendOpt,
|
||||
MetricsType,
|
||||
MetricModes,
|
||||
CallTypes,
|
||||
} from "@/views/dashboard/data";
|
||||
import { ScopeType, EntityType, CallTypes } from "@/views/dashboard/data";
|
||||
import type { Option } from "@/types/app";
|
||||
import { useQueryTopologyMetrics } from "@/hooks/useMetricsProcessor";
|
||||
import { useQueryTopologyExpressionsProcessor } from "@/hooks/useExpressionsProcessor";
|
||||
import type { Node } from "@/types/topology";
|
||||
import type { DashboardItem, MetricConfigOpt } from "@/types/dashboard";
|
||||
import Metrics from "./Metrics.vue";
|
||||
|
||||
@@ -280,7 +171,6 @@ limitations under the License. -->
|
||||
const dashboardStore = useDashboardStore();
|
||||
const topologyStore = useTopologyStore();
|
||||
const { selectedGrid } = dashboardStore;
|
||||
const isExpression = ref<boolean>(dashboardStore.selectedGrid.metricMode === MetricModes.Expression);
|
||||
const nodeDashboard =
|
||||
selectedGrid.nodeDashboard && selectedGrid.nodeDashboard.length ? selectedGrid.nodeDashboard : "";
|
||||
const isService = [EntityType[0].value, EntityType[1].value].includes(dashboardStore.entity);
|
||||
@@ -296,11 +186,6 @@ limitations under the License. -->
|
||||
scope: string;
|
||||
dashboard: string;
|
||||
}[];
|
||||
linkServerMetrics: string[];
|
||||
linkClientMetrics: string[];
|
||||
nodeMetrics: string[];
|
||||
nodeMetricList: Option[];
|
||||
linkMetricList: Option[];
|
||||
linkDashboards: (DashboardItem & { label: string; value: string })[];
|
||||
nodeDashboards: (DashboardItem & { label: string; value: string })[];
|
||||
linkServerExpressions: string[];
|
||||
@@ -309,27 +194,18 @@ limitations under the License. -->
|
||||
}>({
|
||||
linkDashboard: selectedGrid.linkDashboard || "",
|
||||
nodeDashboard: selectedGrid.nodeDashboard || [],
|
||||
linkServerMetrics: selectedGrid.linkServerMetrics || [],
|
||||
linkClientMetrics: selectedGrid.linkClientMetrics || [],
|
||||
nodeMetrics: selectedGrid.nodeMetrics || [],
|
||||
nodeMetricList: [],
|
||||
linkMetricList: [],
|
||||
linkDashboards: [],
|
||||
nodeDashboards: [],
|
||||
linkServerExpressions: selectedGrid.linkServerExpressions || [],
|
||||
linkClientExpressions: selectedGrid.linkClientExpressions || [],
|
||||
nodeExpressions: selectedGrid.nodeExpressions || [],
|
||||
});
|
||||
const l = selectedGrid.legend && selectedGrid.legend.length;
|
||||
const legend = ref<{ name: string; condition: string; value: string }[]>(
|
||||
l ? selectedGrid.legend : [{ name: "", condition: "", value: "" }],
|
||||
);
|
||||
const legendMQE = ref<{ expression: string }>(selectedGrid.legendMQE || { expression: "" });
|
||||
const configType = ref<string>("");
|
||||
const description = reactive<any>(selectedGrid.description || {});
|
||||
|
||||
getMetricList();
|
||||
async function getMetricList() {
|
||||
getDashboardList();
|
||||
async function getDashboardList() {
|
||||
const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
|
||||
const json = await dashboardStore.fetchMetricList();
|
||||
if (json.errors) {
|
||||
@@ -351,13 +227,6 @@ limitations under the License. -->
|
||||
},
|
||||
[],
|
||||
);
|
||||
states.nodeMetricList = (json.data.metrics || []).filter(
|
||||
(d: { type: string }) => d.type === MetricsType.REGULAR_VALUE,
|
||||
);
|
||||
states.linkMetricList = (json.data.metrics || []).filter(
|
||||
(d: { catalog: string; type: string }) =>
|
||||
entity + "Relation" === (MetricCatalog as any)[d.catalog] && d.type === MetricsType.REGULAR_VALUE,
|
||||
);
|
||||
if (isService) {
|
||||
return;
|
||||
}
|
||||
@@ -373,36 +242,15 @@ limitations under the License. -->
|
||||
}
|
||||
async function setLegend() {
|
||||
updateSettings();
|
||||
if (isExpression.value) {
|
||||
const expression = dashboardStore.selectedGrid.legendMQE && dashboardStore.selectedGrid.legendMQE.expression;
|
||||
if (!expression) {
|
||||
emit("updateNodes");
|
||||
return;
|
||||
}
|
||||
const { getExpressionQuery } = useQueryTopologyExpressionsProcessor([expression], topologyStore.nodes);
|
||||
const param = getExpressionQuery();
|
||||
const res = await topologyStore.getNodeExpressionValue(param);
|
||||
if (res.errors) {
|
||||
ElMessage.error(res.errors);
|
||||
} else {
|
||||
topologyStore.setLegendValues([expression], res.data);
|
||||
}
|
||||
const expression = dashboardStore.selectedGrid.legendMQE && dashboardStore.selectedGrid.legendMQE.expression;
|
||||
const { getExpressionQuery } = useQueryTopologyExpressionsProcessor([expression], topologyStore.nodes);
|
||||
const param = getExpressionQuery();
|
||||
const res = await topologyStore.getNodeExpressionValue(param);
|
||||
if (res.errors) {
|
||||
ElMessage.error(res.errors);
|
||||
} else {
|
||||
const names = dashboardStore.selectedGrid.legend.map((d: any) => d.name && d.condition && d.value);
|
||||
if (!names.length) {
|
||||
emit("updateNodes");
|
||||
return;
|
||||
}
|
||||
const ids = topologyStore.nodes.map((d: Node) => d.id);
|
||||
const param = await useQueryTopologyMetrics(names, ids);
|
||||
const res = await topologyStore.getLegendMetrics(param);
|
||||
|
||||
if (res.errors) {
|
||||
ElMessage.error(res.errors);
|
||||
}
|
||||
topologyStore.setLegendValues([expression], res.data);
|
||||
}
|
||||
|
||||
emit("updateNodes");
|
||||
}
|
||||
function changeNodeDashboard(opt: any) {
|
||||
states.nodeDashboard = opt[0].value;
|
||||
@@ -412,9 +260,6 @@ limitations under the License. -->
|
||||
states.linkDashboard = opt[0].value;
|
||||
updateSettings();
|
||||
}
|
||||
function changeLegend(type: string, opt: any, index: number) {
|
||||
(legend.value[index] as any)[type] = opt[0].value || opt;
|
||||
}
|
||||
function changeScope(index: number, opt: Option[] | any) {
|
||||
items[index].scope = opt[0].value;
|
||||
const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
|
||||
@@ -445,27 +290,15 @@ limitations under the License. -->
|
||||
updateSettings();
|
||||
}
|
||||
function updateSettings(metricConfig?: { [key: string]: MetricConfigOpt[] }) {
|
||||
let metrics = [];
|
||||
if (isExpression.value) {
|
||||
metrics = legend.value.filter((d: any) => d.name);
|
||||
} else {
|
||||
metrics = legend.value.filter((d: any) => d.name && d.value && d.condition);
|
||||
}
|
||||
|
||||
const param = {
|
||||
...dashboardStore.selectedGrid,
|
||||
linkDashboard: states.linkDashboard,
|
||||
nodeDashboard: isService
|
||||
? items.filter((d: { scope: string; dashboard: string }) => d.dashboard)
|
||||
: states.nodeDashboard,
|
||||
linkServerMetrics: states.linkServerMetrics,
|
||||
linkClientMetrics: states.linkClientMetrics,
|
||||
nodeMetrics: states.nodeMetrics,
|
||||
linkServerExpressions: states.linkServerExpressions,
|
||||
linkClientExpressions: states.linkClientExpressions,
|
||||
nodeExpressions: states.nodeExpressions,
|
||||
metricMode: isExpression.value ? MetricModes.Expression : MetricModes.General,
|
||||
legend: metrics,
|
||||
legendMQE: legendMQE.value,
|
||||
...metricConfig,
|
||||
description,
|
||||
@@ -474,30 +307,8 @@ limitations under the License. -->
|
||||
dashboardStore.setConfigs(param);
|
||||
emit("update", param);
|
||||
}
|
||||
function updateLinkServerMetrics(options: Option[] | any) {
|
||||
const opt = options.map((d: Option) => d.value);
|
||||
const index = states.linkServerMetrics.findIndex((d: any) => !opt.includes(d));
|
||||
states.linkServerMetrics = opt;
|
||||
if (index < 0) {
|
||||
changeLinkServerMetrics();
|
||||
return;
|
||||
}
|
||||
const origin = dashboardStore.selectedGrid.linkServerMetricConfig || [];
|
||||
const config = origin.length === 1 ? [] : origin.splice(index, 1);
|
||||
changeLinkServerMetrics({ linkServerMetricConfig: config });
|
||||
}
|
||||
async function changeLinkServerMetrics(config?: { [key: string]: MetricConfigOpt[] }) {
|
||||
updateSettings(config);
|
||||
if (!states.linkServerMetrics.length) {
|
||||
topologyStore.setLinkServerMetrics({});
|
||||
return;
|
||||
}
|
||||
topologyStore.getLinkServerMetrics(states.linkServerMetrics);
|
||||
}
|
||||
|
||||
function changeLinkServerExpressions(param: string[]) {
|
||||
if (!isExpression.value) {
|
||||
return;
|
||||
}
|
||||
states.linkServerExpressions = param;
|
||||
updateSettings();
|
||||
if (!states.linkServerExpressions.length) {
|
||||
@@ -507,9 +318,6 @@ limitations under the License. -->
|
||||
topologyStore.getLinkExpressions(states.linkServerExpressions, CallTypes.Server);
|
||||
}
|
||||
function changeLinkClientExpressions(param: string[]) {
|
||||
if (!isExpression.value) {
|
||||
return;
|
||||
}
|
||||
states.linkClientExpressions = param;
|
||||
updateSettings();
|
||||
if (!states.linkClientExpressions.length) {
|
||||
@@ -518,63 +326,11 @@ limitations under the License. -->
|
||||
}
|
||||
topologyStore.getLinkExpressions(states.linkClientExpressions, CallTypes.Client);
|
||||
}
|
||||
function updateLinkClientMetrics(options: Option[] | any) {
|
||||
const opt = options.map((d: Option) => d.value);
|
||||
const index = states.linkClientMetrics.findIndex((d: any) => !opt.includes(d));
|
||||
states.linkClientMetrics = opt;
|
||||
if (index < 0) {
|
||||
changeLinkClientMetrics();
|
||||
return;
|
||||
}
|
||||
const origin = dashboardStore.selectedGrid.linkClientMetricConfig || [];
|
||||
const config = origin.length === 1 ? [] : origin.splice(index, 1);
|
||||
changeLinkClientMetrics({ linkClientMetricConfig: config });
|
||||
}
|
||||
async function changeLinkClientMetrics(config?: { [key: string]: MetricConfigOpt[] }) {
|
||||
updateSettings(config);
|
||||
if (!states.linkClientMetrics.length) {
|
||||
topologyStore.setLinkClientMetrics({});
|
||||
return;
|
||||
}
|
||||
topologyStore.getLinkClientMetrics(states.linkClientMetrics);
|
||||
}
|
||||
function updateNodeMetrics(options: Option[] | any) {
|
||||
const opt = options.map((d: Option) => d.value);
|
||||
const index = states.nodeMetrics.findIndex((d: any) => !opt.includes(d));
|
||||
states.nodeMetrics = opt;
|
||||
if (index < 0) {
|
||||
changeNodeMetrics();
|
||||
return;
|
||||
}
|
||||
const origin = dashboardStore.selectedGrid.nodeMetricConfig || [];
|
||||
const config = origin.length === 1 ? [] : origin.splice(index, 1);
|
||||
changeNodeMetrics({ nodeMetricConfig: config });
|
||||
}
|
||||
async function changeNodeMetrics(config?: { [key: string]: MetricConfigOpt[] }) {
|
||||
updateSettings(config);
|
||||
if (!states.nodeMetrics.length) {
|
||||
topologyStore.setNodeMetricValue({});
|
||||
return;
|
||||
}
|
||||
topologyStore.queryNodeMetrics(states.nodeMetrics);
|
||||
}
|
||||
function deleteMetric(index: number) {
|
||||
if (legend.value.length === 1) {
|
||||
legend.value = [{ name: "", condition: "", value: "" }];
|
||||
return;
|
||||
}
|
||||
legend.value.splice(index, 1);
|
||||
}
|
||||
function addMetric() {
|
||||
legend.value.push({ name: "", condition: "", value: "" });
|
||||
}
|
||||
|
||||
function setConfigType(type: string) {
|
||||
configType.value = type;
|
||||
}
|
||||
function changeNodeExpressions(param: string[]) {
|
||||
if (!isExpression.value) {
|
||||
return;
|
||||
}
|
||||
states.nodeExpressions = param;
|
||||
updateSettings();
|
||||
if (!states.nodeExpressions.length) {
|
||||
@@ -583,25 +339,6 @@ limitations under the License. -->
|
||||
}
|
||||
topologyStore.queryNodeExpressions(states.nodeExpressions);
|
||||
}
|
||||
function changeMetricMode() {
|
||||
legend.value = [{ name: "", condition: "", value: "" }];
|
||||
const config = {
|
||||
linkServerMetricConfig: [],
|
||||
linkClientMetricConfig: [],
|
||||
nodeMetricConfig: [],
|
||||
};
|
||||
if (isExpression.value) {
|
||||
states.linkServerMetrics = [];
|
||||
states.linkClientMetrics = [];
|
||||
states.nodeMetrics = [];
|
||||
} else {
|
||||
states.linkServerExpressions = [];
|
||||
states.linkClientExpressions = [];
|
||||
states.nodeExpressions = [];
|
||||
}
|
||||
|
||||
updateSettings(config);
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.inputs {
|
||||
|
@@ -41,7 +41,6 @@ limitations under the License. -->
|
||||
import router from "@/router";
|
||||
import { ElMessage } from "element-plus";
|
||||
import type { MetricConfigOpt } from "@/types/dashboard";
|
||||
import { aggregation } from "@/hooks/useMetricsProcessor";
|
||||
import getDashboard from "@/hooks/useDashboardsSession";
|
||||
import Graph from "../components/Graph.vue";
|
||||
|
||||
@@ -129,8 +128,8 @@ limitations under the License. -->
|
||||
(val: { id: string; value: unknown }) => val.id === data.id,
|
||||
) || {};
|
||||
const opt: MetricConfigOpt = nodeMetricConfig[index] || {};
|
||||
const v = aggregation(metric.value, opt);
|
||||
return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${v} ${opt.unit || ""}</div>`;
|
||||
|
||||
return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${metric.value} ${opt.unit || ""}</div>`;
|
||||
});
|
||||
const tipHtml = [
|
||||
`<div class="mb-5"><span class="grey">name: </span>${data.name}</div><div class="mb-5"><span class="grey">layer: </span>${data.layer}</div>`,
|
||||
|
@@ -69,7 +69,7 @@ limitations under the License. -->
|
||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||
import { useSelectorStore } from "@/store/modules/selectors";
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
import { EntityType, DepthList, MetricModes, CallTypes } from "@/views/dashboard/data";
|
||||
import { EntityType, DepthList, CallTypes } from "@/views/dashboard/data";
|
||||
import { ElMessage } from "element-plus";
|
||||
import Sankey from "./Sankey.vue";
|
||||
import Settings from "../config/Settings.vue";
|
||||
@@ -119,15 +119,9 @@ limitations under the License. -->
|
||||
};
|
||||
height.value = dom.height - 70;
|
||||
width.value = dom.width - 5;
|
||||
if (settings.value.metricMode === MetricModes.Expression) {
|
||||
topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []);
|
||||
topologyStore.getLinkExpressions(settings.value.linkClientExpressions || [], CallTypes.Client);
|
||||
topologyStore.getLinkExpressions(settings.value.linkServerExpressions || [], CallTypes.Server);
|
||||
} else {
|
||||
topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || []);
|
||||
topologyStore.getLinkServerMetrics(settings.value.linkServerMetrics || []);
|
||||
topologyStore.queryNodeMetrics(settings.value.nodeMetrics || []);
|
||||
}
|
||||
topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []);
|
||||
topologyStore.getLinkExpressions(settings.value.linkClientExpressions || [], CallTypes.Client);
|
||||
topologyStore.getLinkExpressions(settings.value.linkServerExpressions || [], CallTypes.Server);
|
||||
}
|
||||
|
||||
function resize() {
|
||||
|
@@ -22,8 +22,6 @@ limitations under the License. -->
|
||||
import { useTopologyStore } from "@/store/modules/topology";
|
||||
import type { Node, Call } from "@/types/topology";
|
||||
import type { MetricConfigOpt } from "@/types/dashboard";
|
||||
import { aggregation } from "@/hooks/useMetricsProcessor";
|
||||
import { MetricModes } from "@/views/dashboard/data";
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
import { Themes } from "@/constants/data";
|
||||
|
||||
@@ -85,14 +83,8 @@ limitations under the License. -->
|
||||
};
|
||||
}
|
||||
function linkTooltip(data: Call) {
|
||||
const clientMetrics: string[] =
|
||||
props.settings.metricMode === MetricModes.Expression
|
||||
? props.settings.linkClientExpressions
|
||||
: props.settings.linkClientMetrics;
|
||||
const serverMetrics: string[] =
|
||||
props.settings.metricMode === MetricModes.Expression
|
||||
? props.settings.linkServerExpressions
|
||||
: props.settings.linkServerMetrics;
|
||||
const clientMetrics: string[] = props.settings.linkClientExpressions;
|
||||
const serverMetrics: string[] = props.settings.linkServerExpressions;
|
||||
const linkServerMetricConfig: MetricConfigOpt[] = props.settings.linkServerMetricConfig || [];
|
||||
const linkClientMetricConfig: MetricConfigOpt[] = props.settings.linkClientMetricConfig || [];
|
||||
|
||||
@@ -102,8 +94,10 @@ limitations under the License. -->
|
||||
{};
|
||||
if (metric) {
|
||||
const opt: MetricConfigOpt = linkServerMetricConfig[index] || {};
|
||||
const v = aggregation(metric.value, opt);
|
||||
return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${v} ${opt.unit || ""}</div>`;
|
||||
|
||||
return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${metric.value} ${
|
||||
opt.unit || ""
|
||||
}</div>`;
|
||||
}
|
||||
});
|
||||
const htmlClient = clientMetrics.map((m, index) => {
|
||||
@@ -111,8 +105,8 @@ limitations under the License. -->
|
||||
const metric =
|
||||
topologyStore.linkClientMetrics[m].values.find((val: { id: string; value: unknown }) => val.id === data.id) ||
|
||||
{};
|
||||
const v = aggregation(metric.value, opt);
|
||||
return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${v} ${opt.unit || ""}</div>`;
|
||||
|
||||
return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${metric.value} ${opt.unit || ""}</div>`;
|
||||
});
|
||||
const html = [
|
||||
`<div>${data.sourceObj.serviceName} -> ${data.targetObj.serviceName}</div>`,
|
||||
@@ -124,17 +118,14 @@ limitations under the License. -->
|
||||
}
|
||||
|
||||
function nodeTooltip(data: Node) {
|
||||
const nodeMetrics: string[] =
|
||||
props.settings.metricMode === MetricModes.Expression
|
||||
? props.settings.nodeExpressions
|
||||
: props.settings.nodeMetrics;
|
||||
const nodeMetrics: string[] = props.settings.nodeExpressions;
|
||||
const nodeMetricConfig = props.settings.nodeMetricConfig || [];
|
||||
const html = nodeMetrics.map((m, index) => {
|
||||
const metric =
|
||||
topologyStore.nodeMetricValue[m].values.find((val: { id: string; value: unknown }) => val.id === data.id) || {};
|
||||
const opt: MetricConfigOpt = nodeMetricConfig[index] || {};
|
||||
const v = aggregation(metric.value, opt);
|
||||
return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${v} ${opt.unit || ""}</div>`;
|
||||
|
||||
return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${metric.value} ${opt.unit || ""}</div>`;
|
||||
});
|
||||
return [` <div><span>name: </span>${data.serviceName}</div>`, ...html].join(" ");
|
||||
}
|
||||
|
@@ -43,7 +43,6 @@ limitations under the License. -->
|
||||
import router from "@/router";
|
||||
import { ElMessage } from "element-plus";
|
||||
import type { MetricConfigOpt } from "@/types/dashboard";
|
||||
import { aggregation } from "@/hooks/useMetricsProcessor";
|
||||
import getDashboard from "@/hooks/useDashboardsSession";
|
||||
import Graph from "../components/Graph.vue";
|
||||
|
||||
@@ -137,8 +136,7 @@ limitations under the License. -->
|
||||
(val: { id: string; value: unknown }) => val.id === data.id,
|
||||
) || {};
|
||||
const opt: MetricConfigOpt = nodeMetricConfig[index] || {};
|
||||
const v = aggregation(metric.value, opt);
|
||||
return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${v} ${opt.unit || ""}</div>`;
|
||||
return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${metric.value} ${opt.unit || ""}</div>`;
|
||||
});
|
||||
const tipHtml = [
|
||||
`<div class="mb-5"><span class="grey">name: </span>${data.name}</div><div class="mb-5"><span class="grey">layer: </span>${data.layer}</div>`,
|
||||
|
@@ -144,7 +144,7 @@ limitations under the License. -->
|
||||
import { useSelectorStore } from "@/store/modules/selectors";
|
||||
import { useTopologyStore } from "@/store/modules/topology";
|
||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||
import { EntityType, DepthList, MetricModes, CallTypes } from "@/views/dashboard/data";
|
||||
import { EntityType, DepthList, CallTypes } from "@/views/dashboard/data";
|
||||
import router from "@/router";
|
||||
import { ElMessage } from "element-plus";
|
||||
import Settings from "../config/Settings.vue";
|
||||
@@ -154,9 +154,7 @@ limitations under the License. -->
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
import getDashboard from "@/hooks/useDashboardsSession";
|
||||
import type { MetricConfigOpt } from "@/types/dashboard";
|
||||
import { aggregation } from "@/hooks/useMetricsProcessor";
|
||||
import icons from "@/assets/img/icons";
|
||||
import { useQueryTopologyMetrics } from "@/hooks/useMetricsProcessor";
|
||||
import { layout, computeLevels, changeNode } from "../components/utils/layout";
|
||||
import zoom from "@/views/dashboard/related/components/utils/zoom";
|
||||
import { useQueryTopologyExpressionsProcessor } from "@/hooks/useExpressionsProcessor";
|
||||
@@ -231,15 +229,9 @@ limitations under the License. -->
|
||||
}
|
||||
|
||||
async function update() {
|
||||
if (settings.value.metricMode === MetricModes.Expression) {
|
||||
topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []);
|
||||
topologyStore.getLinkExpressions(settings.value.linkClientExpressions || [], CallTypes.Client);
|
||||
topologyStore.getLinkExpressions(settings.value.linkServerExpressions || [], CallTypes.Server);
|
||||
} else {
|
||||
topologyStore.queryNodeMetrics(settings.value.nodeMetrics || []);
|
||||
topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || []);
|
||||
topologyStore.getLinkServerMetrics(settings.value.linkServerMetrics || []);
|
||||
}
|
||||
topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []);
|
||||
topologyStore.getLinkExpressions(settings.value.linkClientExpressions || [], CallTypes.Client);
|
||||
topologyStore.getLinkExpressions(settings.value.linkServerExpressions || [], CallTypes.Server);
|
||||
|
||||
window.addEventListener("resize", resize);
|
||||
await initLegendMetrics();
|
||||
@@ -288,67 +280,33 @@ limitations under the License. -->
|
||||
if (!topologyStore.nodes.length) {
|
||||
return;
|
||||
}
|
||||
if (settings.value.metricMode === MetricModes.Expression) {
|
||||
const expression = props.config.legendMQE && props.config.legendMQE.expression;
|
||||
if (!expression) {
|
||||
return;
|
||||
}
|
||||
const { getExpressionQuery } = useQueryTopologyExpressionsProcessor([expression], topologyStore.nodes);
|
||||
const param = getExpressionQuery();
|
||||
const res = await topologyStore.getNodeExpressionValue(param);
|
||||
if (res.errors) {
|
||||
ElMessage.error(res.errors);
|
||||
} else {
|
||||
topologyStore.setLegendValues([expression], res.data);
|
||||
}
|
||||
|
||||
const expression = props.config.legendMQE && props.config.legendMQE.expression;
|
||||
if (!expression) {
|
||||
return;
|
||||
}
|
||||
const { getExpressionQuery } = useQueryTopologyExpressionsProcessor([expression], topologyStore.nodes);
|
||||
const param = getExpressionQuery();
|
||||
const res = await topologyStore.getNodeExpressionValue(param);
|
||||
if (res.errors) {
|
||||
ElMessage.error(res.errors);
|
||||
} else {
|
||||
const names = props.config.legend.map((d: any) => d.name);
|
||||
if (!names.length) {
|
||||
return;
|
||||
}
|
||||
const ids = topologyStore.nodes.map((d: Node) => d.id);
|
||||
if (ids.length) {
|
||||
const param = await useQueryTopologyMetrics(names, ids);
|
||||
const res = await topologyStore.getLegendMetrics(param);
|
||||
if (res.errors) {
|
||||
ElMessage.error(res.errors);
|
||||
}
|
||||
}
|
||||
topologyStore.setLegendValues([expression], res.data);
|
||||
}
|
||||
}
|
||||
|
||||
function getNodeStatus(d: any) {
|
||||
const { legend, legendMQE } = settings.value;
|
||||
if (settings.value.metricMode === MetricModes.Expression) {
|
||||
if (!legendMQE) {
|
||||
return icons.CUBE;
|
||||
}
|
||||
if (!legendMQE.expression) {
|
||||
return icons.CUBE;
|
||||
}
|
||||
return Number(d[legendMQE.expression]) && d.isReal ? icons.CUBEERROR : icons.CUBE;
|
||||
}
|
||||
if (!legend) {
|
||||
const { legendMQE } = settings.value;
|
||||
if (!legendMQE) {
|
||||
return icons.CUBE;
|
||||
}
|
||||
if (!legend.length) {
|
||||
if (!legendMQE.expression) {
|
||||
return icons.CUBE;
|
||||
}
|
||||
let c = true;
|
||||
for (const l of legend) {
|
||||
if (l.condition === "<") {
|
||||
c = c && d[l.name] < Number(l.value);
|
||||
} else {
|
||||
c = c && d[l.name] > Number(l.value);
|
||||
}
|
||||
}
|
||||
return c && d.isReal ? icons.CUBEERROR : icons.CUBE;
|
||||
return Number(d[legendMQE.expression]) && d.isReal ? icons.CUBEERROR : icons.CUBE;
|
||||
}
|
||||
function showNodeTip(event: MouseEvent, data: Node) {
|
||||
const nodeMetrics: string[] =
|
||||
(settings.value.metricMode === MetricModes.Expression
|
||||
? settings.value.nodeExpressions
|
||||
: settings.value.nodeMetrics) || [];
|
||||
const nodeMetrics: string[] = settings.value.nodeExpressions || [];
|
||||
const nodeMetricConfig = settings.value.nodeMetricConfig || [];
|
||||
const html = nodeMetrics.map((m, index) => {
|
||||
const metric =
|
||||
@@ -356,8 +314,9 @@ limitations under the License. -->
|
||||
topologyStore.nodeMetricValue[m].values.find((val: { id: string; value: unknown }) => val.id === data.id)) ||
|
||||
{};
|
||||
const opt: MetricConfigOpt = nodeMetricConfig[index] || {};
|
||||
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>${metric.value} ${
|
||||
opt.unit || "unknown"
|
||||
}</div>`;
|
||||
});
|
||||
const tipHtml = [
|
||||
`<div class="mb-5"><span class="grey">name: </span>${
|
||||
@@ -373,24 +332,19 @@ limitations under the License. -->
|
||||
.html(tipHtml);
|
||||
}
|
||||
function showLinkTip(event: MouseEvent, data: Call) {
|
||||
const linkClientMetrics: string[] =
|
||||
settings.value.metricMode === MetricModes.Expression
|
||||
? settings.value.linkClientExpressions
|
||||
: settings.value.linkClientMetrics || [];
|
||||
const linkClientMetrics: string[] = settings.value.linkClientExpressions || [];
|
||||
const linkServerMetricConfig: MetricConfigOpt[] = settings.value.linkServerMetricConfig || [];
|
||||
const linkClientMetricConfig: MetricConfigOpt[] = settings.value.linkClientMetricConfig || [];
|
||||
const linkServerMetrics: string[] =
|
||||
settings.value.metricMode === MetricModes.Expression
|
||||
? settings.value.linkServerExpressions
|
||||
: settings.value.linkServerMetrics || [];
|
||||
const linkServerMetrics: string[] = settings.value.linkServerExpressions || [];
|
||||
const htmlServer = linkServerMetrics.map((m, index) => {
|
||||
const metric = topologyStore.linkServerMetrics[m].values.find(
|
||||
(val: { id: string; value: unknown }) => val.id === data.id,
|
||||
);
|
||||
if (metric) {
|
||||
const opt: MetricConfigOpt = linkServerMetricConfig[index] || {};
|
||||
const v = aggregation(metric.value, opt);
|
||||
return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${v} ${opt.unit || ""}</div>`;
|
||||
return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${metric.value} ${
|
||||
opt.unit || ""
|
||||
}</div>`;
|
||||
}
|
||||
});
|
||||
const htmlClient = linkClientMetrics.map((m: string, index: number) => {
|
||||
@@ -399,8 +353,9 @@ limitations under the License. -->
|
||||
(val: { id: string; value: unknown }) => val.id === data.id,
|
||||
);
|
||||
if (metric) {
|
||||
const v = aggregation(metric.value, opt);
|
||||
return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${v} ${opt.unit || ""}</div>`;
|
||||
return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${metric.value} ${
|
||||
opt.unit || ""
|
||||
}</div>`;
|
||||
}
|
||||
});
|
||||
const html = [
|
||||
|
Reference in New Issue
Block a user