feat: add hierarchy settings component

This commit is contained in:
Fine 2024-01-09 14:52:40 +08:00
parent 0be1e6d26c
commit 07860e630a
10 changed files with 97 additions and 30 deletions

View File

@ -385,5 +385,6 @@ const msg = {
traceDesc:
"The trace segment serves as a representation of a trace portion executed within one single OS process, such as a JVM. It comprises a collection of spans, typically associated with and collected from a single request or execution context.",
tabExpressions: "Tab Expressions",
hierarchyServicesSettings: "Service Hierarchy Topology Settings",
};
export default msg;

View File

@ -385,5 +385,6 @@ const msg = {
traceDesc:
"The trace segment serves as a representation of a trace portion executed within one single OS process, such as a JVM. It comprises a collection of spans, typically associated with and collected from a single request or execution context.",
tabExpressions: "Tab Expressions",
hierarchyServicesSettings: "Service Hierarchy Topology Settings",
};
export default msg;

View File

@ -383,5 +383,6 @@ const msg = {
traceDesc:
"Trace Segment代表在单一操作系统进程例如JVM中执行的追踪部分。它包含了一组跨度spans这些跨度通常与单一请求或执行上下文关联。",
tabExpressions: "Tab表达式",
hierarchyServicesSettings: "层次结构服务拓扑设置",
};
export default msg;

View File

@ -92,7 +92,7 @@ html.dark {
--sw-config-header: #303133;
--sw-topology-color: #ccc;
--vis-tooltip-bg: #414243;
--sw-topology-switch-icon: #aaa;
--sw-topology-switch-icon: #999;
--sw-topology-box-shadow: 0 0 2px 0 #444;
--sw-topology-setting-bg: #333;
--sw-topology-border: 1px solid #666;

View File

@ -13,13 +13,13 @@ 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>
<Graph :config="config" v-if="isService" />
<PodTopology :config="config" v-else />
<service-map :config="config" v-if="isService" />
<pod-map :config="config" v-else />
</template>
<script lang="ts" setup>
import type { PropType } from "vue";
import Graph from "./components/Graph.vue";
import PodTopology from "./components/PodTopology.vue";
import ServiceMap from "./components/ServiceMap.vue";
import PodMap from "./components/PodMap.vue";
import { EntityType } from "../../data";
import { useDashboardStore } from "@/store/modules/dashboard";

View File

@ -0,0 +1,38 @@
<!-- 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="hierarchy-services-settings">
<h5 class="title">{{ t("hierarchyServicesSettings") }}</h5>
<div class="label">{{ t("nodeMetrics") }}</div>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref } from "vue";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
</script>
<style lang="scss" scoped>
.title {
color: var(--sw-topology-color);
margin-bottom: 0;
}
.label {
font-size: $font-size-smaller;
margin-top: 10px;
color: var(--sw-topology-color);
}
</style>

View File

