This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-booster-ui.git
The following commit(s) were added to refs/heads/main by this push:
new dce1035f feat: implement a breadcrumb component as navigation (#313)
dce1035f is described below
commit dce1035f2eabe7a5575040d6a0b9bc20aa72a6c4
Author: Fine0830 <[email protected]>
AuthorDate: Wed Aug 30 19:06:40 2023 +0800
feat: implement a breadcrumb component as navigation (#313)
---
src/layout/components/NavBar.vue | 213 +++++++++++++++++++--
src/store/modules/app.ts | 5 -
src/store/modules/selectors.ts | 22 +--
src/styles/reset.scss | 4 +
src/types/app.d.ts | 2 +
src/types/components.d.ts | 2 +
src/types/profile.d.ts | 4 +-
src/utils/arrayAlgorithm.ts | 31 +++
src/views/Alarm.vue | 4 -
src/views/Event.vue | 5 -
src/views/Layer.vue | 3 -
src/views/Settings.vue | 1 -
src/views/components/ConditionTags.vue | 6 +-
src/views/dashboard/Edit.vue | 9 +-
src/views/dashboard/List.vue | 3 -
src/views/dashboard/New.vue | 3 -
src/views/dashboard/data.ts | 1 +
src/views/dashboard/graphs/InstanceList.vue | 4 +
.../related/network-profiling/components/Tasks.vue | 8 +-
19 files changed, 267 insertions(+), 63 deletions(-)
diff --git a/src/layout/components/NavBar.vue b/src/layout/components/NavBar.vue
index 26a0285e..c2b188dd 100644
--- a/src/layout/components/NavBar.vue
+++ b/src/layout/components/NavBar.vue
@@ -14,7 +14,26 @@ See the License for the specific language governing
permissions and
limitations under the License. -->
<template>
<div class="nav-bar flex-h">
- <div class="title">{{ route.name === "ViewWidget" ? "" :
appStore.pageTitle || pageName }}</div>
+ <el-breadcrumb separator=">" class="title flex-h" v-if="pathNames.length">
+ <el-breadcrumb-item
+ v-for="(path, index) in pathNames"
+ :key="index"
+ :replace="true"
+ :to="{ path: getName(path).path || '' }"
+ >
+ <el-dropdown size="small" placement="bottom" :persistent="false">
+ <span class="cp name">{{ getName(path).name }}</span>
+ <template #dropdown>
+ <el-dropdown-menu>
+ <el-dropdown-item @click="setName(p)" v-for="(p, index) in path"
:key="index">
+ <span>{{ p.name }}</span>
+ </el-dropdown-item>
+ </el-dropdown-menu>
+ </template>
+ </el-dropdown>
+ </el-breadcrumb-item>
+ </el-breadcrumb>
+ <div class="title" v-else>{{ pageTitle }}</div>
<div class="app-config">
<span class="red" v-show="timeRange">{{ t("timeTips") }}</span>
<TimePicker
@@ -45,20 +64,46 @@ limitations under the License. -->
import { useI18n } from "vue-i18n";
import timeFormat from "@/utils/timeFormat";
import { useAppStoreWithOut } from "@/store/modules/app";
+ import { useDashboardStore } from "@/store/modules/dashboard";
import { ElMessage } from "element-plus";
+ import { MetricCatalog } from "@/views/dashboard/data";
+ import type { DashboardItem } from "@/types/dashboard";
+ import router from "@/router";
/*global Indexable */
- const { t } = useI18n();
+ const { t, te } = useI18n();
const appStore = useAppStoreWithOut();
+ const dashboardStore = useDashboardStore();
const route = useRoute();
- const pageName = ref<string>("");
+ const pathNames = ref<{ path?: string; name: string; selected: boolean
}[][]>([]);
const timeRange = ref<number>(0);
+ const pageTitle = ref<string>("");
resetDuration();
getVersion();
- const setConfig = (value: string) => {
- pageName.value = value || "";
- };
+ getNavPaths();
+
+ function getName(list: any[]) {
+ return list.find((d: any) => d.selected) || {};
+ }
+
+ function setName(item: any) {
+ pathNames.value = pathNames.value.map((list: { path?: string; name:
string; selected: boolean }[]) => {
+ const p = list.find((i: any) => i.entity === item.entity && item.layer
=== i.layer && i.name === item.name);
+ if (p) {
+ list = list.map((d: any) => {
+ d.selected = false;
+ if (d.entity === item.entity && item.layer === d.layer && d.name ===
item.name) {
+ d.selected = true;
+ }
+ return d;
+ });
+ }
+
+ return list;
+ });
+ item.path && router.push(item.path);
+ }
function handleReload() {
const gap = appStore.duration.end.getTime() -
appStore.duration.start.getTime();
@@ -73,19 +118,138 @@ limitations under the License. -->
}
appStore.setDuration(timeFormat(val));
}
- setConfig(String(route.meta.title));
- watch(
- () => route.meta.title,
- (title: unknown) => {
- setConfig(String(title));
- },
- );
+
+ function getNavPaths() {
+ pathNames.value = [];
+ pageTitle.value = "";
+ const dashboard = dashboardStore.currentDashboard;
+
+ if (!(dashboard && dashboard.name)) {
+ updateNavTitle();
+ return;
+ }
+ const root =
+ dashboardStore.dashboards.filter((d: DashboardItem) => d.isRoot &&
dashboard.layer === d.layer)[0] || {};
+ for (const item of appStore.allMenus) {
+ if (item.subItems && item.subItems.length) {
+ for (const subItem of item.subItems) {
+ if (subItem.layer === root.layer) {
+ root.path = subItem.path;
+ }
+ }
+ } else {
+ if (item.layer === root.layer) {
+ root.path = item.path;
+ }
+ }
+ }
+ pathNames.value.push([{ ...root, selected: true }]);
+ if (dashboard.entity === MetricCatalog.ALL) {
+ return;
+ }
+ if (dashboard.entity === MetricCatalog.SERVICE) {
+ pathNames.value.push([
+ {
+ name: dashboard.name,
+ selected: true,
+ },
+ ]);
+ return;
+ }
+ const serviceDashboards = dashboardStore.dashboards.filter(
+ (d: DashboardItem) => MetricCatalog.SERVICE === d.entity &&
dashboard.layer === d.layer,
+ );
+ if (!serviceDashboards.length) {
+ return;
+ }
+
+ const serviceId = route.params.serviceId;
+ const list = serviceDashboards.map((d: { path: string } & DashboardItem,
index: number) => {
+ let path = `/dashboard/${d.layer}/${d.entity}/${d.name}`;
+ if (serviceId) {
+ path = `/dashboard/${d.layer}/${d.entity}/${serviceId}/${d.name}`;
+ }
+ const selected = index === 0;
+ return {
+ ...d,
+ path,
+ selected,
+ };
+ });
+ pathNames.value.push(list);
+ const podId = route.params.podId;
+ if (dashboard.entity === MetricCatalog.ENDPOINT_RELATION) {
+ const endpointDashboards = dashboardStore.dashboards.filter(
+ (d: DashboardItem) => MetricCatalog.ENDPOINT === d.entity &&
dashboard.layer === d.layer,
+ );
+ const list = endpointDashboards.map((d: { path: string } &
DashboardItem, index: number) => {
+ let path = `/dashboard/${d.layer}/${d.entity}/${d.name}`;
+ if (podId) {
+ path =
`/dashboard/${d.layer}/${d.entity}/${serviceId}/${podId}/${d.name}`;
+ }
+ const selected = index === 0;
+ return {
+ ...d,
+ path,
+ selected,
+ };
+ });
+
+ pathNames.value.push(list);
+ }
+ const destServiceId = route.params.destServiceId;
+ if (dashboard.entity === MetricCatalog.SERVICE_INSTANCE_RELATION) {
+ const serviceRelationDashboards = dashboardStore.dashboards.filter(
+ (d: DashboardItem) => MetricCatalog.SERVICE_RELATION === d.entity &&
dashboard.layer === d.layer,
+ );
+ const list = serviceRelationDashboards.map((d: { path: string } &
DashboardItem, index: number) => {
+ let path =
`/dashboard/related/${d.layer}/${d.entity}/${serviceId}/${destServiceId}/${d.name}`;
+ if (destServiceId) {
+ path =
`/dashboard/related/${d.layer}/${d.entity}/${serviceId}/${destServiceId}/${d.name}`;
+ }
+ const selected = index === 0;
+ return {
+ ...d,
+ path,
+ selected,
+ };
+ });
+ pathNames.value.push(list);
+ }
+ if ([MetricCatalog.Process,
MetricCatalog.PROCESS_RELATION].includes(dashboard.entity)) {
+ const InstanceDashboards = dashboardStore.dashboards.filter(
+ (d: DashboardItem) => MetricCatalog.SERVICE_INSTANCE === d.entity &&
dashboard.layer === d.layer,
+ );
+ const list = InstanceDashboards.map((d: { path: string } &
DashboardItem, index: number) => {
+ let path = `/dashboard/${d.layer}/${d.entity}/${d.name}`;
+ if (podId) {
+ path =
`/dashboard/${d.layer}/${d.entity}/${serviceId}/${podId}/${d.name}`;
+ }
+ const selected = index === 0;
+ return {
+ ...d,
+ path,
+ selected,
+ };
+ });
+
+ pathNames.value.push(list);
+ }
+ pathNames.value.push([
+ {
+ name: dashboard.name,
+ selected: true,
+ },
+ ]);
+ }
+
async function getVersion() {
const res = await appStore.fetchVersion();
if (res.errors) {
ElMessage.error(res.errors);
}
}
+
function resetDuration() {
const { duration }: Indexable = route.params;
if (duration) {
@@ -99,10 +263,22 @@ limitations under the License. -->
appStore.updateUTC(d.utc);
}
}
+
+ function updateNavTitle() {
+ const key = String(route.meta.i18nKey);
+ pageTitle.value = te(key) ? t(key) : String(route.meta.title);
+ }
+
+ watch(
+ () => [dashboardStore.currentDashboard, route.name],
+ () => {
+ getNavPaths();
+ },
+ );
</script>
<style lang="scss" scoped>
.nav-bar {
- padding: 5px 10px;
+ padding: 5px;
text-align: left;
justify-content: space-between;
background-color: #fafbfc;
@@ -121,10 +297,17 @@ limitations under the License. -->
font-size: $font-size-normal;
font-weight: 500;
height: 28px;
- line-height: 28px;
}
.nav-tabs {
padding: 10px;
}
+
+ .name {
+ display: inline-block;
+ max-width: 250px;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+ }
</style>
diff --git a/src/store/modules/app.ts b/src/store/modules/app.ts
index ede73ea5..994e83a5 100644
--- a/src/store/modules/app.ts
+++ b/src/store/modules/app.ts
@@ -32,7 +32,6 @@ interface AppState {
eventStack: (() => unknown)[];
timer: Nullable<TimeoutHandle>;
autoRefresh: boolean;
- pageTitle: string;
version: string;
isMobile: boolean;
reloadTimer: Nullable<IntervalHandle>;
@@ -53,7 +52,6 @@ export const appStore = defineStore({
eventStack: [],
timer: null,
autoRefresh: false,
- pageTitle: "",
version: "",
isMobile: false,
reloadTimer: null,
@@ -146,9 +144,6 @@ export const appStore = defineStore({
setAutoRefresh(auto: boolean) {
this.autoRefresh = auto;
},
- setPageTitle(title: string) {
- this.pageTitle = title;
- },
runEventStack() {
if (this.timer) {
clearTimeout(this.timer);
diff --git a/src/store/modules/selectors.ts b/src/store/modules/selectors.ts
index 74d62399..4101b850 100644
--- a/src/store/modules/selectors.ts
+++ b/src/store/modules/selectors.ts
@@ -184,7 +184,7 @@ export const selectorStore = defineStore({
if (isRelation) {
this.currentDestPod = res.data.data.instance || null;
this.destPods = [res.data.data.instance];
- return;
+ return res.data;
}
this.currentPod = res.data.data.instance || null;
this.pods = [res.data.data.instance];
@@ -199,16 +199,16 @@ export const selectorStore = defineStore({
const res: AxiosResponse = await graphql.query("queryEndpoint").params({
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];
+ if (res.data.errors) {
+ return res.data;
}
-
+ if (isRelation) {
+ this.currentDestPod = res.data.data.endpoint || null;
+ this.destPods = [res.data.data.endpoint];
+ return res.data;
+ }
+ this.currentPod = res.data.data.endpoint || null;
+ this.pods = [res.data.data.endpoint];
return res.data;
},
async getProcess(processId: string, isRelation?: boolean) {
@@ -222,7 +222,7 @@ export const selectorStore = defineStore({
if (isRelation) {
this.currentDestProcess = res.data.data.process || null;
this.destProcesses = [res.data.data.process];
- return;
+ return res.data;
}
this.currentProcess = res.data.data.process || null;
this.processes = [res.data.data.process];
diff --git a/src/styles/reset.scss b/src/styles/reset.scss
index c447ec45..84eb228b 100644
--- a/src/styles/reset.scss
+++ b/src/styles/reset.scss
@@ -212,6 +212,10 @@ div.vis-tooltip {
div:has(> a.menu-title) {
display: none;
}
+
+.el-breadcrumb {
+ line-height: 28px;
+}
.el-input-number .el-input__inner {
text-align: left !important;
}
diff --git a/src/types/app.d.ts b/src/types/app.d.ts
index c759cfef..e697ae07 100644
--- a/src/types/app.d.ts
+++ b/src/types/app.d.ts
@@ -44,6 +44,8 @@ export type EventParams = {
dataType: string;
value: number | any[];
color: string;
+ event: Record<string, T>;
+ dataIndex: number;
event: any;
};
diff --git a/src/types/components.d.ts b/src/types/components.d.ts
index 7e641d1c..9f9c7086 100644
--- a/src/types/components.d.ts
+++ b/src/types/components.d.ts
@@ -6,6 +6,8 @@ import '@vue/runtime-core'
declare module '@vue/runtime-core' {
export interface GlobalComponents {
DateCalendar: typeof import('./../components/DateCalendar.vue')['default']
+ ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
+ ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
ElButton: typeof import('element-plus/es')['ElButton']
ElCard: typeof import('element-plus/es')['ElCard']
ElCollapse: typeof import('element-plus/es')['ElCollapse']
diff --git a/src/types/profile.d.ts b/src/types/profile.d.ts
index c9d64746..ac7fb79f 100644
--- a/src/types/profile.d.ts
+++ b/src/types/profile.d.ts
@@ -55,8 +55,8 @@ export interface SegmentSpan {
component: string;
isError: boolean;
layer: string;
- tags: any[];
- logs: any[];
+ tags: Recordable[];
+ logs: Recordable[];
}
export interface ProfileTaskCreationRequest {
diff --git a/src/utils/arrayAlgorithm.ts b/src/utils/arrayAlgorithm.ts
new file mode 100644
index 00000000..3baab512
--- /dev/null
+++ b/src/utils/arrayAlgorithm.ts
@@ -0,0 +1,31 @@
+/**
+ * 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.
+ */
+
+export function deduplication(arr: any, labels: string[]) {
+ const map = new Map();
+ for (const i of arr) {
+ const key = labels
+ .map((d: string) => {
+ return i[d];
+ })
+ .join("");
+ if (!map.has(i[key])) {
+ map.set(i[key], i);
+ }
+ }
+ return [...map.values()];
+}
diff --git a/src/views/Alarm.vue b/src/views/Alarm.vue
index 236e7e18..e541a8ed 100644
--- a/src/views/Alarm.vue
+++ b/src/views/Alarm.vue
@@ -19,12 +19,8 @@ limitations under the License. -->
</div>
</template>
<script lang="ts" setup>
- import { useAppStoreWithOut } from "@/store/modules/app";
import Header from "./alarm/Header.vue";
import Content from "./alarm/Content.vue";
-
- const appStore = useAppStoreWithOut();
- appStore.setPageTitle("Alerting");
</script>
<style lang="scss" scoped>
.alarm {
diff --git a/src/views/Event.vue b/src/views/Event.vue
index 5fcd39df..fade863e 100644
--- a/src/views/Event.vue
+++ b/src/views/Event.vue
@@ -19,13 +19,8 @@ limitations under the License. -->
</div>
</template>
<script lang="ts" setup>
- import { useAppStoreWithOut } from "@/store/modules/app";
import Header from "./event/Header.vue";
import Content from "./event/Content.vue";
-
- const appStore = useAppStoreWithOut();
-
- appStore.setPageTitle("Events");
</script>
<style lang="scss" scoped>
.event {
diff --git a/src/views/Layer.vue b/src/views/Layer.vue
index a8260375..3f342343 100644
--- a/src/views/Layer.vue
+++ b/src/views/Layer.vue
@@ -24,11 +24,9 @@ limitations under the License. -->
import { useDashboardStore } from "@/store/modules/dashboard";
import Dashboard from "./dashboard/Edit.vue";
import { useI18n } from "vue-i18n";
- import { useAppStoreWithOut } from "@/store/modules/app";
const route = useRoute();
const { t } = useI18n();
- const appStore = useAppStoreWithOut();
const dashboardStore = useDashboardStore();
const layer = ref<string>("GENERAL");
@@ -44,7 +42,6 @@ limitations under the License. -->
d.layer === dashboardStore.layerId && [EntityType[0].value,
EntityType[1].value].includes(d.entity) && d.isRoot,
);
if (!item) {
- appStore.setPageTitle(dashboardStore.layer);
dashboardStore.setCurrentDashboard(null);
dashboardStore.setEntity(EntityType[1].value);
return;
diff --git a/src/views/Settings.vue b/src/views/Settings.vue
index 00beb5e1..86d71a5f 100644
--- a/src/views/Settings.vue
+++ b/src/views/Settings.vue
@@ -66,7 +66,6 @@ limitations under the License. -->
const utcHour = ref<number>(appStore.utcHour);
const utcMin = ref<number>(appStore.utcMin);
- appStore.setPageTitle("Setting");
const handleReload = () => {
const gap = appStore.duration.end.getTime() -
appStore.duration.start.getTime();
const dates: Date[] = [
diff --git a/src/views/components/ConditionTags.vue
b/src/views/components/ConditionTags.vue
index f62629c2..9d33d104 100644
--- a/src/views/components/ConditionTags.vue
+++ b/src/views/components/ConditionTags.vue
@@ -71,7 +71,7 @@ limitations under the License. -->
import { ElMessage } from "element-plus";
import { useAppStoreWithOut } from "@/store/modules/app";
- /*global defineEmits, defineProps */
+ /*global defineEmits, defineProps, Recordable */
const emit = defineEmits(["update"]);
const props = defineProps({
type: { type: String, default: "TRACE" },
@@ -118,7 +118,7 @@ limitations under the License. -->
emit("update", { tagsMap, tagsList: tagsList.value });
}
async function fetchTagKeys() {
- let resp: any = {};
+ let resp: Recordable = {};
if (props.type === "TRACE") {
resp = await traceStore.getTagKeys();
} else {
@@ -137,7 +137,7 @@ limitations under the License. -->
async function fetchTagValues() {
const param = tags.value.split("=")[0];
- let resp: any = {};
+ let resp: Recordable = {};
if (props.type === "TRACE") {
resp = await traceStore.getTagValues(param);
} else {
diff --git a/src/views/dashboard/Edit.vue b/src/views/dashboard/Edit.vue
index 88cf5c8f..3d6d523a 100644
--- a/src/views/dashboard/Edit.vue
+++ b/src/views/dashboard/Edit.vue
@@ -41,13 +41,12 @@ limitations under the License. -->
</div>
</template>
<script lang="ts">
- import { ref, defineComponent } from "vue";
+ import { ref, defineComponent, onUnmounted } from "vue";
import { useI18n } from "vue-i18n";
import { useRoute } from "vue-router";
import GridLayout from "./panel/Layout.vue";
import Tool from "./panel/Tool.vue";
import { useDashboardStore } from "@/store/modules/dashboard";
- import { useAppStoreWithOut } from "@/store/modules/app";
import Configuration from "./configuration";
import type { LayoutConfig } from "@/types/dashboard";
import WidgetLink from "./components/WidgetLink.vue";
@@ -57,7 +56,6 @@ limitations under the License. -->
components: { ...Configuration, GridLayout, Tool, WidgetLink },
setup() {
const dashboardStore = useDashboardStore();
- const appStore = useAppStoreWithOut();
const { t } = useI18n();
const p = useRoute().params;
const layoutKey = ref<string>(`${p.layerId}_${p.entity}_${p.name}`);
@@ -77,7 +75,6 @@ limitations under the License. -->
const layout: any = c.configuration || {};
dashboardStore.setLayout(setWidgetsID(layout.children || []));
- appStore.setPageTitle(layout.name);
if (p.entity) {
dashboardStore.setCurrentDashboard({
layer: p.layerId,
@@ -114,6 +111,10 @@ limitations under the License. -->
}
}
+ onUnmounted(() => {
+ dashboardStore.setCurrentDashboard({});
+ });
+
return {
t,
handleClick,
diff --git a/src/views/dashboard/List.vue b/src/views/dashboard/List.vue
index 89f9eac0..89cfface 100644
--- a/src/views/dashboard/List.vue
+++ b/src/views/dashboard/List.vue
@@ -135,7 +135,6 @@ limitations under the License. -->
import { useI18n } from "vue-i18n";
import { ElMessageBox, ElMessage } from "element-plus";
import { ElTable } from "element-plus";
- import { useAppStoreWithOut } from "@/store/modules/app";
import { useDashboardStore } from "@/store/modules/dashboard";
import router from "@/router";
import type { DashboardItem, LayoutConfig } from "@/types/dashboard";
@@ -145,7 +144,6 @@ limitations under the License. -->
/*global Nullable*/
const { t } = useI18n();
- const appStore = useAppStoreWithOut();
const dashboardStore = useDashboardStore();
const pageSize = 20;
const dashboards = ref<DashboardItem[]>([]);
@@ -157,7 +155,6 @@ limitations under the License. -->
const multipleSelection = ref<DashboardItem[]>([]);
const dashboardFile = ref<Nullable<HTMLDivElement>>(null);
- appStore.setPageTitle("Dashboard List");
const handleSelectionChange = (val: DashboardItem[]) => {
multipleSelection.value = val;
};
diff --git a/src/views/dashboard/New.vue b/src/views/dashboard/New.vue
index 842232bf..d25f70fb 100644
--- a/src/views/dashboard/New.vue
+++ b/src/views/dashboard/New.vue
@@ -53,12 +53,9 @@ limitations under the License. -->
import { useSelectorStore } from "@/store/modules/selectors";
import { EntityType } from "./data";
import { ElMessage } from "element-plus";
- import { useAppStoreWithOut } from "@/store/modules/app";
import { useDashboardStore } from "@/store/modules/dashboard";
- const appStore = useAppStoreWithOut();
const dashboardStore = useDashboardStore();
- appStore.setPageTitle("Dashboard New");
const { t } = useI18n();
const selectorStore = useSelectorStore();
const states = reactive({
diff --git a/src/views/dashboard/data.ts b/src/views/dashboard/data.ts
index 28c0affb..f30b5c15 100644
--- a/src/views/dashboard/data.ts
+++ b/src/views/dashboard/data.ts
@@ -161,6 +161,7 @@ export enum MetricCatalog {
SERVICE_RELATION = "ServiceRelation",
SERVICE_INSTANCE_RELATION = "ServiceInstanceRelation",
ENDPOINT_RELATION = "EndpointRelation",
+ Process = "Process",
PROCESS_RELATION = "ProcessRelation",
}
export const EntityType = [
diff --git a/src/views/dashboard/graphs/InstanceList.vue
b/src/views/dashboard/graphs/InstanceList.vue
index d04d47ff..2e3b68cc 100644
--- a/src/views/dashboard/graphs/InstanceList.vue
+++ b/src/views/dashboard/graphs/InstanceList.vue
@@ -294,4 +294,8 @@ limitations under the License. -->
max-height: 400px;
overflow: auto;
}
+
+ .link {
+ color: $active-color;
+ }
</style>
diff --git a/src/views/dashboard/related/network-profiling/components/Tasks.vue
b/src/views/dashboard/related/network-profiling/components/Tasks.vue
index 598350cc..a873a636 100644
--- a/src/views/dashboard/related/network-profiling/components/Tasks.vue
+++ b/src/views/dashboard/related/network-profiling/components/Tasks.vue
@@ -216,7 +216,7 @@ limitations under the License. -->
width: 330px;
height: calc(100% - 10px);
overflow: auto;
- border-right: 1px solid rgba(0, 0, 0, 0.1);
+ border-right: 1px solid rgb(0 0 0 / 10%);
}
.item span {
@@ -225,7 +225,7 @@ limitations under the License. -->
.profile-td {
padding: 10px 5px 10px 10px;
- border-bottom: 1px solid rgba(0, 0, 0, 0.07);
+ border-bottom: 1px solid rgb(0 0 0 / 7%);
&.selected {
background-color: #ededed;
@@ -253,13 +253,13 @@ limitations under the License. -->
.profile-tr {
&:hover {
- background-color: rgba(0, 0, 0, 0.04);
+ background-color: rgb(0 0 0 / 4%);
}
}
.profile-t-tool {
padding: 10px 5px 10px 10px;
- border-bottom: 1px solid rgba(0, 0, 0, 0.07);
+ border-bottom: 1px solid rgb(0 0 0 / 7%);
background: #f3f4f9;
width: 100%;
}