mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-05-12 15:52:57 +00:00
feat: get default dashboard
This commit is contained in:
commit
6c4144a5ef
@ -17,15 +17,25 @@
|
|||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
import type { LayoutConfig } from "@/types/dashboard";
|
import type { LayoutConfig } from "@/types/dashboard";
|
||||||
|
import { ConfigFieldTypes } from "@/views/dashboard/data";
|
||||||
|
|
||||||
export default function getDashboard(param?: { name: string; layer: string; entity: string }) {
|
export default function getDashboard(param?: { name?: string; layer: string; entity: string }, t?: string) {
|
||||||
|
const type = t || ConfigFieldTypes.NAME; // "NAME" or "ISDEFAULT"
|
||||||
const dashboardStore = useDashboardStore();
|
const dashboardStore = useDashboardStore();
|
||||||
const opt = param || dashboardStore.currentDashboard;
|
const opt = param || dashboardStore.currentDashboard;
|
||||||
const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
|
const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
|
||||||
const dashboard = list.find(
|
let dashboard;
|
||||||
(d: { name: string; layer: string; entity: string }) =>
|
if (type === ConfigFieldTypes.NAME) {
|
||||||
d.name === opt.name && d.entity === opt.entity && d.layer === opt.layer,
|
dashboard = list.find(
|
||||||
);
|
(d: { name: string; layer: string; entity: string }) =>
|
||||||
|
d.name === opt.name && d.entity === opt.entity && d.layer === opt.layer,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
dashboard = list.find(
|
||||||
|
(d: { name: string; layer: string; entity: string; isDefault: boolean }) =>
|
||||||
|
d.isDefault && d.entity === opt.entity && d.layer === opt.layer,
|
||||||
|
);
|
||||||
|
}
|
||||||
const all = dashboardStore.layout;
|
const all = dashboardStore.layout;
|
||||||
const widgets: LayoutConfig[] = [];
|
const widgets: LayoutConfig[] = [];
|
||||||
for (const item of all) {
|
for (const item of all) {
|
||||||
|
@ -386,5 +386,6 @@ const msg = {
|
|||||||
"The trace segment serves as a representation of a trace portion executed within one single OS process, such as a JVM. It comprises a collection of spans, typically associated with and collected from a single request or execution context.",
|
"The trace segment serves as a representation of a trace portion executed within one single OS process, such as a JVM. It comprises a collection of spans, typically associated with and collected from a single request or execution context.",
|
||||||
tabExpressions: "Tab Expressions",
|
tabExpressions: "Tab Expressions",
|
||||||
hierarchyServicesSettings: "Service Hierarchy Topology Settings",
|
hierarchyServicesSettings: "Service Hierarchy Topology Settings",
|
||||||
|
hierarchyNodeMetrics: "Metrics related with hierarchy topology nodes",
|
||||||
};
|
};
|
||||||
export default msg;
|
export default msg;
|
||||||
|
@ -386,5 +386,6 @@ const msg = {
|
|||||||
"The trace segment serves as a representation of a trace portion executed within one single OS process, such as a JVM. It comprises a collection of spans, typically associated with and collected from a single request or execution context.",
|
"The trace segment serves as a representation of a trace portion executed within one single OS process, such as a JVM. It comprises a collection of spans, typically associated with and collected from a single request or execution context.",
|
||||||
tabExpressions: "Tab Expressions",
|
tabExpressions: "Tab Expressions",
|
||||||
hierarchyServicesSettings: "Service Hierarchy Topology Settings",
|
hierarchyServicesSettings: "Service Hierarchy Topology Settings",
|
||||||
|
hierarchyNodeMetrics: "Metrics related with hierarchy topology nodes",
|
||||||
};
|
};
|
||||||
export default msg;
|
export default msg;
|
||||||
|
@ -384,5 +384,6 @@ const msg = {
|
|||||||
"Trace Segment代表在单一操作系统进程(例如JVM)中执行的追踪部分。它包含了一组跨度(spans),这些跨度通常与单一请求或执行上下文关联。",
|
"Trace Segment代表在单一操作系统进程(例如JVM)中执行的追踪部分。它包含了一组跨度(spans),这些跨度通常与单一请求或执行上下文关联。",
|
||||||
tabExpressions: "Tab表达式",
|
tabExpressions: "Tab表达式",
|
||||||
hierarchyServicesSettings: "层次结构服务拓扑设置",
|
hierarchyServicesSettings: "层次结构服务拓扑设置",
|
||||||
|
hierarchyNodeMetrics: "层级拓扑节点关联的指标",
|
||||||
};
|
};
|
||||||
export default msg;
|
export default msg;
|
||||||
|
1
src/types/dashboard.d.ts
vendored
1
src/types/dashboard.d.ts
vendored
@ -22,6 +22,7 @@ export type DashboardItem = {
|
|||||||
isRoot: boolean;
|
isRoot: boolean;
|
||||||
name: string;
|
name: string;
|
||||||
isDefault: boolean;
|
isDefault: boolean;
|
||||||
|
expressions?: string[];
|
||||||
};
|
};
|
||||||
export interface LayoutConfig {
|
export interface LayoutConfig {
|
||||||
x: number;
|
x: number;
|
||||||
|
@ -78,7 +78,7 @@ limitations under the License. -->
|
|||||||
<el-popconfirm
|
<el-popconfirm
|
||||||
:title="t('rootTitle')"
|
:title="t('rootTitle')"
|
||||||
@confirm="handleTopLevel(scope.row)"
|
@confirm="handleTopLevel(scope.row)"
|
||||||
v-if="[EntityType[0].value].includes(scope.row.entity)"
|
v-if="[EntityType[0].value, EntityType[3].value].includes(scope.row.entity)"
|
||||||
>
|
>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<el-button size="small" style="width: 80px">
|
<el-button size="small" style="width: 80px">
|
||||||
@ -97,6 +97,13 @@ limitations under the License. -->
|
|||||||
<el-button size="small" @click="handleRename(scope.row)">
|
<el-button size="small" @click="handleRename(scope.row)">
|
||||||
{{ t("rename") }}
|
{{ t("rename") }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
:disabled="![EntityType[0].value, EntityType[3].value].includes(scope.row.entity)"
|
||||||
|
size="small"
|
||||||
|
@click="handleEditMQE(scope.row)"
|
||||||
|
>
|
||||||
|
MQE
|
||||||
|
</el-button>
|
||||||
<el-popconfirm :title="t('deleteTitle')" @confirm="handleDelete(scope.row)">
|
<el-popconfirm :title="t('deleteTitle')" @confirm="handleDelete(scope.row)">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<el-button size="small" type="danger">
|
<el-button size="small" type="danger">
|
||||||
@ -139,6 +146,23 @@ limitations under the License. -->
|
|||||||
@next-click="changePage"
|
@next-click="changePage"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<el-dialog v-model="MQEVisible" title="Edit MQE" width="400px">
|
||||||
|
<div>{{ t("hierarchyNodeMetrics") }}</div>
|
||||||
|
<div class="mt-10 expressions">
|
||||||
|
<Tags
|
||||||
|
:tags="currentRow.expressions || []"
|
||||||
|
:vertical="true"
|
||||||
|
:text="t('addExpressions')"
|
||||||
|
@change="(param) => changeExpressions(param)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="MQEVisible = false">Cancel</el-button>
|
||||||
|
<el-button type="primary" @click="saveMQE"> Confirm </el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -167,6 +191,8 @@ limitations under the License. -->
|
|||||||
const multipleTableRef = ref<InstanceType<typeof ElTable>>();
|
const multipleTableRef = ref<InstanceType<typeof ElTable>>();
|
||||||
const multipleSelection = ref<DashboardItem[]>([]);
|
const multipleSelection = ref<DashboardItem[]>([]);
|
||||||
const dashboardFile = ref<Nullable<HTMLDivElement>>(null);
|
const dashboardFile = ref<Nullable<HTMLDivElement>>(null);
|
||||||
|
const MQEVisible = ref<boolean>(false);
|
||||||
|
const currentRow = ref<any>({});
|
||||||
|
|
||||||
const handleSelectionChange = (val: DashboardItem[]) => {
|
const handleSelectionChange = (val: DashboardItem[]) => {
|
||||||
multipleSelection.value = val;
|
multipleSelection.value = val;
|
||||||
@ -176,6 +202,55 @@ limitations under the License. -->
|
|||||||
await dashboardStore.setDashboards();
|
await dashboardStore.setDashboards();
|
||||||
searchDashboards(1);
|
searchDashboards(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function changeExpressions(params: string[]) {
|
||||||
|
currentRow.value.expressions = params;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleEditMQE(row: DashboardItem) {
|
||||||
|
MQEVisible.value = !MQEVisible.value;
|
||||||
|
currentRow.value = row;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveMQE() {
|
||||||
|
const items: DashboardItem[] = [];
|
||||||
|
loading.value = true;
|
||||||
|
for (const d of dashboardStore.dashboards) {
|
||||||
|
if (d.id === currentRow.value.id) {
|
||||||
|
d.expressions = currentRow.value.expressions;
|
||||||
|
const key = [d.layer, d.entity, d.name].join("_");
|
||||||
|
const layout = sessionStorage.getItem(key) || "{}";
|
||||||
|
const c = {
|
||||||
|
...JSON.parse(layout).configuration,
|
||||||
|
...d,
|
||||||
|
};
|
||||||
|
delete c.id;
|
||||||
|
const setting = {
|
||||||
|
id: d.id,
|
||||||
|
configuration: JSON.stringify(c),
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await dashboardStore.updateDashboard(setting);
|
||||||
|
if (res.data.changeTemplate.status) {
|
||||||
|
sessionStorage.setItem(
|
||||||
|
key,
|
||||||
|
JSON.stringify({
|
||||||
|
id: d.id,
|
||||||
|
configuration: c,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
loading.value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
items.push(d);
|
||||||
|
}
|
||||||
|
dashboardStore.resetDashboards(items);
|
||||||
|
searchDashboards(1);
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
async function importTemplates(event: any) {
|
async function importTemplates(event: any) {
|
||||||
const arr: any = await readFile(event);
|
const arr: any = await readFile(event);
|
||||||
for (const item of arr) {
|
for (const item of arr) {
|
||||||
@ -352,6 +427,9 @@ limitations under the License. -->
|
|||||||
configuration: c,
|
configuration: c,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
loading.value = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (
|
if (
|
||||||
@ -380,6 +458,9 @@ limitations under the License. -->
|
|||||||
configuration: c,
|
configuration: c,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
loading.value = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -416,6 +497,9 @@ limitations under the License. -->
|
|||||||
configuration: c,
|
configuration: c,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
loading.value = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (d.layer === row.layer && [EntityType[0].value].includes(d.entity) && !row.isDefault && d.isDefault) {
|
if (d.layer === row.layer && [EntityType[0].value].includes(d.entity) && !row.isDefault && d.isDefault) {
|
||||||
@ -439,6 +523,9 @@ limitations under the License. -->
|
|||||||
configuration: c,
|
configuration: c,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
loading.value = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -607,4 +694,8 @@ limitations under the License. -->
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.expressions {
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -366,3 +366,7 @@ export enum CallTypes {
|
|||||||
Server = "SERVER",
|
Server = "SERVER",
|
||||||
Client = "CLIENT",
|
Client = "CLIENT",
|
||||||
}
|
}
|
||||||
|
export enum ConfigFieldTypes {
|
||||||
|
ISDEFAULT = "ISDEFAULT",
|
||||||
|
NAME = "NAME",
|
||||||
|
}
|
||||||
|
@ -94,7 +94,7 @@ limitations under the License. -->
|
|||||||
import type { Node } from "@/types/topology";
|
import type { Node } from "@/types/topology";
|
||||||
import { useTopologyStore } from "@/store/modules/topology";
|
import { useTopologyStore } from "@/store/modules/topology";
|
||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
import { EntityType } from "@/views/dashboard/data";
|
import { EntityType, ConfigFieldTypes } from "@/views/dashboard/data";
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||||
@ -105,6 +105,7 @@ limitations under the License. -->
|
|||||||
import zoom from "@/views/dashboard/related/components/utils/zoom";
|
import zoom from "@/views/dashboard/related/components/utils/zoom";
|
||||||
import HierarchySettings from "../config/HierarchySettings.vue";
|
import HierarchySettings from "../config/HierarchySettings.vue";
|
||||||
import type { HierarchyServicesConfig } from "@/types/dashboard";
|
import type { HierarchyServicesConfig } from "@/types/dashboard";
|
||||||
|
import getDashboard from "@/hooks/useDashboardsSession";
|
||||||
|
|
||||||
/*global Nullable, defineProps */
|
/*global Nullable, defineProps */
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -208,11 +209,16 @@ limitations under the License. -->
|
|||||||
return Number(d[item.legendMQE]) && d.isReal ? icons.CUBEERROR : icons.CUBE;
|
return Number(d[item.legendMQE]) && d.isReal ? icons.CUBEERROR : icons.CUBE;
|
||||||
}
|
}
|
||||||
function showNodeTip(event: MouseEvent, data: Node) {
|
function showNodeTip(event: MouseEvent, data: Node) {
|
||||||
const config: HierarchyServicesConfig =
|
const { dashboard } = getDashboard(
|
||||||
(settings.value.hierarchyServicesConfig || []).find((d: HierarchyServicesConfig) => d.layer === data.layer) || {};
|
{
|
||||||
const exprssions = config.nodeExpressions || [];
|
layer: data.layer || "",
|
||||||
const nodeMetricConfig = config.expressionsConfig || [];
|
entity: EntityType[0].value,
|
||||||
const html = exprssions.map((m, index) => {
|
},
|
||||||
|
ConfigFieldTypes.ISDEFAULT,
|
||||||
|
);
|
||||||
|
const exprssions = dashboard.nodeExpressions || [];
|
||||||
|
const nodeMetricConfig = dashboard.nodeExpressionsConfig || [];
|
||||||
|
const html = exprssions.map((m: string, index: number) => {
|
||||||
const metric =
|
const metric =
|
||||||
topologyStore.hierarchyNodeMetrics[data.layer || ""][m].values.find(
|
topologyStore.hierarchyNodeMetrics[data.layer || ""][m].values.find(
|
||||||
(val: { id: string; value: unknown }) => val.id === data.id,
|
(val: { id: string; value: unknown }) => val.id === data.id,
|
||||||
@ -240,11 +246,15 @@ limitations under the License. -->
|
|||||||
function handleNodeClick(event: MouseEvent, d: Node & { x: number; y: number }) {
|
function handleNodeClick(event: MouseEvent, d: Node & { x: number; y: number }) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
hideTip();
|
hideTip();
|
||||||
topologyStore.setHierarchyServiceNode(d);
|
// topologyStore.setHierarchyServiceNode(d);
|
||||||
handleGoDashboard();
|
const { dashboard } = getDashboard(
|
||||||
}
|
{
|
||||||
function handleGoDashboard() {
|
layer: d.layer || "",
|
||||||
const name = ""; // todo
|
entity: EntityType[0].value,
|
||||||
|
},
|
||||||
|
ConfigFieldTypes.ISDEFAULT,
|
||||||
|
);
|
||||||
|
const name = dashboard.name;
|
||||||
const path = `/dashboard/${dashboardStore.layerId}/${EntityType[0].value}/${topologyStore.node.id}/${name}`;
|
const path = `/dashboard/${dashboardStore.layerId}/${EntityType[0].value}/${topologyStore.node.id}/${name}`;
|
||||||
const routeUrl = router.resolve({ path });
|
const routeUrl = router.resolve({ path });
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user