feat: Support searching endpoints with keyword (#43)

This commit is contained in:
Fine0830 2022-03-28 18:07:09 +08:00 committed by GitHub
parent d78ca0cd4b
commit 0a29a86c34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 200 additions and 151 deletions

View File

@ -1,15 +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. -->
<svg t="1648440420715" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3665" width="32" height="32"><path d="M914.894958 0 109.105042 0c-21.501383 0-38.907264 14.078286-38.907264 31.740136L70.197778 990.855388c0 25.340915 34.811763 40.443077 60.664616 26.108822l350.677314-194.280351c13.054411-7.167128 29.948355-7.423096 43.002765-0.255969l368.851102 196.328102c25.852853 13.822317 60.152678-1.279844 60.152678-26.62076L953.546253 31.740136C953.802222 14.334255 936.39634 0 914.894958 0zM562.681831 746.661113l-101.363662 0-196.328102-547.773322 90.61297 0 155.885025 454.344695 2.30372 0 155.117118-454.344695 90.61297 0L562.681831 746.661113z" p-id="3666" fill="#e6e6e6"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -23,6 +23,9 @@ limitations under the License. -->
:disabled="disabled"
:style="{ borderRadius }"
:clearable="clearable"
:remote="isRemote"
:reserve-keyword="isRemote"
:remote-method="remoteMethod"
>
<el-option
v-for="item in options"
@ -43,7 +46,7 @@ interface Option {
}
/*global defineProps, defineEmits*/
const emit = defineEmits(["change"]);
const emit = defineEmits(["change", "query"]);
const props = defineProps({
options: {
type: Array as PropType<(Option & { disabled: boolean })[]>,
@ -62,6 +65,7 @@ const props = defineProps({
multiple: { type: Boolean, default: false },
disabled: { type: Boolean, default: false },
clearable: { type: Boolean, default: false },
isRemote: { type: Boolean, default: false },
});
const selected = ref<string[] | string>(props.value);
@ -73,6 +77,13 @@ function changeSelected() {
);
emit("change", options);
}
function remoteMethod(query: string) {
if (props.isRemote) {
emit("query", query);
}
}
watch(
() => props.value,
(data) => {

View File

@ -19,7 +19,7 @@ import TimePicker from "./TimePicker.vue";
import Selector from "./Selector.vue";
import Graph from "./Graph.vue";
import Radio from "./Radio.vue";
import SelectSingle from "./Select.vue";
import SelectSingle from "./SelectSingle.vue";
import type { App } from "vue";
import VueGridLayout from "vue-grid-layout";

View File

@ -52,7 +52,7 @@ export const Instances = {
export const Endpoints = {
variable: "$serviceId: ID!, $keyword: String!",
query: `
pods: findEndpoint(serviceId: $serviceId, keyword: $keyword, limit: 100) {
pods: findEndpoint(serviceId: $serviceId, keyword: $keyword, limit: 20) {
id
value: name
label: name

View File

@ -30,6 +30,20 @@ limitations under the License. -->
<span title="refresh" class="ghost ml-5 cp" @click="handleReload">
<Icon iconName="retry" :loading="appStore.autoRefresh" class="middle" />
</span>
<span class="version ml-5 cp">
<el-popover
trigger="hover"
width="250"
placement="left-end"
:content="appStore.version"
>
<template #reference>
<span>
<Icon iconName="info_outline" size="middle" />
</span>
</template>
</el-popover>
</span>
</div>
</div>
</template>
@ -39,6 +53,7 @@ import { useRoute } from "vue-router";
import { useI18n } from "vue-i18n";
import timeFormat from "@/utils/timeFormat";
import { useAppStoreWithOut } from "@/store/modules/app";
import { ElMessage } from "element-plus";
const { t } = useI18n();
const appStore = useAppStoreWithOut();
@ -47,6 +62,7 @@ const pageName = ref<string>("");
const timeRange = ref<number>(0);
const theme = ref<string>("light");
getVersion();
const setConfig = (value: string) => {
pageName.value = value || "";
theme.value = route.path.includes("/infrastructure/") ? "dark" : "light";
@ -76,6 +92,12 @@ watch(
setConfig(String(title));
}
);
async function getVersion() {
const res = await appStore.fetchVersion();
if (res.errors) {
ElMessage.error(res.errors);
}
}
</script>
<style lang="scss" scoped>
.nav-bar {

View File

@ -13,8 +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>
<div class="side-bar flex-v">
<div>
<div class="side-bar">
<div :class="isCollapse ? 'logo-icon-collapse' : 'logo-icon'">
<Icon
:size="isCollapse ? 'xl' : 'logo'"
@ -103,32 +102,14 @@ limitations under the License. -->
/>
</div>
</div>
<div class="version">
<el-popover
trigger="hover"
width="250"
placement="right"
:content="appStore.version"
>
<template #reference>
<span>
<Icon iconName="version" size="middle" />
</span>
</template>
</el-popover>
</div>
</div>
</template>
<script lang="ts" setup>
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";
import Icon from "@/components/Icon.vue";
const appStore = useAppStoreWithOut();
const { t } = useI18n();
const name = ref<any>(String(useRouter().currentRoute.value.name));
const theme = ["VirtualMachine", "Kubernetes"].includes(name.value || "")
@ -139,7 +120,6 @@ const isCollapse = ref(false);
const controlMenu = () => {
isCollapse.value = !isCollapse.value;
};
getVersion();
const changePage = (menu: RouteRecordRaw) => {
theme.value = ["VirtualMachine", "Kubernetes"].includes(String(menu.name))
? "light"
@ -148,23 +128,15 @@ 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);
}
}
</script>
<style lang="scss" scoped>
.side-bar {
position: relative;
background: #252a2f;
height: 100%;
overflow-y: auto;
overflow-x: hidden;
min-height: 700px;
justify-content: space-between;
position: relative;
margin-bottom: 100px;
}
.el-menu-vertical:not(.el-menu--collapse) {
@ -192,7 +164,7 @@ span.collapse {
}
.menu-control {
position: fixed;
position: absolute;
top: 8px;
left: 200px;
cursor: pointer;
@ -220,5 +192,13 @@ span.collapse {
cursor: pointer;
padding-left: 23px;
margin-bottom: 10px;
position: absolute;
bottom: 0;
left: 10px;
}
.empty {
width: 100%;
height: 60px;
}
</style>

View File

@ -86,14 +86,14 @@ export const logStore = defineStore({
] || [{ value: " 0", label: "All" }];
return res.data;
},
async getEndpoints(id: string) {
async getEndpoints(id: string, keyword?: string) {
const serviceId = this.selectorStore.currentService
? this.selectorStore.currentService.id
: id;
const res: AxiosResponse = await graphql.query("queryEndpoints").params({
serviceId,
duration: this.durationTime,
keyword: "",
keyword: keyword || "",
});
if (res.data.errors) {
return res.data;

View File

@ -101,14 +101,14 @@ export const traceStore = defineStore({
] || [{ value: " 0", label: "All" }];
return res.data;
},
async getEndpoints(id: string) {
async getEndpoints(id: string, keyword?: string) {
const serviceId = this.selectorStore.currentService
? this.selectorStore.currentService.id
: id;
const res: AxiosResponse = await graphql.query("queryEndpoints").params({
serviceId,
duration: this.durationTime,
keyword: "",
keyword: keyword || "",
});
if (res.data.errors) {
return res.data;

View File

@ -219,8 +219,8 @@ async function setMetricType(chart?: any) {
}
}
function setDashboards() {
const { graph } = dashboardStore.selectedGrid;
function setDashboards(type?: string) {
const graph = type || dashboardStore.selectedGrid.graph;
const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
const arr = list.reduce(
(
@ -279,7 +279,7 @@ function changeChartType(item: Option) {
defaultLen.value = 5;
}
setMetricType(graph);
setDashboards();
setDashboards(graph.type);
states.dashboardName = "";
defaultLen.value = 10;
}

View File

@ -40,7 +40,11 @@ limitations under the License. -->
size="small"
placeholder="Select a data"
@change="changePods"
@query="searchPods"
class="selectorPod"
:isRemote="
['EndpointRelation', 'Endpoint'].includes(dashboardStore.entity)
"
/>
</div>
<div class="selectors-item" v-if="states.key === 2 || states.key === 4">
@ -60,15 +64,17 @@ limitations under the License. -->
dashboardStore.entity === "EndpointRelation"
? "$DestinationEndpoint"
: "$DestinationServiceInstance"
}}</span
>
}}
</span>
<Selector
v-model="states.currentDestPod"
:options="selectorStore.destPods"
size="small"
placeholder="Select a data"
@change="changePods"
@change="changeDestPods"
class="selectorPod"
@query="searchDestPods"
:isRemote="dashboardStore.entity === 'EndpointRelation'"
/>
</div>
</div>
@ -126,7 +132,6 @@ const params = useRoute().params;
const toolIcons = ref<{ name: string; content: string; id: string }[]>(
EndpointRelationTools
);
const limit = ref<number>(10);
const loading = ref<boolean>(false);
const states = reactive<{
destService: string;
@ -320,6 +325,14 @@ function changePods(pod: any) {
}
}
function changeDestPods(pod: any) {
if (pod[0]) {
selectorStore.setCurrentDestPod(pod[0]);
} else {
selectorStore.setCurrentDestPod(null);
}
}
function changeMode() {
if (dashboardStore.editMode) {
ElMessage.warning(t("editWarning"));
@ -403,11 +416,16 @@ function setControls(id: string) {
}
}
async function fetchPods(type: string, serviceId: string, setPod: boolean) {
async function fetchPods(
type: string,
serviceId: string,
setPod: boolean,
param?: { keyword?: string }
) {
let resp;
switch (type) {
case EntityType[2].value:
resp = await selectorStore.getEndpoints({ serviceId, limit });
resp = await selectorStore.getEndpoints({ serviceId, ...param });
if (setPod) {
selectorStore.setCurrentPod(
selectorStore.pods.length ? selectorStore.pods[0] : null
@ -428,7 +446,7 @@ async function fetchPods(type: string, serviceId: string, setPod: boolean) {
resp = await selectorStore.getEndpoints({
serviceId,
isRelation: true,
limit,
...param,
});
if (setPod) {
selectorStore.setCurrentDestPod(
@ -483,6 +501,23 @@ function getTools() {
toolIcons.value = EndpointRelationTools;
}
}
function searchPods(query: string) {
const param = {
keyword: query,
};
fetchPods(EntityType[2].value, selectorStore.currentService.id, false, param);
}
function searchDestPods(query: string) {
const param = {
keyword: query,
};
fetchPods(
EntityType[6].value,
selectorStore.currentDestService.id,
false,
param
);
}
</script>
<style lang="scss" scoped>
.dashboard-tool {

View File

@ -46,6 +46,8 @@ limitations under the License. -->
:options="logStore.endpoints"
placeholder="Select a endpoint"
@change="changeField('endpoint', $event)"
:isRemote="true"
@query="searchEndpoints"
/>
</div>
</div>
@ -243,6 +245,12 @@ function changeField(type: string, opt: any) {
getInstances(state.service.id);
}
}
async function searchEndpoints(keyword: string) {
const resp = await logStore.getEndpoints(state.service.id, keyword);
if (resp.errors) {
ElMessage.error(resp.errors);
}
}
function updateTags(data: { tagsMap: Array<Option>; tagsList: string[] }) {
tagsList.value = data.tagsList;
tagsMap.value = data.tagsMap;

View File

@ -41,7 +41,9 @@ limitations under the License. -->
:value="state.endpoint.value"
:options="traceStore.endpoints"
placeholder="Select a endpoint"
:isRemote="true"
@change="changeField('endpoint', $event)"
@query="searchEndpoints"
/>
</div>
<div class="mr-5">
@ -149,8 +151,8 @@ async function getServices() {
getInstances(state.service.id);
}
async function getEndpoints(id?: string) {
const resp = await traceStore.getEndpoints(id);
async function getEndpoints(id?: string, keyword?: string) {
const resp = await traceStore.getEndpoints(id, keyword);
if (resp.errors) {
ElMessage.error(resp.errors);
return;
@ -208,6 +210,12 @@ function updateTags(data: { tagsMap: Array<Option>; tagsList: string[] }) {
tagsList.value = data.tagsList;
tagsMap.value = data.tagsMap;
}
async function searchEndpoints(keyword: string) {
const resp = await traceStore.getEndpoints(state.service.id, keyword);
if (resp.errors) {
ElMessage.error(resp.errors);
}
}
watch(
() => [selectorStore.currentPod],
() => {