mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-10-14 20:01:28 +00:00
feat: support collapsing and expanding for the event widget (#503)
This commit is contained in:
@@ -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,28 +14,37 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License. -->
|
||||
<template>
|
||||
<div class="event-wrapper flex-v">
|
||||
<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>
|
||||
</template>
|
||||
<div class="tools" @click="editConfig">
|
||||
<span>{{ t("edit") }}</span>
|
||||
</div>
|
||||
<div class="tools" @click="removeWidget">
|
||||
<span>{{ t("delete") }}</span>
|
||||
</div>
|
||||
</el-popover>
|
||||
<div class="header">
|
||||
<Header :needQuery="needQuery" />
|
||||
</div>
|
||||
<div class="event">
|
||||
<Content :data="data" />
|
||||
<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="cp">
|
||||
<Icon iconName="ellipsis_v" size="middle" />
|
||||
</span>
|
||||
</template>
|
||||
<div class="tools" @click="editConfig">
|
||||
<span>{{ t("edit") }}</span>
|
||||
</div>
|
||||
<div class="tools" @click="removeWidget">
|
||||
<span>{{ t("delete") }}</span>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
<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