diff --git a/src/router/dashboard.ts b/src/router/dashboard.ts index 37369ec8..01105f94 100644 --- a/src/router/dashboard.ts +++ b/src/router/dashboard.ts @@ -87,6 +87,16 @@ export const routesDashboard: Array = [ notShow: true, }, }, + { + path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name", + component: () => import("@/views/dashboard/Edit.vue"), + name: "ViewPodRelation", + meta: { + title: "dashboardEdit", + exact: true, + notShow: true, + }, + }, ], }, ]; diff --git a/src/store/data.ts b/src/store/data.ts index 24402d22..d2bb2805 100644 --- a/src/store/data.ts +++ b/src/store/data.ts @@ -143,3 +143,45 @@ export const ConfigData4: any = { }, children: [], }; +export const ConfigData5: any = { + x: 0, + y: 0, + w: 8, + h: 12, + i: "0", + metrics: ["endpoint_relation_cpm"], + metricTypes: ["readMetricsValues"], + type: "Widget", + widget: { + title: "endpoint_relation_cpm", + tips: "Tooltip", + }, + graph: { + type: "Line", + }, + standard: { + unit: "min", + }, + children: [], +}; +export const ConfigData6: any = { + x: 0, + y: 0, + w: 8, + h: 12, + i: "0", + metrics: ["service_instance_relation_server_cpm"], + metricTypes: ["readMetricsValues"], + type: "Widget", + widget: { + title: "service_instance_relation_server_cpm", + tips: "Tooltip", + }, + graph: { + type: "Line", + }, + standard: { + unit: "min", + }, + children: [], +}; diff --git a/src/store/modules/dashboard.ts b/src/store/modules/dashboard.ts index 3500c87d..cf926f83 100644 --- a/src/store/modules/dashboard.ts +++ b/src/store/modules/dashboard.ts @@ -25,6 +25,8 @@ import { ConfigData2, ConfigData3, ConfigData4, + ConfigData5, + ConfigData6, } from "../data"; import { useAppStoreWithOut } from "@/store/modules/app"; import { useSelectorStore } from "@/store/modules/selectors"; @@ -170,6 +172,12 @@ export const dashboardStore = defineStore({ if (type == "ServiceRelation") { this.layout = [ConfigData4]; } + if (type == "ServiceInstanceRelation") { + this.layout = [ConfigData6]; + } + if (type == "EndpointRelation") { + this.layout = [ConfigData5]; + } }, setTopology(show: boolean) { this.showTopology = show; diff --git a/src/store/modules/selectors.ts b/src/store/modules/selectors.ts index 04fb9220..893af48b 100644 --- a/src/store/modules/selectors.ts +++ b/src/store/modules/selectors.ts @@ -24,11 +24,13 @@ import { useAppStoreWithOut } from "@/store/modules/app"; interface SelectorState { services: Service[]; + destServices: Service[]; pods: Array; currentService: Nullable; currentPod: Nullable; currentDestService: Nullable; currentDestPod: Nullable; + destPods: Array; durationTime: Duration; } @@ -36,7 +38,9 @@ export const selectorStore = defineStore({ id: "selector", state: (): SelectorState => ({ services: [], + destServices: [], pods: [], + destPods: [], currentService: null, currentPod: null, currentDestService: null, @@ -54,7 +58,7 @@ export const selectorStore = defineStore({ this.currentPod = pod; }, setCurrentDestPod(pod: Nullable) { - this.currentPod = pod; + this.currentDestPod = pod; }, async fetchLayers(): Promise { const res: AxiosResponse = await graphql.query("queryLayers").params({}); @@ -68,11 +72,13 @@ export const selectorStore = defineStore({ if (!res.data.errors) { this.services = res.data.data.services || []; + this.destServices = res.data.data.services || []; } return res.data; }, async getServiceInstances(param?: { serviceId: string; + isRelation: boolean; }): Promise> { const serviceId = param ? param.serviceId : this.currentService?.id; if (!serviceId) { @@ -83,20 +89,22 @@ export const selectorStore = defineStore({ duration: this.durationTime, }); if (!res.data.errors) { + if (param && param.isRelation) { + this.destPods = res.data.data.pods || []; + return res.data; + } this.pods = res.data.data.pods || []; } return res.data; }, - async getEndpoints(params?: { + async getEndpoints(params: { keyword?: string; serviceId?: string; + isRelation?: boolean; }): Promise> { if (!params) { params = {}; } - if (!params.keyword) { - params.keyword = ""; - } const serviceId = params.serviceId || this.currentService?.id; if (!serviceId) { return null; @@ -104,14 +112,18 @@ export const selectorStore = defineStore({ const res: AxiosResponse = await graphql.query("queryEndpoints").params({ serviceId, duration: this.durationTime, - keyword: params.keyword, + keyword: params.keyword || "", }); if (!res.data.errors) { + if (params.isRelation) { + this.destPods = res.data.data.pods || []; + return res.data; + } this.pods = res.data.data.pods || []; } return res.data; }, - async getService(serviceId: string) { + async getService(serviceId: string, isRelation: boolean) { if (!serviceId) { return; } @@ -119,13 +131,18 @@ export const selectorStore = defineStore({ serviceId, }); if (!res.data.errors) { + if (isRelation) { + this.setCurrentDestService(res.data.data.service); + this.destServices = [res.data.data.service]; + return res.data; + } this.setCurrentService(res.data.data.service); this.services = [res.data.data.service]; } return res.data; }, - async getInstance(instanceId: string) { + async getInstance(instanceId: string, isRelation?: boolean) { if (!instanceId) { return; } @@ -133,12 +150,18 @@ export const selectorStore = defineStore({ instanceId, }); if (!res.data.errors) { + if (isRelation) { + this.currentDestPod = res.data.data.instance || null; + this.destPods = [res.data.data.instance]; + return; + } this.currentPod = res.data.data.instance || null; + this.pods = [res.data.data.instance]; } return res.data; }, - async getEndpoint(endpointId: string) { + async getEndpoint(endpointId: string, isRelation?: string) { if (!endpointId) { return; } @@ -146,7 +169,13 @@ export const selectorStore = defineStore({ endpointId, }); if (!res.data.errors) { + if (isRelation) { + this.currentDestPod = res.data.data.endpoint || null; + this.destPods = [res.data.data.endpoint]; + return; + } this.currentPod = res.data.data.endpoint || null; + this.pods = [res.data.data.endpoint]; } return res.data; diff --git a/src/views/dashboard/controls/Widget.vue b/src/views/dashboard/controls/Widget.vue index 7d538732..9f1977c9 100644 --- a/src/views/dashboard/controls/Widget.vue +++ b/src/views/dashboard/controls/Widget.vue @@ -147,7 +147,16 @@ export default defineComponent({ } ); watch( - () => selectorStore.currentPod, + () => [selectorStore.currentPod], + () => { + if (dashboardStore.entity === EntityType[0].value) { + return; + } + queryMetrics(); + } + ); + watch( + () => [selectorStore.currentDestPod], () => { if (dashboardStore.entity === EntityType[0].value) { return; diff --git a/src/views/dashboard/data.ts b/src/views/dashboard/data.ts index 3eb60567..f651d6ee 100644 --- a/src/views/dashboard/data.ts +++ b/src/views/dashboard/data.ts @@ -166,9 +166,9 @@ export const ToolIcons = [ { name: "playlist_add", content: "Add Widget", id: "addWidget" }, { name: "all_inbox", content: "Add Tab", id: "addTab" }, // { name: "insert_image", content: "Add Image", id: "addImage" }, - { name: "save_alt", content: "Export", id: "export" }, - { name: "folder_open", content: "Import", id: "import" }, - { name: "settings", content: "Settings", id: "settings" }, + // { name: "save_alt", content: "Export", id: "export" }, + // { name: "folder_open", content: "Import", id: "import" }, + // { name: "settings", content: "Settings", id: "settings" }, { name: "device_hub", content: "Topology", id: "topology" }, - { name: "save", content: "Apply", id: "apply" }, + // { name: "save", content: "Apply", id: "apply" }, ]; diff --git a/src/views/dashboard/panel/Tool.vue b/src/views/dashboard/panel/Tool.vue index 3f24cfa9..d1dbb4b8 100644 --- a/src/views/dashboard/panel/Tool.vue +++ b/src/views/dashboard/panel/Tool.vue @@ -43,11 +43,11 @@ limitations under the License. --> class="selectorPod" /> -
+
$DestinationService
$DestinationServiceInstance
@@ -111,6 +110,7 @@ const states = reactive<{ currentService: string; currentPod: string; currentDestService: string; + currentDestPod: string; }>({ destService: "", destPod: "", @@ -118,6 +118,7 @@ const states = reactive<{ currentService: "", currentPod: "", currentDestService: "", + currentDestPod: "", }); dashboardStore.setLayer(String(params.layerId)); @@ -135,12 +136,19 @@ function initSelector() { async function setSelector() { if ( - params.entity === EntityType[2].value || - params.entity === EntityType[3].value + [ + EntityType[2].value, + EntityType[3].value, + EntityType[5].value, + EntityType[6].value, + ].includes(String(params.entity)) ) { await selectorStore.getService(String(params.serviceId)); states.currentService = selectorStore.currentService.value; - await fetchPods(String(params.entity), false); + await selectorStore.getService(String(params.destServiceId), true); + states.currentDestService = selectorStore.currentDestService.value; + const e = String(params.entity).split("Relation")[0]; + await fetchPods(e, selectorStore.currentService.id, false); if (!(selectorStore.pods.length && selectorStore.pods[0])) { selectorStore.setCurrentPod(null); states.currentPod = ""; @@ -150,11 +158,36 @@ async function setSelector() { const currentPod = selectorStore.pods.filter( (d: { id: string }) => d.id === pod )[0]; - selectorStore.setCurrentPod(currentPod); - states.currentPod = currentPod.label; + if (currentPod) { + selectorStore.setCurrentPod(currentPod); + states.currentPod = currentPod.label; + } + if ( + [EntityType[2].value, EntityType[3].value].includes(String(params.entity)) + ) { + return; + } + await fetchPods( + String(params.entity), + selectorStore.currentDestService.id, + false + ); + if (!(selectorStore.destPods.length && selectorStore.destPods[0])) { + selectorStore.setCurrentDestPod(null); + states.currentDestPod = ""; + return; + } + const destPod = params.destPodId || selectorStore.destPods[0].id; + const currentDestPod = selectorStore.destPods.filter( + (d: { id: string }) => d.id === destPod + )[0]; + if (currentDestPod) { + selectorStore.setCurrentDestPod(currentDestPod); + states.currentDestPod = currentDestPod.label; + } return; } - // entity=Service with serviceId + // entity=Service/ServiceRelation const json = await selectorStore.fetchServices(dashboardStore.layerId); if (json.errors) { ElMessage.error(json.errors); @@ -195,14 +228,16 @@ async function getServices() { ); states.currentService = selectorStore.currentService.value; states.currentDestService = selectorStore.currentDestService.value; - fetchPods(dashboardStore.entity, true); + const e = dashboardStore.entity.split("Relation")[0]; + fetchPods(e, selectorStore.currentService.id, true); + fetchPods(dashboardStore.entity, selectorStore.currentDestService.id, true); } async function changeService(service: Service[]) { if (service[0]) { states.currentService = service[0].value; selectorStore.setCurrentService(service[0]); - fetchPods(dashboardStore.entity, true); + fetchPods(dashboardStore.entity, selectorStore.currentService.id, true); } else { selectorStore.setCurrentService(null); } @@ -247,11 +282,11 @@ function clickIcons(t: { id: string; content: string; name: string }) { } } -async function fetchPods(type: string, setPod: boolean) { +async function fetchPods(type: string, serviceId: string, setPod: boolean) { let resp; switch (type) { - case "Endpoint": - resp = await selectorStore.getEndpoints(); + case EntityType[2].value: + resp = await selectorStore.getEndpoints({ serviceId }); if (setPod) { selectorStore.setCurrentPod( selectorStore.pods.length ? selectorStore.pods[0] : null @@ -259,8 +294,8 @@ async function fetchPods(type: string, setPod: boolean) { states.currentPod = selectorStore.currentPod.label; } break; - case "ServiceInstance": - resp = await selectorStore.getServiceInstances(); + case EntityType[3].value: + resp = await selectorStore.getServiceInstances({ serviceId }); if (setPod) { selectorStore.setCurrentPod( selectorStore.pods.length ? selectorStore.pods[0] : null @@ -268,6 +303,27 @@ async function fetchPods(type: string, setPod: boolean) { states.currentPod = selectorStore.currentPod.label; } break; + case EntityType[6].value: + resp = await selectorStore.getEndpoints({ serviceId, isRelation: true }); + if (setPod) { + selectorStore.setCurrentDestPod( + selectorStore.destPods.length ? selectorStore.destPods[0] : null + ); + states.currentDestPod = selectorStore.currentDestPod.label; + } + break; + case EntityType[5].value: + resp = await selectorStore.getServiceInstances({ + serviceId, + isRelation: true, + }); + if (setPod) { + selectorStore.setCurrentDestPod( + selectorStore.destPods.length ? selectorStore.destPods[0] : null + ); + states.currentDestPod = selectorStore.currentDestPod.label; + } + break; default: resp = {}; } diff --git a/src/views/dashboard/related/topology/components/Graph.vue b/src/views/dashboard/related/topology/components/Graph.vue index b8c9fc0b..51be8824 100644 --- a/src/views/dashboard/related/topology/components/Graph.vue +++ b/src/views/dashboard/related/topology/components/Graph.vue @@ -200,6 +200,9 @@ function handleLinkClick(event: any, d: Call) { event.stopPropagation(); topologyStore.setNode(null); topologyStore.setLink(d); + if (settings.value.linkDashboard) { + return; + } const e = dashboardStore.entity === EntityType[1].value ? EntityType[0].value diff --git a/src/views/dashboard/related/topology/components/PodTopology.vue b/src/views/dashboard/related/topology/components/PodTopology.vue index 149b5489..52fb74fb 100644 --- a/src/views/dashboard/related/topology/components/PodTopology.vue +++ b/src/views/dashboard/related/topology/components/PodTopology.vue @@ -36,12 +36,24 @@ limitations under the License. --> :style="`height:${height}px;width:${width}px;`" v-loading="loading" > - + +
+
+ + {{ item.title }} +