This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-booster-ui.git


The following commit(s) were added to refs/heads/main by this push:
     new 61449f4b feat: add content decorations to Table and Card widgets (#419)
61449f4b is described below

commit 61449f4b172a143d96cca139bed50839f5f2a5d6
Author: Fine0830 <[email protected]>
AuthorDate: Tue Oct 15 16:25:21 2024 +0800

    feat: add content decorations to Table and Card widgets (#419)
---
 src/locales/lang/en.ts                             |   1 +
 src/locales/lang/es.ts                             |   1 +
 src/locales/lang/zh.ts                             |   1 +
 src/types/dashboard.d.ts                           |   1 +
 src/views/dashboard/Widget.vue                     |   1 +
 src/views/dashboard/configuration/Widget.vue       |   3 +-
 .../configuration/widget/graph-styles/Card.vue     |   7 +-
 .../configuration/widget/graph-styles/Table.vue    |   5 ++
 .../graph-styles/components/ContentDecorations.vue | 100 +++++++++++++++++++++
 src/views/dashboard/graphs/Card.vue                |   4 +-
 src/views/dashboard/graphs/Table.vue               |   8 +-
 11 files changed, 128 insertions(+), 4 deletions(-)

diff --git a/src/locales/lang/en.ts b/src/locales/lang/en.ts
index 4d816ad7..0c6df128 100644
--- a/src/locales/lang/en.ts
+++ b/src/locales/lang/en.ts
@@ -386,5 +386,6 @@ const msg = {
   tabExpressions: "Tab Expressions",
   hierarchyNodeMetrics: "Metrics for Hierarchy Graph Node",
   hierarchyNodeDashboard: "As dashboard for Hierarchy Graph Node",
+  contentDecorations: "Content Decorations",
 };
 export default msg;
diff --git a/src/locales/lang/es.ts b/src/locales/lang/es.ts
index fbf22826..c643df61 100644
--- a/src/locales/lang/es.ts
+++ b/src/locales/lang/es.ts
@@ -386,5 +386,6 @@ const msg = {
   tabExpressions: "Tab Expressions",
   hierarchyNodeMetrics: "Metrics for Hierarchy Graph Node",
   hierarchyNodeDashboard: "As dashboard for Hierarchy Graph Node",
+  contentDecorations: "Content Decorations",
 };
 export default msg;
diff --git a/src/locales/lang/zh.ts b/src/locales/lang/zh.ts
index 0a2d5c0f..1a4ee12f 100644
--- a/src/locales/lang/zh.ts
+++ b/src/locales/lang/zh.ts
@@ -384,5 +384,6 @@ const msg = {
   tabExpressions: "Tab表达式",
   hierarchyNodeMetrics: "层次图节点的指标",
   hierarchyNodeDashboard: "作为层次图节点的dashboard",
+  contentDecorations: "内容装饰",
 };
 export default msg;
diff --git a/src/types/dashboard.d.ts b/src/types/dashboard.d.ts
index 5a24e53d..90243c77 100644
--- a/src/types/dashboard.d.ts
+++ b/src/types/dashboard.d.ts
@@ -123,6 +123,7 @@ export interface CardConfig {
   fontSize?: number;
   showUnit?: boolean;
   textAlign?: "center" | "right" | "left";
+  decorations?: { [key: string]: string };
 }
 
 export interface TextConfig {
diff --git a/src/views/dashboard/Widget.vue b/src/views/dashboard/Widget.vue
index a2f01a42..fc0b00ca 100644
--- a/src/views/dashboard/Widget.vue
+++ b/src/views/dashboard/Widget.vue
@@ -32,6 +32,7 @@ limitations under the License. -->
         :config="{
           i: 0,
           ...graph,
+          decorations: graph?.decorations,
           metricConfig: config.metricConfig,
           expressions: config.expressions || [],
           typesOfMQE: typesOfMQE || [],
diff --git a/src/views/dashboard/configuration/Widget.vue 
b/src/views/dashboard/configuration/Widget.vue
index 62248e94..dc36d47f 100644
--- a/src/views/dashboard/configuration/Widget.vue
+++ b/src/views/dashboard/configuration/Widget.vue
@@ -32,7 +32,8 @@ limitations under the License. -->
           :data="states.source"
           :config="{
             ...graph,
-            legend: (dashboardStore.selectedGrid.graph || {}).legend,
+            decorations: dashboardStore.selectedGrid.graph?.decorations,
+            legend: dashboardStore.selectedGrid.graph?.legend,
             i: dashboardStore.selectedGrid.i,
             metricConfig: dashboardStore.selectedGrid.metricConfig,
             relatedTrace: dashboardStore.selectedGrid.relatedTrace,
diff --git a/src/views/dashboard/configuration/widget/graph-styles/Card.vue 
b/src/views/dashboard/configuration/widget/graph-styles/Card.vue
index 79a43992..b90195f3 100644
--- a/src/views/dashboard/configuration/widget/graph-styles/Card.vue
+++ b/src/views/dashboard/configuration/widget/graph-styles/Card.vue
@@ -13,6 +13,10 @@ 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>
+    <span class="label">{{ t("contentDecorations") }}</span>
+    <content-decorations />
+  </div>
   <div>
     <span class="label">{{ t("fontSize") }}</span>
     <el-slider
@@ -26,7 +30,7 @@ limitations under the License. -->
       @change="updateConfig({ fontSize })"
     />
   </div>
-  <div class="item">
+  <div>
     <span class="label">{{ t("showUnit") }}</span>
     <el-switch v-model="showUnit" active-text="Yes" inactive-text="No" 
@change="updateConfig({ showUnit })" />
   </div>
@@ -35,6 +39,7 @@ limitations under the License. -->
   import { ref } from "vue";
   import { useI18n } from "vue-i18n";
   import { useDashboardStore } from "@/store/modules/dashboard";
+  import ContentDecorations from "./components/ContentDecorations.vue";
 
   const { t } = useI18n();
   const dashboardStore = useDashboardStore();
diff --git a/src/views/dashboard/configuration/widget/graph-styles/Table.vue 
b/src/views/dashboard/configuration/widget/graph-styles/Table.vue
index 65ca8d70..9b350ed0 100644
--- a/src/views/dashboard/configuration/widget/graph-styles/Table.vue
+++ b/src/views/dashboard/configuration/widget/graph-styles/Table.vue
@@ -14,6 +14,10 @@ See the License for the specific language governing 
permissions and
 limitations under the License. -->
 <template>
   <div>
+    <span class="label">{{ t("contentDecorations") }}</span>
+    <content-decorations />
+  </div>
+  <div class="item">
     <span class="label">{{ t("showValues") }}</span>
     <el-switch
       v-model="showTableValues"
@@ -37,6 +41,7 @@ limitations under the License. -->
   import { ref } from "vue";
   import { useI18n } from "vue-i18n";
   import { useDashboardStore } from "@/store/modules/dashboard";
+  import ContentDecorations from "./components/ContentDecorations.vue";
 
   const { t } = useI18n();
   const dashboardStore = useDashboardStore();
diff --git 
a/src/views/dashboard/configuration/widget/graph-styles/components/ContentDecorations.vue
 
b/src/views/dashboard/configuration/widget/graph-styles/components/ContentDecorations.vue
new file mode 100644
index 00000000..4931e65a
--- /dev/null
+++ 
b/src/views/dashboard/configuration/widget/graph-styles/components/ContentDecorations.vue
@@ -0,0 +1,100 @@
+<!-- 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 v-for="(key, index) in keys" :key="index" class="mb-10 flex-h">
+    <div class="content-decoration" contenteditable="true" 
@blur="changeKeys($event, index)">
+      {{ key }}
+    </div>
+    <div class="ml-5 mr-10">:</div>
+    <div class="content-decoration" contenteditable="true" 
@blur="changeValues($event, key)">
+      {{ decorations[key] }}
+    </div>
+    <div v-if="index === keys.length - 1">
+      <Icon class="cp mr-5" iconName="add_circle_outlinecontrol_point" 
size="middle" @click="addDecoration" />
+      <Icon
+        v-if="index !== 0"
+        class="cp"
+        iconName="remove_circle_outline"
+        size="middle"
+        @click="deleteDecoration(index)"
+      />
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+  import { ref } from "vue";
+  import { useDashboardStore } from "@/store/modules/dashboard";
+
+  const dashboardStore = useDashboardStore();
+  const graph = dashboardStore.selectedGrid.graph;
+  const decorations = ref<{ [key: string]: string }>(graph?.decorations || {});
+  const keys = ref<string[]>(graph.decorations ? 
Object.keys(decorations.value) : [""]);
+
+  function changeKeys(event: any, index: number) {
+    const params = event.target.textContent || "";
+    const list = Object.keys(decorations.value);
+    if (params) {
+      decorations.value[params] = decorations.value[list[index]];
+    }
+    delete decorations.value[list[index]];
+    keys.value = Object.keys(decorations.value);
+    updateConfig({ decorations: decorations.value });
+  }
+
+  function changeValues(event: any, key: string) {
+    decorations.value[key] = event.target.textContent || "";
+    updateConfig({ decorations: decorations.value });
+  }
+
+  function addDecoration() {
+    keys.value.push("");
+  }
+
+  function deleteDecoration(index: number) {
+    if (!keys.value.length) {
+      return;
+    }
+    if (!keys.value[index]) {
+      return;
+    }
+    delete decorations.value[keys.value[index]];
+    keys.value.splice(index, 1);
+    updateConfig({ decorations: decorations.value });
+  }
+
+  function updateConfig(param: { [key: string]: unknown }) {
+    const graph = {
+      ...dashboardStore.selectedGrid.graph,
+      ...param,
+    };
+    dashboardStore.selectWidget({ ...dashboardStore.selectedGrid, graph });
+  }
+</script>
+<style lang="scss" scoped>
+  .content-decoration {
+    width: 200px;
+    border: 1px solid $border-color;
+    cursor: text;
+    padding: 0 5px;
+    border-radius: 3px;
+    outline: none;
+    margin-right: 5px;
+    min-height: 26px;
+
+    &:focus {
+      border-color: $active-color;
+    }
+  }
+</style>
diff --git a/src/views/dashboard/graphs/Card.vue 
b/src/views/dashboard/graphs/Card.vue
index ff5b2c33..0c4b34da 100644
--- a/src/views/dashboard/graphs/Card.vue
+++ b/src/views/dashboard/graphs/Card.vue
@@ -22,7 +22,7 @@ limitations under the License. -->
       justifyContent: config.textAlign || 'center',
     }"
   >
-    {{ singleVal }}
+    {{ decorations[singleVal] || singleVal }}
     <span class="unit" v-show="config.showUnit && unit">
       {{ decodeURIComponent(unit) }}
     </span>
@@ -48,11 +48,13 @@ limitations under the License. -->
         showUnit: true,
         textAlign: "center",
         metricConfig: [],
+        decorations: {},
       }),
     },
   });
   const { t } = useI18n();
   const metricConfig = computed(() => props.config.metricConfig || []);
