feat(appointments): toolbar personnel filter (پرسنل را انتخاب کنید...)

Adds staffUuid to AppointmentFilters and a toolbar staff select that filters
the loaded day's rows client-side, matching appointments-table.pdf.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
hamed
2026-07-14 00:09:08 +03:30
co-authored by Claude Fable 5
parent f426a98ee6
commit 376e610260
3 changed files with 25 additions and 1 deletions
@@ -40,6 +40,10 @@ describe('applyAppointmentFilters', () => {
expect(applyAppointmentFilters(items, { ...EMPTY_FILTERS, statuses: ['cancelled'] })).toHaveLength(1);
expect(applyAppointmentFilters(items, { ...EMPTY_FILTERS, statuses: ['salon', 'completed'] })).toHaveLength(2);
expect(applyAppointmentFilters(items, { ...EMPTY_FILTERS, gender: 'female' })).toHaveLength(2);
expect(applyAppointmentFilters(
items.map((a, i) => ({ ...a, staff: i === 0 ? { uuid: 'st1', full_name: 'x' } : null })),
{ ...EMPTY_FILTERS, staffUuid: 'st1' },
)).toHaveLength(1);
expect(applyAppointmentFilters(items, EMPTY_FILTERS)).toHaveLength(3);
});
});
@@ -13,12 +13,14 @@ export interface AppointmentFilters {
nationalCode: string;
sectionUuid: string;
itemUuid: string;
/** toolbar «پرسنل را انتخاب کنید...» select — not part of the modal */
staffUuid: string;
statuses: string[];
gender: 'female' | 'male' | 'both';
}
export const EMPTY_FILTERS: AppointmentFilters = {
name: '', nationalCode: '', sectionUuid: '', itemUuid: '', statuses: [], gender: 'both',
name: '', nationalCode: '', sectionUuid: '', itemUuid: '', staffUuid: '', statuses: [], gender: 'both',
};
// design's 6 checkboxes; لغو شده covers both cancel reasons
@@ -38,6 +40,7 @@ export function applyAppointmentFilters(items: Appointment[], f: AppointmentFilt
if (f.nationalCode && !(a.patient_national_code ?? '').includes(f.nationalCode)) return false;
if (f.sectionUuid && a.service_section?.uuid !== f.sectionUuid) return false;
if (f.itemUuid && a.service_item?.uuid !== f.itemUuid) return false;
if (f.staffUuid && a.staff?.uuid !== f.staffUuid) return false;
if (f.statuses.length) {
const matches = f.statuses.some(s =>
s === 'cancelled' ? a.status.startsWith('cancelled') : a.status === s);