feat: open dashboards with selector ids of link url

This commit is contained in:
Qiuxia Fan 2022-01-24 18:31:33 +08:00
parent 21fb053bda
commit e314f45874
13 changed files with 177 additions and 47 deletions

View File

@ -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>
<router-view />
<router-view :key="$route.fullPath" />
</template>
<style>

View File

@ -59,3 +59,49 @@ export const Endpoints = {
}
`,
};
export const getService = {
variable: "$serviceId: String!",
query: `
service: getService(serviceId: $serviceId) {
id
value: name
label: name
group
layers
normal
}
`,
};
export const getInstance = {
variable: "$instanceId: String!",
query: `
instance: getInstance(instanceId: $instanceId) {
id
value: name
label: name
language
instanceUUID
layer
attributes {
name
value
}
}
`,
};
export const getEndpoint = {
variable: "$endpointId: String!",
query: `
endpoint: getEndpointInfo(endpointId: $endpointId) {
id
value: name
label: name
serviceId
serviceName
}
}
`,
};

View File

@ -14,10 +14,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Services, Layers, Endpoints, Instances } from "../fragments/selector";
import {
Services,
Layers,
Endpoints,
Instances,
getService,
getInstance,
getEndpoint,
} from "../fragments/selector";
export const queryServices = `query queryServices(${Services.variable}) {${Services.query}}`;
export const queryEndpoints = `query queryEndpoints(${Endpoints.variable}) {${Endpoints.query}}`;
export const queryInstances = `query queryInstances(${Instances.variable}) {${Instances.query}}`;
export const queryLayers = `query listLayer {${Layers.query}}`;
export const queryService = `query queryService(${getService.variable}) {${getService.query}}`;
export const queryInstance = `query queryInstance(${getInstance.variable}) {${getInstance.query}}`;
export const queryEndpoint = `query queryInstance(${getEndpoint.variable}) {${getEndpoint.query}}`;

View File

@ -28,6 +28,9 @@ export function useQueryProcessor(config: any) {
const appStore = useAppStoreWithOut();
const dashboardStore = useDashboardStore();
const selectorStore = useSelectorStore();
if (!selectorStore.currentService) {
return;
}
const conditions: { [key: string]: unknown } = {
duration: appStore.durationTime,
};
@ -76,10 +79,10 @@ export function useQueryProcessor(config: any) {
? undefined
: selectorStore.currentService.normal,
serviceInstanceName: dashboardStore.entity.includes("ServiceInstance")
? selectorStore.currentPod
? selectorStore.currentPod.value
: undefined,
endpointName: dashboardStore.entity.includes("Endpoint")
? selectorStore.currentPod
? selectorStore.currentPod.value
: undefined,
destNormal: isRelation
? selectorStore.currentDestService.normal
@ -89,11 +92,11 @@ export function useQueryProcessor(config: any) {
: undefined,
destServiceInstanceName:
dashboardStore.entity === "ServiceInstanceRelation"
? selectorStore.currentDestPod
? selectorStore.currentDestPod.value
: undefined,
destEndpointName:
dashboardStore.entity === "EndpointRelation"
? selectorStore.currentDestPod
? selectorStore.currentDestPod.value
: undefined,
},
};

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. -->
<template>
<section class="app-main">
<router-view v-slot="{ Component }">
<router-view v-slot="{ Component }" :key="$route.fullPath">
<keep-alive>
<component :is="Component" />
</keep-alive>

View File

@ -15,8 +15,8 @@
* limitations under the License.
*/
import { defineStore } from "pinia";
import { Option, Duration } from "@/types/app";
import { Service } from "@/types/selector";
import { Duration } from "@/types/app";
import { Service, Instance, Endpoint } from "@/types/selector";
import { store } from "@/store";
import graph from "@/graph";
import { AxiosResponse } from "axios";
@ -24,13 +24,11 @@ import { useAppStoreWithOut } from "@/store/modules/app";
interface SelectorState {
services: Service[];
instances: Option[];
pods: Option[];
endpoints: Option[];
pods: Array<Instance | Endpoint>;
currentService: Nullable<Service>;
currentPod: string;
currentPod: Nullable<Instance | Endpoint>;
currentDestService: Nullable<Service>;
currentDestPod: string;
currentDestPod: Nullable<Instance | Endpoint>;
durationTime: Duration;
}
@ -38,20 +36,18 @@ export const selectorStore = defineStore({
id: "selector",
state: (): SelectorState => ({
services: [],
instances: [],
pods: [],
endpoints: [],
currentService: null,
currentPod: "",
currentPod: null,
currentDestService: null,
currentDestPod: "",
currentDestPod: null,
durationTime: useAppStoreWithOut().durationTime,
}),
actions: {
setCurrentService(service: Service) {
this.currentService = service;
},
setCurrentPod(pod: string) {
setCurrentPod(pod: Nullable<Instance | Endpoint>) {
this.currentPod = pod;
},
async fetchLayers(): Promise<AxiosResponse> {
@ -82,9 +78,8 @@ export const selectorStore = defineStore({
duration: this.durationTime,
});
if (!res.data.errors) {
this.instances = res.data.data.pods || [];
this.pods = this.instances;
this.currentPod = this.pods.length ? this.pods[0].value : "";
this.pods = res.data.data.pods || [];
this.currentPod = this.pods.length ? this.pods[0] : null;
}
return res.data;
},
@ -108,12 +103,50 @@ export const selectorStore = defineStore({
keyword: params.keyword,
});
if (!res.data.errors) {
this.endpoints = res.data.data.pods || [];
this.pods = this.endpoints;
this.currentPod = this.pods.length ? this.pods[0].value : "";
this.pods = res.data.data.pods || [];
this.currentPod = this.pods.length ? this.pods[0] : null;
}
return res.data;
},
async getService(serviceId: string) {
if (!serviceId) {
return;
}
const res: AxiosResponse = await graph.query("queryService").params({
serviceId,
});
if (!res.data.errors) {
this.currentService = res.data.data.service || {};
}
return res.data;
},
async getInstance(instanceId: string) {
if (!instanceId) {
return;
}
const res: AxiosResponse = await graph.query("queryInstance").params({
instanceId,
});
if (!res.data.errors) {
this.currentPod = res.data.data.instance || null;
}
return res.data;
},
async getEndpoint(endpointId: string) {
if (!endpointId) {
return;
}
const res: AxiosResponse = await graph.query("queryEndpoint").params({
endpointId,
});
if (!res.data.errors) {
this.currentPod = res.data.data.endpoint || null;
}
return res.data;
},
},
});

View File

@ -194,9 +194,13 @@ async function queryMetrics() {
}
function changeDashboard(item: Option[]) {
const graph = {
...dashboardStore.selectedGrid.graph,
dashboardName: item[0].value,
};
dashboardStore.selectWidget({
...dashboardStore.selectedGrid,
...{ dashboardName: item[0].value },
graph,
});
}
function addMetric() {

View File

@ -61,6 +61,7 @@ limitations under the License. -->
<script lang="ts">
import { toRefs, reactive, defineComponent, ref, watch } from "vue";
import type { PropType } from "vue";
import { useRoute } from "vue-router";
import { LayoutConfig } from "@/types/dashboard";
import { useDashboardStore } from "@/store/modules/dashboard";
import { useAppStoreWithOut } from "@/store/modules/app";
@ -82,6 +83,7 @@ export default defineComponent({
props,
setup(props) {
const { t } = useI18n();
const params = useRoute().params;
const loading = ref<boolean>(false);
const state = reactive<{ source: { [key: string]: unknown } }>({
source: {},
@ -91,6 +93,10 @@ export default defineComponent({
const dashboardStore = useDashboardStore();
const selectorStore = useSelectorStore();
if (params.serviceId) {
queryMetrics();
}
async function queryMetrics() {
const params = await useQueryProcessor(props.data);
if (!params) {

View File

@ -39,7 +39,7 @@ limitations under the License. -->
<router-link
target="_blank"
class="link"
:to="`/dashboard/${scope.row.layer}/endpoint/${selectorStore.currentService.value}/${scope.row.value}/${config.dashboardName}`"
:to="`/dashboard/${scope.row.layer}/Endpoint/${selectorStore.currentService.id}/${scope.row.id}/${config.dashboardName}`"
:style="{ fontSize: `${config.fontSize}px` }"
>
{{ scope.row.label }}
@ -67,7 +67,7 @@ limitations under the License. -->
background
layout="prev, pager, next"
:page-size="pageSize"
:total="selectorStore.endpoints.length"
:total="selectorStore.pods.length"
@current-change="changePage"
@prev-click="changePage"
@next-click="changePage"
@ -115,8 +115,8 @@ async function queryEndpoints() {
ElMessage.error(resp.errors);
return;
}
searchEndpoints.value = selectorStore.endpoints;
endpoints.value = selectorStore.endpoints.splice(0, pageSize);
searchEndpoints.value = selectorStore.pods;
endpoints.value = selectorStore.pods.splice(0, pageSize);
queryEndpointMetrics(endpoints.value);
}
async function queryEndpointMetrics(currentPods: Endpoint[]) {
@ -147,8 +147,8 @@ function changePage(pageIndex: number) {
endpoints.value = searchEndpoints.value.splice(pageIndex - 1, pageSize);
}
function searchList() {
const currentEndpoints = selectorStore.instances.filter(
(d: { label: string }) => d.label.includes(searchText.value)
const currentEndpoints = selectorStore.pods.filter((d: { label: string }) =>
d.label.includes(searchText.value)
);
searchEndpoints.value = currentEndpoints;
endpoints.value = currentEndpoints.splice(0, pageSize);

View File

@ -37,9 +37,8 @@ limitations under the License. -->
<el-table-column label="Service Instances">
<template #default="scope">
<router-link
target="_blank"
class="link"
:to="`/dashboard/${scope.row.layer}/serviceInstance/${selectorStore.currentService.value}/${scope.row.value}/${config.dashboardName}`"
:to="`/dashboard/${scope.row.layer}/ServiceInstance/${selectorStore.currentService.id}/${scope.row.id}/${config.dashboardName}`"
:style="{ fontSize: `${config.fontSize}px` }"
>
{{ scope.row.label }}
@ -96,7 +95,7 @@ defineProps({
const selectorStore = useSelectorStore();
const dashboardStore = useDashboardStore();
const chartLoading = ref<boolean>(false);
const instances = ref<(Instance | any)[]>([]); // current instances
const instances = ref<Instance[]>([]); // current instances
const searchInstances = ref<Instance[]>([]); // all instances
const pageSize = 5;
const searchText = ref<string>("");
@ -112,7 +111,7 @@ async function queryInstance() {
ElMessage.error(resp.errors);
return;
}
searchInstances.value = selectorStore.instances;
searchInstances.value = selectorStore.pods;
const currentInstances = searchInstances.value.splice(0, pageSize);
queryInstanceMetrics(currentInstances);
@ -147,8 +146,8 @@ function changePage(pageIndex: number) {
instances.value = searchInstances.value.splice(pageIndex - 1, pageSize);
}
function searchList() {
searchInstances.value = selectorStore.instances.filter(
(d: { label: string }) => d.label.includes(searchText.value)
searchInstances.value = selectorStore.pods.filter((d: { label: string }) =>
d.label.includes(searchText.value)
);
instances.value = searchInstances.value.splice(0, pageSize);
}

View File

@ -39,7 +39,8 @@ limitations under the License. -->
<router-link
target="_blank"
class="link"
:to="`/dashboard/${scope.row.layer}/service/${selectorStore.currentService.value}/${config.dashboardName}`"
:to="`/dashboard/${scope.row.layer}/Service/${selectorStore.currentService.value}/${config.dashboardName}`"
:key="1"
:style="{ fontSize: `${config.fontSize}px` }"
>
{{ scope.row.label }}
@ -144,8 +145,8 @@ function changePage(pageIndex: number) {
services.value = selectorStore.services.splice(pageIndex - 1, pageSize);
}
function searchList() {
searchServices.value = selectorStore.instances.filter(
(d: { label: string }) => d.label.includes(searchText.value)
searchServices.value = selectorStore.services.filter((d: { label: string }) =>
d.label.includes(searchText.value)
);
services.value = searchServices.value.splice(0, pageSize);
}

View File

@ -16,6 +16,8 @@
*/
.table {
height: 100%;
overflow: auto;
padding: 0 10px 5px 0;
}
.pagination {

View File

@ -14,7 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License. -->
<template>
<div class="dashboard-tool flex-h">
<div class="flex-h" v-if="!params.serviceId">
<div v-if="params.serviceId"></div>
<div class="flex-h" v-else>
<div class="selectors-item" v-if="states.key !== 10">
<span class="label">$Service</span>
<Selector
@ -35,7 +36,7 @@ limitations under the License. -->
}}
</span>
<Selector
v-model="selectorStore.currentPod"
v-model="states.currentPod"
:options="selectorStore.pods"
size="mini"
placeholder="Select a data"
@ -57,7 +58,7 @@ limitations under the License. -->
<div class="selectors-item" v-if="states.key === 4">
<span class="label">$DestinationServiceInstance</span>
<Selector
v-model="selectorStore.currentPod"
v-model="states.currentPod"
:options="selectorStore.pods"
size="mini"
placeholder="Select a data"
@ -96,21 +97,43 @@ import { Service } from "@/types/selector";
const dashboardStore = useDashboardStore();
const selectorStore = useSelectorStore();
const params = useRoute().params;
const type = EntityType.filter((d: Option) => d.value === params.entity)[0];
const states = reactive<{
destService: string;
destPod: string;
key: number;
currentService: string;
currentPod: string;
}>({
destService: "",
destPod: "",
key: EntityType.filter((d: Option) => d.value === params.entity)[0].key || 0,
key: (type && type.key) || 0,
currentService: "",
currentPod: "",
});
dashboardStore.setLayer(String(params.layerId));
dashboardStore.setEntity(String(params.entity));
getServices();
if (params.serviceId) {
setSelector();
} else {
getServices();
}
async function setSelector() {
await selectorStore.getService(String(params.serviceId));
states.currentService = selectorStore.currentService.value;
if (params.podId) {
if (String(params.entity) === EntityType[2].value) {
await selectorStore.getEndpoint(String(params.podId));
}
if (String(params.entity) === EntityType[3].value) {
await selectorStore.getInstance(String(params.podId));
}
states.currentPod = selectorStore.currentPod.label;
}
}
async function getServices() {
if (!dashboardStore.layerId) {
@ -167,15 +190,18 @@ async function fetchPods(type: string) {
switch (type) {
case "Endpoint":
resp = await selectorStore.getEndpoints();
states.currentPod = selectorStore.currentPod.label;
break;
case "ServiceInstance":
resp = await selectorStore.getServiceInstances();
states.currentPod = selectorStore.currentPod.label;
break;
default:
resp = {};
}
if (resp.errors) {
ElMessage.error(resp.errors);
return;
}
}
</script>