1 parent
e2fa810f2e
commit
b3e8709272
13 files changed
+133
-10
No files matched your search
@@ -253,7 +253,7 @@ import { allNullColumnIndexes } from "@/lib/dataGrid/dataGridColumnVisibility";
|
||||
import { buildDataGridColumnLookupItems, dataGridColumnCommentFor, filterDataGridColumnLookupItems } from "@/lib/dataGrid/dataGridColumnLookup";
|
||||
import { uniqueDataGridColumnOrderKeys } from "@/lib/dataGrid/dataGridColumnOrder";
|
||||
import { dataGridColumnLayoutScopeKey, TABLE_DATA_GRID_COLUMN_ORDER_CHANGED_EVENT, tableDataGridColumnOrderScopeKey } from "@/lib/dataGrid/dataGridColumnLayoutStorage";
|
||||
import { summarizeSelection } from "@/lib/dataGrid/gridSelection";
|
||||
import { createPendingSelectionSummary, formatSelectionAggregate, formatSelectionAverage, summarizeSelection } from "@/lib/dataGrid/gridSelection";
|
||||
import { captureDataGridSelection, restoreDataGridSelection, type CaptureDataGridSelectionOptions, type PersistedDataGridSelection } from "@/lib/dataGrid/dataGridSelectionPersistence";
|
||||
import { dataGridFrameCoversRow, dataGridSelectionEdgeMask, dataGridSelectionFrameKindAtCell, dataGridSelectionUsesOuterFrame, resolveDataGridSelectionFrames } from "@/lib/dataGrid/dataGridSelectionFrames";
|
||||
import {
|
||||
@@ -5554,12 +5554,7 @@ const multiRowCount = computed(() => {
|
||||
const selectionSummary = computed(() => {
|
||||
if (!hasCellSelection.value) return null;
|
||||
if (isSelectingCells.value) {
|
||||
return {
|
||||
cellCount: selectedCellCount.value,
|
||||
rowCount: multiRowCount.value,
|
||||
numericCount: 0,
|
||||
sum: 0,
|
||||
};
|
||||
return createPendingSelectionSummary(selectedCellCount.value, multiRowCount.value);
|
||||
}
|
||||
return summarizeSelection(selectedCells.value);
|
||||
});
|
||||
@@ -5567,8 +5562,11 @@ const selectionSummarySumText = computed(() => {
|
||||
if (isSelectingCells.value) return "…";
|
||||
const summary = selectionSummary.value;
|
||||
if (!summary) return "0";
|
||||
const sum = Object.is(summary.sum, -0) ? 0 : summary.sum;
|
||||
return Number.isInteger(sum) ? String(sum) : sum.toLocaleString(undefined, { maximumFractionDigits: 12 });
|
||||
return formatSelectionAggregate(summary.sum);
|
||||
});
|
||||
const selectionSummaryAverageText = computed(() => {
|
||||
if (isSelectingCells.value) return "…";
|
||||
return formatSelectionAverage(selectionSummary.value?.average);
|
||||
});
|
||||
|
||||
const isMultiRow = computed(() => multiRowCount.value > 1);
|
||||
@@ -13587,6 +13585,7 @@ function currentGridContextMenuItems(): ContextMenuItem[] {
|
||||
:pagination-enabled="paginationEnabled"
|
||||
:selection-summary="selectionSummary"
|
||||
:selection-summary-sum-text="selectionSummarySumText"
|
||||
:selection-summary-average-text="selectionSummaryAverageText"
|
||||
:loading="gridPaginationBusy"
|
||||
:infinite-scroll-enabled="infiniteScrollEnabled"
|
||||
:infinite-scroll-all-loaded="infiniteScrollAllLoaded"
|
||||
|
||||
@@ -16,6 +16,7 @@ const props = withDefaults(
|
||||
paginationEnabled?: boolean;
|
||||
selectionSummary: { cellCount: number; rowCount: number } | null;
|
||||
selectionSummarySumText: string;
|
||||
selectionSummaryAverageText: string;
|
||||
loading: boolean;
|
||||
infiniteScrollEnabled: boolean;
|
||||
infiniteScrollAllLoaded: boolean;
|
||||
@@ -86,6 +87,7 @@ function handlePageInputKeydown(event: KeyboardEvent) {
|
||||
<div class="flex min-w-max items-center justify-end gap-1">
|
||||
<div v-if="selectionSummary" class="flex shrink-0 items-center gap-3 tabular-nums">
|
||||
<span class="shrink-0">{{ t("grid.selectionSum", { value: selectionSummarySumText }) }}</span>
|
||||
<span class="shrink-0">{{ t("grid.selectionAverage", { value: selectionSummaryAverageText }) }}</span>
|
||||
<div class="flex shrink-0 items-center gap-1">
|
||||
<span class="shrink-0">{{ t("grid.selectionCells", { count: selectionSummary.cellCount }) }}</span>
|
||||
<span class="shrink-0">{{ t("grid.rows", { count: selectionSummary.rowCount }) }}</span>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// @vitest-environment happy-dom
|
||||
|
||||
import { readFileSync } from "node:fs";
|
||||
import { nextTick } from "vue";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { dispatch, findAll, findOne, hostText, mountComponent } from "./vueHostHarness";
|
||||
@@ -98,6 +99,8 @@ import DataGridPagination from "@/components/grid/DataGridPagination.vue";
|
||||
import DataGridQueryControls from "@/components/grid/DataGridQueryControls.vue";
|
||||
import DataGridSearchBar from "@/components/grid/DataGridSearchBar.vue";
|
||||
|
||||
const dataGridSource = readFileSync("apps/desktop/src/components/grid/DataGrid.vue", "utf8");
|
||||
|
||||
function detail(patch: Partial<DataGridCellDetail> = {}): DataGridCellDetail {
|
||||
return {
|
||||
rowNumber: 1,
|
||||
@@ -184,6 +187,42 @@ describe("DataGridSearchBar", () => {
|
||||
});
|
||||
|
||||
describe("DataGridPagination", () => {
|
||||
it("keeps drag summaries count-only and wires the derived average without materializing selected cells", () => {
|
||||
const summaryStart = dataGridSource.indexOf("const selectionSummary = computed");
|
||||
const pendingSummary = dataGridSource.indexOf("createPendingSelectionSummary(selectedCellCount.value, multiRowCount.value)", summaryStart);
|
||||
const materializedSummary = dataGridSource.indexOf("summarizeSelection(selectedCells.value)", summaryStart);
|
||||
|
||||
expect(summaryStart).toBeGreaterThan(-1);
|
||||
expect(pendingSummary).toBeGreaterThan(summaryStart);
|
||||
expect(materializedSummary).toBeGreaterThan(pendingSummary);
|
||||
expect(dataGridSource).toContain('const selectionSummaryAverageText = computed(() => {\n if (isSelectingCells.value) return "…";');
|
||||
expect(dataGridSource).toContain(':selection-summary-average-text="selectionSummaryAverageText"');
|
||||
});
|
||||
|
||||
it("shows average beside the existing selection summary values", () => {
|
||||
const mounted = mountComponent(DataGridPagination, {
|
||||
selectionSummary: { cellCount: 4, rowCount: 2 },
|
||||
selectionSummarySumText: "10",
|
||||
selectionSummaryAverageText: "2.5",
|
||||
loading: false,
|
||||
infiniteScrollEnabled: false,
|
||||
infiniteScrollAllLoaded: false,
|
||||
pageSize: 100,
|
||||
customPageSizeInput: "",
|
||||
pageSizeMenuItems: [],
|
||||
exportMenuItems: [],
|
||||
currentPage: 1,
|
||||
canGoNextPage: false,
|
||||
canJumpLastPage: false,
|
||||
});
|
||||
|
||||
const summaryText = hostText(mounted.root);
|
||||
expect(summaryText).toContain("grid.selectionSum");
|
||||
expect(summaryText).toContain("grid.selectionAverage");
|
||||
expect(summaryText).toContain("grid.selectionCells");
|
||||
expect(summaryText).toContain("grid.rows");
|
||||
});
|
||||
|
||||
it("enforces first/previous/next/last disabled boundaries", async () => {
|
||||
const firstPage = vi.fn();
|
||||
const previousPage = vi.fn();
|
||||
@@ -192,6 +231,7 @@ describe("DataGridPagination", () => {
|
||||
const mounted = mountComponent(DataGridPagination, {
|
||||
selectionSummary: null,
|
||||
selectionSummarySumText: "",
|
||||
selectionSummaryAverageText: "",
|
||||
loading: false,
|
||||
infiniteScrollEnabled: false,
|
||||
infiniteScrollAllLoaded: false,
|
||||
@@ -236,6 +276,7 @@ describe("DataGridPagination", () => {
|
||||
const mounted = mountComponent(DataGridPagination, {
|
||||
selectionSummary: null,
|
||||
selectionSummarySumText: "",
|
||||
selectionSummaryAverageText: "",
|
||||
loading: false,
|
||||
infiniteScrollEnabled: false,
|
||||
infiniteScrollAllLoaded: false,
|
||||
@@ -278,6 +319,7 @@ describe("DataGridPagination", () => {
|
||||
paginationEnabled: false,
|
||||
selectionSummary: null,
|
||||
selectionSummarySumText: "",
|
||||
selectionSummaryAverageText: "",
|
||||
loading: false,
|
||||
infiniteScrollEnabled: false,
|
||||
infiniteScrollAllLoaded: false,
|
||||
|
||||
Reference in new issue
Block a user