@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.
- package/README.md +75 -3
- package/esm2022/ieeesa-npm-dashboard.mjs +5 -0
- package/esm2022/lib/assets/constants.json +141 -0
- package/esm2022/lib/assets/dashboard-mock.mjs +217 -0
- package/esm2022/lib/assets/dashboard-route-paths.mock.mjs +12 -0
- package/esm2022/lib/assets/dashboard-user-permissions.mock.mjs +23 -0
- package/esm2022/lib/assets/date-formats.mjs +28 -0
- package/esm2022/lib/components/event-group-card/event-group-card.component.mjs +277 -0
- package/esm2022/lib/components/meeting-attendance-row/meeting-attendance-row.component.mjs +181 -0
- package/esm2022/lib/components/member-level-badge/member-level-badge.component.mjs +79 -0
- package/esm2022/lib/components/upcoming-meetings-events/upcoming-meetings-events.component.mjs +163 -0
- package/esm2022/lib/components/welcome-header/dashboard-welcome-header.component.mjs +151 -0
- package/esm2022/lib/components/your-groups/your-groups.component.mjs +206 -0
- package/esm2022/lib/dashboard.component.mjs +377 -0
- package/esm2022/lib/dashboard.module.mjs +16 -0
- package/esm2022/lib/dashboard.routes.mjs +7 -0
- package/esm2022/lib/models/attendance-action-permissions.model.mjs +2 -0
- package/esm2022/lib/models/attendance-state.model.mjs +7 -0
- package/esm2022/lib/models/dashboard-list-response.model.mjs +2 -0
- package/esm2022/lib/models/dashboard-route-config.model.mjs +2 -0
- package/esm2022/lib/models/dashboard-section-state.model.mjs +9 -0
- package/esm2022/lib/models/dashboard-user-info.model.mjs +2 -0
- package/esm2022/lib/models/group-row.model.mjs +2 -0
- package/esm2022/lib/models/meeting-row.model.mjs +2 -0
- package/esm2022/lib/models/page-change.model.mjs +2 -0
- package/esm2022/lib/models/upcoming-event.model.mjs +2 -0
- package/esm2022/lib/services/attendance-reducers.mjs +54 -0
- package/esm2022/lib/services/dashboard.service.mjs +208 -0
- package/esm2022/lib/services/user-permissions.service.mjs +50 -0
- package/esm2022/lib/utils/attendance-action.util.mjs +53 -0
- package/esm2022/public-api.mjs +34 -0
- package/fesm2022/ieeesa-npm-dashboard.mjs +2234 -0
- package/fesm2022/ieeesa-npm-dashboard.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/assets/dashboard-mock.d.ts +31 -0
- package/lib/assets/dashboard-route-paths.mock.d.ts +2 -0
- package/lib/assets/dashboard-user-permissions.mock.d.ts +2 -0
- package/lib/assets/date-formats.d.ts +27 -0
- package/lib/components/event-group-card/event-group-card.component.d.ts +300 -0
- package/lib/components/meeting-attendance-row/meeting-attendance-row.component.d.ts +239 -0
- package/lib/components/member-level-badge/member-level-badge.component.d.ts +161 -0
- package/lib/components/upcoming-meetings-events/upcoming-meetings-events.component.d.ts +238 -0
- package/lib/components/welcome-header/dashboard-welcome-header.component.d.ts +98 -0
- package/lib/components/your-groups/your-groups.component.d.ts +110 -0
- package/lib/dashboard.component.d.ts +376 -0
- package/lib/dashboard.module.d.ts +7 -0
- package/lib/dashboard.routes.d.ts +2 -0
- package/lib/models/attendance-action-permissions.model.d.ts +4 -0
- package/lib/models/attendance-state.model.d.ts +4 -0
- package/lib/models/dashboard-list-response.model.d.ts +5 -0
- package/lib/models/dashboard-route-config.model.d.ts +7 -0
- package/lib/models/dashboard-section-state.model.d.ts +6 -0
- package/lib/models/dashboard-user-info.model.d.ts +5 -0
- package/lib/models/group-row.model.d.ts +8 -0
- package/lib/models/meeting-row.model.d.ts +12 -0
- package/lib/models/page-change.model.d.ts +4 -0
- package/lib/models/upcoming-event.model.d.ts +13 -0
- package/lib/services/attendance-reducers.d.ts +43 -0
- package/lib/services/dashboard.service.d.ts +119 -0
- package/lib/services/user-permissions.service.d.ts +31 -0
- package/lib/utils/attendance-action.util.d.ts +38 -0
- package/package.json +30 -3
- package/public-api.d.ts +24 -0
|
@@ -0,0 +1,54 @@
|
|
|
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 const applyLogAttendanceSuccess = (map, meetingId) => ({
|
|
16
|
+
...map,
|
|
17
|
+
[meetingId]: AttendanceState.CURRENTLY_ATTENDING,
|
|
18
|
+
});
|
|
19
|
+
/**
|
|
20
|
+
* Produce a new attendance-state map with the target meeting set to
|
|
21
|
+
* NOT_ATTENDING. Every other entry is copied unchanged (frame property).
|
|
22
|
+
*
|
|
23
|
+
* @param {Record<string, AttendanceState>} map The current attendance-state map (not mutated).
|
|
24
|
+
* @param {string} meetingId The meeting whose state transitions to NOT_ATTENDING.
|
|
25
|
+
* @return {Record<string, AttendanceState>} A new map reflecting the successful leave-meeting action.
|
|
26
|
+
*/
|
|
27
|
+
export const applyLeaveMeetingSuccess = (map, meetingId) => ({
|
|
28
|
+
...map,
|
|
29
|
+
[meetingId]: AttendanceState.NOT_ATTENDING,
|
|
30
|
+
});
|
|
31
|
+
/**
|
|
32
|
+
* Add a meeting to the in-flight set, returning a new set. Prior membership is
|
|
33
|
+
* retained so the displayed attendance state is preserved while the request
|
|
34
|
+
* resolves.
|
|
35
|
+
*
|
|
36
|
+
* @param {ReadonlySet<string>} set The current in-flight meeting-id set (not mutated).
|
|
37
|
+
* @param {string} meetingId The meeting whose attendance action has started.
|
|
38
|
+
* @return {Set<string>} A new set that additionally contains the meeting id.
|
|
39
|
+
*/
|
|
40
|
+
export const beginAttendanceAction = (set, meetingId) => new Set([...set, meetingId]);
|
|
41
|
+
/**
|
|
42
|
+
* Remove a meeting from the in-flight set, returning a new set. All other
|
|
43
|
+
* in-flight ids are retained.
|
|
44
|
+
*
|
|
45
|
+
* @param {ReadonlySet<string>} set The current in-flight meeting-id set (not mutated).
|
|
46
|
+
* @param {string} meetingId The meeting whose attendance action has resolved.
|
|
47
|
+
* @return {Set<string>} A new set that no longer contains the meeting id.
|
|
48
|
+
*/
|
|
49
|
+
export const endAttendanceAction = (set, meetingId) => {
|
|
50
|
+
const next = new Set(set);
|
|
51
|
+
next.delete(meetingId);
|
|
52
|
+
return next;
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0ZW5kYW5jZS1yZWR1Y2Vycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Rhc2hib2FyZC9zcmMvbGliL3NlcnZpY2VzL2F0dGVuZGFuY2UtcmVkdWNlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBRW5FOzs7O0dBSUc7QUFFSDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxDQUFDLE1BQU0seUJBQXlCLEdBQUcsQ0FDdkMsR0FBb0MsRUFDcEMsU0FBaUIsRUFDZ0IsRUFBRSxDQUFDLENBQUM7SUFDckMsR0FBRyxHQUFHO0lBQ04sQ0FBQyxTQUFTLENBQUMsRUFBRSxlQUFlLENBQUMsbUJBQW1CO0NBQ2pELENBQUMsQ0FBQztBQUVIOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLENBQUMsTUFBTSx3QkFBd0IsR0FBRyxDQUN0QyxHQUFvQyxFQUNwQyxTQUFpQixFQUNnQixFQUFFLENBQUMsQ0FBQztJQUNyQyxHQUFHLEdBQUc7SUFDTixDQUFDLFNBQVMsQ0FBQyxFQUFFLGVBQWUsQ0FBQyxhQUFhO0NBQzNDLENBQUMsQ0FBQztBQUVIOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUcsQ0FDbkMsR0FBd0IsRUFDeEIsU0FBaUIsRUFDSixFQUFFLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDO0FBRS9DOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyxDQUNqQyxHQUF3QixFQUN4QixTQUFpQixFQUNKLEVBQUU7SUFDZixNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMxQixJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3ZCLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQXR0ZW5kYW5jZVN0YXRlIH0gZnJvbSAnLi4vbW9kZWxzL2F0dGVuZGFuY2Utc3RhdGUubW9kZWwnO1xyXG5cclxuLyoqXHJcbiAqIFB1cmUgcmVkdWNlcnMgZm9yIHRoZSBkYXNoYm9hcmQgYXR0ZW5kYW5jZSBzdGF0ZS4gVGhlc2UgZnVuY3Rpb25zIG5ldmVyXHJcbiAqIG11dGF0ZSB0aGVpciBpbnB1dHM7IGVhY2ggcmV0dXJucyBhIG5ldyBvYmplY3Qvc2V0IHNvIHRoZXkgY2FuIGJlIGV4ZXJjaXNlZFxyXG4gKiBkaXJlY3RseSBieSBwcm9wZXJ0eSB0ZXN0cyBhbmQgY29tcG9zZWQgYnkgdGhlIERhc2hib2FyZFNlcnZpY2UuXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIFByb2R1Y2UgYSBuZXcgYXR0ZW5kYW5jZS1zdGF0ZSBtYXAgd2l0aCB0aGUgdGFyZ2V0IG1lZXRpbmcgc2V0IHRvXHJcbiAqIENVUlJFTlRMWV9BVFRFTkRJTkcuIEV2ZXJ5IG90aGVyIGVudHJ5IGlzIGNvcGllZCB1bmNoYW5nZWQgKGZyYW1lIHByb3BlcnR5KS5cclxuICpcclxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBBdHRlbmRhbmNlU3RhdGU+fSBtYXAgVGhlIGN1cnJlbnQgYXR0ZW5kYW5jZS1zdGF0ZSBtYXAgKG5vdCBtdXRhdGVkKS5cclxuICogQHBhcmFtIHtzdHJpbmd9IG1lZXRpbmdJZCBUaGUgbWVldGluZyB3aG9zZSBzdGF0ZSB0cmFuc2l0aW9ucyB0byBDVVJSRU5UTFlfQVRURU5ESU5HLlxyXG4gKiBAcmV0dXJuIHtSZWNvcmQ8c3RyaW5nLCBBdHRlbmRhbmNlU3RhdGU+fSBBIG5ldyBtYXAgcmVmbGVjdGluZyB0aGUgc3VjY2Vzc2Z1bCBsb2ctYXR0ZW5kYW5jZSBhY3Rpb24uXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgYXBwbHlMb2dBdHRlbmRhbmNlU3VjY2VzcyA9IChcclxuICBtYXA6IFJlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT4sXHJcbiAgbWVldGluZ0lkOiBzdHJpbmdcclxuKTogUmVjb3JkPHN0cmluZywgQXR0ZW5kYW5jZVN0YXRlPiA9PiAoe1xyXG4gIC4uLm1hcCxcclxuICBbbWVldGluZ0lkXTogQXR0ZW5kYW5jZVN0YXRlLkNVUlJFTlRMWV9BVFRFTkRJTkcsXHJcbn0pO1xyXG5cclxuLyoqXHJcbiAqIFByb2R1Y2UgYSBuZXcgYXR0ZW5kYW5jZS1zdGF0ZSBtYXAgd2l0aCB0aGUgdGFyZ2V0IG1lZXRpbmcgc2V0IHRvXHJcbiAqIE5PVF9BVFRFTkRJTkcuIEV2ZXJ5IG90aGVyIGVudHJ5IGlzIGNvcGllZCB1bmNoYW5nZWQgKGZyYW1lIHByb3BlcnR5KS5cclxuICpcclxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBBdHRlbmRhbmNlU3RhdGU+fSBtYXAgVGhlIGN1cnJlbnQgYXR0ZW5kYW5jZS1zdGF0ZSBtYXAgKG5vdCBtdXRhdGVkKS5cclxuICogQHBhcmFtIHtzdHJpbmd9IG1lZXRpbmdJZCBUaGUgbWVldGluZyB3aG9zZSBzdGF0ZSB0cmFuc2l0aW9ucyB0byBOT1RfQVRURU5ESU5HLlxyXG4gKiBAcmV0dXJuIHtSZWNvcmQ8c3RyaW5nLCBBdHRlbmRhbmNlU3RhdGU+fSBBIG5ldyBtYXAgcmVmbGVjdGluZyB0aGUgc3VjY2Vzc2Z1bCBsZWF2ZS1tZWV0aW5nIGFjdGlvbi5cclxuICovXHJcbmV4cG9ydCBjb25zdCBhcHBseUxlYXZlTWVldGluZ1N1Y2Nlc3MgPSAoXHJcbiAgbWFwOiBSZWNvcmQ8c3RyaW5nLCBBdHRlbmRhbmNlU3RhdGU+LFxyXG4gIG1lZXRpbmdJZDogc3RyaW5nXHJcbik6IFJlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT4gPT4gKHtcclxuICAuLi5tYXAsXHJcbiAgW21lZXRpbmdJZF06IEF0dGVuZGFuY2VTdGF0ZS5OT1RfQVRURU5ESU5HLFxyXG59KTtcclxuXHJcbi8qKlxyXG4gKiBBZGQgYSBtZWV0aW5nIHRvIHRoZSBpbi1mbGlnaHQgc2V0LCByZXR1cm5pbmcgYSBuZXcgc2V0LiBQcmlvciBtZW1iZXJzaGlwIGlzXHJcbiAqIHJldGFpbmVkIHNvIHRoZSBkaXNwbGF5ZWQgYXR0ZW5kYW5jZSBzdGF0ZSBpcyBwcmVzZXJ2ZWQgd2hpbGUgdGhlIHJlcXVlc3RcclxuICogcmVzb2x2ZXMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlTZXQ8c3RyaW5nPn0gc2V0IFRoZSBjdXJyZW50IGluLWZsaWdodCBtZWV0aW5nLWlkIHNldCAobm90IG11dGF0ZWQpLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gbWVldGluZ0lkIFRoZSBtZWV0aW5nIHdob3NlIGF0dGVuZGFuY2UgYWN0aW9uIGhhcyBzdGFydGVkLlxyXG4gKiBAcmV0dXJuIHtTZXQ8c3RyaW5nPn0gQSBuZXcgc2V0IHRoYXQgYWRkaXRpb25hbGx5IGNvbnRhaW5zIHRoZSBtZWV0aW5nIGlkLlxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IGJlZ2luQXR0ZW5kYW5jZUFjdGlvbiA9IChcclxuICBzZXQ6IFJlYWRvbmx5U2V0PHN0cmluZz4sXHJcbiAgbWVldGluZ0lkOiBzdHJpbmdcclxuKTogU2V0PHN0cmluZz4gPT4gbmV3IFNldChbLi4uc2V0LCBtZWV0aW5nSWRdKTtcclxuXHJcbi8qKlxyXG4gKiBSZW1vdmUgYSBtZWV0aW5nIGZyb20gdGhlIGluLWZsaWdodCBzZXQsIHJldHVybmluZyBhIG5ldyBzZXQuIEFsbCBvdGhlclxyXG4gKiBpbi1mbGlnaHQgaWRzIGFyZSByZXRhaW5lZC5cclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seVNldDxzdHJpbmc+fSBzZXQgVGhlIGN1cnJlbnQgaW4tZmxpZ2h0IG1lZXRpbmctaWQgc2V0IChub3QgbXV0YXRlZCkuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZWV0aW5nSWQgVGhlIG1lZXRpbmcgd2hvc2UgYXR0ZW5kYW5jZSBhY3Rpb24gaGFzIHJlc29sdmVkLlxyXG4gKiBAcmV0dXJuIHtTZXQ8c3RyaW5nPn0gQSBuZXcgc2V0IHRoYXQgbm8gbG9uZ2VyIGNvbnRhaW5zIHRoZSBtZWV0aW5nIGlkLlxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IGVuZEF0dGVuZGFuY2VBY3Rpb24gPSAoXHJcbiAgc2V0OiBSZWFkb25seVNldDxzdHJpbmc+LFxyXG4gIG1lZXRpbmdJZDogc3RyaW5nXHJcbik6IFNldDxzdHJpbmc+ID0+IHtcclxuICBjb25zdCBuZXh0ID0gbmV3IFNldChzZXQpO1xyXG4gIG5leHQuZGVsZXRlKG1lZXRpbmdJZCk7XHJcbiAgcmV0dXJuIG5leHQ7XHJcbn07XHJcbiJdfQ==
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { BehaviorSubject, catchError, map, of, } from 'rxjs';
|
|
3
|
+
import { AttendanceState } from '../models/attendance-state.model';
|
|
4
|
+
import { DashboardSectionState } from '../models/dashboard-section-state.model';
|
|
5
|
+
import { DashboardGroupsMock, DashboardUpcomingEventsMock, } from '../assets/dashboard-mock';
|
|
6
|
+
import { applyLeaveMeetingSuccess, applyLogAttendanceSuccess, beginAttendanceAction, endAttendanceAction, } from './attendance-reducers';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
import * as i1 from "@ieeesa-npm/utility";
|
|
9
|
+
/**
|
|
10
|
+
* DashboardService is the single source of truth for the dashboard landing
|
|
11
|
+
* page's data and attendance state. It mirrors the `events-and-meetings`
|
|
12
|
+
* service conventions: it is a `providedIn: 'root'` singleton, holds the host
|
|
13
|
+
* `apiBaseUrl` / `userPermissions` set via {@link setAppConfig}, owns its state
|
|
14
|
+
* via `BehaviorSubject`s exposed as observables, and reaches the backend only
|
|
15
|
+
* through the shared `HttpService` from `@ieeesa-npm/utility` (never
|
|
16
|
+
* `HttpClient` directly).
|
|
17
|
+
*
|
|
18
|
+
* The upcoming-events and groups loads currently return annotated mock data
|
|
19
|
+
* because their endpoints are not yet available; the attendance actions compose
|
|
20
|
+
* the pure reducers from `attendance-reducers.ts` so the displayed
|
|
21
|
+
* `AttendanceState` only advances on a successful resolution and the prior
|
|
22
|
+
* state is retained on failure.
|
|
23
|
+
* @export
|
|
24
|
+
* @class DashboardService
|
|
25
|
+
*/
|
|
26
|
+
export class DashboardService {
|
|
27
|
+
constructor(
|
|
28
|
+
// eslint-disable-next-line no-unused-vars
|
|
29
|
+
httpService // eslint-disable-next-line no-empty-function
|
|
30
|
+
) {
|
|
31
|
+
this.httpService = httpService;
|
|
32
|
+
this.upcomingEvents = new BehaviorSubject([]);
|
|
33
|
+
this.groups = new BehaviorSubject([]);
|
|
34
|
+
this.upcomingState = new BehaviorSubject(DashboardSectionState.LOADING);
|
|
35
|
+
this.groupsState = new BehaviorSubject(DashboardSectionState.LOADING);
|
|
36
|
+
this.attendanceStates = new BehaviorSubject({});
|
|
37
|
+
this.inFlightMeetingIds = new BehaviorSubject(new Set());
|
|
38
|
+
/** Emits the list of the user's upcoming events. */
|
|
39
|
+
this.upcomingEvents$ = this.upcomingEvents.asObservable();
|
|
40
|
+
/** Emits the list of the user's groups. */
|
|
41
|
+
this.groups$ = this.groups.asObservable();
|
|
42
|
+
/** Emits the load/empty/error state of the upcoming-events section. */
|
|
43
|
+
this.upcomingState$ = this.upcomingState.asObservable();
|
|
44
|
+
/** Emits the load/empty/error state of the groups section. */
|
|
45
|
+
this.groupsState$ = this.groupsState.asObservable();
|
|
46
|
+
/** Emits the per-meeting attendance-state map. */
|
|
47
|
+
this.attendanceStates$ = this.attendanceStates.asObservable();
|
|
48
|
+
/** Emits the set of meeting ids with an attendance action in flight. */
|
|
49
|
+
this.inFlightMeetingIds$ = this.inFlightMeetingIds.asObservable();
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Stores the host-supplied API base URL and user permissions used to build
|
|
53
|
+
* request URLs and gate permission-controlled actions. Mirrors the
|
|
54
|
+
* `events-and-meetings` service `setAppConfig`.
|
|
55
|
+
* @param {string} apiBaseURL - The host application's API base URL.
|
|
56
|
+
* @param {UserPermission[]} userPermissions - The signed-in user's permissions.
|
|
57
|
+
* @return {void}
|
|
58
|
+
* @memberof DashboardService
|
|
59
|
+
*/
|
|
60
|
+
setAppConfig(apiBaseURL, userPermissions) {
|
|
61
|
+
this.apiBaseUrl = apiBaseURL;
|
|
62
|
+
this.userPermissions = userPermissions;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Loads the user's upcoming events, driving the upcoming section through
|
|
66
|
+
* LOADING → LOADED/EMPTY on success and leaving the caller to set ERROR on
|
|
67
|
+
* failure. Follows the `pipe(map, catchError(throw))` pattern and seeds the
|
|
68
|
+
* per-meeting attendance-state map from the loaded meetings.
|
|
69
|
+
*
|
|
70
|
+
* TODO: Replace mock with real API call when BE is ready
|
|
71
|
+
* @return {Observable<DashboardListResponse<UpcomingEvent[]>>} The upcoming-events response envelope.
|
|
72
|
+
* @memberof DashboardService
|
|
73
|
+
*/
|
|
74
|
+
loadUpcomingEvents() {
|
|
75
|
+
this.upcomingState.next(DashboardSectionState.LOADING);
|
|
76
|
+
// TODO: Replace mock with real API call when BE is ready
|
|
77
|
+
const response$ = of({
|
|
78
|
+
status: true,
|
|
79
|
+
body: DashboardUpcomingEventsMock,
|
|
80
|
+
});
|
|
81
|
+
return response$.pipe(map((response) => {
|
|
82
|
+
const events = response?.body ?? [];
|
|
83
|
+
this.upcomingEvents.next(events);
|
|
84
|
+
this.seedAttendanceStates(events);
|
|
85
|
+
this.upcomingState.next(events.length > 0
|
|
86
|
+
? DashboardSectionState.LOADED
|
|
87
|
+
: DashboardSectionState.EMPTY);
|
|
88
|
+
return response;
|
|
89
|
+
}), catchError((error) => {
|
|
90
|
+
this.upcomingState.next(DashboardSectionState.ERROR);
|
|
91
|
+
throw error;
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Loads the user's groups, driving the groups section through
|
|
96
|
+
* LOADING → LOADED/EMPTY on success and leaving the caller to set ERROR on
|
|
97
|
+
* failure. Follows the `pipe(map, catchError(throw))` pattern.
|
|
98
|
+
*
|
|
99
|
+
* TODO: Replace mock with real API call when BE is ready
|
|
100
|
+
* @return {Observable<DashboardListResponse<GroupRow[]>>} The groups response envelope.
|
|
101
|
+
* @memberof DashboardService
|
|
102
|
+
*/
|
|
103
|
+
loadGroups() {
|
|
104
|
+
this.groupsState.next(DashboardSectionState.LOADING);
|
|
105
|
+
// TODO: Replace mock with real API call when BE is ready
|
|
106
|
+
const response$ = of({
|
|
107
|
+
status: true,
|
|
108
|
+
body: DashboardGroupsMock,
|
|
109
|
+
});
|
|
110
|
+
return response$.pipe(map((response) => {
|
|
111
|
+
const groups = response?.body ?? [];
|
|
112
|
+
this.groups.next(groups);
|
|
113
|
+
this.groupsState.next(groups.length > 0
|
|
114
|
+
? DashboardSectionState.LOADED
|
|
115
|
+
: DashboardSectionState.EMPTY);
|
|
116
|
+
return response;
|
|
117
|
+
}), catchError((error) => {
|
|
118
|
+
this.groupsState.next(DashboardSectionState.ERROR);
|
|
119
|
+
throw error;
|
|
120
|
+
}));
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Logs attendance for a meeting. Marks the meeting in-flight (retaining the
|
|
124
|
+
* prior displayed state), posts through `HttpService`, applies the
|
|
125
|
+
* log-attendance-success reducer on success, clears the in-flight flag on
|
|
126
|
+
* completion, and rethrows while retaining prior state on failure.
|
|
127
|
+
* @param {string} meetingId - The meeting to log attendance for.
|
|
128
|
+
* @return {Observable<DashboardListResponse<unknown>>} The attendance response envelope.
|
|
129
|
+
* @memberof DashboardService
|
|
130
|
+
*/
|
|
131
|
+
logAttendance(meetingId) {
|
|
132
|
+
this.inFlightMeetingIds.next(beginAttendanceAction(this.inFlightMeetingIds.value, meetingId));
|
|
133
|
+
return this.httpService
|
|
134
|
+
.postData(`${this.apiBaseUrl}/meetings/attendance/log`, { meetingId })
|
|
135
|
+
.pipe(map((response) => {
|
|
136
|
+
this.attendanceStates.next(applyLogAttendanceSuccess(this.attendanceStates.value, meetingId));
|
|
137
|
+
this.inFlightMeetingIds.next(endAttendanceAction(this.inFlightMeetingIds.value, meetingId));
|
|
138
|
+
return response;
|
|
139
|
+
}), catchError((error) => {
|
|
140
|
+
// Retain prior attendance state; only clear the in-flight flag.
|
|
141
|
+
this.inFlightMeetingIds.next(endAttendanceAction(this.inFlightMeetingIds.value, meetingId));
|
|
142
|
+
throw error;
|
|
143
|
+
}));
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Leaves a meeting. Marks the meeting in-flight (retaining the prior
|
|
147
|
+
* displayed state), posts through `HttpService`, applies the
|
|
148
|
+
* leave-meeting-success reducer on success, clears the in-flight flag on
|
|
149
|
+
* completion, and rethrows while retaining prior state on failure.
|
|
150
|
+
* @param {string} meetingId - The meeting to leave.
|
|
151
|
+
* @return {Observable<DashboardListResponse<unknown>>} The attendance response envelope.
|
|
152
|
+
* @memberof DashboardService
|
|
153
|
+
*/
|
|
154
|
+
leaveMeeting(meetingId) {
|
|
155
|
+
this.inFlightMeetingIds.next(beginAttendanceAction(this.inFlightMeetingIds.value, meetingId));
|
|
156
|
+
return this.httpService
|
|
157
|
+
.postData(`${this.apiBaseUrl}/meetings/attendance/leave`, { meetingId })
|
|
158
|
+
.pipe(map((response) => {
|
|
159
|
+
this.attendanceStates.next(applyLeaveMeetingSuccess(this.attendanceStates.value, meetingId));
|
|
160
|
+
this.inFlightMeetingIds.next(endAttendanceAction(this.inFlightMeetingIds.value, meetingId));
|
|
161
|
+
return response;
|
|
162
|
+
}), catchError((error) => {
|
|
163
|
+
// Retain prior attendance state; only clear the in-flight flag.
|
|
164
|
+
this.inFlightMeetingIds.next(endAttendanceAction(this.inFlightMeetingIds.value, meetingId));
|
|
165
|
+
throw error;
|
|
166
|
+
}));
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Returns a synchronous snapshot of the per-meeting attendance-state map.
|
|
170
|
+
* @return {Record<string, AttendanceState>} The current attendance-state map.
|
|
171
|
+
* @memberof DashboardService
|
|
172
|
+
*/
|
|
173
|
+
getAttendanceStatesSnapshot() {
|
|
174
|
+
return this.attendanceStates.value;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Seeds the attendance-state map from a freshly loaded list of events, using
|
|
178
|
+
* each meeting's `attendanceState` (defaulting to `NOT_ATTENDING`). Keeps the
|
|
179
|
+
* displayed state in sync with the data load without overwriting ids that are
|
|
180
|
+
* not present in the new list.
|
|
181
|
+
* @param {UpcomingEvent[]} events - The loaded upcoming events.
|
|
182
|
+
* @return {void}
|
|
183
|
+
* @memberof DashboardService
|
|
184
|
+
*/
|
|
185
|
+
seedAttendanceStates(events) {
|
|
186
|
+
const next = {
|
|
187
|
+
...this.attendanceStates.value,
|
|
188
|
+
};
|
|
189
|
+
events.forEach((event) => {
|
|
190
|
+
event.meetings?.forEach((meeting) => {
|
|
191
|
+
if (meeting.meetingId) {
|
|
192
|
+
next[meeting.meetingId] =
|
|
193
|
+
meeting.attendanceState ?? AttendanceState.NOT_ATTENDING;
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
this.attendanceStates.next(next);
|
|
198
|
+
}
|
|
199
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DashboardService, deps: [{ token: i1.HttpService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
200
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DashboardService, providedIn: 'root' }); }
|
|
201
|
+
}
|
|
202
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DashboardService, decorators: [{
|
|
203
|
+
type: Injectable,
|
|
204
|
+
args: [{
|
|
205
|
+
providedIn: 'root',
|
|
206
|
+
}]
|
|
207
|
+
}], ctorParameters: function () { return [{ type: i1.HttpService }]; } });
|
|
208
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGFzaGJvYXJkLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9kYXNoYm9hcmQvc3JjL2xpYi9zZXJ2aWNlcy9kYXNoYm9hcmQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFDTCxlQUFlLEVBRWYsVUFBVSxFQUNWLEdBQUcsRUFDSCxFQUFFLEdBQ0gsTUFBTSxNQUFNLENBQUM7QUFHZCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFbkUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFHaEYsT0FBTyxFQUNMLG1CQUFtQixFQUNuQiwyQkFBMkIsR0FDNUIsTUFBTSwwQkFBMEIsQ0FBQztBQUNsQyxPQUFPLEVBQ0wsd0JBQXdCLEVBQ3hCLHlCQUF5QixFQUN6QixxQkFBcUIsRUFDckIsbUJBQW1CLEdBQ3BCLE1BQU0sdUJBQXVCLENBQUM7OztBQUUvQjs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUlILE1BQU0sT0FBTyxnQkFBZ0I7SUFxQzNCO0lBQ0UsMENBQTBDO0lBQ2xDLFdBQXdCLENBQUMsNkNBQTZDOztRQUF0RSxnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQW5DakIsbUJBQWMsR0FBRyxJQUFJLGVBQWUsQ0FBa0IsRUFBRSxDQUFDLENBQUM7UUFDMUQsV0FBTSxHQUFHLElBQUksZUFBZSxDQUFhLEVBQUUsQ0FBQyxDQUFDO1FBQzdDLGtCQUFhLEdBQUcsSUFBSSxlQUFlLENBQ2xELHFCQUFxQixDQUFDLE9BQU8sQ0FDOUIsQ0FBQztRQUNlLGdCQUFXLEdBQUcsSUFBSSxlQUFlLENBQ2hELHFCQUFxQixDQUFDLE9BQU8sQ0FDOUIsQ0FBQztRQUNlLHFCQUFnQixHQUFHLElBQUksZUFBZSxDQUVyRCxFQUFFLENBQUMsQ0FBQztRQUNX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LElBQUksR0FBb0M7WUFDNUMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSztTQUMvQixDQUFDO1FBQ0YsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ3ZCLEtBQUssQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7Z0JBQ2xDLElBQUksT0FBTyxDQUFDLFNBQVMsRUFBRTtvQkFDckIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUM7d0JBQ3JCLE9BQU8sQ0FBQyxlQUFlLElBQUksZUFBZSxDQUFDLGFBQWEsQ0FBQztpQkFDNUQ7WUFDSCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuQyxDQUFDOytHQXZPVSxnQkFBZ0I7bUhBQWhCLGdCQUFnQixjQUZmLE1BQU07OzRGQUVQLGdCQUFnQjtrQkFINUIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7XHJcbiAgQmVoYXZpb3JTdWJqZWN0LFxyXG4gIE9ic2VydmFibGUsXHJcbiAgY2F0Y2hFcnJvcixcclxuICBtYXAsXHJcbiAgb2YsXHJcbn0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IEh0dHBTZXJ2aWNlIH0gZnJvbSAnQGllZWVzYS1ucG0vdXRpbGl0eSc7XHJcbmltcG9ydCB7IFVzZXJQZXJtaXNzaW9uIH0gZnJvbSAnQGllZWVzYS1ucG0vbW9kZWxzJztcclxuaW1wb3J0IHsgQXR0ZW5kYW5jZVN0YXRlIH0gZnJvbSAnLi4vbW9kZWxzL2F0dGVuZGFuY2Utc3RhdGUubW9kZWwnO1xyXG5pbXBvcnQgeyBEYXNoYm9hcmRMaXN0UmVzcG9uc2UgfSBmcm9tICcuLi9tb2RlbHMvZGFzaGJvYXJkLWxpc3QtcmVzcG9uc2UubW9kZWwnO1xyXG5pbXBvcnQgeyBEYXNoYm9hcmRTZWN0aW9uU3RhdGUgfSBmcm9tICcuLi9tb2RlbHMvZGFzaGJvYXJkLXNlY3Rpb24tc3RhdGUubW9kZWwnO1xyXG5pbXBvcnQgeyBHcm91cFJvdyB9IGZyb20gJy4uL21vZGVscy9ncm91cC1yb3cubW9kZWwnO1xyXG5pbXBvcnQgeyBVcGNvbWluZ0V2ZW50IH0gZnJvbSAnLi4vbW9kZWxzL3VwY29taW5nLWV2ZW50Lm1vZGVsJztcclxuaW1wb3J0IHtcclxuICBEYXNoYm9hcmRHcm91cHNNb2NrLFxyXG4gIERhc2hib2FyZFVwY29taW5nRXZlbnRzTW9jayxcclxufSBmcm9tICcuLi9hc3NldHMvZGFzaGJvYXJkLW1vY2snO1xyXG5pbXBvcnQge1xyXG4gIGFwcGx5TGVhdmVNZWV0aW5nU3VjY2VzcyxcclxuICBhcHBseUxvZ0F0dGVuZGFuY2VTdWNjZXNzLFxyXG4gIGJlZ2luQXR0ZW5kYW5jZUFjdGlvbixcclxuICBlbmRBdHRlbmRhbmNlQWN0aW9uLFxyXG59IGZyb20gJy4vYXR0ZW5kYW5jZS1yZWR1Y2Vycyc7XHJcblxyXG4vKipcclxuICogRGFzaGJvYXJkU2VydmljZSBpcyB0aGUgc2luZ2xlIHNvdXJjZSBvZiB0cnV0aCBmb3IgdGhlIGRhc2hib2FyZCBsYW5kaW5nXHJcbiAqIHBhZ2UncyBkYXRhIGFuZCBhdHRlbmRhbmNlIHN0YXRlLiBJdCBtaXJyb3JzIHRoZSBgZXZlbnRzLWFuZC1tZWV0aW5nc2BcclxuICogc2VydmljZSBjb252ZW50aW9uczogaXQgaXMgYSBgcHJvdmlkZWRJbjogJ3Jvb3QnYCBzaW5nbGV0b24sIGhvbGRzIHRoZSBob3N0XHJcbiAqIGBhcGlCYXNlVXJsYCAvIGB1c2VyUGVybWlzc2lvbnNgIHNldCB2aWEge0BsaW5rIHNldEFwcENvbmZpZ30sIG93bnMgaXRzIHN0YXRlXHJcbiAqIHZpYSBgQmVoYXZpb3JTdWJqZWN0YHMgZXhwb3NlZCBhcyBvYnNlcnZhYmxlcywgYW5kIHJlYWNoZXMgdGhlIGJhY2tlbmQgb25seVxyXG4gKiB0aHJvdWdoIHRoZSBzaGFyZWQgYEh0dHBTZXJ2aWNlYCBmcm9tIGBAaWVlZXNhLW5wbS91dGlsaXR5YCAobmV2ZXJcclxuICogYEh0dHBDbGllbnRgIGRpcmVjdGx5KS5cclxuICpcclxuICogVGhlIHVwY29taW5nLWV2ZW50cyBhbmQgZ3JvdXBzIGxvYWRzIGN1cnJlbnRseSByZXR1cm4gYW5ub3RhdGVkIG1vY2sgZGF0YVxyXG4gKiBiZWNhdXNlIHRoZWlyIGVuZHBvaW50cyBhcmUgbm90IHlldCBhdmFpbGFibGU7IHRoZSBhdHRlbmRhbmNlIGFjdGlvbnMgY29tcG9zZVxyXG4gKiB0aGUgcHVyZSByZWR1Y2VycyBmcm9tIGBhdHRlbmRhbmNlLXJlZHVjZXJzLnRzYCBzbyB0aGUgZGlzcGxheWVkXHJcbiAqIGBBdHRlbmRhbmNlU3RhdGVgIG9ubHkgYWR2YW5jZXMgb24gYSBzdWNjZXNzZnVsIHJlc29sdXRpb24gYW5kIHRoZSBwcmlvclxyXG4gKiBzdGF0ZSBpcyByZXRhaW5lZCBvbiBmYWlsdXJlLlxyXG4gKiBAZXhwb3J0XHJcbiAqIEBjbGFzcyBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAqL1xyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgRGFzaGJvYXJkU2VydmljZSB7XHJcbiAgYXBpQmFzZVVybCE6IHN0cmluZztcclxuICB1c2VyUGVybWlzc2lvbnMhOiBVc2VyUGVybWlzc2lvbltdO1xyXG5cclxuICBwcml2YXRlIHJlYWRvbmx5IHVwY29taW5nRXZlbnRzID0gbmV3IEJlaGF2aW9yU3ViamVjdDxVcGNvbWluZ0V2ZW50W10+KFtdKTtcclxuICBwcml2YXRlIHJlYWRvbmx5IGdyb3VwcyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8R3JvdXBSb3dbXT4oW10pO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgdXBjb21pbmdTdGF0ZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8RGFzaGJvYXJkU2VjdGlvblN0YXRlPihcclxuICAgIERhc2hib2FyZFNlY3Rpb25TdGF0ZS5MT0FESU5HXHJcbiAgKTtcclxuICBwcml2YXRlIHJlYWRvbmx5IGdyb3Vwc1N0YXRlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxEYXNoYm9hcmRTZWN0aW9uU3RhdGU+KFxyXG4gICAgRGFzaGJvYXJkU2VjdGlvblN0YXRlLkxPQURJTkdcclxuICApO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgYXR0ZW5kYW5jZVN0YXRlcyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8XHJcbiAgICBSZWNvcmQ8c3RyaW5nLCBBdHRlbmRhbmNlU3RhdGU+XHJcbiAgPih7fSk7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBpbkZsaWdodE1lZXRpbmdJZHMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFxyXG4gICAgUmVhZG9ubHlTZXQ8c3RyaW5nPlxyXG4gID4obmV3IFNldDxzdHJpbmc+KCkpO1xyXG5cclxuICAvKiogRW1pdHMgdGhlIGxpc3Qgb2YgdGhlIHVzZXIncyB1cGNvbWluZyBldmVudHMuICovXHJcbiAgdXBjb21pbmdFdmVudHMkOiBPYnNlcnZhYmxlPFVwY29taW5nRXZlbnRbXT4gPVxyXG4gICAgdGhpcy51cGNvbWluZ0V2ZW50cy5hc09ic2VydmFibGUoKTtcclxuICAvKiogRW1pdHMgdGhlIGxpc3Qgb2YgdGhlIHVzZXIncyBncm91cHMuICovXHJcbiAgZ3JvdXBzJDogT2JzZXJ2YWJsZTxHcm91cFJvd1tdPiA9IHRoaXMuZ3JvdXBzLmFzT2JzZXJ2YWJsZSgpO1xyXG4gIC8qKiBFbWl0cyB0aGUgbG9hZC9lbXB0eS9lcnJvciBzdGF0ZSBvZiB0aGUgdXBjb21pbmctZXZlbnRzIHNlY3Rpb24uICovXHJcbiAgdXBjb21pbmdTdGF0ZSQ6IE9ic2VydmFibGU8RGFzaGJvYXJkU2VjdGlvblN0YXRlPiA9XHJcbiAgICB0aGlzLnVwY29taW5nU3RhdGUuYXNPYnNlcnZhYmxlKCk7XHJcbiAgLyoqIEVtaXRzIHRoZSBsb2FkL2VtcHR5L2Vycm9yIHN0YXRlIG9mIHRoZSBncm91cHMgc2VjdGlvbi4gKi9cclxuICBncm91cHNTdGF0ZSQ6IE9ic2VydmFibGU8RGFzaGJvYXJkU2VjdGlvblN0YXRlPiA9XHJcbiAgICB0aGlzLmdyb3Vwc1N0YXRlLmFzT2JzZXJ2YWJsZSgpO1xyXG4gIC8qKiBFbWl0cyB0aGUgcGVyLW1lZXRpbmcgYXR0ZW5kYW5jZS1zdGF0ZSBtYXAuICovXHJcbiAgYXR0ZW5kYW5jZVN0YXRlcyQ6IE9ic2VydmFibGU8UmVjb3JkPHN0cmluZywgQXR0ZW5kYW5jZVN0YXRlPj4gPVxyXG4gICAgdGhpcy5hdHRlbmRhbmNlU3RhdGVzLmFzT2JzZXJ2YWJsZSgpO1xyXG4gIC8qKiBFbWl0cyB0aGUgc2V0IG9mIG1lZXRpbmcgaWRzIHdpdGggYW4gYXR0ZW5kYW5jZSBhY3Rpb24gaW4gZmxpZ2h0LiAqL1xyXG4gIGluRmxpZ2h0TWVldGluZ0lkcyQ6IE9ic2VydmFibGU8UmVhZG9ubHlTZXQ8c3RyaW5nPj4gPVxyXG4gICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC12YXJzXHJcbiAgICBwcml2YXRlIGh0dHBTZXJ2aWNlOiBIdHRwU2VydmljZSAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZW1wdHktZnVuY3Rpb25cclxuICApIHt9XHJcblxyXG4gIC8qKlxyXG4gICAqIFN0b3JlcyB0aGUgaG9zdC1zdXBwbGllZCBBUEkgYmFzZSBVUkwgYW5kIHVzZXIgcGVybWlzc2lvbnMgdXNlZCB0byBidWlsZFxyXG4gICAqIHJlcXVlc3QgVVJMcyBhbmQgZ2F0ZSBwZXJtaXNzaW9uLWNvbnRyb2xsZWQgYWN0aW9ucy4gTWlycm9ycyB0aGVcclxuICAgKiBgZXZlbnRzLWFuZC1tZWV0aW5nc2Agc2VydmljZSBgc2V0QXBwQ29uZmlnYC5cclxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXBpQmFzZVVSTCAtIFRoZSBob3N0IGFwcGxpY2F0aW9uJ3MgQVBJIGJhc2UgVVJMLlxyXG4gICAqIEBwYXJhbSB7VXNlclBlcm1pc3Npb25bXX0gdXNlclBlcm1pc3Npb25zIC0gVGhlIHNpZ25lZC1pbiB1c2VyJ3MgcGVybWlzc2lvbnMuXHJcbiAgICogQHJldHVybiB7dm9pZH1cclxuICAgKiBAbWVtYmVyb2YgRGFzaGJvYXJkU2VydmljZVxyXG4gICAqL1xyXG4gIHNldEFwcENvbmZpZyhhcGlCYXNlVVJMOiBzdHJpbmcsIHVzZXJQZXJtaXNzaW9uczogVXNlclBlcm1pc3Npb25bXSk6IHZvaWQge1xyXG4gICAgdGhpcy5hcGlCYXNlVXJsID0gYXBpQmFzZVVSTDtcclxuICAgIHRoaXMudXNlclBlcm1pc3Npb25zID0gdXNlclBlcm1pc3Npb25zO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9hZHMgdGhlIHVzZXIncyB1cGNvbWluZyBldmVudHMsIGRyaXZpbmcgdGhlIHVwY29taW5nIHNlY3Rpb24gdGhyb3VnaFxyXG4gICAqIExPQURJTkcg4oaSIExPQURFRC9FTVBUWSBvbiBzdWNjZXNzIGFuZCBsZWF2aW5nIHRoZSBjYWxsZXIgdG8gc2V0IEVSUk9SIG9uXHJcbiAgICogZmFpbHVyZS4gRm9sbG93cyB0aGUgYHBpcGUobWFwLCBjYXRjaEVycm9yKHRocm93KSlgIHBhdHRlcm4gYW5kIHNlZWRzIHRoZVxyXG4gICAqIHBlci1tZWV0aW5nIGF0dGVuZGFuY2Utc3RhdGUgbWFwIGZyb20gdGhlIGxvYWRlZCBtZWV0aW5ncy5cclxuICAgKlxyXG4gICAqIFRPRE86IFJlcGxhY2UgbW9jayB3aXRoIHJlYWwgQVBJIGNhbGwgd2hlbiBCRSBpcyByZWFkeVxyXG4gICAqIEByZXR1cm4ge09ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPFVwY29taW5nRXZlbnRbXT4+fSBUaGUgdXBjb21pbmctZXZlbnRzIHJlc3BvbnNlIGVudmVsb3BlLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgbG9hZFVwY29taW5nRXZlbnRzKCk6IE9ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPFVwY29taW5nRXZlbnRbXT4+IHtcclxuICAgIHRoaXMudXBjb21pbmdTdGF0ZS5uZXh0KERhc2hib2FyZFNlY3Rpb25TdGF0ZS5MT0FESU5HKTtcclxuICAgIC8vIFRPRE86IFJlcGxhY2UgbW9jayB3aXRoIHJlYWwgQVBJIGNhbGwgd2hlbiBCRSBpcyByZWFkeVxyXG4gICAgY29uc3QgcmVzcG9uc2UkOiBPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTxVcGNvbWluZ0V2ZW50W10+PiA9IG9mKHtcclxuICAgICAgc3RhdHVzOiB0cnVlLFxyXG4gICAgICBib2R5OiBEYXNoYm9hcmRVcGNvbWluZ0V2ZW50c01vY2ssXHJcbiAgICB9KTtcclxuICAgIHJldHVybiByZXNwb25zZSQucGlwZShcclxuICAgICAgbWFwKChyZXNwb25zZSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IGV2ZW50cyA9IHJlc3BvbnNlPy5ib2R5ID8/IFtdO1xyXG4gICAgICAgIHRoaXMudXBjb21pbmdFdmVudHMubmV4dChldmVudHMpO1xyXG4gICAgICAgIHRoaXMuc2VlZEF0dGVuZGFuY2VTdGF0ZXMoZXZlbnRzKTtcclxuICAgICAgICB0aGlzLnVwY29taW5nU3RhdGUubmV4dChcclxuICAgICAgICAgIGV2ZW50cy5sZW5ndGggPiAwXHJcbiAgICAgICAgICAgID8gRGFzaGJvYXJkU2VjdGlvblN0YXRlLkxPQURFRFxyXG4gICAgICAgICAgICA6IERhc2hib2FyZFNlY3Rpb25TdGF0ZS5FTVBUWVxyXG4gICAgICAgICk7XHJcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICB9KSxcclxuICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcclxuICAgICAgICB0aGlzLnVwY29taW5nU3RhdGUubmV4dChEYXNoYm9hcmRTZWN0aW9uU3RhdGUuRVJST1IpO1xyXG4gICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICB9KVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExvYWRzIHRoZSB1c2VyJ3MgZ3JvdXBzLCBkcml2aW5nIHRoZSBncm91cHMgc2VjdGlvbiB0aHJvdWdoXHJcbiAgICogTE9BRElORyDihpIgTE9BREVEL0VNUFRZIG9uIHN1Y2Nlc3MgYW5kIGxlYXZpbmcgdGhlIGNhbGxlciB0byBzZXQgRVJST1Igb25cclxuICAgKiBmYWlsdXJlLiBGb2xsb3dzIHRoZSBgcGlwZShtYXAsIGNhdGNoRXJyb3IodGhyb3cpKWAgcGF0dGVybi5cclxuICAgKlxyXG4gICAqIFRPRE86IFJlcGxhY2UgbW9jayB3aXRoIHJlYWwgQVBJIGNhbGwgd2hlbiBCRSBpcyByZWFkeVxyXG4gICAqIEByZXR1cm4ge09ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPEdyb3VwUm93W10+Pn0gVGhlIGdyb3VwcyByZXNwb25zZSBlbnZlbG9wZS5cclxuICAgKiBAbWVtYmVyb2YgRGFzaGJvYXJkU2VydmljZVxyXG4gICAqL1xyXG4gIGxvYWRHcm91cHMoKTogT2JzZXJ2YWJsZTxEYXNoYm9hcmRMaXN0UmVzcG9uc2U8R3JvdXBSb3dbXT4+IHtcclxuICAgIHRoaXMuZ3JvdXBzU3RhdGUubmV4dChEYXNoYm9hcmRTZWN0aW9uU3RhdGUuTE9BRElORyk7XHJcbiAgICAvLyBUT0RPOiBSZXBsYWNlIG1vY2sgd2l0aCByZWFsIEFQSSBjYWxsIHdoZW4gQkUgaXMgcmVhZHlcclxuICAgIGNvbnN0IHJlc3BvbnNlJDogT2JzZXJ2YWJsZTxEYXNoYm9hcmRMaXN0UmVzcG9uc2U8R3JvdXBSb3dbXT4+ID0gb2Yoe1xyXG4gICAgICBzdGF0dXM6IHRydWUsXHJcbiAgICAgIGJvZHk6IERhc2hib2FyZEdyb3Vwc01vY2ssXHJcbiAgICB9KTtcclxuICAgIHJldHVybiByZXNwb25zZSQucGlwZShcclxuICAgICAgbWFwKChyZXNwb25zZSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IGdyb3VwcyA9IHJlc3BvbnNlPy5ib2R5ID8/IFtdO1xyXG4gICAgICAgIHRoaXMuZ3JvdXBzLm5leHQoZ3JvdXBzKTtcclxuICAgICAgICB0aGlzLmdyb3Vwc1N0YXRlLm5leHQoXHJcbiAgICAgICAgICBncm91cHMubGVuZ3RoID4gMFxyXG4gICAgICAgICAgICA/IERhc2hib2FyZFNlY3Rpb25TdGF0ZS5MT0FERURcclxuICAgICAgICAgICAgOiBEYXNoYm9hcmRTZWN0aW9uU3RhdGUuRU1QVFlcclxuICAgICAgICApO1xyXG4gICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgfSksXHJcbiAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XHJcbiAgICAgICAgdGhpcy5ncm91cHNTdGF0ZS5uZXh0KERhc2hib2FyZFNlY3Rpb25TdGF0ZS5FUlJPUik7XHJcbiAgICAgICAgdGhyb3cgZXJyb3I7XHJcbiAgICAgIH0pXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9ncyBhdHRlbmRhbmNlIGZvciBhIG1lZXRpbmcuIE1hcmtzIHRoZSBtZWV0aW5nIGluLWZsaWdodCAocmV0YWluaW5nIHRoZVxyXG4gICAqIHByaW9yIGRpc3BsYXllZCBzdGF0ZSksIHBvc3RzIHRocm91Z2ggYEh0dHBTZXJ2aWNlYCwgYXBwbGllcyB0aGVcclxuICAgKiBsb2ctYXR0ZW5kYW5jZS1zdWNjZXNzIHJlZHVjZXIgb24gc3VjY2VzcywgY2xlYXJzIHRoZSBpbi1mbGlnaHQgZmxhZyBvblxyXG4gICAqIGNvbXBsZXRpb24sIGFuZCByZXRocm93cyB3aGlsZSByZXRhaW5pbmcgcHJpb3Igc3RhdGUgb24gZmFpbHVyZS5cclxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVldGluZ0lkIC0gVGhlIG1lZXRpbmcgdG8gbG9nIGF0dGVuZGFuY2UgZm9yLlxyXG4gICAqIEByZXR1cm4ge09ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPHVua25vd24+Pn0gVGhlIGF0dGVuZGFuY2UgcmVzcG9uc2UgZW52ZWxvcGUuXHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBsb2dBdHRlbmRhbmNlKFxyXG4gICAgbWVldGluZ0lkOiBzdHJpbmdcclxuICApOiBPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj4ge1xyXG4gICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgYmVnaW5BdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICApO1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cFNlcnZpY2VcclxuICAgICAgLnBvc3REYXRhKGAke3RoaXMuYXBpQmFzZVVybH0vbWVldGluZ3MvYXR0ZW5kYW5jZS9sb2dgLCB7IG1lZXRpbmdJZCB9KVxyXG4gICAgICAucGlwZShcclxuICAgICAgICBtYXAoKHJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmF0dGVuZGFuY2VTdGF0ZXMubmV4dChcclxuICAgICAgICAgICAgYXBwbHlMb2dBdHRlbmRhbmNlU3VjY2Vzcyh0aGlzLmF0dGVuZGFuY2VTdGF0ZXMudmFsdWUsIG1lZXRpbmdJZClcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICB0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy5uZXh0KFxyXG4gICAgICAgICAgICBlbmRBdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAvLyBSZXRhaW4gcHJpb3IgYXR0ZW5kYW5jZSBzdGF0ZTsgb25seSBjbGVhciB0aGUgaW4tZmxpZ2h0IGZsYWcuXHJcbiAgICAgICAgICB0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy5uZXh0KFxyXG4gICAgICAgICAgICBlbmRBdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhyb3cgZXJyb3I7XHJcbiAgICAgICAgfSlcclxuICAgICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExlYXZlcyBhIG1lZXRpbmcuIE1hcmtzIHRoZSBtZWV0aW5nIGluLWZsaWdodCAocmV0YWluaW5nIHRoZSBwcmlvclxyXG4gICAqIGRpc3BsYXllZCBzdGF0ZSksIHBvc3RzIHRocm91Z2ggYEh0dHBTZXJ2aWNlYCwgYXBwbGllcyB0aGVcclxuICAgKiBsZWF2ZS1tZWV0aW5nLXN1Y2Nlc3MgcmVkdWNlciBvbiBzdWNjZXNzLCBjbGVhcnMgdGhlIGluLWZsaWdodCBmbGFnIG9uXHJcbiAgICogY29tcGxldGlvbiwgYW5kIHJldGhyb3dzIHdoaWxlIHJldGFpbmluZyBwcmlvciBzdGF0ZSBvbiBmYWlsdXJlLlxyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZWV0aW5nSWQgLSBUaGUgbWVldGluZyB0byBsZWF2ZS5cclxuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj59IFRoZSBhdHRlbmRhbmNlIHJlc3BvbnNlIGVudmVsb3BlLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgbGVhdmVNZWV0aW5nKFxyXG4gICAgbWVldGluZ0lkOiBzdHJpbmdcclxuICApOiBPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj4ge1xyXG4gICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgYmVnaW5BdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICApO1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cFNlcnZpY2VcclxuICAgICAgLnBvc3REYXRhKGAke3RoaXMuYXBpQmFzZVVybH0vbWVldGluZ3MvYXR0ZW5kYW5jZS9sZWF2ZWAsIHsgbWVldGluZ0lkIH0pXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIG1hcCgocmVzcG9uc2UpID0+IHtcclxuICAgICAgICAgIHRoaXMuYXR0ZW5kYW5jZVN0YXRlcy5uZXh0KFxyXG4gICAgICAgICAgICBhcHBseUxlYXZlTWVldGluZ1N1Y2Nlc3ModGhpcy5hdHRlbmRhbmNlU3RhdGVzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgICAgICAgZW5kQXR0ZW5kYW5jZUFjdGlvbih0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy52YWx1ZSwgbWVldGluZ0lkKVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICB9KSxcclxuICAgICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgLy8gUmV0YWluIHByaW9yIGF0dGVuZGFuY2Ugc3RhdGU7IG9ubHkgY2xlYXIgdGhlIGluLWZsaWdodCBmbGFnLlxyXG4gICAgICAgICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgICAgICAgZW5kQXR0ZW5kYW5jZUFjdGlvbih0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy52YWx1ZSwgbWVldGluZ0lkKVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm5zIGEgc3luY2hyb25vdXMgc25hcHNob3Qgb2YgdGhlIHBlci1tZWV0aW5nIGF0dGVuZGFuY2Utc3RhdGUgbWFwLlxyXG4gICAqIEByZXR1cm4ge1JlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT59IFRoZSBjdXJyZW50IGF0dGVuZGFuY2Utc3RhdGUgbWFwLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgZ2V0QXR0ZW5kYW5jZVN0YXRlc1NuYXBzaG90KCk6IFJlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT4ge1xyXG4gICAgcmV0dXJuIHRoaXMuYXR0ZW5kYW5jZVN0YXRlcy52YWx1ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNlZWRzIHRoZSBhdHRlbmRhbmNlLXN0YXRlIG1hcCBmcm9tIGEgZnJlc2hseSBsb2FkZWQgbGlzdCBvZiBldmVudHMsIHVzaW5nXHJcbiAgICogZWFjaCBtZWV0aW5nJ3MgYGF0dGVuZGFuY2VTdGF0ZWAgKGRlZmF1bHRpbmcgdG8gYE5PVF9BVFRFTkRJTkdgKS4gS2VlcHMgdGhlXHJcbiAgICogZGlzcGxheWVkIHN0YXRlIGluIHN5bmMgd2l0aCB0aGUgZGF0YSBsb2FkIHdpdGhvdXQgb3ZlcndyaXRpbmcgaWRzIHRoYXQgYXJlXHJcbiAgICogbm90IHByZXNlbnQgaW4gdGhlIG5ldyBsaXN0LlxyXG4gICAqIEBwYXJhbSB7VXBjb21pbmdFdmVudFtdfSBldmVudHMgLSBUaGUgbG9hZGVkIHVwY29taW5nIGV2ZW50cy5cclxuICAgKiBAcmV0dXJuIHt2b2lkfVxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBzZWVkQXR0ZW5kYW5jZVN0YXRlcyhldmVudHM6IFVwY29taW5nRXZlbnRbXSk6IHZvaWQge1xyXG4gICAgY29uc3QgbmV4dDogUmVjb3JkPHN0cmluZywgQXR0ZW5kYW5jZVN0YXRlPiA9IHtcclxuICAgICAgLi4udGhpcy5hdHRlbmRhbmNlU3RhdGVzLnZhbHVlLFxyXG4gICAgfTtcclxuICAgIGV2ZW50cy5mb3JFYWNoKChldmVudCkgPT4ge1xyXG4gICAgICBldmVudC5tZWV0aW5ncz8uZm9yRWFjaCgobWVldGluZykgPT4ge1xyXG4gICAgICAgIGlmIChtZWV0aW5nLm1lZXRpbmdJZCkge1xyXG4gICAgICAgICAgbmV4dFttZWV0aW5nLm1lZXRpbmdJZF0gPVxyXG4gICAgICAgICAgICBtZWV0aW5nLmF0dGVuZGFuY2VTdGF0ZSA/PyBBdHRlbmRhbmNlU3RhdGUuTk9UX0FUVEVORElORztcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgICB0aGlzLmF0dGVuZGFuY2VTdGF0ZXMubmV4dChuZXh0KTtcclxuICB9XHJcbn1cclxuIl19
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
/**
|
|
4
|
+
* Permission identifiers (by name) that gate the dashboard attendance actions.
|
|
5
|
+
* Mirrors the permission-type pattern used by the `events-and-meetings` and
|
|
6
|
+
* `groups` user-permissions services.
|
|
7
|
+
*/
|
|
8
|
+
/* eslint-disable no-unused-vars */
|
|
9
|
+
export var DashboardPermissionType;
|
|
10
|
+
(function (DashboardPermissionType) {
|
|
11
|
+
DashboardPermissionType["LOG_ATTENDANCE"] = "Log Attendance";
|
|
12
|
+
DashboardPermissionType["LEAVE_MEETING"] = "Leave Meeting";
|
|
13
|
+
})(DashboardPermissionType || (DashboardPermissionType = {}));
|
|
14
|
+
/* eslint-enable no-unused-vars */
|
|
15
|
+
export class UserPermissionsService {
|
|
16
|
+
/**
|
|
17
|
+
* Returns access provision for the passed action/feature based on whether the signed in user has appropriate permission.
|
|
18
|
+
* @param {DashboardPermissionType} permission
|
|
19
|
+
* @param {UserPermission[]} userPermissions
|
|
20
|
+
* @return {boolean}
|
|
21
|
+
* @memberof UserPermissionsService
|
|
22
|
+
*/
|
|
23
|
+
validateAccessPermission(permission, userPermissions) {
|
|
24
|
+
const isPermitted = userPermissions?.length > 0
|
|
25
|
+
? userPermissions?.some(({ permissionName }) => permissionName === permission)
|
|
26
|
+
: false;
|
|
27
|
+
return isPermitted;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Maps the host-supplied user permissions to the attendance-action permissions consumed by the dashboard rows.
|
|
31
|
+
* @param {UserPermission[]} userPermissions
|
|
32
|
+
* @return {AttendanceActionPermissions}
|
|
33
|
+
* @memberof UserPermissionsService
|
|
34
|
+
*/
|
|
35
|
+
mapToAttendanceActionPermissions(userPermissions) {
|
|
36
|
+
return {
|
|
37
|
+
canLogAttendance: this.validateAccessPermission(DashboardPermissionType.LOG_ATTENDANCE, userPermissions),
|
|
38
|
+
canLeaveMeeting: this.validateAccessPermission(DashboardPermissionType.LEAVE_MEETING, userPermissions),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UserPermissionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
42
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UserPermissionsService, providedIn: 'root' }); }
|
|
43
|
+
}
|
|
44
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UserPermissionsService, decorators: [{
|
|
45
|
+
type: Injectable,
|
|
46
|
+
args: [{
|
|
47
|
+
providedIn: 'root',
|
|
48
|
+
}]
|
|
49
|
+
}] });
|
|
50
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1wZXJtaXNzaW9ucy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZGFzaGJvYXJkL3NyYy9saWIvc2VydmljZXMvdXNlci1wZXJtaXNzaW9ucy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBSTNDOzs7O0dBSUc7QUFDSCxtQ0FBbUM7QUFDbkMsTUFBTSxDQUFOLElBQVksdUJBR1g7QUFIRCxXQUFZLHVCQUF1QjtJQUNqQyw0REFBaUMsQ0FBQTtJQUNqQywwREFBK0IsQ0FBQTtBQUNqQyxDQUFDLEVBSFcsdUJBQXVCLEtBQXZCLHVCQUF1QixRQUdsQztBQUNELGtDQUFrQztBQUtsQyxNQUFNLE9BQU8sc0JBQXNCO0lBQ2pDOzs7Ozs7T0FNRztJQUNILHdCQUF3QixDQUN0QixVQUFtQyxFQUNuQyxlQUFpQztRQUVqQyxNQUFNLFdBQVcsR0FDZixlQUFlLEVBQUUsTUFBTSxHQUFHLENBQUM7WUFDekIsQ0FBQyxDQUFDLGVBQWUsRUFBRSxJQUFJLENBQ25CLENBQUMsRUFBRSxjQUFjLEVBQUUsRUFBRSxFQUFFLENBQUMsY0FBYyxLQUFLLFVBQVUsQ0FDdEQ7WUFDSCxDQUFDLENBQUMsS0FBSyxDQUFDO1FBQ1osT0FBTyxXQUFXLENBQUM7SUFDckIsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsZ0NBQWdDLENBQzlCLGVBQWlDO1FBRWpDLE9BQU87WUFDTCxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsd0JBQXdCLENBQzdDLHVCQUF1QixDQUFDLGNBQWMsRUFDdEMsZUFBZSxDQUNoQjtZQUNELGVBQWUsRUFBRSxJQUFJLENBQUMsd0JBQXdCLENBQzVDLHVCQUF1QixDQUFDLGFBQWEsRUFDckMsZUFBZSxDQUNoQjtTQUNGLENBQUM7SUFDSixDQUFDOytHQXhDVSxzQkFBc0I7bUhBQXRCLHNCQUFzQixjQUZyQixNQUFNOzs0RkFFUCxzQkFBc0I7a0JBSGxDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBVc2VyUGVybWlzc2lvbiB9IGZyb20gJ0BpZWVlc2EtbnBtL21vZGVscyc7XHJcbmltcG9ydCB7IEF0dGVuZGFuY2VBY3Rpb25QZXJtaXNzaW9ucyB9IGZyb20gJy4uL21vZGVscy9hdHRlbmRhbmNlLWFjdGlvbi1wZXJtaXNzaW9ucy5tb2RlbCc7XHJcblxyXG4vKipcclxuICogUGVybWlzc2lvbiBpZGVudGlmaWVycyAoYnkgbmFtZSkgdGhhdCBnYXRlIHRoZSBkYXNoYm9hcmQgYXR0ZW5kYW5jZSBhY3Rpb25zLlxyXG4gKiBNaXJyb3JzIHRoZSBwZXJtaXNzaW9uLXR5cGUgcGF0dGVybiB1c2VkIGJ5IHRoZSBgZXZlbnRzLWFuZC1tZWV0aW5nc2AgYW5kXHJcbiAqIGBncm91cHNgIHVzZXItcGVybWlzc2lvbnMgc2VydmljZXMuXHJcbiAqL1xyXG4vKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtdmFycyAqL1xyXG5leHBvcnQgZW51bSBEYXNoYm9hcmRQZXJtaXNzaW9uVHlwZSB7XHJcbiAgTE9HX0FUVEVOREFOQ0UgPSAnTG9nIEF0dGVuZGFuY2UnLFxyXG4gIExFQVZFX01FRVRJTkcgPSAnTGVhdmUgTWVldGluZycsXHJcbn1cclxuLyogZXNsaW50LWVuYWJsZSBuby11bnVzZWQtdmFycyAqL1xyXG5cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIFVzZXJQZXJtaXNzaW9uc1NlcnZpY2Uge1xyXG4gIC8qKlxyXG4gICAqIFJldHVybnMgYWNjZXNzIHByb3Zpc2lvbiBmb3IgdGhlIHBhc3NlZCBhY3Rpb24vZmVhdHVyZSBiYXNlZCBvbiB3aGV0aGVyIHRoZSBzaWduZWQgaW4gdXNlciBoYXMgYXBwcm9wcmlhdGUgcGVybWlzc2lvbi5cclxuICAgKiBAcGFyYW0ge0Rhc2hib2FyZFBlcm1pc3Npb25UeXBlfSBwZXJtaXNzaW9uXHJcbiAgICogQHBhcmFtIHtVc2VyUGVybWlzc2lvbltdfSB1c2VyUGVybWlzc2lvbnNcclxuICAgKiBAcmV0dXJuIHtib29sZWFufVxyXG4gICAqIEBtZW1iZXJvZiBVc2VyUGVybWlzc2lvbnNTZXJ2aWNlXHJcbiAgICovXHJcbiAgdmFsaWRhdGVBY2Nlc3NQZXJtaXNzaW9uKFxyXG4gICAgcGVybWlzc2lvbjogRGFzaGJvYXJkUGVybWlzc2lvblR5cGUsXHJcbiAgICB1c2VyUGVybWlzc2lvbnM6IFVzZXJQZXJtaXNzaW9uW11cclxuICApOiBib29sZWFuIHtcclxuICAgIGNvbnN0IGlzUGVybWl0dGVkID1cclxuICAgICAgdXNlclBlcm1pc3Npb25zPy5sZW5ndGggPiAwXHJcbiAgICAgICAgPyB1c2VyUGVybWlzc2lvbnM/LnNvbWUoXHJcbiAgICAgICAgICAgICh7IHBlcm1pc3Npb25OYW1lIH0pID0+IHBlcm1pc3Npb25OYW1lID09PSBwZXJtaXNzaW9uXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgOiBmYWxzZTtcclxuICAgIHJldHVybiBpc1Blcm1pdHRlZDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1hcHMgdGhlIGhvc3Qtc3VwcGxpZWQgdXNlciBwZXJtaXNzaW9ucyB0byB0aGUgYXR0ZW5kYW5jZS1hY3Rpb24gcGVybWlzc2lvbnMgY29uc3VtZWQgYnkgdGhlIGRhc2hib2FyZCByb3dzLlxyXG4gICAqIEBwYXJhbSB7VXNlclBlcm1pc3Npb25bXX0gdXNlclBlcm1pc3Npb25zXHJcbiAgICogQHJldHVybiB7QXR0ZW5kYW5jZUFjdGlvblBlcm1pc3Npb25zfVxyXG4gICAqIEBtZW1iZXJvZiBVc2VyUGVybWlzc2lvbnNTZXJ2aWNlXHJcbiAgICovXHJcbiAgbWFwVG9BdHRlbmRhbmNlQWN0aW9uUGVybWlzc2lvbnMoXHJcbiAgICB1c2VyUGVybWlzc2lvbnM6IFVzZXJQZXJtaXNzaW9uW11cclxuICApOiBBdHRlbmRhbmNlQWN0aW9uUGVybWlzc2lvbnMge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgY2FuTG9nQXR0ZW5kYW5jZTogdGhpcy52YWxpZGF0ZUFjY2Vzc1Blcm1pc3Npb24oXHJcbiAgICAgICAgRGFzaGJvYXJkUGVybWlzc2lvblR5cGUuTE9HX0FUVEVOREFOQ0UsXHJcbiAgICAgICAgdXNlclBlcm1pc3Npb25zXHJcbiAgICAgICksXHJcbiAgICAgIGNhbkxlYXZlTWVldGluZzogdGhpcy52YWxpZGF0ZUFjY2Vzc1Blcm1pc3Npb24oXHJcbiAgICAgICAgRGFzaGJvYXJkUGVybWlzc2lvblR5cGUuTEVBVkVfTUVFVElORyxcclxuICAgICAgICB1c2VyUGVybWlzc2lvbnNcclxuICAgICAgKSxcclxuICAgIH07XHJcbiAgfVxyXG59XHJcbiJdfQ==
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers for the per-meeting attendance action state machine. No Angular /
|
|
3
|
+
* service dependencies so they are trivially testable (property-tested as
|
|
4
|
+
* Property 1) and reusable by `MeetingAttendanceRowComponent`.
|
|
5
|
+
*
|
|
6
|
+
* The handler is the single source of truth for what a meeting row's action
|
|
7
|
+
* button should emit when activated. The displayed `AttendanceState` only
|
|
8
|
+
* advances on a successful resolution (handled by the service reducers), so this
|
|
9
|
+
* function is a pure mapping from the current inputs to the action to emit.
|
|
10
|
+
*/
|
|
11
|
+
import { AttendanceState } from '../models/attendance-state.model';
|
|
12
|
+
/* eslint-disable no-unused-vars */
|
|
13
|
+
/**
|
|
14
|
+
* The action a meeting row's action button should emit when activated.
|
|
15
|
+
* `NONE` means the activation is non-actionable (empty id or in-flight) and the
|
|
16
|
+
* row must emit no `logAttendance` / `leaveMeeting` / navigation event.
|
|
17
|
+
*/
|
|
18
|
+
export var AttendanceAction;
|
|
19
|
+
(function (AttendanceAction) {
|
|
20
|
+
AttendanceAction["LOG_ATTENDANCE"] = "LOG_ATTENDANCE";
|
|
21
|
+
AttendanceAction["LEAVE_MEETING"] = "LEAVE_MEETING";
|
|
22
|
+
AttendanceAction["NONE"] = "NONE";
|
|
23
|
+
})(AttendanceAction || (AttendanceAction = {}));
|
|
24
|
+
/* eslint-enable no-unused-vars */
|
|
25
|
+
/**
|
|
26
|
+
* Resolves the attendance action to emit for a meeting row, following the
|
|
27
|
+
* attendance action state machine (see design: Attendance Action State Machine).
|
|
28
|
+
*
|
|
29
|
+
* Behavior:
|
|
30
|
+
* - Returns `NONE` when `meetingId` is empty or undefined (non-actionable row).
|
|
31
|
+
* - Returns `NONE` while the row is in-flight (re-entrancy guard — no further
|
|
32
|
+
* event is emitted until the current action resolves).
|
|
33
|
+
* - Returns `LEAVE_MEETING` when the state is `CURRENTLY_ATTENDING`.
|
|
34
|
+
* - Returns `LOG_ATTENDANCE` when the state is `NOT_ATTENDING` or undefined.
|
|
35
|
+
*
|
|
36
|
+
* @param {AttendanceState | undefined} attendanceState The row's current attendance state.
|
|
37
|
+
* @param {boolean} isInFlight Whether an attendance action for this row is awaiting resolution.
|
|
38
|
+
* @param {string | undefined} meetingId The row's meeting identifier.
|
|
39
|
+
* @return {AttendanceAction} The action to emit, or `NONE` when non-actionable.
|
|
40
|
+
*/
|
|
41
|
+
export function resolveAttendanceAction(attendanceState, isInFlight, meetingId) {
|
|
42
|
+
if (!meetingId) {
|
|
43
|
+
return AttendanceAction.NONE;
|
|
44
|
+
}
|
|
45
|
+
if (isInFlight) {
|
|
46
|
+
return AttendanceAction.NONE;
|
|
47
|
+
}
|
|
48
|
+
if (attendanceState === AttendanceState.CURRENTLY_ATTENDING) {
|
|
49
|
+
return AttendanceAction.LEAVE_MEETING;
|
|
50
|
+
}
|
|
51
|
+
return AttendanceAction.LOG_ATTENDANCE;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0ZW5kYW5jZS1hY3Rpb24udXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Rhc2hib2FyZC9zcmMvbGliL3V0aWxzL2F0dGVuZGFuY2UtYWN0aW9uLnV0aWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7OztHQVNHO0FBQ0gsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBRW5FLG1DQUFtQztBQUNuQzs7OztHQUlHO0FBQ0gsTUFBTSxDQUFOLElBQVksZ0JBSVg7QUFKRCxXQUFZLGdCQUFnQjtJQUMxQixxREFBaUMsQ0FBQTtJQUNqQyxtREFBK0IsQ0FBQTtJQUMvQixpQ0FBYSxDQUFBO0FBQ2YsQ0FBQyxFQUpXLGdCQUFnQixLQUFoQixnQkFBZ0IsUUFJM0I7QUFDRCxrQ0FBa0M7QUFFbEM7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gsTUFBTSxVQUFVLHVCQUF1QixDQUNyQyxlQUE0QyxFQUM1QyxVQUFtQixFQUNuQixTQUE2QjtJQUU3QixJQUFJLENBQUMsU0FBUyxFQUFFO1FBQ2QsT0FBTyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUM7S0FDOUI7SUFFRCxJQUFJLFVBQVUsRUFBRTtRQUNkLE9BQU8sZ0JBQWdCLENBQUMsSUFBSSxDQUFDO0tBQzlCO0lBRUQsSUFBSSxlQUFlLEtBQUssZUFBZSxDQUFDLG1CQUFtQixFQUFFO1FBQzNELE9BQU8sZ0JBQWdCLENBQUMsYUFBYSxDQUFDO0tBQ3ZDO0lBRUQsT0FBTyxnQkFBZ0IsQ0FBQyxjQUFjLENBQUM7QUFDekMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxyXG4gKiBQdXJlIGhlbHBlcnMgZm9yIHRoZSBwZXItbWVldGluZyBhdHRlbmRhbmNlIGFjdGlvbiBzdGF0ZSBtYWNoaW5lLiBObyBBbmd1bGFyIC9cclxuICogc2VydmljZSBkZXBlbmRlbmNpZXMgc28gdGhleSBhcmUgdHJpdmlhbGx5IHRlc3RhYmxlIChwcm9wZXJ0eS10ZXN0ZWQgYXNcclxuICogUHJvcGVydHkgMSkgYW5kIHJldXNhYmxlIGJ5IGBNZWV0aW5nQXR0ZW5kYW5jZVJvd0NvbXBvbmVudGAuXHJcbiAqXHJcbiAqIFRoZSBoYW5kbGVyIGlzIHRoZSBzaW5nbGUgc291cmNlIG9mIHRydXRoIGZvciB3aGF0IGEgbWVldGluZyByb3cncyBhY3Rpb25cclxuICogYnV0dG9uIHNob3VsZCBlbWl0IHdoZW4gYWN0aXZhdGVkLiBUaGUgZGlzcGxheWVkIGBBdHRlbmRhbmNlU3RhdGVgIG9ubHlcclxuICogYWR2YW5jZXMgb24gYSBzdWNjZXNzZnVsIHJlc29sdXRpb24gKGhhbmRsZWQgYnkgdGhlIHNlcnZpY2UgcmVkdWNlcnMpLCBzbyB0aGlzXHJcbiAqIGZ1bmN0aW9uIGlzIGEgcHVyZSBtYXBwaW5nIGZyb20gdGhlIGN1cnJlbnQgaW5wdXRzIHRvIHRoZSBhY3Rpb24gdG8gZW1pdC5cclxuICovXHJcbmltcG9ydCB7IEF0dGVuZGFuY2VTdGF0ZSB9IGZyb20gJy4uL21vZGVscy9hdHRlbmRhbmNlLXN0YXRlLm1vZGVsJztcclxuXHJcbi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXHJcbi8qKlxyXG4gKiBUaGUgYWN0aW9uIGEgbWVldGluZyByb3cncyBhY3Rpb24gYnV0dG9uIHNob3VsZCBlbWl0IHdoZW4gYWN0aXZhdGVkLlxyXG4gKiBgTk9ORWAgbWVhbnMgdGhlIGFjdGl2YXRpb24gaXMgbm9uLWFjdGlvbmFibGUgKGVtcHR5IGlkIG9yIGluLWZsaWdodCkgYW5kIHRoZVxyXG4gKiByb3cgbXVzdCBlbWl0IG5vIGBsb2dBdHRlbmRhbmNlYCAvIGBsZWF2ZU1lZXRpbmdgIC8gbmF2aWdhdGlvbiBldmVudC5cclxuICovXHJcbmV4cG9ydCBlbnVtIEF0dGVuZGFuY2VBY3Rpb24ge1xyXG4gIExPR19BVFRFTkRBTkNFID0gJ0xPR19BVFRFTkRBTkNFJyxcclxuICBMRUFWRV9NRUVUSU5HID0gJ0xFQVZFX01FRVRJTkcnLFxyXG4gIE5PTkUgPSAnTk9ORScsXHJcbn1cclxuLyogZXNsaW50LWVuYWJsZSBuby11bnVzZWQtdmFycyAqL1xyXG5cclxuLyoqXHJcbiAqIFJlc29sdmVzIHRoZSBhdHRlbmRhbmNlIGFjdGlvbiB0byBlbWl0IGZvciBhIG1lZXRpbmcgcm93LCBmb2xsb3dpbmcgdGhlXHJcbiAqIGF0dGVuZGFuY2UgYWN0aW9uIHN0YXRlIG1hY2hpbmUgKHNlZSBkZXNpZ246IEF0dGVuZGFuY2UgQWN0aW9uIFN0YXRlIE1hY2hpbmUpLlxyXG4gKlxyXG4gKiBCZWhhdmlvcjpcclxuICogLSBSZXR1cm5zIGBOT05FYCB3aGVuIGBtZWV0aW5nSWRgIGlzIGVtcHR5IG9yIHVuZGVmaW5lZCAobm9uLWFjdGlvbmFibGUgcm93KS5cclxuICogLSBSZXR1cm5zIGBOT05FYCB3aGlsZSB0aGUgcm93IGlzIGluLWZsaWdodCAocmUtZW50cmFuY3kgZ3VhcmQg4oCUIG5vIGZ1cnRoZXJcclxuICogICBldmVudCBpcyBlbWl0dGVkIHVudGlsIHRoZSBjdXJyZW50IGFjdGlvbiByZXNvbHZlcykuXHJcbiAqIC0gUmV0dXJucyBgTEVBVkVfTUVFVElOR2Agd2hlbiB0aGUgc3RhdGUgaXMgYENVUlJFTlRMWV9BVFRFTkRJTkdgLlxyXG4gKiAtIFJldHVybnMgYExPR19BVFRFTkRBTkNFYCB3aGVuIHRoZSBzdGF0ZSBpcyBgTk9UX0FUVEVORElOR2Agb3IgdW5kZWZpbmVkLlxyXG4gKlxyXG4gKiBAcGFyYW0ge0F0dGVuZGFuY2VTdGF0ZSB8IHVuZGVmaW5lZH0gYXR0ZW5kYW5jZVN0YXRlIFRoZSByb3cncyBjdXJyZW50IGF0dGVuZGFuY2Ugc3RhdGUuXHJcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNJbkZsaWdodCBXaGV0aGVyIGFuIGF0dGVuZGFuY2UgYWN0aW9uIGZvciB0aGlzIHJvdyBpcyBhd2FpdGluZyByZXNvbHV0aW9uLlxyXG4gKiBAcGFyYW0ge3N0cmluZyB8IHVuZGVmaW5lZH0gbWVldGluZ0lkIFRoZSByb3cncyBtZWV0aW5nIGlkZW50aWZpZXIuXHJcbiAqIEByZXR1cm4ge0F0dGVuZGFuY2VBY3Rpb259IFRoZSBhY3Rpb24gdG8gZW1pdCwgb3IgYE5PTkVgIHdoZW4gbm9uLWFjdGlvbmFibGUuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUF0dGVuZGFuY2VBY3Rpb24oXHJcbiAgYXR0ZW5kYW5jZVN0YXRlOiBBdHRlbmRhbmNlU3RhdGUgfCB1bmRlZmluZWQsXHJcbiAgaXNJbkZsaWdodDogYm9vbGVhbixcclxuICBtZWV0aW5nSWQ6IHN0cmluZyB8IHVuZGVmaW5lZFxyXG4pOiBBdHRlbmRhbmNlQWN0aW9uIHtcclxuICBpZiAoIW1lZXRpbmdJZCkge1xyXG4gICAgcmV0dXJuIEF0dGVuZGFuY2VBY3Rpb24uTk9ORTtcclxuICB9XHJcblxyXG4gIGlmIChpc0luRmxpZ2h0KSB7XHJcbiAgICByZXR1cm4gQXR0ZW5kYW5jZUFjdGlvbi5OT05FO1xyXG4gIH1cclxuXHJcbiAgaWYgKGF0dGVuZGFuY2VTdGF0ZSA9PT0gQXR0ZW5kYW5jZVN0YXRlLkNVUlJFTlRMWV9BVFRFTkRJTkcpIHtcclxuICAgIHJldHVybiBBdHRlbmRhbmNlQWN0aW9uLkxFQVZFX01FRVRJTkc7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gQXR0ZW5kYW5jZUFjdGlvbi5MT0dfQVRURU5EQU5DRTtcclxufVxyXG4iXX0=
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Public API Surface of dashboard
|
|
3
|
+
*/
|
|
4
|
+
// Container component + navigation intent type (DashboardComponent, DashboardNavigationIntent)
|
|
5
|
+
export * from './lib/dashboard.component';
|
|
6
|
+
// Child components
|
|
7
|
+
export * from './lib/components/welcome-header/dashboard-welcome-header.component';
|
|
8
|
+
export * from './lib/components/upcoming-meetings-events/upcoming-meetings-events.component';
|
|
9
|
+
export * from './lib/components/event-group-card/event-group-card.component';
|
|
10
|
+
export * from './lib/components/meeting-attendance-row/meeting-attendance-row.component';
|
|
11
|
+
export * from './lib/components/your-groups/your-groups.component';
|
|
12
|
+
export * from './lib/components/member-level-badge/member-level-badge.component';
|
|
13
|
+
// Module + routes
|
|
14
|
+
export * from './lib/dashboard.module';
|
|
15
|
+
export * from './lib/dashboard.routes';
|
|
16
|
+
// Models
|
|
17
|
+
export * from './lib/models/dashboard-route-config.model';
|
|
18
|
+
export * from './lib/models/attendance-state.model';
|
|
19
|
+
export * from './lib/models/dashboard-section-state.model';
|
|
20
|
+
export * from './lib/models/page-change.model';
|
|
21
|
+
export * from './lib/models/dashboard-user-info.model';
|
|
22
|
+
export * from './lib/models/meeting-row.model';
|
|
23
|
+
export * from './lib/models/upcoming-event.model';
|
|
24
|
+
export * from './lib/models/group-row.model';
|
|
25
|
+
export * from './lib/models/attendance-action-permissions.model';
|
|
26
|
+
export * from './lib/models/dashboard-list-response.model';
|
|
27
|
+
// Services
|
|
28
|
+
export * from './lib/services/dashboard.service';
|
|
29
|
+
export * from './lib/services/user-permissions.service';
|
|
30
|
+
// Asset mocks consumed by the demo app
|
|
31
|
+
export * from './lib/assets/dashboard-route-paths.mock';
|
|
32
|
+
export * from './lib/assets/dashboard-user-permissions.mock';
|
|
33
|
+
export * from './lib/assets/dashboard-mock';
|
|
34
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL2Rhc2hib2FyZC9zcmMvcHVibGljLWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILCtGQUErRjtBQUMvRixjQUFjLDJCQUEyQixDQUFDO0FBRTFDLG1CQUFtQjtBQUNuQixjQUFjLG9FQUFvRSxDQUFDO0FBQ25GLGNBQWMsOEVBQThFLENBQUM7QUFDN0YsY0FBYyw4REFBOEQsQ0FBQztBQUM3RSxjQUFjLDBFQUEwRSxDQUFDO0FBQ3pGLGNBQWMsb0RBQW9ELENBQUM7QUFDbkUsY0FBYyxrRUFBa0UsQ0FBQztBQUVqRixrQkFBa0I7QUFDbEIsY0FBYyx3QkFBd0IsQ0FBQztBQUN2QyxjQUFjLHdCQUF3QixDQUFDO0FBRXZDLFNBQVM7QUFDVCxjQUFjLDJDQUEyQyxDQUFDO0FBQzFELGNBQWMscUNBQXFDLENBQUM7QUFDcEQsY0FBYyw0Q0FBNEMsQ0FBQztBQUMzRCxjQUFjLGdDQUFnQyxDQUFDO0FBQy9DLGNBQWMsd0NBQXdDLENBQUM7QUFDdkQsY0FBYyxnQ0FBZ0MsQ0FBQztBQUMvQyxjQUFjLG1DQUFtQyxDQUFDO0FBQ2xELGNBQWMsOEJBQThCLENBQUM7QUFDN0MsY0FBYyxrREFBa0QsQ0FBQztBQUNqRSxjQUFjLDRDQUE0QyxDQUFDO0FBRTNELFdBQVc7QUFDWCxjQUFjLGtDQUFrQyxDQUFDO0FBQ2pELGNBQWMseUNBQXlDLENBQUM7QUFFeEQsdUNBQXVDO0FBQ3ZDLGNBQWMseUNBQXlDLENBQUM7QUFDeEQsY0FBYyw4Q0FBOEMsQ0FBQztBQUM3RCxjQUFjLDZCQUE2QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcclxuICogUHVibGljIEFQSSBTdXJmYWNlIG9mIGRhc2hib2FyZFxyXG4gKi9cclxuXHJcbi8vIENvbnRhaW5lciBjb21wb25lbnQgKyBuYXZpZ2F0aW9uIGludGVudCB0eXBlIChEYXNoYm9hcmRDb21wb25lbnQsIERhc2hib2FyZE5hdmlnYXRpb25JbnRlbnQpXHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL2Rhc2hib2FyZC5jb21wb25lbnQnO1xyXG5cclxuLy8gQ2hpbGQgY29tcG9uZW50c1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb21wb25lbnRzL3dlbGNvbWUtaGVhZGVyL2Rhc2hib2FyZC13ZWxjb21lLWhlYWRlci5jb21wb25lbnQnO1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb21wb25lbnRzL3VwY29taW5nLW1lZXRpbmdzLWV2ZW50cy91cGNvbWluZy1tZWV0aW5ncy1ldmVudHMuY29tcG9uZW50JztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvY29tcG9uZW50cy9ldmVudC1ncm91cC1jYXJkL2V2ZW50LWdyb3VwLWNhcmQuY29tcG9uZW50JztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvY29tcG9uZW50cy9tZWV0aW5nLWF0dGVuZGFuY2Utcm93L21lZXRpbmctYXR0ZW5kYW5jZS1yb3cuY29tcG9uZW50JztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvY29tcG9uZW50cy95b3VyLWdyb3Vwcy95b3VyLWdyb3Vwcy5jb21wb25lbnQnO1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb21wb25lbnRzL21lbWJlci1sZXZlbC1iYWRnZS9tZW1iZXItbGV2ZWwtYmFkZ2UuY29tcG9uZW50JztcclxuXHJcbi8vIE1vZHVsZSArIHJvdXRlc1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9kYXNoYm9hcmQubW9kdWxlJztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvZGFzaGJvYXJkLnJvdXRlcyc7XHJcblxyXG4vLyBNb2RlbHNcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvbW9kZWxzL2Rhc2hib2FyZC1yb3V0ZS1jb25maWcubW9kZWwnO1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9tb2RlbHMvYXR0ZW5kYW5jZS1zdGF0ZS5tb2RlbCc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL21vZGVscy9kYXNoYm9hcmQtc2VjdGlvbi1zdGF0ZS5tb2RlbCc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL21vZGVscy9wYWdlLWNoYW5nZS5tb2RlbCc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL21vZGVscy9kYXNoYm9hcmQtdXNlci1pbmZvLm1vZGVsJztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvbW9kZWxzL21lZXRpbmctcm93Lm1vZGVsJztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvbW9kZWxzL3VwY29taW5nLWV2ZW50Lm1vZGVsJztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvbW9kZWxzL2dyb3VwLXJvdy5tb2RlbCc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL21vZGVscy9hdHRlbmRhbmNlLWFjdGlvbi1wZXJtaXNzaW9ucy5tb2RlbCc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL21vZGVscy9kYXNoYm9hcmQtbGlzdC1yZXNwb25zZS5tb2RlbCc7XHJcblxyXG4vLyBTZXJ2aWNlc1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9zZXJ2aWNlcy9kYXNoYm9hcmQuc2VydmljZSc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL3NlcnZpY2VzL3VzZXItcGVybWlzc2lvbnMuc2VydmljZSc7XHJcblxyXG4vLyBBc3NldCBtb2NrcyBjb25zdW1lZCBieSB0aGUgZGVtbyBhcHBcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvYXNzZXRzL2Rhc2hib2FyZC1yb3V0ZS1wYXRocy5tb2NrJztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvYXNzZXRzL2Rhc2hib2FyZC11c2VyLXBlcm1pc3Npb25zLm1vY2snO1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9hc3NldHMvZGFzaGJvYXJkLW1vY2snO1xyXG4iXX0=
|