mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-07-18 11:25:22 +00:00
feat: add profile
This commit is contained in:
parent
977ffbaf74
commit
5cc9884ee2
124
src/graphql/fragments/profile.ts
Normal file
124
src/graphql/fragments/profile.ts
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
/**
|
||||||
|
* 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 ProfileSegment = {
|
||||||
|
variable: "$segmentId: String",
|
||||||
|
query: `
|
||||||
|
segment: getProfiledSegment(segmentId: $segmentId) {
|
||||||
|
spans {
|
||||||
|
spanId
|
||||||
|
parentSpanId
|
||||||
|
serviceCode
|
||||||
|
startTime
|
||||||
|
endTime
|
||||||
|
endpointName
|
||||||
|
type
|
||||||
|
peer
|
||||||
|
component
|
||||||
|
isError
|
||||||
|
layer
|
||||||
|
tags {
|
||||||
|
key value
|
||||||
|
}
|
||||||
|
logs {
|
||||||
|
time
|
||||||
|
data {
|
||||||
|
key
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CreateProfileTask = {
|
||||||
|
variable: "$creationRequest: ProfileTaskCreationRequest",
|
||||||
|
query: `
|
||||||
|
task: createProfileTask(creationRequest: $creationRequest) {
|
||||||
|
id
|
||||||
|
errorReason
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const GetProfileTaskList = {
|
||||||
|
variable: "$endpointName: String, $serviceId: ID",
|
||||||
|
query: `
|
||||||
|
taskList: getProfileTaskList(endpointName: $endpointName, serviceId: $serviceId) {
|
||||||
|
serviceId
|
||||||
|
endpointName
|
||||||
|
startTime
|
||||||
|
duration
|
||||||
|
minDurationThreshold
|
||||||
|
dumpPeriod
|
||||||
|
maxSamplingCount
|
||||||
|
id
|
||||||
|
logs {
|
||||||
|
id
|
||||||
|
instanceId
|
||||||
|
instanceName
|
||||||
|
operationType
|
||||||
|
operationTime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
export const GetProfileTaskSegmentList = {
|
||||||
|
variable: "$taskID: String",
|
||||||
|
query: `
|
||||||
|
segmentList: getProfileTaskSegmentList(taskID: $taskID) {
|
||||||
|
segmentId
|
||||||
|
endpointNames
|
||||||
|
start
|
||||||
|
duration
|
||||||
|
traceIds
|
||||||
|
isError
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const GetProfileAnalyze = {
|
||||||
|
variable: "$segmentId: String!, $timeRanges: [ProfileAnalyzeTimeRange!]!",
|
||||||
|
query: `
|
||||||
|
analyze: getProfileAnalyze(segmentId: $segmentId, timeRanges: $timeRanges) {
|
||||||
|
tip
|
||||||
|
trees {
|
||||||
|
elements {
|
||||||
|
id
|
||||||
|
parentId
|
||||||
|
codeSignature
|
||||||
|
duration
|
||||||
|
durationChildExcluded
|
||||||
|
count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
export const GetProfileTaskLogs = {
|
||||||
|
variable: "$taskID: String",
|
||||||
|
query: `
|
||||||
|
taskLogs: getProfileTaskLogs(taskID: $taskID) {
|
||||||
|
id
|
||||||
|
instanceId
|
||||||
|
instanceName
|
||||||
|
operationTime
|
||||||
|
operationType
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
};
|
39
src/graphql/query/profile.ts
Normal file
39
src/graphql/query/profile.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* 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 {
|
||||||
|
ProfileSegment,
|
||||||
|
CreateProfileTask,
|
||||||
|
GetProfileTaskList,
|
||||||
|
GetProfileTaskSegmentList,
|
||||||
|
GetProfileAnalyze,
|
||||||
|
GetProfileTaskLogs,
|
||||||
|
} from "../fragments/profile";
|
||||||
|
|
||||||
|
export const queryProfileSegment = `query queryProfileSegment(${ProfileSegment.variable}) {${ProfileSegment.query}}`;
|
||||||
|
|
||||||
|
export const saveProfileTask = `mutation createProfileTask(${CreateProfileTask.variable}) {${CreateProfileTask.query}}`;
|
||||||
|
|
||||||
|
export const getProfileTaskList = `query getProfileTaskList(${GetProfileTaskList.variable}) {
|
||||||
|
${GetProfileTaskList.query}}`;
|
||||||
|
|
||||||
|
export const getProfileTaskSegmentList = `query getProfileTaskSegmentList(${GetProfileTaskSegmentList.variable}) {
|
||||||
|
${GetProfileTaskSegmentList.query}}`;
|
||||||
|
|
||||||
|
export const getProfileAnalyze = `query getProfileAnalyze(${GetProfileAnalyze.variable}) {${GetProfileAnalyze.query}}`;
|
||||||
|
|
||||||
|
export const getProfileTaskLogs = `query profileTaskLogs(${GetProfileTaskLogs.variable}) {${GetProfileTaskLogs.query}}`;
|
@ -95,7 +95,7 @@ export const dashboardStore = defineStore({
|
|||||||
showDepth: true,
|
showDepth: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (type === "Trace") {
|
if (type === "Trace" || type === "Profile") {
|
||||||
newItem.h = 24;
|
newItem.h = 24;
|
||||||
}
|
}
|
||||||
this.layout = this.layout.map((d: LayoutConfig) => {
|
this.layout = this.layout.map((d: LayoutConfig) => {
|
||||||
|
185
src/store/modules/profile.ts
Normal file
185
src/store/modules/profile.ts
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
/**
|
||||||
|
* 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 { defineStore } from "pinia";
|
||||||
|
import { Duration } from "@/types/app";
|
||||||
|
import { Service } from "@/types/selector";
|
||||||
|
import {
|
||||||
|
TaskListItem,
|
||||||
|
SegmentSpan,
|
||||||
|
ProfileAnalyzationTrees,
|
||||||
|
TaskLog,
|
||||||
|
} from "@/types/profile";
|
||||||
|
import { Trace } from "@/types/trace";
|
||||||
|
import { store } from "@/store";
|
||||||
|
import graphql from "@/graphql";
|
||||||
|
import { AxiosResponse } from "axios";
|
||||||
|
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||||
|
|
||||||
|
interface ProfileState {
|
||||||
|
services: Service[];
|
||||||
|
durationTime: Duration;
|
||||||
|
condition: { serviceId: string; endpointName: string };
|
||||||
|
taskList: TaskListItem[];
|
||||||
|
segmentList: Trace[];
|
||||||
|
currentSegment: Nullable<Trace>;
|
||||||
|
segmentSpans: SegmentSpan[];
|
||||||
|
currentSpan: Nullable<SegmentSpan>;
|
||||||
|
analyzeTrees: ProfileAnalyzationTrees;
|
||||||
|
taskLogs: TaskLog[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const traceStore = defineStore({
|
||||||
|
id: "profile",
|
||||||
|
state: (): ProfileState => ({
|
||||||
|
services: [{ value: "0", label: "All" }],
|
||||||
|
durationTime: useAppStoreWithOut().durationTime,
|
||||||
|
condition: { serviceId: "", endpointName: "" },
|
||||||
|
taskList: [],
|
||||||
|
segmentList: [],
|
||||||
|
currentSegment: null,
|
||||||
|
segmentSpans: [],
|
||||||
|
currentSpan: null,
|
||||||
|
analyzeTrees: [],
|
||||||
|
taskLogs: [],
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
setConditions(data: { serviceId?: string; endpointName?: string }) {
|
||||||
|
this.condition = {
|
||||||
|
...this.condition,
|
||||||
|
...data,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
async getServices(layer: string) {
|
||||||
|
const res: AxiosResponse = await graphql.query("queryServices").params({
|
||||||
|
layer,
|
||||||
|
});
|
||||||
|
if (res.data.errors) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
this.services = [
|
||||||
|
{ value: "0", label: "All" },
|
||||||
|
...res.data.data.services,
|
||||||
|
] || [{ value: "0", label: "All" }];
|
||||||
|
return res.data;
|
||||||
|
},
|
||||||
|
async getTaskList() {
|
||||||
|
const res: AxiosResponse = await graphql
|
||||||
|
.query("getProfileTaskList")
|
||||||
|
.params(this.condition);
|
||||||
|
|
||||||
|
if (res.data.errors) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
const list = res.data.data.taskList;
|
||||||
|
this.taskList = list;
|
||||||
|
if (!list.length) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async getSegmentList(params: { taskID: string }) {
|
||||||
|
const res: AxiosResponse = await graphql
|
||||||
|
.query("getProfileTaskSegmentList")
|
||||||
|
.params(params);
|
||||||
|
|
||||||
|
if (res.data.errors) {
|
||||||
|
this.segmentList = [];
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
const { segmentList } = res.data.data;
|
||||||
|
|
||||||
|
this.segmentList = segmentList;
|
||||||
|
|
||||||
|
if (segmentList[0]) {
|
||||||
|
this.currentSegment = segmentList[0];
|
||||||
|
} else {
|
||||||
|
this.currentSegment = null;
|
||||||
|
}
|
||||||
|
return res.data;
|
||||||
|
},
|
||||||
|
async getSegmentSpans(params: { segmentId: string }) {
|
||||||
|
const res: AxiosResponse = await graphql
|
||||||
|
.query("queryProfileSegment")
|
||||||
|
.params(params);
|
||||||
|
if (res.data.errors) {
|
||||||
|
this.segmentSpans = [];
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
const { segment } = res.data.data;
|
||||||
|
if (!segment) {
|
||||||
|
this.segmentSpans = [];
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
this.segmentSpans = segment.spans;
|
||||||
|
if (!(segment.spans && segment.spans.length)) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
const index = segment.spans.length - 1 || 0;
|
||||||
|
this.currentSpan = segment.spans[index];
|
||||||
|
return res.data;
|
||||||
|
},
|
||||||
|
async getProfileAnalyze(params: {
|
||||||
|
segmentId: string;
|
||||||
|
timeRanges: Array<{ start: number; end: number }>;
|
||||||
|
}) {
|
||||||
|
const res: AxiosResponse = await graphql
|
||||||
|
.query("getProfileAnalyze")
|
||||||
|
.params(params);
|
||||||
|
|
||||||
|
if (res.data.errors) {
|
||||||
|
this.segmentSpans = [];
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
const { analyze, tip } = res.data.data;
|
||||||
|
if (tip) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!analyze) {
|
||||||
|
this.analyzeTrees = [];
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
this.analyzeTrees = analyze.trees;
|
||||||
|
return res.data;
|
||||||
|
},
|
||||||
|
async createTask(param: any) {
|
||||||
|
const res: AxiosResponse = await graphql
|
||||||
|
.query("saveProfileTask")
|
||||||
|
.params({ param });
|
||||||
|
|
||||||
|
if (res.data.errors) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
this.getTaskList();
|
||||||
|
return res.data;
|
||||||
|
},
|
||||||
|
async getTaskLogs(param: { taskID: string }) {
|
||||||
|
const res: AxiosResponse = await graphql
|
||||||
|
.query("getProfileTaskLogs")
|
||||||
|
.params(param);
|
||||||
|
|
||||||
|
if (res.data.errors) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
this.taskLogs = res.data.data.taskLogs;
|
||||||
|
return res.data;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export function useProfileStore(): any {
|
||||||
|
return traceStore(store);
|
||||||
|
}
|
60
src/types/profile.d.ts
vendored
Normal file
60
src/types/profile.d.ts
vendored
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
type ProfileStackElement = {
|
||||||
|
id: string;
|
||||||
|
parentId: string;
|
||||||
|
codeSignature: string;
|
||||||
|
duration: number;
|
||||||
|
durationChildExcluded: number;
|
||||||
|
count: number;
|
||||||
|
};
|
||||||
|
export type ProfileAnalyzationTrees = { elements: ProfileStackElement[] }[];
|
||||||
|
export interface TaskLog {
|
||||||
|
id: string;
|
||||||
|
instanceId: string;
|
||||||
|
instanceName: string;
|
||||||
|
operationTime: number;
|
||||||
|
operationType: string;
|
||||||
|
}
|
||||||
|
export interface TaskListItem {
|
||||||
|
id: string;
|
||||||
|
serviceId: string;
|
||||||
|
serviceName: string;
|
||||||
|
endpointName: string;
|
||||||
|
startTime: number;
|
||||||
|
duration: number;
|
||||||
|
minDurationThreshold: number;
|
||||||
|
dumpPeriod: number;
|
||||||
|
maxSamplingCount: number;
|
||||||
|
logs: TaskLog[];
|
||||||
|
}
|
||||||
|
export interface SegmentSpan {
|
||||||
|
spanId: string;
|
||||||
|
parentSpanId: string;
|
||||||
|
serviceCode: string;
|
||||||
|
serviceInstanceName: string;
|
||||||
|
startTime: number;
|
||||||
|
endTime: number;
|
||||||
|
endpointName: string;
|
||||||
|
type: string;
|
||||||
|
peer: string;
|
||||||
|
component: string;
|
||||||
|
isError: boolean;
|
||||||
|
layer: string;
|
||||||
|
tags: any[];
|
||||||
|
logs: any[];
|
||||||
|
}
|
86
src/views/dashboard/controls/Profile.vue
Normal file
86
src/views/dashboard/controls/Profile.vue
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<!-- 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="profile-wrapper flex-v">
|
||||||
|
<el-popover placement="bottom" trigger="click" :width="100">
|
||||||
|
<template #reference>
|
||||||
|
<span class="delete cp">
|
||||||
|
<Icon iconName="ellipsis_v" size="middle" class="operation" />
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<div class="tools">
|
||||||
|
<span @click="removeWidget">{{ t("delete") }}</span>
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
<div class="header">header</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { PropType } from "vue";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
|
|
||||||
|
/*global defineProps */
|
||||||
|
const props = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Object as PropType<any>,
|
||||||
|
default: () => ({ graph: {} }),
|
||||||
|
},
|
||||||
|
activeIndex: { type: String, default: "" },
|
||||||
|
});
|
||||||
|
const { t } = useI18n();
|
||||||
|
const dashboardStore = useDashboardStore();
|
||||||
|
function removeWidget() {
|
||||||
|
dashboardStore.removeControls(props.data);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.profile-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
font-size: 12px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete {
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
right: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
border-bottom: 1px solid #dcdfe6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools {
|
||||||
|
padding: 5px 0;
|
||||||
|
color: #999;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #409eff;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.trace {
|
||||||
|
width: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
</style>
|
@ -18,5 +18,6 @@ import Topology from "./Topology.vue";
|
|||||||
import Tab from "./Tab.vue";
|
import Tab from "./Tab.vue";
|
||||||
import Widget from "./Widget.vue";
|
import Widget from "./Widget.vue";
|
||||||
import Trace from "./Trace.vue";
|
import Trace from "./Trace.vue";
|
||||||
|
import Profile from "./Profile.vue";
|
||||||
|
|
||||||
export default { Tab, Widget, Trace, Topology };
|
export default { Tab, Widget, Trace, Topology, Profile };
|
||||||
|
@ -167,6 +167,7 @@ export const ToolIcons = [
|
|||||||
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
||||||
{ name: "device_hub", content: "Add Topology", id: "topology" },
|
{ name: "device_hub", content: "Add Topology", id: "topology" },
|
||||||
{ name: "merge", content: "Add Trace", id: "trace" },
|
{ name: "merge", content: "Add Trace", id: "trace" },
|
||||||
|
{ name: "timeline", content: "Add Profile", id: "profile" },
|
||||||
// { name: "save_alt", content: "Export", id: "export" },
|
// { name: "save_alt", content: "Export", id: "export" },
|
||||||
// { name: "folder_open", content: "Import", id: "import" },
|
// { name: "folder_open", content: "Import", id: "import" },
|
||||||
// { name: "settings", content: "Settings", id: "settings" },
|
// { name: "settings", content: "Settings", id: "settings" },
|
||||||
|
@ -295,6 +295,9 @@ function clickIcons(t: { id: string; content: string; name: string }) {
|
|||||||
case "trace":
|
case "trace":
|
||||||
dashboardStore.addControl("Trace");
|
dashboardStore.addControl("Trace");
|
||||||
break;
|
break;
|
||||||
|
case "profile":
|
||||||
|
dashboardStore.addControl("Profile");
|
||||||
|
break;
|
||||||
case "topology":
|
case "topology":
|
||||||
dashboardStore.addControl("Topology");
|
dashboardStore.addControl("Topology");
|
||||||
break;
|
break;
|
||||||
|
63
src/views/dashboard/related/profile/Header.vue
Normal file
63
src/views/dashboard/related/profile/Header.vue
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<!-- 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="flex-h">
|
||||||
|
<div class="mr-5">
|
||||||
|
<span class="grey mr-5">{{ t("service") }}:</span>
|
||||||
|
<Selector
|
||||||
|
size="small"
|
||||||
|
:value="service.value"
|
||||||
|
:options="profileStore.services"
|
||||||
|
placeholder="Select a service"
|
||||||
|
@change="changeService"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="mr-5">
|
||||||
|
<span class="sm b grey mr-5">{{ t("endpointName") }}:</span>
|
||||||
|
<el-input class="inputs mr-5" v-model="endpointName" />
|
||||||
|
</div>
|
||||||
|
<el-button
|
||||||
|
class="search-btn"
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
@click="searchTasks"
|
||||||
|
>
|
||||||
|
{{ t("search") }}
|
||||||
|
</el-button>
|
||||||
|
<el-button class="search-btn" size="small">
|
||||||
|
{{ t("newTask") }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from "vue";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
import { useProfileStore } from "@/store/modules/profile";
|
||||||
|
|
||||||
|
const profileStore = useProfileStore();
|
||||||
|
const { t } = useI18n();
|
||||||
|
const service = ref<any>({});
|
||||||
|
const endpointName = ref<string>("");
|
||||||
|
|
||||||
|
function changeService(opt: any[]) {
|
||||||
|
service.value = opt[0];
|
||||||
|
}
|
||||||
|
function searchTasks() {
|
||||||
|
profileStore.setConditions({
|
||||||
|
serviceId: service.value.id,
|
||||||
|
endpointName: endpointName.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
Loading…
Reference in New Issue
Block a user