set service list

This commit is contained in:
Qiuxia Fan 2022-03-15 11:11:39 +08:00
parent 30fed5c83f
commit 6d5fcbb402
18 changed files with 167 additions and 493 deletions

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
const msg = {
generalService: "General Service",
general: "General Service",
services: "Services",
service: "Service",
traces: "Traces",
@ -96,6 +96,8 @@ const msg = {
taskList: "Task List",
sampledTraces: "Sampled Traces",
editTab: "Enable editing tab names",
label: "Name",
id: "ID",
hourTip: "Select Hour",
minuteTip: "Select Minute",
secondTip: "Select Second",
@ -234,7 +236,7 @@ const msg = {
parentService: "Parent Service",
isParentService: "Set Parent Service",
noneParentService: "No Parent Service",
serviceGroup: "Service Group",
group: "Service Group",
endpointFilter: "Endpoint Filter",
databaseView: "Database",
browserView: "Browser",

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
const msg = {
generalService: "普通服务",
general: "普通服务",
services: "服务",
traces: "跟踪",
metrics: "指标",
@ -96,6 +96,8 @@ const msg = {
taskList: "任务列表",
sampledTraces: "采样的追踪",
editTab: "开启编辑Tab的名称",
label: "名称",
id: "ID",
hourTip: "选择小时",
minuteTip: "选择分钟",
secondTip: "选择秒数",
@ -236,7 +238,7 @@ const msg = {
parentService: "父级服务",
isParentService: "设置父服务",
noneParentService: "不设置父服务",
serviceGroup: "服务组",
group: "服务组",
endpointFilter: "端点过滤器",
databaseView: "数据库视图",
browserView: "浏览器视图",

View File

@ -36,17 +36,7 @@ export const routesDatabase: Array<RouteRecordRaw> = [
headPath: "/database",
exact: true,
},
component: () => import("@/views/service/Service.vue"),
},
{
path: "/database/:id/:type",
name: "DatabasePanel",
meta: {
title: "databasePanel",
headPath: "/database",
exact: true,
},
component: () => import("@/views/service/Panel.vue"),
component: () => import("@/views/Service.vue"),
},
],
},

View File

@ -20,9 +20,9 @@ import Layout from "@/layout/Index.vue";
export const routesGen: Array<RouteRecordRaw> = [
{
path: "",
name: "GeneralService",
name: "General",
meta: {
title: "generalService",
title: "general",
icon: "chart",
hasGroup: false,
exact: true,
@ -30,24 +30,14 @@ export const routesGen: Array<RouteRecordRaw> = [
component: Layout,
children: [
{
path: "/generalService",
name: "Services",
path: "/general",
name: "GeneralServices",
meta: {
title: "services",
headPath: "/generalService/service",
headPath: "/general/service",
exact: true,
},
component: () => import("@/views/service/Service.vue"),
},
{
path: "/generalService/service/:id/:type",
name: "GeneralServicePanel",
meta: {
title: "generalServicePanel",
headPath: "/generalService/service",
exact: true,
},
component: () => import("@/views/service/Panel.vue"),
component: () => import("@/views/Service.vue"),
},
],
},

View File

@ -52,7 +52,7 @@ router.beforeEach((to, from, next) => {
(window as any).axiosCancel = [];
}
if (to.path === "/") {
next({ path: "/generalService" });
next({ path: "/general" });
} else {
next();
}

View File

@ -36,7 +36,7 @@ export const routesMesh: Array<RouteRecordRaw> = [
title: "services",
headPath: "/mesh/services",
},
component: () => import("@/views/service/Service.vue"),
component: () => import("@/views/Service.vue"),
},
{
path: "/mesh/controlPanel",
@ -45,7 +45,7 @@ export const routesMesh: Array<RouteRecordRaw> = [
title: "controlPanel",
headPath: "/mesh/controlPanel",
},
component: () => import("@/views/service/Service.vue"),
component: () => import("@/views/Service.vue"),
},
{
path: "/mesh/dataPanel",
@ -54,40 +54,7 @@ export const routesMesh: Array<RouteRecordRaw> = [
title: "dataPanel",
headPath: "/mesh/dataPanel",
},
component: () => import("@/views/service/Service.vue"),
},
{
path: "/mesh/services/:id/:type",
name: "MeshServicePanel",
meta: {
title: "meshServicePanel",
headPath: "/mesh/services",
exact: true,
notShow: true,
},
component: () => import("@/views/service/Panel.vue"),
},
{
path: "/mesh/controlPanel/:id/:type",
name: "MeshControlPanel",
meta: {
title: "controlPanel",
headPath: "/mesh/controlPanel",
exact: true,
notShow: true,
},
component: () => import("@/views/service/Panel.vue"),
},
{
path: "/mesh/dataPanel/:id/:type",
name: "MeshDataPanel",
meta: {
title: "dataPanel",
headPath: "/mesh/dataPanel",
exact: true,
notShow: true,
},
component: () => import("@/views/service/Panel.vue"),
component: () => import("@/views/Service.vue"),
},
],
},

View File

@ -317,9 +317,8 @@ export const dashboardStore = defineStore({
layer: c.layer,
entity: c.entity,
name: c.name,
date: c.date,
isRoot: c.isRoot,
});
console.log(key);
sessionStorage.setItem(key, JSON.stringify(t));
}
sessionStorage.setItem("dashboards", JSON.stringify(list));

144
src/views/Service.vue Normal file
View File

@ -0,0 +1,144 @@
<!-- 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="service-table">
<el-table :data="selectorStore.services" :border="true">
<el-table-column
v-for="(h, index) in tableHeader"
:label="t(h)"
:key="h + index"
>
<template #default="scope">
<span
v-if="h === tableHeader[1] && index !== 0"
class="service-name cp"
@click="visitLayout(scope.row)"
>
{{ scope.row[h] }}
</span>
<span v-else>{{ scope.row[h] }}</span>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script lang="ts" setup>
import { ref, watch } from "vue";
import { useI18n } from "vue-i18n";
import { useRoute } from "vue-router";
import { ElTable, ElTableColumn } from "element-plus";
import { useSelectorStore } from "@/store/modules/selectors";
import { ElMessage } from "element-plus";
import { EntityType } from "./dashboard/data";
import { useDashboardStore } from "@/store/modules/dashboard";
import { useAppStoreWithOut } from "@/store/modules/app";
import router from "@/router";
const route = useRoute();
const { t } = useI18n();
const appStore = useAppStoreWithOut();
const dashboardStore = useDashboardStore();
const selectorStore = useSelectorStore();
const tableHeader = ["group", "label", "id"];
const path = [
"GeneralServices",
"Database",
"MeshServices",
"ControlPanel",
"DataPanel",
];
const dashboards = ref<
{ name: string; layer: string; entity: string; isRoot: boolean }[]
>([]);
const layer = ref<string>("GENERAL");
getServices();
setList();
async function setList() {
if (!sessionStorage.getItem("dashboards")) {
const res = await dashboardStore.fetchTemplates();
if (res.errors) {
dashboards.value = [];
ElMessage.error(res.errors);
return;
}
}
dashboards.value = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
}
async function getServices() {
setLayer(String(route.name));
const res = selectorStore.fetchServices(layer.value);
if (res.errors) {
ElMessage.error(res.errors);
}
}
function visitLayout(row: { id: string }) {
const l =
dashboards.value.filter(
(d: { name: string; isRoot: boolean; layer: string; entity: string }) =>
d.layer === layer.value && d.entity === EntityType[0].value && d.isRoot
)[0] || {};
router.push(
`/dashboard/${layer.value}/${EntityType[0].value}/${row.id}/${l.name
.split(" ")
.join("-")}`
);
}
function setLayer(p: string) {
switch (p) {
case path[0]:
layer.value = "GENERAL";
break;
case path[1]:
layer.value = "VIRTUAL_DATABASE";
break;
case path[2]:
layer.value = "MESH";
break;
case path[3]:
layer.value = "MESH_CP";
break;
case path[4]:
layer.value = "MESH_DP";
break;
default:
layer.value = "GENERAL";
break;
}
appStore.setPageTitle(layer.value);
}
watch(
() => route.name,
(name: unknown) => {
if (!name) {
return;
}
getServices();
}
);
</script>
<style lang="scss" scoped>
.service-name {
color: #448edf;
cursor: pointer;
}
.service-table {
padding: 15px;
}
</style>

View File

@ -95,7 +95,7 @@ appStore.setPageTitle("Dashboard List");
// # - browser
// # - skywalking
const { t } = useI18n();
const dashboards = ref<any[]>([]);
const dashboards = ref<{ name: string; layer: string; entity: string }[]>([]);
const searchText = ref<string>("");
setList();

View File

@ -177,7 +177,8 @@ async function setSelector() {
selectorStore.setCurrentService(currentService);
selectorStore.setCurrentDestService(currentDestService);
states.currentService = selectorStore.currentService.value;
states.currentDestService = selectorStore.currentDestService.value;
states.currentDestService =
selectorStore.currentDestService && selectorStore.currentDestService.value;
}
async function setSourceSelector() {

View File

@ -1,23 +0,0 @@
<!-- 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="enpoints">This is a enpoint page</div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
div {
padding: 15px;
}
</style>

View File

@ -1,24 +0,0 @@
<!-- 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>This is the Metrics page</div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
div {
padding: 15px;
text-align: center;
}
</style>

View File

@ -1,110 +0,0 @@
<!-- 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="service-detail">
<div class="title">
<span>{{ state.serviceID }}</span>
<span>Types</span>
<span>Technologies</span>
</div>
<div class="tabs">
<router-link
class="tab cp"
v-for="tab in tabs"
:key="tab"
@click="handleClick(tab)"
:class="{ active: tab === activeName }"
:to="`${state.path}/${state.serviceID}/${tab}`"
>
{{ t(tab) }}
</router-link>
</div>
<Endpoints v-if="state.type === tabs[2]" />
<Metrics v-else-if="state.type === tabs[0]" />
<Topology
v-else-if="state.type === tabs[1]"
msg="This is the Topology page"
/>
<Traces v-else-if="state.type === tabs[3]" msg="This is the Trace page" />
<Profiles v-else msg="This is the Profiles page" />
</div>
</template>
<script lang="ts" setup>
import { ref, reactive } from "vue";
import { useI18n } from "vue-i18n";
import { useRoute } from "vue-router";
import Metrics from "./Metrics.vue";
import Endpoints from "./Endpoints.vue";
import Topology from "./Topology.vue";
import Traces from "./Traces.vue";
import Profiles from "./Profiles.vue";
import { useAppStoreWithOut } from "@/store/modules/app";
const appStore = useAppStoreWithOut();
appStore.setPageTitle("General Service");
const route = useRoute();
const { t } = useI18n();
const tabs = ["metrics", "topologies", "endpoints", "traces", "profiles"];
const activeName = ref<string>(tabs[0]);
const state = reactive({
serviceID: route.params.id,
type: route.params.type,
path: route.meta.headPath,
});
function handleClick(tab: string) {
activeName.value = tab;
state.type = tab;
}
</script>
<style lang="scss" scoped>
.service-detail {
text-align: left;
}
.tabs {
padding: 15px 15px 0 15px;
border-bottom: 1px solid var(--el-border-color-light);
}
.tab {
display: inline-block;
margin-right: 30px;
font-size: 13px;
font-weight: 400;
height: 30px;
&:hover {
color: var(--el-color-primary);
}
&.active {
color: var(--el-color-primary);
border-bottom: 1px solid var(--el-color-primary);
}
}
.title {
padding: 5px 0 5px 15px;
font-size: 14px;
font-weight: 400;
border-bottom: 1px solid #dfe4e8;
background-color: #c4c8e133;
span {
display: inline-block;
margin-right: 10px;
}
}
</style>

View File

@ -1,31 +0,0 @@
<!-- 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>{{ msg }}</div>
</template>
<script lang="ts" setup>
/*global defineProps */
defineProps({
msg: { type: String },
});
// props.msg
</script>
<style scoped>
div {
padding: 15px;
}
</style>

View File

@ -1,131 +0,0 @@
<!-- 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="service-table">
<el-table :data="tableData" :span-method="objectSpanMethod" border>
<el-table-column
v-for="(h, index) in tableHeader"
:label="t(h)"
:key="h + index"
>
<template #default="scope">
<router-link
:to="`${state.path}/${scope.row.serviceName}/metrics`"
v-if="h === tableHeader[1] && index !== 0"
>
<span class="service-name cp">{{ scope.row[h] }}</span>
</router-link>
<span v-else>{{ scope.row[h] }}</span>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script lang="ts" setup>
import { reactive, watch } from "vue";
import { useI18n } from "vue-i18n";
import { useRoute } from "vue-router";
import { ElTable, ElTableColumn } from "element-plus";
const route = useRoute();
const { t } = useI18n();
const tableHeader = [
"groupName",
"serviceName",
"types",
"technologies",
"endpoints",
"health",
];
const tableData = [
{
endpoints: 2,
groupName: "group 1",
serviceName: "discount",
types: "HTTP",
health: true,
technologies: "Spring Boot",
},
{
endpoints: 3,
groupName: "group 1",
serviceName: "frontend",
types: "HTTP",
health: true,
technologies: "Node.js",
},
{
endpoints: 3,
groupName: "group 2",
serviceName: "web",
types: "",
health: true,
technologies: "Nginx",
},
{
endpoints: 3,
groupName: "group 2",
serviceName: "shipping",
types: "HTTP",
health: true,
technologies: "JVM",
},
{
endpoints: 3,
groupName: "group 3",
serviceName: "payment",
types: "HTTP MESSAGING",
health: true,
technologies: "RabbitMQ Python",
},
];
const state = reactive({
path: route.meta.headPath,
});
const objectSpanMethod = (item: { columnIndex: number; rowIndex: number }) => {
if (item.columnIndex === 0) {
if (item.rowIndex % 2 === 0) {
return {
rowspan: 2,
colspan: 1,
};
} else {
return {
rowspan: 0,
colspan: 0,
};
}
}
};
watch(
() => route.meta.headPath,
(path: unknown) => {
if (!path) {
return;
}
state.path = path;
}
);
</script>
<style lang="scss" scoped>
.service-name {
color: #448edf;
cursor: pointer;
}
.service-table {
padding: 15px;
}
</style>

View File

@ -1,30 +0,0 @@
<!-- 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>Topology</div>
</template>
<script lang="ts" setup>
/*global defineProps */
defineProps({
msg: { type: String },
});
// props.msg
</script>
<style scoped>
div {
padding: 15px;
}
</style>

View File

@ -1,31 +0,0 @@
<!-- 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>Traces</div>
</template>
<script lang="ts" setup>
/*global defineProps */
defineProps({
msg: { type: String },
});
// props.msg
</script>
<style scoped>
div {
padding: 15px;
}
</style>

View File

@ -1,41 +0,0 @@
/**
* 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.
*/
export const TabsConfig: { [key: string]: any } = {
GeneralService: [
{ name: "metrics", path: "/generalService/metrics" },
{ name: "traces", path: "/generalService/traces" },
{ name: "profiles", path: "/generalService/profiles" },
{ name: "services", path: "/generalService" },
],
ServiceMesh: [
{ name: "services", path: "/serviceMesh" },
{ name: "metrics", path: "/serviceMesh/metrics" },
{ name: "traces", path: "/serviceMesh/traces" },
{ name: "profiles", path: "/serviceMesh/profiles" },
],
};
export const PagesConfig = [
{ label: "generalService", name: "GeneralService" },
{ label: "serviceMesh", name: "ServiceMesh" },
{ label: "virtualMachine", name: "VirtualMachine" },
{ label: "dashboardHome", name: "DashboardHome" },
{ label: "dashboardList", name: "DashboardList" },
{ label: "logs", name: "Logs" },
{ label: "settings", name: "Settings" },
{ label: "events", name: "Events" },
{ label: "alerts", name: "Alerts" },
];