feat(base): add BaseViewDraft type and view-draft atom family

This commit is contained in:
Philipinho
2026-04-20 22:40:37 +01:00
parent 9b5e3783dd
commit 196afc21d4
2 changed files with 33 additions and 0 deletions
@@ -0,0 +1,22 @@
import { atomFamily, atomWithStorage } from "jotai/utils";
import { BaseViewDraft } from "@/features/base/types/base.types";
export type ViewDraftKey = {
userId: string;
baseId: string;
viewId: string;
};
export const viewDraftStorageKey = (k: ViewDraftKey) =>
`docmost:base-view-draft:v1:${k.userId}:${k.baseId}:${k.viewId}`;
// `atomWithStorage` handles JSON serialization, cross-tab sync via the
// `storage` event, and lazy first-read out of the box. `atomFamily`'s
// comparator ensures the same triple resolves to the same atom instance
// across renders, so identity-equality cache hits in Jotai still work.
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,
);
@@ -299,3 +299,14 @@ export type UpdatePropertyResult = {
// when the job finished migrating cells.
jobId: string | null;
};
// Local-first draft of filter / sort tweaks for a single view, stored in
// localStorage scoped to (userId, baseId, viewId). An absent `filter` or
// `sorts` field means "inherit the baseline for that axis". See
// `.claude/superpowers/specs/2026-04-20-base-view-draft-design.md`.
export type BaseViewDraft = {
filter?: FilterGroup;
sorts?: ViewSortConfig[];
// ISO timestamp written on each put; diagnostic only, not read by logic.
updatedAt: string;
};