mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-05-14 09:00:50 +00:00
support multiple widgets
This commit is contained in:
parent
437383d4b2
commit
21420e7395
@ -61,7 +61,7 @@ onMounted(async () => {
|
|||||||
if (!instance) {
|
if (!instance) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
instance.on("click", (params: any) => {
|
instance.on("click", (params: unknown) => {
|
||||||
emits("select", params);
|
emits("select", params);
|
||||||
});
|
});
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
28
src/types/components.d.ts
vendored
28
src/types/components.d.ts
vendored
@ -5,36 +5,8 @@
|
|||||||
declare module '@vue/runtime-core' {
|
declare module '@vue/runtime-core' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
DateCalendar: typeof import('./../components/DateCalendar.vue')['default']
|
DateCalendar: typeof import('./../components/DateCalendar.vue')['default']
|
||||||
ElButton: typeof import('element-plus/es')['ElButton']
|
|
||||||
ElCollapse: typeof import('element-plus/es')['ElCollapse']
|
|
||||||
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
|
|
||||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
|
||||||
ElDropdown: typeof import('element-plus/es')['ElDropdown']
|
|
||||||
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
|
|
||||||
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
|
|
||||||
ElIcon: typeof import('element-plus/es')['ElIcon']
|
|
||||||
ElInput: typeof import('element-plus/es')['ElInput']
|
|
||||||
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
|
||||||
ElMenu: typeof import('element-plus/es')['ElMenu']
|
|
||||||
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
|
|
||||||
ElMenuItemGroup: typeof import('element-plus/es')['ElMenuItemGroup']
|
|
||||||
ElOption: typeof import('element-plus/es')['ElOption']
|
|
||||||
ElPagination: typeof import('element-plus/es')['ElPagination']
|
|
||||||
ElPopconfirm: typeof import('element-plus/es')['ElPopconfirm']
|
|
||||||
ElPopover: typeof import('element-plus/es')['ElPopover']
|
|
||||||
ElProgress: typeof import('element-plus/es')['ElProgress']
|
|
||||||
ElRadio: typeof import('element-plus/es')['ElRadio']
|
|
||||||
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
|
|
||||||
ElSelect: typeof import('element-plus/es')['ElSelect']
|
|
||||||
ElSlider: typeof import('element-plus/es')['ElSlider']
|
|
||||||
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
|
|
||||||
ElSwitch: typeof import('element-plus/es')['ElSwitch']
|
|
||||||
ElTable: typeof import('element-plus/es')['ElTable']
|
|
||||||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
|
||||||
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
|
||||||
Graph: typeof import('./../components/Graph.vue')['default']
|
Graph: typeof import('./../components/Graph.vue')['default']
|
||||||
Icon: typeof import('./../components/Icon.vue')['default']
|
Icon: typeof import('./../components/Icon.vue')['default']
|
||||||
Loading: typeof import('element-plus/es')['ElLoadingDirective']
|
|
||||||
Radio: typeof import('./../components/Radio.vue')['default']
|
Radio: typeof import('./../components/Radio.vue')['default']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
|
13
src/types/dashboard.d.ts
vendored
13
src/types/dashboard.d.ts
vendored
@ -37,6 +37,7 @@ export interface LayoutConfig {
|
|||||||
activedTabIndex?: number;
|
activedTabIndex?: number;
|
||||||
metricConfig?: MetricConfigOpt[];
|
metricConfig?: MetricConfigOpt[];
|
||||||
id?: string;
|
id?: string;
|
||||||
|
associate?: { widgetIds: string }[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MetricConfigOpt = {
|
export type MetricConfigOpt = {
|
||||||
@ -139,3 +140,15 @@ export interface TopologyConfig {
|
|||||||
depth?: number;
|
depth?: number;
|
||||||
showDepth?: boolean;
|
showDepth?: boolean;
|
||||||
}
|
}
|
||||||
|
export type EventParams = {
|
||||||
|
componentType: string;
|
||||||
|
seriesType: string;
|
||||||
|
seriesIndex: number;
|
||||||
|
seriesName: string;
|
||||||
|
name: string;
|
||||||
|
dataIndex: number;
|
||||||
|
data: Record<string, unknown>;
|
||||||
|
dataType: string;
|
||||||
|
value: number | number[];
|
||||||
|
color: string;
|
||||||
|
};
|
||||||
|
@ -16,12 +16,13 @@ limitations under the License. -->
|
|||||||
<div class="item">
|
<div class="item">
|
||||||
<span class="label">{{ t("widget") }}</span>
|
<span class="label">{{ t("widget") }}</span>
|
||||||
<Selector
|
<Selector
|
||||||
:value="widgetId"
|
:multiple="true"
|
||||||
|
:value="widgetIds"
|
||||||
:options="widgets"
|
:options="widgets"
|
||||||
size="small"
|
size="small"
|
||||||
placeholder="Select a widget"
|
placeholder="Select a widget"
|
||||||
@change="updateWidgetConfig({ associateWidget: $event[0].value })"
|
|
||||||
class="selectors"
|
class="selectors"
|
||||||
|
@change="updateWidgetConfig"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -31,13 +32,14 @@ import { useI18n } from "vue-i18n";
|
|||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
import getDashboard from "@/hooks/useDashboardsSession";
|
import getDashboard from "@/hooks/useDashboardsSession";
|
||||||
import { LayoutConfig } from "@/types/dashboard";
|
import { LayoutConfig } from "@/types/dashboard";
|
||||||
|
import { Option } from "@/types/app";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const dashboardStore = useDashboardStore();
|
const dashboardStore = useDashboardStore();
|
||||||
const associate = dashboardStore.selectedGrid.associate || {};
|
const associate = dashboardStore.selectedGrid.associate || {};
|
||||||
const widgetId = ref<string>(associate.widgetId || "");
|
const widgetIds = ref<string[]>(associate.widgetIds || []);
|
||||||
const widgets = computed(() => {
|
const widgets = computed(() => {
|
||||||
const isLinear = ["Bar", "Line"].includes(
|
const isLinear = ["Bar", "Line", "Area"].includes(
|
||||||
dashboardStore.selectedGrid.graph && dashboardStore.selectedGrid.graph.type
|
dashboardStore.selectedGrid.graph && dashboardStore.selectedGrid.graph.type
|
||||||
);
|
);
|
||||||
const isRank = ["TopList"].includes(
|
const isRank = ["TopList"].includes(
|
||||||
@ -47,14 +49,14 @@ const widgets = computed(() => {
|
|||||||
const items = widgets.filter(
|
const items = widgets.filter(
|
||||||
(d: { value: string; label: string } & LayoutConfig) => {
|
(d: { value: string; label: string } & LayoutConfig) => {
|
||||||
if (dashboardStore.selectedGrid.id !== d.id) {
|
if (dashboardStore.selectedGrid.id !== d.id) {
|
||||||
if (isLinear && d.widget) {
|
if (isLinear && d.widget && d.id) {
|
||||||
d.value = d.id || "";
|
d.value = d.id;
|
||||||
d.label = d.widget.name || d.id || "";
|
d.label = d.widget.name || d.id;
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
if (isRank && d.type !== "Widget" && d.widget) {
|
if (isRank && d.type !== "Widget" && d.widget && d.id) {
|
||||||
d.value = d.id || "";
|
d.value = d.id;
|
||||||
d.label = d.widget.name || d.id || "";
|
d.label = d.widget.name || d.id;
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,17 +64,13 @@ const widgets = computed(() => {
|
|||||||
);
|
);
|
||||||
return items;
|
return items;
|
||||||
});
|
});
|
||||||
function updateWidgetConfig(param: { [key: string]: string }) {
|
function updateWidgetConfig(options: Option[]) {
|
||||||
const key = Object.keys(param)[0];
|
const opt = options.map((d: Option) => d.value);
|
||||||
if (!key) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { selectedGrid } = dashboardStore;
|
|
||||||
const widget = {
|
const widget = {
|
||||||
...dashboardStore.selectedGrid.widget,
|
...dashboardStore.selectedGrid,
|
||||||
[key]: decodeURIComponent(param[key]),
|
associate: { widgetIds: opt },
|
||||||
};
|
};
|
||||||
dashboardStore.selectWidget({ ...selectedGrid, widget });
|
dashboardStore.selectWidget({ ...widget });
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -62,8 +62,10 @@ limitations under the License. -->
|
|||||||
metricTypes: data.metricTypes || [''],
|
metricTypes: data.metricTypes || [''],
|
||||||
i: data.i,
|
i: data.i,
|
||||||
metricConfig: data.metricConfig,
|
metricConfig: data.metricConfig,
|
||||||
|
associate: data.associate || [],
|
||||||
}"
|
}"
|
||||||
:needQuery="needQuery"
|
:needQuery="needQuery"
|
||||||
|
@click="clickHandle"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="no-data">{{ t("noGraph") }}</div>
|
<div v-else class="no-data">{{ t("noGraph") }}</div>
|
||||||
@ -84,6 +86,7 @@ import {
|
|||||||
useGetMetricEntity,
|
useGetMetricEntity,
|
||||||
} from "@/hooks/useProcessor";
|
} from "@/hooks/useProcessor";
|
||||||
import { EntityType, ListChartTypes } from "../data";
|
import { EntityType, ListChartTypes } from "../data";
|
||||||
|
import { EventParams } from "@/types/dashboard";
|
||||||
|
|
||||||
const props = {
|
const props = {
|
||||||
data: {
|
data: {
|
||||||
@ -93,6 +96,7 @@ const props = {
|
|||||||
activeIndex: { type: String, default: "" },
|
activeIndex: { type: String, default: "" },
|
||||||
needQuery: { type: Boolean, default: false },
|
needQuery: { type: Boolean, default: false },
|
||||||
};
|
};
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "Widget",
|
name: "Widget",
|
||||||
components: { ...graphs },
|
components: { ...graphs },
|
||||||
@ -156,6 +160,12 @@ export default defineComponent({
|
|||||||
dashboardStore.activeGridItem(props.data.i);
|
dashboardStore.activeGridItem(props.data.i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function clickHandle(params: EventParams | any) {
|
||||||
|
console.log(params);
|
||||||
|
console.log(props.data.associate);
|
||||||
|
// for (const id of props.config.associate.widgetIds) {
|
||||||
|
// }
|
||||||
|
}
|
||||||
watch(
|
watch(
|
||||||
() => [props.data.metricTypes, props.data.metrics],
|
() => [props.data.metricTypes, props.data.metrics],
|
||||||
() => {
|
() => {
|
||||||
@ -221,6 +231,7 @@ export default defineComponent({
|
|||||||
t,
|
t,
|
||||||
graph,
|
graph,
|
||||||
widget,
|
widget,
|
||||||
|
clickHandle,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -13,15 +13,16 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License. -->
|
limitations under the License. -->
|
||||||
<template>
|
<template>
|
||||||
<Graph :option="option" />
|
<Graph :option="option" @select="clickEvent" />
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
import type { PropType } from "vue";
|
import type { PropType } from "vue";
|
||||||
import { Event } from "@/types/events";
|
import { Event } from "@/types/events";
|
||||||
import { LineConfig } from "@/types/dashboard";
|
import { LineConfig, EventParams } from "@/types/dashboard";
|
||||||
|
|
||||||
/*global defineProps */
|
/*global defineProps, defineEmits */
|
||||||
|
const emits = defineEmits(["click"]);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: {
|
data: {
|
||||||
type: Object as PropType<{ [key: string]: number[] }>,
|
type: Object as PropType<{ [key: string]: number[] }>,
|
||||||
@ -31,7 +32,9 @@ const props = defineProps({
|
|||||||
theme: { type: String, default: "light" },
|
theme: { type: String, default: "light" },
|
||||||
itemEvents: { type: Array as PropType<Event[]>, default: () => [] },
|
itemEvents: { type: Array as PropType<Event[]>, default: () => [] },
|
||||||
config: {
|
config: {
|
||||||
type: Object as PropType<LineConfig>,
|
type: Object as PropType<
|
||||||
|
LineConfig & { associate: { widgetIds: string[] } }
|
||||||
|
>,
|
||||||
default: () => ({
|
default: () => ({
|
||||||
step: false,
|
step: false,
|
||||||
smooth: false,
|
smooth: false,
|
||||||
@ -215,4 +218,8 @@ function getOption() {
|
|||||||
series: temp,
|
series: temp,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clickEvent(params: EventParams) {
|
||||||
|
emits("click", params);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
Reference in New Issue
Block a user