@ieeesa-npm/dashboard 0.0.0-stage → 0.0.1

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 (63) hide show
  1. package/README.md +75 -3
  2. package/esm2022/ieeesa-npm-dashboard.mjs +5 -0
  3. package/esm2022/lib/assets/constants.json +141 -0
  4. package/esm2022/lib/assets/dashboard-mock.mjs +217 -0
  5. package/esm2022/lib/assets/dashboard-route-paths.mock.mjs +12 -0
  6. package/esm2022/lib/assets/dashboard-user-permissions.mock.mjs +23 -0
  7. package/esm2022/lib/assets/date-formats.mjs +28 -0
  8. package/esm2022/lib/components/event-group-card/event-group-card.component.mjs +277 -0
  9. package/esm2022/lib/components/meeting-attendance-row/meeting-attendance-row.component.mjs +181 -0
  10. package/esm2022/lib/components/member-level-badge/member-level-badge.component.mjs +79 -0
  11. package/esm2022/lib/components/upcoming-meetings-events/upcoming-meetings-events.component.mjs +163 -0
  12. package/esm2022/lib/components/welcome-header/dashboard-welcome-header.component.mjs +151 -0
  13. package/esm2022/lib/components/your-groups/your-groups.component.mjs +206 -0
  14. package/esm2022/lib/dashboard.component.mjs +377 -0
  15. package/esm2022/lib/dashboard.module.mjs +16 -0
  16. package/esm2022/lib/dashboard.routes.mjs +7 -0
  17. package/esm2022/lib/models/attendance-action-permissions.model.mjs +2 -0
  18. package/esm2022/lib/models/attendance-state.model.mjs +7 -0
  19. package/esm2022/lib/models/dashboard-list-response.model.mjs +2 -0
  20. package/esm2022/lib/models/dashboard-route-config.model.mjs +2 -0
  21. package/esm2022/lib/models/dashboard-section-state.model.mjs +9 -0
  22. package/esm2022/lib/models/dashboard-user-info.model.mjs +2 -0
  23. package/esm2022/lib/models/group-row.model.mjs +2 -0
  24. package/esm2022/lib/models/meeting-row.model.mjs +2 -0
  25. package/esm2022/lib/models/page-change.model.mjs +2 -0
  26. package/esm2022/lib/models/upcoming-event.model.mjs +2 -0
  27. package/esm2022/lib/services/attendance-reducers.mjs +54 -0
  28. package/esm2022/lib/services/dashboard.service.mjs +208 -0
  29. package/esm2022/lib/services/user-permissions.service.mjs +50 -0
  30. package/esm2022/lib/utils/attendance-action.util.mjs +53 -0
  31. package/esm2022/public-api.mjs +34 -0
  32. package/fesm2022/ieeesa-npm-dashboard.mjs +2234 -0
  33. package/fesm2022/ieeesa-npm-dashboard.mjs.map +1 -0
  34. package/index.d.ts +5 -0
  35. package/lib/assets/dashboard-mock.d.ts +31 -0
  36. package/lib/assets/dashboard-route-paths.mock.d.ts +2 -0
  37. package/lib/assets/dashboard-user-permissions.mock.d.ts +2 -0
  38. package/lib/assets/date-formats.d.ts +27 -0
  39. package/lib/components/event-group-card/event-group-card.component.d.ts +300 -0
  40. package/lib/components/meeting-attendance-row/meeting-attendance-row.component.d.ts +239 -0
  41. package/lib/components/member-level-badge/member-level-badge.component.d.ts +161 -0
  42. package/lib/components/upcoming-meetings-events/upcoming-meetings-events.component.d.ts +238 -0
  43. package/lib/components/welcome-header/dashboard-welcome-header.component.d.ts +98 -0
  44. package/lib/components/your-groups/your-groups.component.d.ts +110 -0
  45. package/lib/dashboard.component.d.ts +376 -0
  46. package/lib/dashboard.module.d.ts +7 -0
  47. package/lib/dashboard.routes.d.ts +2 -0
  48. package/lib/models/attendance-action-permissions.model.d.ts +4 -0
  49. package/lib/models/attendance-state.model.d.ts +4 -0
  50. package/lib/models/dashboard-list-response.model.d.ts +5 -0
  51. package/lib/models/dashboard-route-config.model.d.ts +7 -0
  52. package/lib/models/dashboard-section-state.model.d.ts +6 -0
  53. package/lib/models/dashboard-user-info.model.d.ts +5 -0
  54. package/lib/models/group-row.model.d.ts +8 -0
  55. package/lib/models/meeting-row.model.d.ts +12 -0
  56. package/lib/models/page-change.model.d.ts +4 -0
  57. package/lib/models/upcoming-event.model.d.ts +13 -0
  58. package/lib/services/attendance-reducers.d.ts +43 -0
  59. package/lib/services/dashboard.service.d.ts +119 -0
  60. package/lib/services/user-permissions.service.d.ts +31 -0
  61. package/lib/utils/attendance-action.util.d.ts +38 -0
  62. package/package.json +30 -3
  63. package/public-api.d.ts +24 -0
