@ieeesa-npm/dashboard 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/esm2022/lib/assets/constants.json +7 -3
  2. package/esm2022/lib/components/event-group-card/event-group-card.component.mjs +99 -13
  3. package/esm2022/lib/components/meeting-attendance-row/meeting-attendance-row.component.mjs +101 -23
  4. package/esm2022/lib/components/upcoming-meetings-events/upcoming-meetings-events.component.mjs +66 -6
  5. package/esm2022/lib/components/your-groups/your-groups.component.mjs +3 -3
  6. package/esm2022/lib/dashboard.component.mjs +63 -12
  7. package/esm2022/lib/models/attendance-state.model.mjs +8 -1
  8. package/esm2022/lib/models/dashboard-route-config.model.mjs +1 -1
  9. package/esm2022/lib/models/event-meeting-list-item.model.mjs +1 -1
  10. package/esm2022/lib/models/event-meeting-list-payload.model.mjs +7 -5
  11. package/esm2022/lib/models/meeting-row.model.mjs +1 -1
  12. package/esm2022/lib/models/upcoming-event.model.mjs +1 -1
  13. package/esm2022/lib/services/dashboard.service.mjs +71 -126
  14. package/esm2022/lib/services/user-permissions.service.mjs +23 -9
  15. package/esm2022/lib/utils/event-meeting-mapper.util.mjs +47 -41
  16. package/fesm2022/ieeesa-npm-dashboard.mjs +490 -289
  17. package/fesm2022/ieeesa-npm-dashboard.mjs.map +1 -1
  18. package/lib/components/event-group-card/event-group-card.component.d.ts +73 -6
  19. package/lib/components/meeting-attendance-row/meeting-attendance-row.component.d.ts +61 -7
  20. package/lib/components/member-level-badge/member-level-badge.component.d.ts +12 -1
  21. package/lib/components/upcoming-meetings-events/upcoming-meetings-events.component.d.ts +49 -3
  22. package/lib/dashboard.component.d.ts +39 -6
  23. package/lib/models/attendance-state.model.d.ts +8 -1
  24. package/lib/models/dashboard-route-config.model.d.ts +14 -0
  25. package/lib/models/event-meeting-list-item.model.d.ts +68 -68
  26. package/lib/models/event-meeting-list-payload.model.d.ts +14 -25
  27. package/lib/models/meeting-row.model.d.ts +2 -0
  28. package/lib/models/upcoming-event.model.d.ts +9 -0
  29. package/lib/services/dashboard.service.d.ts +25 -53
  30. package/lib/services/user-permissions.service.d.ts +8 -4
  31. package/lib/utils/event-meeting-mapper.util.d.ts +15 -21
  32. package/package.json +1 -1
