-
Notifications
You must be signed in to change notification settings - Fork 79
Expand file tree
/
Copy pathuse-table-ui-state.ts
More file actions
112 lines (97 loc) · 3.05 KB
/
Copy pathuse-table-ui-state.ts
File metadata and controls
112 lines (97 loc) · 3.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import { eq, useLiveQuery } from "@tanstack/react-db";
import type { RowSelectionState } from "@tanstack/react-table";
import { useCallback, useEffect, useMemo } from "react";
import type { Table } from "../../data/adapter";
import { type TableUiState, useStudio } from "../studio/context";
import {
cloneEditingFilter,
createDefaultFilter,
createEditingFilterFromApplied,
type EditingFilterGroup,
} from "./filter-utils";
import { useNavigation } from "./use-navigation";
export interface TableUiStateDefaults {
editingFilter?: EditingFilterGroup;
rowSelectionState?: RowSelectionState;
stagedRows?: Record<string, unknown>[];
stagedUpdates?: NonNullable<TableUiState["stagedUpdates"]>;
}
function createDefaultTableUiState(
scopeKey: string,
defaults?: TableUiStateDefaults,
): TableUiState {
return {
id: scopeKey,
editingFilter: cloneEditingFilter(
defaults?.editingFilter ??
createEditingFilterFromApplied(createDefaultFilter()),
),
rowSelectionState: { ...(defaults?.rowSelectionState ?? {}) },
stagedRows: [...(defaults?.stagedRows ?? [])],
stagedUpdates: [...(defaults?.stagedUpdates ?? [])],
};
}
export function getTableScopeKey(activeTable: Table | undefined): string {
if (!activeTable) {
return "";
}
return `${activeTable.schema}.${activeTable.name}`;
}
export function useTableUiState(defaults?: TableUiStateDefaults) {
const { tableUiStateCollection } = useStudio();
const {
metadata: { activeTable },
} = useNavigation();
const scopeKey = useMemo(() => getTableScopeKey(activeTable), [activeTable]);
const { data: tableUiState } = useLiveQuery(
(q) => {
if (!scopeKey) {
return undefined;
}
return q
.from({ item: tableUiStateCollection })
.where(({ item }) => eq(item.id, scopeKey))
.select(({ item }) => ({
id: item.id,
editingFilter: item.editingFilter,
rowSelectionState: item.rowSelectionState,
stagedRows: item.stagedRows,
stagedUpdates: item.stagedUpdates,
}))
.findOne();
},
[scopeKey, tableUiStateCollection],
);
useEffect(() => {
if (!scopeKey || tableUiStateCollection.has(scopeKey)) {
return;
}
tableUiStateCollection.insert(
createDefaultTableUiState(scopeKey, defaults),
);
}, [defaults, scopeKey, tableUiStateCollection]);
const resolvedState =
!scopeKey || tableUiState
? tableUiState
: createDefaultTableUiState(scopeKey, defaults);
const updateTableUiState = useCallback(
(updater: (draft: TableUiState) => void) => {
if (!scopeKey) {
return;
}
if (!tableUiStateCollection.has(scopeKey)) {
const nextState = createDefaultTableUiState(scopeKey, defaults);
updater(nextState);
tableUiStateCollection.insert(nextState);
return;
}
tableUiStateCollection.update(scopeKey, updater);
},
[defaults, scopeKey, tableUiStateCollection],
);
return {
scopeKey,
tableUiState: resolvedState,
updateTableUiState,
};
}