feat: save and init topology templates (#32)

This commit is contained in:
Fine0830 2022-03-22 13:40:40 +08:00 committed by GitHub
parent f1e405fbb4
commit f9aacb72e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 169 additions and 98 deletions

View File

@ -23,6 +23,8 @@ import { useSelectorStore } from "@/store/modules/selectors";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import { AxiosResponse } from "axios"; import { AxiosResponse } from "axios";
import query from "@/graphql/fetch"; import query from "@/graphql/fetch";
import { useQueryTopologyMetrics } from "@/hooks/useProcessor";
import { ElMessage } from "element-plus";
interface MetricVal { interface MetricVal {
[key: string]: { values: { id: string; value: unknown }[] }; [key: string]: { values: { id: string; value: unknown }[] };
@ -32,7 +34,7 @@ interface TopologyState {
call: Nullable<Call>; call: Nullable<Call>;
calls: Call[]; calls: Call[];
nodes: Node[]; nodes: Node[];
nodeMetrics: MetricVal; nodeMetricValue: MetricVal;
linkServerMetrics: MetricVal; linkServerMetrics: MetricVal;
linkClientMetrics: MetricVal; linkClientMetrics: MetricVal;
} }
@ -44,7 +46,7 @@ export const topologyStore = defineStore({
nodes: [], nodes: [],
node: null, node: null,
call: null, call: null,
nodeMetrics: {}, nodeMetricValue: {},
linkServerMetrics: {}, linkServerMetrics: {},
linkClientMetrics: {}, linkClientMetrics: {},
}), }),
@ -103,8 +105,8 @@ export const topologyStore = defineStore({
this.calls = calls; this.calls = calls;
this.nodes = nodes; this.nodes = nodes;
}, },
setNodeMetrics(m: { id: string; value: unknown }[]) { setNodeMetricValue(m: { id: string; value: unknown }[]) {
this.nodeMetrics = m; this.nodeMetricValue = m;
}, },
setLinkServerMetrics(m: { id: string; value: unknown }[]) { setLinkServerMetrics(m: { id: string; value: unknown }[]) {
this.linkServerMetrics = m; this.linkServerMetrics = m;
@ -388,7 +390,7 @@ export const topologyStore = defineStore({
return { calls, nodes }; return { calls, nodes };
}, },
async getNodeMetrics(param: { async getNodeMetricValue(param: {
queryStr: string; queryStr: string;
conditions: { [key: string]: unknown }; conditions: { [key: string]: unknown };
}) { }) {
@ -397,9 +399,52 @@ export const topologyStore = defineStore({
if (res.data.errors) { if (res.data.errors) {
return res.data; return res.data;
} }
this.setNodeMetrics(res.data.data); this.setNodeMetricValue(res.data.data);
return res.data; return res.data;
}, },
async getLinkClientMetrics(linkClientMetrics: string[]) {
if (!linkClientMetrics.length) {
this.setLinkClientMetrics({});
return;
}
const idsC = this.calls
.filter((i: Call) => i.detectPoints.includes("CLIENT"))
.map((b: Call) => b.id);
const param = await useQueryTopologyMetrics(linkClientMetrics, idsC);
const res = await this.getCallClientMetrics(param);
if (res.errors) {
ElMessage.error(res.errors);
}
},
async getLinkServerMetrics(linkServerMetrics: string[]) {
if (!linkServerMetrics.length) {
this.setLinkServerMetrics({});
return;
}
const idsS = this.calls
.filter((i: Call) => i.detectPoints.includes("SERVER"))
.map((b: Call) => b.id);
const param = await useQueryTopologyMetrics(linkServerMetrics, idsS);
const res = await this.getCallServerMetrics(param);
if (res.errors) {
ElMessage.error(res.errors);
}
},
async queryNodeMetrics(nodeMetrics: string[]) {
if (!nodeMetrics.length) {
this.setNodeMetricValue({});
return;
}
const ids = this.nodes.map((d: Node) => d.id);
const param = await useQueryTopologyMetrics(nodeMetrics, ids);
const res = await this.getNodeMetricValue(param);
if (res.errors) {
ElMessage.error(res.errors);
}
},
async getLegendMetrics(param: { async getLegendMetrics(param: {
queryStr: string; queryStr: string;
conditions: { [key: string]: unknown }; conditions: { [key: string]: unknown };

View File

@ -46,7 +46,9 @@ limitations under the License. -->
<el-table-column type="selection" width="55" /> <el-table-column type="selection" width="55" />
<el-table-column prop="name" label="Name"> <el-table-column prop="name" label="Name">
<template #default="scope"> <template #default="scope">
<span @click="handleView(scope.row)">{{ scope.row.name }}</span> <span class="cp" @click="handleView(scope.row)">{{
scope.row.name
}}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="layer" label="Layer" width="200" /> <el-table-column prop="layer" label="Layer" width="200" />

View File

@ -53,8 +53,9 @@ limitations under the License. -->
> >
<Icon <Icon
class="cp mr-5" class="cp mr-5"
v-show=" v-if="
index === states.metrics.length - 1 && states.metrics.length < 5 index === states.metrics.length - 1 &&
states.metrics.length < defaultLen
" "
iconName="add_circle_outlinecontrol_point" iconName="add_circle_outlinecontrol_point"
size="middle" size="middle"
@ -84,7 +85,7 @@ limitations under the License. -->
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive } from "vue"; import { reactive, ref } from "vue";
import { Option } from "@/types/app"; import { Option } from "@/types/app";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { import {
@ -128,6 +129,7 @@ const states = reactive<{
}); });
states.isList = ListChartTypes.includes(graph.type); states.isList = ListChartTypes.includes(graph.type);
const defaultLen = ref<number>(states.isList ? 5 : 10);
states.visTypes = setVisTypes(); states.visTypes = setVisTypes();
setDashboards(); setDashboards();
@ -241,10 +243,12 @@ function changeChartType(item: Option) {
}); });
states.metrics = [""]; states.metrics = [""];
states.metricTypes = [""]; states.metricTypes = [""];
defaultLen.value = 5;
} }
setMetricType(); setMetricType();
setDashboards(); setDashboards();
states.dashboardName = ""; states.dashboardName = "";
defaultLen.value = 10;
} }
function changeMetrics( function changeMetrics(

View File

@ -35,7 +35,7 @@ limitations under the License. -->
<template #default="scope"> <template #default="scope">
<span <span
class="link" class="link"
@click="clickEndpoint" @click="clickEndpoint(scope)"
:style="{ fontSize: `${config.fontSize}px` }" :style="{ fontSize: `${config.fontSize}px` }"
> >
{{ scope.row.label }} {{ scope.row.label }}

View File

@ -35,7 +35,7 @@ limitations under the License. -->
<template #default="scope"> <template #default="scope">
<span <span
class="link" class="link"
@click="clickInstance" @click="clickInstance(scope)"
:style="{ fontSize: `${config.fontSize}px` }" :style="{ fontSize: `${config.fontSize}px` }"
> >
{{ scope.row.label }} {{ scope.row.label }}

View File

@ -13,12 +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>
<PodTopology :config="config" v-if="isSankey" /> <Graph :config="config" v-if="isService" />
<Graph :config="config" v-else /> <PodTopology :config="config" v-else />
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import type { PropType } from "vue"; import type { PropType } from "vue";
import { ref } from "vue";
import Graph from "./components/Graph.vue"; import Graph from "./components/Graph.vue";
import PodTopology from "./components/PodTopology.vue"; import PodTopology from "./components/PodTopology.vue";
import { EntityType } from "../../data"; import { EntityType } from "../../data";
@ -32,7 +31,7 @@ defineProps({
}, },
}); });
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const isSankey = ref<boolean>( const isService = [EntityType[0].value, EntityType[1].value].includes(
[EntityType[2].value, EntityType[3].value].includes(dashboardStore.entity) dashboardStore.entity
); );
</script> </script>

