refactor: Implement a common pagination component (#516)

This commit is contained in:
Fine0830
2026-01-06 18:19:35 +08:00
committed by GitHub
parent f74a59f757
commit 0334c28da5
7 changed files with 133 additions and 47 deletions

View File

@@ -63,7 +63,7 @@ export const logStore = defineStore({
this.logs = [];
this.conditions = {
queryDuration: getDurationTime(),
paging: { pageNum: 1, pageSize: 15 },
paging: { pageNum: 1, pageSize: PageSizeDefault },
};
},
setLogHeaderType(type: string) {

View File

@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. -->
<template>
<div class="timeline-table clear" v-loading="alarmStore.loading">
<div v-for="(i, index) in alarmStore.alarms" :key="index" class="clear timeline-item">
<div v-for="(i, index) in displayAlarms" :key="index" class="clear timeline-item">
<div class="g-sm-3 grey sm hide-xs time-line tr">
{{ dateFormat(parseInt(i.startTime)) }}
</div>
@@ -42,7 +42,7 @@ limitations under the License. -->
</div>
</div>
</div>
<div v-if="!alarmStore.alarms.length" class="tips">{{ t("noData") }}</div>
<div v-if="!displayAlarms.length" class="tips">{{ t("noData") }}</div>
</div>
<el-dialog
v-model="isShowDetails"
@@ -125,11 +125,11 @@ limitations under the License. -->
</el-dialog>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import { ref, computed } from "vue";
import { useI18n } from "vue-i18n";
import type { Alarm, Event } from "@/types/alarm";
import { useAlarmStore } from "@/store/modules/alarm";
import { EventsDetailHeaders, AlarmDetailCol, EventsDetailKeys } from "./data";
import { EventsDetailHeaders, AlarmDetailCol, EventsDetailKeys, PageSizeDefaultAlarm } from "./data";
import { dateFormat } from "@/utils/dateFormat";
import Snapshot from "./components/Snapshot.vue";
@@ -141,6 +141,11 @@ limitations under the License. -->
const alarmTags = ref<string[]>([]);
const currentEvents = ref<any[]>([]);
const currentEvent = ref<Event | any>({});
const pageSize = PageSizeDefaultAlarm;
const displayAlarms = computed(() =>
alarmStore.alarms.length >= pageSize ? alarmStore.alarms.slice(0, pageSize - 1) : alarmStore.alarms,
);
function showDetails(item: Alarm) {
isShowDetails.value = true;

View File

@@ -41,19 +41,11 @@ limitations under the License. -->
/>
</div>
<div class="pagination">
<el-pagination
v-model="pageNum"
:page-size="pageSize"
layout="prev, pager, next"
:total="total"
@current-change="changePage"
:pager-count="5"
size="small"
:style="
appStore.theme === Themes.Light
? `--el-pagination-bg-color: #f0f2f5; --el-pagination-button-disabled-bg-color: #f0f2f5;`
: ''
"
<Pagination
v-model:currentPage="pageNum"
:pageSize="pageSize"
:total="alarmStore.alarms.length"
@change="changePage"
/>
</div>
</div>
@@ -70,19 +62,19 @@ limitations under the License. -->
import { useI18n } from "vue-i18n";
import { ElMessage } from "element-plus";
import ConditionTags from "@/views/components/ConditionTags.vue";
import { AlarmOptions } from "./data";
import Pagination from "@/views/components/Pagination.vue";
import { AlarmOptions, PageSizeDefaultAlarm } from "./data";
import { useAppStoreWithOut, InitializationDurationRow } from "@/store/modules/app";
import { useAlarmStore } from "@/store/modules/alarm";
import { useDuration } from "@/hooks/useDuration";
import timeFormat from "@/utils/timeFormat";
import type { DurationTime, Duration } from "@/types/app";
import { Themes } from "@/constants/data";
/*global Indexable */
const appStore = useAppStoreWithOut();
const alarmStore = useAlarmStore();
const { t } = useI18n();
const { setDurationRow, getDurationTime, getMaxRange } = useDuration();
const pageSize = 20;
const pageSize = PageSizeDefaultAlarm;
const entity = ref<string>("");
const keyword = ref<string>("");
const pageNum = ref<number>(1);
@@ -90,9 +82,6 @@ limitations under the License. -->
const durationRow = ref<Duration>(InitializationDurationRow);
const tagsMap = ref<{ key: string; value: string }[]>();
const total = computed(() =>
alarmStore.alarms.length === pageSize ? pageSize * pageNum.value + 1 : pageSize * pageNum.value,
);
const maxRange = computed(() =>
getMaxRange(appStore.coldStageMode ? appStore.recordsTTL?.coldNormal || 0 : appStore.recordsTTL?.normal || 0),
);

View File

@@ -14,6 +14,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export const PageSizeDefaultAlarm = 21;
export const AlarmOptions = [
{ label: "All", value: "" },
{ label: "Service", value: "Service" },

View File

@@ -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 class="pagination-container">
<el-pagination
v-model:current-page="currentPageModel"
:page-size="displayPageSize"
size="small"
layout="prev, pager, next"
:total="computedTotal"
:pager-count="pagerCount"
@current-change="handlePageChange"
:style="paginationStyle"
/>
</div>
</template>
<script lang="ts" setup>
import { computed } from "vue";
/*global defineProps, defineEmits*/
const props = defineProps({
currentPage: {
type: Number,
default: 1,
},
pageSize: {
type: Number,
required: true,
},
total: {
type: Number,
required: true,
},
pagerCount: {
type: Number,
default: 5,
},
align: {
type: String as () => "left" | "center" | "right",
default: "right",
},
});
const emits = defineEmits<{
(e: "update:currentPage", page: number): void;
(e: "change", page: number): void;
}>();
// The display page size is pageSize - 1 because we fetch pageSize items
// but the last item is only used to check if there are more pages
const displayPageSize = computed(() => props.pageSize - 1);
// Calculate total for pagination display based on fetched items
// If we fetched pageSize items, there might be more pages
const computedTotal = computed(() => {
if (props.total >= props.pageSize) {
return displayPageSize.value * props.currentPage + 1;
}
return displayPageSize.value * props.currentPage;
});
const currentPageModel = computed({
get: () => props.currentPage,
set: (val: number) => emits("update:currentPage", val),
});
const paginationStyle = computed(() => {
const alignMap = {
left: "flex-start",
center: "center",
right: "flex-end",
};
return {
display: "flex",
justifyContent: alignMap[props.align],
};
});
function handlePageChange(page: number) {
emits("update:currentPage", page);
emits("change", page);
}
</script>
<style lang="scss" scoped>
.pagination-container {
margin: 5px 0;
}
</style>

View File

@@ -133,7 +133,7 @@ limitations under the License. -->
import type { PropType } from "vue";
import { useI18n } from "vue-i18n";
import { ElMessage } from "element-plus";
import { useLogStore } from "@/store/modules/log";
import { useLogStore, PageSizeDefault } from "@/store/modules/log";
import { useDashboardStore } from "@/store/modules/dashboard";
import { useAppStoreWithOut, InitializationDurationRow } from "@/store/modules/app";
import { useSelectorStore } from "@/store/modules/selectors";
@@ -274,7 +274,7 @@ limitations under the License. -->
serviceId: selectorStore.currentService ? selectorStore.currentService.id : state.service.id,
pagePathId: endpoint || state.endpoint.id || undefined,
serviceVersionId: instance || state.instance.id || undefined,
paging: { pageNum: 1, pageSize: 15 },
paging: { pageNum: 1, pageSize: PageSizeDefault },
queryDuration: duration,
category: state.category.value,
});
@@ -292,7 +292,7 @@ limitations under the License. -->
keywordsOfContent: keywordsOfContent.value,
excludingKeywordsOfContent: excludingKeywordsOfContent.value,
tags: tagsMap.value.length ? tagsMap.value : undefined,
paging: { pageNum: 1, pageSize: 15 },
paging: { pageNum: 1, pageSize: PageSizeDefault },
relatedTrace: traceId.value ? { traceId: traceId.value, segmentId, spanId } : undefined,
});
}

