mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-07-18 13:25:25 +00:00
feat: set links for topology
This commit is contained in:
parent
d7c42fe2cb
commit
078f1bc042
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License. -->
|
limitations under the License. -->
|
||||||
<template>
|
<template>
|
||||||
<el-select
|
<el-select
|
||||||
:size="size"
|
size
|
||||||
v-model="selected"
|
v-model="selected"
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
@change="changeSelected"
|
@change="changeSelected"
|
||||||
@ -55,7 +55,7 @@ const props = defineProps({
|
|||||||
type: [Array, String] as PropType<string[] | string>,
|
type: [Array, String] as PropType<string[] | string>,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
size: { type: String, default: "default" },
|
size: { type: String },
|
||||||
placeholder: { type: String, default: "Select a option" },
|
placeholder: { type: String, default: "Select a option" },
|
||||||
borderRadius: { type: Number, default: 3 },
|
borderRadius: { type: Number, default: 3 },
|
||||||
multiple: { type: Boolean, default: false },
|
multiple: { type: Boolean, default: false },
|
||||||
|
43
src/router/alarm.ts
Normal file
43
src/router/alarm.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
import { RouteRecordRaw } from "vue-router";
|
||||||
|
import Layout from "@/layout/Index.vue";
|
||||||
|
|
||||||
|
export const routesAlarm: Array<RouteRecordRaw> = [
|
||||||
|
{
|
||||||
|
path: "",
|
||||||
|
name: "Alarm",
|
||||||
|
meta: {
|
||||||
|
title: "alarm",
|
||||||
|
icon: "spam",
|
||||||
|
hasGroup: false,
|
||||||
|
exact: true,
|
||||||
|
},
|
||||||
|
component: Layout,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: "/alarm",
|
||||||
|
name: "Alarm",
|
||||||
|
meta: {
|
||||||
|
title: "alarmList",
|
||||||
|
exact: false,
|
||||||
|
},
|
||||||
|
component: () => import("@/views/Log.vue"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
@ -60,7 +60,7 @@ export const routesDashboard: Array<RouteRecordRaw> = [
|
|||||||
{
|
{
|
||||||
path: "/dashboard/:layerId/:entity/:serviceId/:name",
|
path: "/dashboard/:layerId/:entity/:serviceId/:name",
|
||||||
component: () => import("@/views/dashboard/Edit.vue"),
|
component: () => import("@/views/dashboard/Edit.vue"),
|
||||||
name: "CreateService",
|
name: "View",
|
||||||
meta: {
|
meta: {
|
||||||
title: "dashboardEdit",
|
title: "dashboardEdit",
|
||||||
exact: false,
|
exact: false,
|
||||||
@ -70,7 +70,7 @@ export const routesDashboard: Array<RouteRecordRaw> = [
|
|||||||
{
|
{
|
||||||
path: "/dashboard/:layerId/:entity/:serviceId/:destServiceId/:name",
|
path: "/dashboard/:layerId/:entity/:serviceId/:destServiceId/:name",
|
||||||
component: () => import("@/views/dashboard/Edit.vue"),
|
component: () => import("@/views/dashboard/Edit.vue"),
|
||||||
name: "CreateServiceRelation",
|
name: "ViewServiceRelation",
|
||||||
meta: {
|
meta: {
|
||||||
title: "dashboardEdit",
|
title: "dashboardEdit",
|
||||||
exact: false,
|
exact: false,
|
||||||
|
@ -152,6 +152,7 @@ export const EntityType = [
|
|||||||
},
|
},
|
||||||
{ value: "EndpointRelation", label: "Endpoint Relation", key: 4 },
|
{ value: "EndpointRelation", label: "Endpoint Relation", key: 4 },
|
||||||
];
|
];
|
||||||
|
export const hasTopology = ["All", "Service", "ServiceRelation", "Endpoint"];
|
||||||
export const TableEntity: any = {
|
export const TableEntity: any = {
|
||||||
InstanceList: EntityType[3].value,
|
InstanceList: EntityType[3].value,
|
||||||
EndpointList: EntityType[2].value,
|
EndpointList: EntityType[2].value,
|
||||||
|
@ -69,13 +69,20 @@ limitations under the License. -->
|
|||||||
</div>
|
</div>
|
||||||
<div class="tool-icons">
|
<div class="tool-icons">
|
||||||
<span
|
<span
|
||||||
class="icon-btn"
|
|
||||||
@click="clickIcons(t)"
|
@click="clickIcons(t)"
|
||||||
v-for="(t, index) in ToolIcons"
|
v-for="(t, index) in ToolIcons"
|
||||||
:key="index"
|
:key="index"
|
||||||
:title="t.content"
|
:title="t.content"
|
||||||
>
|
>
|
||||||
<Icon size="sm" :iconName="t.name" />
|
<Icon
|
||||||
|
class="icon-btn"
|
||||||
|
size="sm"
|
||||||
|
:iconName="t.name"
|
||||||
|
v-if="
|
||||||
|
t.id !== 'topology' ||
|
||||||
|
(t.id === 'topology' && hasTopology.includes(dashboardStore.entity))
|
||||||
|
"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -86,7 +93,7 @@ import { reactive, watch } from "vue";
|
|||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||||
import { EntityType, ToolIcons } from "../data";
|
import { EntityType, ToolIcons, hasTopology } from "../data";
|
||||||
import { useSelectorStore } from "@/store/modules/selectors";
|
import { useSelectorStore } from "@/store/modules/selectors";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { Option } from "@/types/app";
|
import { Option } from "@/types/app";
|
||||||
@ -288,7 +295,7 @@ watch(
|
|||||||
|
|
||||||
.icon-btn {
|
.icon-btn {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 0 5px 2px 5px;
|
padding: 3px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
@ -39,7 +39,7 @@ import zoom from "./utils/zoom";
|
|||||||
import { simulationInit, simulationSkip } from "./utils/simulation";
|
import { simulationInit, simulationSkip } from "./utils/simulation";
|
||||||
import nodeElement from "./utils/nodeElement";
|
import nodeElement from "./utils/nodeElement";
|
||||||
import { linkElement, anchorElement, arrowMarker } from "./utils/linkElement";
|
import { linkElement, anchorElement, arrowMarker } from "./utils/linkElement";
|
||||||
// import tool from "./utils/tool";
|
import tool from "./utils/tool";
|
||||||
import topoLegend from "./utils/legend";
|
import topoLegend from "./utils/legend";
|
||||||
import { Node, Call } from "@/types/topology";
|
import { Node, Call } from "@/types/topology";
|
||||||
import { useTopologyStore } from "@/store/modules/topology";
|
import { useTopologyStore } from "@/store/modules/topology";
|
||||||
@ -48,7 +48,6 @@ import { EntityType } from "../../data";
|
|||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import Settings from "./Settings.vue";
|
import Settings from "./Settings.vue";
|
||||||
// import { Option } from "@/types/app";
|
|
||||||
|
|
||||||
/*global Nullable */
|
/*global Nullable */
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
@ -99,48 +98,23 @@ onMounted(async () => {
|
|||||||
anchor.value = graph.value.append("g").selectAll(".topo-line-anchor");
|
anchor.value = graph.value.append("g").selectAll(".topo-line-anchor");
|
||||||
arrow.value = graph.value.append("g").selectAll(".topo-line-arrow");
|
arrow.value = graph.value.append("g").selectAll(".topo-line-arrow");
|
||||||
svg.value.call(zoom(d3, graph.value));
|
svg.value.call(zoom(d3, graph.value));
|
||||||
// tools.value = tool(graph.value, [
|
tools.value = tool(graph.value, tip.value, [
|
||||||
// { icon: "API", click: handleGoEndpoint },
|
{ icon: "API", title: "Endpoint", func: handleGoEndpoint },
|
||||||
// { icon: "INSTANCE", click: handleGoInstance },
|
{ icon: "INSTANCE", title: "Instance", func: handleGoInstance },
|
||||||
// { icon: "TRACE", click: handleGoTrace },
|
{ icon: "TRACE", title: "Dashboard", func: handleGoDashboard },
|
||||||
// { icon: "ALARM", click: handleGoAlarm },
|
{ icon: "ALARM", title: "Alarm", func: handleGoAlarm },
|
||||||
// { icon: "ENDPOINT", click: handleGoEndpointDependency },
|
{ icon: "" },
|
||||||
// { icon: "" },
|
{ icon: "" },
|
||||||
// ]);
|
]);
|
||||||
// legend
|
// legend
|
||||||
legend.value = graph.value.append("g").attr("class", "topo-legend");
|
legend.value = graph.value.append("g").attr("class", "topo-legend");
|
||||||
topoLegend(legend.value, height.value, width.value);
|
topoLegend(legend.value, height.value, width.value);
|
||||||
svg.value.on("click", (event: any) => {
|
svg.value.on("click", (event: any) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
tools.value.attr("style", "display: none");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
async function getTopology() {
|
|
||||||
let resp;
|
|
||||||
switch (dashboardStore.entity) {
|
|
||||||
case EntityType[0].value:
|
|
||||||
resp = await topologyStore.getServiceTopology();
|
|
||||||
break;
|
|
||||||
case EntityType[1].value:
|
|
||||||
resp = await topologyStore.getGlobalTopology();
|
|
||||||
break;
|
|
||||||
case EntityType[2].value:
|
|
||||||
resp = await topologyStore.getEndpointTopology();
|
|
||||||
break;
|
|
||||||
case EntityType[3].value:
|
|
||||||
resp = await topologyStore.getInstanceTopology();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return resp;
|
|
||||||
}
|
|
||||||
function setConfig() {
|
|
||||||
showSetting.value = !showSetting.value;
|
|
||||||
}
|
|
||||||
function resize() {
|
|
||||||
height.value = document.body.clientHeight - 90;
|
|
||||||
width.value = document.body.clientWidth - 40;
|
|
||||||
svg.value.attr("height", height.value).attr("width", width.value);
|
|
||||||
}
|
|
||||||
function ticked() {
|
function ticked() {
|
||||||
link.value.attr(
|
link.value.attr(
|
||||||
"d",
|
"d",
|
||||||
@ -268,6 +242,59 @@ function update() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function handleGoEndpoint() {
|
||||||
|
const node = topologyStore.node;
|
||||||
|
const path = `/dashboard/${dashboardStore.layerId}/Endpoint/${node.id}/${settings.value.nodeDashboard}`;
|
||||||
|
const routeUrl = router.resolve({ path });
|
||||||
|
|
||||||
|
window.open(routeUrl.href, "_blank");
|
||||||
|
}
|
||||||
|
function handleGoInstance() {
|
||||||
|
const node = topologyStore.node;
|
||||||
|
const path = `/dashboard/${dashboardStore.layerId}/ServiceInstance/${node.id}/${settings.value.nodeDashboard}`;
|
||||||
|
const routeUrl = router.resolve({ path });
|
||||||
|
|
||||||
|
window.open(routeUrl.href, "_blank");
|
||||||
|
}
|
||||||
|
function handleGoDashboard() {
|
||||||
|
const node = topologyStore.node;
|
||||||
|
const path = `/dashboard/${dashboardStore.layerId}/Service/${node.id}/${settings.value.nodeDashboard}`;
|
||||||
|
const routeUrl = router.resolve({ path });
|
||||||
|
|
||||||
|
window.open(routeUrl.href, "_blank");
|
||||||
|
}
|
||||||
|
function handleGoAlarm() {
|
||||||
|
const path = `/alarm`;
|
||||||
|
const routeUrl = router.resolve({ path });
|
||||||
|
|
||||||
|
window.open(routeUrl.href, "_blank");
|
||||||
|
}
|
||||||
|
async function getTopology() {
|
||||||
|
let resp;
|
||||||
|
switch (dashboardStore.entity) {
|
||||||
|
case EntityType[0].value:
|
||||||
|
resp = await topologyStore.getServiceTopology();
|
||||||
|
break;
|
||||||
|
case EntityType[1].value:
|
||||||
|
resp = await topologyStore.getGlobalTopology();
|
||||||
|
break;
|
||||||
|
case EntityType[2].value:
|
||||||
|
resp = await topologyStore.getEndpointTopology();
|
||||||
|
break;
|
||||||
|
case EntityType[3].value:
|
||||||
|
resp = await topologyStore.getInstanceTopology();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
function setConfig() {
|
||||||
|
showSetting.value = !showSetting.value;
|
||||||
|
}
|
||||||
|
function resize() {
|
||||||
|
height.value = document.body.clientHeight - 90;
|
||||||
|
width.value = document.body.clientWidth - 40;
|
||||||
|
svg.value.attr("height", height.value).attr("width", width.value);
|
||||||
|
}
|
||||||
function updateSettings(config: any) {
|
function updateSettings(config: any) {
|
||||||
settings.value = config;
|
settings.value = config;
|
||||||
}
|
}
|
||||||
|
@ -56,16 +56,16 @@ export default (
|
|||||||
.on("mouseout", function () {
|
.on("mouseout", function () {
|
||||||
tip.hide(this);
|
tip.hide(this);
|
||||||
})
|
})
|
||||||
.on("click", (event: any, d: unknown) => {
|
.on("click", (event: any, d: Node | any) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
// event.preventDefault();
|
event.preventDefault();
|
||||||
// tool.attr("style", "display: none");
|
tool.attr("style", "display: none");
|
||||||
funcs.handleNodeClick(d);
|
funcs.handleNodeClick(d);
|
||||||
// if (d.isReal) {
|
if (d.isReal) {
|
||||||
// tool
|
tool
|
||||||
// .attr("transform", `translate(${d.x},${d.y - 20})`)
|
.attr("transform", `translate(${d.x},${d.y - 20})`)
|
||||||
// .attr("style", "display: block");
|
.attr("style", "display: block");
|
||||||
// }
|
}
|
||||||
});
|
});
|
||||||
nodeEnter
|
nodeEnter
|
||||||
.append("image")
|
.append("image")
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import icons from "./icons";
|
import icons from "./icons";
|
||||||
|
import { Node } from "@/types/topology";
|
||||||
|
|
||||||
const Hexagon = (side: number, r: number, cx: number, cy: number) => {
|
const Hexagon = (side: number, r: number, cx: number, cy: number) => {
|
||||||
let path = "";
|
let path = "";
|
||||||
@ -27,7 +28,7 @@ const Hexagon = (side: number, r: number, cx: number, cy: number) => {
|
|||||||
return path;
|
return path;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default (graph: any, data: any) => {
|
export default (graph: any, tip: any, data: any) => {
|
||||||
const tool = graph.append("g").attr("class", "topo-tool");
|
const tool = graph.append("g").attr("class", "topo-tool");
|
||||||
const side = 6;
|
const side = 6;
|
||||||
for (let i = 0; i < data.length; i += 1) {
|
for (let i = 0; i < data.length; i += 1) {
|
||||||
@ -36,7 +37,13 @@ export default (graph: any, data: any) => {
|
|||||||
const tool_g = tool
|
const tool_g = tool
|
||||||
.append("g")
|
.append("g")
|
||||||
.attr("class", "topo-tool-i")
|
.attr("class", "topo-tool-i")
|
||||||
.on("click", data[i].click);
|
.on("mouseover", function (event: any, d: Node) {
|
||||||
|
tip.html(() => data[i].title).show(d, this);
|
||||||
|
})
|
||||||
|
.on("mouseout", function () {
|
||||||
|
tip.hide(this);
|
||||||
|
})
|
||||||
|
.on("click", data[i].func);
|
||||||
tool_g
|
tool_g
|
||||||
.append("path")
|
.append("path")
|
||||||
.attr("class", "tool-hexagon")
|
.attr("class", "tool-hexagon")
|
||||||
|
Loading…
Reference in New Issue
Block a user