View File

@ -20,7 +20,7 @@ limitations under the License. -->
element-loading-background="rgba(0, 0, 0, 0)" element-loading-background="rgba(0, 0, 0, 0)"
:style="`height: ${height}px`" :style="`height: ${height}px`"
> >
<div class="setting" v-show="showSetting"> <div class="setting" v-if="showSetting">
<Settings @update="updateSettings" @updateNodes="freshNodes" /> <Settings @update="updateSettings" @updateNodes="freshNodes" />
</div> </div>
<div class="tool"> <div class="tool">
@ -34,7 +34,12 @@ limitations under the License. -->
@change="changeDepth" @change="changeDepth"
/> />
</span> </span>
<span class="switch-icon ml-5" title="Settings" @click="setConfig"> <span
class="switch-icon ml-5"
title="Settings"
@click="setConfig"
v-if="dashboardStore.editMode"
>
<Icon size="middle" iconName="settings" /> <Icon size="middle" iconName="settings" />
</span> </span>
<span <span
@ -113,14 +118,11 @@ const anchor = ref<any>(null);
const arrow = ref<any>(null); const arrow = ref<any>(null);
const legend = ref<any>(null); const legend = ref<any>(null);
const showSetting = ref<boolean>(false); const showSetting = ref<boolean>(false);
const settings = ref<any>({}); const settings = ref<any>(props.config);
const operationsPos = reactive<{ x: number; y: number }>({ x: NaN, y: NaN }); const operationsPos = reactive<{ x: number; y: number }>({ x: NaN, y: NaN });
const items = ref< const items = ref<
{ id: string; title: string; func: any; dashboard?: string }[] { id: string; title: string; func: any; dashboard?: string }[]
>([ >([]);
{ id: "inspect", title: "Inspect", func: handleInspect },
{ id: "alarm", title: "Alarm", func: handleGoAlarm },
]);
const depth = ref<number>(props.config.graph.depth || 2); const depth = ref<number>(props.config.graph.depth || 2);
onMounted(async () => { onMounted(async () => {
@ -130,6 +132,9 @@ onMounted(async () => {
if (resp && resp.errors) { if (resp && resp.errors) {
ElMessage.error(resp.errors); ElMessage.error(resp.errors);
} }
topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || []);
topologyStore.getLinkServerMetrics(settings.value.linkServerMetrics || []);
topologyStore.queryNodeMetrics(settings.value.nodeMetrics || []);
const dom = document.querySelector(".topology")?.getBoundingClientRect() || { const dom = document.querySelector(".topology")?.getBoundingClientRect() || {
height: 40, height: 40,
width: 0, width: 0,
@ -140,6 +145,7 @@ onMounted(async () => {
svg.value = d3.select(chart.value).append("svg").attr("class", "topo-svg"); svg.value = d3.select(chart.value).append("svg").attr("class", "topo-svg");
await init(); await init();
update(); update();
setNodeTools(settings.value.nodeDashboard);
}); });
async function init() { async function init() {
tip.value = (d3tip as any)().attr("class", "d3-tip").offset([-8, 0]); tip.value = (d3tip as any)().attr("class", "d3-tip").offset([-8, 0]);
@ -167,6 +173,7 @@ async function init() {
event.preventDefault(); event.preventDefault();
topologyStore.setNode(null); topologyStore.setNode(null);
topologyStore.setLink(null); topologyStore.setLink(null);
dashboardStore.selectWidget(props.config);
}); });
} }
function ticked() { function ticked() {
@ -236,6 +243,7 @@ function handleLinkClick(event: any, d: Call) {
if (!settings.value.linkDashboard) { if (!settings.value.linkDashboard) {
return; return;
} }
const origin = dashboardStore.entity;
const e = const e =
dashboardStore.entity === EntityType[1].value dashboardStore.entity === EntityType[1].value
? EntityType[0].value ? EntityType[0].value
@ -251,6 +259,7 @@ function handleLinkClick(event: any, d: Call) {
}/${p.name.split(" ").join("-")}`; }/${p.name.split(" ").join("-")}`;
const routeUrl = router.resolve({ path }); const routeUrl = router.resolve({ path });
window.open(routeUrl.href, "_blank"); window.open(routeUrl.href, "_blank");
dashboardStore.setEntity(origin);
} }
function update() { function update() {
// node element // node element
@ -271,7 +280,7 @@ function update() {
const nodeMetrics: string[] = settings.value.nodeMetrics || []; const nodeMetrics: string[] = settings.value.nodeMetrics || [];
const html = nodeMetrics.map((m) => { const html = nodeMetrics.map((m) => {
const metric = const metric =
topologyStore.nodeMetrics[m].values.filter( topologyStore.nodeMetricValue[m].values.filter(
(val: { id: string; value: unknown }) => val.id === data.id (val: { id: string; value: unknown }) => val.id === data.id
)[0] || {}; )[0] || {};
const val = m.includes("_sla") ? metric.value / 100 : metric.value; const val = m.includes("_sla") ? metric.value / 100 : metric.value;
@ -380,6 +389,7 @@ async function handleInspect() {
update(); update();
} }
function handleGoEndpoint(name: string) { function handleGoEndpoint(name: string) {
const origin = dashboardStore.entity;
const p = getDashboard({ const p = getDashboard({
name, name,
layer: dashboardStore.layerId, layer: dashboardStore.layerId,
@ -392,8 +402,10 @@ function handleGoEndpoint(name: string) {
const routeUrl = router.resolve({ path }); const routeUrl = router.resolve({ path });
window.open(routeUrl.href, "_blank"); window.open(routeUrl.href, "_blank");
dashboardStore.setEntity(origin);
} }
function handleGoInstance(name: string) { function handleGoInstance(name: string) {
const origin = dashboardStore.entity;
const p = getDashboard({ const p = getDashboard({
name, name,
layer: dashboardStore.layerId, layer: dashboardStore.layerId,
@ -406,8 +418,10 @@ function handleGoInstance(name: string) {
const routeUrl = router.resolve({ path }); const routeUrl = router.resolve({ path });
window.open(routeUrl.href, "_blank"); window.open(routeUrl.href, "_blank");
dashboardStore.setEntity(origin);
} }
function handleGoDashboard(name: string) { function handleGoDashboard(name: string) {
const origin = dashboardStore.entity;
const p = getDashboard({ const p = getDashboard({
name, name,
layer: dashboardStore.layerId, layer: dashboardStore.layerId,
@ -420,6 +434,7 @@ function handleGoDashboard(name: string) {
const routeUrl = router.resolve({ path }); const routeUrl = router.resolve({ path });
window.open(routeUrl.href, "_blank"); window.open(routeUrl.href, "_blank");
dashboardStore.setEntity(origin);
} }
function handleGoAlarm() { function handleGoAlarm() {
const path = `/alarm`; const path = `/alarm`;
@ -455,6 +470,7 @@ async function getTopology() {
} }
function setConfig() { function setConfig() {
showSetting.value = !showSetting.value; showSetting.value = !showSetting.value;
dashboardStore.selectWidget(props.config);
} }
function resize() { function resize() {
height.value = document.body.clientHeight; height.value = document.body.clientHeight;
@ -462,16 +478,19 @@ function resize() {
svg.value.attr("height", height.value).attr("width", width.value); svg.value.attr("height", height.value).attr("width", width.value);
} }
function updateSettings(config: any) { function updateSettings(config: any) {
settings.value = config;
setNodeTools(config.nodeDashboard);
}
function setNodeTools(nodeDashboard: any) {
items.value = [ items.value = [
{ id: "inspect", title: "Inspect", func: handleInspect }, { id: "inspect", title: "Inspect", func: handleInspect },
{ id: "alarm", title: "Alarm", func: handleGoAlarm }, { id: "alarm", title: "Alarm", func: handleGoAlarm },
]; ];
settings.value = config; for (const item of nodeDashboard) {
for (const item of config.nodeDashboard) {
if (item.scope === EntityType[0].value) { if (item.scope === EntityType[0].value) {
items.value.push({ items.value.push({
id: "dashboard", id: "dashboard",
title: "Dashboard", title: "Service Dashboard",
func: handleGoDashboard, func: handleGoDashboard,
...item, ...item,
}); });
@ -479,7 +498,7 @@ function updateSettings(config: any) {
if (item.scope === EntityType[2].value) { if (item.scope === EntityType[2].value) {
items.value.push({ items.value.push({
id: "endpoint", id: "endpoint",
title: "Endpoint", title: "Endpoint Dashboard",
func: handleGoEndpoint, func: handleGoEndpoint,
...item, ...item,
}); });
@ -487,7 +506,7 @@ function updateSettings(config: any) {
if (item.scope === EntityType[3].value) { if (item.scope === EntityType[3].value) {
items.value.push({ items.value.push({
id: "instance", id: "instance",
title: "Service Instance", title: "Service Instance Dashboard",
func: handleGoInstance, func: handleGoInstance,
...item, ...item,
}); });
@ -567,7 +586,6 @@ watch(
span { span {
display: block; display: block;
height: 30px; height: 30px;
width: 140px;
line-height: 30px; line-height: 30px;
text-align: center; text-align: center;
} }

View File

@ -28,7 +28,12 @@ limitations under the License. -->
@change="changeDepth" @change="changeDepth"
/> />
</span> </span>
<span class="switch-icon ml-5" title="Settings" @click="setConfig"> <span
class="switch-icon ml-5"
title="Settings"
@click="setConfig"
v-if="dashboardStore.editMode"
>
<Icon size="middle" iconName="settings" /> <Icon size="middle" iconName="settings" />
</span> </span>
<span <span
@ -38,7 +43,7 @@ limitations under the License. -->
> >
<Icon size="middle" iconName="keyboard_backspace" /> <Icon size="middle" iconName="keyboard_backspace" />
</span> </span>
<div class="settings" v-show="showSettings"> <div class="settings" v-if="showSettings">
<Settings @update="updateConfig" /> <Settings @update="updateConfig" />
</div> </div>
</div> </div>
@ -104,7 +109,7 @@ const loading = ref<boolean>(false);
const height = ref<number>(100); const height = ref<number>(100);
const width = ref<number>(100); const width = ref<number>(100);
const showSettings = ref<boolean>(false); const showSettings = ref<boolean>(false);
const settings = ref<any>({}); const settings = ref<any>(props.config);
const operationsPos = reactive<{ x: number; y: number }>({ x: NaN, y: NaN }); const operationsPos = reactive<{ x: number; y: number }>({ x: NaN, y: NaN });
const depth = ref<number>(props.config.graph.depth || 3); const depth = ref<number>(props.config.graph.depth || 3);
const items = [ const items = [
@ -130,6 +135,9 @@ async function loadTopology(id: string) {
}; };
height.value = dom.height - 70; height.value = dom.height - 70;
width.value = dom.width - 5; width.value = dom.width - 5;
topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || []);
topologyStore.getLinkServerMetrics(settings.value.linkServerMetrics || []);
topologyStore.queryNodeMetrics(settings.value.nodeMetrics || []);
} }
function inspect() { function inspect() {
@ -158,7 +166,9 @@ function goDashboard() {
}); });
dashboardStore.setEntity(entity); dashboardStore.setEntity(entity);
dashboardStore.setCurrentDashboard(d); dashboardStore.setCurrentDashboard(d);
const path = `/dashboard/${d.layer}/${entity}/${topologyStore.node.serviceId}/${topologyStore.node.id}/${d.name}`; const path = `/dashboard/${d.layer}/${entity}/${
topologyStore.node.serviceId
}/${topologyStore.node.id}/${d.name.split(" ").join("-")}`;
const routeUrl = router.resolve({ path }); const routeUrl = router.resolve({ path });
window.open(routeUrl.href, "_blank"); window.open(routeUrl.href, "_blank");
topologyStore.setNode(null); topologyStore.setNode(null);
@ -167,6 +177,7 @@ function goDashboard() {
function setConfig() { function setConfig() {
topologyStore.setNode(null); topologyStore.setNode(null);
showSettings.value = !showSettings.value; showSettings.value = !showSettings.value;
dashboardStore.selectWidget(props.config);
} }
function updateConfig(config: any) { function updateConfig(config: any) {
@ -196,7 +207,9 @@ function selectNodeLink(d: any) {
entity, entity,
}); });
dashboardStore.setEntity(entity); dashboardStore.setEntity(entity);
const path = `/dashboard/${p.layer}/${entity}/${sourceObj.serviceId}/${sourceObj.id}/${targetObj.serviceId}/${targetObj.id}/${p.name}`; const path = `/dashboard/${p.layer}/${entity}/${sourceObj.serviceId}/${
sourceObj.id
}/${targetObj.serviceId}/${targetObj.id}/${p.name.split(" ").join("-")}`;
const routeUrl = router.resolve({ path }); const routeUrl = router.resolve({ path });
window.open(routeUrl.href, "_blank"); window.open(routeUrl.href, "_blank");
return; return;
@ -221,7 +234,7 @@ async function getTopology(id: string) {
Number(depth.value) Number(depth.value)
); );
break; break;
case EntityType[3].value: case EntityType[4].value:
resp = await topologyStore.getInstanceTopology(); resp = await topologyStore.getInstanceTopology();
break; break;
} }
@ -231,6 +244,7 @@ function handleClick(event: any) {
if (event.target.nodeName === "svg") { if (event.target.nodeName === "svg") {
topologyStore.setNode(null); topologyStore.setNode(null);
topologyStore.setLink(null); topologyStore.setLink(null);
dashboardStore.selectWidget(props.config);
} }
} }
watch( watch(
@ -262,10 +276,10 @@ watch(
top: 60px; top: 60px;
right: 10px; right: 10px;
width: 400px; width: 400px;
height: 500px; height: 600px;
background-color: #2b3037; background-color: #2b3037;
overflow: auto; overflow: auto;
padding: 0 15px; padding: 10px 15px;
border-radius: 3px; border-radius: 3px;
color: #ccc; color: #ccc;
transition: all 0.5ms linear; transition: all 0.5ms linear;

View File

@ -105,10 +105,10 @@ function linkTooltip(data: Call) {
} }
function nodeTooltip(data: Node) { function nodeTooltip(data: Node) {
const nodeMetrics: string[] = Object.keys(topologyStore.nodeMetrics); const nodeMetrics: string[] = Object.keys(topologyStore.nodeMetricValue);
const html = nodeMetrics.map((m) => { const html = nodeMetrics.map((m) => {
const metric = const metric =
topologyStore.nodeMetrics[m].values.filter( topologyStore.nodeMetricValue[m].values.filter(
(val: { id: string; value: unknown }) => val.id === data.id (val: { id: string; value: unknown }) => val.id === data.id
)[0] || {}; )[0] || {};
const val = m.includes("_sla") ? metric.value / 100 : metric.value; const val = m.includes("_sla") ? metric.value / 100 : metric.value;

View File

@ -186,7 +186,7 @@ import { ElMessage } from "element-plus";
import { MetricCatalog, ScopeType, MetricConditions } from "../../../data"; import { MetricCatalog, ScopeType, MetricConditions } from "../../../data";
import { Option } from "@/types/app"; import { Option } from "@/types/app";
import { useQueryTopologyMetrics } from "@/hooks/useProcessor"; import { useQueryTopologyMetrics } from "@/hooks/useProcessor";
import { Node, Call } from "@/types/topology"; import { Node } from "@/types/topology";
import { DashboardItem } from "@/types/dashboard"; import { DashboardItem } from "@/types/dashboard";
import { EntityType, LegendOpt, MetricsType } from "../../../data"; import { EntityType, LegendOpt, MetricsType } from "../../../data";
@ -195,12 +195,16 @@ const emit = defineEmits(["update", "updateNodes"]);
const { t } = useI18n(); const { t } = useI18n();
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const topologyStore = useTopologyStore(); const topologyStore = useTopologyStore();
const { selectedGrid } = dashboardStore;
const isService = [EntityType[0].value, EntityType[1].value].includes(
dashboardStore.entity
);
const items = reactive< const items = reactive<
{ {
scope: string; scope: string;
dashboard: string; dashboard: string;
}[] }[]
>([{ scope: "", dashboard: "" }]); >((isService && selectedGrid.nodeDashboard) || [{ scope: "", dashboard: "" }]);
const states = reactive<{ const states = reactive<{
linkDashboard: string; linkDashboard: string;
nodeDashboard: { nodeDashboard: {
@ -215,23 +219,19 @@ const states = reactive<{
linkDashboards: (DashboardItem & { label: string; value: string })[]; linkDashboards: (DashboardItem & { label: string; value: string })[];
nodeDashboards: (DashboardItem & { label: string; value: string })[]; nodeDashboards: (DashboardItem & { label: string; value: string })[];
}>({ }>({
linkDashboard: "", linkDashboard: selectedGrid.linkDashboard || "",
nodeDashboard: [], nodeDashboard: selectedGrid.nodeDashboard || [],
linkServerMetrics: [], linkServerMetrics: selectedGrid.linkServerMetrics || [],
linkClientMetrics: [], linkClientMetrics: selectedGrid.linkClientMetrics || [],
nodeMetrics: [], nodeMetrics: selectedGrid.nodeMetrics || [],
nodeMetricList: [], nodeMetricList: [],
linkMetricList: [], linkMetricList: [],
linkDashboards: [], linkDashboards: [],
nodeDashboards: [], nodeDashboards: [],
}); });
console.log(dashboardStore.selectedGrid);
const isService = [EntityType[0].value, EntityType[1].value].includes(
dashboardStore.entity
);
const legend = reactive<{ const legend = reactive<{
metric: { name: string; condition: string; value: string }[]; metric: { name: string; condition: string; value: string }[];
}>({ metric: [{ name: "", condition: "", value: "" }] }); }>({ metric: selectedGrid.legend || [{ name: "", condition: "", value: "" }] });
getMetricList(); getMetricList();
async function getMetricList() { async function getMetricList() {
@ -270,24 +270,26 @@ async function getMetricList() {
entity + "Relation" === (MetricCatalog as any)[d.catalog] && entity + "Relation" === (MetricCatalog as any)[d.catalog] &&
d.type === MetricsType.REGULAR_VALUE d.type === MetricsType.REGULAR_VALUE
); );
if (isService) {
return;
}
states.nodeDashboards = list.reduce(
(
prev: (DashboardItem & { label: string; value: string })[],
d: DashboardItem
) => {
if (d.layer === dashboardStore.layerId && d.entity === entity) {
prev.push({ ...d, label: d.name, value: d.name });
}
return prev;
},
[]
);
} }
async function setLegend() { async function setLegend() {
const metrics = legend.metric.filter( updateSettings();
(d: any) => d.name && d.value && d.condition
);
const names = metrics.map((d: any) => d.name);
emit("update", {
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,
legend: metrics,
});
const ids = topologyStore.nodes.map((d: Node) => d.id); const ids = topologyStore.nodes.map((d: Node) => d.id);
const names = dashboardStore.selectedGrid.legend.map((d: any) => d.name);
const param = await useQueryTopologyMetrics(names, ids); const param = await useQueryTopologyMetrics(names, ids);
const res = await topologyStore.getLegendMetrics(param); const res = await topologyStore.getLegendMetrics(param);
@ -298,9 +300,11 @@ async function setLegend() {
} }
function changeNodeDashboard(opt: any) { function changeNodeDashboard(opt: any) {
states.nodeDashboard = opt[0].value; states.nodeDashboard = opt[0].value;
updateSettings();
} }
function changeLinkDashboard(opt: any) { function changeLinkDashboard(opt: any) {
states.linkDashboard = opt[0].value; states.linkDashboard = opt[0].value;
updateSettings();
} }
function changeLegend(type: string, opt: any, index: number) { function changeLegend(type: string, opt: any, index: number) {
(legend.metric[index] as any)[type] = opt[0].value || opt; (legend.metric[index] as any)[type] = opt[0].value || opt;
@ -321,6 +325,7 @@ function changeScope(index: number, opt: Option[] | any) {
[] []
); );
items[index].dashboard = states.nodeDashboards[0].value; items[index].dashboard = states.nodeDashboards[0].value;
updateSettings();
} }
function updateNodeDashboards(index: number, content: Option[] | any) { function updateNodeDashboards(index: number, content: Option[] | any) {
items[index].dashboard = content[0].value; items[index].dashboard = content[0].value;
@ -334,7 +339,10 @@ function deleteItem(index: number) {
updateSettings(); updateSettings();
} }
function updateSettings() { function updateSettings() {
emit("update", { const metrics = legend.metric.filter(
(d: any) => d.name && d.value && d.condition
);
const param = {
linkDashboard: states.linkDashboard, linkDashboard: states.linkDashboard,
nodeDashboard: isService nodeDashboard: isService
? items.filter((d: { scope: string; dashboard: string }) => d.dashboard) ? items.filter((d: { scope: string; dashboard: string }) => d.dashboard)
@ -342,8 +350,11 @@ function updateSettings() {
linkServerMetrics: states.linkServerMetrics, linkServerMetrics: states.linkServerMetrics,
linkClientMetrics: states.linkClientMetrics, linkClientMetrics: states.linkClientMetrics,
nodeMetrics: states.nodeMetrics, nodeMetrics: states.nodeMetrics,
legend: legend.metric, legend: metrics,
}); };
dashboardStore.selectWidget({ ...dashboardStore.selectedGrid, ...param });
dashboardStore.setConfigs({ ...dashboardStore.selectedGrid, ...param });
emit("update", param);
} }
async function changeLinkServerMetrics(options: Option[] | any) { async function changeLinkServerMetrics(options: Option[] | any) {
states.linkServerMetrics = options.map((d: Option) => d.value); states.linkServerMetrics = options.map((d: Option) => d.value);
@ -352,15 +363,7 @@ async function changeLinkServerMetrics(options: Option[] | any) {
topologyStore.setLinkServerMetrics({}); topologyStore.setLinkServerMetrics({});
return; return;
} }
const idsS = topologyStore.calls topologyStore.getLinkServerMetrics(states.linkServerMetrics);
.filter((i: Call) => i.detectPoints.includes("SERVER"))
.map((b: Call) => b.id);
const param = await useQueryTopologyMetrics(states.linkServerMetrics, idsS);
const res = await topologyStore.getCallServerMetrics(param);
if (res.errors) {
ElMessage.error(res.errors);
}
} }
async function changeLinkClientMetrics(options: Option[] | any) { async function changeLinkClientMetrics(options: Option[] | any) {
states.linkClientMetrics = options.map((d: Option) => d.value); states.linkClientMetrics = options.map((d: Option) => d.value);
@ -369,30 +372,16 @@ async function changeLinkClientMetrics(options: Option[] | any) {
topologyStore.setLinkClientMetrics({}); topologyStore.setLinkClientMetrics({});
return; return;
} }
const idsC = topologyStore.calls topologyStore.getLinkClientMetrics(states.linkClientMetrics);
.filter((i: Call) => i.detectPoints.includes("CLIENT"))
.map((b: Call) => b.id);
const param = await useQueryTopologyMetrics(states.linkClientMetrics, idsC);
const res = await topologyStore.getCallClientMetrics(param);
if (res.errors) {
ElMessage.error(res.errors);
}
} }
async function changeNodeMetrics(options: Option[] | any) { async function changeNodeMetrics(options: Option[] | any) {
states.nodeMetrics = options.map((d: Option) => d.value); states.nodeMetrics = options.map((d: Option) => d.value);
updateSettings(); updateSettings();
if (!states.nodeMetrics.length) { if (!states.nodeMetrics.length) {
topologyStore.setNodeMetrics({}); topologyStore.setNodeMetricValue({});
return; return;
} }
const ids = topologyStore.nodes.map((d: Node) => d.id); topologyStore.queryNodeMetrics(states.nodeMetrics);
const param = await useQueryTopologyMetrics(states.nodeMetrics, ids);
const res = await topologyStore.getNodeMetrics(param);
if (res.errors) {
ElMessage.error(res.errors);
}
} }
function deleteMetric(index: number) { function deleteMetric(index: number) {
legend.metric.splice(index, 1); legend.metric.splice(index, 1);