Objective
- Display multiple events at the same property as a single group on the calendar. When several events are at the same property and scheduled within a few hours of each other, show them as one "group of events" block instead of multiple separate events.
- Keep the calendar cleaner and easier to read. Grouping reduces visual clutter so the calendar stays scannable.
- Expose all events in the group. Within that group block, users must be able to see all associated events (e.g. expand, tooltip, or list inside the block).
Background
- Today, every event is rendered as its own block on the calendar, so several events at the same address within a short time window appear as several blocks and can look noisy.
- Product feedback is that users want same-property, close-in-time events to appear as one grouped block, with a way to see the full list of events in that group.
- The requirement is to define "same property" (e.g. same address or same property identifier) and "within a few hours" (e.g. a configurable or fixed time window), then render a single group block and allow viewing all associated events inside it.
Scope
Frontend
- Calendar that displays events. The main calendar is built from
attik-frontend/src/app/tools/calendar/MasterCalendar.tsx, which usesCalendarBaseand oneCalendarRowper inspector. Each row usesattik-frontend/src/components/calendar/CalendarRow.tsxwitheventTypes={['vacations', 'events', 'inspections', 'slots']}and fetches data for that employee. Events are placed byattik-frontend/src/components/calendar/eventPlacementFunc.tsxand rendered byCalendarEventWrapperandCalendarEventBodyinattik-frontend/src/components/calendar/CalendarEventWrapper.tsxandCalendarEventBody.tsx. Inspections exposeaddress(and related fields); events can carry address from inspection lookup. In scope: before or during placement, identify events that belong to the same property and fall within a few hours of each other; render one "group" block for each such set instead of one block per event; and provide a way to see all associated events inside the group (e.g. expandable list, popover, or inline list). Grouping logic (same property + time window) and UX for "see all events" are left to the dev; the requirement is a single group block and visibility of all associated events within it. - Dispatch calendar. There is also
attik-frontend/src/app/tools/dispatch/calendar/page.tsxand dispatch-related calendar components (DispatchCalendarNew, etc.). If the same event list is shown there and should also be grouped by property and time, that is in scope; otherwise limit to the main calendar. Decision needed on whether grouping applies only to the main calendar or to dispatch (and any other views) as well.
Backend
- Calendar API. Events and inspections are returned by
attik-backend/src/routes/calendar.ts(e.g.GET /calendarwitheventTypes,employeeId, date range). Inspections include address; events can get address via inspection lookup. No backend change is required for grouping if the frontend groups client-side using address (and datetime). If the backend should return pre-grouped "group of events" entities or a dedicated grouping endpoint, that is a design decision; the requirement can be met by frontend-only grouping using existing calendar payloads.
References
- Codebase entry points:
- Main calendar:
attik-frontend/src/app/tools/calendar/MasterCalendar.tsx,attik-frontend/src/app/tools/calendar/page.tsx. - Row and event rendering:
attik-frontend/src/components/calendar/CalendarRow.tsx,CalendarEventWrapper.tsx,CalendarEventBody.tsx. - Event placement and shape:
attik-frontend/src/components/calendar/eventPlacementFunc.tsx(CalendarEventWithPlacement, placement/collision). - Calendar API:
attik-backend/src/routes/calendar.ts(events, inspections, vacations, slots by date range and employee).