fix(02): show owner name / Family in event popover footer
Backend: - expand.ts: add ownerName: string | null to CalendarOccurrence interface and expandOccurrences() signature; thread it onto every emitted occurrence. - events.ts: SELECT users.displayName as ownerName in the join; pass it to expandOccurrences(). Frontend: - client.ts: add ownerName: string | null to CalendarOccurrence. - EventDetailPopover.tsx: render isShared ? 'Family' : (ownerName ?? calendarName) in the footer instead of calendarName. Tests: - expand.test.ts: pass ownerName to all expandOccurrences() calls; assert ownerName is carried onto occurrences in the DST test. - events.test.ts: add ownerName to mock rows; assert ownerName present on occurrences; add ownerName assertion to timed-recurring test. - EventDetailPopover.test.tsx: add ownerName to fixtures; split "calendar name in footer" into three targeted tests covering personal-with-owner, shared→Family, and null-owner fallback.
This commit is contained in:
@@ -45,6 +45,13 @@ export interface CalendarOccurrence {
|
||||
* Client routes Schedule-X calendarId as String(ownerUserId) for personal calendars.
|
||||
*/
|
||||
ownerUserId: number
|
||||
/**
|
||||
* Display name of the calendar owner (users.displayName).
|
||||
* Null when the user has not set a display name.
|
||||
* The popover uses this to show the owner name for personal events;
|
||||
* falls back to calendarName when null.
|
||||
*/
|
||||
ownerName: string | null
|
||||
/** Hex color: users.color for personal calendars, '#F25C7A' for shared-family */
|
||||
color: string
|
||||
/** True when this occurrence belongs to the shared-family calendar (calendars.isShared=true) */
|
||||
@@ -67,6 +74,8 @@ export interface OccurrenceMeta {
|
||||
calendarId: number
|
||||
calendarName: string
|
||||
ownerUserId: number
|
||||
/** Display name of the calendar owner; null when users.displayName is not set */
|
||||
ownerName: string | null
|
||||
/** Hex color: pre-computed by the route (users.color or shared-family constant) */
|
||||
color: string
|
||||
isShared: boolean
|
||||
@@ -162,6 +171,7 @@ export function expandOccurrences(
|
||||
calendarId: number,
|
||||
calendarName: string,
|
||||
ownerUserId: number,
|
||||
ownerName: string | null,
|
||||
color: string,
|
||||
isShared: boolean,
|
||||
): CalendarOccurrence[] {
|
||||
@@ -229,6 +239,7 @@ export function expandOccurrences(
|
||||
calendarId,
|
||||
calendarName,
|
||||
ownerUserId,
|
||||
ownerName,
|
||||
color,
|
||||
isShared,
|
||||
title: event.summary ?? '',
|
||||
@@ -274,6 +285,7 @@ export function expandOccurrences(
|
||||
calendarId,
|
||||
calendarName,
|
||||
ownerUserId,
|
||||
ownerName,
|
||||
color,
|
||||
isShared,
|
||||
title: event.summary ?? '',
|
||||
|
||||
@@ -82,6 +82,7 @@ eventsRouter.get('/', zValidator('query', eventsQuerySchema), async (c) => {
|
||||
isShared: calendars.isShared,
|
||||
userId: users.id,
|
||||
userColor: users.color,
|
||||
ownerName: users.displayName,
|
||||
})
|
||||
.from(calendarEvents)
|
||||
.innerJoin(calendars, eq(calendarEvents.calendarId, calendars.id))
|
||||
@@ -126,6 +127,7 @@ eventsRouter.get('/', zValidator('query', eventsQuerySchema), async (c) => {
|
||||
row.calendarId,
|
||||
row.calendarName ?? '',
|
||||
row.userId,
|
||||
row.ownerName ?? null,
|
||||
color,
|
||||
row.isShared,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user