Calendar Break Update Button
Business view
Every staff member in Dentolize has working-hours settings: which days they're open, what time they open and close each day, and any breaks during the day (lunch, prayer, etc.). This lives on Settings → Users → (a user) → User Calendar Settings.
Before this fix, adding or editing a break time — and only that, without touching any other field on the page — could leave the Update button stuck disabled. The change was made on screen, but there was no way to save it. Nothing indicated why; the button just didn't respond. Anyone touching another field first (like a room or opening time) would "unstick" it, which made the bug inconsistent and hard to describe when reported.
This is fixed: adding, editing, or removing a break now correctly enables Update, the same as changing any other setting on the page.
Technical view
File: packages/clinic-web/src/components/dashboard/settings/Users/UserCalendarSettingsTab.js
The tab is built on an Ant Design Form, but break times aren't modeled as a form field. They live in their own React state:
const [breaks, setBreaks] = useState(calendarSettings.breaks || [])
...
const addBreak = i => { ... setBreaks(newBreaks) }
const updateBreak = (val, breakIndex, day) => { ... setBreaks(newBreaks) }
(UserCalendarSettingsTab.js:17, :242-252)
Because breaks is state outside the Form, Ant Design's form.isFieldsTouched() has no idea it changed — isFieldsTouched() only tracks the form's own registered fields (opening/closing times, rooms, closed days, etc.).
The Update button's disabled prop therefore has to combine both signals explicitly:
disabled={
!user.permissions.editUser ||
(!isFieldsTouched() && String(calendarSettings.breaks) === String(breaks)) ||
getFieldsError().filter(({ errors }) => errors.length).length
}
(UserCalendarSettingsTab.js:436-440)
The middle clause is the "nothing has changed at all" check: disable only when neither the form fields nor the breaks state differ from what was loaded. Before this PR, that clause used !== instead of ===:
// before (buggy)
(!isFieldsTouched() && String(calendarSettings.breaks) !== String(breaks))
With !==, the clause read "disable when the form is untouched and breaks have changed" — i.e., editing only the breaks (form untouched, breaks now different from the saved value) satisfied the disable condition and locked the button, which is the opposite of the intent. Editing any other form field first would flip isFieldsTouched() to true, making the whole clause false regardless of the breaks comparison — which is why the bug only showed up when breaks were the only thing edited.
The fix flips the comparison to ===, so the clause is only true (and the button only disabled by this rule) when both the form is untouched and breaks matches the last-saved value — i.e., truly nothing changed.
No backend or schema changes were needed; breaks was already saved correctly by the mutation (UPDATE_USER_CALENDAR_SETTINGS) whenever it could be reached. The bug was purely in the client-side gate that decided whether the save button was clickable at all.