Skip to content

Commit bb93473

Browse files
theosanderson-agenttheosandersonclaude
authored
fix(website): stop date range strictness checkbox stuck on strict when no date entered (#6485)
Fixes #6483 ## What was happening When you toggled the strictness checkbox in a `DateRangeField` (e.g. the Collection date filter) without having entered any dates, was stuck on. This matches the user reports in #6483: - The checkbox "actually seems stuck enabled" ## Fix In the read-in effect, skip the `setStrictMode` call when none of the four bound fields are defined — there is no signal to derive from in that case, so we preserve the user's manual selection. When at least one field is defined the existing `isStrictMode` logic still runs and stays in charge. The write-out effect is unchanged. External (URL-driven) changes still flow in correctly because they always come with at least one bound defined. 🤖 Generated with [Claude Code](https://claude.com/claude-code) 🚀 Preview: https://fix-date-range-strictness.loculus.org Co-authored-by: theosanderson-agent <theo@theo.io> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 3947ca8 commit bb93473

2 files changed

Lines changed: 43 additions & 8 deletions

File tree

website/src/components/SearchPage/fields/DateRangeField.spec.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,38 @@ describe('DateRangeField', () => {
158158
);
159159
});
160160

161+
it('does not snap back to strict when user toggles without having entered dates', async () => {
162+
function Wrapper() {
163+
const [values, _setValues] = useState<FieldValues>({});
164+
165+
const setValues: SetSomeFieldValues = useCallback((...fieldValuesToSet) => {
166+
_setValues((state) => {
167+
const newState = { ...state };
168+
fieldValuesToSet.forEach(([k, v]) => {
169+
// mirror the production behaviour of useSearchPageState: null/'' deletes
170+
if (v === null || v === '') {
171+
delete newState[k];
172+
} else {
173+
newState[k] = v;
174+
}
175+
});
176+
return newState;
177+
});
178+
}, []);
179+
180+
return <DateRangeField field={field} fieldValues={values} setSomeFieldValues={setValues} />;
181+
}
182+
183+
const user = userEvent.setup();
184+
render(<Wrapper />);
185+
186+
const strictCheckbox = screen.getByRole('checkbox');
187+
expect(strictCheckbox).toBeChecked();
188+
189+
await user.click(strictCheckbox);
190+
expect(strictCheckbox).not.toBeChecked();
191+
});
192+
161193
it('setting fieldValue to empty string clears date field', async () => {
162194
function Wrapper() {
163195
const [values, _setValues] = useState<FieldValues>({

website/src/components/SearchPage/fields/DateRangeField.tsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,17 @@ export const DateRangeField = ({ field, fieldValues, setSomeFieldValues }: DateR
6060
const [upperValue, setUpperValue] = useState(getFieldValue(upperField.name));
6161

6262
useEffect(() => {
63-
setStrictMode(
64-
isStrictMode(
65-
lowerFromField.name in fieldValues,
66-
lowerToField.name in fieldValues,
67-
upperFromField.name in fieldValues,
68-
upperToField.name in fieldValues,
69-
),
70-
);
63+
const lowerFromDefined = lowerFromField.name in fieldValues;
64+
const lowerToDefined = lowerToField.name in fieldValues;
65+
const upperFromDefined = upperFromField.name in fieldValues;
66+
const upperToDefined = upperToField.name in fieldValues;
67+
// Only re-derive strictMode from fieldValues when at least one bound is actually defined.
68+
// When the user toggles strictness without having entered any dates the other effect
69+
// below clears all four fields, which would otherwise feed back into isStrictMode and
70+
// collapse strictMode back to its default `true` — making the checkbox appear stuck on.
71+
if (lowerFromDefined || lowerToDefined || upperFromDefined || upperToDefined) {
72+
setStrictMode(isStrictMode(lowerFromDefined, lowerToDefined, upperFromDefined, upperToDefined));
73+
}
7174
setLowerValue(validateSingleValue(fieldValues[lowerField.name], lowerField.name));
7275
setUpperValue(validateSingleValue(fieldValues[upperField.name], upperField.name));
7376
}, [field, fieldValues]);

0 commit comments

Comments
 (0)