Skip to content

Commit 4dcc7d6

Browse files
committed
Change how closing a tip modal modifies filters
Clicking on a tip activates a modal and activates the corresponding strain filter. Previously clearing the modal would always inactivate the filter. In the absence of any filtering this behaviour is not bad, but when already filtering to a set of strains then it's counter-intuitive because we inactivate a filter that was active. The new behaviour restores the filtering state of the strain before the modal was opened. Specifically, * If the tip was already filtered, opening and closing the modal doesn't change the filters. * If the tip was filtered but inactive, opening the modal activates it and closing the modal returns it to the inactive state. * If the tip wasn't filtered (active or inactive) then opening the modal makes it an active filter and closing the modal removes the filter entirely. Closes #1701
1 parent 72ba248 commit 4dcc7d6

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

src/components/tree/reactD3Interface/callbacks.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ export const onTipHover = function onTipHover(d) {
1919
export const onTipClick = function onTipClick(d) {
2020
if (d.visibility !== NODE_VISIBLE) return;
2121
if (this.props.narrativeMode) return;
22+
/* The order of these two dispatches is important: the reducer handling
23+
`SELECT_NODE` must have access to the filtering state _prior_ to these filters
24+
being applied */
2225
this.props.dispatch({type: SELECT_NODE, name: d.n.name, idx: d.n.arrayIdx});
2326
this.props.dispatch(applyFilter("add", strainSymbol, [d.n.name]));
2427
};
@@ -119,7 +122,14 @@ export const onTipLeave = function onTipLeave(d) {
119122
/* clearSelectedNode when clicking to remove the node-selected modal */
120123
export const clearSelectedNode = function clearSelectedNode(selectedNode, isTerminal) {
121124
if (isTerminal) {
122-
this.props.dispatch(applyFilter("inactivate", strainSymbol, [selectedNode.name]));
125+
/* perform the filtering action (if necessary) that will restore the
126+
filtering state of the node prior to the selection */
127+
if (!selectedNode.existingFilterState) {
128+
this.props.dispatch(applyFilter("remove", strainSymbol, [selectedNode.name]));
129+
} else if (selectedNode.existingFilterState==='inactive') {
130+
this.props.dispatch(applyFilter("inactivate", strainSymbol, [selectedNode.name]));
131+
}
132+
/* else the filter was already active, so leave it unchanged */
123133
}
124134
this.props.dispatch({type: DESELECT_NODE});
125135
};

src/reducers/controls.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,11 @@ const Controls = (state: ControlsState = getDefaultControlsState(), action): Con
234234
geoResolution: action.data
235235
});
236236

237-
case types.SELECT_NODE: {
238-
return {...state, selectedNode: {name: action.name, idx: action.idx}};
237+
case types.SELECT_NODE: {
238+
const existingFilterInfo = (state.filters?.[strainSymbol]||[]).find((info) => info.value===action.name);
239+
const existingFilterState = existingFilterInfo === undefined ? null :
240+
existingFilterInfo.active ? 'active' : 'inactive';
241+
return {...state, selectedNode: {name: action.name, idx: action.idx, existingFilterState}};
239242
}
240243
case types.DESELECT_NODE: {
241244
return {...state, selectedNode: null}

0 commit comments

Comments
 (0)