From 4380a874dec253ec142fd7f7ccf733fde6d733e2 Mon Sep 17 00:00:00 2001 From: Fine0830 Date: Thu, 24 Mar 2022 21:35:22 +0800 Subject: [PATCH] fix: polish pages and bugs fix (#36) --- src/assets/icons/donut_small.svg | 17 ++++++ src/components/Graph.vue | 2 +- src/components/Selector.vue | 2 + src/layout/components/SideBar.vue | 31 ++++++++++ src/locales/lang/en.ts | 6 +- src/locales/lang/zh.ts | 6 +- src/router/index.ts | 2 + src/router/infrastructure.ts | 8 --- src/router/k8s.ts | 50 +++++++++++++++++ src/store/modules/app.ts | 12 ++++ src/store/modules/log.ts | 19 ++++--- src/store/modules/profile.ts | 5 +- src/store/modules/trace.ts | 19 ++++--- src/views/Layer.vue | 6 +- src/views/dashboard/List.vue | 3 + src/views/dashboard/configuration/Widget.vue | 20 ++++++- .../configuration/widget/MetricOptions.vue | 35 +++++++++--- src/views/dashboard/graphs/EndpointList.vue | 28 +++++----- src/views/dashboard/graphs/InstanceList.vue | 56 +++++++++++-------- src/views/dashboard/graphs/ServiceList.vue | 51 ++++++++++------- src/views/dashboard/panel/Tool.vue | 9 ++- .../related/components/LogTable/Index.vue | 1 + .../components/LogTable/LogService.vue | 2 + .../related/components/LogTable/data.ts | 4 ++ src/views/dashboard/related/log/Header.vue | 21 +++---- src/views/dashboard/related/trace/Filter.vue | 33 ++++++----- 26 files changed, 314 insertions(+), 134 deletions(-) create mode 100644 src/assets/icons/donut_small.svg create mode 100644 src/router/k8s.ts diff --git a/src/assets/icons/donut_small.svg b/src/assets/icons/donut_small.svg new file mode 100644 index 00000000..1c4cad71 --- /dev/null +++ b/src/assets/icons/donut_small.svg @@ -0,0 +1,17 @@ + + + + diff --git a/src/components/Graph.vue b/src/components/Graph.vue index bdc0dfb7..e70b7a1d 100644 --- a/src/components/Graph.vue +++ b/src/components/Graph.vue @@ -38,7 +38,7 @@ const props = defineProps({ onMounted(async () => { await setOptions(props.option); - addResizeListener(unref(chartRef), resize); + chartRef.value && addResizeListener(unref(chartRef), resize); setTimeout(() => { const instance = getInstance(); diff --git a/src/components/Selector.vue b/src/components/Selector.vue index b6dd34c7..908b2f65 100644 --- a/src/components/Selector.vue +++ b/src/components/Selector.vue @@ -22,6 +22,7 @@ limitations under the License. --> :multiple="multiple" :disabled="disabled" :style="{ borderRadius }" + :clearable="clearable" > (props.value); diff --git a/src/layout/components/SideBar.vue b/src/layout/components/SideBar.vue index e7afe788..1316cdef 100644 --- a/src/layout/components/SideBar.vue +++ b/src/layout/components/SideBar.vue @@ -101,6 +101,18 @@ limitations under the License. --> @click="controlMenu" /> +
+ + + +
@@ -108,7 +120,10 @@ limitations under the License. --> import { ref } from "vue"; import { useRouter, RouteRecordRaw } from "vue-router"; import { useI18n } from "vue-i18n"; +import { useAppStoreWithOut } from "@/store/modules/app"; +import { ElMessage } from "element-plus"; +const appStore = useAppStoreWithOut(); const { t } = useI18n(); const name = ref(String(useRouter().currentRoute.value.name)); const theme = ["VirtualMachine", "Kubernetes"].includes(name.value || "") @@ -119,6 +134,7 @@ const isCollapse = ref(false); const controlMenu = () => { isCollapse.value = !isCollapse.value; }; +getVersion(); const changePage = (menu: RouteRecordRaw) => { theme.value = ["VirtualMachine", "Kubernetes"].includes(String(menu.name)) ? "light" @@ -127,6 +143,12 @@ const changePage = (menu: RouteRecordRaw) => { const filterMenus = (menus: any[]) => { return menus.filter((d) => d.meta && !d.meta.notShow); }; +async function getVersion() { + const res = await appStore.fetchVersion(); + if (res.errors) { + ElMessage.error(res.errors); + } +} diff --git a/src/locales/lang/en.ts b/src/locales/lang/en.ts index 26dc9d19..08cf4bbf 100644 --- a/src/locales/lang/en.ts +++ b/src/locales/lang/en.ts @@ -23,7 +23,6 @@ const msg = { serviceMesh: "Service Mesh", infrastructure: "Infrastructure", virtualMachine: "Virtual Machine", - kubernetes: "Kubernetes", dashboardNew: "New Dashboard", dashboardList: "Dashboard List", logs: "Logs", @@ -123,6 +122,9 @@ const msg = { viewWarning: "You are entering view mode", virtualDatabase: "Virtual Database", reloadDashboards: "Reload dashboards", + kubernetesService: "Service", + kubernetesCluster: "Cluster", + kubernetes: "Kubernetes", hourTip: "Select Hour", minuteTip: "Select Minute", secondTip: "Select Second", @@ -304,7 +306,7 @@ const msg = { keywordsOfContentLogTips: "Current storage of SkyWalking OAP server does not support this.", setEvent: "Set Event", - instanceAttributes: "Instance Attributes", + viewAttributes: "View Attributes", serviceEvents: "Service Events", select: "Select", eventID: "Event ID", diff --git a/src/locales/lang/zh.ts b/src/locales/lang/zh.ts index f8702996..3b01a719 100644 --- a/src/locales/lang/zh.ts +++ b/src/locales/lang/zh.ts @@ -22,7 +22,6 @@ const msg = { serviceMesh: "服务网格", infrastructure: "基础结构", virtualMachine: "虚拟机", - kubernetes: "Kubernetes", dashboardNew: "新建仪表板", dashboardHome: "仪表盘首页", dashboardList: "仪表盘列表", @@ -123,6 +122,9 @@ const msg = { viewWarning: "你正在进入预览模式", virtualDatabase: "虚拟数据库", reloadDashboards: "重新加载仪表盘", + kubernetesService: "服务", + kubernetesCluster: "集群", + kubernetes: "Kubernetes", hourTip: "选择小时", minuteTip: "选择分钟", secondTip: "选择秒数", @@ -303,7 +305,7 @@ const msg = { "只有core/default/searchableLogsTags中定义的标记才可搜索。查看配置词汇表页面上的更多详细信息。", keywordsOfContentLogTips: "SkyWalking OAP服务器的当前存储不支持此操作", setEvent: "设置事件", - instanceAttributes: "实例属性", + viewAttributes: "实例属性", serviceEvents: "服务事件", select: "选择", eventID: "事件ID", diff --git a/src/router/index.ts b/src/router/index.ts index 2102c00e..da15693d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -26,11 +26,13 @@ import { routesAlarm } from "./alarm"; import { routesSelf } from "./selfObservability"; import { routesFunctions } from "./functions"; import { routesBrowser } from "./browser"; +import { routesK8s } from "./k8s"; const routes: Array = [ ...routesGen, ...routesMesh, ...routesFunctions, + ...routesK8s, ...routesInfra, ...routesBrowser, ...routesDatabase, diff --git a/src/router/infrastructure.ts b/src/router/infrastructure.ts index 8a2783c7..c3c11dfe 100644 --- a/src/router/infrastructure.ts +++ b/src/router/infrastructure.ts @@ -38,14 +38,6 @@ export const routesInfra: Array = [ }, component: () => import("@/views/Layer.vue"), }, - { - path: "/kubernetes", - name: "Kubernetes", - meta: { - title: "kubernetes", - }, - component: () => import("@/views/Layer.vue"), - }, // { // path: "/infrastructure/vm", // name: "VirtualMachine", diff --git a/src/router/k8s.ts b/src/router/k8s.ts new file mode 100644 index 00000000..1e7bf0b8 --- /dev/null +++ b/src/router/k8s.ts @@ -0,0 +1,50 @@ +/** + * 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 { RouteRecordRaw } from "vue-router"; +import Layout from "@/layout/Index.vue"; + +export const routesK8s: Array = [ + { + path: "", + name: "Kubernetes", + meta: { + title: "kubernetes", + icon: "donut_small", + hasGroup: true, + }, + redirect: "/kubernetes/cluster", + component: Layout, + children: [ + { + path: "/kubernetes/cluster", + name: "KubernetesCluster", + meta: { + title: "kubernetesCluster", + }, + component: () => import("@/views/Layer.vue"), + }, + { + path: "/kubernetes/service", + name: "KubernetesService", + meta: { + title: "kubernetesService", + }, + component: () => import("@/views/Layer.vue"), + }, + ], + }, +]; diff --git a/src/store/modules/app.ts b/src/store/modules/app.ts index c19bf552..8c320e97 100644 --- a/src/store/modules/app.ts +++ b/src/store/modules/app.ts @@ -32,6 +32,7 @@ interface AppState { timer: Nullable; autoRefresh: boolean; pageTitle: string; + version: string; } export const appStore = defineStore({ @@ -49,6 +50,7 @@ export const appStore = defineStore({ timer: null, autoRefresh: false, pageTitle: "", + version: "", }), getters: { duration(): Duration { @@ -155,6 +157,16 @@ export const appStore = defineStore({ return res.data; }, + async fetchVersion(): Promise { + const res: AxiosResponse = await graphql + .query("queryOAPVersion") + .params({}); + if (res.data.errors) { + return res.data; + } + this.version = res.data.data.version; + return res.data; + }, }, }); export function useAppStoreWithOut(): any { diff --git a/src/store/modules/log.ts b/src/store/modules/log.ts index ef1e97bc..a4d93ca3 100644 --- a/src/store/modules/log.ts +++ b/src/store/modules/log.ts @@ -65,15 +65,15 @@ export const logStore = defineStore({ if (res.data.errors) { return res.data; } - this.services = [ - { value: "0", label: "All" }, - ...res.data.data.services, - ] || [{ value: "0", label: "All" }]; + this.services = res.data.data.services; return res.data; }, - async getInstances() { + async getInstances(id: string) { + const serviceId = this.selectorStore.currentService + ? this.selectorStore.currentService.id + : id; const res: AxiosResponse = await graphql.query("queryInstances").params({ - serviceId: this.selectorStore.currentService.id, + serviceId, duration: this.durationTime, }); @@ -86,9 +86,12 @@ export const logStore = defineStore({ ] || [{ value: " 0", label: "All" }]; return res.data; }, - async getEndpoints() { + async getEndpoints(id: string) { + const serviceId = this.selectorStore.currentService + ? this.selectorStore.currentService.id + : id; const res: AxiosResponse = await graphql.query("queryEndpoints").params({ - serviceId: this.selectorStore.currentService.id, + serviceId, duration: this.durationTime, keyword: "", }); diff --git a/src/store/modules/profile.ts b/src/store/modules/profile.ts index ccca3d56..10f9e308 100644 --- a/src/store/modules/profile.ts +++ b/src/store/modules/profile.ts @@ -82,10 +82,7 @@ export const profileStore = defineStore({ if (res.data.errors) { return res.data; } - this.services = [ - { value: "0", label: "All" }, - ...res.data.data.services, - ] || [{ value: "0", label: "All" }]; + this.services = res.data.data.services; return res.data; }, async getTaskList() { diff --git a/src/store/modules/trace.ts b/src/store/modules/trace.ts index 8fe7aafe..695865f7 100644 --- a/src/store/modules/trace.ts +++ b/src/store/modules/trace.ts @@ -80,15 +80,15 @@ export const traceStore = defineStore({ if (res.data.errors) { return res.data; } - this.services = [ - { value: "0", label: "All" }, - ...res.data.data.services, - ] || [{ value: "0", label: "All" }]; + this.services = res.data.data.services; return res.data; }, - async getInstances() { + async getInstances(id: string) { + const serviceId = this.selectorStore.currentService + ? this.selectorStore.currentService.id + : id; const res: AxiosResponse = await graphql.query("queryInstances").params({ - serviceId: this.selectorStore.currentService.id, + serviceId: serviceId, duration: this.durationTime, }); @@ -101,9 +101,12 @@ export const traceStore = defineStore({ ] || [{ value: " 0", label: "All" }]; return res.data; }, - async getEndpoints() { + async getEndpoints(id: string) { + const serviceId = this.selectorStore.currentService + ? this.selectorStore.currentService.id + : id; const res: AxiosResponse = await graphql.query("queryEndpoints").params({ - serviceId: this.selectorStore.currentService.id, + serviceId, duration: this.durationTime, keyword: "", }); diff --git a/src/views/Layer.vue b/src/views/Layer.vue index 16ef43f3..71dbb62f 100644 --- a/src/views/Layer.vue +++ b/src/views/Layer.vue @@ -35,7 +35,7 @@ const dashboardStore = useDashboardStore(); const routesMap: { [key: string]: string } = { GeneralServices: "GENERAL", Database: "VIRTUAL_DATABASE", - MESH: "MESH", + MeshServices: "MESH", ControlPanel: "MESH_CP", DataPanel: "MESH_DP", Linux: "OS_LINUX", @@ -43,7 +43,8 @@ const routesMap: { [key: string]: string } = { Satellite: "SO11Y_SATELLITE", Functions: "FAAS", Browser: "BROWSER", - Kubernetes: "K8S", + KubernetesCluster: "K8S", + KubernetesService: "K8S_SERVICE", }; const layer = ref("GENERAL"); @@ -51,6 +52,7 @@ 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/List.vue b/src/views/dashboard/List.vue index 8cd9fc3d..3ad81053 100644 --- a/src/views/dashboard/List.vue +++ b/src/views/dashboard/List.vue @@ -203,6 +203,9 @@ async function importTemplates(event: any) { dashboardFile.value = null; } function exportTemplates() { + if (!multipleSelection.value.length) { + return; + } const arr = multipleSelection.value.sort( (a: DashboardItem, b: DashboardItem) => { return a.name.localeCompare(b.name); diff --git a/src/views/dashboard/configuration/Widget.vue b/src/views/dashboard/configuration/Widget.vue index e3f45822..57c1184c 100644 --- a/src/views/dashboard/configuration/Widget.vue +++ b/src/views/dashboard/configuration/Widget.vue @@ -37,8 +37,9 @@ limitations under the License. --> metrics: dashboardStore.selectedGrid.metrics, metricTypes: dashboardStore.selectedGrid.metricTypes, standard: dashboardStore.selectedGrid.standard, - isEdit: true, }" + :isEdit="isEdit" + @changeOpt="setStatus" />
{{ t("noData") }} @@ -51,7 +52,11 @@ limitations under the License. --> :style="{ '--el-collapse-header-font-size': '15px' }" > - + @@ -85,6 +90,7 @@ 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", @@ -101,6 +107,7 @@ export default defineComponent({ const dashboardStore = useDashboardStore(); const appStoreWithOut = useAppStoreWithOut(); const loading = ref(false); + const isEdit = ref(false); const states = reactive<{ activeNames: string; source: unknown; @@ -123,8 +130,13 @@ export default defineComponent({ } function applyConfig() { - dashboardStore.setConfigs(dashboardStore.selectedGrid); dashboardStore.setConfigPanel(false); + setStatus(); + dashboardStore.setConfigs(dashboardStore.selectedGrid); + } + + function setStatus() { + isEdit.value = true; } function cancelConfig() { @@ -143,6 +155,8 @@ export default defineComponent({ cancelConfig, getSource, setLoading, + setStatus, + isEdit, }; }, }); diff --git a/src/views/dashboard/configuration/widget/MetricOptions.vue b/src/views/dashboard/configuration/widget/MetricOptions.vue index 7e6bc992..0e399f33 100644 --- a/src/views/dashboard/configuration/widget/MetricOptions.vue +++ b/src/views/dashboard/configuration/widget/MetricOptions.vue @@ -13,15 +13,16 @@ 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. --> - - -
+ + + diff --git a/src/views/dashboard/panel/Tool.vue b/src/views/dashboard/panel/Tool.vue index d2bcf284..9c9e55c3 100644 --- a/src/views/dashboard/panel/Tool.vue +++ b/src/views/dashboard/panel/Tool.vue @@ -127,6 +127,7 @@ const params = useRoute().params; const toolIcons = ref<{ name: string; content: string; id: string }[]>( EndpointRelationTools ); +const limit = ref(10); const loading = ref(false); const states = reactive<{ destService: string; @@ -401,7 +402,7 @@ async function fetchPods(type: string, serviceId: string, setPod: boolean) { let resp; switch (type) { case EntityType[2].value: - resp = await selectorStore.getEndpoints({ serviceId }); + resp = await selectorStore.getEndpoints({ serviceId, limit }); if (setPod) { selectorStore.setCurrentPod( selectorStore.pods.length ? selectorStore.pods[0] : null @@ -419,7 +420,11 @@ async function fetchPods(type: string, serviceId: string, setPod: boolean) { } break; case EntityType[6].value: - resp = await selectorStore.getEndpoints({ serviceId, isRelation: true }); + resp = await selectorStore.getEndpoints({ + serviceId, + isRelation: true, + limit, + }); if (setPod) { selectorStore.setCurrentDestPod( selectorStore.destPods.length ? selectorStore.destPods[0] : null diff --git a/src/views/dashboard/related/components/LogTable/Index.vue b/src/views/dashboard/related/components/LogTable/Index.vue index e70707b8..c6d6fd90 100644 --- a/src/views/dashboard/related/components/LogTable/Index.vue +++ b/src/views/dashboard/related/components/LogTable/Index.vue @@ -114,6 +114,7 @@ function setCurrentLog(log: any) { } .serviceInstanceName, + .endpointName, .serviceName { width: 200px; } diff --git a/src/views/dashboard/related/components/LogTable/LogService.vue b/src/views/dashboard/related/components/LogTable/LogService.vue index 3f94af0f..c91b1efe 100644 --- a/src/views/dashboard/related/components/LogTable/LogService.vue +++ b/src/views/dashboard/related/components/LogTable/LogService.vue @@ -82,6 +82,7 @@ function showSelectSpan() { } .serviceInstanceName, + .endpointName, .serviceName { width: 200px; } @@ -98,6 +99,7 @@ function showSelectSpan() { border: 1px solid transparent; border-right: 1px dotted silver; overflow: hidden; + height: 30px; line-height: 30px; text-overflow: ellipsis; white-space: nowrap; diff --git a/src/views/dashboard/related/components/LogTable/data.ts b/src/views/dashboard/related/components/LogTable/data.ts index 9ddd3c50..58009b25 100644 --- a/src/views/dashboard/related/components/LogTable/data.ts +++ b/src/views/dashboard/related/components/LogTable/data.ts @@ -24,6 +24,10 @@ export const ServiceLogConstants = [ label: "serviceInstanceName", value: "instance", }, + { + label: "endpointName", + value: "endpoint", + }, { label: "timestamp", value: "time", diff --git a/src/views/dashboard/related/log/Header.vue b/src/views/dashboard/related/log/Header.vue index 71d6d922..be71bc07 100644 --- a/src/views/dashboard/related/log/Header.vue +++ b/src/views/dashboard/related/log/Header.vue @@ -143,7 +143,7 @@ const isBrowser = ref(dashboardStore.layerId === "BROWSER"); const state = reactive({ instance: { value: "0", label: "All" }, endpoint: { value: "0", label: "All" }, - service: { value: "0", label: "All" }, + service: { value: "", label: "" }, }); init(); @@ -154,11 +154,10 @@ async function init() { ElMessage.error(resp.errors); return; } + await fetchSelectors(); + await searchLogs(); state.instance = { value: "0", label: "All" }; state.endpoint = { value: "0", label: "All" }; - state.service = { value: "0", label: "All" }; - searchLogs(); - fetchSelectors(); } function fetchSelectors() { @@ -187,18 +186,20 @@ async function getServices() { return; } state.service = logStore.services[0]; + getInstances(state.service.id); + getEndpoints(state.service.id); } -async function getEndpoints() { - const resp = await logStore.getEndpoints(); +async function getEndpoints(id?: string) { + const resp = await logStore.getEndpoints(id); if (resp.errors) { ElMessage.error(resp.errors); return; } state.endpoint = logStore.endpoints[0]; } -async function getInstances() { - const resp = await logStore.getInstances(); +async function getInstances(id?: string) { + const resp = await logStore.getInstances(id); if (resp.errors) { ElMessage.error(resp.errors); return; @@ -238,8 +239,8 @@ async function queryLogs() { function changeField(type: string, opt: any) { state[type] = opt[0]; if (type === "service") { - getEndpoints(); - getInstances(); + getEndpoints(state.service.id); + getInstances(state.service.id); } } function updateTags(data: { tagsMap: Array