@ieeesa-npm/groups 0.15.3 → 0.15.4
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/esm2022/lib/assets/constants.json +32 -0
- package/esm2022/lib/components/view-roster/view-roster.component.mjs +47 -7
- package/esm2022/lib/services/roster-export.service.mjs +396 -0
- package/esm2022/public-api.mjs +2 -1
- package/fesm2022/ieeesa-npm-groups.mjs +466 -10
- package/fesm2022/ieeesa-npm-groups.mjs.map +1 -1
- package/lib/components/view-roster/view-roster.component.d.ts +16 -2
- package/lib/services/groups.service.d.ts +1 -13
- package/lib/services/roster-export.service.d.ts +171 -0
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
|
@@ -2,7 +2,7 @@ import { AfterViewInit, ChangeDetectorRef, OnDestroy, OnInit } from '@angular/co
|
|
|
2
2
|
import { Subject } from 'rxjs';
|
|
3
3
|
import { Sort } from '@angular/material/sort';
|
|
4
4
|
import { MatDialog } from '@angular/material/dialog';
|
|
5
|
-
import { TableColumnSchema, TableActions, AlignType, ChipOption, CheckboxOption, FiltersAndOptions } from '@ieeesa-npm/presentation';
|
|
5
|
+
import { TableColumnSchema, TableActions, AlignType, ChipOption, CheckboxOption, FiltersAndOptions, ExportFormat } from '@ieeesa-npm/presentation';
|
|
6
6
|
import { AlertsService, GlobalErrorHandlerService } from '@ieeesa-npm/utility';
|
|
7
7
|
import { AlertType } from '@ieeesa-npm/models';
|
|
8
8
|
import { GroupsService } from '../../services/groups.service';
|
|
@@ -10,6 +10,7 @@ import { User, LoggedInUserInfo } from '../../models/user.model';
|
|
|
10
10
|
import { GroupUserInfo } from '../../models/group-user-info.model';
|
|
11
11
|
import { GroupRosterType } from '../../models/roster-type.model';
|
|
12
12
|
import { FilterType } from '../../models/filter-type.model';
|
|
13
|
+
import { RosterExportService } from '../../services/roster-export.service';
|
|
13
14
|
import * as i0 from "@angular/core";
|
|
14
15
|
/**
|
|
15
16
|
* ViewRosterComponent implements the functionalities to add, edit, delete user to group roster, assign and modify roles(s) to the group users, and search user from roster.
|
|
@@ -23,6 +24,7 @@ export declare class ViewRosterComponent implements AfterViewInit, OnDestroy, On
|
|
|
23
24
|
private alertService;
|
|
24
25
|
private cdr;
|
|
25
26
|
private globalErrorHandlerService;
|
|
27
|
+
rosterExportService: RosterExportService;
|
|
26
28
|
destroy$: Subject<boolean>;
|
|
27
29
|
constants: any;
|
|
28
30
|
viewRosterConstants: any;
|
|
@@ -53,7 +55,7 @@ export declare class ViewRosterComponent implements AfterViewInit, OnDestroy, On
|
|
|
53
55
|
tableColumnsForSystemUsers: any;
|
|
54
56
|
emptyFieldValueReplacedBy: any;
|
|
55
57
|
userInfo: LoggedInUserInfo;
|
|
56
|
-
constructor(dialog: MatDialog, groupService: GroupsService, alertService: AlertsService, cdr: ChangeDetectorRef, globalErrorHandlerService: GlobalErrorHandlerService);
|
|
58
|
+
constructor(dialog: MatDialog, groupService: GroupsService, alertService: AlertsService, cdr: ChangeDetectorRef, globalErrorHandlerService: GlobalErrorHandlerService, rosterExportService: RosterExportService);
|
|
57
59
|
ngOnInit(): void;
|
|
58
60
|
/**
|
|
59
61
|
* Show add new user success message when canShowMessage is set true
|
|
@@ -159,6 +161,18 @@ export declare class ViewRosterComponent implements AfterViewInit, OnDestroy, On
|
|
|
159
161
|
* @memberof ViewRosterComponent
|
|
160
162
|
*/
|
|
161
163
|
showAlertMessage(message: string | string[], alertType: AlertType): void;
|
|
164
|
+
/**
|
|
165
|
+
* Toggles the export format popover — delegates to RosterExportService.
|
|
166
|
+
* @memberof ViewRosterComponent
|
|
167
|
+
*/
|
|
168
|
+
onExportClick(): void;
|
|
169
|
+
/**
|
|
170
|
+
* Handles export format selection — delegates to RosterExportService using the
|
|
171
|
+
* currently selected group's id and name.
|
|
172
|
+
* @param {ExportFormat} format
|
|
173
|
+
* @memberof ViewRosterComponent
|
|
174
|
+
*/
|
|
175
|
+
onExportFormatSelected(format: ExportFormat): void;
|
|
162
176
|
/**
|
|
163
177
|
* NgOnDestroy performs necessary cleanup tasks, such as unsubscribing from subscription when the component is being destroyed.
|
|
164
178
|
* @memberof ViewRosterComponent
|
|
@@ -46,14 +46,6 @@ export declare class GroupsService {
|
|
|
46
46
|
"1006": string;
|
|
47
47
|
"1007": string;
|
|
48
48
|
"1008": string;
|
|
49
|
-
/**
|
|
50
|
-
* Handles custom API errors: maps BE error codes to messages and shows an
|
|
51
|
-
* alert. Mirrors the events-and-meetings error handling so reciprocal-credit
|
|
52
|
-
* failures (e.g. MTG-011 duplicate, MTG-012 permission) surface consistently.
|
|
53
|
-
* @param {*} error the HttpErrorResponse from a failed call
|
|
54
|
-
* @param {boolean} [showAlert=true] whether to display the alert
|
|
55
|
-
* @memberof GroupsService
|
|
56
|
-
*/
|
|
57
49
|
"1009": string;
|
|
58
50
|
"1010": string;
|
|
59
51
|
"1011": string;
|
|
@@ -86,11 +78,7 @@ export declare class GroupsService {
|
|
|
86
78
|
"1038": string;
|
|
87
79
|
"1039": string;
|
|
88
80
|
"2001": string;
|
|
89
|
-
"2002": string;
|
|
90
|
-
* Sets group function type.
|
|
91
|
-
* @param {GroupFunctionType} groupFunctionType -group function type.
|
|
92
|
-
* @memberof GroupsService
|
|
93
|
-
*/
|
|
81
|
+
"2002": string;
|
|
94
82
|
"2010": string;
|
|
95
83
|
"2011": string;
|
|
96
84
|
"20l2": string;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { HttpClient } from '@angular/common/http';
|
|
2
|
+
import { MatDialog } from '@angular/material/dialog';
|
|
3
|
+
import { ExportFormat, ExportFormatOption } from '@ieeesa-npm/presentation';
|
|
4
|
+
import { AlertsService } from '@ieeesa-npm/utility';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
/**
|
|
7
|
+
* RosterExportService owns the complete group roster export flow:
|
|
8
|
+
* 1. Manages export popover open/close state
|
|
9
|
+
* 2. Opens IEEE Data Access and Use Policy confirmation dialog
|
|
10
|
+
* 3. Calls the backend roster export API (blob response)
|
|
11
|
+
* 4. Triggers file download via File System Access API / file-saver
|
|
12
|
+
* 5. Shows success/error dialogs and toasts
|
|
13
|
+
*
|
|
14
|
+
* The component only needs to:
|
|
15
|
+
* - Subscribe to `isPopoverOpen$` for popover visibility
|
|
16
|
+
* - Call `togglePopover()` on Export button click
|
|
17
|
+
* - Call `onFormatSelected(format, groupId, groupName)` when user picks a format
|
|
18
|
+
*
|
|
19
|
+
* Follows the same pattern as MeetingExportService in the events-and-meetings library.
|
|
20
|
+
* @export
|
|
21
|
+
* @class RosterExportService
|
|
22
|
+
*/
|
|
23
|
+
export declare class RosterExportService {
|
|
24
|
+
private httpClient;
|
|
25
|
+
private dialog;
|
|
26
|
+
private alertService;
|
|
27
|
+
private constants;
|
|
28
|
+
private apiBaseUrl;
|
|
29
|
+
private destroy$;
|
|
30
|
+
/** Controls popover open/close state */
|
|
31
|
+
private isPopoverOpenSubject$;
|
|
32
|
+
isPopoverOpen$: import("rxjs").Observable<boolean>;
|
|
33
|
+
/** Controls in-progress state for button disable */
|
|
34
|
+
private isExportInProgressSubject$;
|
|
35
|
+
isExportInProgress$: import("rxjs").Observable<boolean>;
|
|
36
|
+
/** Format options for the export popover */
|
|
37
|
+
exportFormatOptions: ExportFormatOption[];
|
|
38
|
+
/** Subtitle labels for the format selection cards */
|
|
39
|
+
exportFormatSubtitles: Record<string, string>;
|
|
40
|
+
/** Popover title */
|
|
41
|
+
popoverTitle: any;
|
|
42
|
+
constructor(httpClient: HttpClient, dialog: MatDialog, alertService: AlertsService);
|
|
43
|
+
/**
|
|
44
|
+
* Sets the API base URL for roster export calls.
|
|
45
|
+
* @param {string} url - Base URL (e.g., 'https://saappsapidev.ieee.org/v1')
|
|
46
|
+
* @memberof RosterExportService
|
|
47
|
+
*/
|
|
48
|
+
setApiBaseUrl(url: string): void;
|
|
49
|
+
/**
|
|
50
|
+
* Toggles the export format popover open/closed.
|
|
51
|
+
* Called by the component on Export button click.
|
|
52
|
+
* @memberof RosterExportService
|
|
53
|
+
*/
|
|
54
|
+
togglePopover(): void;
|
|
55
|
+
/**
|
|
56
|
+
* Closes the export format popover.
|
|
57
|
+
* @memberof RosterExportService
|
|
58
|
+
*/
|
|
59
|
+
closePopover(): void;
|
|
60
|
+
/**
|
|
61
|
+
* Handles format selection from the export popover.
|
|
62
|
+
* Closes popover, opens IEEE Policy dialog, on confirm triggers export.
|
|
63
|
+
* This is the main entry point called by the component after user picks a format.
|
|
64
|
+
* @param {ExportFormat} format - Selected format (CSV or XLS)
|
|
65
|
+
* @param {string} groupId - The group ID to export the roster for
|
|
66
|
+
* @param {string} groupName - The group name for filename generation
|
|
67
|
+
* @memberof RosterExportService
|
|
68
|
+
*/
|
|
69
|
+
onFormatSelected(format: ExportFormat, groupId: string, groupName: string): void;
|
|
70
|
+
/**
|
|
71
|
+
* Starts the export after the user confirms the policy dialog.
|
|
72
|
+
*
|
|
73
|
+
* When the File System Access API is available, the native Save picker is opened
|
|
74
|
+
* HERE — synchronously within the confirm handler — while the user activation from
|
|
75
|
+
* the confirm click is still valid. (Opening it later, inside the async HTTP
|
|
76
|
+
* response callback, would exceed the activation window and the browser would
|
|
77
|
+
* reject it with a SecurityError.) The obtained file handle is then passed to the
|
|
78
|
+
* HTTP flow, which writes the downloaded bytes to it once the response arrives, so
|
|
79
|
+
* the success dialog is still shown only AFTER the file is saved.
|
|
80
|
+
*
|
|
81
|
+
* If the user cancels the picker we abort before making the request. If the API is
|
|
82
|
+
* unavailable (Firefox/Safari) we proceed without a handle and fall back to
|
|
83
|
+
* `saveAs()` after the response.
|
|
84
|
+
* @param {ExportFormat} format
|
|
85
|
+
* @param {string} groupId
|
|
86
|
+
* @param {string} groupName
|
|
87
|
+
* @memberof RosterExportService
|
|
88
|
+
*/
|
|
89
|
+
private startExport;
|
|
90
|
+
/**
|
|
91
|
+
* Executes the roster export API call and writes the downloaded file.
|
|
92
|
+
* Endpoint: GET /v1/groups/roster/export/{groupId}?format=csv|xlsx
|
|
93
|
+
* When a pre-obtained file handle is provided (from the picker opened at confirm
|
|
94
|
+
* time) the bytes are written to it; otherwise it falls back to `saveAs()`.
|
|
95
|
+
* The success dialog is shown only after the file has been written.
|
|
96
|
+
* @param {ExportFormat} format - The selected export format
|
|
97
|
+
* @param {string} groupId - The group identifier
|
|
98
|
+
* @param {string} groupName - The group name for filename
|
|
99
|
+
* @param {FileSystemFileHandle | null} fileHandle - Handle from the Save picker, or null
|
|
100
|
+
* @memberof RosterExportService
|
|
101
|
+
*/
|
|
102
|
+
private executeExport;
|
|
103
|
+
/**
|
|
104
|
+
* Shows the export success dialog after a successful file download.
|
|
105
|
+
* @param {string} filename - The downloaded filename
|
|
106
|
+
* @memberof RosterExportService
|
|
107
|
+
*/
|
|
108
|
+
private showExportSuccessDialogAfterDownload;
|
|
109
|
+
/**
|
|
110
|
+
* Returns the API base URL for roster export.
|
|
111
|
+
* @return {string}
|
|
112
|
+
* @memberof RosterExportService
|
|
113
|
+
*/
|
|
114
|
+
private getExportApiUrl;
|
|
115
|
+
/**
|
|
116
|
+
* Extracts filename from Content-Disposition header.
|
|
117
|
+
* Falls back to buildFilename() if header is missing.
|
|
118
|
+
* @param {HttpResponse<Blob>} response
|
|
119
|
+
* @param {ExportFormat} format
|
|
120
|
+
* @param {string} groupName
|
|
121
|
+
* @return {string}
|
|
122
|
+
* @memberof RosterExportService
|
|
123
|
+
*/
|
|
124
|
+
private extractFilenameFromResponse;
|
|
125
|
+
/**
|
|
126
|
+
* Builds a sanitized filename for the roster export.
|
|
127
|
+
* Pattern: {SanitizedGroupName}_Roster.{extension}
|
|
128
|
+
* @param {string} groupName
|
|
129
|
+
* @param {ExportFormat} format
|
|
130
|
+
* @return {string}
|
|
131
|
+
* @memberof RosterExportService
|
|
132
|
+
*/
|
|
133
|
+
buildFilename(groupName: string, format: ExportFormat): string;
|
|
134
|
+
/**
|
|
135
|
+
* Sanitizes the group name for use in a filename.
|
|
136
|
+
* Replaces non-alphanumeric characters (except hyphen/underscore) with underscore,
|
|
137
|
+
* collapses consecutive underscores, and truncates to 200 chars.
|
|
138
|
+
* @param {string} groupName
|
|
139
|
+
* @return {string}
|
|
140
|
+
* @memberof RosterExportService
|
|
141
|
+
*/
|
|
142
|
+
sanitizeGroupName(groupName: string): string;
|
|
143
|
+
/**
|
|
144
|
+
* Writes the downloaded bytes to disk and resolves ONLY when the save has actually
|
|
145
|
+
* completed.
|
|
146
|
+
*
|
|
147
|
+
* The Save picker is opened earlier (at policy-confirm time, while user activation
|
|
148
|
+
* is still valid — see {@link startExport}); this method only writes to the handle
|
|
149
|
+
* it produced. That keeps the "success dialog after save" ordering without hitting
|
|
150
|
+
* the SecurityError that occurs when the picker is opened from this async callback.
|
|
151
|
+
*
|
|
152
|
+
* When no handle is provided (File System Access API unavailable, or the picker
|
|
153
|
+
* errored), we fall back to FileSaver's `saveAs()`, which resolves immediately.
|
|
154
|
+
* @param {Blob} blob - The file contents
|
|
155
|
+
* @param {string} filename - The suggested filename (used by the saveAs fallback)
|
|
156
|
+
* @param {ExportFormat} format - The selected export format (drives MIME type)
|
|
157
|
+
* @param {FileSystemFileHandle | null} fileHandle - Handle from the Save picker, or null
|
|
158
|
+
* @return {Promise<{ saved: boolean }>} Resolves with `saved: true` once written.
|
|
159
|
+
* @memberof RosterExportService
|
|
160
|
+
*/
|
|
161
|
+
downloadFile(blob: Blob, filename: string, format: ExportFormat, fileHandle: any): Promise<{
|
|
162
|
+
saved: boolean;
|
|
163
|
+
}>;
|
|
164
|
+
/**
|
|
165
|
+
* Cleanup — call from the component's ngOnDestroy.
|
|
166
|
+
* @memberof RosterExportService
|
|
167
|
+
*/
|
|
168
|
+
destroy(): void;
|
|
169
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<RosterExportService, never>;
|
|
170
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<RosterExportService>;
|
|
171
|
+
}
|
package/package.json
CHANGED
package/public-api.d.ts
CHANGED
|
@@ -24,5 +24,6 @@ export * from './lib/models/table-column-schema-user-group.model';
|
|
|
24
24
|
export * from './lib/models/parent-groups-info.model';
|
|
25
25
|
export * from './lib/models/reciprocal-credit.model';
|
|
26
26
|
export * from './lib/services/groups.service';
|
|
27
|
+
export * from './lib/services/roster-export.service';
|
|
27
28
|
export * from './lib/assets/form-validations';
|
|
28
29
|
export * from './lib/groups.module';
|