You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2023/01/03 08:12:49 UTC

[skywalking-booster-ui] branch main updated: feat: add a iframe widget for zipkin ui (#215)

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 8785817  feat: add a iframe widget for zipkin ui (#215)
8785817 is described below

commit 8785817efed1ea255f6e6101c3ab042c0caa7762
Author: Fine0830 <fa...@gmail.com>
AuthorDate: Tue Jan 3 16:12:45 2023 +0800

    feat: add a iframe widget for zipkin ui (#215)
---
 src/assets/icons/add_iframe.svg                    | 15 ++++
 src/locales/lang/en.ts                             |  2 +
 src/locales/lang/es.ts                             |  2 +
 src/locales/lang/zh.ts                             |  2 +
 src/store/data.ts                                  |  2 +
 src/store/modules/dashboard.ts                     |  6 +-
 .../dashboard/configuration/ThirdPartyApp.vue      | 89 ++++++++++++++++++++++
 src/views/dashboard/configuration/index.ts         |  2 +
 src/views/dashboard/controls/Text.vue              |  4 +-
 .../controls/{Text.vue => ThirdPartyApp.vue}       | 42 +++++-----
 src/views/dashboard/controls/index.ts              |  2 +
 src/views/dashboard/controls/tab.ts                |  2 +
 src/views/dashboard/data.ts                        | 10 ++-
 src/views/dashboard/panel/Tool.vue                 |  6 ++
 vite.config.ts                                     | 12 ++-
 15 files changed, 166 insertions(+), 32 deletions(-)

diff --git a/src/assets/icons/add_iframe.svg b/src/assets/icons/add_iframe.svg
new file mode 100644
index 0000000..5fa776c
--- /dev/null
+++ b/src/assets/icons/add_iframe.svg
@@ -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 class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path d="M856.32 428.064a32 32 0 0 0-32 32v163.328H372.48c-0.896 0-1.664 0.448-2.56 0.512v-177.696h244.48a32 32 0 1 0 0-64H130.56c-0.896 0-1.664 0.448-2.56 0.512V231.68h488.16a32 32 0 1 0 0-64H96a32 32 0 0 0-32 32v701.824a32 32 0 0 0 32 32h760.32a32 32 0 0 0 32-32V460.064a32 32 0 0 0-32-32zM128 445.728c0.896 0.064 1.664 0.512 2.56 0.512h175.36v423.264H128V445.728z m241.92 423 [...]
\ No newline at end of file
diff --git a/src/locales/lang/en.ts b/src/locales/lang/en.ts
index cdcceae..60c6c9a 100644
--- a/src/locales/lang/en.ts
+++ b/src/locales/lang/en.ts
@@ -179,6 +179,8 @@ const msg = {
   when4xx: "Sample HTTP requests and responses with tracing when response code between 400 and 499",
   when5xx: "Sample HTTP requests and responses with tracing when response code between 500 and 599",
   taskTitle: "HTTP request and response collecting rules",
+  iframeWidgetTip: "Add a link to a widget",
+  iframeSrc: "Iframe Link",
   seconds: "Seconds",
   hourTip: "Select Hour",
   minuteTip: "Select Minute",
diff --git a/src/locales/lang/es.ts b/src/locales/lang/es.ts
index b4485f0..3cbcd4c 100644
--- a/src/locales/lang/es.ts
+++ b/src/locales/lang/es.ts
@@ -162,6 +162,8 @@ const msg = {
   latency: "Retraso",
   metricValues: "Valor métrico",
   legendValues: "Valor de la leyenda",
+  iframeWidgetTip: "Añadir enlaces a los gadgets",
+  iframeSrc: "Enlace Iframe",
   seconds: "Segundos",
   hourTip: "Seleccione Hora",
   minuteTip: "Seleccione Minuto",
diff --git a/src/locales/lang/zh.ts b/src/locales/lang/zh.ts
index 54f4f72..59f7cdf 100644
--- a/src/locales/lang/zh.ts
+++ b/src/locales/lang/zh.ts
@@ -176,6 +176,8 @@ const msg = {
   when4xx: "当响应代码介于400和499之间时,带有跟踪的HTTP请求和响应示例",
   when5xx: "当响应代码介于500和599之间时,带有跟踪的HTTP请求和响应示例",
   taskTitle: "HTTP请求和响应收集规则",
+  iframeWidgetTip: "添加widget的链接",
+  iframeSrc: "Iframe链接",
   seconds: "秒",
   hourTip: "选择小时",
   minuteTip: "选择分钟",
diff --git a/src/store/data.ts b/src/store/data.ts
index ce31dd2..04a51f5 100644
--- a/src/store/data.ts
+++ b/src/store/data.ts
@@ -37,3 +37,5 @@ export const TimeRangeConfig = {
   textAlign: "center",
   text: "text",
 };
+
+export const ControlsTypes = ["Trace", "Profile", "Log", "DemandLog", "Ebpf", "NetworkProfiling", "ThirdPartyApp"];
diff --git a/src/store/modules/dashboard.ts b/src/store/modules/dashboard.ts
index 3258bfb..7a20c78 100644
--- a/src/store/modules/dashboard.ts
+++ b/src/store/modules/dashboard.ts
@@ -21,7 +21,7 @@ import graphql from "@/graphql";
 import query from "@/graphql/fetch";
 import type { DashboardItem } from "@/types/dashboard";
 import { useSelectorStore } from "@/store/modules/selectors";
-import { NewControl, TextConfig, TimeRangeConfig } from "../data";
+import { NewControl, TextConfig, TimeRangeConfig, ControlsTypes } from "../data";
 import type { AxiosResponse } from "axios";
 import { ElMessage } from "element-plus";
 import { useI18n } from "vue-i18n";
@@ -108,7 +108,7 @@ export const dashboardStore = defineStore({
           depth: this.entity === EntityType[1].value ? 1 : this.entity === EntityType[0].value ? 2 : 3,
         };
       }
-      if (["Trace", "Profile", "Log", "DemandLog", "Ebpf", "NetworkProfiling"].includes(type)) {
+      if (ControlsTypes.includes(type)) {
         newItem.h = 36;
       }
       if (type === "Text") {
@@ -168,7 +168,7 @@ export const dashboardStore = defineStore({
           showDepth: true,
         };
       }
-      if (["Trace", "Profile", "Log", "DemandLog", "Ebpf", "NetworkProfiling"].includes(type)) {
+      if (ControlsTypes.includes(type)) {
         newItem.h = 32;
       }
       if (type === "Text") {
diff --git a/src/views/dashboard/configuration/ThirdPartyApp.vue b/src/views/dashboard/configuration/ThirdPartyApp.vue
new file mode 100644
index 0000000..da700dc
--- /dev/null
+++ b/src/views/dashboard/configuration/ThirdPartyApp.vue
@@ -0,0 +1,89 @@
+<!-- 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="item">
+    <span class="label">{{ t("iframeSrc") }}</span>
+    <el-input class="input" v-model="url" size="small" @change="changeConfig({ url: encodeURIComponent(url) })" />
+  </div>
+  <div class="footer">
+    <el-button size="small" @click="cancelConfig">
+      {{ t("cancel") }}
+    </el-button>
+    <el-button size="small" type="primary" @click="applyConfig">
+      {{ t("apply") }}
+    </el-button>
+  </div>
+</template>
+<script lang="ts" setup>
+  import { useI18n } from "vue-i18n";
+  import { ref } from "vue";
+  import { useDashboardStore } from "@/store/modules/dashboard";
+  const { t } = useI18n();
+  const dashboardStore = useDashboardStore();
+  const originConfig = dashboardStore.selectedGrid;
+  const widget = originConfig.widget || {};
+  const url = ref(widget.url || "");
+  function changeConfig(param: { [key: string]: string }) {
+    const key = Object.keys(param)[0];
+    if (!key) {
+      return;
+    }
+    const { selectedGrid } = dashboardStore;
+    const widget = {
+      ...dashboardStore.selectedGrid.widget,
+      [key]: decodeURIComponent(param[key]),
+    };
+    dashboardStore.selectWidget({ ...selectedGrid, widget });
+  }
+  function applyConfig() {
+    dashboardStore.setConfigPanel(false);
+    dashboardStore.setConfigs(dashboardStore.selectedGrid);
+  }
+
+  function cancelConfig() {
+    dashboardStore.selectWidget(originConfig);
+    dashboardStore.setConfigPanel(false);
+  }
+</script>
+<style lang="scss" scoped>
+  .slider {
+    width: 500px;
+    margin-top: -3px;
+  }
+
+  .label {
+    font-size: 13px;
+    font-weight: 500;
+    display: block;
+    margin-bottom: 5px;
+  }
+
+  .input {
+    width: 500px;
+  }
+
+  .item {
+    margin-bottom: 10px;
+  }
+
+  .footer {
+    position: fixed;
+    bottom: 0;
+    right: 0;
+    border-top: 1px solid #eee;
+    padding: 10px;
+    text-align: right;
+    width: 100%;
+    background-color: #fff;
+  }
+</style>
diff --git a/src/views/dashboard/configuration/index.ts b/src/views/dashboard/configuration/index.ts
index 0055f82..1fb47e4 100644
--- a/src/views/dashboard/configuration/index.ts
+++ b/src/views/dashboard/configuration/index.ts
@@ -20,6 +20,7 @@ import Widget from "./Widget.vue";
 import Topology from "./Topology.vue";
 import Event from "./Event.vue";
 import TimeRange from "./TimeRange.vue";
+import ThirdPartyApp from "./ThirdPartyApp.vue";
 
 export default {
   Text,
@@ -27,4 +28,5 @@ export default {
   Topology,
   Event,
   TimeRange,
+  ThirdPartyApp,
 };
diff --git a/src/views/dashboard/controls/Text.vue b/src/views/dashboard/controls/Text.vue
index 209694d..3c637c7 100644
--- a/src/views/dashboard/controls/Text.vue
+++ b/src/views/dashboard/controls/Text.vue
@@ -13,7 +13,7 @@ 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="topology">
+  <div class="text">
     <div class="header">
       <el-popover placement="bottom" trigger="click" :width="100" v-if="dashboardStore.editMode">
         <template #reference>
@@ -77,7 +77,7 @@ limitations under the License. -->
   }
 </script>
 <style lang="scss" scoped>
-  .topology {
+  .text {
     font-size: 12px;
     height: 100%;
     position: relative;
diff --git a/src/views/dashboard/controls/Text.vue b/src/views/dashboard/controls/ThirdPartyApp.vue
similarity index 81%
copy from src/views/dashboard/controls/Text.vue
copy to src/views/dashboard/controls/ThirdPartyApp.vue
index 209694d..81b476d 100644
--- a/src/views/dashboard/controls/Text.vue
+++ b/src/views/dashboard/controls/ThirdPartyApp.vue
@@ -13,7 +13,7 @@ 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="topology">
+  <div class="text">
     <div class="header">
       <el-popover placement="bottom" trigger="click" :width="100" v-if="dashboardStore.editMode">
         <template #reference>
@@ -29,23 +29,16 @@ limitations under the License. -->
         </div>
       </el-popover>
     </div>
-    <div
-      class="body"
-      :style="{
-        backgroundColor: TextColors[graph.backgroundColor],
-        justifyContent: graph.textAlign,
-      }"
-    >
-      <a
-        :href="graph.url"
-        target="_blank"
-        :style="{
-          color: TextColors[graph.fontColor],
-          fontSize: graph.fontSize + 'px',
-        }"
-      >
-        {{ graph.content }}
-      </a>
+    <div class="body">
+      <iframe
+        v-if="widget.url"
+        :src="widget.url"
+        width="100%"
+        height="100%"
+        scrolling="no"
+        style="border: none"
+      ></iframe>
+      <div v-else class="tips">{{ t("iframeWidgetTip") }}</div>
     </div>
   </div>
 </template>
@@ -54,7 +47,6 @@ limitations under the License. -->
   import type { PropType } from "vue";
   import { useI18n } from "vue-i18n";
   import { useDashboardStore } from "@/store/modules/dashboard";
-  import { TextColors } from "@/views/dashboard/data";
 
   /*global defineProps */
   const props = defineProps({
@@ -65,8 +57,8 @@ limitations under the License. -->
     activeIndex: { type: String, default: "" },
   });
   const { t } = useI18n();
-  const graph = computed(() => props.data.graph || {});
   const dashboardStore = useDashboardStore();
+  const widget = computed(() => props.data.widget || {});
 
   function removeTopo() {
     dashboardStore.removeControls(props.data);
@@ -77,7 +69,7 @@ limitations under the License. -->
   }
 </script>
 <style lang="scss" scoped>
-  .topology {
+  .text {
     font-size: 12px;
     height: 100%;
     position: relative;
@@ -94,7 +86,6 @@ limitations under the License. -->
   }
 
   .body {
-    padding: 0 20px 0 10px;
     width: 100%;
     height: 100%;
     cursor: pointer;
@@ -115,4 +106,11 @@ limitations under the License. -->
       background-color: #eee;
     }
   }
+
+  .tips {
+    font-size: 14px;
+    color: #888;
+    width: 100%;
+    text-align: center;
+  }
 </style>
diff --git a/src/views/dashboard/controls/index.ts b/src/views/dashboard/controls/index.ts
index 70cb7f9..6b4c5fd 100644
--- a/src/views/dashboard/controls/index.ts
+++ b/src/views/dashboard/controls/index.ts
@@ -26,6 +26,7 @@ import DemandLog from "./DemandLog.vue";
 import Event from "./Event.vue";
 import NetworkProfiling from "./NetworkProfiling.vue";
 import TimeRange from "./TimeRange.vue";
+import ThirdPartyApp from "./ThirdPartyApp.vue";
 
 export default {
   Tab,
@@ -40,4 +41,5 @@ export default {
   Event,
   NetworkProfiling,
   TimeRange,
+  ThirdPartyApp,
 };
diff --git a/src/views/dashboard/controls/tab.ts b/src/views/dashboard/controls/tab.ts
index f081a10..b619460 100644
--- a/src/views/dashboard/controls/tab.ts
+++ b/src/views/dashboard/controls/tab.ts
@@ -25,6 +25,7 @@ import DemandLog from "./DemandLog.vue";
 import Event from "./Event.vue";
 import NetworkProfiling from "./NetworkProfiling.vue";
 import TimeRange from "./TimeRange.vue";
+import ThirdPartyApp from "./ThirdPartyApp.vue";
 
 export default {
   Widget,
@@ -38,4 +39,5 @@ export default {
   Event,
   NetworkProfiling,
   TimeRange,
+  ThirdPartyApp,
 };
diff --git a/src/views/dashboard/data.ts b/src/views/dashboard/data.ts
index ecb1331..56acd19 100644
--- a/src/views/dashboard/data.ts
+++ b/src/views/dashboard/data.ts
@@ -184,6 +184,7 @@ 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: "add_iframe", content: "Add Iframe", id: "addIframe" },
 ];
 export const ServiceTools = [
   { name: "playlist_add", content: "Add Widget", id: "addWidget" },
@@ -196,6 +197,7 @@ export const ServiceTools = [
   { name: "assignment", content: "Add Log", id: "addLog" },
   { name: "demand", content: "Add On Demand Log", id: "addDemandLog" },
   { name: "event", content: "Add Event", id: "addEvent" },
+  { name: "add_iframe", content: "Add Iframe", id: "addIframe" },
 ];
 export const InstanceTools = [
   { name: "playlist_add", content: "Add Widget", id: "addWidget" },
@@ -205,6 +207,7 @@ export const InstanceTools = [
   { name: "assignment", content: "Add Log", id: "addLog" },
   { name: "demand", content: "Add On Demand Log", id: "addDemandLog" },
   { name: "event", content: "Add Event", id: "addEvent" },
+  { name: "add_iframe", content: "Add Iframe", id: "addIframe" },
   {
     name: "timeline",
     content: "Add Network Profiling",
@@ -218,31 +221,36 @@ 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: "event", content: "Add Event", id: "addEvent" },
+  { name: "event", content: "Add Event", id: "c" },
+  { name: "add_iframe", content: "Add Iframe", id: "addIframe" },
 ];
 export const ProcessTools = [
   { name: "playlist_add", content: "Add Widget", id: "addWidget" },
   { name: "all_inbox", content: "Add Tabs", id: "addTab" },
   { name: "library_books", content: "Add Text", id: "addText" },
   { name: "time_range", content: "Add Time Range Text", id: "addTimeRange" },
+  { name: "add_iframe", content: "Add Iframe", id: "addIframe" },
 ];
 export const ServiceRelationTools = [
   { name: "playlist_add", content: "Add Widget", id: "addWidget" },
   { name: "all_inbox", content: "Add Tabs", id: "addTab" },
   { name: "library_books", content: "Add Text", id: "addText" },
   { name: "device_hub", content: "Add Topology", id: "addTopology" },
+  { name: "add_iframe", content: "Add Iframe", id: "addIframe" },
 ];
 
 export const EndpointRelationTools = [
   { name: "playlist_add", content: "Add Widget", id: "addWidget" },
   { name: "all_inbox", content: "Add Tabs", id: "addTab" },
   { name: "library_books", content: "Add Text", id: "addText" },
+  { name: "add_iframe", content: "Add Iframe", id: "addIframe" },
 ];
 export const InstanceRelationTools = [
   { name: "playlist_add", content: "Add Widget", id: "addWidget" },
   { name: "all_inbox", content: "Add Tabs", id: "addTab" },
   { name: "library_books", content: "Add Text", id: "addText" },
   { name: "device_hub", content: "Add Topology", id: "addTopology" },
+  { name: "add_iframe", content: "Add Iframe", id: "addIframe" },
 ];
 
 export const ScopeType = [
diff --git a/src/views/dashboard/panel/Tool.vue b/src/views/dashboard/panel/Tool.vue
index 2da10c4..5c2555c 100644
--- a/src/views/dashboard/panel/Tool.vue
+++ b/src/views/dashboard/panel/Tool.vue
@@ -448,6 +448,9 @@ limitations under the License. -->
       case "addTimeRange":
         dashboardStore.addTabControls("TimeRange");
         break;
+      case "addIframe":
+        dashboardStore.addTabControls("ThirdPartyApp");
+        break;
       default:
         ElMessage.info("Don't support this control");
         break;
@@ -492,6 +495,9 @@ limitations under the License. -->
       case "addTimeRange":
         dashboardStore.addControl("TimeRange");
         break;
+      case "addIframe":
+        dashboardStore.addControl("ThirdPartyApp");
+        break;
       default:
         dashboardStore.addControl("Widget");
     }
diff --git a/vite.config.ts b/vite.config.ts
index 9468b97..249c133 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -85,13 +85,17 @@ export default ({ mode }: ConfigEnv): UserConfig => {
             if (id.includes("node_modules")) {
               if (id.includes("lodash")) {
                 return "lodash";
-              } else if (id.includes("echarts")) {
+              }
+              if (id.includes("echarts")) {
                 return "echarts";
-              } else if (id.includes("element-plus")) {
+              }
+              if (id.includes("element-plus")) {
                 return "element-plus";
-              } else if (id.includes("monaco-editor")) {
+              }
+              if (id.includes("monaco-editor")) {
                 return "monaco-editor";
-              } else if (id.includes("d3")) {
+              }
+              if (id.includes("d3")) {
                 return "d3";
               }
             }