@@ -0,0 +1,376 @@
1
+ import { EventEmitter, OnDestroy, OnInit } from '@angular/core';
2
+ import { BreakpointObserverService } from '@ieeesa-npm/presentation';
3
+ import { UserPermission } from '@ieeesa-npm/models';
4
+ import { AlertsService } from '@ieeesa-npm/utility';
5
+ import { AttendanceActionPermissions } from './models/attendance-action-permissions.model';
6
+ import { AttendanceState } from './models/attendance-state.model';
7
+ import { DashboardRouteConfig } from './models/dashboard-route-config.model';
8
+ import { DashboardSectionState } from './models/dashboard-section-state.model';
9
+ import { DashboardUserInfo } from './models/dashboard-user-info.model';
10
+ import { GroupRow } from './models/group-row.model';
11
+ import { PageChange } from './models/page-change.model';
12
+ import { UpcomingEvent } from './models/upcoming-event.model';
13
+ import { DashboardService } from './services/dashboard.service';
14
+ import { UserPermissionsService } from './services/user-permissions.service';
15
+ import { DashboardJumpTarget } from './components/welcome-header/dashboard-welcome-header.component';
16
+ import * as i0 from "@angular/core";
17
+ /**
18
+ * A navigation intent emitted by {@link DashboardComponent} for the host
19
+ * application to act on. The library never performs navigation itself; it emits
20
+ * the resolved target `path` (from the {@link DashboardRouteConfig}) together
21
+ * with the triggering identifier so the host can route accordingly (Req 11.1).
22
+ */
23
+ export interface DashboardNavigationIntent {
24
+ /** The resolved target route path from the active {@link DashboardRouteConfig}. */
25
+ path: string;
26
+ /** The identifier that triggered the navigation (event/meeting/group id), when applicable. */
27
+ id?: string;
28
+ }
29
+ /**
30
+ * Dashboard (`ieeesa-dashboard`) is the root container and single host entry
31
+ * point for the "NESC Revision Cycle" dashboard landing page. It owns the
32
+ * host-supplied configuration (`routePaths`, `apiBaseURL`, `userInfo`,
33
+ * `userPermissions`), composes the four regions — welcome header, upcoming
34
+ * meetings & events, your groups, and footer — and orchestrates data loading
35
+ * and attendance actions through the {@link DashboardService}.
36
+ *
37
+ * The component is composition-first and host-agnostic: it subscribes to the
38
+ * service observables (`upcomingEvents$`, `groups$`, the per-section states, the
39
+ * attendance-state map, and the in-flight set) with `takeUntil(destroy$)` and
40
+ * tracks `isMobileView` from the Presentation_Library
41
+ * {@link BreakpointObserverService} (Req 13.1, 13.2, 13.5, 15.1, 15.2). Child
42
+ * navigation `@Output()`s are composed into a single {@link dashboardNavigate}
43
+ * stream of `{ path, id }` intents resolved from `routePaths` (falling back to
44
+ * the default route configuration in `constants.json` when `routePaths` is
45
+ * omitted) (Req 5.2, 6.4, 7.4, 8.2, 8.7, 11.1, 11.5). Attendance `@Output()`s
46
+ * are delegated to the service, and on failure the attendance-action error
47
+ * message from `constants.json` is surfaced via the shared {@link AlertsService}
48
+ * (Req 7.7, 7.8, 13.7). Per-row {@link AttendanceActionPermissions} are computed
49
+ * from `userPermissions` and passed down to the rows (Req 12.3).
50
+ * @export
51
+ * @class DashboardComponent
52
+ */
53
+ export declare class DashboardComponent implements OnInit, OnDestroy {
54
+ private dashboardService;
55
+ private userPermissionsService;
56
+ private breakpointObserverService;
57
+ private alertService;
58
+ /** User-facing strings and the default route config sourced from `constants.json`. */
59
+ constants: {
60
+ welcomeHeader: {
61
+ greeting: string;
62
+ fallbackGreeting: string;
63
+ helperText: string;
64
+ jumpToLabel: string;
65
+ shortcuts: {
66
+ meetings: {
67
+ label: string;
68
+ iconUrl: string;
69
+ ariaLabel: string;
70
+ };
71
+ groups: {
72
+ label: string;
73
+ iconUrl: string;
74
+ ariaLabel: string;
75
+ };
76
+ };
77
+ };
78
+ upcomingSection: {
79
+ title: string;
80
+ viewAllLabel: string;
81
+ expandLabel: string;
82
+ collapseLabel: string;
83
+ ariaLabel: {
84
+ viewAll: string;
85
+ toggle: string;
86
+ };
87
+ emptyMessage: string;
88
+ errorMessage: string;
89
+ };
90
+ eventGroupCard: {
91
+ viewEventLabel: string;
92
+ meetingListToggle: {
93
+ showLabelPrefix: string;
94
+ showLabelSuffix: string;
95
+ hideLabel: string;
96
+ };
97
+ ariaLabel: {
98
+ viewEvent: string;
99
+ meetingListToggle: string;
100
+ };
101
+ paginator: {
102
+ rangeTemplate: string;
103
+ totalTemplate: string;
104
+ };
105
+ };
106
+ meetingRow: {
107
+ emptyFieldPlaceholder: string;
108
+ currentlyAttendingIndicator: string;
109
+ logAttendanceLabel: string;
110
+ leaveMeetingLabel: string;
111
+ ariaLabel: {
112
+ meetingNameLink: string;
113
+ logAttendance: string;
114
+ leaveMeeting: string;
115
+ };
116
+ };
117
+ groupsSection: {
118
+ title: string;
119
+ viewAllLabel: string;
120
+ expandLabel: string;
121
+ collapseLabel: string;
122
+ countSuffix: string;
123
+ emptyValue: string;
124
+ ariaLabel: {
125
+ viewAll: string;
126
+ toggle: string;
127
+ groupLink: string;
128
+ };
129
+ columns: {
130
+ group: string;
131
+ type: string;
132
+ officerRole: string;
133
+ affiliation: string;
134
+ memberLevel: string;
135
+ };
136
+ paginator: {
137
+ rangeTemplate: string;
138
+ totalTemplate: string;
139
+ };
140
+ memberLevelBadge: {
141
+ votingMember: string;
142
+ default: string;
143
+ };
144
+ emptyMessage: string;
145
+ errorMessage: string;
146
+ };
147
+ memberLevel: {
148
+ colorMap: {
149
+ "Voting Member": string;
150
+ Observer: string;
151
+ "Associate Member": string;
152
+ Member: string;
153
+ default: string;
154
+ };
155
+ };
156
+ attendance: {
157
+ errorMessage: string;
158
+ };
159
+ footer: {
160
+ links: {
161
+ label: string;
162
+ target: string;
163
+ }[];
164
+ copyright: string;
165
+ };
166
+ defaultRouteConfig: {
167
+ eventDetail: string;
168
+ meetingDetail: string;
169
+ groupDetail: string;
170
+ viewAllEvents: string;
171
+ /** The signed-in user's info used by the welcome header greeting (Req 11.3, 4.1). */
172
+ viewAllGroups: string;
173
+ };
174
+ };
175
+ /** Host navigation paths; falls back to the `constants.json` default when omitted (Req 11.1, 11.5). */
176
+ routePaths?: DashboardRouteConfig;
177
+ /** The host application's API base URL, forwarded to the service (Req 11.2). */
178
+ apiBaseURL: string;
179
+ /** The signed-in user's info used by the welcome header greeting (Req 11.3, 4.1). */
180
+ userInfo: DashboardUserInfo;
181
+ /** The signed-in user's permissions used to gate attendance actions (Req 11.4, 12.3). */
182
+ userPermissions: UserPermission[];
183
+ /** Emits a resolved navigation intent for the host to act on (Req 5.2, 6.4, 7.4, 8.2, 8.7, 11.1). */
184
+ dashboardNavigate: EventEmitter<DashboardNavigationIntent>;
185
+ /** The user's upcoming events, bound to the upcoming section (Req 13.1, 13.2). */
186
+ upcomingEvents: UpcomingEvent[];
187
+ /** The user's groups, bound to the groups section (Req 13.1, 13.2). */
188
+ groups: GroupRow[];
189
+ /** The upcoming-events section's load/empty/error state (Req 13.1, 13.2, 13.5). */
190
+ upcomingState: DashboardSectionState;
191
+ /** The groups section's load/empty/error state (Req 13.1, 13.2, 13.5). */
192
+ groupsState: DashboardSectionState;
193
+ /** The per-meeting attendance-state map passed down to the rows. */
194
+ attendanceStates: Record<string, AttendanceState>;
195
+ /** The set of meeting ids with an attendance action awaiting resolution. */
196
+ inFlightMeetingIds: ReadonlySet<string>;
197
+ /** The per-row attendance-action permissions derived from `userPermissions` (Req 12.3). */
198
+ attendancePermissions: AttendanceActionPermissions;
199
+ /** Whether the viewport is at/below the mobile breakpoint (Req 15.1, 15.2). */
200
+ isMobileView: boolean;
201
+ /**
202
+ * Total number of meetings across the loaded upcoming events, shown in the
203
+ * welcome header's "Upcoming Meetings & Events" shortcut badge.
204
+ * @readonly
205
+ * @memberof DashboardComponent
206
+ */
207
+ get meetingsCount(): number;
208
+ /**
209
+ * Number of loaded groups, shown in the welcome header's "Your Groups"
210
+ * shortcut badge.
211
+ * @readonly
212
+ * @memberof DashboardComponent
213
+ */
214
+ get groupsCount(): number;
215
+ /** The current zero-based page index of the groups table. */
216
+ groupsPageIndex: number;
217
+ /** The current page size of the groups table. */
218
+ groupsPageSize: number;
219
+ /** Completes on destroy to tear down all subscriptions (Req 2.4, 2.5). */
220
+ private readonly destroy$;
221
+ constructor(dashboardService: DashboardService, userPermissionsService: UserPermissionsService, breakpointObserverService: BreakpointObserverService, alertService: AlertsService);
222
+ /**
223
+ * Initializes the dashboard: forwards the host config to the service, derives
224
+ * the per-row attendance permissions, kicks off the upcoming-events and groups
225
+ * loads, and wires up subscriptions to the service state observables and the
226
+ * breakpoint observer — all cleaned up via `takeUntil(destroy$)` (Req 11.2,
227
+ * 11.4, 12.3, 13.1, 13.2, 13.5, 15.1, 15.2).
228
+ * @return {void}
229
+ * @memberof DashboardComponent
230
+ */
231
+ ngOnInit(): void;
232
+ /**
233
+ * Tears down all subscriptions on destroy (Req 2.4, 2.5).
234
+ * @return {void}
235
+ * @memberof DashboardComponent
236
+ */
237
+ ngOnDestroy(): void;
238
+ /**
239
+ * Handles the welcome-header "Jump to" date selection. The dashboard currently
240
+ * has no date-scoped data load, so the selection is accepted without side
241
+ * effects; the hook keeps the header's contract satisfied for future filtering.
242
+ * @return {void}
243
+ * @memberof DashboardComponent
244
+ */
245
+ onJumpToDateSelected(): void;
246
+ /**
247
+ * Handles a welcome-header "Jump to" shortcut, emitting the navigation intent
248
+ * for the matching section so the host app routes to it: MEETINGS →
249
+ * `viewAllEvents` (/events-and-meetings/view-events-meetings-list), GROUPS →
250
+ * `viewAllGroups` (/groups).
251
+ * @param {DashboardJumpTarget} target - The selected shortcut target.
252
+ * @return {void}
253
+ * @memberof DashboardComponent
254
+ */
255
+ onJumpToShortcut(target: DashboardJumpTarget): void;
256
+ /**
257
+ * Emits the "View All" upcoming-events navigation intent, targeting the
258
+ * `viewAllEvents` route with no id (Req 5.2, 11.1).
259
+ * @return {void}
260
+ * @memberof DashboardComponent
261
+ */
262
+ onViewAllEvents(): void;
263
+ /**
264
+ * Emits the "View Event" navigation intent, targeting the `eventDetail` route
265
+ * with the event id (Req 6.4, 11.1).
266
+ * @param {string} eventId - The id of the event to view.
267
+ * @return {void}
268
+ * @memberof DashboardComponent
269
+ */
270
+ onViewEvent(eventId: string): void;
271
+ /**
272
+ * Emits the open-meeting navigation intent, targeting the `meetingDetail`
273
+ * route with the meeting id (Req 7.4, 11.1).
274
+ * @param {string} meetingId - The id of the meeting to open.
275
+ * @return {void}
276
+ * @memberof DashboardComponent
277
+ */
278
+ onOpenMeeting(meetingId: string): void;
279
+ /**
280
+ * Emits the "View All" groups navigation intent, targeting the
281
+ * `viewAllGroups` route with no id (Req 8.2, 11.1).
282
+ * @return {void}
283
+ * @memberof DashboardComponent
284
+ */
285
+ onViewAllGroups(): void;
286
+ /**
287
+ * Emits the group-detail navigation intent, targeting the `groupDetail` route
288
+ * with the group id (Req 8.7, 11.1).
289
+ * @param {string} groupId - The id of the selected group.
290
+ * @return {void}
291
+ * @memberof DashboardComponent
292
+ */
293
+ onGroupSelected(groupId: string): void;
294
+ /**
295
+ * Updates the groups table paging state in response to a paginator change so
296
+ * the groups section reflects the requested page (Req 8.10).
297
+ * @param {PageChange} page - The requested page index and size.
298
+ * @return {void}
299
+ * @memberof DashboardComponent
300
+ */
301
+ onGroupsPageChange(page: PageChange): void;
302
+ /**
303
+ * Delegates a log-attendance request to the service, surfacing the
304
+ * attendance-action error message via the shared {@link AlertsService} on
305
+ * failure while the service retains the prior displayed state (Req 7.7, 13.7).
306
+ * @param {string} meetingId - The meeting to log attendance for.
307
+ * @return {void}
308
+ * @memberof DashboardComponent
309
+ */
310
+ onLogAttendance(meetingId: string): void;
311
+ /**
312
+ * Delegates a leave-meeting request to the service, surfacing the
313
+ * attendance-action error message via the shared {@link AlertsService} on
314
+ * failure while the service retains the prior displayed state (Req 7.8, 13.7).
315
+ * @param {string} meetingId - The meeting to leave.
316
+ * @return {void}
317
+ * @memberof DashboardComponent
318
+ */
319
+ onLeaveMeeting(meetingId: string): void;
320
+ /**
321
+ * The route configuration in effect: the host-supplied `routePaths` when
322
+ * provided, otherwise the default route config from `constants.json` so
323
+ * navigation intents always carry valid targets (Req 11.1, 11.5).
324
+ * @return {DashboardRouteConfig} The active route configuration.
325
+ * @memberof DashboardComponent
326
+ */
327
+ private get activeRouteConfig();
328
+ /**
329
+ * Subscribes to the service's state observables, mirroring each into a local
330
+ * field for the template to bind. All subscriptions are torn down via
331
+ * `takeUntil(destroy$)` (Req 13.1, 13.2, 13.5).
332
+ * @return {void}
333
+ * @memberof DashboardComponent
334
+ */
335
+ private subscribeToServiceState;
336
+ /**
337
+ * Subscribes to the Presentation_Library breakpoint observer to keep
338
+ * `isMobileView` in sync with the viewport (Req 15.1, 15.2).
339
+ * @return {void}
340
+ * @memberof DashboardComponent
341
+ */
342
+ private subscribeToBreakpoint;
343
+ /**
344
+ * Triggers the upcoming-events load, setting the section to `ERROR` on failure
345
+ * so only the section error region renders (Req 13.1, 13.2, 13.5).
346
+ * @return {void}
347
+ * @memberof DashboardComponent
348
+ */
349
+ private loadUpcomingEvents;
350
+ /**
351
+ * Triggers the groups load, setting the section to `ERROR` on failure so only
352
+ * the section error region renders. Isolated from the upcoming-events load so
353
+ * one failing does not affect the other (Req 13.1, 13.2, 13.5).
354
+ * @return {void}
355
+ * @memberof DashboardComponent
356
+ */
357
+ private loadGroups;
358
+ /**
359
+ * Composes and emits a {@link DashboardNavigationIntent} for the host from the
360
+ * resolved target path and an optional triggering id (Req 11.1).
361
+ * @param {string} path - The resolved target route path.
362
+ * @param {string} [id] - The triggering identifier, when applicable.
363
+ * @return {void}
364
+ * @memberof DashboardComponent
365
+ */
366
+ private emitNavigation;
367
+ /**
368
+ * Surfaces the attendance-action error message from `constants.json` via the
369
+ * shared {@link AlertsService} (Req 13.7).
370
+ * @return {void}
371
+ * @memberof DashboardComponent
372
+ */
373
+ private showAttendanceError;
374
+ static ɵfac: i0.ɵɵFactoryDeclaration<DashboardComponent, never>;
375
+ static ɵcmp: i0.ɵɵComponentDeclaration<DashboardComponent, "ieeesa-dashboard", never, { "routePaths": { "alias": "routePaths"; "required": false; }; "apiBaseURL": { "alias": "apiBaseURL"; "required": false; }; "userInfo": { "alias": "userInfo"; "required": false; }; "userPermissions": { "alias": "userPermissions"; "required": false; }; }, { "dashboardNavigate": "dashboardNavigate"; }, never, never, true, never>;
376
+ }
@@ -0,0 +1,7 @@
1
+ import * as i0 from "@angular/core";
2
+ import * as i1 from "./dashboard.component";
3
+ export declare class DashboardModule {
4
+ static ɵfac: i0.ɵɵFactoryDeclaration<DashboardModule, never>;
5
+ static ɵmod: i0.ɵɵNgModuleDeclaration<DashboardModule, never, [typeof i1.DashboardComponent], [typeof i1.DashboardComponent]>;
6
+ static ɵinj: i0.ɵɵInjectorDeclaration<DashboardModule>;
7
+ }
@@ -0,0 +1,2 @@
1
+ import { Routes } from '@angular/router';
2
+ export declare const DASHBOARD_ROUTES: Routes;
@@ -0,0 +1,4 @@
1
+ export interface AttendanceActionPermissions {
2
+ canLogAttendance: boolean;
3
+ canLeaveMeeting: boolean;
4
+ }
@@ -0,0 +1,4 @@
1
+ export declare enum AttendanceState {
2
+ CURRENTLY_ATTENDING = "CURRENTLY_ATTENDING",
3
+ NOT_ATTENDING = "NOT_ATTENDING"
4
+ }
@@ -0,0 +1,5 @@
1
+ export interface DashboardListResponse<T> {
2
+ status: boolean | string;
3
+ message?: string;
4
+ body?: T;
5
+ }
@@ -0,0 +1,7 @@
1
+ export interface DashboardRouteConfig {
2
+ eventDetail: string;
3
+ meetingDetail: string;
4
+ groupDetail: string;
5
+ viewAllEvents: string;
6
+ viewAllGroups: string;
7
+ }
@@ -0,0 +1,6 @@
1
+ export declare enum DashboardSectionState {
2
+ LOADING = "LOADING",
3
+ LOADED = "LOADED",
4
+ EMPTY = "EMPTY",
5
+ ERROR = "ERROR"
6
+ }
@@ -0,0 +1,5 @@
1
+ export interface DashboardUserInfo {
2
+ name?: string;
3
+ userId?: string;
4
+ appId?: string;
5
+ }
@@ -0,0 +1,8 @@
1
+ export interface GroupRow {
2
+ groupId: string;
3
+ group: string;
4
+ type?: string;
5
+ officerRole?: string;
6
+ affiliation?: string;
7
+ memberLevel: string;
8
+ }
@@ -0,0 +1,12 @@
1
+ import { AttendanceState } from './attendance-state.model';
2
+ export interface MeetingRow {
3
+ meetingId: string;
4
+ meetingName: string;
5
+ groupOrCommittee?: string;
6
+ roomOrLocation?: string;
7
+ meetingDate: string;
8
+ meetingTime: string;
9
+ timezone: string;
10
+ isOpenForAttendance?: boolean;
11
+ attendanceState?: AttendanceState;
12
+ }
@@ -0,0 +1,4 @@
1
+ export interface PageChange {
2
+ pageIndex: number;
3
+ pageSize: number;
4
+ }
@@ -0,0 +1,13 @@
1
+ import { MeetingRow } from './meeting-row.model';
2
+ export interface UpcomingEvent {
3
+ eventId: string;
4
+ title: string;
5
+ status: string;
6
+ dayIndicator?: string;
7
+ meetingCount: number;
8
+ openForAttendanceCount: number;
9
+ startDate: string;
10
+ endDate: string;
11
+ timezone: string;
12
+ meetings: MeetingRow[];
13
+ }
@@ -0,0 +1,43 @@
1
+ import { AttendanceState } from '../models/attendance-state.model';
2
+ /**
3
+ * Pure reducers for the dashboard attendance state. These functions never
4
+ * mutate their inputs; each returns a new object/set so they can be exercised
5
+ * directly by property tests and composed by the DashboardService.
6
+ */
7
+ /**
8
+ * Produce a new attendance-state map with the target meeting set to
9
+ * CURRENTLY_ATTENDING. Every other entry is copied unchanged (frame property).
10
+ *
11
+ * @param {Record<string, AttendanceState>} map The current attendance-state map (not mutated).
12
+ * @param {string} meetingId The meeting whose state transitions to CURRENTLY_ATTENDING.
13
+ * @return {Record<string, AttendanceState>} A new map reflecting the successful log-attendance action.
14
+ */
15
+ export declare const applyLogAttendanceSuccess: (map: Record<string, AttendanceState>, meetingId: string) => Record<string, AttendanceState>;
16
+ /**
17
+ * Produce a new attendance-state map with the target meeting set to
18
+ * NOT_ATTENDING. Every other entry is copied unchanged (frame property).
19
+ *
20
+ * @param {Record<string, AttendanceState>} map The current attendance-state map (not mutated).
21
+ * @param {string} meetingId The meeting whose state transitions to NOT_ATTENDING.
22
+ * @return {Record<string, AttendanceState>} A new map reflecting the successful leave-meeting action.
23
+ */
24
+ export declare const applyLeaveMeetingSuccess: (map: Record<string, AttendanceState>, meetingId: string) => Record<string, AttendanceState>;
25
+ /**
26
+ * Add a meeting to the in-flight set, returning a new set. Prior membership is
27
+ * retained so the displayed attendance state is preserved while the request
28
+ * resolves.
29
+ *
30
+ * @param {ReadonlySet<string>} set The current in-flight meeting-id set (not mutated).
31
+ * @param {string} meetingId The meeting whose attendance action has started.
32
+ * @return {Set<string>} A new set that additionally contains the meeting id.
33
+ */
34
+ export declare const beginAttendanceAction: (set: ReadonlySet<string>, meetingId: string) => Set<string>;
35
+ /**
36
+ * Remove a meeting from the in-flight set, returning a new set. All other
37
+ * in-flight ids are retained.
38
+ *
39
+ * @param {ReadonlySet<string>} set The current in-flight meeting-id set (not mutated).
40
+ * @param {string} meetingId The meeting whose attendance action has resolved.
41
+ * @return {Set<string>} A new set that no longer contains the meeting id.
42
+ */
43
+ export declare const endAttendanceAction: (set: ReadonlySet<string>, meetingId: string) => Set<string>;
@@ -0,0 +1,119 @@
1
+ import { Observable } from 'rxjs';
2
+ import { HttpService } from '@ieeesa-npm/utility';
3
+ import { UserPermission } from '@ieeesa-npm/models';
4
+ import { AttendanceState } from '../models/attendance-state.model';
5
+ import { DashboardListResponse } from '../models/dashboard-list-response.model';
6
+ import { DashboardSectionState } from '../models/dashboard-section-state.model';
7
+ import { GroupRow } from '../models/group-row.model';
8
+ import { UpcomingEvent } from '../models/upcoming-event.model';
9
+ import * as i0 from "@angular/core";
10
+ /**
11
+ * DashboardService is the single source of truth for the dashboard landing
12
+ * page's data and attendance state. It mirrors the `events-and-meetings`
13
+ * service conventions: it is a `providedIn: 'root'` singleton, holds the host
14
+ * `apiBaseUrl` / `userPermissions` set via {@link setAppConfig}, owns its state
15
+ * via `BehaviorSubject`s exposed as observables, and reaches the backend only
16
+ * through the shared `HttpService` from `@ieeesa-npm/utility` (never
17
+ * `HttpClient` directly).
18
+ *
19
+ * The upcoming-events and groups loads currently return annotated mock data
20
+ * because their endpoints are not yet available; the attendance actions compose
21
+ * the pure reducers from `attendance-reducers.ts` so the displayed
22
+ * `AttendanceState` only advances on a successful resolution and the prior
23
+ * state is retained on failure.
24
+ * @export
25
+ * @class DashboardService
26
+ */
27
+ export declare class DashboardService {
28
+ private httpService;
29
+ apiBaseUrl: string;
30
+ userPermissions: UserPermission[];
31
+ private readonly upcomingEvents;
32
+ private readonly groups;
33
+ private readonly upcomingState;
34
+ private readonly groupsState;
35
+ private readonly attendanceStates;
36
+ private readonly inFlightMeetingIds;
37
+ /** Emits the list of the user's upcoming events. */
38
+ upcomingEvents$: Observable<UpcomingEvent[]>;
39
+ /** Emits the list of the user's groups. */
40
+ groups$: Observable<GroupRow[]>;
41
+ /** Emits the load/empty/error state of the upcoming-events section. */
42
+ upcomingState$: Observable<DashboardSectionState>;
43
+ /** Emits the load/empty/error state of the groups section. */
44
+ groupsState$: Observable<DashboardSectionState>;
45
+ /** Emits the per-meeting attendance-state map. */
46
+ attendanceStates$: Observable<Record<string, AttendanceState>>;
47
+ /** Emits the set of meeting ids with an attendance action in flight. */
48
+ inFlightMeetingIds$: Observable<ReadonlySet<string>>;
49
+ constructor(httpService: HttpService);
50
+ /**
51
+ * Stores the host-supplied API base URL and user permissions used to build
52
+ * request URLs and gate permission-controlled actions. Mirrors the
53
+ * `events-and-meetings` service `setAppConfig`.
54
+ * @param {string} apiBaseURL - The host application's API base URL.
55
+ * @param {UserPermission[]} userPermissions - The signed-in user's permissions.
56
+ * @return {void}
57
+ * @memberof DashboardService
58
+ */
59
+ setAppConfig(apiBaseURL: string, userPermissions: UserPermission[]): void;
60
+ /**
61
+ * Loads the user's upcoming events, driving the upcoming section through
62
+ * LOADING → LOADED/EMPTY on success and leaving the caller to set ERROR on
63
+ * failure. Follows the `pipe(map, catchError(throw))` pattern and seeds the
64
+ * per-meeting attendance-state map from the loaded meetings.
65
+ *
66
+ * TODO: Replace mock with real API call when BE is ready
67
+ * @return {Observable<DashboardListResponse<UpcomingEvent[]>>} The upcoming-events response envelope.
68
+ * @memberof DashboardService
69
+ */
70
+ loadUpcomingEvents(): Observable<DashboardListResponse<UpcomingEvent[]>>;
71
+ /**
72
+ * Loads the user's groups, driving the groups section through
73
+ * LOADING → LOADED/EMPTY on success and leaving the caller to set ERROR on
74
+ * failure. Follows the `pipe(map, catchError(throw))` pattern.
75
+ *
76
+ * TODO: Replace mock with real API call when BE is ready
77
+ * @return {Observable<DashboardListResponse<GroupRow[]>>} The groups response envelope.
78
+ * @memberof DashboardService
79
+ */
80
+ loadGroups(): Observable<DashboardListResponse<GroupRow[]>>;
81
+ /**
82
+ * Logs attendance for a meeting. Marks the meeting in-flight (retaining the
83
+ * prior displayed state), posts through `HttpService`, applies the
84
+ * log-attendance-success reducer on success, clears the in-flight flag on
85
+ * completion, and rethrows while retaining prior state on failure.
86
+ * @param {string} meetingId - The meeting to log attendance for.
87
+ * @return {Observable<DashboardListResponse<unknown>>} The attendance response envelope.
88
+ * @memberof DashboardService
89
+ */
90
+ logAttendance(meetingId: string): Observable<DashboardListResponse<unknown>>;
91
+ /**
92
+ * Leaves a meeting. Marks the meeting in-flight (retaining the prior
93
+ * displayed state), posts through `HttpService`, applies the
94
+ * leave-meeting-success reducer on success, clears the in-flight flag on
95
+ * completion, and rethrows while retaining prior state on failure.
96
+ * @param {string} meetingId - The meeting to leave.
97
+ * @return {Observable<DashboardListResponse<unknown>>} The attendance response envelope.
98
+ * @memberof DashboardService
99
+ */
100
+ leaveMeeting(meetingId: string): Observable<DashboardListResponse<unknown>>;
101
+ /**
102
+ * Returns a synchronous snapshot of the per-meeting attendance-state map.
103
+ * @return {Record<string, AttendanceState>} The current attendance-state map.
104
+ * @memberof DashboardService
105
+ */
106
+ getAttendanceStatesSnapshot(): Record<string, AttendanceState>;
107
+ /**
108
+ * Seeds the attendance-state map from a freshly loaded list of events, using
109
+ * each meeting's `attendanceState` (defaulting to `NOT_ATTENDING`). Keeps the
110
+ * displayed state in sync with the data load without overwriting ids that are
111
+ * not present in the new list.
112
+ * @param {UpcomingEvent[]} events - The loaded upcoming events.
113
+ * @return {void}
114
+ * @memberof DashboardService
115
+ */
116
+ private seedAttendanceStates;
117
+ static ɵfac: i0.ɵɵFactoryDeclaration<DashboardService, never>;
118
+ static ɵprov: i0.ɵɵInjectableDeclaration<DashboardService>;
119
+ }
@@ -0,0 +1,31 @@
1
+ import { UserPermission } from '@ieeesa-npm/models';
2
+ import { AttendanceActionPermissions } from '../models/attendance-action-permissions.model';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * Permission identifiers (by name) that gate the dashboard attendance actions.
6
+ * Mirrors the permission-type pattern used by the `events-and-meetings` and
7
+ * `groups` user-permissions services.
8
+ */
9
+ export declare enum DashboardPermissionType {
10
+ LOG_ATTENDANCE = "Log Attendance",
11
+ LEAVE_MEETING = "Leave Meeting"
12
+ }
13
+ export declare class UserPermissionsService {
14
+ /**
15
+ * Returns access provision for the passed action/feature based on whether the signed in user has appropriate permission.
16
+ * @param {DashboardPermissionType} permission
17
+ * @param {UserPermission[]} userPermissions
18
+ * @return {boolean}
19
+ * @memberof UserPermissionsService
20
+ */
21
+ validateAccessPermission(permission: DashboardPermissionType, userPermissions: UserPermission[]): boolean;
22
+ /**
23
+ * Maps the host-supplied user permissions to the attendance-action permissions consumed by the dashboard rows.
24
+ * @param {UserPermission[]} userPermissions
25
+ * @return {AttendanceActionPermissions}
26
+ * @memberof UserPermissionsService
27
+ */
28
+ mapToAttendanceActionPermissions(userPermissions: UserPermission[]): AttendanceActionPermissions;
29
+ static ɵfac: i0.ɵɵFactoryDeclaration<UserPermissionsService, never>;
30
+ static ɵprov: i0.ɵɵInjectableDeclaration<UserPermissionsService>;
31
+ }