diff --git a/apps/desktop/src/components/editor/EditorSettingsDialog.vue b/apps/desktop/src/components/editor/EditorSettingsDialog.vue index 64b5d3815..194df4202 100644 --- a/apps/desktop/src/components/editor/EditorSettingsDialog.vue +++ b/apps/desktop/src/components/editor/EditorSettingsDialog.vue @@ -24,6 +24,7 @@ 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, @@ -51,6 +52,7 @@ 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); @@ -67,6 +69,7 @@ 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; @@ -90,6 +93,7 @@ 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 || @@ -105,6 +109,7 @@ function applySettings() { fontSize: editFontSize.value, theme: editTheme.value, executeMode: editExecuteMode.value, + pageSize: normalizeResultPageSize(editPageSize.value), wordWrap: editWordWrap.value, appLayout: editAppLayout.value, redisScanPageSize: editRedisScanPageSize.value, @@ -119,6 +124,7 @@ 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; @@ -130,6 +136,10 @@ 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; } @@ -565,6 +575,28 @@ watch( +
+
+ + + {{ t("settings.resultPageSizeOption", { count: editPageSize }) }} + +
+ +

{{ t("settings.resultPageSizeDescription") }}

+
+ + +
diff --git a/apps/desktop/src/components/grid/DataGrid.vue b/apps/desktop/src/components/grid/DataGrid.vue index fdf6dede2..d14ce9e2e 100644 --- a/apps/desktop/src/components/grid/DataGrid.vue +++ b/apps/desktop/src/components/grid/DataGrid.vue @@ -59,8 +59,11 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; +import { Input } from "@/components/ui/input"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; @@ -105,6 +108,12 @@ import { isCancelSearchShortcut, isFocusSearchShortcut } from "@/lib/keyboardSho import { dataGridHeaderContentWidth, scrollbarGutterWidth } from "@/lib/dataGridScrollGutter"; import { dataGridSaveActionMode, dataGridSaveToolbarState } from "@/lib/dataGridSaveUi"; import { appendColumnValueFilterCondition, buildColumnValueFilterCondition } from "@/lib/dataGridColumnFilter"; +import { + MAX_RESULT_PAGE_SIZE, + MIN_RESULT_PAGE_SIZE, + normalizeResultPageSize, + resultPageSizeMenuOptions, +} from "@/lib/paginationPageSize"; import { filterColumnVisibilityOptions, nextHiddenColumnIndexes, @@ -1114,14 +1123,20 @@ watch( ); // --- Pagination --- -const pageSize = ref(settingsStore.editorSettings.pageSize); +const pageSize = ref(normalizeResultPageSize(settingsStore.editorSettings.pageSize)); const currentPage = ref(1); +const pageSizeOptions = computed(() => resultPageSizeMenuOptions(pageSize.value)); +const customPageSizeInput = ref(String(pageSize.value)); +watch(pageSize, (value) => { + customPageSizeInput.value = String(value); +}); watch( () => [props.pageOffset, props.pageLimit], ([offset, limit]) => { if (typeof offset !== "number" || typeof limit !== "number" || limit <= 0) return; - pageSize.value = limit; - currentPage.value = Math.floor(offset / limit) + 1; + const normalizedLimit = normalizeResultPageSize(limit); + pageSize.value = normalizedLimit; + currentPage.value = Math.floor(offset / normalizedLimit) + 1; }, ); const canGoNextPage = computed(() => props.result.has_more === true || props.result.rows.length >= pageSize.value); @@ -1216,11 +1231,16 @@ function nextPage() { emit("paginate", (currentPage.value - 1) * pageSize.value, pageSize.value, currentWhereInput(), currentOrderBy()); } function changePageSize(size: number) { - pageSize.value = size; - settingsStore.updateEditorSettings({ pageSize: size }); + const normalizedSize = normalizeResultPageSize(size); + pageSize.value = normalizedSize; + settingsStore.updateEditorSettings({ pageSize: normalizedSize }); currentPage.value = 1; resetGridVerticalScroll(true); - emit("paginate", 0, size, currentWhereInput(), currentOrderBy()); + emit("paginate", 0, normalizedSize, currentWhereInput(), currentOrderBy()); +} + +function applyCustomPageSize() { + changePageSize(normalizeResultPageSize(customPageSizeInput.value, pageSize.value)); } async function lastPage() { @@ -3946,10 +3966,27 @@ defineExpose({ {{ pageSize }}{{ t("grid.rowsPerPageShort") }} - - + + {{ s }} {{ t("grid.rowsPerPageShort") }} + + {{ t("grid.customRowsPerPage") }} +
+ + +