fix
All checks were successful
Build And Deploy Main / build-and-deploy (push) Successful in 42s

This commit is contained in:
2026-03-18 12:00:57 -04:00
parent 84d1e4ca47
commit edd20fdcac
2 changed files with 35 additions and 43 deletions

View File

@@ -103,36 +103,20 @@ const EventsList = () => {
return roles.includes('driver') || permissions.includes('isdriver'); return roles.includes('driver') || permissions.includes('isdriver');
}; };
// Default sort: 1) driver name ascending, 2) start time early to late, 3) address ascending, 4) language (empty first) // Default sort: appointment time early to late
const applyDefaultSort = (eventsArray) => { const applyDefaultSort = (eventsArray) => {
return [...eventsArray].sort((a, b) => { return [...eventsArray].sort((a, b) => {
// 1. First sort by driver (transportation) name ascending // Sort by start time (early to late)
const driverA = (a.transportation || '').toLowerCase();
const driverB = (b.transportation || '').toLowerCase();
if (driverA !== driverB) {
return driverA.localeCompare(driverB);
}
// 2. Then sort by start time (early to late)
const timeA = a.start_time ? new Date(a.start_time).getTime() : 0; const timeA = a.start_time ? new Date(a.start_time).getTime() : 0;
const timeB = b.start_time ? new Date(b.start_time).getTime() : 0; const timeB = b.start_time ? new Date(b.start_time).getTime() : 0;
if (timeA !== timeB) { if (timeA !== timeB) {
return timeA - timeB; return timeA - timeB;
} }
// 3. Then sort by resource address ascending // Stable fallback sort by customer name
const addressA = (a.address || '').toLowerCase(); const customerA = (a.customer || '').toLowerCase();
const addressB = (b.address || '').toLowerCase(); const customerB = (b.customer || '').toLowerCase();
if (addressA !== addressB) { return customerA.localeCompare(customerB);
return addressA.localeCompare(addressB);
}
// 4. Finally sort by language (empty values first, then values with content)
const langA = (a.translation || '').trim();
const langB = (b.translation || '').trim();
if (langA === '' && langB !== '') return -1; // Empty comes first
if (langA !== '' && langB === '') return 1; // Empty comes first
return langA.localeCompare(langB); // Both empty or both have values - sort alphabetically
}); });
}; };
@@ -180,7 +164,7 @@ const EventsList = () => {
return item; return item;
}).filter(item => item.type === 'medical' && item.confirmed); }).filter(item => item.type === 'medical' && item.confirmed);
// Apply default sort (driver name → start time → address) // Apply default sort (appointment time early first)
const sortedEvents = applyDefaultSort(processedEvents); const sortedEvents = applyDefaultSort(processedEvents);
setEvents(sortedEvents); setEvents(sortedEvents);
setTransportationOptionsList(data.data.filter((item) => item.type === 'transportation' && item.status === 'active')) setTransportationOptionsList(data.data.filter((item) => item.type === 'transportation' && item.status === 'active'))
@@ -191,7 +175,6 @@ const EventsList = () => {
// Apply multi-column sorting // Apply multi-column sorting
// After all custom sorting rules, always sort by language (empty first)
const applyMultiColumnSort = (eventsArray, rules) => { const applyMultiColumnSort = (eventsArray, rules) => {
if (rules.length === 0) { if (rules.length === 0) {
return applyDefaultSort(eventsArray); return applyDefaultSort(eventsArray);
@@ -209,12 +192,10 @@ const EventsList = () => {
} }
} }
// After all rules, always sort by language (empty values first, then values with content) // Stable fallback sort by appointment time ascending
const langA = (a.translation || '').trim(); const timeA = a.start_time ? new Date(a.start_time).getTime() : 0;
const langB = (b.translation || '').trim(); const timeB = b.start_time ? new Date(b.start_time).getTime() : 0;
if (langA === '' && langB !== '') return -1; // Empty comes first return timeA - timeB;
if (langA !== '' && langB === '') return 1; // Empty comes first
return langA.localeCompare(langB); // Both empty or both have values - sort alphabetically
}); });
}; };

View File

