Skip to content

Commit d651909

Browse files
committed
Reworked the reducer to do the filtering
1 parent 6320715 commit d651909

File tree

5 files changed

+43
-20
lines changed

5 files changed

+43
-20
lines changed

apps/webapp/app/components/primitives/TreeView/TreeView.tsx

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,12 @@ export function TreeView<TData>({
128128
);
129129
}
130130

131-
export type Filter<TData> = {
132-
text?: string;
133-
fn: (text: string, node: FlatTreeItem<TData>) => boolean;
131+
export type Filter<TData, TFilterValue> = {
132+
value?: TFilterValue;
133+
fn: (value: TFilterValue, node: FlatTreeItem<TData>) => boolean;
134134
};
135135

136-
type TreeStateHookProps<TData> = {
136+
type TreeStateHookProps<TData, TFilterValue> = {
137137
tree: FlatTree<TData>;
138138
selectedId?: string;
139139
collapsedIds?: string[];
@@ -144,7 +144,7 @@ type TreeStateHookProps<TData> = {
144144
index: number;
145145
}) => number;
146146
parentRef: RefObject<any>;
147-
filter?: Filter<TData>;
147+
filter?: Filter<TData, TFilterValue>;
148148
};
149149

150150
//this is so Framer Motion can be used to render the components
@@ -180,15 +180,15 @@ export type UseTreeStateOutput = {
180180
scrollToNode: (id: string) => void;
181181
};
182182

183-
export function useTree<TData>({
183+
export function useTree<TData, TFilterValue>({
184184
tree,
185185
selectedId,
186186
collapsedIds,
187187
onSelectedIdChanged,
188188
parentRef,
189189
estimatedRowHeight,
190190
filter,
191-
}: TreeStateHookProps<TData>): UseTreeStateOutput {
191+
}: TreeStateHookProps<TData, TFilterValue>): UseTreeStateOutput {
192192
const previousNodeCount = useRef(tree.length);
193193
const previousSelectedId = useRef<string | undefined>(selectedId);
194194

@@ -197,6 +197,7 @@ export function useTree<TData>({
197197
concreteStateFromInput({ tree, selectedId, collapsedIds, filter })
198198
);
199199

200+
//fire onSelectedIdChanged()
200201
useEffect(() => {
201202
const selectedId = selectedIdFromState(state.nodes);
202203
if (selectedId !== previousSelectedId.current) {
@@ -205,13 +206,30 @@ export function useTree<TData>({
205206
}
206207
}, [state.changes.selectedId]);
207208

209+
//update tree when the number of nodes changes
208210
useEffect(() => {
209211
if (tree.length !== previousNodeCount.current) {
210212
previousNodeCount.current = tree.length;
211213
dispatch({ type: "UPDATE_TREE", payload: { tree } });
212214
}
213215
}, [previousNodeCount.current, tree.length]);
214216

217+
//update the filter, if it's changed
218+
const previousFilter = useRef(filter);
219+
useEffect(() => {
220+
//check if the value (not reference) of the filter is the same
221+
const previousValue = previousFilter.current
222+
? JSON.stringify(previousFilter.current.value)
223+
: undefined;
224+
const newValue = filter ? JSON.stringify(filter.value) : undefined;
225+
226+
previousFilter.current = filter;
227+
228+
if (previousValue !== newValue) {
229+
dispatch({ type: "UPDATE_FILTER", payload: { filter } });
230+
}
231+
}, [filter?.value]);
232+
215233
const virtualizer = useVirtualizer({
216234
count: state.visibleNodeIds.length,
217235
getItemKey: (index) => state.visibleNodeIds[index],

apps/webapp/app/components/primitives/TreeView/reducer.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export type TreeState = {
2626
nodes: NodesState;
2727
filteredNodes: NodesState;
2828
changes: Changes;
29-
filter: Filter<any> | undefined;
29+
filter: Filter<any, any> | undefined;
3030
visibleNodeIds: string[];
3131
};
3232

@@ -155,7 +155,7 @@ type SelectParentNodeAction = {
155155
type UpdateFilterAction = {
156156
type: "UPDATE_FILTER";
157157
payload: {
158-
filter: Filter<any>;
158+
filter: Filter<any, any> | undefined;
159159
};
160160
};
161161

@@ -181,8 +181,6 @@ export type Action =
181181
| UpdateFilterAction;
182182

183183
export function reducer(state: TreeState, action: Action): TreeState {
184-
console.log(`reducer: ${action.type}`);
185-
186184
switch (action.type) {
187185
case "SELECT_NODE": {
188186
//if the node was already selected, do nothing. The user needs to use deselectNode to deselect
@@ -532,6 +530,13 @@ export function reducer(state: TreeState, action: Action): TreeState {
532530
});
533531
return newState;
534532
}
533+
case "UPDATE_FILTER": {
534+
const newState = applyFilterToState({
535+
...state,
536+
filter: action.payload.filter,
537+
});
538+
return newState;
539+
}
535540
}
536541

537542
throw new Error(`Unhandled action type: ${(action as any).type}`);

apps/webapp/app/components/primitives/TreeView/utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export function concreteStateFromInput({
1313
collapsedIds,
1414
}: {
1515
tree: FlatTree<any>;
16-
filter: Filter<any> | undefined;
16+
filter: Filter<any, any> | undefined;
1717
selectedId: string | undefined;
1818
collapsedIds: string[] | undefined;
1919
}): TreeState {
@@ -96,7 +96,7 @@ export function applyFilterToState<TData>({
9696
visibleNodeIds,
9797
changes,
9898
}: TreeState): TreeState {
99-
if (!filter || !filter.text?.trim()) {
99+
if (!filter || !filter.value) {
100100
return {
101101
tree,
102102
nodes,
@@ -110,7 +110,7 @@ export function applyFilterToState<TData>({
110110
//we need to do two passes, first collect all the nodes that are results
111111
const newFilteredOut = new Set<string>();
112112
for (const node of tree) {
113-
if (!filter.fn(filter.text, node)) {
113+
if (!filter.fn(filter.value, node)) {
114114
newFilteredOut.add(node.id);
115115
}
116116
}

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -266,13 +266,13 @@ function TasksTreeView({
266266
estimatedRowHeight: () => 32,
267267
parentRef,
268268
filter: {
269-
text: filterText,
270-
fn: (text, node) => {
271-
const nodePassesErrorTest = (errorsOnly && node.data.isError) || !errorsOnly;
269+
value: { text: filterText, errorsOnly },
270+
fn: (value, node) => {
271+
const nodePassesErrorTest = (value.errorsOnly && node.data.isError) || !value.errorsOnly;
272272
if (!nodePassesErrorTest) return false;
273273

274-
if (text === "") return true;
275-
if (node.data.message.toLowerCase().includes(text.toLowerCase())) {
274+
if (value.text === "") return true;
275+
if (node.data.message.toLowerCase().includes(value.text.toLowerCase())) {
276276
return true;
277277
}
278278
return false;

apps/webapp/app/routes/storybook.tree-view/route.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ function TreeViewParent({
160160
estimatedRowHeight: () => 32,
161161
parentRef,
162162
filter: {
163-
text: filterText,
163+
value: filterText,
164164
fn: (text, node) => {
165165
if (text === "") return true;
166166
if (node.data.title.toLowerCase().includes(text.toLowerCase())) {

0 commit comments

Comments
 (0)