Support observable grid queries and file filters
This commit is contained in:
@@ -126,11 +126,16 @@ type DataGridBaseProps<T> = {
|
||||
|
||||
/**
|
||||
* Query ownership is deliberately explicit: client grids receive all rows and
|
||||
* DataGrid queries them locally; server grids receive one page and must handle
|
||||
* the complete query through `onQueryChange`.
|
||||
* DataGrid queries them locally, while optional `onQueryChange` observers can
|
||||
* explain the current match. Server grids receive one page and must handle the
|
||||
* complete query through `onQueryChange`.
|
||||
*/
|
||||
export type DataGridProps<T> = DataGridBaseProps<T> & (
|
||||
| {pagination?: DataGridClientPagination;onQueryChange?: never;}
|
||||
| {
|
||||
pagination?: DataGridClientPagination;
|
||||
/** Observe client-side filters and sorting without taking ownership of them. */
|
||||
onQueryChange?: (query: DataGridQueryState) => void;
|
||||
}
|
||||
| {pagination: DataGridServerPagination;onQueryChange: (query: DataGridQueryState) => void;}
|
||||
);
|
||||
|
||||
@@ -256,7 +261,7 @@ export default function DataGrid<T>({
|
||||
const serverQueryMode = pagination?.mode === "server";
|
||||
const onQueryChangeRef = useRef(onQueryChange);
|
||||
const serverPaginationRef = useRef<DataGridServerPagination | null>(serverQueryMode ? pagination : null);
|
||||
const lastServerQueryRef = useRef<DataGridQueryState | null>(null);
|
||||
const lastQueryRef = useRef<DataGridQueryState | null>(null);
|
||||
const lastLayoutSignatureRef = useRef<string | null>(null);
|
||||
const lastContainerWidthRef = useRef<number | undefined>(undefined);
|
||||
const [measuredWidths, setMeasuredWidths] = useState<Record<string, number>>({});
|
||||
@@ -265,7 +270,6 @@ export default function DataGrid<T>({
|
||||
|
||||
useEffect(() => {
|
||||
serverPaginationRef.current = serverQueryMode ? pagination as DataGridServerPagination : null;
|
||||
if (!serverQueryMode) lastServerQueryRef.current = null;
|
||||
}, [pagination, serverQueryMode]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -510,18 +514,23 @@ export default function DataGrid<T>({
|
||||
}, [openFilterColumnId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!serverQueryMode) return;
|
||||
const query = {
|
||||
const nextQuery = {
|
||||
sort: state.sort ?? null,
|
||||
filters: { ...(state.filters ?? {}) }
|
||||
};
|
||||
const previousQuery = lastServerQueryRef.current;
|
||||
lastServerQueryRef.current = query;
|
||||
const previousQuery = lastQueryRef.current;
|
||||
lastQueryRef.current = nextQuery;
|
||||
const serverPagination = serverPaginationRef.current;
|
||||
if (previousQuery && !dataGridQueriesEqual(previousQuery, query) && serverPagination && serverPagination.page !== 1) {
|
||||
if (
|
||||
serverQueryMode &&
|
||||
previousQuery &&
|
||||
!dataGridQueriesEqual(previousQuery, nextQuery) &&
|
||||
serverPagination &&
|
||||
serverPagination.page !== 1
|
||||
) {
|
||||
serverPagination.onPageChange(1);
|
||||
}
|
||||
onQueryChangeRef.current?.(query);
|
||||
onQueryChangeRef.current?.(nextQuery);
|
||||
}, [serverQueryMode, state.sort, state.filters]);
|
||||
|
||||
const filterTypes = useMemo(() => {
|
||||
|
||||
@@ -857,7 +857,7 @@ export type FilesFileFolder = {
|
||||
};
|
||||
|
||||
export type FilesFileSpacesResponse = { spaces: FilesFileSpace[] };
|
||||
export type FilesFileListResponse = { files: FilesManagedFile[]; cursor?: string | null; next_cursor?: string | null };
|
||||
export type FilesFileListResponse = { files: FilesManagedFile[]; total: number; cursor?: string | null; next_cursor?: string | null };
|
||||
export type FilesFileFoldersResponse = { folders: FilesFileFolder[]; cursor?: string | null; next_cursor?: string | null };
|
||||
export type FilesFileDeltaResponse = {
|
||||
files: FilesManagedFile[];
|
||||
@@ -917,7 +917,7 @@ export type FilesFileExplorerUiCapability = {
|
||||
FolderTree: ComponentType<FilesFolderTreeProps>;
|
||||
ManagedFileChooser?: ComponentType<FilesManagedFileChooserProps>;
|
||||
listFileSpaces?: (settings: ApiSettings) => Promise<FilesFileSpacesResponse>;
|
||||
listFiles?: (settings: ApiSettings, params?: { owner_type?: FilesOwnerType | string; owner_id?: string; campaign_id?: string; path_prefix?: string; page_size?: number; cursor?: string | null }) => Promise<FilesFileListResponse>;
|
||||
listFiles?: (settings: ApiSettings, params?: { owner_type?: FilesOwnerType | string; owner_id?: string; campaign_id?: string; path_prefix?: string; campaign_usage?: "linked" | "unlinked"; audit_relevant?: boolean; page_size?: number; cursor?: string | null }) => Promise<FilesFileListResponse>;
|
||||
listFilesDelta?: (settings: ApiSettings, params?: { owner_type?: FilesOwnerType | string; owner_id?: string; campaign_id?: string; path_prefix?: string; since?: string | null; limit?: number }) => Promise<FilesFileDeltaResponse>;
|
||||
listFolders?: (settings: ApiSettings, params: { owner_type: FilesOwnerType; owner_id: string; page_size?: number; cursor?: string | null }) => Promise<FilesFileFoldersResponse>;
|
||||
resolveFilePatterns?: (
|
||||
|
||||
Reference in New Issue
Block a user