+  const decorations = computed(() => props.config.decorations || {});
   const key = computed(() => Object.keys(props.data)[0]);
   const singleVal = computed(() =>
     Array.isArray(props.data[key.value]) ? props.data[key.value][0] : 
props.data[key.value],
diff --git a/src/views/dashboard/graphs/Table.vue 
b/src/views/dashboard/graphs/Table.vue
index 7818498d..0d663e21 100644
--- a/src/views/dashboard/graphs/Table.vue
+++ b/src/views/dashboard/graphs/Table.vue
@@ -37,7 +37,7 @@ limitations under the License. -->
         >{{ k.split("=")[1] }}</div
       >
       <div class="value-col" v-if="config.showTableValues">
-        {{ data[(keys as string[]).join(",")][data[(keys as 
string[]).join(",")].length - 1 || 0] }}
+        {{ getColValue(keys) }}
       </div>
     </div>
   </div>
@@ -58,12 +58,14 @@ limitations under the License. -->
         showTableValues: boolean;
         tableHeaderCol2: string;
         typesOfMQE: string[];
+        decorations: {};
       }>,
       default: () => ({ showTableValues: true }),
     },
   });
 
   const { t } = useI18n();
+  const decorations = computed<{ [key: number]: string }>(() => 
props.config.decorations || {});
   const nameWidth = computed(() => (props.config.showTableValues ? 80 : 100));
   const dataKeys = computed(() => {
     const keys = Object.keys(props.data || {}).filter(
@@ -73,6 +75,10 @@ limitations under the License. -->
 
     return list;
   });
+  function getColValue(keys: string[]) {
+    const val = props.data[(keys as string[]).join(",")][props.data[(keys as 
string[]).join(",")].length - 1 || 0];
+    return decorations.value[val] || val;
+  }
 </script>
 <style lang="scss" scoped>
   .chart-table {

Reply via email to