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 normal: selectorStore.currentService
? selectorStore.currentService.normal ? selectorStore.currentService.normal
: true, : true,
scope: config.catalog || dashboardStore.entity, scope: config.catalog,
topN: c.topN || 10, topN: c.topN || 10,
order: c.sortOrder || "DES", order: c.sortOrder || "DES",
}; };

View File

@ -141,3 +141,15 @@ pre {
.el-icon.menu-icons { .el-icon.menu-icons {
margin-top: -3px !important; 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="widget-config flex-v">
<div class="graph" v-loading="loading"> <div class="graph" v-loading="loading">
<div class="header"> <div class="header">
<span>{{ widget.title || "" }}</span> <span>{{ decodeURIComponent(title) }}</span>
<div class="tips" v-show="widget.tips"> <div class="tips" v-show="widget.tips">
<el-tooltip :content="widget.tips || ''"> <el-tooltip :content="decodeURIComponent(tips) || ''">
<Icon iconName="info_outline" size="sm" /> <span>
<Icon iconName="info_outline" size="sm" />
</span>
</el-tooltip> </el-tooltip>
</div> </div>
</div> </div>
@ -113,6 +115,8 @@ export default defineComponent({
const originConfig = dashboardStore.selectedGrid; const originConfig = dashboardStore.selectedGrid;
const widget = computed(() => dashboardStore.selectedGrid.widget || {}); const widget = computed(() => dashboardStore.selectedGrid.widget || {});
const graph = computed(() => dashboardStore.selectedGrid.graph || {}); const graph = computed(() => dashboardStore.selectedGrid.graph || {});
const title = computed(() => encodeURIComponent(widget.value.title || ""));
const tips = computed(() => encodeURIComponent(widget.value.tips || ""));
function getSource(source: unknown) { function getSource(source: unknown) {
states.source = source; states.source = source;
@ -152,6 +156,8 @@ export default defineComponent({
isEdit, isEdit,
widget, widget,
graph, graph,
title,
tips,
}; };
}, },
}); });

View File

@ -20,7 +20,7 @@ limitations under the License. -->
v-model="title" v-model="title"
size="small" size="small"
placeholder="Please input title" placeholder="Please input title"
@change="updateWidgetConfig({ title })" @change="updateWidgetConfig({ title: encodeURIComponent(title) })"
/> />
</div> </div>
<div class="item"> <div class="item">
@ -30,7 +30,7 @@ limitations under the License. -->
v-model="tips" v-model="tips"
size="small" size="small"
placeholder="Please input tips" placeholder="Please input tips"
@change="updateWidgetConfig({ tips })" @change="updateWidgetConfig({ tips: encodeURIComponent(tips) })"
/> />
</div> </div>
</template> </template>
@ -46,10 +46,14 @@ const widget = dashboardStore.selectedGrid.widget || {};
const title = ref<string>(widget.title || ""); const title = ref<string>(widget.title || "");
const tips = ref<string>(widget.tips || ""); 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 = { const widget = {
...dashboardStore.selectedGrid.widget, ...dashboardStore.selectedGrid.widget,
...param, [key]: decodeURIComponent(param[key]),
}; };
dashboardStore.selectWidget({ ...selectedGrid, widget }); dashboardStore.selectWidget({ ...selectedGrid, widget });
} }

View File