View File

@@ -17,18 +17,12 @@ limitations under the License. -->
<LogTable v-loading="logStore.loadLogs" :tableData="displayLogs" :type="type" :noLink="false" :data="data">
<div class="log-tips" v-if="!logStore.logs.length">{{ t("noData") }}</div>
</LogTable>
<div class="mt-5 mb-5">
<el-pagination
v-model="logStore.conditions.paging.pageNum"
:page-size="pageSize - 1"
size="small"
layout="prev, pager, next"
:total="total"
:pager-count="5"
@current-change="updatePage"
:style="`float: right`"
/>
</div>
<Pagination
v-model:currentPage="logStore.conditions.paging.pageNum"
:pageSize="pageSize"
:total="logStore.logs.length"
@change="updatePage"
/>
</div>
</template>
<script lang="ts" setup>
@@ -37,6 +31,7 @@ limitations under the License. -->
import type { PropType } from "vue";
import type { LayoutConfig } from "@/types/dashboard";
import LogTable from "./LogTable/Index.vue";
import Pagination from "@/views/components/Pagination.vue";
import { useLogStore, PageSizeDefault } from "@/store/modules/log";
import { useDashboardStore } from "@/store/modules/dashboard";
import { ElMessage } from "element-plus";
@@ -54,18 +49,13 @@ limitations under the License. -->
const logStore = useLogStore();
const dashboardStore = useDashboardStore();
const type = ref<string>(dashboardStore.layerId === "BROWSER" ? "browser" : "service");
const pageSize = ref<number>(PageSizeDefault);
const total = computed(() =>
logStore.logs.length >= pageSize.value
? (pageSize.value - 1) * logStore.conditions.paging.pageNum + 1
: (pageSize.value - 1) * logStore.conditions.paging.pageNum,
);
const pageSize = PageSizeDefault;
const displayLogs = computed(() =>
logStore.logs.length === pageSize.value ? logStore.logs.slice(0, pageSize.value - 1) : logStore.logs,
logStore.logs.length === pageSize ? logStore.logs.slice(0, pageSize - 1) : logStore.logs,
);
function updatePage(p: number) {
logStore.setLogCondition({
paging: { pageNum: p, pageSize: pageSize.value },
paging: { pageNum: p, pageSize: pageSize },
});
queryLogs();
}