mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-05-01 19:54:27 +00:00
fix: update tooltips and controls (#49)
This commit is contained in:
parent
13b508e896
commit
b51e423c2b
15
src/assets/icons/control.svg
Normal file
15
src/assets/icons/control.svg
Normal file
@ -0,0 +1,15 @@
|
||||
<!-- 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="1648717513168" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15451" width="48" height="48"><path d="M810.666667 213.333333v597.333334H213.333333V213.333333h597.333334m85.333333-85.333333H128v768h768V128z m-512 170.666667h-85.333333v85.333333h85.333333z m170.666667 0h-85.333334v85.333333h85.333334z m-170.666667 170.666666h-85.333333v85.333334h85.333333z m170.666667 0h-85.333334v85.333334h85.333334z m-170.666667 170.666667h-85.333333v85.333333h85.333333z m170.666667 0h-85.333334v85.333333h85.333334z m170.666666-341.333333h-85.333333v85.333333h85.333333z m0 170.666666h-85.333333v85.333334h85.333333z m0 170.666667h-85.333333v85.333333h85.333333z" p-id="15452" fill="#515151"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |
@ -68,7 +68,7 @@ export function useQueryProcessor(config: any) {
|
||||
normal: selectorStore.currentService
|
||||
? selectorStore.currentService.normal
|
||||
: true,
|
||||
scope: config.catalog || dashboardStore.entity,
|
||||
scope: config.catalog,
|
||||
topN: c.topN || 10,
|
||||
order: c.sortOrder || "DES",
|
||||
};
|
||||
|
@ -141,3 +141,15 @@ pre {
|
||||
.el-icon.menu-icons {
|
||||
margin-top: -3px !important;
|
||||
}
|
||||
|
||||
.el-switch__label--left {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.el-switch__label--right {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.switch {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
@ -16,10 +16,12 @@ limitations under the License. -->
|
||||
<div class="widget-config flex-v">
|
||||
<div class="graph" v-loading="loading">
|
||||
<div class="header">
|
||||
<span>{{ widget.title || "" }}</span>
|
||||
<span>{{ decodeURIComponent(title) }}</span>
|
||||
<div class="tips" v-show="widget.tips">
|
||||
<el-tooltip :content="widget.tips || ''">
|
||||
<Icon iconName="info_outline" size="sm" />
|
||||
<el-tooltip :content="decodeURIComponent(tips) || ''">
|
||||
<span>
|
||||
<Icon iconName="info_outline" size="sm" />
|
||||
</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
@ -113,6 +115,8 @@ export default defineComponent({
|
||||
const originConfig = dashboardStore.selectedGrid;
|
||||
const widget = computed(() => dashboardStore.selectedGrid.widget || {});
|
||||
const graph = computed(() => dashboardStore.selectedGrid.graph || {});
|
||||
const title = computed(() => encodeURIComponent(widget.value.title || ""));
|
||||
const tips = computed(() => encodeURIComponent(widget.value.tips || ""));
|
||||
|
||||
function getSource(source: unknown) {
|
||||
states.source = source;
|
||||
@ -152,6 +156,8 @@ export default defineComponent({
|
||||
isEdit,
|
||||
widget,
|
||||
graph,
|
||||
title,
|
||||
tips,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@ -20,7 +20,7 @@ limitations under the License. -->
|
||||
v-model="title"
|
||||
size="small"
|
||||
placeholder="Please input title"
|
||||
@change="updateWidgetConfig({ title })"
|
||||
@change="updateWidgetConfig({ title: encodeURIComponent(title) })"
|
||||
/>
|
||||
</div>
|
||||
<div class="item">
|
||||
@ -30,7 +30,7 @@ limitations under the License. -->
|
||||
v-model="tips"
|
||||
size="small"
|
||||
placeholder="Please input tips"
|
||||
@change="updateWidgetConfig({ tips })"
|
||||
@change="updateWidgetConfig({ tips: encodeURIComponent(tips) })"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@ -46,10 +46,14 @@ const widget = dashboardStore.selectedGrid.widget || {};
|
||||
const title = ref<string>(widget.title || "");
|
||||
const tips = ref<string>(widget.tips || "");
|
||||
|
||||
function updateWidgetConfig(param: { [key: string]: unknown }) {
|
||||
function updateWidgetConfig(param: { [key: string]: string }) {
|
||||
const key = Object.keys(param)[0];
|
||||
if (!key) {
|
||||
return;
|
||||
}
|
||||
const widget = {
|
||||
...dashboardStore.selectedGrid.widget,
|
||||
...param,
|
||||
[key]: decodeURIComponent(param[key]),
|
||||
};
|
||||
dashboardStore.selectWidget({ ...selectedGrid, widget });
|
||||
}
|
||||
|
@ -21,7 +21,9 @@ limitations under the License. -->
|
||||
v-model="currentMetric.unit"
|
||||
size="small"
|
||||
placeholder="Please input unit"
|
||||
@change="changeConfigs(index, { unit: currentMetric.unit })"
|
||||
@change="
|
||||
updateConfig(index, { unit: encodeURIComponent(currentMetric.unit) })
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<div class="item mb-10" v-show="metricType === 'readLabeledMetricsValues'">
|
||||
@ -31,7 +33,11 @@ limitations under the License. -->
|
||||
v-model="currentMetric.label"
|
||||
size="small"
|
||||
placeholder="Please input a name"
|
||||
@change="changeConfigs(index, { label: currentMetric.label })"
|
||||
@change="
|
||||
updateConfig(index, {
|
||||
label: encodeURIComponent(currentMetric.label),
|
||||
})
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<div class="item mb-10" v-show="metricType === 'readLabeledMetricsValues'">
|
||||
@ -42,7 +48,9 @@ limitations under the License. -->
|
||||
size="small"
|
||||
placeholder="auto"
|
||||
@change="
|
||||
changeConfigs(index, { labelsIndex: currentMetric.labelsIndex })
|
||||
updateConfig(index, {
|
||||
labelsIndex: encodeURIComponent(currentMetric.labelsIndex),
|
||||
})
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
@ -108,13 +116,21 @@ const metricType = ref<string>(metricTypes[props.index]);
|
||||
const isTopn = computed(() =>
|
||||
["sortMetrics", "readSampledRecords"].includes(metricTypes[props.index])
|
||||
);
|
||||
function updateConfig(index: number, param: { [key: string]: string }) {
|
||||
const key = Object.keys(param)[0];
|
||||
if (!key) {
|
||||
return;
|
||||
}
|
||||
changeConfigs(index, { key: decodeURIComponent(param[key]) });
|
||||
}
|
||||
function changeConfigs(
|
||||
index: number,
|
||||
param: { [key: string]: string | number }
|
||||
) {
|
||||
const metricConfig = dashboardStore.selectedGrid.metricConfig || [];
|
||||
metricConfig[index] = { ...metricConfig[index], ...param };
|
||||
|
||||
metricConfig[index] = { ...metricConfig[index], ...param };
|
||||
currentMetric.value = metricConfig[index];
|
||||
dashboardStore.selectWidget({
|
||||
...dashboardStore.selectedGrid,
|
||||
metricConfig,
|
||||
|
@ -174,17 +174,15 @@ export const AllTools = [
|
||||
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
|
||||
{ name: "merge", content: "Add Trace", id: "addTrace" },
|
||||
{ name: "assignment", content: "Add Log", id: "addLog" },
|
||||
{ name: "save", content: "Apply", id: "apply" },
|
||||
];
|
||||
export const ServiceTools = [
|
||||
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
||||
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
||||
{ name: "library_books", content: "Add Text", id: "addText" },
|
||||
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
|
||||
{ name: "merge", content: "Add Trace", id: "addTrace" },
|
||||
{ name: "timeline", content: "Add Profile", id: "addProfile" },
|
||||
{ name: "assignment", content: "Add Log", id: "addLog" },
|
||||
{ name: "save", content: "Apply", id: "apply" },
|
||||
{ name: "playlist_add", content: "Widget", id: "addWidget" },
|
||||
{ name: "all_inbox", content: "Tab", id: "addTab" },
|
||||
{ name: "library_books", content: "Text", id: "addText" },
|
||||
{ name: "device_hub", content: "Topology", id: "addTopology" },
|
||||
{ name: "merge", content: "Trace", id: "addTrace" },
|
||||
{ name: "timeline", content: "Profile", id: "addProfile" },
|
||||
{ name: "assignment", content: "Log", id: "addLog" },
|
||||
];
|
||||
export const InstanceTools = [
|
||||
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
||||
@ -192,7 +190,6 @@ export const InstanceTools = [
|
||||
{ name: "library_books", content: "Add Text", id: "addText" },
|
||||
{ name: "merge", content: "Add Trace", id: "addTrace" },
|
||||
{ name: "assignment", content: "Add Log", id: "addLog" },
|
||||
{ name: "save", content: "Apply", id: "apply" },
|
||||
];
|
||||
export const EndpointTools = [
|
||||
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
||||
@ -201,28 +198,24 @@ export const EndpointTools = [
|
||||
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
|
||||
{ name: "merge", content: "Add Trace", id: "addTrace" },
|
||||
{ name: "assignment", content: "Add Log", id: "addLog" },
|
||||
{ name: "save", content: "Apply", id: "apply" },
|
||||
];
|
||||
export const ServiceRelationTools = [
|
||||
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
||||
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
||||
{ name: "library_books", content: "Add Text", id: "addText" },
|
||||
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
|
||||
{ name: "save", content: "Apply", id: "apply" },
|
||||
];
|
||||
|
||||
export const EndpointRelationTools = [
|
||||
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
||||
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
||||
{ name: "library_books", content: "Add Text", id: "addText" },
|
||||
{ name: "save", content: "Apply", id: "apply" },
|
||||
];
|
||||
export const InstanceRelationTools = [
|
||||
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
||||
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
||||
{ name: "library_books", content: "Add Text", id: "addText" },
|
||||
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
|
||||
{ name: "save", content: "Apply", id: "apply" },
|
||||
];
|
||||
|
||||
export const ScopeType = [
|
||||
|
@ -22,13 +22,14 @@ limitations under the License. -->
|
||||
>
|
||||
{{ singleVal.toFixed(2) }}
|
||||
<span v-show="config.showUnit">
|
||||
{{ metricConfig[0]?.unit }}
|
||||
{{ decodeURIComponent(unit) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="center no-data" v-else>No Data</div>
|
||||
<div class="center no-data" v-else>{{ t("noData") }}</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed, PropType } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { CardConfig, MetricConfigOpt } from "@/types/dashboard";
|
||||
|
||||
/*global defineProps */
|
||||
@ -47,9 +48,13 @@ const props = defineProps({
|
||||
}),
|
||||
},
|
||||
});
|
||||
const { t } = useI18n();
|
||||
const metricConfig = computed(() => props.config.metricConfig || []);
|
||||
const key = computed(() => Object.keys(props.data)[0]);
|
||||
const singleVal = computed(() => Number(props.data[key.value]));
|
||||
const unit = computed(
|
||||
() => metricConfig.value[0] && encodeURIComponent(metricConfig.value[0].unit)
|
||||
);
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.chart-card {
|
||||
|
@ -43,8 +43,8 @@ limitations under the License. -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-for="(metric, index) in config.metrics"
|
||||
:label="`${metric} ${getUnit(index)}`"
|
||||
v-for="(metric, index) in colMetrics"
|
||||
:label="`${metric} ${decodeURIComponent(getUnit(index))}`"
|
||||
:key="metric + index"
|
||||
>
|
||||
<template #default="scope">
|
||||
@ -73,7 +73,7 @@ limitations under the License. -->
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from "vue";
|
||||
import { ref, watch, computed } from "vue";
|
||||
import { useSelectorStore } from "@/store/modules/selectors";
|
||||
import { ElMessage } from "element-plus";
|
||||
import type { PropType } from "vue";
|
||||
@ -118,6 +118,7 @@ const dashboardStore = useDashboardStore();
|
||||
const chartLoading = ref<boolean>(false);
|
||||
const endpoints = ref<Endpoint[]>([]);
|
||||
const searchText = ref<string>("");
|
||||
const colMetrics = computed(() => props.config.metrics.map((d: string) => d));
|
||||
|
||||
queryEndpoints();
|
||||
|
||||
@ -187,9 +188,9 @@ function getUnit(index: number) {
|
||||
props.config.metricConfig[index].unit) ||
|
||||
"";
|
||||
if (u) {
|
||||
return `(${u})`;
|
||||
return `(${encodeURIComponent(u)})`;
|
||||
}
|
||||
return u;
|
||||
return encodeURIComponent("");
|
||||
}
|
||||
watch(
|
||||
() => [props.config.metricTypes, props.config.metrics],
|
||||
|
@ -43,8 +43,8 @@ limitations under the License. -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-for="(metric, index) in config.metrics"
|
||||
:label="`${metric} ${getUnit(index)}`"
|
||||
v-for="(metric, index) in colMetrics"
|
||||
:label="`${metric} ${decodeURIComponent(getUnit(index))}`"
|
||||
:key="metric + index"
|
||||
>
|
||||
<template #default="scope">
|
||||
@ -103,7 +103,7 @@ limitations under the License. -->
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from "vue";
|
||||
import { ref, watch, computed } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { ElMessage } from "element-plus";
|
||||
import type { PropType } from "vue";
|
||||
@ -149,6 +149,7 @@ const chartLoading = ref<boolean>(false);
|
||||
const instances = ref<Instance[]>([]); // current instances
|
||||
const pageSize = 10;
|
||||
const searchText = ref<string>("");
|
||||
const colMetrics = computed(() => props.config.metrics.map((d: string) => d));
|
||||
|
||||
queryInstance();
|
||||
async function queryInstance() {
|
||||
@ -238,9 +239,9 @@ function getUnit(index: number) {
|
||||
props.config.metricConfig[index].unit) ||
|
||||
"";
|
||||
if (u) {
|
||||
return `(${u})`;
|
||||
return `(${encodeURIComponent(u)})`;
|
||||
}
|
||||
return u;
|
||||
return encodeURIComponent("");
|
||||
}
|
||||
|
||||
watch(
|
||||
|
@ -150,12 +150,14 @@ function getOption() {
|
||||
color: "#ccc",
|
||||
},
|
||||
enterable: true,
|
||||
confine: true,
|
||||
extraCssText: "max-height: 300px; overflow: auto; border: none;",
|
||||
};
|
||||
const tips = {
|
||||
formatter(params: any) {
|
||||
return `${params[0].value[1]}`;
|
||||
},
|
||||
confine: true,
|
||||
extraCssText: `height: 20px; padding:0 2px;`,
|
||||
trigger: "axis",
|
||||
textStyle: {
|
||||
|
@ -55,8 +55,8 @@ limitations under the License. -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-for="(metric, index) in config.metrics"
|
||||
:label="`${metric} ${getUnit(index)}`"
|
||||
v-for="(metric, index) in colMetrics"
|
||||
:label="`${metric} ${decodeURIComponent(getUnit(index))}`"
|
||||
:key="metric + index"
|
||||
>
|
||||
<template #default="scope">
|
||||
@ -96,7 +96,7 @@ limitations under the License. -->
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { watch, ref } from "vue";
|
||||
import { watch, ref, computed } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
import type { PropType } from "vue";
|
||||
import { ServiceListConfig } from "@/types/dashboard";
|
||||
@ -138,6 +138,9 @@ const services = ref<Service[]>([]);
|
||||
const searchText = ref<string>("");
|
||||
const groups = ref<any>({});
|
||||
const sortServices = ref<(Service & { merge: boolean })[]>([]);
|
||||
const colMetrics = computed(() =>
|
||||
props.config.metrics.filter((d: string) => d)
|
||||
);
|
||||
|
||||
queryServices();
|
||||
|
||||
@ -278,9 +281,9 @@ function getUnit(index: number) {
|
||||
props.config.metricConfig[index].unit) ||
|
||||
"";
|
||||
if (u) {
|
||||
return `(${u})`;
|
||||
return `(${encodeURIComponent(u)})`;
|
||||
}
|
||||
return u;
|
||||
return encodeURIComponent("");
|
||||
}
|
||||
watch(
|
||||
() => [props.config.metricTypes, props.config.metrics],
|
||||
|
@ -80,24 +80,39 @@ limitations under the License. -->
|
||||
</div>
|
||||
<div class="flex-h tools" v-loading="loading">
|
||||
<div class="tool-icons flex-h" v-if="dashboardStore.editMode">
|
||||
<span
|
||||
@click="clickIcons(t)"
|
||||
v-for="(t, index) in toolIcons"
|
||||
:key="index"
|
||||
:title="t.content"
|
||||
>
|
||||
<el-tooltip :content="t.content" placement="bottom">
|
||||
<i>
|
||||
<Icon class="icon-btn" size="sm" :iconName="t.name" />
|
||||
</i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<el-dropdown content="Controls" placement="bottom">
|
||||
<i>
|
||||
<Icon class="icon-btn" size="sm" iconName="control" />
|
||||
</i>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
@click="clickIcons(t)"
|
||||
v-for="(t, index) in toolIcons"
|
||||
:key="index"
|
||||
:title="t.content"
|
||||
>
|
||||
<Icon class="mr-5" size="middle" :iconName="t.name" />
|
||||
<span>{{ t.content }}</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<el-tooltip content="Apply" placement="bottom">
|
||||
<i @click="applyDashboard">
|
||||
<Icon class="icon-btn" size="sm" iconName="save" />
|
||||
</i>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="switch">
|
||||
<el-switch
|
||||
v-model="dashboardStore.editMode"
|
||||
active-text="Edit"
|
||||
inactive-text="View"
|
||||
size="small"
|
||||
inline-prompt
|
||||
active-color="#409eff"
|
||||
inactive-color="#999"
|
||||
@change="changeMode"
|
||||
/>
|
||||
</div>
|
||||
@ -341,13 +356,13 @@ function changeMode() {
|
||||
ElMessage.warning(t("viewWarning"));
|
||||
}
|
||||
|
||||
async function applyDashboard() {
|
||||
loading.value = true;
|
||||
await dashboardStore.saveDashboard();
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
async function clickIcons(t: { id: string; content: string; name: string }) {
|
||||
if (t.id === "apply") {
|
||||
loading.value = true;
|
||||
await dashboardStore.saveDashboard();
|
||||
loading.value = false;
|
||||
return;
|
||||
}
|
||||
if (
|
||||
dashboardStore.selectedGrid &&
|
||||
dashboardStore.selectedGrid.type === "Tab"
|
||||
@ -545,6 +560,7 @@ function searchDestPods(query: string) {
|
||||
|
||||
.tools {
|
||||
justify-content: space-between;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.icon-btn {
|
||||
|
Loading…
Reference in New Issue
Block a user