@@ -59,9 +59,25 @@ export declare class EventGroupCardComponent {
59
59
  * so the container can lazily fetch the event's child meetings from the
60
60
  * backend. Standalone-meeting cards never emit this.
61
61
  */
62
- loadMeetings: EventEmitter<number>;
62
+ loadMeetings: EventEmitter<{
63
+ page: number;
64
+ size: number;
65
+ }>;
66
+ /**
67
+ * Bubbles the owning event id + meeting id when an attendance button is
68
+ * activated for an In-Progress meeting, so the host can navigate to the
69
+ * view-meeting screen (where the real Log Attendance popup opens).
70
+ */
71
+ navigateToMeeting: EventEmitter<{
72
+ eventId: string;
73
+ meetingId: string;
74
+ logAttendance?: boolean | undefined;
75
+ leaveMeeting?: boolean | undefined;
76
+ }>;
63
77
  /** The default page size for the per-card meeting paginator. */
64
78
  readonly defaultPageSize = 5;
79
+ /** Page-size options shown in the paginator dropdown (matches the app-wide paginator). */
80
+ readonly pageSizeOptions: number[];
65
81
  /** The current zero-based page index of the meeting list. */
66
82
  pageIndex: number;
67
83
  /** The current page size of the meeting list. */
@@ -175,19 +191,70 @@ export declare class EventGroupCardComponent {
175
191
  */
176
192
  get isStandaloneAttending(): boolean;
177
193
  /**
178
- * Whether the STANDALONE meeting's Log Attendance button is shown (not
179
- * attending and the host grants the permission).
194
+ * Whether the STANDALONE meeting's Log Attendance button is shown (whenever
195
+ * not currently attending). No permission gating — mirrors the attendance
196
+ * library.
180
197
  * @return {boolean} True when the log-attendance button is visible.
181
198
  * @memberof EventGroupCardComponent
182
199
  */
183
200
  get showStandaloneLog(): boolean;
184
201
  /**
185
- * Whether the STANDALONE meeting's Leave Meeting button is shown (attending
186
- * and the host grants the permission).
202
+ * Whether the STANDALONE meeting's Leave Meeting button is shown — only while
203
+ * the meeting is currently attending AND active.
187
204
  * @return {boolean} True when the leave-meeting button is visible.
188
205
  * @memberof EventGroupCardComponent
189
206
  */
190
207
  get showStandaloneLeave(): boolean;
208
+ /**
209
+ * Whether the STANDALONE meeting is eligible for an attendance action. The
210
+ * backend supplies an `attendanceState` only for attendance-eligible meetings
211
+ * (open for attendance), so its presence is the eligibility signal.
212
+ * @return {boolean} True when the standalone meeting is attendance-eligible.
213
+ * @memberof EventGroupCardComponent
214
+ */
215
+ get isStandaloneEligible(): boolean;
216
+ /**
217
+ * Whether the STANDALONE meeting is currently In Progress — the attendance
218
+ * button is only ENABLED during the meeting (disabled otherwise, mirroring the
219
+ * view-meeting page).
220
+ * @return {boolean} True when the standalone meeting status is 'In Progress'.
221
+ * @memberof EventGroupCardComponent
222
+ */
223
+ get isStandaloneActive(): boolean;
224
+ /**
225
+ * Whether the STANDALONE Log Attendance button is disabled (outside meeting
226
+ * time), matching the view-meeting page's inactive state.
227
+ * @return {boolean} True when the standalone log button should be disabled.
228
+ * @memberof EventGroupCardComponent
229
+ */
230
+ get isStandaloneLogDisabled(): boolean;
231
+ /** The inactive-button message shown when the standalone meeting is not active. */
232
+ get inactiveMessage(): string;
233
+ /**
234
+ * Bubbles a row's navigate-to-meeting request upward unchanged so the host can
235
+ * route to the view-meeting screen.
236
+ * @param {{ eventId: string; meetingId: string }} request - The meeting identity.
237
+ * @memberof EventGroupCardComponent
238
+ */
239
+ onNavigateToMeeting(request: {
240
+ eventId: string;
241
+ meetingId: string;
242
+ logAttendance?: boolean;
243
+ leaveMeeting?: boolean;
244
+ }): void;
245
+ /**
246
+ * Emits the navigate-to-meeting intent for a STANDALONE meeting's attendance
247
+ * action (Log Attendance or Leave Meeting, requesting the matching popup
248
+ * auto-open). Its own id is the meeting id; it has no parent event.
249
+ * @memberof EventGroupCardComponent
250
+ */
251
+ onNavigateToStandalone(): void;
252
+ /**
253
+ * Emits the navigate-to-meeting intent for a STANDALONE meeting's name link
254
+ * (view only — no popup auto-open).
255
+ * @memberof EventGroupCardComponent
256
+ */
257
+ onOpenStandalone(): void;
191
258
  /** The luxon-formatted start date of the event (ISO or epoch ms) (Req 6.2). */
192
259
  get formattedStartDate(): string;
193
260
  /** The luxon-formatted end date of the event (ISO or epoch ms) (Req 6.2). */
@@ -264,5 +331,5 @@ export declare class EventGroupCardComponent {
264
331
  */
265
332
  private formatDate;
266
333
  static ɵfac: i0.ɵɵFactoryDeclaration<EventGroupCardComponent, never>;
267
- static ɵcmp: i0.ɵɵComponentDeclaration<EventGroupCardComponent, "ieeesa-event-group-card", never, { "event": { "alias": "event"; "required": false; }; "permissions": { "alias": "permissions"; "required": false; }; "attendanceStates": { "alias": "attendanceStates"; "required": false; }; "inFlightMeetingIds": { "alias": "inFlightMeetingIds"; "required": false; }; "isMobileView": { "alias": "isMobileView"; "required": false; }; }, { "viewEvent": "viewEvent"; "openMeeting": "openMeeting"; "logAttendance": "logAttendance"; "leaveMeeting": "leaveMeeting"; "pageChange": "pageChange"; "loadMeetings": "loadMeetings"; }, never, never, true, never>;
334
+ static ɵcmp: i0.ɵɵComponentDeclaration<EventGroupCardComponent, "ieeesa-event-group-card", never, { "event": { "alias": "event"; "required": false; }; "permissions": { "alias": "permissions"; "required": false; }; "attendanceStates": { "alias": "attendanceStates"; "required": false; }; "inFlightMeetingIds": { "alias": "inFlightMeetingIds"; "required": false; }; "isMobileView": { "alias": "isMobileView"; "required": false; }; }, { "viewEvent": "viewEvent"; "openMeeting": "openMeeting"; "logAttendance": "logAttendance"; "leaveMeeting": "leaveMeeting"; "pageChange": "pageChange"; "loadMeetings": "loadMeetings"; "navigateToMeeting": "navigateToMeeting"; }, never, never, true, never>;
268
335
  }
@@ -39,8 +39,39 @@ export declare class MeetingAttendanceRowComponent {
39
39
  logAttendance: EventEmitter<string>;
40
40
  /** Emits the meeting id to request leaving the meeting (Req 7.8). */
41
41
  leaveMeeting: EventEmitter<string>;
42
+ /**
43
+ * Emits the owning event id + meeting id when the attendance button is
44
+ * activated for an In-Progress meeting, so the host can navigate to the
45
+ * view-meeting screen (where the real Log Attendance popup opens).
46
+ */
47
+ navigateToMeeting: EventEmitter<{
48
+ eventId: string;
49
+ meetingId: string;
50
+ logAttendance?: boolean | undefined;
51
+ leaveMeeting?: boolean | undefined;
52
+ }>;
42
53
  /** Expose the enum to the template for state comparisons. */
43
54
  readonly AttendanceState: typeof AttendanceState;
55
+ /**
56
+ * Whether the meeting is eligible for an attendance action (an attendance
57
+ * button is rendered at all). The backend supplies an `attendanceState` for
58
+ * every loggable meeting, so its presence is the eligibility signal. Rows the
59
+ * backend deems ineligible carry no state and render no button.
60
+ * @return {boolean} True when the meeting is attendance-eligible.
61
+ * @memberof MeetingAttendanceRowComponent
62
+ */
63
+ get isEligibleForAttendance(): boolean;
64
+ /**
65
+ * Whether the meeting is currently In Progress. Mirrors the attendance
66
+ * library's `isMeetingActive`: the attendance button is only ENABLED during
67
+ * the meeting; outside the meeting time it renders disabled with the inactive
68
+ * message.
69
+ * @return {boolean} True when the meeting status is 'In Progress'.
70
+ * @memberof MeetingAttendanceRowComponent
71
+ */
72
+ get isMeetingActive(): boolean;
73
+ /** The inactive-button message shown when the meeting is not In Progress. */
74
+ get inactiveMessage(): string;
44
75
  /**
45
76
  * Whether this row is actionable — a non-empty `meetingId` is required for the
46
77
  * meeting-name link and action button to emit anything (Req 7.10).
@@ -56,17 +87,26 @@ export declare class MeetingAttendanceRowComponent {
56
87
  */
57
88
  get isCurrentlyAttending(): boolean;
58
89
  /**
59
- * Whether the log-attendance button should be shown: only when the row is in
60
- * the log state (not currently attending) and the host grants
61
- * `canLogAttendance` (Req 7.6, 12.1).
90
+ * Whether the log-attendance button should be shown: whenever the row is not
91
+ * currently attending. Mirrors the attendance library, which toggles between
92
+ * Log Attendance and Leave Meeting purely on attendance state (no permission
93
+ * gating).
62
94
  * @return {boolean} True when the log-attendance button is visible.
63
95
  * @memberof MeetingAttendanceRowComponent
64
96
  */
65
97
  get showLogAttendanceButton(): boolean;
66
98
  /**
67
- * Whether the leave-meeting button should be shown: only when the row is in
68
- * the currently-attending state and the host grants `canLeaveMeeting`
69
- * (Req 7.5, 12.2).
99
+ * Whether the Log Attendance button is disabled: outside the meeting time
100
+ * (not In Progress) or while an attendance action is in flight. Matches the
101
+ * view-meeting page, which disables the button with an inactive message when
102
+ * the meeting is not active.
103
+ * @return {boolean} True when the Log Attendance button should be disabled.
104
+ * @memberof MeetingAttendanceRowComponent
105
+ */
106
+ get isLogDisabled(): boolean;
107
+ /**
108
+ * Whether the leave-meeting button should be shown: whenever the row is
109
+ * currently attending. Mirrors the attendance library (no permission gating).
70
110
  * @return {boolean} True when the leave-meeting button is visible.
71
111
  * @memberof MeetingAttendanceRowComponent
72
112
  */
@@ -95,6 +135,20 @@ export declare class MeetingAttendanceRowComponent {
95
135
  * @memberof MeetingAttendanceRowComponent
96
136
  */
97
137
  get formattedTime(): string;
138
+ /**
139
+ * The bold time range only (e.g. "10:00–11:00"), 12-hour with meridiem,
140
+ * rendered dark per Figma.
141
+ * @return {string} The formatted start–end time range.
142
+ * @memberof MeetingAttendanceRowComponent
143
+ */
144
+ get timeRange(): string;
145
+ /**
146
+ * The timezone label only (light grey per Figma), wrapped in parentheses, or
147
+ * an empty string when no timezone is present.
148
+ * @return {string} The parenthesised timezone, or an empty string.
149
+ * @memberof MeetingAttendanceRowComponent
150
+ */
151
+ get timezoneDisplay(): string;
98
152
  /**
99
153
  * Handles activation of the attendance action button. Delegates to the pure
100
154
  * `resolveAttendanceAction` handler and emits exactly one event based on the
@@ -111,5 +165,5 @@ export declare class MeetingAttendanceRowComponent {
111
165
  */
112
166
  onOpenMeeting(): void;
113
167
  static ɵfac: i0.ɵɵFactoryDeclaration<MeetingAttendanceRowComponent, never>;
114
- static ɵcmp: i0.ɵɵComponentDeclaration<MeetingAttendanceRowComponent, "ieeesa-meeting-attendance-row", never, { "meeting": { "alias": "meeting"; "required": false; }; "attendanceState": { "alias": "attendanceState"; "required": false; }; "isInFlight": { "alias": "isInFlight"; "required": false; }; "permissions": { "alias": "permissions"; "required": false; }; "compact": { "alias": "compact"; "required": false; }; }, { "openMeeting": "openMeeting"; "logAttendance": "logAttendance"; "leaveMeeting": "leaveMeeting"; }, never, never, true, never>;
168
+ static ɵcmp: i0.ɵɵComponentDeclaration<MeetingAttendanceRowComponent, "ieeesa-meeting-attendance-row", never, { "meeting": { "alias": "meeting"; "required": false; }; "attendanceState": { "alias": "attendanceState"; "required": false; }; "isInFlight": { "alias": "isInFlight"; "required": false; }; "permissions": { "alias": "permissions"; "required": false; }; "compact": { "alias": "compact"; "required": false; }; }, { "openMeeting": "openMeeting"; "logAttendance": "logAttendance"; "leaveMeeting": "leaveMeeting"; "navigateToMeeting": "navigateToMeeting"; }, never, never, true, never>;
115
169
  }
@@ -39,6 +39,7 @@ export declare class MemberLevelBadgeComponent {
39
39
  };
40
40
  emptyMessage: string;
41
41
  errorMessage: string;
42
+ collapsedSummaryTemplate: string;
42
43
  paginator: {
43
44
  rangeTemplate: string;
44
45
  };
@@ -47,7 +48,14 @@ export declare class MemberLevelBadgeComponent {
47
48
  eventBadge: string;
48
49
  standaloneBadge: string;
49
50
  viewLabel: string;
50
- viewEventLabel: string;
51
+ viewEventLabel: string; /**
52
+ * Builds the single-item Legend list for the supplied member level, resolving
53
+ * the pill color from the `constants.json` color map and falling back to the
54
+ * configured default color when the level has no explicit mapping.
55
+ * @param {string} memberLevel - The member-level label to render.
56
+ * @return {Legend[]} A single-element Legend array for the Legend component.
57
+ * @memberof MemberLevelBadgeComponent
58
+ */
51
59
  eventDatesLabel: string;
52
60
  meetingDateLabel: string;
53
61
  timeTimezoneLabel: string;
@@ -76,6 +84,7 @@ export declare class MemberLevelBadgeComponent {
76
84
  currentlyAttendingIndicator: string;
77
85
  logAttendanceLabel: string;
78
86
  leaveMeetingLabel: string;
87
+ inactiveMessage: string;
79
88
  ariaLabel: {
80
89
  meetingNameLink: string;
81
90
  logAttendance: string;
@@ -139,6 +148,8 @@ export declare class MemberLevelBadgeComponent {
139
148
  groupDetail: string;
140
149
  viewAllEvents: string;
141
150
  viewAllGroups: string;
151
+ viewMeeting: string;
152
+ viewMeetingUnderEvent: string;
142
153
  };
143
154
  };
144
155
  private memberLevelValue;
@@ -56,10 +56,18 @@ export declare class UpcomingMeetingsEventsComponent {
56
56
  meetingPageChange: EventEmitter<{
57
57
  eventId: string;
58
58
  } & PageChange>;
59
- /** Emits the event id + one-based page to lazily load an event's child meetings. */
59
+ /** Emits the event id + one-based page + size to lazily load an event's child meetings. */
60
60
  loadEventMeetings: EventEmitter<{
61
61
  eventId: string;
62
62
  page: number;
63
+ size: number;
64
+ }>;
65
+ /** Bubbles a navigate-to-meeting request (eventId + meetingId [+ logAttendance]) for the host to route. */
66
+ navigateToMeeting: EventEmitter<{
67
+ eventId: string;
68
+ meetingId: string;
69
+ logAttendance?: boolean | undefined;
70
+ leaveMeeting?: boolean | undefined;
63
71
  }>;
64
72
  /** Whether the section's card list is currently expanded; starts collapsed. */
65
73
  isExpanded: boolean;
@@ -94,6 +102,30 @@ export declare class UpcomingMeetingsEventsComponent {
94
102
  * @memberof UpcomingMeetingsEventsComponent
95
103
  */
96
104
  onSectionPageChange(event: PageEvent): void;
105
+ /** Number of EVENT rows in the list (for the collapsed summary). */
106
+ get eventCount(): number;
107
+ /**
108
+ * Total number of meetings across the list: each event's `meetingCount` plus
109
+ * one per standalone meeting (for the collapsed summary).
110
+ * @return {number} The total meeting count.
111
+ * @memberof UpcomingMeetingsEventsComponent
112
+ */
113
+ get totalMeetingCount(): number;
114
+ /**
115
+ * Total number of meetings open for attendance across the list (for the
116
+ * collapsed summary): each event's open count plus any standalone meeting that
117
+ * is attendance-eligible.
118
+ * @return {number} The total open-for-attendance count.
119
+ * @memberof UpcomingMeetingsEventsComponent
120
+ */
121
+ get totalOpenForAttendanceCount(): number;
122
+ /**
123
+ * The collapsed summary line (e.g. "3 events · 50 meetings · 21 open for
124
+ * attendance") built from the `constants.json` template and the counts.
125
+ * @return {string} The formatted collapsed summary.
126
+ * @memberof UpcomingMeetingsEventsComponent
127
+ */
128
+ get collapsedSummary(): string;
97
129
  /**
98
130
  * Allows the host/container to open or close the section (e.g. a "Jump to"
99
131
  * shortcut opens it). Writing the input mirrors the value onto the internal
@@ -169,7 +201,21 @@ export declare class UpcomingMeetingsEventsComponent {
169
201
  * @param {number} page - The one-based page requested by the card.
170
202
  * @memberof UpcomingMeetingsEventsComponent
171
203
  */
172
- onLoadEventMeetings(eventId: string, page: number): void;
204
+ onLoadEventMeetings(eventId: string, request: {
205
+ page: number;
206
+ size: number;
207
+ }): void;
208
+ /**
209
+ * Bubbles a card's navigate-to-meeting request upward unchanged.
210
+ * @param {{ eventId: string; meetingId: string }} request - The meeting identity.
211
+ * @memberof UpcomingMeetingsEventsComponent
212
+ */
213
+ onNavigateToMeeting(request: {
214
+ eventId: string;
215
+ meetingId: string;
216
+ logAttendance?: boolean;
217
+ leaveMeeting?: boolean;
218
+ }): void;
173
219
  static ɵfac: i0.ɵɵFactoryDeclaration<UpcomingMeetingsEventsComponent, never>;
174
- static ɵcmp: i0.ɵɵComponentDeclaration<UpcomingMeetingsEventsComponent, "ieeesa-upcoming-meetings-events", never, { "events": { "alias": "events"; "required": false; }; "sectionState": { "alias": "sectionState"; "required": false; }; "permissions": { "alias": "permissions"; "required": false; }; "attendanceStates": { "alias": "attendanceStates"; "required": false; }; "inFlightMeetingIds": { "alias": "inFlightMeetingIds"; "required": false; }; "isMobileView": { "alias": "isMobileView"; "required": false; }; "expanded": { "alias": "expanded"; "required": false; }; }, { "viewAll": "viewAll"; "viewEvent": "viewEvent"; "openMeeting": "openMeeting"; "logAttendance": "logAttendance"; "leaveMeeting": "leaveMeeting"; "meetingPageChange": "meetingPageChange"; "loadEventMeetings": "loadEventMeetings"; "expandedChange": "expandedChange"; }, never, never, true, never>;
220
+ static ɵcmp: i0.ɵɵComponentDeclaration<UpcomingMeetingsEventsComponent, "ieeesa-upcoming-meetings-events", never, { "events": { "alias": "events"; "required": false; }; "sectionState": { "alias": "sectionState"; "required": false; }; "permissions": { "alias": "permissions"; "required": false; }; "attendanceStates": { "alias": "attendanceStates"; "required": false; }; "inFlightMeetingIds": { "alias": "inFlightMeetingIds"; "required": false; }; "isMobileView": { "alias": "isMobileView"; "required": false; }; "expanded": { "alias": "expanded"; "required": false; }; }, { "viewAll": "viewAll"; "viewEvent": "viewEvent"; "openMeeting": "openMeeting"; "logAttendance": "logAttendance"; "leaveMeeting": "leaveMeeting"; "meetingPageChange": "meetingPageChange"; "loadEventMeetings": "loadEventMeetings"; "navigateToMeeting": "navigateToMeeting"; "expandedChange": "expandedChange"; }, never, never, true, never>;
175
221
  }
@@ -25,6 +25,8 @@ export interface DashboardNavigationIntent {
25
25
  path: string;
26
26
  /** The identifier that triggered the navigation (event/meeting/group id), when applicable. */
27
27
  id?: string;
28
+ /** Query params to attach to the navigation (e.g. eventId/meetingId/actionType). */
29
+ queryParams?: Record<string, string>;
28
30
  }
29
31
  /**
30
32
  * Dashboard (`ieeesa-dashboard`) is the root container and single host entry
@@ -86,6 +88,7 @@ export declare class DashboardComponent implements OnInit, OnDestroy {
86
88
  };
87
89
  emptyMessage: string;
88
90
  errorMessage: string;
91
+ collapsedSummaryTemplate: string;
89
92
  paginator: {
90
93
  rangeTemplate: string;
91
94
  };
@@ -98,6 +101,12 @@ export declare class DashboardComponent implements OnInit, OnDestroy {
98
101
  eventDatesLabel: string;
99
102
  meetingDateLabel: string;
100
103
  timeTimezoneLabel: string;
104
+ /**
105
+ * A navigation intent emitted by {@link DashboardComponent} for the host
106
+ * application to act on. The library never performs navigation itself; it emits
107
+ * the resolved target `path` (from the {@link DashboardRouteConfig}) together
108
+ * with the triggering identifier so the host can route accordingly (Req 11.1).
109
+ */
101
110
  meetingsLabel: string;
102
111
  openForAttendanceTemplate: string;
103
112
  meetingListToggle: {
@@ -109,7 +118,7 @@ export declare class DashboardComponent implements OnInit, OnDestroy {
109
118
  ariaLabel: {
110
119
  view: string;
111
120
  viewEvent: string;
112
- meetingListToggle: string; /** The resolved target route path from the active {@link DashboardRouteConfig}. */
121
+ meetingListToggle: string; /** The identifier that triggered the navigation (event/meeting/group id), when applicable. */
113
122
  };
114
123
  paginator: {
115
124
  rangeTemplate: string;
@@ -123,6 +132,7 @@ export declare class DashboardComponent implements OnInit, OnDestroy {
123
132
  currentlyAttendingIndicator: string;
124
133
  logAttendanceLabel: string;
125
134
  leaveMeetingLabel: string;
135
+ inactiveMessage: string;
126
136
  ariaLabel: {
127
137
  meetingNameLink: string;
128
138
  logAttendance: string;
@@ -186,6 +196,8 @@ export declare class DashboardComponent implements OnInit, OnDestroy {
186
196
  groupDetail: string;
187
197
  viewAllEvents: string;
188
198
  viewAllGroups: string;
199
+ viewMeeting: string;
200
+ viewMeetingUnderEvent: string;
189
201
  };
190
202
  };
191
203
  /** Host navigation paths; falls back to the `constants.json` default when omitted (Req 11.1, 11.5). */
@@ -214,7 +226,7 @@ export declare class DashboardComponent implements OnInit, OnDestroy {
214
226
  attendancePermissions: AttendanceActionPermissions;
215
227
  /** Whether the viewport is at/below the mobile breakpoint (Req 15.1, 15.2). */
216
228
  isMobileView: boolean;
217
- /** Whether the Upcoming Meetings & Events card is expanded. Starts collapsed. */
229
+ /** Whether the Upcoming Meetings & Events card is expanded. Starts expanded. */
218
230
  meetingsExpanded: boolean;
219
231
  /** Whether the Your Groups card is expanded. Starts collapsed. */
220
232
  groupsExpanded: boolean;
@@ -295,8 +307,11 @@ export declare class DashboardComponent implements OnInit, OnDestroy {
295
307
  */
296
308
  onViewEvent(eventId: string): void;
297
309
  /**
298
- * Emits the open-meeting navigation intent, targeting the `meetingDetail`
299
- * route with the meeting id (Req 7.4, 11.1).
310
+ * Emits the open-meeting navigation intent to the view-meeting screen,
311
+ * matching the reference list: a meeting under an event targets
312
+ * `viewMeetingUnderEvent` with `eventId` + `meetingId` + `actionType=edit`; a
313
+ * standalone meeting targets `viewMeeting` with `meetingId` + `actionType=edit`.
314
+ * (Retained for the legacy string `openMeeting` output.)
300
315
  * @param {string} meetingId - The id of the meeting to open.
301
316
  * @return {void}
302
317
  * @memberof DashboardComponent
@@ -328,14 +343,32 @@ export declare class DashboardComponent implements OnInit, OnDestroy {
328
343
  /**
329
344
  * Lazily loads (or paginates) the child meetings of an expanded EVENT card via
330
345
  * the service, surfacing the attendance error message on failure. Each event
331
- * paginates independently.
332
- * @param {{ eventId: string; page: number }} request - The event id and one-based page to load.
346
+ * paginates independently. Loading feedback is handled by the host
347
+ * application's global spinner, so no per-event loading state is tracked here.
348
+ * @param {{ eventId: string; page: number; size: number }} request - The event id and one-based page to load.
333
349
  * @return {void}
334
350
  * @memberof DashboardComponent
335
351
  */
336
352
  onLoadEventMeetings(request: {
337
353
  eventId: string;
338
354
  page: number;
355
+ size: number;
356
+ }): void;
357
+ /**
358
+ * Handles an attendance-button activation for an In-Progress meeting by
359
+ * emitting a navigation intent to the view-meeting screen with `eventId`,
360
+ * `meetingId`, and `actionType=edit` query params — producing a URL like
361
+ * `/events-and-meetings/view-event/view-meeting?eventId=...&meetingId=...&actionType=edit`.
362
+ * The Log Attendance popup is opened by that destination page.
363
+ * @param {{ eventId: string; meetingId: string }} request - The meeting identity.
364
+ * @return {void}
365
+ * @memberof DashboardComponent
366
+ */
367
+ onNavigateToMeeting(request: {
368
+ eventId: string;
369
+ meetingId: string;
370
+ logAttendance?: boolean;
371
+ leaveMeeting?: boolean;
339
372
  }): void;
340
373
  /**
341
374
  * Delegates a log-attendance request to the service, surfacing the
@@ -1,4 +1,11 @@
1
+ /**
2
+ * Per-meeting attendance state as returned by the home endpoints.
3
+ * - NOT_ATTENDING: the user has not logged attendance (shows Log Attendance).
4
+ * - CURRENTLY_ATTENDING: the user is logged in (shows Leave Meeting + pill).
5
+ * - ATTENDED: the user attended and has since logged out.
6
+ */
1
7
  export declare enum AttendanceState {
2
8
  CURRENTLY_ATTENDING = "CURRENTLY_ATTENDING",
3
- NOT_ATTENDING = "NOT_ATTENDING"
9
+ NOT_ATTENDING = "NOT_ATTENDING",
10
+ ATTENDED = "ATTENDED"
4
11
  }
@@ -1,7 +1,21 @@
1
1
  export interface DashboardRouteConfig {
2
+ /** View-event screen; the dashboard appends `?eventId=`. e.g. `/events-and-meetings/view-event`. */
2
3
  eventDetail: string;
4
+ /** Legacy meeting-detail route (kept for backward compatibility). */
3
5
  meetingDetail: string;
4
6
  groupDetail: string;
5
7
  viewAllEvents: string;
6
8
  viewAllGroups: string;
9
+ /**
10
+ * Standalone view-meeting screen. The dashboard appends `meetingId` and
11
+ * `actionType=edit` (and `logAttendance=true` for the Log Attendance action),
12
+ * e.g. `/events-and-meetings/view-meeting`.
13
+ */
14
+ viewMeeting?: string;
15
+ /**
16
+ * View-meeting-under-event screen. The dashboard appends `eventId`,
17
+ * `meetingId`, and `actionType=edit`,
18
+ * e.g. `/events-and-meetings/view-event/view-meeting`.
19
+ */
20
+ viewMeetingUnderEvent?: string;
7
21
  }
@@ -1,25 +1,25 @@
1
+ import { AttendanceState } from './attendance-state.model';
1
2
  /**
2
- * Raw list item returned by the real "events & meetings" backend
3
- * (`POST {apiBaseUrl}/meetings/eventsAndMeetings`). A single list may contain
4
- * both EVENT rows (`isMeetingEvent === true` / `hasChildren === true`, which own
5
- * child meetings) and STANDALONE MEETING rows (`isMeetingEvent === false`).
3
+ * Raw combined list item returned by the home events-&-meetings endpoint
4
+ * (`POST {apiBaseUrl}/meetings/home/eventsAndMeetings`). A single list contains
5
+ * both EVENT rows (`isMeetingEvent === true`, which own child meetings) and
6
+ * STANDALONE MEETING rows (`isMeetingEvent === false`).
6
7
  *
7
- * Dates are epoch milliseconds (not ISO strings) and must be formatted with
8
- * luxon `DateTime.fromMillis`. This shape mirrors the `events-and-meetings`
9
- * library's `EventsAndMeetings` list model so the dashboard reuses the exact
10
- * backend contract referenced by the existing
11
- * `view-events-meetings-list` screen.
8
+ * Dates are ISO-8601 strings (e.g. "2026-09-19T09:00:00"). Row-type fields are
9
+ * omitted (NON_NULL) when not applicable:
10
+ * - EVENT rows carry {@link totalMeetingCount} / {@link meetingsOpenForAttendanceCount}; no `attendanceState`.
11
+ * - STANDALONE rows carry {@link attendanceState}; no event counts.
12
12
  */
13
13
  export interface EventMeetingListItem {
14
14
  /** Stable identifier of the event or standalone meeting. */
15
15
  id: string;
16
16
  /** Event / meeting display name. */
17
17
  name: string;
18
- /** Start date-time as an ISO-8601 string (or epoch ms for legacy fixtures). */
19
- startDateTime: string | number;
20
- /** End date-time as an ISO-8601 string (or epoch ms for legacy fixtures). */
21
- endDateTime: string | number;
22
- /** IANA / offset-prefixed timezone string, e.g. "(UTC+05:30) Asia/Kolkata". */
18
+ /** Start date-time as an ISO-8601 string. */
19
+ startDateTime: string;
20
+ /** End date-time as an ISO-8601 string. */
21
+ endDateTime: string;
22
+ /** IANA timezone string, e.g. "Asia/Kolkata". */
23
23
  timeZone: string;
24
24
  /** Owning group id. */
25
25
  groupId?: string;
@@ -27,81 +27,81 @@ export interface EventMeetingListItem {
27
27
  groupName?: string;
28
28
  /** Owning group acronym, when provided. */
29
29
  groupAcronym?: string;
30
- /** Room / location text, when provided. */
30
+ /** Room / location text, when provided (null for virtual/none). */
31
31
  meetingLocation?: string | null;
32
32
  /** True when this row is an EVENT that owns child meetings. */
33
33
  hasChildren?: boolean;
34
- /**
35
- * True when the row represents an EVENT (vs. a standalone meeting). Combined
36
- * with {@link hasChildren} this is the EVENT-vs-STANDALONE discriminator.
37
- */
38
- isMeetingEvent?: boolean;
39
- /** Lifecycle status, e.g. "In Progress", "Upcoming", "Starts Soon". */
34
+ /** True when the row represents an EVENT (vs. a standalone meeting). */
35
+ isMeetingEvent: boolean;
36
+ /** Lifecycle status, e.g. "In Progress", "Upcoming", "Completed". */
40
37
  status?: string;
41
- /** True when the signed-in user is a member of the owning group. */
42
- isMemberOfGroup?: boolean;
43
- /** True when the current user is currently attending (drives the pill). */
44
- isCurrentlyAttending?: boolean;
45
- /** True when the row is open for attendance logging. */
46
- isOpenForAttendance?: boolean;
47
- /** Event id a standalone/child meeting belongs to, when applicable. */
48
- eventId?: string;
49
- /** Meeting id, when the row is a meeting. */
50
- meetingId?: string;
51
- /** Alternate name key some payloads use for meetings. */
52
- meetingTitle?: string;
53
- /** Alternate status key (the list screen copies status here). */
54
- contentUnderLink?: string;
55
- /** Alternate location key used by some meeting payloads. */
56
- room?: string | null;
57
- /** Count of child meetings for an event, when the backend provides it. */
58
- meetingCount?: number;
59
- /** Count of child meetings open for attendance, when provided. */
60
- openForAttendanceCount?: number;
61
- /** "Day X of Y" indicator string, when the backend provides it. */
62
- dayIndicator?: string;
38
+ registeredParticipants?: boolean;
39
+ hasAttendanceRecords?: boolean;
40
+ registrationRequired?: boolean;
41
+ registrationLink?: string | null;
42
+ creditEnabled?: boolean;
43
+ /** EVENT only: total active meetings in the event. */
44
+ totalMeetingCount?: number;
45
+ /** EVENT only: meetings upcoming/in-progress AND attendance-enabled. */
46
+ meetingsOpenForAttendanceCount?: number;
47
+ /** STANDALONE only: the user's attendance state for this meeting. */
48
+ attendanceState?: AttendanceState;
63
49
  }
64
- /**
65
- * Response envelope for the dashboard events-&-meetings list endpoint, matching
66
- * the `events-and-meetings` library's `GetEventsAndMeetingsResponse` body shape.
67
- */
50
+ /** Body of the home events-&-meetings list response. */
51
+ export interface EventMeetingListBody {
52
+ totalRecords: number;
53
+ eventMeetingList: EventMeetingListItem[];
54
+ }
55
+ /** Response envelope for the home events-&-meetings list endpoint. */
68
56
  export interface EventMeetingListResponse {
69
57
  status: boolean;
70
58
  message?: string;
71
- body: {
72
- totalRecords: number;
73
- eventMeetingList: EventMeetingListItem[];
74
- };
59
+ body: EventMeetingListBody;
75
60
  }
76
61
  /**
77
- * Child-meeting list item returned by the per-event expand endpoint
78
- * (`POST {apiBaseUrl}/meetings/meetingsDetails`). Dates are epoch milliseconds.
79
- * Mirrors the `events-and-meetings` library's `Meeting` model.
62
+ * Child-meeting item returned by the per-event drill-down endpoint
63
+ * (`POST {apiBaseUrl}/meetings/home/events/{eventId}/meetings`). Dates are
64
+ * ISO-8601 strings. `location` follows the backend rule (physical location, else
65
+ * "Virtual" when a virtual URL exists, else null).
80
66
  */
81
67
  export interface EventMeetingDetailItem {
82
68
  meetingId: string;
83
69
  meetingTitle: string;
84
- meetingStDate: string | number;
85
- meetingEdDate: string | number;
86
- meetingLocation?: string;
87
70
  groupId?: string;
88
71
  groupName?: string;
89
72
  groupAcronym?: string;
73
+ location?: string | null;
74
+ meetingStDate: string;
75
+ meetingEdDate: string;
90
76
  timeZone?: string;
91
77
  status?: string;
92
- isMemberOfGroup?: boolean;
93
- isCurrentlyAttending?: boolean;
94
- isOpenForAttendance?: boolean;
78
+ attendanceState?: AttendanceState;
95
79
  }
96
- /**
97
- * Response envelope for the per-event child-meetings expand endpoint, matching
98
- * the `events-and-meetings` library's `GetMeetingsByEventIdResponse` body shape.
99
- */
80
+ /** Body of the per-event drill-down response. */
81
+ export interface EventMeetingDetailBody {
82
+ eventId: string;
83
+ eventName: string;
84
+ status: string;
85
+ /** Current day index for the "Day X of Y" display. */
86
+ currentDay: number;
87
+ /** Total day span for the "Day X of Y" display. */
88
+ totalDays: number;
89
+ startDate: string;
90
+ endDate: string;
91
+ timeZone: string;
92
+ /** All active meetings in the event. */
93
+ totalMeetingCount: number;
94
+ /** Upcoming/in-progress AND attendance-enabled meetings. */
95
+ meetingsOpenForAttendanceCount: number;
96
+ /** Count of the user's tied upcoming meetings for this event (paginator length). */
97
+ totalRecords: number;
98
+ page: number;
99
+ size: number;
100
+ meetings: EventMeetingDetailItem[];
101
+ }
102
+ /** Response envelope for the per-event drill-down endpoint. */
100
103
  export interface EventMeetingDetailResponse {
101
104
  status: boolean;
102
105
  message?: string;
103
- body: {
104
- totalRecords: number;
105
- meetings: EventMeetingDetailItem[];
106
- };
106
+ body: EventMeetingDetailBody;
107
107
  }