mirror of
https://github.com/docmost/docmost.git
synced 2026-08-29 18:14:58 +08:00
Base WIP
This commit is contained in:
@@ -61,7 +61,13 @@ export function useUpdatePropertyMutation() {
|
||||
},
|
||||
);
|
||||
|
||||
if (result.conversionSummary || variables.type) {
|
||||
// Invalidate rows only for the synchronous (inline) path — the
|
||||
// HTTP response there is the "cells are migrated" signal. When the
|
||||
// server hands back a `jobId`, cells are still being rewritten; the
|
||||
// `base:schema:bumped` socket event is the canonical refetch
|
||||
// trigger in that case, and we'd only churn pages with old data by
|
||||
// refetching now.
|
||||
if (variables.type && !result.jobId) {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ["base-rows", variables.baseId],
|
||||
});
|
||||
|
||||
@@ -16,41 +16,61 @@ import {
|
||||
UpdateRowInput,
|
||||
DeleteRowInput,
|
||||
ReorderRowInput,
|
||||
ViewFilterConfig,
|
||||
FilterNode,
|
||||
SearchSpec,
|
||||
ViewSortConfig,
|
||||
} from "@/features/base/types/base.types";
|
||||
import { notifications } from "@mantine/notifications";
|
||||
import { queryClient } from "@/main";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { IPagination } from "@/lib/types";
|
||||
import { markRequestIdOutbound } from "@/features/base/hooks/use-base-socket";
|
||||
|
||||
type RowCacheContext = {
|
||||
snapshots: [readonly unknown[], InfiniteData<IPagination<IBaseRow>> | undefined][];
|
||||
};
|
||||
|
||||
// Generate a fresh requestId and pre-register it as outbound so the
|
||||
// incoming socket echo is suppressed by `useBaseSocket`.
|
||||
function newRequestId(): string {
|
||||
const id =
|
||||
typeof crypto !== "undefined" &&
|
||||
typeof (crypto as any).randomUUID === "function"
|
||||
? (crypto as any).randomUUID()
|
||||
: `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
|
||||
markRequestIdOutbound(id);
|
||||
return id;
|
||||
}
|
||||
|
||||
export function useBaseRowsQuery(
|
||||
baseId: string | undefined,
|
||||
filters?: ViewFilterConfig[],
|
||||
filter?: FilterNode,
|
||||
sorts?: ViewSortConfig[],
|
||||
search?: SearchSpec,
|
||||
) {
|
||||
// Normalize empty arrays to undefined so query keys stay stable
|
||||
const activeFilters = filters?.length ? filters : undefined;
|
||||
const activeFilter = filter ?? undefined;
|
||||
const activeSorts = sorts?.length ? sorts : undefined;
|
||||
const activeSearch = search?.query ? search : undefined;
|
||||
|
||||
return useInfiniteQuery({
|
||||
queryKey: ["base-rows", baseId, activeFilters, activeSorts],
|
||||
queryKey: ["base-rows", baseId, activeFilter, activeSorts, activeSearch],
|
||||
queryFn: ({ pageParam }) =>
|
||||
listRows(baseId!, {
|
||||
cursor: pageParam,
|
||||
limit: 100,
|
||||
filters: activeFilters,
|
||||
filter: activeFilter,
|
||||
sorts: activeSorts,
|
||||
search: activeSearch,
|
||||
}),
|
||||
enabled: !!baseId,
|
||||
initialPageParam: undefined as string | undefined,
|
||||
getNextPageParam: (lastPage: IPagination<IBaseRow>) =>
|
||||
lastPage.meta?.nextCursor ?? undefined,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
// Cap cached pages so an invalidate after a type-conversion refetches
|
||||
// a bounded set instead of serially re-requesting every page the user
|
||||
// has ever scrolled through.
|
||||
maxPages: 5,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -64,7 +84,7 @@ export function flattenRows(
|
||||
export function useCreateRowMutation() {
|
||||
const { t } = useTranslation();
|
||||
return useMutation<IBaseRow, Error, CreateRowInput>({
|
||||
mutationFn: (data) => createRow(data),
|
||||
mutationFn: (data) => createRow({ ...data, requestId: newRequestId() }),
|
||||
onSuccess: (newRow) => {
|
||||
queryClient.setQueriesData<InfiniteData<IPagination<IBaseRow>>>(
|
||||
{ queryKey: ["base-rows", newRow.baseId] },
|
||||
@@ -95,7 +115,7 @@ export function useCreateRowMutation() {
|
||||
export function useUpdateRowMutation() {
|
||||
const { t } = useTranslation();
|
||||
return useMutation<IBaseRow, Error, UpdateRowInput, RowCacheContext>({
|
||||
mutationFn: (data) => updateRow(data),
|
||||
mutationFn: (data) => updateRow({ ...data, requestId: newRequestId() }),
|
||||
onMutate: async (variables) => {
|
||||
await queryClient.cancelQueries({
|
||||
queryKey: ["base-rows", variables.baseId],
|
||||
@@ -164,7 +184,7 @@ export function useUpdateRowMutation() {
|
||||
export function useDeleteRowMutation() {
|
||||
const { t } = useTranslation();
|
||||
return useMutation<void, Error, DeleteRowInput, RowCacheContext>({
|
||||
mutationFn: (data) => deleteRow(data),
|
||||
mutationFn: (data) => deleteRow({ ...data, requestId: newRequestId() }),
|
||||
onMutate: async (variables) => {
|
||||
await queryClient.cancelQueries({
|
||||
queryKey: ["base-rows", variables.baseId],
|
||||
@@ -207,7 +227,7 @@ export function useDeleteRowMutation() {
|
||||
export function useReorderRowMutation() {
|
||||
const { t } = useTranslation();
|
||||
return useMutation<void, Error, ReorderRowInput, RowCacheContext>({
|
||||
mutationFn: (data) => reorderRow(data),
|
||||
mutationFn: (data) => reorderRow({ ...data, requestId: newRequestId() }),
|
||||
onMutate: async (variables) => {
|
||||
await queryClient.cancelQueries({
|
||||
queryKey: ["base-rows", variables.baseId],
|
||||
|
||||
Reference in New Issue
Block a user