mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-05-13 00:08:56 +00:00
feat: update legend
This commit is contained in:
parent
7a73b24587
commit
f563ba59b8
@ -381,5 +381,6 @@ const msg = {
|
|||||||
metricMode: "Metric Mode",
|
metricMode: "Metric Mode",
|
||||||
addExpressions: "Add Expressions",
|
addExpressions: "Add Expressions",
|
||||||
expressions: "Expression",
|
expressions: "Expression",
|
||||||
|
unhealthyExpression: "Unhealthy Expression",
|
||||||
};
|
};
|
||||||
export default msg;
|
export default msg;
|
||||||
|
@ -381,5 +381,6 @@ const msg = {
|
|||||||
metricMode: "Metric Mode",
|
metricMode: "Metric Mode",
|
||||||
addExpressions: "Add Expressions",
|
addExpressions: "Add Expressions",
|
||||||
expressions: "Expression",
|
expressions: "Expression",
|
||||||
|
unhealthyExpression: "Unhealthy Expression",
|
||||||
};
|
};
|
||||||
export default msg;
|
export default msg;
|
||||||
|
@ -379,5 +379,6 @@ const msg = {
|
|||||||
metricMode: "指标模式",
|
metricMode: "指标模式",
|
||||||
addExpressions: "添加表达式",
|
addExpressions: "添加表达式",
|
||||||
expressions: "表达式",
|
expressions: "表达式",
|
||||||
|
unhealthyExpression: "非健康表达式",
|
||||||
};
|
};
|
||||||
export default msg;
|
export default msg;
|
||||||
|
@ -361,23 +361,27 @@ limitations under the License. -->
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function initLegendMetrics() {
|
async function initLegendMetrics() {
|
||||||
const names = props.config.legend.map((d: any) => d.name);
|
|
||||||
if (!names.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (settings.value.metricMode === MetricModes.Expression) {
|
|
||||||
if (!topologyStore.nodes.length) {
|
if (!topologyStore.nodes.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { getExpressionQuery } = useQueryTopologyExpressionsProcessor(names, topologyStore.nodes);
|
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 param = getExpressionQuery();
|
||||||
const res = await topologyStore.getNodeExpressionValue(param);
|
const res = await topologyStore.getNodeExpressionValue(param);
|
||||||
if (res.errors) {
|
if (res.errors) {
|
||||||
ElMessage.error(res.errors);
|
ElMessage.error(res.errors);
|
||||||
} else {
|
} else {
|
||||||
topologyStore.setLegendValues(names, res.data);
|
topologyStore.setLegendValues([expression], res.data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
const names = props.config.legend.map((d: any) => d.name);
|
||||||
|
if (!names.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const ids = topologyStore.nodes.map((d: Node) => d.id);
|
const ids = topologyStore.nodes.map((d: Node) => d.id);
|
||||||
if (ids.length) {
|
if (ids.length) {
|
||||||
const param = await useQueryTopologyMetrics(names, ids);
|
const param = await useQueryTopologyMetrics(names, ids);
|
||||||
@ -390,20 +394,22 @@ limitations under the License. -->
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getNodeStatus(d: any) {
|
function getNodeStatus(d: any) {
|
||||||
const legend = settings.value.legend;
|
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) {
|
if (!legend) {
|
||||||
return icons.CUBE;
|
return icons.CUBE;
|
||||||
}
|
}
|
||||||
if (!legend.length) {
|
if (!legend.length) {
|
||||||
return icons.CUBE;
|
return icons.CUBE;
|
||||||
}
|
}
|
||||||
if (settings.value.metricMode === MetricModes.Expression) {
|
|
||||||
let c = true;
|
|
||||||
for (const l of legend) {
|
|
||||||
c = c && !!Number(d[l.name]);
|
|
||||||
}
|
|
||||||
return c && d.isReal ? icons.CUBEERROR : icons.CUBE;
|
|
||||||
}
|
|
||||||
let c = true;
|
let c = true;
|
||||||
for (const l of legend) {
|
for (const l of legend) {
|
||||||
if (l.condition === "<") {
|
if (l.condition === "<") {
|
||||||
|
@ -13,11 +13,11 @@ 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 class="mb-10 mt-20">
|
<div class="mt-20">
|
||||||
<h5 class="title">{{ t("metricMode") }}</h5>
|
<h5 class="title">{{ t("metricMode") }}</h5>
|
||||||
<el-switch
|
<el-switch
|
||||||
v-model="isExpression"
|
v-model="isExpression"
|
||||||
class="mb-5"
|
class="mt-5"
|
||||||
active-text="Expressions"
|
active-text="Expressions"
|
||||||
inactive-text="General"
|
inactive-text="General"
|
||||||
size="small"
|
size="small"
|
||||||
@ -196,17 +196,26 @@ limitations under the License. -->
|
|||||||
</div>
|
</div>
|
||||||
<div class="legend-settings" v-show="isService">
|
<div class="legend-settings" v-show="isService">
|
||||||
<h5 class="title">{{ t("legendSettings") }}</h5>
|
<h5 class="title">{{ t("legendSettings") }}</h5>
|
||||||
<div class="label">{{ t("conditions") }}</div>
|
<span v-if="isExpression">
|
||||||
<div v-for="(metric, index) of legend" :key="index">
|
<div class="label">Healthy Description</div>
|
||||||
<el-input
|
<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>
|
||||||
|
<el-tooltip
|
||||||
|
class="cp"
|
||||||
v-if="isExpression"
|
v-if="isExpression"
|
||||||
v-model="metric.name"
|
content="The node would be red to indicate unhealthy status when the expression return greater than 0"
|
||||||
placeholder="Please input a expression"
|
>
|
||||||
@change="changeLegend(LegendOpt.NAME, $event, index)"
|
<span>
|
||||||
size="small"
|
<Icon class="icon-help ml-5" iconName="help" size="small" />
|
||||||
class="legend-inputs"
|
</span>
|
||||||
/>
|
</el-tooltip>
|
||||||
<span v-else>
|
</div>
|
||||||
|
<div v-if="isExpression">
|
||||||
|
<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
|
<Selector
|
||||||
class="item"
|
class="item"
|
||||||
:value="metric.name"
|
:value="metric.name"
|
||||||
@ -231,7 +240,6 @@ limitations under the License. -->
|
|||||||
size="small"
|
size="small"
|
||||||
class="item"
|
class="item"
|
||||||
/>
|
/>
|
||||||
</span>
|
|
||||||
<span>
|
<span>
|
||||||
<Icon class="cp delete" iconName="remove_circle_outline" size="middle" @click="deleteMetric(index)" />
|
<Icon class="cp delete" iconName="remove_circle_outline" size="middle" @click="deleteMetric(index)" />
|
||||||
<Icon
|
<Icon
|
||||||
@ -244,8 +252,10 @@ limitations under the License. -->
|
|||||||
</span>
|
</span>
|
||||||
<div v-show="index !== legend.length - 1">&&</div>
|
<div v-show="index !== legend.length - 1">&&</div>
|
||||||
</div>
|
</div>
|
||||||
|
<span v-if="!isExpression">
|
||||||
<div class="label">Healthy Description</div>
|
<div class="label">Healthy Description</div>
|
||||||
<el-input v-model="description.healthy" placeholder="Please input description" size="small" class="mt-5" />
|
<el-input v-model="description.healthy" placeholder="Please input description" size="small" class="mt-5" />
|
||||||
|
</span>
|
||||||
<div class="label">Unhealthy Description</div>
|
<div class="label">Unhealthy Description</div>
|
||||||
<el-input v-model="description.unhealthy" placeholder="Please input description" size="small" class="mt-5" />
|
<el-input v-model="description.unhealthy" placeholder="Please input description" size="small" class="mt-5" />
|
||||||
<el-button @click="setLegend" class="legend-btn" size="small" type="primary">
|
<el-button @click="setLegend" class="legend-btn" size="small" type="primary">
|
||||||
@ -325,6 +335,7 @@ limitations under the License. -->
|
|||||||
const legend = ref<{ name: string; condition: string; value: string }[]>(
|
const legend = ref<{ name: string; condition: string; value: string }[]>(
|
||||||
l ? selectedGrid.legend : [{ name: "", condition: "", value: "" }],
|
l ? selectedGrid.legend : [{ name: "", condition: "", value: "" }],
|
||||||
);
|
);
|
||||||
|
const legendMQE = ref<{ expression: string }>(selectedGrid.legendMQE || { expression: "" });
|
||||||
const configType = ref<string>("");
|
const configType = ref<string>("");
|
||||||
const description = reactive<any>(selectedGrid.description || {});
|
const description = reactive<any>(selectedGrid.description || {});
|
||||||
|
|
||||||
@ -373,21 +384,26 @@ limitations under the License. -->
|
|||||||
}
|
}
|
||||||
async function setLegend() {
|
async function setLegend() {
|
||||||
updateSettings();
|
updateSettings();
|
||||||
const names = dashboardStore.selectedGrid.legend.map((d: any) => d.name);
|
if (isExpression.value) {
|
||||||
if (!names.length) {
|
const expression = dashboardStore.selectedGrid.legendMQE && dashboardStore.selectedGrid.legendMQE.expression;
|
||||||
|
if (!expression) {
|
||||||
emit("updateNodes");
|
emit("updateNodes");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isExpression.value) {
|
const { getExpressionQuery } = useQueryTopologyExpressionsProcessor([expression], topologyStore.nodes);
|
||||||
const { getExpressionQuery } = useQueryTopologyExpressionsProcessor(names, topologyStore.nodes);
|
|
||||||
const param = getExpressionQuery();
|
const param = getExpressionQuery();
|
||||||
const res = await topologyStore.getNodeExpressionValue(param);
|
const res = await topologyStore.getNodeExpressionValue(param);
|
||||||
if (res.errors) {
|
if (res.errors) {
|
||||||
ElMessage.error(res.errors);
|
ElMessage.error(res.errors);
|
||||||
} else {
|
} else {
|
||||||
topologyStore.setLegendValues(names, res.data);
|
topologyStore.setLegendValues([expression], res.data);
|
||||||
}
|
}
|
||||||
} else {
|
} 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 ids = topologyStore.nodes.map((d: Node) => d.id);
|
||||||
const param = await useQueryTopologyMetrics(names, ids);
|
const param = await useQueryTopologyMetrics(names, ids);
|
||||||
const res = await topologyStore.getLegendMetrics(param);
|
const res = await topologyStore.getLegendMetrics(param);
|
||||||
@ -461,6 +477,7 @@ limitations under the License. -->
|
|||||||
nodeExpressions: states.nodeExpressions,
|
nodeExpressions: states.nodeExpressions,
|
||||||
metricMode: isExpression.value ? MetricModes.Expression : MetricModes.General,
|
metricMode: isExpression.value ? MetricModes.Expression : MetricModes.General,
|
||||||
legend: metrics,
|
legend: metrics,
|
||||||
|
legendMQE: legendMQE.value,
|
||||||
...metricConfig,
|
...metricConfig,
|
||||||
description,
|
description,
|
||||||
};
|
};
|
||||||
@ -623,9 +640,8 @@ limitations under the License. -->
|
|||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
margin-bottom: 0;
|
|
||||||
margin-top: 0;
|
|
||||||
color: #666;
|
color: #666;
|
||||||
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
|
Loading…
Reference in New Issue
Block a user