You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2022/03/25 07:51:09 UTC
[skywalking-booster-ui] branch main updated: feat: Implement Text control and update Topology (#37)
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 99e23c3 feat: Implement Text control and update Topology (#37)
99e23c3 is described below
commit 99e23c33dc55add382b02233b5fea725f33d74d6
Author: Fine0830 <fi...@outlook.com>
AuthorDate: Fri Mar 25 15:51:06 2022 +0800
feat: Implement Text control and update Topology (#37)
---
src/locales/lang/en.ts | 1 +
src/locales/lang/zh.ts | 1 +
src/store/data.ts | 9 +-
src/store/modules/dashboard.ts | 17 ++-
src/types/dashboard.ts | 8 ++
src/views/Layer.vue | 5 +-
src/views/dashboard/Edit.vue | 96 +++++++------
src/views/dashboard/configuration/Text.vue | 149 +++++++++++++++++++++
src/views/dashboard/configuration/Widget.vue | 1 -
.../dashboard/{controls => configuration}/index.ts | 14 +-
src/views/dashboard/controls/Tab.vue | 4 +-
src/views/dashboard/controls/Text.vue | 129 ++++++++++++++++++
src/views/dashboard/controls/index.ts | 3 +-
src/views/dashboard/data.ts | 18 ++-
src/views/dashboard/panel/Layout.vue | 3 +
src/views/dashboard/panel/Tool.vue | 6 +
.../related/topology/components/Graph.vue | 14 +-
.../related/topology/components/PodTopology.vue | 5 +-
.../related/topology/components/Settings.vue | 21 ++-
.../dashboard/related/trace/utils/d3-trace-list.ts | 12 +-
20 files changed, 436 insertions(+), 80 deletions(-)
diff --git a/src/locales/lang/en.ts b/src/locales/lang/en.ts
index 08cf4bb..c11b198 100644
--- a/src/locales/lang/en.ts
+++ b/src/locales/lang/en.ts
@@ -125,6 +125,7 @@ const msg = {
kubernetesService: "Service",
kubernetesCluster: "Cluster",
kubernetes: "Kubernetes",
+ textUrl: "Text Hyperlink",
hourTip: "Select Hour",
minuteTip: "Select Minute",
secondTip: "Select Second",
diff --git a/src/locales/lang/zh.ts b/src/locales/lang/zh.ts
index 3b01a71..6c1d334 100644
--- a/src/locales/lang/zh.ts
+++ b/src/locales/lang/zh.ts
@@ -125,6 +125,7 @@ const msg = {
kubernetesService: "服务",
kubernetesCluster: "集群",
kubernetes: "Kubernetes",
+ textUrl: "文本超链接",
hourTip: "选择小时",
minuteTip: "选择分钟",
secondTip: "选择秒数",
diff --git a/src/store/data.ts b/src/store/data.ts
index 50dbbd2..6fdfdd9 100644
--- a/src/store/data.ts
+++ b/src/store/data.ts
@@ -22,10 +22,17 @@ export const NewControl = {
i: "0",
type: "Widget",
widget: {
- title: "Title",
+ title: "",
},
graph: {},
standard: {},
metrics: [""],
metricTypes: [""],
};
+export const TextConfig = {
+ fontColor: "white",
+ backgroundColor: "green",
+ content: "Text",
+ fontSize: 14,
+ textAlign: "left",
+};
diff --git a/src/store/modules/dashboard.ts b/src/store/modules/dashboard.ts
index 2536a4c..410df5d 100644
--- a/src/store/modules/dashboard.ts
+++ b/src/store/modules/dashboard.ts
@@ -22,7 +22,7 @@ import query from "@/graphql/fetch";
import { DashboardItem } from "@/types/dashboard";
import { useAppStoreWithOut } from "@/store/modules/app";
import { useSelectorStore } from "@/store/modules/selectors";
-import { NewControl } from "../data";
+import { NewControl, TextConfig } from "../data";
import { Duration } from "@/types/app";
import { AxiosResponse } from "axios";
import { ElMessage } from "element-plus";
@@ -112,6 +112,10 @@ export const dashboardStore = defineStore({
if (type === "Trace" || type === "Profile" || type === "Log") {
newItem.h = 36;
}
+ if (type === "Text") {
+ newItem.h = 6;
+ newItem.graph = TextConfig;
+ }
this.activedGridItem = newItem.i;
this.selectedGrid = newItem;
this.layout = this.layout.map((d: LayoutConfig) => {
@@ -158,6 +162,10 @@ export const dashboardStore = defineStore({
if (type === "Trace" || type === "Profile" || type === "Log") {
newItem.h = 32;
}
+ if (type === "Text") {
+ newItem.h = 6;
+ newItem.graph = TextConfig;
+ }
if (this.layout[idx].children) {
const items = children.map((d: LayoutConfig) => {
d.y = d.y + newItem.h;
@@ -171,10 +179,9 @@ export const dashboardStore = defineStore({
activeGridItem(index: string) {
this.activedGridItem = index;
},
- setActiveTabIndex(index: number) {
- const idx = this.layout.findIndex(
- (d: LayoutConfig) => d.i === this.activedGridItem
- );
+ setActiveTabIndex(index: number, target?: number) {
+ const m = target || this.activedGridItem;
+ const idx = this.layout.findIndex((d: LayoutConfig) => d.i === m);
if (idx < 0) {
return;
}
diff --git a/src/types/dashboard.ts b/src/types/dashboard.ts
index bae7588..62d12b9 100644
--- a/src/types/dashboard.ts
+++ b/src/types/dashboard.ts
@@ -91,6 +91,14 @@ export interface CardConfig {
textAlign?: "center" | "right" | "left";
}
+export interface TextConfig {
+ fontSize: number;
+ backgroundColor: string;
+ textAlign: string;
+ fontColor: string;
+ content: string;
+}
+
export interface TableConfig {
type?: string;
showTableValues: boolean;
diff --git a/src/views/Layer.vue b/src/views/Layer.vue
index 71dbb62..d18a018 100644
--- a/src/views/Layer.vue
+++ b/src/views/Layer.vue
@@ -13,7 +13,7 @@ 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. -->
<template>
- <Edit v-if="dashboardStore.currentDashboard" />
+ <Dashboard v-if="dashboardStore.currentDashboard" />
<div v-else class="no-root">
{{ t("noRoot") }} {{ dashboardStore.layerId }}
</div>
@@ -24,7 +24,7 @@ import { ref } from "vue";
import { useRoute } from "vue-router";
import { EntityType } from "./dashboard/data";
import { useDashboardStore } from "@/store/modules/dashboard";
-import Edit from "./dashboard/Edit.vue";
+import Dashboard from "./dashboard/Edit.vue";
import { useI18n } from "vue-i18n";
import { useAppStoreWithOut } from "@/store/modules/app";
@@ -52,7 +52,6 @@ getDashboard();
async function getDashboard() {
layer.value = routesMap[String(route.name)];
- console.log(layer.value);
dashboardStore.setLayer(layer.value);
dashboardStore.setEntity(EntityType[1].value);
dashboardStore.setMode(false);
diff --git a/src/views/dashboard/Edit.vue b/src/views/dashboard/Edit.vue
index 595a089..ad4b8c9 100644
--- a/src/views/dashboard/Edit.vue
+++ b/src/views/dashboard/Edit.vue
@@ -28,63 +28,71 @@ limitations under the License. -->
:destroy-on-close="true"
@closed="dashboardStore.setConfigPanel(false)"
>
- <TopologyConfig v-if="dashboardStore.selectedGrid.type === 'Topology'" />
- <WidgetConfig v-else />
+ <component :is="dashboardStore.selectedGrid.type" />
</el-dialog>
</div>
</template>
-<script lang="ts" setup>
-import { ref } from "vue";
+<script lang="ts">
+import { ref, defineComponent } 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 TopologyConfig from "./configuration/Topology.vue";
-import WidgetConfig from "./configuration/Widget.vue";
import { useDashboardStore } from "@/store/modules/dashboard";
import { useAppStoreWithOut } from "@/store/modules/app";
+import Configuration from "./configuration";
-const dashboardStore = useDashboardStore();
-const appStore = useAppStoreWithOut();
-const { t } = useI18n();
-const p = useRoute().params;
-const layoutKey = ref<string>(`${p.layerId}_${p.entity}_${p.name}`);
+export default defineComponent({
+ name: "Dashboard",
+ components: { ...Configuration, GridLayout, Tool },
+ setup() {
+ const dashboardStore = useDashboardStore();
+ const appStore = useAppStoreWithOut();
+ const { t } = useI18n();
+ const p = useRoute().params;
+ const layoutKey = ref<string>(`${p.layerId}_${p.entity}_${p.name}`);
+ setTemplate();
+ async function setTemplate() {
+ await dashboardStore.setDashboards();
-setTemplate();
-async function setTemplate() {
- await dashboardStore.setDashboards();
-
- if (!p.entity) {
- if (!dashboardStore.currentDashboard) {
- return;
+ if (!p.entity) {
+ if (!dashboardStore.currentDashboard) {
+ return;
+ }
+ const { layer, entity, name } = dashboardStore.currentDashboard;
+ layoutKey.value = `${layer}_${entity}_${name}`;
+ }
+ const c: { configuration: string; id: string } = JSON.parse(
+ sessionStorage.getItem(layoutKey.value) || "{}"
+ );
+ const layout: any = c.configuration || {};
+ dashboardStore.setLayout(layout.children || []);
+ appStore.setPageTitle(layout.name);
+ if (p.entity) {
+ dashboardStore.setCurrentDashboard({
+ layer: p.layerId,
+ entity: p.entity,
+ name: p.name,
+ id: c.id,
+ isRoot: layout.isRoot,
+ });
+ }
+ }
+ function handleClick(e: any) {
+ e.stopPropagation();
+ if (e.target.className === "ds-main") {
+ dashboardStore.activeGridItem("");
+ dashboardStore.selectWidget(null);
+ }
}
- const { layer, entity, name } = dashboardStore.currentDashboard;
- layoutKey.value = `${layer}_${entity}_${name}`;
- }
- const c: { configuration: string; id: string } = JSON.parse(
- sessionStorage.getItem(layoutKey.value) || "{}"
- );
- const layout: any = c.configuration || {};
- dashboardStore.setLayout(layout.children || []);
- appStore.setPageTitle(layout.name);
- if (p.entity) {
- dashboardStore.setCurrentDashboard({
- layer: p.layerId,
- entity: p.entity,
- name: p.name,
- id: c.id,
- isRoot: layout.isRoot,
- });
- }
-}
-function handleClick(e: any) {
- e.stopPropagation();
- if (e.target.className === "ds-main") {
- dashboardStore.activeGridItem("");
- dashboardStore.selectWidget(null);
- }
-}
+ return {
+ t,
+ handleClick,
+ dashboardStore,
+ };
+ },
+});
</script>
<style lang="scss" scoped>
.ds-main {
diff --git a/src/views/dashboard/configuration/Text.vue b/src/views/dashboard/configuration/Text.vue
new file mode 100644
index 0000000..268be91
--- /dev/null
+++ b/src/views/dashboard/configuration/Text.vue
@@ -0,0 +1,149 @@
+<!-- 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. -->
+<template>
+ <div class="item">
+ <span class="label">{{ t("textUrl") }}</span>
+ <el-input
+ class="input"
+ v-model="url"
+ size="small"
+ @change="changeConfig({ url })"
+ />
+ </div>
+ <div class="item">
+ <span class="label">{{ t("content") }}</span>
+ <el-input
+ class="input"
+ v-model="content"
+ size="small"
+ @change="changeConfig({ content })"
+ />
+ </div>
+ <div class="item">
+ <span class="label">{{ t("backgroundColors") }}</span>
+ <Selector
+ :value="backgroundColor"
+ :options="Colors"
+ size="small"
+ placeholder="Select a color"
+ class="input"
+ @change="changeConfig({ backgroundColor: $event[0].value })"
+ />
+ </div>
+ <div class="item">
+ <span class="label">{{ t("fontSize") }}</span>
+ <el-slider
+ class="slider"
+ v-model="fontSize"
+ show-input
+ input-size="small"
+ :min="12"
+ :max="30"
+ :step="1"
+ @change="changeConfig({ fontSize })"
+ />
+ </div>
+ <div class="item">
+ <span class="label">{{ t("fontColors") }}</span>
+ <Selector
+ :value="fontColor"
+ :options="Colors"
+ size="small"
+ placeholder="Select a color"
+ class="input"
+ @change="changeConfig({ fontColor: $event[0].value })"
+ />
+ </div>
+ <div class="footer">
+ <el-button size="small" @click="cancelConfig">
+ {{ t("cancel") }}
+ </el-button>
+ <el-button size="small" type="primary" @click="applyConfig">
+ {{ t("apply") }}
+ </el-button>
+ </div>
+</template>
+<script lang="ts" setup>
+import { useI18n } from "vue-i18n";
+import { ref } from "vue";
+import { useDashboardStore } from "@/store/modules/dashboard";
+const { t } = useI18n();
+const dashboardStore = useDashboardStore();
+const originConfig = dashboardStore.selectedGrid;
+const url = ref(originConfig.graph.url || "");
+const backgroundColor = ref(originConfig.graph.backgroundColor || "green");
+const fontColor = ref(originConfig.graph.fontColor || "white");
+const content = ref<string>(originConfig.graph.content || "");
+const fontSize = ref<number>(originConfig.graph.fontSize || 12);
+const Colors = [
+ {
+ label: "Green",
+ value: "green",
+ },
+ { label: "Blue", value: "blue" },
+ { label: "Red", value: "red" },
+ { label: "Grey", value: "grey" },
+ { label: "White", value: "white" },
+ { label: "Black", value: "black" },
+ { label: "Orange", value: "orange" },
+];
+function changeConfig(param: { [key: string]: unknown }) {
+ const { selectedGrid } = dashboardStore;
+ const graph = {
+ ...selectedGrid.graph,
+ ...param,
+ };
+ dashboardStore.selectWidget({ ...selectedGrid, graph });
+}
+function applyConfig() {
+ dashboardStore.setConfigPanel(false);
+ dashboardStore.setConfigs(dashboardStore.selectedGrid);
+}
+
+function cancelConfig() {
+ dashboardStore.selectWidget(originConfig);
+ dashboardStore.setConfigPanel(false);
+}
+</script>
+<style lang="scss" scoped>
+.slider {
+ width: 500px;
+ margin-top: -3px;
+}
+
+.label {
+ font-size: 13px;
+ font-weight: 500;
+ display: block;
+ margin-bottom: 5px;
+}
+
+.input {
+ width: 500px;
+}
+
+.item {
+ margin-bottom: 10px;
+}
+
+.footer {
+ position: fixed;
+ bottom: 0;
+ right: 0;
+ border-top: 1px solid #eee;
+ padding: 10px;
+ text-align: right;
+ width: 100%;
+ background-color: #fff;
+}
+</style>
diff --git a/src/views/dashboard/configuration/Widget.vue b/src/views/dashboard/configuration/Widget.vue
index 57c1184..442e859 100644
--- a/src/views/dashboard/configuration/Widget.vue
+++ b/src/views/dashboard/configuration/Widget.vue
@@ -90,7 +90,6 @@ import configs from "./widget/graph-styles";
import WidgetOptions from "./widget/WidgetOptions.vue";
import StandardOptions from "./widget/StandardOptions.vue";
import MetricOptions from "./widget/MetricOptions.vue";
-import { ListChartTypes } from "../data";
export default defineComponent({
name: "ConfigEdit",
diff --git a/src/views/dashboard/controls/index.ts b/src/views/dashboard/configuration/index.ts
similarity index 82%
copy from src/views/dashboard/controls/index.ts
copy to src/views/dashboard/configuration/index.ts
index 7fdcd85..a1359ee 100644
--- a/src/views/dashboard/controls/index.ts
+++ b/src/views/dashboard/configuration/index.ts
@@ -14,11 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import Topology from "./Topology.vue";
-import Tab from "./Tab.vue";
+
+import Text from "./Text.vue";
import Widget from "./Widget.vue";
-import Trace from "./Trace.vue";
-import Profile from "./Profile.vue";
-import Log from "./Log.vue";
+import Topology from "./Topology.vue";
-export default { Tab, Widget, Trace, Topology, Profile, Log };
+export default {
+ Text,
+ Widget,
+ Topology,
+};
diff --git a/src/views/dashboard/controls/Tab.vue b/src/views/dashboard/controls/Tab.vue
index 2582f3b..26d1163 100644
--- a/src/views/dashboard/controls/Tab.vue
+++ b/src/views/dashboard/controls/Tab.vue
@@ -121,6 +121,7 @@ import Widget from "./Widget.vue";
import Trace from "./Trace.vue";
import Profile from "./Profile.vue";
import Log from "./Log.vue";
+import Text from "./Text.vue";
const props = {
data: {
@@ -131,7 +132,7 @@ const props = {
};
export default defineComponent({
name: "Tab",
- components: { Topology, Widget, Trace, Profile, Log },
+ components: { Topology, Widget, Trace, Profile, Log, Text },
props,
setup(props) {
const { t } = useI18n();
@@ -149,6 +150,7 @@ export default defineComponent({
dashboardStore.setCurrentTabItems(
dashboardStore.layout[l].children[activeTabIndex.value].children
);
+ dashboardStore.setActiveTabIndex(activeTabIndex.value, props.data.i);
}
function clickTabs(e: Event, idx: number) {
diff --git a/src/views/dashboard/controls/Text.vue b/src/views/dashboard/controls/Text.vue
new file mode 100644
index 0000000..60f77ed
--- /dev/null
+++ b/src/views/dashboard/controls/Text.vue
@@ -0,0 +1,129 @@
+<!-- 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. -->
+<template>
+ <div class="topology">
+ <div class="header">
+ <el-popover
+ placement="bottom"
+ trigger="click"
+ :width="100"
+ v-if="dashboardStore.editMode"
+ >
+ <template #reference>
+ <span>
+ <Icon iconName="ellipsis_v" size="middle" class="operation" />
+ </span>
+ </template>
+ <div class="tools" @click="editConfig">
+ <span>{{ t("edit") }}</span>
+ </div>
+ <div class="tools" @click="removeTopo">
+ <span>{{ t("delete") }}</span>
+ </div>
+ </el-popover>
+ </div>
+ <div
+ class="body"
+ :style="{ backgroundColor: TextColors[data.graph.backgroundColor] }"
+ >
+ <div
+ :style="{
+ color: TextColors[data.graph.fontColor],
+ fontSize: data.graph.fontSize + 'px',
+ }"
+ >
+ <a :href="data.graph.url" target="_blank">
+ {{ data.graph.content }}
+ </a>
+ </div>
+ </div>
+ </div>
+</template>
+<script lang="ts" setup>
+import type { PropType } from "vue";
+import { useI18n } from "vue-i18n";
+import { useDashboardStore } from "@/store/modules/dashboard";
+import { TextColors } from "@/views/dashboard/data";
+
+/*global defineProps */
+const props = defineProps({
+ data: {
+ type: Object as PropType<any>,
+ default: () => ({ graph: {} }),
+ },
+ activeIndex: { type: String, default: "" },
+});
+const { t } = useI18n();
+const dashboardStore = useDashboardStore();
+
+function removeTopo() {
+ dashboardStore.removeControls(props.data);
+}
+function editConfig() {
+ dashboardStore.setConfigPanel(true);
+ dashboardStore.selectWidget(props.data);
+}
+function viewText() {
+ const path = props.data.graph.url;
+ console.log(path);
+ if (!path) {
+ return;
+ }
+ window.open(path, "_blank");
+}
+</script>
+<style lang="scss" scoped>
+.topology {
+ font-size: 12px;
+ height: 100%;
+ position: relative;
+}
+
+.operation {
+ cursor: pointer;
+}
+
+.header {
+ position: absolute;
+ top: 10px;
+ right: 10px;
+}
+
+.body {
+ text-align: center;
+ width: 100%;
+ height: 100%;
+ cursor: pointer;
+ box-sizing: border-box;
+ color: #333;
+ display: -webkit-box;
+ -webkit-box-orient: horizontal;
+ -webkit-box-pack: center;
+ -webkit-box-align: center;
+}
+
+.tools {
+ padding: 5px 0;
+ color: #999;
+ cursor: pointer;
+ position: relative;
+ text-align: center;
+
+ &:hover {
+ color: #409eff;
+ background-color: #eee;
+ }
+}
+</style>
diff --git a/src/views/dashboard/controls/index.ts b/src/views/dashboard/controls/index.ts
index 7fdcd85..9829a0d 100644
--- a/src/views/dashboard/controls/index.ts
+++ b/src/views/dashboard/controls/index.ts
@@ -20,5 +20,6 @@ import Widget from "./Widget.vue";
import Trace from "./Trace.vue";
import Profile from "./Profile.vue";
import Log from "./Log.vue";
+import Text from "./Text.vue";
-export default { Tab, Widget, Trace, Topology, Profile, Log };
+export default { Tab, Widget, Trace, Topology, Profile, Log, Text };
diff --git a/src/views/dashboard/data.ts b/src/views/dashboard/data.ts
index a97fc3d..9668d76 100644
--- a/src/views/dashboard/data.ts
+++ b/src/views/dashboard/data.ts
@@ -23,10 +23,10 @@ export const ChartTypes = [
{ label: "Bar", value: "Bar" },
{ label: "Line", value: "Line" },
{ label: "Area", value: "Area" },
- // { label: "Pie", value: "Pie" },
{ label: "Card", value: "Card" },
{ label: "Top List", value: "TopList" },
{ label: "Table", value: "Table" },
+ { label: "Text", value: "Text" },
{ label: "Heatmap", value: "Heatmap" },
{ label: "Service List", value: "ServiceList" },
{ label: "Endpoint List", value: "EndpointList" },
@@ -169,6 +169,7 @@ export const SortOrder = [
export const AllTools = [
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
+ { name: "library_books", content: "Add Text", id: "addText" },
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
{ name: "merge", content: "Add Trace", id: "addTrace" },
{ name: "assignment", content: "Add Log", id: "addLog" },
@@ -177,6 +178,7 @@ export const AllTools = [
export const ServiceTools = [
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
+ { name: "library_books", content: "Add Text", id: "addText" },
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
{ name: "merge", content: "Add Trace", id: "addTrace" },
{ name: "timeline", content: "Add Profile", id: "addProfile" },
@@ -186,6 +188,7 @@ export const ServiceTools = [
export const InstanceTools = [
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
+ { name: "library_books", content: "Add Text", id: "addText" },
{ name: "merge", content: "Add Trace", id: "addTrace" },
{ name: "assignment", content: "Add Log", id: "addLog" },
{ name: "save", content: "Apply", id: "apply" },
@@ -193,6 +196,7 @@ export const InstanceTools = [
export const EndpointTools = [
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
+ { name: "library_books", content: "Add Text", id: "addText" },
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
{ name: "merge", content: "Add Trace", id: "addTrace" },
{ name: "assignment", content: "Add Log", id: "addLog" },
@@ -201,6 +205,7 @@ export const EndpointTools = [
export const ServiceRelationTools = [
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
+ { name: "library_books", content: "Add Text", id: "addText" },
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
{ name: "save", content: "Apply", id: "apply" },
];
@@ -208,11 +213,13 @@ export const ServiceRelationTools = [
export const EndpointRelationTools = [
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
+ { name: "library_books", content: "Add Text", id: "addText" },
{ name: "save", content: "Apply", id: "apply" },
];
export const InstanceRelationTools = [
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
+ { name: "library_books", content: "Add Text", id: "addText" },
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
{ name: "save", content: "Apply", id: "apply" },
];
@@ -248,3 +255,12 @@ export const QueryOrders = [
{ label: "Start Time", value: "BY_START_TIME" },
{ label: "Duration", value: "BY_DURATION" },
];
+export const TextColors: { [key: string]: string } = {
+ green: "#67C23A",
+ blue: "#409EFF",
+ red: "#F56C6C",
+ grey: "#909399",
+ white: "#fff",
+ black: "#000",
+ orange: "#E6A23C",
+};
diff --git a/src/views/dashboard/panel/Layout.vue b/src/views/dashboard/panel/Layout.vue
index 93d8ad1..cec440a 100644
--- a/src/views/dashboard/panel/Layout.vue
+++ b/src/views/dashboard/panel/Layout.vue
@@ -59,6 +59,9 @@ export default defineComponent({
function clickGrid(item: LayoutConfig) {
dashboardStore.activeGridItem(item.i);
dashboardStore.selectWidget(item);
+ if (item.type === "Tab") {
+ dashboardStore.setActiveTabIndex(0);
+ }
}
onBeforeUnmount(() => {
dashboardStore.setLayout([]);
diff --git a/src/views/dashboard/panel/Tool.vue b/src/views/dashboard/panel/Tool.vue
index 9c9e55c..d5476d0 100644
--- a/src/views/dashboard/panel/Tool.vue
+++ b/src/views/dashboard/panel/Tool.vue
@@ -367,6 +367,9 @@ function setTabControls(id: string) {
case "addTopology":
dashboardStore.addTabControls("Topology");
break;
+ case "addText":
+ dashboardStore.addTabControls("Text");
+ break;
default:
ElMessage.info("Don't support this control");
break;
@@ -393,6 +396,9 @@ function setControls(id: string) {
case "addTopology":
dashboardStore.addControl("Topology");
break;
+ case "addText":
+ dashboardStore.addControl("Text");
+ break;
default:
dashboardStore.addControl("Widget");
}
diff --git a/src/views/dashboard/related/topology/components/Graph.vue b/src/views/dashboard/related/topology/components/Graph.vue
index b682677..f48705a 100644
--- a/src/views/dashboard/related/topology/components/Graph.vue
+++ b/src/views/dashboard/related/topology/components/Graph.vue
@@ -30,7 +30,6 @@ limitations under the License. -->
class="inputs"
:value="depth"
:options="DepthList"
- placeholder="Select a option"
@change="changeDepth"
/>
</span>
@@ -377,10 +376,12 @@ async function handleInspect() {
topologyStore.setNode(null);
topologyStore.setLink(null);
loading.value = true;
- const resp = await topologyStore.getServicesTopology([id]);
+ const resp = await topologyStore.getDepthServiceTopology(
+ [id],
+ Number(depth.value)
+ );
loading.value = false;
-
- if (resp.errors) {
+ if (resp && resp.errors) {
ElMessage.error(resp.errors);
}
await init();
@@ -555,17 +556,18 @@ watch(
.operations-list {
position: absolute;
- padding: 10px;
color: #333;
cursor: pointer;
background-color: #fff;
border-radius: 3px;
+ padding: 10px 0;
span {
display: block;
height: 30px;
line-height: 30px;
- text-align: center;
+ text-align: left;
+ padding: 0 15px;
}
span:hover {
diff --git a/src/views/dashboard/related/topology/components/PodTopology.vue b/src/views/dashboard/related/topology/components/PodTopology.vue
index b336279..8fc4df7 100644
--- a/src/views/dashboard/related/topology/components/PodTopology.vue
+++ b/src/views/dashboard/related/topology/components/PodTopology.vue
@@ -324,7 +324,7 @@ watch(
.operations-list {
position: absolute;
- padding: 10px;
+ padding: 10px 0;
color: #333;
cursor: pointer;
background-color: #fff;
@@ -335,7 +335,8 @@ watch(
height: 30px;
width: 140px;
line-height: 30px;
- text-align: center;
+ text-align: left;
+ padding: 0 15px;
}
span:hover {
diff --git a/src/views/dashboard/related/topology/components/Settings.vue b/src/views/dashboard/related/topology/components/Settings.vue
index 8dbe619..21e15c8 100644
--- a/src/views/dashboard/related/topology/components/Settings.vue
+++ b/src/views/dashboard/related/topology/components/Settings.vue
@@ -23,6 +23,7 @@ limitations under the License. -->
placeholder="Please input a dashboard name for calls"
@change="changeLinkDashboard"
class="inputs"
+ :clearable="true"
/>
<div class="label">{{ t("linkServerMetrics") }}</div>
<Selector
@@ -86,7 +87,6 @@ limitations under the License. -->
<span>
<Icon
class="cp mr-5"
- v-show="items.length > 1"
iconName="remove_circle_outline"
size="middle"
@click="deleteItem(index)"
@@ -144,7 +144,6 @@ limitations under the License. -->
iconName="remove_circle_outline"
size="middle"
@click="deleteMetric(index)"
- v-show="legend.metric.length > 1"
/>
<Icon
class="cp"
@@ -196,6 +195,10 @@ const { t } = useI18n();
const dashboardStore = useDashboardStore();
const topologyStore = useTopologyStore();
const { selectedGrid } = dashboardStore;
+const nodeDashboard =
+ selectedGrid.nodeDashboard && selectedGrid.nodeDashboard.length
+ ? selectedGrid.nodeDashboard
+ : "";
const isService = [EntityType[0].value, EntityType[1].value].includes(
dashboardStore.entity
);
@@ -204,7 +207,7 @@ const items = reactive<
scope: string;
dashboard: string;
}[]
->((isService && selectedGrid.nodeDashboard) || [{ scope: "", dashboard: "" }]);
+>(isService && nodeDashboard ? nodeDashboard : [{ scope: "", dashboard: "" }]);
const states = reactive<{
linkDashboard: string;
nodeDashboard: {
@@ -229,9 +232,12 @@ const states = reactive<{
linkDashboards: [],
nodeDashboards: [],
});
+const l = selectedGrid.legend && selectedGrid.legend.length;
const legend = reactive<{
metric: { name: string; condition: string; value: string }[];
-}>({ metric: selectedGrid.legend || [{ name: "", condition: "", value: "" }] });
+}>({
+ metric: l ? selectedGrid.legend : [{ name: "", condition: "", value: "" }],
+});
getMetricList();
async function getMetricList() {
@@ -335,6 +341,9 @@ function addItem() {
items.push({ scope: "", dashboard: "" });
}
function deleteItem(index: number) {
+ if (items.length === 1) {
+ items.push({ scope: "", dashboard: "" });
+ }
items.splice(index, 1);
updateSettings();
}
@@ -384,6 +393,10 @@ async function changeNodeMetrics(options: Option[] | any) {
topologyStore.queryNodeMetrics(states.nodeMetrics);
}
function deleteMetric(index: number) {
+ if (legend.metric.length === 1) {
+ legend.metric = [{ name: "", condition: "", value: "" }];
+ return;
+ }
legend.metric.splice(index, 1);
}
function addMetric() {
diff --git a/src/views/dashboard/related/trace/utils/d3-trace-list.ts b/src/views/dashboard/related/trace/utils/d3-trace-list.ts
index f987e1b..dc2c16a 100644
--- a/src/views/dashboard/related/trace/utils/d3-trace-list.ts
+++ b/src/views/dashboard/related/trace/utils/d3-trace-list.ts
@@ -40,14 +40,15 @@ export default class ListGraph {
constructor(el: HTMLDivElement, handleSelectSpan: (i: Trace) => void) {
this.handleSelectSpan = handleSelectSpan;
this.el = el;
- this.width = el.clientWidth - 20;
+ this.width = el.clientWidth - 10;
this.height = el.clientHeight;
this.svg = d3
.select(this.el)
.append("svg")
.attr("class", "trace-list-dowanload")
.attr("width", this.width)
- .attr("height", this.height);
+ .attr("height", this.height)
+ .attr("transform", `translate(-5, 0)`);
this.tip = (d3tip as any)()
.attr("class", "d3-tip")
.offset([-8, 0])
@@ -220,7 +221,7 @@ export default class ListGraph {
nodeEnter
.transition()
.duration(400)
- .attr("transform", (d: any) => `translate(${d.y},${d.x})`)
+ .attr("transform", (d: any) => `translate(${d.y + 5},${d.x})`)
.style("opacity", 1);
nodeEnter
.append("circle")
@@ -243,7 +244,7 @@ export default class ListGraph {
node
.transition()
.duration(400)
- .attr("transform", (d: any) => `translate(${d.y},${d.x})`)
+ .attr("transform", (d: any) => `translate(${d.y + 5},${d.x})`)
.style("opacity", 1)
.select("circle")
.attr("fill", (d: any) =>
@@ -273,8 +274,9 @@ export default class ListGraph {
.attr("fill", "rgba(0,0,0,0)")
.attr("stroke", "rgba(0, 0, 0, 0.1)")
.attr("stroke-width", 2)
+ .attr("transform", `translate(5, 0)`)
.attr("d", () => {
- const o = { x: source.x0 + 35, y: source.y0 };
+ const o = { x: source.x0 + 40, y: source.y0 };
return this.diagonal({ source: o, target: o });
})
.transition()