fix formula

This commit is contained in:
Philipinho
2026-04-24 01:33:14 +01:00
parent 82705ce3bd
commit f99450f04a
3 changed files with 43 additions and 6 deletions
@@ -234,7 +234,15 @@ export function CreatePropertyPopover({ baseId, properties, onPropertyCreated }:
</Stack>
)}
{panel === "configure" && selectedType === "formula" && (
<Stack gap={0} p="sm">
<Stack gap="xs" p="sm">
<TextInput
ref={nameInputRef}
size="xs"
label={t("Name")}
placeholder={selectedTypeLabel}
value={name}
onChange={(e) => setName(e.currentTarget.value)}
/>
<FormulaEditor
properties={properties ?? []}
editingPropertyId={null}
@@ -269,9 +269,31 @@ export function useBaseSocket(baseId: string | undefined): void {
break;
}
case "base:rows:updated": {
// Formula recompute wrote new cell values on the server. The event
// only carries row IDs, so invalidate the rows query to refetch.
queryClient.invalidateQueries({ queryKey: ["base-rows", baseId] });
const e = event as BaseRowsUpdated;
// Only refetch if the batch touches rows currently in cache.
// Uncached pages will fetch fresh when the user scrolls to them,
// so invalidating on batches the user can't see is wasted work —
// formula backfills on a large base emit one batch event per 500
// rows, so this also drops ~Nrows/500 redundant refetches.
const updatedIds = new Set(e.rowIds);
const caches = queryClient.getQueriesData<
InfiniteData<IPagination<IBaseRow>>
>({ queryKey: ["base-rows", baseId] });
let touchesCache = false;
outer: for (const [, data] of caches) {
if (!data) continue;
for (const page of data.pages) {
for (const row of page.items) {
if (updatedIds.has(row.id)) {
touchesCache = true;
break outer;
}
}
}
}
if (touchesCache) {
queryClient.invalidateQueries({ queryKey: ["base-rows", baseId] });
}
break;
}
case "base:formula:recompute:started": {
@@ -64,7 +64,14 @@ export function useViewDraft(args: UseViewDraftArgs): ViewDraftState {
(next: FilterGroup | undefined) => {
if (!ready) return;
const current = storedDraft ?? null;
const mergedFilter = next;
// If the baseline has a filter, clearing to `undefined` would fall
// back to the baseline in effectiveFilter. Persist an empty AND-group
// instead so the draft explicitly overrides the baseline with no
// predicates.
const mergedFilter =
next === undefined && baselineFilter !== undefined
? ({ op: "and", children: [] } as FilterGroup)
: next;
const mergedSorts = current?.sorts;
if (mergedFilter === undefined && (mergedSorts === undefined || mergedSorts === null)) {
setDraft(RESET);
@@ -76,7 +83,7 @@ export function useViewDraft(args: UseViewDraftArgs): ViewDraftState {
updatedAt: new Date().toISOString(),
});
},
[ready, storedDraft, setDraft],
[ready, storedDraft, setDraft, baselineFilter],
);
const setSorts = useCallback(