fix(grid): move total row count refresh into the total label

Refs: #7520
This commit is contained in:
zipg
2026-08-30 03:05:10 +08:00
committed by GitHub
parent 1e8c58b3df
commit 45fb7fb7e6
11 changed files with 34 additions and 20 deletions
+18 -14
View File
@@ -14109,26 +14109,30 @@ function openGridSnapshot() {
count: result.rows.length,
})
}}
<span v-if="typeof displayedTotalRowCount === 'number' && displayedTotalRowCount >= 0" class="text-muted-foreground/70">{{ t(totalRowCountLabelKey, { count: displayedTotalRowCount }) }}</span>
<i18n-t v-if="showRerunTotalCountAction && !(totalRowCountBusy && !manualTotalRowCountLoading)" keypath="grid.totalRowCountWithAction" tag="span" class="text-muted-foreground/70">
<template #button>
<button
type="button"
class="mr-1 inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center rounded-sm align-middle text-muted-foreground/70 hover:bg-gray-200 hover:text-foreground disabled:pointer-events-none disabled:opacity-50 dark:hover:bg-gray-800"
:disabled="manualTotalRowCountLoading"
:aria-busy="manualTotalRowCountLoading ? 'true' : undefined"
:title="manualTotalRowCountLoading ? t('grid.totalRowCountLoading') : t('grid.calculateTotalRows')"
:aria-label="manualTotalRowCountLoading ? t('grid.totalRowCountLoading') : t('grid.calculateTotalRows')"
@click="calculateTotalRowCount"
>
<Loader2 v-if="manualTotalRowCountLoading" aria-hidden="true" class="h-3 w-3 animate-spin" />
<RefreshCcw v-else aria-hidden="true" class="h-3 w-3" />
</button>
</template>
<template #count>{{ displayedTotalRowCount }}</template>
</i18n-t>
<span v-else-if="typeof displayedTotalRowCount === 'number' && displayedTotalRowCount >= 0" class="text-muted-foreground/70">{{ t(totalRowCountLabelKey, { count: displayedTotalRowCount }) }}</span>
<span v-if="totalRowCountBusy && !(showRerunTotalCountAction && manualTotalRowCountLoading)" class="text-muted-foreground/70">
{{ t("grid.totalRowCountLoading") }}
</span>
<button v-else-if="showExactTotalCountAction" type="button" class="text-muted-foreground/70 underline underline-offset-2 hover:text-foreground disabled:pointer-events-none" :disabled="manualTotalRowCountLoading" @click="calculateTotalRowCount">
{{ t("grid.calculateTotalRowsInline") }}
</button>
<button
v-else-if="showRerunTotalCountAction"
type="button"
class="ml-1 inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center rounded-sm align-middle text-muted-foreground/70 hover:bg-gray-200 hover:text-foreground disabled:pointer-events-none disabled:opacity-50 dark:hover:bg-gray-800"
:disabled="manualTotalRowCountLoading"
:aria-busy="manualTotalRowCountLoading ? 'true' : undefined"
:title="manualTotalRowCountLoading ? t('grid.totalRowCountLoading') : t('grid.calculateTotalRows')"
:aria-label="manualTotalRowCountLoading ? t('grid.totalRowCountLoading') : t('grid.calculateTotalRows')"
@click="calculateTotalRowCount"
>
<Loader2 v-if="manualTotalRowCountLoading" aria-hidden="true" class="h-3 w-3 animate-spin" />
<RefreshCcw v-else aria-hidden="true" class="h-3 w-3" />
</button>
</span>
<span v-if="showTruncationWarning" class="shrink-0 text-amber-500 text-xs">(truncated)</span>
<span v-if="!hasData" class="shrink-0">{{ t("grid.rowsAffected", { count: result.affected_rows }) }}</span>
@@ -12,7 +12,7 @@ const statusRenderSource = (() => {
})();
const rerunBranch = (() => {
const start = statusRenderSource.indexOf("} else if ($setup.showRerunTotalCountAction) {");
const start = statusRenderSource.indexOf("$setup.showRerunTotalCountAction && !($setup.totalRowCountBusy && !$setup.manualTotalRowCountLoading)");
return start === -1 ? "" : statusRenderSource.slice(start, statusRenderSource.indexOf("</button>", start));
})();
@@ -48,19 +48,21 @@ describe("DataGrid rerun total row count action", () => {
expect(showDataGridRerunTotalCountAction({ canCalculateTotalRowCount: true, displayedTotalRowCount: NaN, totalRowCountIsExact: true })).toBe(false);
});
it("keeps the numeric total outside the action chain and orders busy, inline link, then rerun icon", () => {
it("places the rerun icon before the numeric total and keeps the other actions ordered", () => {
const numericTotal = statusRenderSource.indexOf('typeof $setup.displayedTotalRowCount === "number" && $setup.displayedTotalRowCount >= 0');
const rerunAction = statusRenderSource.indexOf("$setup.showRerunTotalCountAction && !($setup.totalRowCountBusy && !$setup.manualTotalRowCountLoading)");
const busyBranch = statusRenderSource.indexOf("if ($setup.totalRowCountBusy && !($setup.showRerunTotalCountAction && $setup.manualTotalRowCountLoading)) {");
const inlineLink = statusRenderSource.indexOf("} else if ($setup.showExactTotalCountAction) {");
const rerunAction = statusRenderSource.indexOf("} else if ($setup.showRerunTotalCountAction) {");
expect(numericTotal).toBeGreaterThan(-1);
expect(rerunAction).toBeGreaterThan(-1);
expect(rerunAction).toBeLessThan(numericTotal);
expect(busyBranch).toBeGreaterThan(numericTotal);
expect(inlineLink).toBeGreaterThan(busyBranch);
expect(rerunAction).toBeGreaterThan(inlineLink);
});
it("renders a spaced rerun icon labelled for the total-count action and disabled while counting", () => {
expect(rerunBranch).toContain('<button type="button" class="ml-1 inline-flex h-3.5 w-3.5');
expect(statusRenderSource).toContain('keypath: "grid.totalRowCountWithAction"');
expect(rerunBranch).toContain('<button type="button" class="mr-1 inline-flex h-3.5 w-3.5');
expect(rerunBranch).toContain("disabled:pointer-events-none");
expect(rerunBranch).toContain("disabled:opacity-50");
// title/aria-label toggle between idle and busy copy
+1
View File
@@ -1534,6 +1534,7 @@ export default {
totalRows: "Total {count} rows",
loadedRows: "Loaded {count} rows",
totalRowCount: "({count} total)",
totalRowCountWithAction: "({button}{count} total)",
totalRowCountAtLeast: "(at least {count} total)",
totalRowCountEstimated: "(~{count})",
totalRowCountLoading: "(counting...)",
+1
View File
@@ -1475,6 +1475,7 @@ export default withEnglishFallback({
totalRows: "Total {count} filas",
loadedRows: "{count} filas cargadas",
totalRowCount: "({count} en total)",
totalRowCountWithAction: "({button}{count} en total)",
totalRowCountAtLeast: "(al menos {count} en total)",
totalRowCountEstimated: "(aprox. {count})",
totalRowCountLoading: "(contando...)",
+1
View File
@@ -1473,6 +1473,7 @@ export default withEnglishFallback({
totalRows: "Totale {count} righe",
loadedRows: "{count} righe caricate",
totalRowCount: "({count} in totale)",
totalRowCountWithAction: "({button}{count} in totale)",
totalRowCountAtLeast: "(almeno {count} in totale)",
totalRowCountEstimated: "(circa {count})",
totalRowCountLoading: "(conteggio...)",
+1
View File
@@ -1495,6 +1495,7 @@ export default withEnglishFallback({
totalRows: "{count}件表示",
loadedRows: "{count}件読み込み済み",
totalRowCount: "(全{count}件)",
totalRowCountWithAction: "({button}全{count}件)",
totalRowCountAtLeast: "(少なくとも{count}件)",
totalRowCountEstimated: "(約 {count}件)",
totalRowCountLoading: "(カウント中...)",
+1
View File
@@ -1415,6 +1415,7 @@ export default withEnglishFallback({
totalRows: "전체 {count}행",
loadedRows: "{count}행 로드됨",
totalRowCount: "(전체 {count})",
totalRowCountWithAction: "({button}전체 {count})",
totalRowCountAtLeast: "(최소 {count})",
totalRowCountEstimated: "(약 {count})",
totalRowCountLoading: "(집계 중...)",
+1
View File
@@ -1475,6 +1475,7 @@ export default withEnglishFallback({
totalRows: "Total de {count} linhas",
loadedRows: "{count} linhas carregadas",
totalRowCount: "({count} no total)",
totalRowCountWithAction: "({button}{count} no total)",
totalRowCountAtLeast: "(pelo menos {count} no total)",
totalRowCountEstimated: "(aprox. {count})",
totalRowCountLoading: "(contando...)",
+1
View File
@@ -1458,6 +1458,7 @@ export default withEnglishFallback({
totalRows: "共 {count} 行",
loadedRows: "已加载 {count} 行",
totalRowCount: "(总计 {count} 行)",
totalRowCountWithAction: "({button}总计 {count} 行)",
totalRowCountAtLeast: "(至少 {count} 行)",
totalRowCountEstimated: "(约 {count} 行)",
totalRowCountLoading: "(统计中...)",
+1
View File
@@ -1474,6 +1474,7 @@ export default withEnglishFallback({
totalRows: "共 {count} 筆",
loadedRows: "已載入 {count} 筆",
totalRowCount: "(總計 {count} 筆)",
totalRowCountWithAction: "({button}總計 {count} 筆)",
totalRowCountAtLeast: "(至少 {count} 筆)",
totalRowCountEstimated: "(約 {count} 筆)",
totalRowCountLoading: "(統計中...)",
+1 -1
View File
@@ -269,7 +269,7 @@ test("rerun total-count visibility comes from the shared rule and triggers the m
assert.match(rerunComputed, /canCalculateTotalRowCount: canCalculateTotalRowCount\.value/);
assert.match(rerunComputed, /displayedTotalRowCount: displayedTotalRowCount\.value/);
assert.match(rerunComputed, /totalRowCountIsExact: totalRowCountIsExact\.value/);
const rerunButton = source.match(/<button\s+v-else-if="showRerunTotalCountAction"[\s\S]*?<\/button>/)?.[0] ?? "";
const rerunButton = source.match(/<i18n-t v-if="showRerunTotalCountAction[\s\S]*?<template #button>[\s\S]*?<button[\s\S]*?<\/button>/)?.[0] ?? "";
assert.match(rerunButton, /@click="calculateTotalRowCount"/);
});