import { ComputedRef, Ref, computed, ref, shallowRef, watch } from 'vue'; import { api } from 'src/services'; import type { Settings, Table } from '../stores/main/models'; interface Params { selectedTable: Ref; settings: ComputedRef; } type Row = Record; /** * Server-mode rows controller. * * Tables whose rows live in wp_vtables_source are paged by the server: the * backend returns metadata plus only the first page (see the fetch_table / * query_rows endpoints), and this composable holds the current page and * drives pagination. The page size is the server's (vtables_default_per_page): * the rows-per-page setting, search, sorting and filtering are vTables Pro * features. For tables still holding their rows inline (legacy, not yet * migrated) `isServerMode` is false and this stays inert. */ export function useServerRows({ selectedTable, settings }: Params) { const serverRows = shallowRef([]); const serverTotal: Ref = ref(0); const serverLoading: Ref = ref(false); const isServerMode: ComputedRef = computed( () => selectedTable.value?.server_mode === true ); function rowsPerPage(): number { return selectedTable.value?.per_page ?? 10; } function syncPaginationMeta(page: number) { const init = settings.value.bottom.initial as Record; init.page = page; init.rowsPerPage = rowsPerPage(); init.rowsNumber = serverTotal.value; } async function fetchPage(page: number) { if (!selectedTable.value) return; serverLoading.value = true; const { response, error } = await api.queryRows({ tableId: selectedTable.value.id, page, perPage: rowsPerPage(), }); serverLoading.value = false; if (error) return; const data = response.data as { rows: Row[]; total: number }; serverRows.value = data.rows ?? []; serverTotal.value = data.total ?? 0; syncPaginationMeta(page); } // Seed from page 1, which the FETCH_TABLE action folds into `source.rows` // (the backend ships it as `first_page` for server-mode tables). Key on the // table object reference (not id) because navigating from the list replaces // the table object while keeping the same id, and we still need to (re)seed. watch( () => selectedTable.value, () => { if (!isServerMode.value || !selectedTable.value) return; serverTotal.value = selectedTable.value.total_rows ?? 0; serverRows.value = (selectedTable.value.source?.rows ?? []) as Row[]; syncPaginationMeta(1); }, { immediate: true } ); // q-table @request handler (lazy mode): page changes. function onTableRequest(requestProps: { pagination?: { page?: number } }) { if (!isServerMode.value) return; void fetchPage(requestProps.pagination?.page ?? 1); } async function reload() { const init = settings.value.bottom.initial as Record; await fetchPage(init.page ?? 1); } return { isServerMode, serverRows, serverTotal, serverLoading, onTableRequest, reload, }; }