mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-07-18 11:25:22 +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. -->
|
||||
<template>
|
||||
<el-select
|
||||
:size="size"
|
||||
size
|
||||
v-model="selected"
|
||||
:placeholder="placeholder"
|
||||
@change="changeSelected"
|
||||
@ -55,7 +55,7 @@ const props = defineProps({
|
||||
type: [Array, String] as PropType<string[] | string>,
|
||||
default: () => [],
|
||||
},
|
||||
size: { type: String, default: "default" },
|
||||
size: { type: String },
|
||||
placeholder: { type: String, default: "Select a option" },
|
||||
borderRadius: { type: Number, default: 3 },
|
||||
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",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
name: "CreateService",
|
||||
name: "View",
|
||||
meta: {
|
||||
title: "dashboardEdit",
|
||||
exact: false,
|
||||
@ -70,7 +70,7 @@ export const routesDashboard: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: "/dashboard/:layerId/:entity/:serviceId/:destServiceId/:name",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
name: "CreateServiceRelation",
|
||||
name: "ViewServiceRelation",
|
||||
meta: {
|
||||
title: "dashboardEdit",
|
||||
exact: false,
|
||||
|
@ -152,6 +152,7 @@ export const EntityType = [
|
||||
},
|
||||
{ value: "EndpointRelation", label: "Endpoint Relation", key: 4 },
|
||||
];
|
||||
export const hasTopology = ["All", "Service", "ServiceRelation", "Endpoint"];
|
||||
export const TableEntity: any = {
|
||||
InstanceList: EntityType[3].value,
|
||||
EndpointList: EntityType[2].value,
|
||||
|
@ -69,13 +69,20 @@ limitations under the License. -->
|
||||
</div>
|
||||
<div class="tool-icons">
|
||||
<span
|
||||
class="icon-btn"
|
||||
@click="clickIcons(t)"
|
||||
v-for="(t, index) in ToolIcons"
|
||||
:key="index"
|
||||
: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>
|
||||
</div>
|
||||
</div>
|
||||
@ -86,7 +93,7 @@ import { reactive, watch } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
import { EntityType, ToolIcons } from "../data";
|
||||
import { EntityType, ToolIcons, hasTopology } from "../data";
|
||||
import { useSelectorStore } from "@/store/modules/selectors";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { Option } from "@/types/app";
|
||||
@ -288,7 +295,7 @@ watch(
|
||||
|
||||
.icon-btn {
|
||||
display: inline-block;
|
||||
padding: 0 5px 2px 5px;
|
||||
padding: 3px;
|
||||
text-align: center;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 3px;
|
||||
|
@ -39,7 +39,7 @@ import zoom from "./utils/zoom";
|
||||
import { simulationInit, simulationSkip } from "./utils/simulation";
|
||||
import nodeElement from "./utils/nodeElement";
|
||||
import { linkElement, anchorElement, arrowMarker } from "./utils/linkElement";
|
||||
// import tool from "./utils/tool";
|
||||
import tool from "./utils/tool";
|
||||
import topoLegend from "./utils/legend";
|
||||
import { Node, Call } from "@/types/topology";
|
||||
import { useTopologyStore } from "@/store/modules/topology";
|
||||
@ -48,7 +48,6 @@ import { EntityType } from "../../data";
|
||||
import router from "@/router";
|
||||
import { ElMessage } from "element-plus";
|
||||
import Settings from "./Settings.vue";
|
||||
// import { Option } from "@/types/app";
|
||||
|
||||
/*global Nullable */
|
||||
const { t } = useI18n();
|
||||
@ -99,48 +98,23 @@ onMounted(async () => {
|
||||
anchor.value = graph.value.append("g").selectAll(".topo-line-anchor");
|
||||
arrow.value = graph.value.append("g").selectAll(".topo-line-arrow");
|
||||
svg.value.call(zoom(d3, graph.value));
|
||||
// tools.value = tool(graph.value, [
|
||||
// { icon: "API", click: handleGoEndpoint },
|
||||
// { icon: "INSTANCE", click: handleGoInstance },
|
||||
// { icon: "TRACE", click: handleGoTrace },
|
||||
// { icon: "ALARM", click: handleGoAlarm },
|
||||
// { icon: "ENDPOINT", click: handleGoEndpointDependency },
|
||||
// { icon: "" },
|
||||
// ]);
|
||||
tools.value = tool(graph.value, tip.value, [
|
||||
{ icon: "API", title: "Endpoint", func: handleGoEndpoint },
|
||||
{ icon: "INSTANCE", title: "Instance", func: handleGoInstance },
|
||||
{ icon: "TRACE", title: "Dashboard", func: handleGoDashboard },
|
||||
{ icon: "ALARM", title: "Alarm", func: handleGoAlarm },
|
||||
{ icon: "" },
|
||||
{ icon: "" },
|
||||
]);
|
||||
// legend
|
||||
legend.value = graph.value.append("g").attr("class", "topo-legend");
|
||||
topoLegend(legend.value, height.value, width.value);
|
||||
svg.value.on("click", (event: any) => {
|
||||
event.stopPropagation();
|
||||
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() {
|
||||
link.value.attr(
|
||||
"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) {
|
||||
settings.value = config;
|
||||
}
|
||||
|
@ -56,16 +56,16 @@ export default (
|
||||
.on("mouseout", function () {
|
||||
tip.hide(this);
|
||||
})
|
||||
.on("click", (event: any, d: unknown) => {
|
||||
.on("click", (event: any, d: Node | any) => {
|
||||
event.stopPropagation();
|
||||
// event.preventDefault();
|
||||
// tool.attr("style", "display: none");
|
||||
event.preventDefault();
|
||||
tool.attr("style", "display: none");
|
||||
funcs.handleNodeClick(d);
|
||||
// if (d.isReal) {
|
||||
// tool
|
||||
// .attr("transform", `translate(${d.x},${d.y - 20})`)
|
||||
// .attr("style", "display: block");
|
||||
// }
|
||||
if (d.isReal) {
|
||||
tool
|
||||
.attr("transform", `translate(${d.x},${d.y - 20})`)
|
||||
.attr("style", "display: block");
|
||||
}
|
||||
});
|
||||
nodeEnter
|
||||
.append("image")
|
||||
|
@ -15,6 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import icons from "./icons";
|
||||
import { Node } from "@/types/topology";
|
||||
|
||||
const Hexagon = (side: number, r: number, cx: number, cy: number) => {
|
||||
let path = "";
|
||||
@ -27,7 +28,7 @@ const Hexagon = (side: number, r: number, cx: number, cy: number) => {
|
||||
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 side = 6;
|
||||
for (let i = 0; i < data.length; i += 1) {
|
||||
@ -36,7 +37,13 @@ export default (graph: any, data: any) => {
|
||||
const tool_g = tool
|
||||
.append("g")
|
||||
.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
|
||||
.append("path")
|
||||
.attr("class", "tool-hexagon")
|
||||
|
Loading…
Reference in New Issue
Block a user