mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-05-01 20:14:30 +00:00
feat: Implement Text control and update Topology (#37)
This commit is contained in:
parent
4380a874de
commit
99e23c33dc
@ -125,6 +125,7 @@ const msg = {
|
||||
kubernetesService: "Service",
|
||||
kubernetesCluster: "Cluster",
|
||||
kubernetes: "Kubernetes",
|
||||
textUrl: "Text Hyperlink",
|
||||
hourTip: "Select Hour",
|
||||
minuteTip: "Select Minute",
|
||||
secondTip: "Select Second",
|
||||
|
@ -125,6 +125,7 @@ const msg = {
|
||||
kubernetesService: "服务",
|
||||
kubernetesCluster: "集群",
|
||||
kubernetes: "Kubernetes",
|
||||
textUrl: "文本超链接",
|
||||
hourTip: "选择小时",
|
||||
minuteTip: "选择分钟",
|
||||
secondTip: "选择秒数",
|
||||
|
@ -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",
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
149
src/views/dashboard/configuration/Text.vue
Normal file
149
src/views/dashboard/configuration/Text.vue
Normal file
@ -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>
|
@ -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",
|
||||
|
26
src/views/dashboard/configuration/index.ts
Normal file
26
src/views/dashboard/configuration/index.ts
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Text from "./Text.vue";
|
||||
import Widget from "./Widget.vue";
|
||||
import Topology from "./Topology.vue";
|
||||
|
||||
export default {
|
||||
Text,
|
||||
Widget,
|
||||
Topology,
|
||||
};
|
@ -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) {
|
||||
|
129
src/views/dashboard/controls/Text.vue
Normal file
129
src/views/dashboard/controls/Text.vue
Normal file
@ -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>
|
@ -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 };
|
||||
|
@ -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",
|
||||
};
|
||||
|
@ -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([]);
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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() {
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user