fix: update tooltips and controls (#49)

This commit is contained in:
Fine0830 2022-03-31 19:59:19 +08:00 committed by GitHub
parent 13b508e896
commit b51e423c2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 135 additions and 61 deletions

View 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

View File

@ -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",
};

View File

@ -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;
}

View File

@ -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,
};
},
});

View File

@ -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 });
}

View File

@ -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,

View File

@ -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 = [

View File

@ -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 {

View File

@ -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],

View File

@ -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(

View File

@ -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: {

View File

@ -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],

View File

@ -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 {