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,
};
}