@@ -12,7 +12,7 @@ const EventsMultipleList = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const [events, setEvents] = useState([]); const [events, setEvents] = useState([]);
const [customers, setCustomers] = useState([]); const [customers, setCustomers] = useState([]);
const [sorting, setSorting] = useState({key: '', order: ''}); const [sorting, setSorting] = useState({key: 'appointment_time', order: 'asc'});
const [selectedItems, setSelectedItems] = useState([]); const [selectedItems, setSelectedItems] = useState([]);
const [resources, setResources] = useState([]); const [resources, setResources] = useState([]);
const [fromDate, setFromDate] = useState(new Date()); const [fromDate, setFromDate] = useState(new Date());
@@ -170,6 +170,21 @@ const EventsMultipleList = () => {
return currentCustomer?.disability || event?.data?.disability?.toLowerCase() === 'yes' || false; return currentCustomer?.disability || event?.data?.disability?.toLowerCase() === 'yes' || false;
}; };
const sortEventsByKey = (eventsList = [], key = '', order = 'asc') => {
if (!key) return [...eventsList];
const sorted = [...eventsList].sort((a, b) => {
if (key === 'appointment_time') {
const aTime = a?.start_time ? new Date(a.start_time).getTime() : 0;
const bTime = b?.start_time ? new Date(b.start_time).getTime() : 0;
return aTime - bTime;
}
const aValue = `${a?.[key] || ''}`.toLowerCase();
const bValue = `${b?.[key] || ''}`.toLowerCase();
return aValue.localeCompare(bValue);
});
return order === 'desc' ? sorted.reverse() : sorted;
};
useEffect(() => { useEffect(() => {
if (!AuthService.canViewMedicalEvents()) { if (!AuthService.canViewMedicalEvents()) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.') window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
@@ -187,7 +202,7 @@ const EventsMultipleList = () => {
useEffect(() => { useEffect(() => {
if (fromDate && toDate && customers?.length > 0 && resources?.length > 0) { if (fromDate && toDate && customers?.length > 0 && resources?.length > 0) {
EventsService.getAllEvents({ from: EventsService.formatDate(fromDate), to: EventsService.formatDate(toDate) }).then((data) => { EventsService.getAllEvents({ from: EventsService.formatDate(fromDate), to: EventsService.formatDate(toDate) }).then((data) => {
setEvents(data.data.filter((item) => { const nextEvents = data.data.filter((item) => {
const currentCustomer = customers.find(c => c.id === item?.data?.customer) || customers?.find(c => c?.name === item?.data?.client_name || c?.name === item?.target_name); const currentCustomer = customers.find(c => c.id === item?.data?.customer) || customers?.find(c => c?.name === item?.data?.client_name || c?.name === item?.target_name);
const currentResource = resources.find(r => r.id === item?.data?.resource); const currentResource = resources.find(r => r.id === item?.data?.resource);
const customerName = item?.data?.customer ? (currentCustomer?.name || item?.data?.client_name || '') : (item?.data?.client_name || ''); const customerName = item?.data?.customer ? (currentCustomer?.name || item?.data?.client_name || '') : (item?.data?.client_name || '');
@@ -231,7 +246,8 @@ const EventsMultipleList = () => {
item.eyes_on = checkDisability(customers, item) ? 'Yes' : 'No'; item.eyes_on = checkDisability(customers, item) ? 'Yes' : 'No';
item.dob = item?.data?.customer ? customers.find(c => c.id === item?.data?.customer)?.birth_date : (item?.data?.client_birth_date || '') item.dob = item?.data?.customer ? customers.find(c => c.id === item?.data?.customer)?.birth_date : (item?.data?.client_birth_date || '')
return item; return item;
}).filter(item => item.type === 'medical')); }).filter(item => item.type === 'medical');
setEvents(sortEventsByKey(nextEvents, sorting?.key || 'appointment_time', sorting?.order || 'asc'));
}) })
} }
}, [fromDate, toDate, customers, resources]); }, [fromDate, toDate, customers, resources]);
@@ -270,20 +286,14 @@ const EventsMultipleList = () => {
useEffect(() => { useEffect(() => {
const newEvents = [...events]; setEvents((prevEvents) => sortEventsByKey(prevEvents, sorting.key, sorting.order || 'asc'));
const sortedEvents = sorting.key === '' ? newEvents : newEvents.sort((a, b) => {
return a[sorting.key]?.localeCompare(b[sorting.key]);
});
setEvents(
sorting.order === 'asc' ? sortedEvents : sortedEvents.reverse()
)
}, [sorting]); }, [sorting]);
const confirmEvent = (id) => { const confirmEvent = (id) => {
if (!AuthService.canEditMedicalEvents()) return; if (!AuthService.canEditMedicalEvents()) return;
EventsService.updateEvent(id, {confirmed: true}).then(() => { EventsService.updateEvent(id, {confirmed: true}).then(() => {
EventsService.getAllEvents({ from: EventsService.formatDate(fromDate), to: EventsService.formatDate(toDate) }).then((data) => { EventsService.getAllEvents({ from: EventsService.formatDate(fromDate), to: EventsService.formatDate(toDate) }).then((data) => {
setEvents(data.data.filter((item) => { const nextEvents = data.data.filter((item) => {
const currentCustomer = customers.find(c => c.id === item?.data?.customer) || customers?.find(c => c?.name === item?.data?.client_name || c?.name === item?.target_name); const currentCustomer = customers.find(c => c.id === item?.data?.customer) || customers?.find(c => c?.name === item?.data?.client_name || c?.name === item?.target_name);
const currentResource = resources.find(r => r.id === item?.data?.resource); const currentResource = resources.find(r => r.id === item?.data?.resource);
const customerName = item?.data?.customer ? (currentCustomer?.name || item?.data?.client_name || '') : (item?.data?.client_name || ''); const customerName = item?.data?.customer ? (currentCustomer?.name || item?.data?.client_name || '') : (item?.data?.client_name || '');
@@ -327,7 +337,8 @@ const EventsMultipleList = () => {
item.chinese_name = item?.data?.customer ? customers.find(c => c.id === item?.data?.customer)?.name_cn : (customers?.find(c=> c?.name === item?.data?.client_name || c?.name === item?.target_name )?.name_cn || ''); item.chinese_name = item?.data?.customer ? customers.find(c => c.id === item?.data?.customer)?.name_cn : (customers?.find(c=> c?.name === item?.data?.client_name || c?.name === item?.target_name )?.name_cn || '');
item.dob = item?.data?.customer ? customers.find(c => c.id === item?.data?.customer)?.birth_date : (item?.data?.client_birth_date || '') item.dob = item?.data?.customer ? customers.find(c => c.id === item?.data?.customer)?.birth_date : (item?.data?.client_birth_date || '')
return item; return item;
}).filter(item => item.type === 'medical')); }).filter(item => item.type === 'medical');
setEvents(sortEventsByKey(nextEvents, sorting?.key || 'appointment_time', sorting?.order || 'asc'));
}) })
}); });
} }