@ -76,11 +76,33 @@ limitations under the License. -->
</g>
</svg>
<div id="popover"></div>
<div class="legend">
<div>
<img :src="icons.CUBE" />
<span>
{{ settings.description ? settings.description.healthy || "" : "" }}
</span>
</div>
<div>
<img :src="icons.CUBEERROR" />
<span>
{{ settings.description ? settings.description.unhealthy || "" : "" }}
</span>
</div>
</div>
<div class="tool">
<span class="switch-icon ml-5" title="Settings" @click="showConfig" v-if="dashboardStore.editMode">
<Icon size="middle" iconName="settings" />
</span>
</div>
<div class="setting" v-if="showSetting && dashboardStore.editMode">
<hierachy-settings />
</div>
</div>
</template>
<script lang="ts" setup>
import type { PropType } from "vue";
import { ref, onMounted, onBeforeUnmount, watch, computed, nextTick } from "vue";
import { ref, onMounted, watch, computed, nextTick } from "vue";
import { useI18n } from "vue-i18n";
import * as d3 from "d3";
import type { Node, Call } from "@/types/topology";
@ -100,6 +122,7 @@ limitations under the License. -->
import { layout, changeNode, computeLevels } from "./utils/layout";
import zoom from "../../components/utils/zoom";
import { useQueryTopologyExpressionsProcessor } from "@/hooks/useExpressionsProcessor";
import HierachySettings from "./HierachySettings.vue";
/*global Nullable, defineProps */
const props = defineProps({
@ -119,6 +142,7 @@ limitations under the License. -->
const svg = ref<Nullable<any>>(null);
const graph = ref<Nullable<any>>(null);
const settings = ref<any>(props.config);
const showSetting = ref<boolean>(false);
const graphConfig = computed(() => props.config.graph || {});
const topologyLayout = ref<any>({});
const popover = ref<Nullable<any>>(null);
@ -153,7 +177,8 @@ limitations under the License. -->
}
async function freshNodes() {
topologyStore.setHierarchyServiceNode(null);
const resp = await topologyStore.getHierarchyServiceTopology();
const resp = await getTopology();
// const resp = await topologyStore.getHierarchyServiceTopology();
loading.value = false;
if (resp && resp.errors) {
@ -190,6 +215,17 @@ limitations under the License. -->
currentNode.value = null;
}
async function getTopology() {
const ids = selectorStore.services.map((d: Service) => d.id);
const serviceIds = dashboardStore.entity === EntityType[0].value ? [selectorStore.currentService.id] : ids;
const resp = await topologyStore.getDepthServiceTopology(serviceIds, 2);
return resp;
}
function showConfig() {
showSetting.value = !showSetting.value;
}
async function initLegendMetrics() {
if (!topologyStore.nodes.length) {
return;
@ -336,9 +372,10 @@ limitations under the License. -->
.legend {
position: absolute;
top: 10px;
left: 25px;
top: 0;
left: 0;
color: var(--sw-topology-color);
font-size: 12px;
div {
margin-bottom: 8px;
@ -359,10 +396,10 @@ limitations under the License. -->
.setting {
position: absolute;
top: 80px;
top: 40px;
right: 10px;
width: 400px;
height: 600px;
width: 300px;
height: 400px;
overflow: auto;
padding: 0 15px;
border-radius: 3px;
@ -404,7 +441,7 @@ limitations under the License. -->
.tool {
position: absolute;
top: 35px;
top: 10px;
right: 10px;
}
@ -414,7 +451,7 @@ limitations under the License. -->
background: var(--sw-topology-switch-icon);
color: $text-color;
display: inline-block;
padding: 2px 4px;
padding: 1px;
border-radius: 3px;
}

View File

@ -128,13 +128,7 @@ limitations under the License. -->
{{ item.title }}
</span>
</div>
<el-dialog
v-model="hierarchyRelated"
:destroy-on-close="true"
@closed="hierarchyRelated = false"
width="640px"
height="600px"
>
<el-dialog v-model="hierarchyRelated" :destroy-on-close="true" @closed="hierarchyRelated = false" width="640px">
<div class="hierarchy-related">
<hierarchy-map :config="config" />
</div>

View File

@ -24,7 +24,7 @@ limitations under the License. -->
@change="changeMetricMode"
/>
</div>
<div class="link-settings">
<div class="mb-20">
<h5 class="title">{{ t("callSettings") }}</h5>
<div class="label">{{ t("linkDashboard") }}</div>
<Selector
@ -107,7 +107,7 @@ limitations under the License. -->
/>
</span>
</div>
<div class="node-settings">
<div>
<h5 class="title">{{ t("nodeSettings") }}</h5>
<div class="label">{{ t("nodeDashboard") }}</div>
<Selector
@ -182,7 +182,7 @@ limitations under the License. -->
@change="updateNodeMetrics"
/>
</div>
<div class="legend-settings" v-show="isService">
<div v-show="isService">
<h5 class="title">{{ t("legendSettings") }}</h5>
<span v-if="isExpression">
<div class="label">Healthy Description</div>
@ -246,7 +246,7 @@ limitations under the License. -->
</span>
<div class="label">Unhealthy Description</div>
<el-input v-model="description.unhealthy" placeholder="Please input description" size="small" class="mt-5" />
<el-button @click="setLegend" class="legend-btn" size="small" type="primary">
<el-button @click="setLegend" class="mt-20" size="small" type="primary">
{{ t("setLegend") }}
</el-button>
</div>
@ -604,10 +604,6 @@ limitations under the License. -->
}
</script>
<style lang="scss" scoped>
.link-settings {
margin-bottom: 20px;
}
.inputs {
margin-top: 8px;
width: 355px;
@ -640,7 +636,6 @@ limitations under the License. -->
}
.legend-btn {
margin: 20px 0;
cursor: pointer;
}