This is an automated email from the ASF dual-hosted git repository.
qiuxiafan 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 1377703 feat: Implement adding controls in Tabs (#21)
1377703 is described below
commit 1377703185c83bd3bf530efdc169e5d017905c14
Author: Fine0830 <[email protected]>
AuthorDate: Fri Mar 4 15:35:29 2022 +0800
feat: Implement adding controls in Tabs (#21)
---
src/components/Icon.vue | 13 +-
src/locales/lang/en.ts | 1 +
src/locales/lang/zh.ts | 1 +
src/router/index.ts | 3 +-
src/store/modules/dashboard.ts | 105 ++++++--
src/types/dashboard.ts | 1 +
src/views/dashboard/Edit.vue | 1 +
src/views/dashboard/controls/Tab.vue | 267 +++++++++++++--------
src/views/dashboard/controls/Widget.vue | 8 +-
src/views/dashboard/data.ts | 6 +-
src/views/dashboard/panel/Layout.vue | 1 +
src/views/dashboard/panel/Tool.vue | 50 +++-
src/views/dashboard/related/profile/Content.vue | 9 +-
.../related/profile/components/SpanTree.vue | 28 ++-
.../related/trace/components/Table/TableItem.vue | 3 +-
15 files changed, 347 insertions(+), 150 deletions(-)
diff --git a/src/components/Icon.vue b/src/components/Icon.vue
index 10becda..fc6a0ce 100644
--- a/src/components/Icon.vue
+++ b/src/components/Icon.vue
@@ -21,7 +21,7 @@ limitations under the License. -->
lg: size === 'lg',
xl: size === 'xl',
logo: size === 'logo',
- loading: loading,
+ loading,
}"
>
<use :xlink:href="`#${iconName}`"></use>
@@ -73,4 +73,15 @@ defineProps({
width: 30px;
}
}
+@keyframes loading {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+
+ to {
+ -webkit-transform: rotate(1turn);
+ transform: rotate(1turn);
+ }
+}
</style>
diff --git a/src/locales/lang/en.ts b/src/locales/lang/en.ts
index 29feac0..b364919 100644
--- a/src/locales/lang/en.ts
+++ b/src/locales/lang/en.ts
@@ -95,6 +95,7 @@ const msg = {
topChildren: "Top 5 of children",
taskList: "Task List",
sampledTraces: "Sampled Traces",
+ editTab: "Enable editing tab names",
hourTip: "Select Hour",
minuteTip: "Select Minute",
secondTip: "Select Second",
diff --git a/src/locales/lang/zh.ts b/src/locales/lang/zh.ts
index 5764eee..d60322c 100644
--- a/src/locales/lang/zh.ts
+++ b/src/locales/lang/zh.ts
@@ -95,6 +95,7 @@ const msg = {
showDepth: "展示深度选择器",
taskList: "任务列表",
sampledTraces: "采样的追踪",
+ editTab: "开启编辑Tab的名称",
hourTip: "选择小时",
minuteTip: "选择分钟",
secondTip: "选择秒数",
diff --git a/src/router/index.ts b/src/router/index.ts
index 80068c3..4ab9d19 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -26,7 +26,6 @@ import { routesEvent } from "./event";
import { routesAlert } from "./alert";
import { routesSetting } from "./setting";
import { routesAlarm } from "./alarm";
-import { useTimeoutFn } from "@/hooks/useTimeout";
const routes: Array<RouteRecordRaw> = [
...routesGen,
@@ -52,7 +51,7 @@ router.beforeEach((to, from, next) => {
// const token = window.localStorage.getItem("skywalking-authority");
if ((window as any).axiosCancel.length !== 0) {
for (const func of (window as any).axiosCancel) {
- useTimeoutFn(func(), 0);
+ setTimeout(func(), 0);
}
(window as any).axiosCancel = [];
}
diff --git a/src/store/modules/dashboard.ts b/src/store/modules/dashboard.ts
index 24a19e3..ad15f25 100644
--- a/src/store/modules/dashboard.ts
+++ b/src/store/modules/dashboard.ts
@@ -43,6 +43,7 @@ interface DashboardState {
durationTime: Duration;
selectorStore: any;
showTopology: boolean;
+ currentTabItems: LayoutConfig[];
}
export const dashboardStore = defineStore({
@@ -57,6 +58,7 @@ export const dashboardStore = defineStore({
durationTime: useAppStoreWithOut().durationTime,
selectorStore: useSelectorStore(),
showTopology: false,
+ currentTabItems: [],
}),
actions: {
setLayout(data: LayoutConfig[]) {
@@ -71,7 +73,8 @@ export const dashboardStore = defineStore({
metrics: [""],
};
if (type === "Tab") {
- newItem.h = 24;
+ newItem.h = 36;
+ newItem.activedTabIndex = 0;
newItem.children = [
{
name: "Tab1",
@@ -96,14 +99,15 @@ export const dashboardStore = defineStore({
};
}
if (type === "Trace" || type === "Profile") {
- newItem.h = 36;
+ newItem.h = 24;
}
+ this.activedGridItem = newItem.i;
+ this.selectedGrid = newItem;
this.layout = this.layout.map((d: LayoutConfig) => {
d.y = d.y + newItem.h;
return d;
});
this.layout.push(newItem);
- this.activedGridItem = newItem.i;
},
addTabItem(item: LayoutConfig) {
const idx = this.layout.findIndex((d: LayoutConfig) => d.i === item.i);
@@ -117,7 +121,7 @@ export const dashboardStore = defineStore({
};
this.layout[idx].children?.push(i);
},
- addTabWidget(tabIndex: number) {
+ addTabControls(type: string) {
const activedGridItem = this.activedGridItem.split("-")[0];
const idx = this.layout.findIndex(
(d: LayoutConfig) => d.i === activedGridItem
@@ -125,37 +129,91 @@ export const dashboardStore = defineStore({
if (idx < 0) {
return;
}
+ const tabIndex = this.layout[idx].activedTabIndex;
const { children } = this.layout[idx].children[tabIndex];
- const newWidget = {
- x: 0,
- y: 0,
- w: 24,
- h: 12,
+ const newItem: LayoutConfig = {
+ ...NewControl,
i: String(children.length),
- type: "Widget",
- widget: {
- title: "Title",
- },
- graph: {},
- standard: {},
+ type,
+ metricTypes: [""],
+ metrics: [""],
};
+ if (type === "Topology") {
+ newItem.w = 4;
+ newItem.h = 6;
+ newItem.graph = {
+ fontColor: "white",
+ backgroundColor: "green",
+ iconTheme: true,
+ content: "Topology",
+ fontSize: 18,
+ showDepth: true,
+ };
+ }
+ if (type === "Trace" || type === "Profile") {
+ newItem.h = 24;
+ }
if (this.layout[idx].children) {
const items = children.map((d: LayoutConfig) => {
- d.y = d.y + newWidget.h;
+ d.y = d.y + newItem.h;
return d;
});
- items.push(newWidget);
+ items.push(newItem);
this.layout[idx].children[tabIndex].children = items;
+ this.currentTabItems = items;
}
},
activeGridItem(index: string) {
this.activedGridItem = index;
},
+ setActiveTabIndex(index: number) {
+ const idx = this.layout.findIndex(
+ (d: LayoutConfig) => d.i === this.activedGridItem
+ );
+ if (idx < 0) {
+ return;
+ }
+ this.layout[idx].activedTabIndex = index;
+ },
+ setCurrentTabItems(items: LayoutConfig[]) {
+ this.currentTabItems = items;
+ },
+ removeTab(item: LayoutConfig) {
+ if (this.selectedGrid && this.selectedGrid.i === item.i) {
+ this.selectedGrid = null;
+ }
+ this.layout = this.layout.filter((d: LayoutConfig) => d.i !== item.i);
+ },
removeControls(item: LayoutConfig) {
+ const actived = this.activedGridItem.split("-");
+ const index = this.layout.findIndex(
+ (d: LayoutConfig) => actived[0] === d.i
+ );
+
+ if (this.selectedGrid && this.selectedGrid.i === item.i) {
+ this.selectedGrid = null;
+ }
+ if (actived.length === 3) {
+ const tabIndex = Number(actived[1]);
+ const itemIndex = this.layout[index].children[
+ tabIndex
+ ].children.findIndex((d: LayoutConfig) => actived[2] === d.i);
+
+ this.layout[index].children[tabIndex].children.splice(itemIndex, 1);
+
this.setCurrentTabItems(this.layout[index].children[tabIndex].children);
+ return;
+ }
this.layout = this.layout.filter((d: LayoutConfig) => d.i !== item.i);
},
removeTabItem(item: LayoutConfig, index: number) {
const idx = this.layout.findIndex((d: LayoutConfig) => d.i === item.i);
+ if (this.selectedGrid) {
+ for (const item of this.layout[idx].children[index].children) {
+ if (this.selectedGrid.i === item.i) {
+ this.selectedGrid = null;
+ }
+ }
+ }
if (this.layout[idx].children) {
this.layout[idx].children?.splice(index, 1);
}
@@ -204,11 +262,18 @@ export const dashboardStore = defineStore({
);
if (actived.length === 3) {
- this.layout[index].children[actived[1]].children[actived[2]] = {
- ...this.layout[index],
+ const tabIndex = Number(actived[1]);
+ const itemIndex = this.layout[index].children[
+ tabIndex
+ ].children.findIndex((d: LayoutConfig) => actived[2] === d.i);
+
+ this.layout[index].children[tabIndex].children[itemIndex] = {
+ ...this.layout[index].children[tabIndex].children[itemIndex],
...param,
};
- this.selectedGrid = this.layout[index];
+ this.selectedGrid =
+ this.layout[index].children[tabIndex].children[itemIndex];
+
this.setCurrentTabItems(this.layout[index].children[tabIndex].children);
return;
}
this.layout[index] = {
diff --git a/src/types/dashboard.ts b/src/types/dashboard.ts
index b8c0544..c0ec3d8 100644
--- a/src/types/dashboard.ts
+++ b/src/types/dashboard.ts
@@ -27,6 +27,7 @@ export interface LayoutConfig {
type: string;
metricTypes: string[];
children?: any;
+ activedTabIndex?: number;
}
export interface WidgetConfig {
diff --git a/src/views/dashboard/Edit.vue b/src/views/dashboard/Edit.vue
index 075b0ec..d6b3e24 100644
--- a/src/views/dashboard/Edit.vue
+++ b/src/views/dashboard/Edit.vue
@@ -75,6 +75,7 @@ function handleClick(e: any) {
e.stopPropagation();
if (e.target.className === "ds-main") {
dashboardStore.activeGridItem("");
+ dashboardStore.selectWidget(null);
}
}
</script>
diff --git a/src/views/dashboard/controls/Tab.vue
b/src/views/dashboard/controls/Tab.vue
index 5c31a87..20c106d 100644
--- a/src/views/dashboard/controls/Tab.vue
+++ b/src/views/dashboard/controls/Tab.vue
@@ -33,38 +33,62 @@ limitations under the License. -->
v-show="activeTabIndex === idx"
size="sm"
iconName="cancel"
- @click="deleteTabItem(idx)"
+ @click="deleteTabItem($event, idx)"
/>
</span>
<span class="tab-icons">
- <el-tooltip effect="dark" content="Add tab items" placement="bottom">
+ <el-tooltip content="Add tab items" placement="bottom">
<i @click="addTabItem">
<Icon size="middle" iconName="add" />
</i>
</el-tooltip>
- <el-tooltip effect="dark" content="Add widgets" placement="bottom">
- <i @click="addTabWidget">
- <Icon size="middle" iconName="playlist_add" />
- </i>
- </el-tooltip>
</span>
</div>
<div class="operations">
- <Icon size="sm" iconName="clearclose" @click="removeTab" />
+ <el-popover
+ placement="bottom"
+ trigger="click"
+ :width="200"
+ v-model:visible="showTools"
+ >
+ <template #reference>
+ <span>
+ <Icon
+ iconName="ellipsis_v"
+ size="middle"
+ class="operation"
+ @click="showTools = true"
+ />
+ </span>
+ </template>
+ <div
+ class="tools"
+ @click="
+ canEditTabName = true;
+ showTools = false;
+ "
+ >
+ <span class="edit-tab">{{ t("editTab") }}</span>
+ </div>
+ <div class="tools" @click="removeTab">
+ <span>{{ t("delete") }}</span>
+ </div>
+ </el-popover>
</div>
</div>
- <div class="tab-layout">
+ <div class="tab-layout" @click="handleClick">
<grid-layout
- v-if="state.layout.length"
- v-model:layout="state.layout"
+ v-if="dashboardStore.currentTabItems.length"
+ v-model:layout="dashboardStore.currentTabItems"
:col-num="24"
:row-height="10"
:is-draggable="true"
:is-resizable="true"
+ :responsive="true"
@layout-updated="layoutUpdatedEvent"
>
<grid-item
- v-for="item in state.layout"
+ v-for="item in dashboardStore.currentTabItems"
:x="item.x"
:y="item.y"
:w="item.w"
@@ -74,103 +98,147 @@ limitations under the License. -->
@click="clickTabGrid($event, item)"
:class="{ active: activeTabWidget === item.i }"
>
- <Widget
+ <component
+ :is="item.type"
:data="item"
:activeIndex="`${data.i}-${activeTabIndex}-${item.i}`"
+ :needQuery="needQuery"
/>
</grid-item>
</grid-layout>
<div class="no-data-tips" v-else>Please add widgets.</div>
</div>
</template>
-<script lang="ts" setup>
-import { ref, watch, reactive } from "vue";
+<script lang="ts">
+import { ref, watch, defineComponent, toRefs } from "vue";
+import { useI18n } from "vue-i18n";
import type { PropType } from "vue";
-import Widget from "./Widget.vue";
import { LayoutConfig } from "@/types/dashboard";
import { useDashboardStore } from "@/store/modules/dashboard";
-/*global defineProps */
-const props = defineProps({
+import Topology from "./Topology.vue";
+import Widget from "./Widget.vue";
+import Trace from "./Trace.vue";
+import Profile from "./Profile.vue";
+
+const props = {
data: {
type: Object as PropType<LayoutConfig>,
default: () => ({ children: [] }),
},
active: { type: Boolean, default: false },
-});
-const dashboardStore = useDashboardStore();
-const activeTabIndex = ref<number>(0);
-const activeTabWidget = ref<string>("0");
-const editTabIndex = ref<number>(NaN); // edit tab item name
-const state = reactive<{
- layout: LayoutConfig[];
-}>({
- layout:
-
dashboardStore.layout[props.data.i].children[activeTabIndex.value].children,
-});
-
-function layoutUpdatedEvent(newLayout: LayoutConfig[]) {
- state.layout = newLayout;
-}
-function clickTabs(e: Event, idx: number) {
- e.stopPropagation();
- activeTabIndex.value = idx;
-}
-function removeTab() {
- dashboardStore.removeControls(props.data);
-}
-function deleteTabItem(idx: number) {
- dashboardStore.removeTabItem(props.data, idx);
-}
-function addTabItem() {
- dashboardStore.addTabItem(props.data);
-}
-function editTabName(el: Event, index: number) {
- el.stopPropagation();
- editTabIndex.value = index;
-}
-function handleClick(el: any) {
- if (el.target.className === "tab-name") {
- return;
- }
- editTabIndex.value = NaN;
-}
-function addTabWidget(e: Event) {
- e.stopPropagation();
- activeTabWidget.value = String(state.layout.length);
- dashboardStore.addTabWidget(activeTabIndex.value);
- dashboardStore.activeGridItem(
- `${props.data.i}-${activeTabIndex.value}-${activeTabWidget.value}`
- );
-}
-function clickTabGrid(e: Event, item: LayoutConfig) {
- e.stopPropagation();
- activeTabWidget.value = item.i;
- dashboardStore.activeGridItem(
- `${props.data.i}-${activeTabIndex.value}-${item.i}`
- );
-}
-document.body.addEventListener("click", handleClick, false);
+};
+export default defineComponent({
+ name: "Tab",
+ components: { Topology, Widget, Trace, Profile },
+ props,
+ setup(props) {
+ const { t } = useI18n();
+ const dashboardStore = useDashboardStore();
+ const activeTabIndex = ref<number>(0);
+ const activeTabWidget = ref<string>("");
+ const editTabIndex = ref<number>(NaN); // edit tab item name
+ const canEditTabName = ref<boolean>(false);
+ const needQuery = ref<boolean>(false);
+ const showTools = ref<boolean>(false);
+ const l = dashboardStore.layout.findIndex(
+ (d: LayoutConfig) => d.i === props.data.i
+ );
+ dashboardStore.setCurrentTabItems(
+ dashboardStore.layout[l].children[activeTabIndex.value].children
+ );
-const children = ref(
- dashboardStore.layout[props.data.i].children[activeTabIndex.value].children
-);
-watch(
- () => children.value,
- (data) => {
- state.layout = data;
- }
-);
-watch(
- () => dashboardStore.activedGridItem,
- (data) => {
- const i = data.split("-");
- if (i[0] === props.data.i && activeTabIndex.value === Number(i[1])) {
- activeTabWidget.value = i[2];
- } else {
- activeTabWidget.value = "";
+ function clickTabs(e: Event, idx: number) {
+ e.stopPropagation();
+ activeTabIndex.value = idx;
+ dashboardStore.activeGridItem(props.data.i);
+ dashboardStore.selectWidget(props.data);
+ dashboardStore.setActiveTabIndex(idx);
+ const l = dashboardStore.layout.findIndex(
+ (d: LayoutConfig) => d.i === props.data.i
+ );
+ dashboardStore.setCurrentTabItems(
+ dashboardStore.layout[l].children[activeTabIndex.value].children
+ );
+ needQuery.value = true;
}
- }
-);
+ function removeTab(e: Event) {
+ e.stopPropagation();
+ dashboardStore.removeTab(props.data);
+ }
+ function deleteTabItem(e: Event, idx: number) {
+ e.stopPropagation();
+ dashboardStore.removeTabItem(props.data, idx);
+ }
+ function addTabItem() {
+ dashboardStore.addTabItem(props.data);
+ }
+ function editTabName(el: Event, index: number) {
+ if (!canEditTabName.value) {
+ editTabIndex.value = NaN;
+ return;
+ }
+ editTabIndex.value = index;
+ }
+ function handleClick(el: any) {
+ if (["tab-name", "edit-tab"].includes(el.target.className)) {
+ return;
+ }
+ canEditTabName.value = false;
+ editTabIndex.value = NaN;
+ }
+ function clickTabGrid(e: Event, item: LayoutConfig) {
+ e.stopPropagation();
+ activeTabWidget.value = item.i;
+ dashboardStore.activeGridItem(
+ `${props.data.i}-${activeTabIndex.value}-${item.i}`
+ );
+ handleClick(e);
+ }
+ function layoutUpdatedEvent() {
+ const l = dashboardStore.layout.findIndex(
+ (d: LayoutConfig) => d.i === props.data.i
+ );
+ dashboardStore.setCurrentTabItems(
+ dashboardStore.layout[l].children[activeTabIndex.value].children
+ );
+ }
+ document.body.addEventListener("click", handleClick, false);
+ watch(
+ () => dashboardStore.activedGridItem,
+ (data) => {
+ if (!data) {
+ activeTabWidget.value = "";
+ return;
+ }
+ const i = data.split("-");
+ if (i[0] === props.data.i && activeTabIndex.value === Number(i[1])) {
+ activeTabWidget.value = i[2];
+ } else {
+ activeTabWidget.value = "";
+ }
+ }
+ );
+ return {
+ handleClick,
+ layoutUpdatedEvent,
+ clickTabGrid,
+ editTabName,
+ addTabItem,
+ deleteTabItem,
+ removeTab,
+ clickTabs,
+ ...toRefs(props),
+ activeTabWidget,
+ dashboardStore,
+ activeTabIndex,
+ editTabIndex,
+ needQuery,
+ canEditTabName,
+ showTools,
+ t,
+ };
+ },
+});
</script>
<style lang="scss" scoped>
.tabs {
@@ -218,10 +286,6 @@ watch(
}
}
-.el-input__inner {
- border: none !important;
-}
-
.operations {
color: #aaa;
cursor: pointer;
@@ -263,4 +327,17 @@ watch(
padding-top: 30px;
color: #888;
}
+
+.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/Widget.vue
b/src/views/dashboard/controls/Widget.vue
index 74ca377..56de472 100644
--- a/src/views/dashboard/controls/Widget.vue
+++ b/src/views/dashboard/controls/Widget.vue
@@ -77,6 +77,7 @@ const props = {
default: () => ({ widget: {} }),
},
activeIndex: { type: String, default: "" },
+ needQuery: { type: Boolean, default: false },
};
export default defineComponent({
name: "Widget",
@@ -93,7 +94,7 @@ export default defineComponent({
const dashboardStore = useDashboardStore();
const selectorStore = useSelectorStore();
- if (dashboardStore.entity === EntityType[1].value) {
+ if (dashboardStore.entity === EntityType[1].value || props.needQuery) {
queryMetrics();
}
@@ -128,7 +129,10 @@ export default defineComponent({
watch(
() => [props.data.metricTypes, props.data.metrics],
() => {
- if (props.data.i !== dashboardStore.selectedGrid.i) {
+ if (
+ dashboardStore.selectedGrid &&
+ props.data.i !== dashboardStore.selectedGrid.i
+ ) {
return;
}
if (TableChartTypes.includes(dashboardStore.selectedGrid.graph.type)) {
diff --git a/src/views/dashboard/data.ts b/src/views/dashboard/data.ts
index 17a186f..396de2c 100644
--- a/src/views/dashboard/data.ts
+++ b/src/views/dashboard/data.ts
@@ -165,9 +165,9 @@ export const SortOrder = [
export const ToolIcons = [
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
- { name: "device_hub", content: "Add Topology", id: "topology" },
- { name: "merge", content: "Add Trace", id: "trace" },
- { name: "timeline", content: "Add Profile", id: "profile" },
+ { name: "device_hub", content: "Add Topology", id: "addTopology" },
+ { name: "merge", content: "Add Trace", id: "addTrace" },
+ { name: "timeline", content: "Add Profile", id: "addProfile" },
// { name: "save_alt", content: "Export", id: "export" },
// { name: "folder_open", content: "Import", id: "import" },
// { name: "settings", content: "Settings", id: "settings" },
diff --git a/src/views/dashboard/panel/Layout.vue
b/src/views/dashboard/panel/Layout.vue
index 72c9588..bc3938f 100644
--- a/src/views/dashboard/panel/Layout.vue
+++ b/src/views/dashboard/panel/Layout.vue
@@ -53,6 +53,7 @@ export default defineComponent({
}
function clickGrid(item: LayoutConfig) {
dashboardStore.activeGridItem(item.i);
+ dashboardStore.selectWidget(item);
}
return {
dashboardStore,
diff --git a/src/views/dashboard/panel/Tool.vue
b/src/views/dashboard/panel/Tool.vue
index 7e5774a..b052257 100644
--- a/src/views/dashboard/panel/Tool.vue
+++ b/src/views/dashboard/panel/Tool.vue
@@ -107,7 +107,6 @@ import { EntityType, ToolIcons, hasTopology, TraceEntitys }
from "../data";
import { useSelectorStore } from "@/store/modules/selectors";
import { ElMessage } from "element-plus";
import { Option } from "@/types/app";
-import { Service } from "@/types/selector";
const dashboardStore = useDashboardStore();
const selectorStore = useSelectorStore();
@@ -260,7 +259,7 @@ async function getServices() {
}
}
-async function changeService(service: Service[]) {
+async function changeService(service: any) {
if (service[0]) {
states.currentService = service[0].value;
selectorStore.setCurrentService(service[0]);
@@ -270,7 +269,7 @@ async function changeService(service: Service[]) {
}
}
-function changeDestService(service: Service[]) {
+function changeDestService(service: any) {
if (service[0]) {
states.currentDestService = service[0].value;
selectorStore.setCurrentDestService(service[0]);
@@ -279,7 +278,7 @@ function changeDestService(service: Service[]) {
}
}
-function changePods(pod: Option[]) {
+function changePods(pod: any) {
if (pod[0]) {
selectorStore.setCurrentPod(pod[0]);
} else {
@@ -288,20 +287,55 @@ function changePods(pod: Option[]) {
}
function clickIcons(t: { id: string; content: string; name: string }) {
- switch (t.id) {
+ if (
+ dashboardStore.selectedGrid &&
+ dashboardStore.selectedGrid.type === "Tab"
+ ) {
+ setTabControls(t.id);
+ return;
+ }
+ if (dashboardStore.activedGridItem.split("-").length === 3) {
+ setTabControls(t.id);
+ return;
+ }
+ setControls(t.id);
+}
+
+function setTabControls(id: string) {
+ switch (id) {
+ case "addWidget":
+ dashboardStore.addTabControls("Widget");
+ break;
+ case "addTrace":
+ dashboardStore.addTabControls("Trace");
+ break;
+ case "addProfile":
+ dashboardStore.addTabControls("Profile");
+ break;
+ case "addTopology":
+ dashboardStore.addTabControls("Topology");
+ break;
+ default:
+ ElMessage.info("Don't support this control");
+ break;
+ }
+}
+
+function setControls(id: string) {
+ switch (id) {
case "addWidget":
dashboardStore.addControl("Widget");
break;
case "addTab":
dashboardStore.addControl("Tab");
break;
- case "trace":
+ case "addTrace":
dashboardStore.addControl("Trace");
break;
- case "profile":
+ case "addProfile":
dashboardStore.addControl("Profile");
break;
- case "topology":
+ case "addTopology":
dashboardStore.addControl("Topology");
break;
case "settings":
diff --git a/src/views/dashboard/related/profile/Content.vue
b/src/views/dashboard/related/profile/Content.vue
index 4679ba6..18bd265 100644
--- a/src/views/dashboard/related/profile/Content.vue
+++ b/src/views/dashboard/related/profile/Content.vue
@@ -65,19 +65,16 @@ function loadTrees(l: boolean) {
}
.thread-stack {
- padding: 5px 12px;
- height: calc(50% - 50px);
+ padding: 5px;
+ height: calc(50% - 20px);
overflow: auto;
width: 100%;
}
.t-loading {
text-align: center;
- position: absolute;
width: 100%;
- height: 70px;
- margin-top: 40px;
- line-height: 88px;
overflow: hidden;
+ height: calc(50% - 20px);
}
</style>
diff --git a/src/views/dashboard/related/profile/components/SpanTree.vue
b/src/views/dashboard/related/profile/components/SpanTree.vue
index 63df51d..0913b7d 100644
--- a/src/views/dashboard/related/profile/components/SpanTree.vue
+++ b/src/views/dashboard/related/profile/components/SpanTree.vue
@@ -35,16 +35,18 @@ limitations under the License. -->
{{ t("analyze") }}
</el-button>
</div>
- <Table
- :data="profileStore.segmentSpans"
- :traceId="
- profileStore.currentSegment.traceIds &&
- profileStore.currentSegment.traceIds[0]
- "
- :showBtnDetail="true"
- headerType="profile"
- @select="selectSpan"
- />
+ <div class="profile-table">
+ <Table
+ :data="profileStore.segmentSpans"
+ :traceId="
+ profileStore.currentSegment.traceIds &&
+ profileStore.currentSegment.traceIds[0]
+ "
+ :showBtnDetail="true"
+ headerType="profile"
+ @select="selectSpan"
+ />
+ </div>
</div>
</template>
<script lang="ts" setup>
@@ -158,10 +160,14 @@ function updateTimeRange() {
padding: 5px;
flex-shrink: 0;
height: 50%;
- overflow: auto;
width: 100%;
}
+.profile-table {
+ height: calc(100% - 30px);
+ overflow: auto;
+}
+
.profile-trace-detail-wrapper {
padding: 5px 0;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
diff --git a/src/views/dashboard/related/trace/components/Table/TableItem.vue
b/src/views/dashboard/related/trace/components/Table/TableItem.vue
index 86c8f5d..7f032fd 100644
--- a/src/views/dashboard/related/trace/components/Table/TableItem.vue
+++ b/src/views/dashboard/related/trace/components/Table/TableItem.vue
@@ -136,7 +136,7 @@ limitations under the License. -->
<script lang="ts">
import dayjs from "dayjs";
import { useI18n } from "vue-i18n";
-import { ref, watch, computed, defineComponent } from "vue";
+import { ref, computed, defineComponent } from "vue";
import type { PropType } from "vue";
import SpanDetail from "../D3Graph/SpanDetail.vue";
@@ -152,7 +152,6 @@ export default defineComponent({
emits: ["select"],
components: { SpanDetail },
setup(props, { emit }) {
- /* global Nullable */
const displayChildren = ref<boolean>(true);
const showDetail = ref<boolean>(false);
const { t } = useI18n();