@ -21,7 +21,9 @@ limitations under the License. -->
v-model="currentMetric.unit" v-model="currentMetric.unit"
size="small" size="small"
placeholder="Please input unit" placeholder="Please input unit"
@change="changeConfigs(index, { unit: currentMetric.unit })" @change="
updateConfig(index, { unit: encodeURIComponent(currentMetric.unit) })
"
/> />
</div> </div>
<div class="item mb-10" v-show="metricType === 'readLabeledMetricsValues'"> <div class="item mb-10" v-show="metricType === 'readLabeledMetricsValues'">
@ -31,7 +33,11 @@ limitations under the License. -->
v-model="currentMetric.label" v-model="currentMetric.label"
size="small" size="small"
placeholder="Please input a name" placeholder="Please input a name"
@change="changeConfigs(index, { label: currentMetric.label })" @change="
updateConfig(index, {
label: encodeURIComponent(currentMetric.label),
})
"
/> />
</div> </div>
<div class="item mb-10" v-show="metricType === 'readLabeledMetricsValues'"> <div class="item mb-10" v-show="metricType === 'readLabeledMetricsValues'">
@ -42,7 +48,9 @@ limitations under the License. -->
size="small" size="small"
placeholder="auto" placeholder="auto"
@change=" @change="
changeConfigs(index, { labelsIndex: currentMetric.labelsIndex }) updateConfig(index, {
labelsIndex: encodeURIComponent(currentMetric.labelsIndex),
})
" "
/> />
</div> </div>
@ -108,13 +116,21 @@ const metricType = ref<string>(metricTypes[props.index]);
const isTopn = computed(() => const isTopn = computed(() =>
["sortMetrics", "readSampledRecords"].includes(metricTypes[props.index]) ["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( function changeConfigs(
index: number, index: number,
param: { [key: string]: string | number } param: { [key: string]: string | number }
) { ) {
const metricConfig = dashboardStore.selectedGrid.metricConfig || []; const metricConfig = dashboardStore.selectedGrid.metricConfig || [];
metricConfig[index] = { ...metricConfig[index], ...param };
metricConfig[index] = { ...metricConfig[index], ...param };
currentMetric.value = metricConfig[index];
dashboardStore.selectWidget({ dashboardStore.selectWidget({
...dashboardStore.selectedGrid, ...dashboardStore.selectedGrid,
metricConfig, metricConfig,

View File

@ -174,17 +174,15 @@ export const AllTools = [
{ name: "device_hub", content: "Add Topology", id: "addTopology" }, { name: "device_hub", content: "Add Topology", id: "addTopology" },
{ name: "merge", content: "Add Trace", id: "addTrace" }, { name: "merge", content: "Add Trace", id: "addTrace" },
{ name: "assignment", content: "Add Log", id: "addLog" }, { name: "assignment", content: "Add Log", id: "addLog" },
{ name: "save", content: "Apply", id: "apply" },
]; ];
export const ServiceTools = [ export const ServiceTools = [
{ name: "playlist_add", content: "Add Widget", id: "addWidget" }, { name: "playlist_add", content: "Widget", id: "addWidget" },
{ name: "all_inbox", content: "Add Tab", id: "addTab" }, { name: "all_inbox", content: "Tab", id: "addTab" },
{ name: "library_books", content: "Add Text", id: "addText" }, { name: "library_books", content: "Text", id: "addText" },
{ name: "device_hub", content: "Add Topology", id: "addTopology" }, { name: "device_hub", content: "Topology", id: "addTopology" },
{ name: "merge", content: "Add Trace", id: "addTrace" }, { name: "merge", content: "Trace", id: "addTrace" },
{ name: "timeline", content: "Add Profile", id: "addProfile" }, { name: "timeline", content: "Profile", id: "addProfile" },
{ name: "assignment", content: "Add Log", id: "addLog" }, { name: "assignment", content: "Log", id: "addLog" },
{ name: "save", content: "Apply", id: "apply" },
]; ];
export const InstanceTools = [ export const InstanceTools = [
{ name: "playlist_add", content: "Add Widget", id: "addWidget" }, { name: "playlist_add", content: "Add Widget", id: "addWidget" },
@ -192,7 +190,6 @@ export const InstanceTools = [
{ name: "library_books", content: "Add Text", id: "addText" }, { name: "library_books", content: "Add Text", id: "addText" },
{ name: "merge", content: "Add Trace", id: "addTrace" }, { name: "merge", content: "Add Trace", id: "addTrace" },
{ name: "assignment", content: "Add Log", id: "addLog" }, { name: "assignment", content: "Add Log", id: "addLog" },
{ name: "save", content: "Apply", id: "apply" },
]; ];
export const EndpointTools = [ export const EndpointTools = [
{ name: "playlist_add", content: "Add Widget", id: "addWidget" }, { name: "playlist_add", content: "Add Widget", id: "addWidget" },
@ -201,28 +198,24 @@ export const EndpointTools = [
{ name: "device_hub", content: "Add Topology", id: "addTopology" }, { name: "device_hub", content: "Add Topology", id: "addTopology" },
{ name: "merge", content: "Add Trace", id: "addTrace" }, { name: "merge", content: "Add Trace", id: "addTrace" },
{ name: "assignment", content: "Add Log", id: "addLog" }, { name: "assignment", content: "Add Log", id: "addLog" },
{ name: "save", content: "Apply", id: "apply" },
]; ];
export const ServiceRelationTools = [ export const ServiceRelationTools = [
{ name: "playlist_add", content: "Add Widget", id: "addWidget" }, { name: "playlist_add", content: "Add Widget", id: "addWidget" },
{ name: "all_inbox", content: "Add Tab", id: "addTab" }, { name: "all_inbox", content: "Add Tab", id: "addTab" },
{ name: "library_books", content: "Add Text", id: "addText" }, { name: "library_books", content: "Add Text", id: "addText" },
{ name: "device_hub", content: "Add Topology", id: "addTopology" }, { name: "device_hub", content: "Add Topology", id: "addTopology" },
{ name: "save", content: "Apply", id: "apply" },
]; ];
export const EndpointRelationTools = [ export const EndpointRelationTools = [
{ name: "playlist_add", content: "Add Widget", id: "addWidget" }, { name: "playlist_add", content: "Add Widget", id: "addWidget" },
{ name: "all_inbox", content: "Add Tab", id: "addTab" }, { name: "all_inbox", content: "Add Tab", id: "addTab" },
{ name: "library_books", content: "Add Text", id: "addText" }, { name: "library_books", content: "Add Text", id: "addText" },
{ name: "save", content: "Apply", id: "apply" },
]; ];
export const InstanceRelationTools = [ export const InstanceRelationTools = [
{ name: "playlist_add", content: "Add Widget", id: "addWidget" }, { name: "playlist_add", content: "Add Widget", id: "addWidget" },
{ name: "all_inbox", content: "Add Tab", id: "addTab" }, { name: "all_inbox", content: "Add Tab", id: "addTab" },
{ name: "library_books", content: "Add Text", id: "addText" }, { name: "library_books", content: "Add Text", id: "addText" },
{ name: "device_hub", content: "Add Topology", id: "addTopology" }, { name: "device_hub", content: "Add Topology", id: "addTopology" },
{ name: "save", content: "Apply", id: "apply" },
]; ];
export const ScopeType = [ export const ScopeType = [

View File

@ -22,13 +22,14 @@ limitations under the License. -->
> >
{{ singleVal.toFixed(2) }} {{ singleVal.toFixed(2) }}
<span v-show="config.showUnit"> <span v-show="config.showUnit">
{{ metricConfig[0]?.unit }} {{ decodeURIComponent(unit) }}
</span> </span>
</div> </div>
<div class="center no-data" v-else>No Data</div> <div class="center no-data" v-else>{{ t("noData") }}</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, PropType } from "vue"; import { computed, PropType } from "vue";
import { useI18n } from "vue-i18n";
import { CardConfig, MetricConfigOpt } from "@/types/dashboard"; import { CardConfig, MetricConfigOpt } from "@/types/dashboard";
/*global defineProps */ /*global defineProps */
@ -47,9 +48,13 @@ const props = defineProps({
}), }),
}, },
}); });
const { t } = useI18n();
const metricConfig = computed(() => props.config.metricConfig || []); const metricConfig = computed(() => props.config.metricConfig || []);
const key = computed(() => Object.keys(props.data)[0]); const key = computed(() => Object.keys(props.data)[0]);
const singleVal = computed(() => Number(props.data[key.value])); const singleVal = computed(() => Number(props.data[key.value]));
const unit = computed(
() => metricConfig.value[0] && encodeURIComponent(metricConfig.value[0].unit)
);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.chart-card { .chart-card {

View File

@ -43,8 +43,8 @@ limitations under the License. -->
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
v-for="(metric, index) in config.metrics" v-for="(metric, index) in colMetrics"
:label="`${metric} ${getUnit(index)}`" :label="`${metric} ${decodeURIComponent(getUnit(index))}`"
:key="metric + index" :key="metric + index"
> >
<template #default="scope"> <template #default="scope">
@ -73,7 +73,7 @@ limitations under the License. -->
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch } from "vue"; import { ref, watch, computed } from "vue";
import { useSelectorStore } from "@/store/modules/selectors"; import { useSelectorStore } from "@/store/modules/selectors";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import type { PropType } from "vue"; import type { PropType } from "vue";
@ -118,6 +118,7 @@ const dashboardStore = useDashboardStore();
const chartLoading = ref<boolean>(false); const chartLoading = ref<boolean>(false);
const endpoints = ref<Endpoint[]>([]); const endpoints = ref<Endpoint[]>([]);
const searchText = ref<string>(""); const searchText = ref<string>("");
const colMetrics = computed(() => props.config.metrics.map((d: string) => d));
queryEndpoints(); queryEndpoints();
@ -187,9 +188,9 @@ function getUnit(index: number) {
props.config.metricConfig[index].unit) || props.config.metricConfig[index].unit) ||
""; "";
if (u) { if (u) {
return `(${u})`; return `(${encodeURIComponent(u)})`;
} }
return u; return encodeURIComponent("");
} }
watch( watch(
() => [props.config.metricTypes, props.config.metrics], () => [props.config.metricTypes, props.config.metrics],

View File

@ -43,8 +43,8 @@ limitations under the License. -->
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
v-for="(metric, index) in config.metrics" v-for="(metric, index) in colMetrics"
:label="`${metric} ${getUnit(index)}`" :label="`${metric} ${decodeURIComponent(getUnit(index))}`"
:key="metric + index" :key="metric + index"
> >
<template #default="scope"> <template #default="scope">
@ -103,7 +103,7 @@ limitations under the License. -->
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch } from "vue"; import { ref, watch, computed } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import type { PropType } from "vue"; import type { PropType } from "vue";
@ -149,6 +149,7 @@ const chartLoading = ref<boolean>(false);
const instances = ref<Instance[]>([]); // current instances const instances = ref<Instance[]>([]); // current instances
const pageSize = 10; const pageSize = 10;
const searchText = ref<string>(""); const searchText = ref<string>("");
const colMetrics = computed(() => props.config.metrics.map((d: string) => d));
queryInstance(); queryInstance();
async function queryInstance() { async function queryInstance() {
@ -238,9 +239,9 @@ function getUnit(index: number) {
props.config.metricConfig[index].unit) || props.config.metricConfig[index].unit) ||
""; "";
if (u) { if (u) {
return `(${u})`; return `(${encodeURIComponent(u)})`;
} }
return u; return encodeURIComponent("");
} }
watch( watch(

View File

@ -150,12 +150,14 @@ function getOption() {
color: "#ccc", color: "#ccc",
}, },
enterable: true, enterable: true,
confine: true,
extraCssText: "max-height: 300px; overflow: auto; border: none;", extraCssText: "max-height: 300px; overflow: auto; border: none;",
}; };
const tips = { const tips = {
formatter(params: any) { formatter(params: any) {
return `${params[0].value[1]}`; return `${params[0].value[1]}`;
}, },
confine: true,
extraCssText: `height: 20px; padding:0 2px;`, extraCssText: `height: 20px; padding:0 2px;`,
trigger: "axis", trigger: "axis",
textStyle: { textStyle: {

View File

@ -55,8 +55,8 @@ limitations under the License. -->
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
v-for="(metric, index) in config.metrics" v-for="(metric, index) in colMetrics"
:label="`${metric} ${getUnit(index)}`" :label="`${metric} ${decodeURIComponent(getUnit(index))}`"
:key="metric + index" :key="metric + index"
> >
<template #default="scope"> <template #default="scope">
@ -96,7 +96,7 @@ limitations under the License. -->
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { watch, ref } from "vue"; import { watch, ref, computed } from "vue";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import type { PropType } from "vue"; import type { PropType } from "vue";
import { ServiceListConfig } from "@/types/dashboard"; import { ServiceListConfig } from "@/types/dashboard";
@ -138,6 +138,9 @@ const services = ref<Service[]>([]);
const searchText = ref<string>(""); const searchText = ref<string>("");
const groups = ref<any>({}); const groups = ref<any>({});
const sortServices = ref<(Service & { merge: boolean })[]>([]); const sortServices = ref<(Service & { merge: boolean })[]>([]);
const colMetrics = computed(() =>
props.config.metrics.filter((d: string) => d)
);
queryServices(); queryServices();
@ -278,9 +281,9 @@ function getUnit(index: number) {
props.config.metricConfig[index].unit) || props.config.metricConfig[index].unit) ||
""; "";
if (u) { if (u) {
return `(${u})`; return `(${encodeURIComponent(u)})`;
} }
return u; return encodeURIComponent("");
} }
watch( watch(
() => [props.config.metricTypes, props.config.metrics], () => [props.config.metricTypes, props.config.metrics],

View File

@ -80,24 +80,39 @@ limitations under the License. -->
</div> </div>
<div class="flex-h tools" v-loading="loading"> <div class="flex-h tools" v-loading="loading">
<div class="tool-icons flex-h" v-if="dashboardStore.editMode"> <div class="tool-icons flex-h" v-if="dashboardStore.editMode">
<span <el-dropdown content="Controls" placement="bottom">
@click="clickIcons(t)" <i>
v-for="(t, index) in toolIcons" <Icon class="icon-btn" size="sm" iconName="control" />
:key="index" </i>
:title="t.content" <template #dropdown>
> <el-dropdown-menu>
<el-tooltip :content="t.content" placement="bottom"> <el-dropdown-item
<i> @click="clickIcons(t)"
<Icon class="icon-btn" size="sm" :iconName="t.name" /> v-for="(t, index) in toolIcons"
</i> :key="index"
</el-tooltip> :title="t.content"
</span> >
<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>
<div class="switch"> <div class="switch">
<el-switch <el-switch
v-model="dashboardStore.editMode" v-model="dashboardStore.editMode"
active-text="Edit" active-text="Edit"
inactive-text="View" inactive-text="View"
size="small"
inline-prompt
active-color="#409eff"
inactive-color="#999"
@change="changeMode" @change="changeMode"
/> />
</div> </div>
@ -341,13 +356,13 @@ function changeMode() {
ElMessage.warning(t("viewWarning")); 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 }) { 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 ( if (
dashboardStore.selectedGrid && dashboardStore.selectedGrid &&
dashboardStore.selectedGrid.type === "Tab" dashboardStore.selectedGrid.type === "Tab"
@ -545,6 +560,7 @@ function searchDestPods(query: string) {
.tools { .tools {
justify-content: space-between; justify-content: space-between;
height: auto;
} }
.icon-btn { .icon-btn {