ServerQueryManager#
@palmyralabs/rt-forms · src/palmyra/wire/ServerQueryManager.tsx
Overview#
Not a component — the file’s single runtime export is the useServerQuery hook. It manages the filter / sort / pagination state of a server-backed grid against a Wire GridStore, and returns an imperative handle (IPageQueryable) that grid templates consume.
If no store is passed in, the hook reaches for StoreFactoryContext and asks the factory for a grid store keyed on endPoint + storeOptions. That’s the seam that makes grids and forms share the same factory configuration.
Signature#
function useServerQuery(props: IServerQueryInput): IPageQueryable;Props — IServerQueryInput#
interface IServerQueryInput extends AbstractHandler {
store?: AbstractQueryStore<any> & { export?(r: ExportRequest): void };
endPoint?: IEndPoint;
storeOptions?: StoreOptions;
fields?: string[];
fetchAll?: boolean;
defaultParams?: DefaultQueryParams;
onDataChange?: (newData: any[], oldData?: any[]) => void;
pageSize?: number | number[];
quickSearch?: string;
filterTopic?: string;
initialFetch?: boolean;
initParams?: {
filter?: any;
sort?: string | string[];
limit?: number;
offset?: number;
};
}Return — IPageQueryable#
interface IQueryable {
setQuickSearch(q: string): void;
setFilter(f: any): void;
addFilter(f: any): void;
resetFilter(): void;
setSortColumns(sort: string | string[]): void;
setEndPointOptions(opts: Record<string, any>): void;
refresh(): void;
getCurrentData(): any[];
export(req: ExportRequest): void;
isLoading(): boolean;
}
interface IPageQueryable extends IQueryable {
setQueryLimit(limit: number): void;
getQueryLimit(): number;
gotoPage(n: number): void;
nextPage(): void;
prevPage(): void;
setPageSize(sizes: number | number[]): void;
getPageNo(): number;
getQueryRequest(): QueryRequest;
getCurrentFilter(): any;
getTotalPages(): number;
getTotalRecords(): number;
}Example — hook-driven grid#
import { useRef } from 'react';
import { useServerQuery, type IPageQueryable } from '@palmyralabs/rt-forms';
import { Table, Pagination, TextInput, Group } from '@mantine/core';
export function ManufacturersGrid() {
const q: IPageQueryable = useServerQuery({
endPoint: '/mstManufacturer',
pageSize: [15, 30, 45],
initParams: { sort: ['-id'], limit: 15, offset: 0 },
initialFetch: true,
});
const rows = q.getCurrentData();
return (
<>
<TextInput placeholder="Search"
onChange={e => q.setQuickSearch(e.currentTarget.value)} mb="md" />
<Table>
<Table.Tbody>
{rows.map((r: any) => (
<Table.Tr key={r.id}>
<Table.Td>{r.name}</Table.Td>
<Table.Td>{r.contactMobile}</Table.Td>
</Table.Tr>
))}
</Table.Tbody>
</Table>
<Group justify="flex-end">
<Pagination total={q.getTotalPages()} value={q.getPageNo()} onChange={q.gotoPage} />
</Group>
</>
);
}SummaryGrid and similar templates just pass their own props into useServerQuery and wire the returned IPageQueryable to the toolbar, table, and paginator — you can build the same thing by hand when you need a non-standard chrome.