fix(grid): respect page size row limits

This commit is contained in:
t8y2
2026-05-19 11:31:38 +08:00
parent 95d70eede6
commit 261d43c1b7
13 changed files with 302 additions and 102 deletions
@@ -24,7 +24,6 @@ import { loadEditorTheme, editorFontTheme } from "@/lib/editorThemes";
import { isTauriRuntime } from "@/lib/tauriRuntime";
import { aiTestConnection } from "@/lib/api";
import { eventToShortcut } from "@/lib/keyboardShortcuts";
import { MAX_RESULT_PAGE_SIZE, MIN_RESULT_PAGE_SIZE, normalizeResultPageSize } from "@/lib/paginationPageSize";
import {
SHORTCUT_DEFINITIONS,
findShortcutConflict,
@@ -52,7 +51,6 @@ const editFontFamily = ref(settingsStore.editorSettings.fontFamily);
const editFontSize = ref(settingsStore.editorSettings.fontSize);
const editTheme = ref(settingsStore.editorSettings.theme);
const editExecuteMode = ref(settingsStore.editorSettings.executeMode);
const editPageSize = ref(settingsStore.editorSettings.pageSize);
const editWordWrap = ref(settingsStore.editorSettings.wordWrap);
const editAppLayout = ref(settingsStore.editorSettings.appLayout);
const editRedisScanPageSize = ref(settingsStore.editorSettings.redisScanPageSize);
@@ -69,7 +67,6 @@ watch(
editFontSize.value = settingsStore.editorSettings.fontSize;
editTheme.value = settingsStore.editorSettings.theme;
editExecuteMode.value = settingsStore.editorSettings.executeMode;
editPageSize.value = settingsStore.editorSettings.pageSize;
editWordWrap.value = settingsStore.editorSettings.wordWrap;
editAppLayout.value = settingsStore.editorSettings.appLayout;
editRedisScanPageSize.value = settingsStore.editorSettings.redisScanPageSize;
@@ -93,7 +90,6 @@ function hasChanges(): boolean {
editFontSize.value !== settingsStore.editorSettings.fontSize ||
editTheme.value !== settingsStore.editorSettings.theme ||
editExecuteMode.value !== settingsStore.editorSettings.executeMode ||
editPageSize.value !== settingsStore.editorSettings.pageSize ||
editWordWrap.value !== settingsStore.editorSettings.wordWrap ||
editAppLayout.value !== settingsStore.editorSettings.appLayout ||
editRedisScanPageSize.value !== settingsStore.editorSettings.redisScanPageSize ||
@@ -109,7 +105,6 @@ function applySettings() {
fontSize: editFontSize.value,
theme: editTheme.value,
executeMode: editExecuteMode.value,
pageSize: normalizeResultPageSize(editPageSize.value),
wordWrap: editWordWrap.value,
appLayout: editAppLayout.value,
redisScanPageSize: editRedisScanPageSize.value,
@@ -124,7 +119,6 @@ function resetDefaults() {
editFontSize.value = DEFAULT_EDITOR_SETTINGS.fontSize;
editTheme.value = DEFAULT_EDITOR_SETTINGS.theme;
editExecuteMode.value = DEFAULT_EDITOR_SETTINGS.executeMode;
editPageSize.value = DEFAULT_EDITOR_SETTINGS.pageSize;
editWordWrap.value = DEFAULT_EDITOR_SETTINGS.wordWrap;
editAppLayout.value = DEFAULT_EDITOR_SETTINGS.appLayout;
editRedisScanPageSize.value = DEFAULT_EDITOR_SETTINGS.redisScanPageSize;
@@ -136,10 +130,6 @@ function onExecuteModeChange(v: any) {
if (v === "all" || v === "current") editExecuteMode.value = v;
}
function onPageSizeInput(event: Event) {
editPageSize.value = normalizeResultPageSize((event.target as HTMLInputElement).value);
}
function onFontFamilyChange(v: any) {
if (typeof v === "string") editFontFamily.value = v;
}
@@ -574,26 +564,6 @@ watch(
</SelectContent>
</Select>
</div>
<div class="space-y-2">
<div class="flex items-center justify-between gap-3">
<Label for="editor-result-page-size">{{ t("settings.resultPageSize") }}</Label>
<span class="text-xs text-muted-foreground tabular-nums">
{{ t("settings.resultPageSizeOption", { count: editPageSize }) }}
</span>
</div>
<Input
id="editor-result-page-size"
type="number"
inputmode="numeric"
:min="MIN_RESULT_PAGE_SIZE"
:max="MAX_RESULT_PAGE_SIZE"
step="1"
:model-value="editPageSize"
@input="onPageSizeInput"
/>
<p class="text-xs text-muted-foreground">{{ t("settings.resultPageSizeDescription") }}</p>
</div>
</div>
<div class="grid gap-4 md:grid-cols-2">
+29 -10
View File
@@ -1130,6 +1130,12 @@ const customPageSizeInput = ref(String(pageSize.value));
watch(pageSize, (value) => {
customPageSizeInput.value = String(value);
});
watch(
() => settingsStore.editorSettings.pageSize,
(value) => {
pageSize.value = normalizeResultPageSize(value, pageSize.value);
},
);
watch(
() => [props.pageOffset, props.pageLimit],
([offset, limit]) => {
@@ -1141,6 +1147,9 @@ watch(
);
const canGoNextPage = computed(() => props.result.has_more === true || props.result.rows.length >= pageSize.value);
const canJumpLastPage = computed(() => canGoNextPage.value && (!!props.tableMeta || !!props.countSql));
const showTruncationWarning = computed(
() => props.result.truncated === true && typeof props.pageLimit !== "number" && props.result.has_more !== true,
);
const isResultsContext = computed(() => props.context === "results");
const resultEditStatus = computed(() => {
if (!isResultsContext.value || !hasData.value) return null;
@@ -2773,10 +2782,10 @@ defineExpose({
</div>
<!-- Truncation warning banner -->
<div
v-if="result.truncated"
v-if="showTruncationWarning"
class="shrink-0 px-3 py-1 bg-amber-500/10 border-b border-amber-500/20 text-xs text-amber-600 dark:text-amber-400 flex items-center gap-1.5"
>
<span>{{ t("grid.truncatedHint") }}</span>
<span>{{ t("grid.truncatedHint", { count: pageSize }) }}</span>
</div>
<!-- Content area: table + DDL drawer -->
<div class="flex-1 flex min-h-0 overflow-hidden">
@@ -3947,7 +3956,7 @@ defineExpose({
<!-- Bottom status bar -->
<div class="flex items-center gap-2 px-3 py-1 border-t text-xs text-muted-foreground bg-muted/30 shrink-0">
<span v-if="hasData">{{ t("grid.totalRows", { count: result.rows.length }) }}</span>
<span v-if="result.truncated" class="text-amber-500 text-xs ml-1">(truncated)</span>
<span v-if="showTruncationWarning" class="text-amber-500 text-xs ml-1">(truncated)</span>
<span v-if="!hasData">{{ t("grid.rowsAffected", { count: result.affected_rows }) }}</span>
<span>{{ result.execution_time_ms }}ms</span>
<span v-if="selectedRowCount > 0 || hasCellSelection" class="text-foreground">{{ selectionSummary }}</span>
@@ -3966,26 +3975,36 @@ defineExpose({
{{ pageSize }}{{ t("grid.rowsPerPageShort") }}
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" class="w-52">
<DropdownMenuContent align="end" class="w-36">
<DropdownMenuItem v-for="s in pageSizeOptions" :key="s" @click="changePageSize(s)">
{{ s }} {{ t("grid.rowsPerPageShort") }}
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuLabel class="text-xs">{{ t("grid.customRowsPerPage") }}</DropdownMenuLabel>
<div class="flex items-center gap-1.5 px-2 pb-2" @click.stop @keydown.stop>
<div class="flex items-center gap-1 px-2 pb-2" @click.stop @keydown.stop>
<Input
v-model="customPageSizeInput"
type="number"
inputmode="numeric"
:min="MIN_RESULT_PAGE_SIZE"
:max="MAX_RESULT_PAGE_SIZE"
class="h-7 text-xs"
class="h-7 w-24 text-xs tabular-nums [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
@keydown.enter.prevent.stop="applyCustomPageSize"
/>
<Button variant="outline" size="sm" class="h-7 px-2 text-xs" @click.stop="applyCustomPageSize">
<Check class="h-3 w-3" />
{{ t("grid.applyPageSize") }}
</Button>
<Tooltip>
<TooltipTrigger as-child>
<Button
variant="outline"
size="icon"
class="h-7 w-7 shrink-0"
:aria-label="t('grid.applyPageSize')"
@click.stop="applyCustomPageSize"
>
<Check class="h-3.5 w-3.5" />
</Button>
</TooltipTrigger>
<TooltipContent side="bottom">{{ t("grid.applyPageSize") }}</TooltipContent>
</Tooltip>
</div>
</DropdownMenuContent>
</DropdownMenu>
@@ -534,6 +534,8 @@ defineExpose({ focusSearch, refreshData });
:connection-id="activeTab.connectionId"
:database="activeTab.database"
:table-meta="activeTab.tableMeta"
:page-offset="activeTab.resultPageOffset"
:page-limit="activeTab.resultPageLimit"
:on-execute-sql="async (sql: string) => emit('executeSql', sql)"
@update:where-input="(v: string) => (activeTab.whereInput = v)"
@reload="