mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-10-14 11:21:29 +00:00
feat: support collapsing and expanding for the event widget (#503)
This commit is contained in:
@@ -413,5 +413,6 @@ const msg = {
|
||||
spanName: "Span name",
|
||||
parentId: "Parent ID",
|
||||
shareTrace: "Share This Trace",
|
||||
eventDefaultCollapse: "Default Collapse",
|
||||
};
|
||||
export default msg;
|
||||
|
@@ -413,5 +413,6 @@ const msg = {
|
||||
spanName: "Nombre de Lapso",
|
||||
parentId: "ID Padre",
|
||||
shareTrace: "Compartir Traza",
|
||||
eventDefaultCollapse: "Default Collapse",
|
||||
};
|
||||
export default msg;
|
||||
|
@@ -411,5 +411,6 @@ const msg = {
|
||||
spanName: "跨度名称",
|
||||
parentId: "父ID",
|
||||
shareTrace: "分享Trace",
|
||||
eventDefaultCollapse: "默认折叠",
|
||||
};
|
||||
export default msg;
|
||||
|
@@ -253,9 +253,13 @@ export const dashboardStore = defineStore({
|
||||
setTopology(show: boolean) {
|
||||
this.showTopology = show;
|
||||
},
|
||||
setConfigs(param: LayoutConfig) {
|
||||
const actived = this.activedGridItem.split("-");
|
||||
setLayouts(param: LayoutConfig[]) {
|
||||
this.layout = param;
|
||||
},
|
||||
setConfigs(param: LayoutConfig, gridIndex?: string) {
|
||||
const actived = gridIndex || this.activedGridItem.split("-");
|
||||
const index = this.layout.findIndex((d: LayoutConfig) => actived[0] === d.i);
|
||||
|
||||
if (actived.length === 3) {
|
||||
const tabIndex = Number(actived[1]);
|
||||
const itemIndex = (this.layout[index].children || [])[tabIndex].children.findIndex(
|
||||
@@ -270,11 +274,13 @@ export const dashboardStore = defineStore({
|
||||
this.setCurrentTabItems((this.layout[index].children || [])[tabIndex].children);
|
||||
return;
|
||||
}
|
||||
this.layout[index] = {
|
||||
...this.layout[index],
|
||||
const layout = JSON.parse(JSON.stringify(this.layout));
|
||||
layout[index] = {
|
||||
...layout[index],
|
||||
...param,
|
||||
};
|
||||
this.selectedGrid = this.layout[index];
|
||||
this.setLayouts(layout);
|
||||
this.selectedGrid = layout[index];
|
||||
},
|
||||
setWidget(param: LayoutConfig) {
|
||||
for (let i = 0; i < this.layout.length; i++) {
|
||||
|
@@ -36,8 +36,8 @@ export const eventStore = defineStore({
|
||||
state: (): eventState => ({
|
||||
loading: false,
|
||||
events: [],
|
||||
instances: [{ value: "", label: "All" }],
|
||||
endpoints: [{ value: "", label: "All" }],
|
||||
instances: [{ value: "0", label: "All" }],
|
||||
endpoints: [{ value: "0", label: "All" }],
|
||||
condition: null,
|
||||
}),
|
||||
actions: {
|
||||
@@ -58,7 +58,7 @@ export const eventStore = defineStore({
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.instances = [{ value: "", label: "All" }, ...response.data.pods];
|
||||
this.instances = [{ value: "0", label: "All" }, ...response.data.pods];
|
||||
return response;
|
||||
},
|
||||
async getEndpoints(keyword?: string) {
|
||||
@@ -75,7 +75,7 @@ export const eventStore = defineStore({
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.endpoints = [{ value: "", label: "All" }, ...response.data.pods];
|
||||
this.endpoints = [{ value: "0", label: "All" }, ...response.data.pods];
|
||||
return response;
|
||||
},
|
||||
async getEvents() {
|
||||
|
@@ -48,6 +48,7 @@ export interface LayoutConfig {
|
||||
id?: string;
|
||||
associate?: { widgetId: string }[];
|
||||
eventAssociate?: boolean;
|
||||
eventDefaultCollapse?: boolean;
|
||||
filters?: Filters;
|
||||
relatedTrace?: RelatedTrace;
|
||||
subExpressions?: string[];
|
||||
|
@@ -15,6 +15,10 @@ limitations under the License. -->
|
||||
<div class="config-label flex-h mr-20">{{ t("enableAssociate") }}</div>
|
||||
<el-switch v-model="eventAssociate" active-text="Yes" inactive-text="No" @change="updateConfig" />
|
||||
</div>
|
||||
<div class="config-item flex-h">
|
||||
<div class="config-label flex-h mr-20">{{ t("eventDefaultCollapse") }}</div>
|
||||
<el-switch v-model="eventDefaultCollapse" active-text="Yes" inactive-text="No" @change="updateConfig" />
|
||||
</div>
|
||||
<ConfigurationFooter />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
@@ -28,10 +32,19 @@ limitations under the License. -->
|
||||
const { t } = useI18n();
|
||||
const dashboardStore = useDashboardStore();
|
||||
const eventAssociate = ref(dashboardStore.selectedGrid?.eventAssociate || false);
|
||||
const eventDefaultCollapse = ref(
|
||||
dashboardStore.selectedGrid?.eventDefaultCollapse === undefined
|
||||
? true
|
||||
: dashboardStore.selectedGrid?.eventDefaultCollapse,
|
||||
);
|
||||
|
||||
function updateConfig() {
|
||||
const { selectedGrid } = dashboardStore;
|
||||
|
||||
dashboardStore.selectWidget({ ...selectedGrid, eventAssociate: eventAssociate.value } as LayoutConfig);
|
||||
dashboardStore.selectWidget({
|
||||
...selectedGrid,
|
||||
eventAssociate: eventAssociate.value,
|
||||
eventDefaultCollapse: eventDefaultCollapse.value,
|
||||
} as LayoutConfig);
|
||||
}
|
||||
</script>
|
||||
|
@@ -14,10 +14,14 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License. -->
|
||||
<template>
|
||||
<div class="event-wrapper flex-v">
|
||||
<div class="operations">
|
||||
<span class="cp" @click="handleCollapse">
|
||||
<Icon iconName="sort" size="middle" />
|
||||
</span>
|
||||
<el-popover placement="bottom" trigger="click" :width="100" v-if="dashboardStore.editMode">
|
||||
<template #reference>
|
||||
<span class="delete cp">
|
||||
<Icon iconName="ellipsis_v" size="middle" class="operation" />
|
||||
<span class="cp">
|
||||
<Icon iconName="ellipsis_v" size="middle" />
|
||||
</span>
|
||||
</template>
|
||||
<div class="tools" @click="editConfig">
|
||||
@@ -27,15 +31,20 @@ limitations under the License. -->
|
||||
<span>{{ t("delete") }}</span>
|
||||
</div>
|
||||
</el-popover>
|
||||
<div class="header">
|
||||
<Header :needQuery="needQuery" />
|
||||
</div>
|
||||
<div class="event">
|
||||
<div class="event-inspector" v-if="collapsedState"> Event Timeline Inspector </div>
|
||||
<Transition name="collapse" v-else>
|
||||
<div class="timeline">
|
||||
<Header :needQuery="needQuery" />
|
||||
<div class="event mt-10">
|
||||
<Content :data="data" />
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch, onMounted, nextTick } from "vue";
|
||||
import type { PropType } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||
@@ -54,6 +63,17 @@ limitations under the License. -->
|
||||
});
|
||||
const { t } = useI18n();
|
||||
const dashboardStore = useDashboardStore();
|
||||
const collapsedState = ref(true);
|
||||
const originalState = ref({ h: props.data.h });
|
||||
|
||||
onMounted(() => {
|
||||
collapsedState.value = props.data.eventDefaultCollapse === undefined ? true : props.data.eventDefaultCollapse;
|
||||
if (collapsedState.value) {
|
||||
dashboardStore.setConfigs({ ...props.data, ...{ h: 3 } }, props.data.i);
|
||||
} else {
|
||||
dashboardStore.setConfigs({ ...props.data, ...originalState.value }, props.data.i);
|
||||
}
|
||||
});
|
||||
|
||||
function removeWidget() {
|
||||
dashboardStore.removeControls(props.data);
|
||||
@@ -62,6 +82,24 @@ limitations under the License. -->
|
||||
dashboardStore.setConfigPanel(true);
|
||||
dashboardStore.selectWidget(props.data);
|
||||
}
|
||||
function handleCollapse() {
|
||||
dashboardStore.activeGridItem(props.data.i);
|
||||
collapsedState.value = !collapsedState.value;
|
||||
if (collapsedState.value) {
|
||||
dashboardStore.setConfigs({ ...props.data, ...{ h: 3 } });
|
||||
} else {
|
||||
dashboardStore.setConfigs({ ...props.data, ...originalState.value });
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.data.h,
|
||||
(newHeight) => {
|
||||
if (!collapsedState.value) {
|
||||
originalState.value = { h: newHeight };
|
||||
}
|
||||
},
|
||||
);
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.event-wrapper {
|
||||
@@ -72,14 +110,14 @@ limitations under the License. -->
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.delete {
|
||||
.operations {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 3px;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.header {
|
||||
.timeline {
|
||||
padding: 10px;
|
||||
font-size: $font-size-smaller;
|
||||
border-bottom: 1px solid $border-color;
|
||||
@@ -103,4 +141,31 @@ limitations under the License. -->
|
||||
width: 100%;
|
||||
height: calc(100% - 80px);
|
||||
}
|
||||
|
||||
.collapse-enter-active,
|
||||
.collapse-leave-active {
|
||||
transition: all 0.8s ease;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.collapse-enter-from,
|
||||
.collapse-leave-to {
|
||||
opacity: 0;
|
||||
max-height: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
|
||||
.collapse-enter-to,
|
||||
.collapse-leave-from {
|
||||
opacity: 1;
|
||||
max-height: 1000px;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.event-inspector {
|
||||
text-align: center;
|
||||
line-height: 45px;
|
||||
font-size: $font-size-normal;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
@@ -95,6 +95,8 @@ limitations under the License. -->
|
||||
:is-draggable="dashboardStore.editMode"
|
||||
:is-resizable="dashboardStore.editMode"
|
||||
@layout-updated="layoutUpdatedEvent"
|
||||
:vertical-compact="true"
|
||||
:auto-size="true"
|
||||
>
|
||||
<grid-item
|
||||
v-for="item in dashboardStore.currentTabItems"
|
||||
|
@@ -122,10 +122,10 @@ limitations under the License. -->
|
||||
};
|
||||
const metrics: { [key: string]: { source: { [key: string]: unknown }; typesOfMQE: string[] } } =
|
||||
(await useDashboardQueryProcessor([config])) || {};
|
||||
const params = metrics[data.value.i];
|
||||
const params = metrics[data.value.i] || {};
|
||||
loading.value = false;
|
||||
state.source = params.source || {};
|
||||
typesOfMQE.value = params.typesOfMQE;
|
||||
typesOfMQE.value = params.typesOfMQE || [];
|
||||
}
|
||||
|
||||
function removeWidget() {
|
||||
|
@@ -23,6 +23,8 @@ limitations under the License. -->
|
||||
v-loading.fullscreen.lock="loading"
|
||||
element-loading-text="Loading..."
|
||||
element-loading-background="rgba(122, 122, 122, 0.8)"
|
||||
:vertical-compact="true"
|
||||
:auto-size="true"
|
||||
>
|
||||
<grid-item
|
||||
v-for="item in dashboardStore.layout"
|
||||
|
@@ -51,6 +51,7 @@ limitations under the License. -->
|
||||
width: 0,
|
||||
height: 0,
|
||||
};
|
||||
visTimeline();
|
||||
useThrottleFn(resize, 500)();
|
||||
});
|
||||
|
||||
|
@@ -86,8 +86,8 @@ limitations under the License. -->
|
||||
const pageSize = 20;
|
||||
const pageNum = ref<number>(1);
|
||||
const state = reactive<any>({
|
||||
instance: { value: "", label: "All", id: "" },
|
||||
endpoint: { value: "", label: "All", id: "" },
|
||||
instance: { value: "0", label: "All" },
|
||||
endpoint: { value: "0", label: "All" },
|
||||
eventType: { value: "", label: "All" },
|
||||
});
|
||||
const total = computed(() =>
|
||||
@@ -99,8 +99,8 @@ limitations under the License. -->
|
||||
async function init() {
|
||||
fetchSelectors();
|
||||
await queryEvents();
|
||||
state.instance = { value: "", label: "All" };
|
||||
state.endpoint = { value: "", label: "All" };
|
||||
state.instance = { value: "0", label: "All" };
|
||||
state.endpoint = { value: "0", label: "All" };
|
||||
}
|
||||
|
||||
function fetchSelectors() {
|
||||
@@ -138,13 +138,13 @@ limitations under the License. -->
|
||||
state.instance = eventStore.instances[0];
|
||||
}
|
||||
async function queryEvents() {
|
||||
let endpoint = state.endpoint.value,
|
||||
instance = state.instance.value;
|
||||
let endpoint = state.endpoint.value === "0" ? undefined : state.endpoint.value,
|
||||
instance = state.instance.value === "0" ? undefined : state.instance.value;
|
||||
if (dashboardStore.entity === EntityType[2].value) {
|
||||
endpoint = selectorStore.currentPod && selectorStore.currentPod.id;
|
||||
endpoint = selectorStore.currentPod?.id;
|
||||
}
|
||||
if (dashboardStore.entity === EntityType[3].value) {
|
||||
instance = selectorStore.currentPod && selectorStore.currentPod.id;
|
||||
instance = selectorStore.currentPod?.id;
|
||||
}
|
||||
if (!selectorStore.currentService) {
|
||||
return;
|
||||
|
Reference in New Issue
Block a user