|
340 | 340 | </span> |
341 | 341 | </template> |
342 | 342 | </span> |
| 343 | + <div v-if="totalRows > 0 && pageSizeOptionsComputed?.length" |
| 344 | + class="flex items-center gap-2 ml-auto" > |
| 345 | + <span class="text-sm text-lightListTablePaginationHelpText dark:text-darkListTablePaginationHelpText whitespace-nowrap"> |
| 346 | + {{ $t('Rows per page') }} |
| 347 | + </span> |
| 348 | + <Select |
| 349 | + v-model="pageSizeInternal" |
| 350 | + :options="pageSizeOptionsComputed" |
| 351 | + :searchDisabled="true" |
| 352 | + :disableTogleOfSelectedItem="true" |
| 353 | + :style="{ width: selectDynamicWidth }" |
| 354 | + :placeholder="pageSizeInternal?.toString()" |
| 355 | + class="text-sm" |
| 356 | + classesForInput="h-[34px] min-h-0 py-1 pl-2 pr-6 text-sm rounded-md cursor-pointer af-button-shadow bg-lightDropdownButtonsBackground text-lightDropdownButtonsText border-lightDropdownButtonsBorder dark:bg-darkDropdownButtonsBackground dark:text-darkDropdownButtonsText dark:border-darkDropdownButtonsBorder" |
| 357 | + /> |
| 358 | + </div> |
343 | 359 | </div> |
344 | 360 | </template> |
345 | 361 |
|
@@ -368,6 +384,7 @@ import { useAdminforth } from '@/adminforth'; |
368 | 384 | import Checkbox from '@/afcl/Checkbox.vue'; |
369 | 385 | import ListActionsThreeDots from '@/components/ListActionsThreeDots.vue'; |
370 | 386 | import CallActionWrapper from '@/components/CallActionWrapper.vue' |
| 387 | +import { Select } from '@/afcl'; |
371 | 388 |
|
372 | 389 | const coreStore = useCoreStore(); |
373 | 390 | const { t } = useI18n(); |
@@ -407,10 +424,45 @@ const emits = defineEmits([ |
407 | 424 | 'update:page', |
408 | 425 | 'update:sort', |
409 | 426 | 'update:checkboxes', |
410 | | - 'update:records' |
| 427 | + 'update:records', |
| 428 | + 'update:pageSize' |
411 | 429 |
|
412 | 430 | ]); |
413 | 431 |
|
| 432 | +const pageSizeOptionsComputed = computed(() => { |
| 433 | + const options = props.resource?.options?.listPageSizeOptions || [10, 20, 50, 100]; |
| 434 | + return options.map(size => ({ |
| 435 | + value: size, |
| 436 | + label: size.toString() |
| 437 | + })); |
| 438 | +}); |
| 439 | +
|
| 440 | +const pageSizeInternal = ref(props.pageSize); |
| 441 | +
|
| 442 | +const selectDynamicWidth = computed(() => { |
| 443 | + const length = pageSizeInternal.value?.toString().length || 2; |
| 444 | + return `${length + 5}ch`; |
| 445 | +}) |
| 446 | +
|
| 447 | +watch(() => pageSizeInternal.value, (newSize) => { |
| 448 | + if (newSize) { |
| 449 | + localStorage.setItem(`pageSize_${props.resource?.resourceId}`, newSize.toString()); |
| 450 | + emits('update:pageSize', newSize); |
| 451 | + page.value = 1; |
| 452 | + } |
| 453 | +}); |
| 454 | +
|
| 455 | +onMounted(() => { |
| 456 | + const savedSize = localStorage.getItem(`pageSize_${props.resource?.resourceId}`); |
| 457 | + if (savedSize) { |
| 458 | + const sizeNum = parseInt(savedSize); |
| 459 | + if (props.resource?.options?.listPageSizeOptions?.includes(sizeNum)) { |
| 460 | + pageSizeInternal.value = sizeNum; |
| 461 | + emits('update:pageSize', sizeNum); |
| 462 | + } |
| 463 | + } |
| 464 | +}); |
| 465 | +
|
414 | 466 | const checkboxesInternal: Ref<any[]> = ref([]); |
415 | 467 | const pageInput = ref('1'); |
416 | 468 | const page = ref(1); |
|
0 commit comments