refactor(base): rename baseId to pageId in client atoms, hooks, types

This commit is contained in:
Philipinho
2026-04-27 01:42:54 +01:00
parent 4510543510
commit 3e9f26a8dd
6 changed files with 57 additions and 57 deletions
@@ -3,12 +3,12 @@ import { BaseViewDraft } from "@/features/base/types/base.types";
export type ViewDraftKey = {
userId: string;
baseId: string;
pageId: string;
viewId: string;
};
export const viewDraftStorageKey = (k: ViewDraftKey) =>
`docmost:base-view-draft:v1:${k.userId}:${k.baseId}:${k.viewId}`;
`docmost:base-view-draft:v1:${k.userId}:${k.pageId}:${k.viewId}`;
// `atomWithStorage` handles JSON serialization, cross-tab sync via the
// `storage` event, and lazy first-read out of the box. `atomFamily`'s
@@ -18,5 +18,5 @@ export const viewDraftAtomFamily = atomFamily(
(k: ViewDraftKey) =>
atomWithStorage<BaseViewDraft | null>(viewDraftStorageKey(k), null),
(a, b) =>
a.userId === b.userId && a.baseId === b.baseId && a.viewId === b.viewId,
a.userId === b.userId && a.pageId === b.pageId && a.viewId === b.viewId,
);
@@ -13,14 +13,14 @@ import { IPagination } from "@/lib/types";
type BaseRowCreated = {
operation: "base:row:created";
baseId: string;
pageId: string;
row: IBaseRow;
requestId?: string | null;
};
type BaseRowUpdated = {
operation: "base:row:updated";
baseId: string;
pageId: string;
rowId: string;
updatedCells: Record<string, unknown>;
requestId?: string | null;
@@ -28,21 +28,21 @@ type BaseRowUpdated = {
type BaseRowDeleted = {
operation: "base:row:deleted";
baseId: string;
pageId: string;
rowId: string;
requestId?: string | null;
};
type BaseRowsDeleted = {
operation: "base:rows:deleted";
baseId: string;
pageId: string;
rowIds: string[];
requestId?: string | null;
};
type BaseRowReordered = {
operation: "base:row:reordered";
baseId: string;
pageId: string;
rowId: string;
position: string;
requestId?: string | null;
@@ -54,7 +54,7 @@ type BasePropertyEvent = {
| "base:property:updated"
| "base:property:deleted"
| "base:property:reordered";
baseId: string;
pageId: string;
property?: IBaseProperty;
propertyId?: string;
requestId?: string | null;
@@ -65,14 +65,14 @@ type BaseViewEvent = {
| "base:view:created"
| "base:view:updated"
| "base:view:deleted";
baseId: string;
pageId: string;
view?: IBaseView;
viewId?: string;
};
type BaseRowsUpdated = {
operation: "base:rows:updated";
baseId: string;
pageId: string;
rowIds: string[];
propertyIds: string[];
requestId?: string | null;
@@ -80,14 +80,14 @@ type BaseRowsUpdated = {
type BaseFormulaRecomputeStarted = {
operation: "base:formula:recompute:started";
baseId: string;
pageId: string;
propertyIds: string[];
jobId: string;
};
type BaseFormulaRecomputeCompleted = {
operation: "base:formula:recompute:completed";
baseId: string;
pageId: string;
propertyIds: string[];
jobId: string;
processed: number;
@@ -105,7 +105,7 @@ type BaseInboundEvent =
| BaseFormulaRecomputeCompleted
| BasePropertyEvent
| BaseViewEvent
| { operation: string; baseId: string };
| { operation: string; pageId: string };
/*
* Module-level set of requestIds we've just sent to the server. When the
@@ -126,24 +126,24 @@ export function markRequestIdOutbound(requestId: string): void {
}
/*
* Realtime bridge for a single base. Joins the server's `base-{baseId}`
* Realtime bridge for a single base. Joins the server's `base-{pageId}`
* room on mount, leaves on unmount, and reconciles the React Query caches
* (`["base-rows", baseId, ...]` and `["bases", baseId]`) when events
* (`["base-rows", pageId, ...]` and `["bases", pageId]`) when events
* arrive from other clients.
*/
export function useBaseSocket(baseId: string | undefined): void {
export function useBaseSocket(pageId: string | undefined): void {
const socket = useAtomValue(socketAtom);
const queryClient = useQueryClient();
useEffect(() => {
if (!socket || !baseId) return;
if (!socket || !pageId) return;
socket.emit("message", { operation: "base:subscribe", baseId });
socket.emit("message", { operation: "base:subscribe", pageId });
const handler = (raw: unknown) => {
if (!raw || typeof raw !== "object") return;
const event = raw as BaseInboundEvent;
if (event.baseId !== baseId) return;
if (event.pageId !== pageId) return;
const requestId = (event as any).requestId as string | undefined;
if (requestId && outboundRequestIds.has(requestId)) {
@@ -155,7 +155,7 @@ export function useBaseSocket(baseId: string | undefined): void {
case "base:row:created": {
const e = event as BaseRowCreated;
queryClient.setQueriesData<InfiniteData<IPagination<IBaseRow>>>(
{ queryKey: ["base-rows", baseId] },
{ queryKey: ["base-rows", pageId] },
(old) => {
if (!old) return old;
const lastPageIndex = old.pages.length - 1;
@@ -174,7 +174,7 @@ export function useBaseSocket(baseId: string | undefined): void {
case "base:row:updated": {
const e = event as BaseRowUpdated;
queryClient.setQueriesData<InfiniteData<IPagination<IBaseRow>>>(
{ queryKey: ["base-rows", baseId] },
{ queryKey: ["base-rows", pageId] },
(old) =>
!old
? old
@@ -198,7 +198,7 @@ export function useBaseSocket(baseId: string | undefined): void {
case "base:row:deleted": {
const e = event as BaseRowDeleted;
queryClient.setQueriesData<InfiniteData<IPagination<IBaseRow>>>(
{ queryKey: ["base-rows", baseId] },
{ queryKey: ["base-rows", pageId] },
(old) =>
!old
? old
@@ -223,7 +223,7 @@ export function useBaseSocket(baseId: string | undefined): void {
const e = event as BaseRowsDeleted;
const removeSet = new Set(e.rowIds);
queryClient.setQueriesData<InfiniteData<IPagination<IBaseRow>>>(
{ queryKey: ["base-rows", baseId] },
{ queryKey: ["base-rows", pageId] },
(old) => {
if (!old) return old;
return {
@@ -250,7 +250,7 @@ export function useBaseSocket(baseId: string | undefined): void {
case "base:row:reordered": {
const e = event as BaseRowReordered;
queryClient.setQueriesData<InfiniteData<IPagination<IBaseRow>>>(
{ queryKey: ["base-rows", baseId] },
{ queryKey: ["base-rows", pageId] },
(old) =>
!old
? old
@@ -278,7 +278,7 @@ export function useBaseSocket(baseId: string | undefined): void {
const updatedIds = new Set(e.rowIds);
const caches = queryClient.getQueriesData<
InfiniteData<IPagination<IBaseRow>>
>({ queryKey: ["base-rows", baseId] });
>({ queryKey: ["base-rows", pageId] });
let touchesCache = false;
outer: for (const [, data] of caches) {
if (!data) continue;
@@ -292,7 +292,7 @@ export function useBaseSocket(baseId: string | undefined): void {
}
}
if (touchesCache) {
queryClient.invalidateQueries({ queryKey: ["base-rows", baseId] });
queryClient.invalidateQueries({ queryKey: ["base-rows", pageId] });
}
break;
}
@@ -325,9 +325,9 @@ export function useBaseSocket(baseId: string | undefined): void {
case "base:view:deleted": {
// Schema/metadata events only touch the base's `properties` /
// `views`, not the cell data — so we invalidate just
// `["bases", baseId]` here. Row reconciliation is handled
// `["bases", pageId]` here. Row reconciliation is handled
// per-event by the row cases above.
queryClient.invalidateQueries({ queryKey: ["bases", baseId] });
queryClient.invalidateQueries({ queryKey: ["bases", pageId] });
break;
}
default:
@@ -339,7 +339,7 @@ export function useBaseSocket(baseId: string | undefined): void {
return () => {
socket.off("message", handler);
socket.emit("message", { operation: "base:unsubscribe", baseId });
socket.emit("message", { operation: "base:unsubscribe", pageId });
};
}, [socket, baseId, queryClient]);
}, [socket, pageId, queryClient]);
}
@@ -400,7 +400,7 @@ export function useBaseTable(
filter: baseline?.filter,
});
updateViewMutation.mutate(
{ viewId: activeView.id, baseId: base.id, config },
{ viewId: activeView.id, pageId: base.id, config },
{
onSettled: () => {
// Don't clear if the user has already scheduled another
@@ -8,7 +8,7 @@ import { useDeleteRowsMutation } from "@/features/base/queries/base-row-query";
const BATCH_SIZE = 500;
export function useDeleteSelectedRows(baseId: string) {
export function useDeleteSelectedRows(pageId: string) {
const { t } = useTranslation();
const { selectedIds, clear } = useRowSelection();
const mutation = useDeleteRowsMutation();
@@ -21,7 +21,7 @@ export function useDeleteSelectedRows(baseId: string) {
}
try {
for (const chunk of chunks) {
await mutation.mutateAsync({ baseId, rowIds: chunk });
await mutation.mutateAsync({ pageId, rowIds: chunk });
}
notifications.show({
message: t("{{count}} rows deleted", { count: ids.length }),
@@ -31,7 +31,7 @@ export function useDeleteSelectedRows(baseId: string) {
// mutation onError already shows notification
}
},
[baseId, mutation, clear, t],
[pageId, mutation, clear, t],
);
const deleteSelected = useCallback(() => {
@@ -11,7 +11,7 @@ import { viewDraftAtomFamily } from "@/features/base/atoms/view-draft-atom";
export type UseViewDraftArgs = {
userId: string | undefined;
baseId: string | undefined;
pageId: string | undefined;
viewId: string | undefined;
baselineFilter: FilterGroup | undefined;
baselineSorts: ViewSortConfig[] | undefined;
@@ -43,18 +43,18 @@ function sortsEq(
}
export function useViewDraft(args: UseViewDraftArgs): ViewDraftState {
const { userId, baseId, viewId, baselineFilter, baselineSorts } = args;
const ready = !!(userId && baseId && viewId);
const { userId, pageId, viewId, baselineFilter, baselineSorts } = args;
const ready = !!(userId && pageId && viewId);
// Always mount an atom with a stable shape so hook order is consistent.
// When not ready we still feed a key, but we won't read/write it.
const atomKey = useMemo(
() => ({
userId: userId ?? "",
baseId: baseId ?? "",
pageId: pageId ?? "",
viewId: viewId ?? "",
}),
[userId, baseId, viewId],
[userId, pageId, viewId],
);
const [storedDraft, setDraft] = useAtom(viewDraftAtomFamily(atomKey));
@@ -81,7 +81,7 @@ export type TypeOptions =
export type IBaseProperty = {
id: string;
baseId: string;
pageId: string;
name: string;
type: BasePropertyType;
position: string;
@@ -99,7 +99,7 @@ export type IBaseProperty = {
export type IBaseRow = {
id: string;
baseId: string;
pageId: string;
cells: Record<string, unknown>;
position: string;
creatorId: string;
@@ -165,7 +165,7 @@ export type ViewConfig = {
export type IBaseView = {
id: string;
baseId: string;
pageId: string;
name: string;
type: 'table' | 'kanban' | 'calendar';
config: ViewConfig;
@@ -204,14 +204,14 @@ export type CreateBaseInput = {
};
export type UpdateBaseInput = {
baseId: string;
pageId: string;
name?: string;
description?: string;
icon?: string;
};
export type CreatePropertyInput = {
baseId: string;
pageId: string;
name: string;
type: BasePropertyType;
typeOptions?: TypeOptions;
@@ -220,7 +220,7 @@ export type CreatePropertyInput = {
export type UpdatePropertyInput = {
propertyId: string;
baseId: string;
pageId: string;
name?: string;
typeOptions?: TypeOptions;
requestId?: string;
@@ -228,19 +228,19 @@ export type UpdatePropertyInput = {
export type DeletePropertyInput = {
propertyId: string;
baseId: string;
pageId: string;
requestId?: string;
};
export type ReorderPropertyInput = {
propertyId: string;
baseId: string;
pageId: string;
position: string;
requestId?: string;
};
export type CountRowsInput = {
baseId: string;
pageId: string;
filter?: FilterNode;
search?: SearchSpec;
// When true the server returns an exact (but capped) count. Otherwise
@@ -255,7 +255,7 @@ export type CountRowsResult = {
};
export type CreateRowInput = {
baseId: string;
pageId: string;
cells?: Record<string, unknown>;
afterRowId?: string;
requestId?: string;
@@ -263,32 +263,32 @@ export type CreateRowInput = {
export type UpdateRowInput = {
rowId: string;
baseId: string;
pageId: string;
cells: Record<string, unknown>;
requestId?: string;
};
export type DeleteRowInput = {
rowId: string;
baseId: string;
pageId: string;
requestId?: string;
};
export type DeleteRowsInput = {
baseId: string;
pageId: string;
rowIds: string[];
requestId?: string;
};
export type ReorderRowInput = {
rowId: string;
baseId: string;
pageId: string;
position: string;
requestId?: string;
};
export type CreateViewInput = {
baseId: string;
pageId: string;
name: string;
type?: 'table' | 'kanban' | 'calendar';
config?: ViewConfig;
@@ -296,7 +296,7 @@ export type CreateViewInput = {
export type UpdateViewInput = {
viewId: string;
baseId: string;
pageId: string;
name?: string;
type?: 'table' | 'kanban' | 'calendar';
config?: ViewConfig;
@@ -304,7 +304,7 @@ export type UpdateViewInput = {
export type DeleteViewInput = {
viewId: string;
baseId: string;
pageId: string;
};
export type UpdatePropertyResult = {