@ieeesa-npm/groups 0.15.8 → 0.15.10
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 +75 -4
- package/esm2022/lib/components/add-user-roster/add-user-roster.component.mjs +86 -35
- package/esm2022/lib/components/edit-user-roles/edit-user-roles.component.mjs +94 -51
- package/esm2022/lib/components/interest-form/interest-form.component.mjs +104 -0
- package/esm2022/lib/components/interest-form-management/interest-form-management.component.mjs +63 -0
- package/esm2022/lib/components/interested-rosters/interested-rosters.component.mjs +28 -0
- package/esm2022/lib/components/org-multi-select/org-multi-select.component.mjs +455 -0
- package/esm2022/lib/components/roster-import/roster-import.component.mjs +149 -82
- package/esm2022/lib/components/roster-import-history/roster-import-history.component.mjs +232 -0
- package/esm2022/lib/components/tree-view/tree-view.component.mjs +26 -5
- package/esm2022/lib/components/view-roster/view-roster.component.mjs +10 -3
- package/esm2022/lib/groups.component.mjs +60 -6
- package/esm2022/lib/models/group-action.model.mjs +2 -1
- package/esm2022/lib/models/group-function-type.model.mjs +2 -1
- package/esm2022/lib/models/permission-type.model.mjs +2 -1
- package/esm2022/lib/models/roster-import.model.mjs +34 -17
- package/esm2022/lib/services/roster-import-api.service.mjs +174 -0
- package/esm2022/public-api.mjs +6 -1
- package/fesm2022/ieeesa-npm-groups.mjs +1562 -308
- package/fesm2022/ieeesa-npm-groups.mjs.map +1 -1
- package/lib/components/add-user-roster/add-user-roster.component.d.ts +30 -0
- package/lib/components/edit-user-roles/edit-user-roles.component.d.ts +31 -0
- package/lib/components/interest-form/interest-form.component.d.ts +75 -0
- package/lib/components/interest-form-management/interest-form-management.component.d.ts +31 -0
- package/lib/components/interested-rosters/interested-rosters.component.d.ts +17 -0
- package/lib/components/org-multi-select/org-multi-select.component.d.ts +212 -0
- package/lib/components/roster-import/roster-import.component.d.ts +77 -38
- package/lib/components/roster-import-history/roster-import-history.component.d.ts +102 -0
- package/lib/components/tree-view/tree-view.component.d.ts +6 -3
- package/lib/components/view-roster/view-roster.component.d.ts +5 -0
- package/lib/groups.component.d.ts +17 -0
- package/lib/models/group-action.model.d.ts +2 -1
- package/lib/models/group-function-type.model.d.ts +2 -1
- package/lib/models/permission-type.model.d.ts +2 -1
- package/lib/models/roster-import.model.d.ts +104 -21
- package/lib/services/groups.service.d.ts +4 -0
- package/lib/services/roster-import-api.service.d.ts +108 -0
- package/package.json +1 -1
- package/public-api.d.ts +5 -0
- package/esm2022/lib/assets/roster-import-mocks.mjs +0 -98
- package/lib/assets/roster-import-mocks.d.ts +0 -27
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { ChangeDetectorRef, OnDestroy, OnInit } from '@angular/core';
|
|
2
|
+
import { TableActions, TableColumnSchema } from '@ieeesa-npm/presentation';
|
|
3
|
+
import { GlobalErrorHandlerService } from '@ieeesa-npm/utility';
|
|
4
|
+
import { RosterImportApiService } from '../../services/roster-import-api.service';
|
|
5
|
+
import { GroupsService } from '../../services/groups.service';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
/** A single row shown in the "Imported Files" table. */
|
|
8
|
+
interface RosterImportHistoryRow {
|
|
9
|
+
timestamp: string;
|
|
10
|
+
personImported: string;
|
|
11
|
+
fileName: string;
|
|
12
|
+
addedRows: number | string;
|
|
13
|
+
errors: number | string;
|
|
14
|
+
targetGroup: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Roster import-history ("View History") dialog body.
|
|
18
|
+
*
|
|
19
|
+
* Rendered inside the shared ModalComponent (which supplies the
|
|
20
|
+
* "← Back to Rosters / View History" breadcrumb title row + X close). Shows the
|
|
21
|
+
* selected group's name and an "Imported Files" table listing prior roster
|
|
22
|
+
* imports.
|
|
23
|
+
*
|
|
24
|
+
* Data comes from the real BE endpoint via {@link RosterImportApiService}:
|
|
25
|
+
* `GET /v1/groups/roster/import/history/{groupId}`. The response is a list of
|
|
26
|
+
* `RosterImportJob` whose JSON view exposes `fileName`, `successRows`,
|
|
27
|
+
* `failedRows`, `status` and ids — but NOT `createdOn` / `createdBy` (both are
|
|
28
|
+
* `@JsonIgnore` on the BE entity). So the "Timestamp" and "Person Imported"
|
|
29
|
+
* columns render a placeholder until the BE exposes those fields. "Target
|
|
30
|
+
* Group" uses the current group's name (history is scoped to one group).
|
|
31
|
+
*
|
|
32
|
+
* @export
|
|
33
|
+
* @class RosterImportHistoryComponent
|
|
34
|
+
*/
|
|
35
|
+
export declare class RosterImportHistoryComponent implements OnInit, OnDestroy {
|
|
36
|
+
private rosterImportApiService;
|
|
37
|
+
private groupService;
|
|
38
|
+
private cdr;
|
|
39
|
+
private globalErrorHandlerService;
|
|
40
|
+
/** Carries the { groupId, groupName } payload from the opening dialog. */
|
|
41
|
+
componentData: any;
|
|
42
|
+
constants: any;
|
|
43
|
+
screenTexts: any;
|
|
44
|
+
private destroy$;
|
|
45
|
+
/** Table column definitions for the "Imported Files" table. */
|
|
46
|
+
columnSchema: TableColumnSchema[];
|
|
47
|
+
/** Import-history rows mapped for the table. */
|
|
48
|
+
tableData: RosterImportHistoryRow[];
|
|
49
|
+
/** True while the history request is in flight. */
|
|
50
|
+
isLoading: boolean;
|
|
51
|
+
/** Inline error message when the history request fails. */
|
|
52
|
+
errorMessage: string | null;
|
|
53
|
+
/** Read-only table — no search / filter / add / edit / delete actions. */
|
|
54
|
+
tableActions: TableActions;
|
|
55
|
+
/** Placeholder shown for fields the BE does not return (timestamp / person). */
|
|
56
|
+
private readonly placeholder;
|
|
57
|
+
constructor(rosterImportApiService: RosterImportApiService, groupService: GroupsService, cdr: ChangeDetectorRef, globalErrorHandlerService: GlobalErrorHandlerService);
|
|
58
|
+
/** The group name shown as the heading above the Imported Files table. */
|
|
59
|
+
get groupName(): string;
|
|
60
|
+
/** The group id whose history is fetched. */
|
|
61
|
+
private get groupId();
|
|
62
|
+
/**
|
|
63
|
+
* Builds the table schema and loads the import history from the BE.
|
|
64
|
+
* @memberof RosterImportHistoryComponent
|
|
65
|
+
*/
|
|
66
|
+
ngOnInit(): void;
|
|
67
|
+
/**
|
|
68
|
+
* Cleans up subscriptions when the component is destroyed.
|
|
69
|
+
* @memberof RosterImportHistoryComponent
|
|
70
|
+
*/
|
|
71
|
+
ngOnDestroy(): void;
|
|
72
|
+
/**
|
|
73
|
+
* Fetches the import history for the current group and maps it to table rows.
|
|
74
|
+
* @memberof RosterImportHistoryComponent
|
|
75
|
+
*/
|
|
76
|
+
loadImportHistory(): void;
|
|
77
|
+
/**
|
|
78
|
+
* Maps a BE import job to a table row. Timestamp and Person Imported are not
|
|
79
|
+
* present in the response (BE `@JsonIgnore`), so they render a placeholder.
|
|
80
|
+
* Target Group uses the current group's name (history is per-group).
|
|
81
|
+
* @param {RosterImportJob} job - The BE import job.
|
|
82
|
+
* @return {RosterImportHistoryRow}
|
|
83
|
+
* @memberof RosterImportHistoryComponent
|
|
84
|
+
*/
|
|
85
|
+
private mapJobToRow;
|
|
86
|
+
/**
|
|
87
|
+
* Maps a failed history request to a user-facing inline error message.
|
|
88
|
+
* A 403 gets the permission-specific message; other errors get the generic
|
|
89
|
+
* one and are forwarded to the global handler for logging/interceptors.
|
|
90
|
+
* @param {*} error - The HttpErrorResponse.
|
|
91
|
+
* @memberof RosterImportHistoryComponent
|
|
92
|
+
*/
|
|
93
|
+
private handleError;
|
|
94
|
+
/**
|
|
95
|
+
* Defines the "Imported Files" table columns.
|
|
96
|
+
* @memberof RosterImportHistoryComponent
|
|
97
|
+
*/
|
|
98
|
+
private buildColumnSchema;
|
|
99
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<RosterImportHistoryComponent, never>;
|
|
100
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<RosterImportHistoryComponent, "ieeesa-roster-import-history", never, { "componentData": { "alias": "componentData"; "required": false; }; }, {}, never, never, true, never>;
|
|
101
|
+
}
|
|
102
|
+
export {};
|
|
@@ -155,6 +155,7 @@ export declare class TreeViewComponent implements OnInit, AfterViewInit, OnDestr
|
|
|
155
155
|
editGroupClick: EventEmitter<EditGroupAndParentInfo>;
|
|
156
156
|
deleteGroupClick: EventEmitter<GroupInfo>;
|
|
157
157
|
viewRosterClick: EventEmitter<GroupInfo>;
|
|
158
|
+
manageInterestFormClick: EventEmitter<GroupInfo>;
|
|
158
159
|
isMobileView: boolean;
|
|
159
160
|
groupFunctionType: typeof GroupFunctionType;
|
|
160
161
|
constructor(database: Groups, elementRef: ElementRef, groupsService: GroupsService, breakpointObserverService: BreakpointObserverService);
|
|
@@ -263,8 +264,10 @@ export declare class TreeViewComponent implements OnInit, AfterViewInit, OnDestr
|
|
|
263
264
|
*/
|
|
264
265
|
getToggleButtonInfo(group: GroupNode): IconButton;
|
|
265
266
|
/**
|
|
266
|
-
* Handles the emitted group actions event
|
|
267
|
-
*
|
|
267
|
+
* Handles the emitted group actions event. Emits the corresponding output
|
|
268
|
+
* for the selected action: view roster, create sub group, edit group,
|
|
269
|
+
* delete group, or manage interest form.
|
|
270
|
+
* @param {GroupNode} group
|
|
268
271
|
* @memberof TreeViewComponent
|
|
269
272
|
*/
|
|
270
273
|
handleGroupActions(group: GroupNode): void;
|
|
@@ -289,5 +292,5 @@ export declare class TreeViewComponent implements OnInit, AfterViewInit, OnDestr
|
|
|
289
292
|
*/
|
|
290
293
|
ngOnDestroy(): void;
|
|
291
294
|
static ɵfac: i0.ɵɵFactoryDeclaration<TreeViewComponent, never>;
|
|
292
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<TreeViewComponent, "ieeesa-tree", never, { "parentGroupsInfo": { "alias": "parentGroupsInfo"; "required": false; }; "childGroupsInfo": { "alias": "childGroupsInfo"; "required": false; }; "isGroupSearchOrFilterActive": { "alias": "isGroupSearchOrFilterActive"; "required": false; }; "deletedGroupIdInfo": { "alias": "deletedGroupIdInfo"; "required": false; }; "userGroupPermissions": { "alias": "userGroupPermissions"; "required": false; }; }, { "toggleGroupClick": "toggleGroupClick"; "createGroupClick": "createGroupClick"; "editGroupClick": "editGroupClick"; "deleteGroupClick": "deleteGroupClick"; "viewRosterClick": "viewRosterClick"; }, never, never, true, never>;
|
|
295
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<TreeViewComponent, "ieeesa-tree", never, { "parentGroupsInfo": { "alias": "parentGroupsInfo"; "required": false; }; "childGroupsInfo": { "alias": "childGroupsInfo"; "required": false; }; "isGroupSearchOrFilterActive": { "alias": "isGroupSearchOrFilterActive"; "required": false; }; "deletedGroupIdInfo": { "alias": "deletedGroupIdInfo"; "required": false; }; "userGroupPermissions": { "alias": "userGroupPermissions"; "required": false; }; }, { "toggleGroupClick": "toggleGroupClick"; "createGroupClick": "createGroupClick"; "editGroupClick": "editGroupClick"; "deleteGroupClick": "deleteGroupClick"; "viewRosterClick": "viewRosterClick"; "manageInterestFormClick": "manageInterestFormClick"; }, never, never, true, never>;
|
|
293
296
|
}
|
|
@@ -188,6 +188,11 @@ export declare class ViewRosterComponent implements AfterViewInit, OnDestroy, On
|
|
|
188
188
|
* @memberof ViewRosterComponent
|
|
189
189
|
*/
|
|
190
190
|
onImportRoster(): void;
|
|
191
|
+
/**
|
|
192
|
+
* "View History" action — opens the roster import-history popup.
|
|
193
|
+
* @memberof ViewRosterComponent
|
|
194
|
+
*/
|
|
195
|
+
onViewHistory(): void;
|
|
191
196
|
/**
|
|
192
197
|
* Handles alerts for success, error, warning.
|
|
193
198
|
* @param {(string | string[])} message -error or warning message
|
|
@@ -117,12 +117,29 @@ export declare class GroupsComponent implements OnInit, OnDestroy {
|
|
|
117
117
|
* @memberof GroupsComponent
|
|
118
118
|
*/
|
|
119
119
|
openRosterImportModal(selectedGroupInfo: GroupInfo): void;
|
|
120
|
+
/**
|
|
121
|
+
* Sets the dialog options for the roster import-history ("View History")
|
|
122
|
+
* modal and opens it. Passes the selected group's id/name to the
|
|
123
|
+
* dynamically-instantiated RosterImportHistoryComponent via the
|
|
124
|
+
* ModalComponent dynamic-input pattern.
|
|
125
|
+
* @param {GroupInfo} selectedGroupInfo
|
|
126
|
+
* @memberof GroupsComponent
|
|
127
|
+
*/
|
|
128
|
+
openRosterImportHistoryModal(selectedGroupInfo: GroupInfo): void;
|
|
120
129
|
/**
|
|
121
130
|
* Sets the dialog options for users modal and calls openModal method.
|
|
122
131
|
* @param {GroupInfo} group
|
|
123
132
|
* @memberof GroupsComponent
|
|
124
133
|
*/
|
|
125
134
|
viewRoster(group: GroupInfo): void;
|
|
135
|
+
/**
|
|
136
|
+
* Opens the Roster Interests dialog for the selected group (SP3M-317). The
|
|
137
|
+
* dialog hosts the "Interested Rosters" and "Interest Form" tabs and receives
|
|
138
|
+
* the group via the dialog data.
|
|
139
|
+
* @param {GroupInfo} group
|
|
140
|
+
* @memberof GroupsComponent
|
|
141
|
+
*/
|
|
142
|
+
openRosterInterests(group: GroupInfo): void;
|
|
126
143
|
/**
|
|
127
144
|
* Opens modal component with for received params and handles form submission success and errors.
|
|
128
145
|
* @param {*} dialogOptions
|
|
@@ -8,5 +8,6 @@ export declare enum GroupFunctionType {
|
|
|
8
8
|
REASSIGN_PARENT_GROUP = "REASSIGN_PARENT_GROUP",
|
|
9
9
|
EDIT_ROSTER_USER_ROLE = "EDIT_ROSTER_USER_ROLE",
|
|
10
10
|
ADD_USER_TO_ROSTER = "ADD_USER_TO_ROSTER",
|
|
11
|
-
IMPORT_ROSTER = "IMPORT_ROSTER"
|
|
11
|
+
IMPORT_ROSTER = "IMPORT_ROSTER",
|
|
12
|
+
VIEW_IMPORT_HISTORY = "VIEW_IMPORT_HISTORY"
|
|
12
13
|
}
|
|
@@ -12,5 +12,6 @@ export declare enum PermissionType {
|
|
|
12
12
|
VIEW_ALL_GROUPS = "VIEW_ALL_GROUPS",
|
|
13
13
|
MANAGE_ALL_GROUPS = "MANAGE_ALL_GROUPS",
|
|
14
14
|
VIEW_ALL_ROSTERS = "VIEW_ALL_ROSTERS",
|
|
15
|
-
MANAGE_ALL_ROSTERS = "MANAGE_ALL_ROSTERS"
|
|
15
|
+
MANAGE_ALL_ROSTERS = "MANAGE_ALL_ROSTERS",
|
|
16
|
+
MANAGE_CUSTOM_INTEREST_QUESTIONS = "MANAGE_CUSTOM_INTEREST_QUESTIONS"
|
|
16
17
|
}
|
|
@@ -1,5 +1,101 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Roster-import status state machine. Mirrors the BE `ImportStatus` enum
|
|
3
|
+
* (sa-saapps-groups-api: org.ieee.standards.groups.model.ImportStatus) and the
|
|
4
|
+
* `status` CHECK constraint on `roster_import_job_tb`.
|
|
5
|
+
*
|
|
6
|
+
* - PENDING upload accepted, awaiting validation (default)
|
|
7
|
+
* - VALIDATING rows are being validated
|
|
8
|
+
* - COMPLETED all rows imported successfully (terminal)
|
|
9
|
+
* - FAILED no rows imported successfully (terminal)
|
|
10
|
+
* - PARTIAL some rows imported, some failed (terminal)
|
|
11
|
+
*/
|
|
12
|
+
export declare enum RosterImportStatus {
|
|
13
|
+
PENDING = "PENDING",
|
|
14
|
+
VALIDATING = "VALIDATING",
|
|
15
|
+
COMPLETED = "COMPLETED",
|
|
16
|
+
FAILED = "FAILED",
|
|
17
|
+
PARTIAL = "PARTIAL"
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A single per-row validation error stored in the import job's `error_report`
|
|
21
|
+
* JSONB column. Mirrors the BE `ErrorReport` POJO ({@code {row, field, message}}).
|
|
22
|
+
*/
|
|
23
|
+
export interface RosterImportErrorReport {
|
|
24
|
+
/** 1-based data-row number in the uploaded file. */
|
|
25
|
+
row: number;
|
|
26
|
+
/** The field/column the error relates to (e.g. "Name", "Email"). */
|
|
27
|
+
field?: string;
|
|
28
|
+
/** Human-readable error message. */
|
|
29
|
+
message: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Roster import job as returned by the BE (upload / confirm / history).
|
|
33
|
+
* Mirrors the JSON-serialized view of the BE `RosterImportJob` entity.
|
|
34
|
+
*
|
|
35
|
+
* IMPORTANT: The BE marks `createdOn`, `createdBy`, `updatedOn`, `updatedBy` as
|
|
36
|
+
* `@JsonIgnore`, so the response carries NO timestamp and NO importer identity.
|
|
37
|
+
* If the "View History" screen needs those (Timestamp / Person Imported
|
|
38
|
+
* columns), the BE must expose them first — this is a BE change, tracked
|
|
39
|
+
* separately. `errorReport` arrives as a raw JSON string (JSONB passthrough);
|
|
40
|
+
* parse it into {@link RosterImportErrorReport}[] on the client when needed.
|
|
41
|
+
*/
|
|
42
|
+
export interface RosterImportJob {
|
|
43
|
+
/** Import job identifier. */
|
|
44
|
+
importId: string;
|
|
45
|
+
/** The target group the roster was imported into. */
|
|
46
|
+
groupId: string;
|
|
47
|
+
/** Uploaded file name (e.g. "07_tenant_custom_fields.csv"). */
|
|
48
|
+
fileName?: string;
|
|
49
|
+
/** Current status (see {@link RosterImportStatus}). */
|
|
50
|
+
status: string;
|
|
51
|
+
/** Total data rows detected (`totalRows = successRows + failedRows`). */
|
|
52
|
+
totalRows?: number;
|
|
53
|
+
/** Rows successfully added/updated. */
|
|
54
|
+
successRows?: number;
|
|
55
|
+
/** Rows skipped due to validation errors. */
|
|
56
|
+
failedRows?: number;
|
|
57
|
+
/**
|
|
58
|
+
* Row-level errors as a RAW JSON string (BE `error_report` JSONB passthrough).
|
|
59
|
+
* Parse with `JSON.parse(...)` into {@link RosterImportErrorReport}[].
|
|
60
|
+
*/
|
|
61
|
+
errorReport?: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Per-row validation outcome in a validate/preview response. Mirrors the BE
|
|
65
|
+
* `RosterImportRowOutcome` POJO.
|
|
66
|
+
*/
|
|
67
|
+
export interface RosterImportRowOutcome {
|
|
68
|
+
/** 1-based data-row number in the uploaded file. */
|
|
69
|
+
row: number;
|
|
70
|
+
/** Whether this row passed validation. */
|
|
71
|
+
valid: boolean;
|
|
72
|
+
/** The field/column the error relates to, for an invalid row. */
|
|
73
|
+
field?: string;
|
|
74
|
+
/** Validation error message, for an invalid row. */
|
|
75
|
+
error?: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Validation preview returned by validate / preview. Mirrors the BE
|
|
79
|
+
* `RosterImportPreview` POJO. Building a preview commits no roster changes.
|
|
80
|
+
* `rows` is never null (BE guarantees an empty list at minimum).
|
|
81
|
+
*/
|
|
82
|
+
export interface RosterImportPreview {
|
|
83
|
+
/** Import job identifier. */
|
|
84
|
+
importId: string;
|
|
85
|
+
/** Current status (see {@link RosterImportStatus}). */
|
|
86
|
+
status: string;
|
|
87
|
+
/** Total data rows (`totalRows = successRows + failedRows`). */
|
|
88
|
+
totalRows: number;
|
|
89
|
+
/** Rows that passed validation. */
|
|
90
|
+
successRows: number;
|
|
91
|
+
/** Rows that failed validation. */
|
|
92
|
+
failedRows: number;
|
|
93
|
+
/** Per-row outcomes (never null). */
|
|
94
|
+
rows: RosterImportRowOutcome[];
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* @deprecated Use {@link RosterImportStatus} instead. Retained for backward
|
|
98
|
+
* compatibility with the pre-BE-integration public API.
|
|
3
99
|
*/
|
|
4
100
|
export declare enum RosterUploadStatus {
|
|
5
101
|
PROCESSING = "PROCESSING",
|
|
@@ -7,7 +103,9 @@ export declare enum RosterUploadStatus {
|
|
|
7
103
|
FAILED = "FAILED"
|
|
8
104
|
}
|
|
9
105
|
/**
|
|
10
|
-
*
|
|
106
|
+
* @deprecated Use {@link RosterImportErrorReport} (`{ row, field, message }`)
|
|
107
|
+
* or {@link RosterImportRowOutcome} instead. Retained for backward
|
|
108
|
+
* compatibility with the pre-BE-integration public API.
|
|
11
109
|
*/
|
|
12
110
|
export interface RosterUploadError {
|
|
13
111
|
/** 1-based row number in the uploaded file. */
|
|
@@ -20,13 +118,12 @@ export interface RosterUploadError {
|
|
|
20
118
|
errorMessage: string;
|
|
21
119
|
}
|
|
22
120
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* is available. It will be reconciled with the backend contract once shared.
|
|
121
|
+
* @deprecated Use {@link RosterImportJob} (confirm/history) or
|
|
122
|
+
* {@link RosterImportPreview} (validate) instead. Retained for backward
|
|
123
|
+
* compatibility with the pre-BE-integration public API.
|
|
27
124
|
*/
|
|
28
125
|
export interface RosterUploadResponse {
|
|
29
|
-
/** Job identifier
|
|
126
|
+
/** Job identifier. */
|
|
30
127
|
uploadJobId?: string;
|
|
31
128
|
/** Terminal job status. */
|
|
32
129
|
status: RosterUploadStatus;
|
|
@@ -39,17 +136,3 @@ export interface RosterUploadResponse {
|
|
|
39
136
|
/** Row-level errors (present when failureCount > 0). */
|
|
40
137
|
rowErrors: RosterUploadError[];
|
|
41
138
|
}
|
|
42
|
-
/**
|
|
43
|
-
* The kind of mock scenario to simulate, so the UI can be exercised against
|
|
44
|
-
* each Figma state without a backend.
|
|
45
|
-
*/
|
|
46
|
-
export declare enum RosterImportMockScenario {
|
|
47
|
-
/** All rows imported successfully (Figma: 30 added / 0 skipped). */
|
|
48
|
-
ALL_SUCCESS = "ALL_SUCCESS",
|
|
49
|
-
/** Some rows imported, some skipped with errors (partial). */
|
|
50
|
-
PARTIAL = "PARTIAL",
|
|
51
|
-
/** Every row skipped with errors (Figma: 0 added / 30 skipped). */
|
|
52
|
-
ALL_SKIPPED = "ALL_SKIPPED",
|
|
53
|
-
/** File contained headers but zero data rows (Figma: "No roster data found"). */
|
|
54
|
-
EMPTY = "EMPTY"
|
|
55
|
-
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
import { HttpService } from '@ieeesa-npm/utility';
|
|
3
|
+
import { RosterImportJob, RosterImportPreview } from '../models/roster-import.model';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
/**
|
|
6
|
+
* RosterImportApiService wraps the backend roster-import state-machine API
|
|
7
|
+
* exposed by sa-saapps-groups-api's `RosterImportController`
|
|
8
|
+
* (`/v1/groups/roster/import`). It drives the upload → validate → preview →
|
|
9
|
+
* confirm / cancel lifecycle plus the read-only import history.
|
|
10
|
+
*
|
|
11
|
+
* All calls return the standard `Response<T>` envelope from the platform
|
|
12
|
+
* (`{ status, body }`); each method maps through the envelope's `body` where
|
|
13
|
+
* useful and rethrows errors so callers can inspect `error.error.body.errorCodes`
|
|
14
|
+
* (e.g. 1072 unsupported format, 1073 too large, 1074 row-limit, 1075 invalid
|
|
15
|
+
* status transition) — mirroring the existing GroupsService pattern.
|
|
16
|
+
*
|
|
17
|
+
* The base URL already carries the version segment (e.g. `.../v1`), matching
|
|
18
|
+
* every other GroupsService call built as `${apiBaseUrl}/groups/...`, so the
|
|
19
|
+
* version is NOT repeated here. Call {@link setApiBaseUrl} before use.
|
|
20
|
+
*
|
|
21
|
+
* @export
|
|
22
|
+
* @class RosterImportApiService
|
|
23
|
+
*/
|
|
24
|
+
export declare class RosterImportApiService {
|
|
25
|
+
private httpService;
|
|
26
|
+
private apiBaseUrl;
|
|
27
|
+
/** Path prefix (relative to apiBaseUrl) for the roster-import endpoints. */
|
|
28
|
+
private readonly IMPORT_BASE_PATH;
|
|
29
|
+
constructor(httpService: HttpService);
|
|
30
|
+
/**
|
|
31
|
+
* Sets the API base URL for roster-import calls.
|
|
32
|
+
* @param {string} url - Base URL ending in the version segment (e.g. '.../v1').
|
|
33
|
+
* @memberof RosterImportApiService
|
|
34
|
+
*/
|
|
35
|
+
setApiBaseUrl(url: string): void;
|
|
36
|
+
/**
|
|
37
|
+
* Builds an import endpoint URL from apiBaseUrl + the base path, guarding
|
|
38
|
+
* against a double slash if apiBaseUrl has a trailing slash.
|
|
39
|
+
* @param {string} [suffix] - Extra path appended after the base path.
|
|
40
|
+
* @return {string}
|
|
41
|
+
* @memberof RosterImportApiService
|
|
42
|
+
*/
|
|
43
|
+
private buildUrl;
|
|
44
|
+
/**
|
|
45
|
+
* Uploads a roster-import file for a group and creates a PENDING import job.
|
|
46
|
+
* POST {apiBaseUrl}/groups/roster/import/upload (multipart form-data).
|
|
47
|
+
*
|
|
48
|
+
* Server validation may reject with: 1072 (unsupported format — only .xlsx /
|
|
49
|
+
* .csv), 1073 (file > 10MB), 1074 (> 10,000 data rows).
|
|
50
|
+
* @param {File} file - The .xlsx or .csv roster file.
|
|
51
|
+
* @param {string} groupId - The target group id.
|
|
52
|
+
* @return {Observable<RosterImportJob>} - The created PENDING import job.
|
|
53
|
+
* @memberof RosterImportApiService
|
|
54
|
+
*/
|
|
55
|
+
uploadImportFile(file: File, groupId: string): Observable<RosterImportJob>;
|
|
56
|
+
/**
|
|
57
|
+
* Transitions a PENDING import job to VALIDATING and returns the per-row
|
|
58
|
+
* validation preview.
|
|
59
|
+
* POST {apiBaseUrl}/groups/roster/import/{importId}/validate.
|
|
60
|
+
* @param {string} importId - The import job identifier.
|
|
61
|
+
* @return {Observable<RosterImportPreview>}
|
|
62
|
+
* @memberof RosterImportApiService
|
|
63
|
+
*/
|
|
64
|
+
validateImportJob(importId: string): Observable<RosterImportPreview>;
|
|
65
|
+
/**
|
|
66
|
+
* Returns the per-row validation preview for a validated import job without
|
|
67
|
+
* committing any roster changes.
|
|
68
|
+
* GET {apiBaseUrl}/groups/roster/import/{importId}/preview.
|
|
69
|
+
* @param {string} importId - The import job identifier.
|
|
70
|
+
* @return {Observable<RosterImportPreview>}
|
|
71
|
+
* @memberof RosterImportApiService
|
|
72
|
+
*/
|
|
73
|
+
getImportPreview(importId: string): Observable<RosterImportPreview>;
|
|
74
|
+
/**
|
|
75
|
+
* Commits a validated import job's roster changes and returns the job with
|
|
76
|
+
* its terminal status (COMPLETED / PARTIAL / FAILED).
|
|
77
|
+
* POST {apiBaseUrl}/groups/roster/import/{importId}/confirm.
|
|
78
|
+
*
|
|
79
|
+
* May reject with 1075 (invalid status transition) if the job is not in a
|
|
80
|
+
* confirmable state.
|
|
81
|
+
* @param {string} importId - The import job identifier.
|
|
82
|
+
* @return {Observable<RosterImportJob>}
|
|
83
|
+
* @memberof RosterImportApiService
|
|
84
|
+
*/
|
|
85
|
+
confirmImportJob(importId: string): Observable<RosterImportJob>;
|
|
86
|
+
/**
|
|
87
|
+
* Cancels an import job after preview without committing any roster changes.
|
|
88
|
+
* POST {apiBaseUrl}/groups/roster/import/{importId}/cancel.
|
|
89
|
+
* @param {string} importId - The import job identifier.
|
|
90
|
+
* @return {Observable<string>} - The cancellation confirmation message.
|
|
91
|
+
* @memberof RosterImportApiService
|
|
92
|
+
*/
|
|
93
|
+
cancelImportJob(importId: string): Observable<string>;
|
|
94
|
+
/**
|
|
95
|
+
* Returns the roster import history for a group (read-only), scoped by the
|
|
96
|
+
* requester's app_id on the server.
|
|
97
|
+
* GET {apiBaseUrl}/groups/roster/import/history/{groupId}.
|
|
98
|
+
*
|
|
99
|
+
* May reject with 403 if the requester lacks view-roster permission for the
|
|
100
|
+
* group.
|
|
101
|
+
* @param {string} groupId - The group whose import history is requested.
|
|
102
|
+
* @return {Observable<RosterImportJob[]>} - The import jobs (never null).
|
|
103
|
+
* @memberof RosterImportApiService
|
|
104
|
+
*/
|
|
105
|
+
getImportHistory(groupId: string): Observable<RosterImportJob[]>;
|
|
106
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<RosterImportApiService, never>;
|
|
107
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<RosterImportApiService>;
|
|
108
|
+
}
|
package/package.json
CHANGED
package/public-api.d.ts
CHANGED
|
@@ -4,6 +4,10 @@ export * from './lib/components/edit-user-roles/edit-user-roles.component';
|
|
|
4
4
|
export * from './lib/components/reciprocal-credit-section/reciprocal-credit-section.component';
|
|
5
5
|
export * from './lib/components/add-working-groups/add-working-groups.component';
|
|
6
6
|
export * from './lib/components/roster-import/roster-import.component';
|
|
7
|
+
export * from './lib/components/roster-import-history/roster-import-history.component';
|
|
8
|
+
export * from './lib/components/interest-form-management/interest-form-management.component';
|
|
9
|
+
export * from './lib/components/interested-rosters/interested-rosters.component';
|
|
10
|
+
export * from './lib/components/interest-form/interest-form.component';
|
|
7
11
|
export * from './lib/groups.component';
|
|
8
12
|
export * from './lib/models/create-group.model';
|
|
9
13
|
export * from './lib/models/group-action.model';
|
|
@@ -26,6 +30,7 @@ export * from './lib/models/parent-groups-info.model';
|
|
|
26
30
|
export * from './lib/models/reciprocal-credit.model';
|
|
27
31
|
export * from './lib/services/groups.service';
|
|
28
32
|
export * from './lib/services/roster-export.service';
|
|
33
|
+
export * from './lib/services/roster-import-api.service';
|
|
29
34
|
export * from './lib/models/roster-import.model';
|
|
30
35
|
export * from './lib/assets/form-validations';
|
|
31
36
|
export * from './lib/groups.module';
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { RosterImportMockScenario, RosterUploadStatus, } from '../models/roster-import.model';
|
|
2
|
-
/**
|
|
3
|
-
* Mock responses for the roster import flow, used to build and exercise the UI
|
|
4
|
-
* before the real backend API is available. Each scenario maps to one of the
|
|
5
|
-
* Figma result screens.
|
|
6
|
-
*
|
|
7
|
-
* Once the API is wired up, `RosterImportComponent` will call the real service
|
|
8
|
-
* method instead of `RosterImportMocks.getMockResponse(...)`.
|
|
9
|
-
*/
|
|
10
|
-
export class RosterImportMocks {
|
|
11
|
-
/** Row errors mirroring the Figma "All Rows are skipped" screen. */
|
|
12
|
-
static { this.mockRowErrors = [
|
|
13
|
-
{
|
|
14
|
-
rowNumber: 2,
|
|
15
|
-
field: 'Name',
|
|
16
|
-
errorMessage: '"Name" record is missing values',
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
rowNumber: 3,
|
|
20
|
-
field: 'Email',
|
|
21
|
-
errorMessage: '"Email" is not a valid email address',
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
rowNumber: 4,
|
|
25
|
-
field: 'Role',
|
|
26
|
-
value: 'Supervisor',
|
|
27
|
-
errorMessage: 'Role "Supervisor" is not an allowed role',
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
rowNumber: 5,
|
|
31
|
-
field: 'Member Type',
|
|
32
|
-
value: 'Gold Member',
|
|
33
|
-
errorMessage: 'Member Type "Gold Member" is not an allowed value',
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
rowNumber: 6,
|
|
37
|
-
field: 'Member Type',
|
|
38
|
-
value: 'Gold Member',
|
|
39
|
-
errorMessage: 'Member Type "Gold Member" is not an allowed value',
|
|
40
|
-
},
|
|
41
|
-
]; }
|
|
42
|
-
/** All 30 rows added successfully (Figma: 30 / 0). */
|
|
43
|
-
static { this.allSuccess = {
|
|
44
|
-
uploadJobId: 'MOCK_JOB_SUCCESS',
|
|
45
|
-
status: RosterUploadStatus.COMPLETED,
|
|
46
|
-
totalRecords: 30,
|
|
47
|
-
successCount: 30,
|
|
48
|
-
failureCount: 0,
|
|
49
|
-
rowErrors: [],
|
|
50
|
-
}; }
|
|
51
|
-
/** Partial import: some added, some skipped. */
|
|
52
|
-
static { this.partial = {
|
|
53
|
-
uploadJobId: 'MOCK_JOB_PARTIAL',
|
|
54
|
-
status: RosterUploadStatus.COMPLETED,
|
|
55
|
-
totalRecords: 30,
|
|
56
|
-
successCount: 25,
|
|
57
|
-
failureCount: 5,
|
|
58
|
-
rowErrors: RosterImportMocks.mockRowErrors,
|
|
59
|
-
}; }
|
|
60
|
-
/** Every row skipped (Figma: 0 / 30, "All Rows are skipped"). */
|
|
61
|
-
static { this.allSkipped = {
|
|
62
|
-
uploadJobId: 'MOCK_JOB_SKIPPED',
|
|
63
|
-
status: RosterUploadStatus.COMPLETED,
|
|
64
|
-
totalRecords: 30,
|
|
65
|
-
successCount: 0,
|
|
66
|
-
failureCount: 30,
|
|
67
|
-
rowErrors: RosterImportMocks.mockRowErrors,
|
|
68
|
-
}; }
|
|
69
|
-
/** Headers only, zero data rows (Figma: "No roster data found"). */
|
|
70
|
-
static { this.empty = {
|
|
71
|
-
uploadJobId: 'MOCK_JOB_EMPTY',
|
|
72
|
-
status: RosterUploadStatus.COMPLETED,
|
|
73
|
-
totalRecords: 0,
|
|
74
|
-
successCount: 0,
|
|
75
|
-
failureCount: 0,
|
|
76
|
-
rowErrors: [],
|
|
77
|
-
}; }
|
|
78
|
-
/**
|
|
79
|
-
* Returns the mock upload response for a given scenario.
|
|
80
|
-
* @param {RosterImportMockScenario} scenario - The scenario to simulate.
|
|
81
|
-
* @return {RosterUploadResponse}
|
|
82
|
-
*/
|
|
83
|
-
static getMockResponse(scenario) {
|
|
84
|
-
switch (scenario) {
|
|
85
|
-
case RosterImportMockScenario.ALL_SUCCESS:
|
|
86
|
-
return RosterImportMocks.allSuccess;
|
|
87
|
-
case RosterImportMockScenario.PARTIAL:
|
|
88
|
-
return RosterImportMocks.partial;
|
|
89
|
-
case RosterImportMockScenario.ALL_SKIPPED:
|
|
90
|
-
return RosterImportMocks.allSkipped;
|
|
91
|
-
case RosterImportMockScenario.EMPTY:
|
|
92
|
-
return RosterImportMocks.empty;
|
|
93
|
-
default:
|
|
94
|
-
return RosterImportMocks.allSuccess;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm9zdGVyLWltcG9ydC1tb2Nrcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2dyb3Vwcy9zcmMvbGliL2Fzc2V0cy9yb3N0ZXItaW1wb3J0LW1vY2tzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx3QkFBd0IsRUFHeEIsa0JBQWtCLEdBQ25CLE1BQU0sK0JBQStCLENBQUM7QUFFdkM7Ozs7Ozs7R0FPRztBQUNILE1BQU0sT0FBTyxpQkFBaUI7SUFDNUIsb0VBQW9FO2FBQ3BELGtCQUFhLEdBQXdCO1FBQ25EO1lBQ0UsU0FBUyxFQUFFLENBQUM7WUFDWixLQUFLLEVBQUUsTUFBTTtZQUNiLFlBQVksRUFBRSxpQ0FBaUM7U0FDaEQ7UUFDRDtZQUNFLFNBQVMsRUFBRSxDQUFDO1lBQ1osS0FBSyxFQUFFLE9BQU87WUFDZCxZQUFZLEVBQUUsc0NBQXNDO1NBQ3JEO1FBQ0Q7WUFDRSxTQUFTLEVBQUUsQ0FBQztZQUNaLEtBQUssRUFBRSxNQUFNO1lBQ2IsS0FBSyxFQUFFLFlBQVk7WUFDbkIsWUFBWSxFQUFFLDBDQUEwQztTQUN6RDtRQUNEO1lBQ0UsU0FBUyxFQUFFLENBQUM7WUFDWixLQUFLLEVBQUUsYUFBYTtZQUNwQixLQUFLLEVBQUUsYUFBYTtZQUNwQixZQUFZLEVBQUUsbURBQW1EO1NBQ2xFO1FBQ0Q7WUFDRSxTQUFTLEVBQUUsQ0FBQztZQUNaLEtBQUssRUFBRSxhQUFhO1lBQ3BCLEtBQUssRUFBRSxhQUFhO1lBQ3BCLFlBQVksRUFBRSxtREFBbUQ7U0FDbEU7S0FDRixDQUFDO0lBRUYsc0RBQXNEO2FBQ3RDLGVBQVUsR0FBeUI7UUFDakQsV0FBVyxFQUFFLGtCQUFrQjtRQUMvQixNQUFNLEVBQUUsa0JBQWtCLENBQUMsU0FBUztRQUNwQyxZQUFZLEVBQUUsRUFBRTtRQUNoQixZQUFZLEVBQUUsRUFBRTtRQUNoQixZQUFZLEVBQUUsQ0FBQztRQUNmLFNBQVMsRUFBRSxFQUFFO0tBQ2QsQ0FBQztJQUVGLGdEQUFnRDthQUNoQyxZQUFPLEdBQXlCO1FBQzlDLFdBQVcsRUFBRSxrQkFBa0I7UUFDL0IsTUFBTSxFQUFFLGtCQUFrQixDQUFDLFNBQVM7UUFDcEMsWUFBWSxFQUFFLEVBQUU7UUFDaEIsWUFBWSxFQUFFLEVBQUU7UUFDaEIsWUFBWSxFQUFFLENBQUM7UUFDZixTQUFTLEVBQUUsaUJBQWlCLENBQUMsYUFBYTtLQUMzQyxDQUFDO0lBRUYsaUVBQWlFO2FBQ2pELGVBQVUsR0FBeUI7UUFDakQsV0FBVyxFQUFFLGtCQUFrQjtRQUMvQixNQUFNLEVBQUUsa0JBQWtCLENBQUMsU0FBUztRQUNwQyxZQUFZLEVBQUUsRUFBRTtRQUNoQixZQUFZLEVBQUUsQ0FBQztRQUNmLFlBQVksRUFBRSxFQUFFO1FBQ2hCLFNBQVMsRUFBRSxpQkFBaUIsQ0FBQyxhQUFhO0tBQzNDLENBQUM7SUFFRixvRUFBb0U7YUFDcEQsVUFBSyxHQUF5QjtRQUM1QyxXQUFXLEVBQUUsZ0JBQWdCO1FBQzdCLE1BQU0sRUFBRSxrQkFBa0IsQ0FBQyxTQUFTO1FBQ3BDLFlBQVksRUFBRSxDQUFDO1FBQ2YsWUFBWSxFQUFFLENBQUM7UUFDZixZQUFZLEVBQUUsQ0FBQztRQUNmLFNBQVMsRUFBRSxFQUFFO0tBQ2QsQ0FBQztJQUVGOzs7O09BSUc7SUFDSCxNQUFNLENBQUMsZUFBZSxDQUNwQixRQUFrQztRQUVsQyxRQUFRLFFBQVEsRUFBRTtZQUNoQixLQUFLLHdCQUF3QixDQUFDLFdBQVc7Z0JBQ3ZDLE9BQU8saUJBQWlCLENBQUMsVUFBVSxDQUFDO1lBQ3RDLEtBQUssd0JBQXdCLENBQUMsT0FBTztnQkFDbkMsT0FBTyxpQkFBaUIsQ0FBQyxPQUFPLENBQUM7WUFDbkMsS0FBSyx3QkFBd0IsQ0FBQyxXQUFXO2dCQUN2QyxPQUFPLGlCQUFpQixDQUFDLFVBQVUsQ0FBQztZQUN0QyxLQUFLLHdCQUF3QixDQUFDLEtBQUs7Z0JBQ2pDLE9BQU8saUJBQWlCLENBQUMsS0FBSyxDQUFDO1lBQ2pDO2dCQUNFLE9BQU8saUJBQWlCLENBQUMsVUFBVSxDQUFDO1NBQ3ZDO0lBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgUm9zdGVySW1wb3J0TW9ja1NjZW5hcmlvLFxyXG4gIFJvc3RlclVwbG9hZEVycm9yLFxyXG4gIFJvc3RlclVwbG9hZFJlc3BvbnNlLFxyXG4gIFJvc3RlclVwbG9hZFN0YXR1cyxcclxufSBmcm9tICcuLi9tb2RlbHMvcm9zdGVyLWltcG9ydC5tb2RlbCc7XHJcblxyXG4vKipcclxuICogTW9jayByZXNwb25zZXMgZm9yIHRoZSByb3N0ZXIgaW1wb3J0IGZsb3csIHVzZWQgdG8gYnVpbGQgYW5kIGV4ZXJjaXNlIHRoZSBVSVxyXG4gKiBiZWZvcmUgdGhlIHJlYWwgYmFja2VuZCBBUEkgaXMgYXZhaWxhYmxlLiBFYWNoIHNjZW5hcmlvIG1hcHMgdG8gb25lIG9mIHRoZVxyXG4gKiBGaWdtYSByZXN1bHQgc2NyZWVucy5cclxuICpcclxuICogT25jZSB0aGUgQVBJIGlzIHdpcmVkIHVwLCBgUm9zdGVySW1wb3J0Q29tcG9uZW50YCB3aWxsIGNhbGwgdGhlIHJlYWwgc2VydmljZVxyXG4gKiBtZXRob2QgaW5zdGVhZCBvZiBgUm9zdGVySW1wb3J0TW9ja3MuZ2V0TW9ja1Jlc3BvbnNlKC4uLilgLlxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIFJvc3RlckltcG9ydE1vY2tzIHtcclxuICAvKiogUm93IGVycm9ycyBtaXJyb3JpbmcgdGhlIEZpZ21hIFwiQWxsIFJvd3MgYXJlIHNraXBwZWRcIiBzY3JlZW4uICovXHJcbiAgc3RhdGljIHJlYWRvbmx5IG1vY2tSb3dFcnJvcnM6IFJvc3RlclVwbG9hZEVycm9yW10gPSBbXHJcbiAgICB7XHJcbiAgICAgIHJvd051bWJlcjogMixcclxuICAgICAgZmllbGQ6ICdOYW1lJyxcclxuICAgICAgZXJyb3JNZXNzYWdlOiAnXCJOYW1lXCIgcmVjb3JkIGlzIG1pc3NpbmcgdmFsdWVzJyxcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIHJvd051bWJlcjogMyxcclxuICAgICAgZmllbGQ6ICdFbWFpbCcsXHJcbiAgICAgIGVycm9yTWVzc2FnZTogJ1wiRW1haWxcIiBpcyBub3QgYSB2YWxpZCBlbWFpbCBhZGRyZXNzJyxcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIHJvd051bWJlcjogNCxcclxuICAgICAgZmllbGQ6ICdSb2xlJyxcclxuICAgICAgdmFsdWU6ICdTdXBlcnZpc29yJyxcclxuICAgICAgZXJyb3JNZXNzYWdlOiAnUm9sZSBcIlN1cGVydmlzb3JcIiBpcyBub3QgYW4gYWxsb3dlZCByb2xlJyxcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIHJvd051bWJlcjogNSxcclxuICAgICAgZmllbGQ6ICdNZW1iZXIgVHlwZScsXHJcbiAgICAgIHZhbHVlOiAnR29sZCBNZW1iZXInLFxyXG4gICAgICBlcnJvck1lc3NhZ2U6ICdNZW1iZXIgVHlwZSBcIkdvbGQgTWVtYmVyXCIgaXMgbm90IGFuIGFsbG93ZWQgdmFsdWUnLFxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgcm93TnVtYmVyOiA2LFxyXG4gICAgICBmaWVsZDogJ01lbWJlciBUeXBlJyxcclxuICAgICAgdmFsdWU6ICdHb2xkIE1lbWJlcicsXHJcbiAgICAgIGVycm9yTWVzc2FnZTogJ01lbWJlciBUeXBlIFwiR29sZCBNZW1iZXJcIiBpcyBub3QgYW4gYWxsb3dlZCB2YWx1ZScsXHJcbiAgICB9LFxyXG4gIF07XHJcblxyXG4gIC8qKiBBbGwgMzAgcm93cyBhZGRlZCBzdWNjZXNzZnVsbHkgKEZpZ21hOiAzMCAvIDApLiAqL1xyXG4gIHN0YXRpYyByZWFkb25seSBhbGxTdWNjZXNzOiBSb3N0ZXJVcGxvYWRSZXNwb25zZSA9IHtcclxuICAgIHVwbG9hZEpvYklkOiAnTU9DS19KT0JfU1VDQ0VTUycsXHJcbiAgICBzdGF0dXM6IFJvc3RlclVwbG9hZFN0YXR1cy5DT01QTEVURUQsXHJcbiAgICB0b3RhbFJlY29yZHM6IDMwLFxyXG4gICAgc3VjY2Vzc0NvdW50OiAzMCxcclxuICAgIGZhaWx1cmVDb3VudDogMCxcclxuICAgIHJvd0Vycm9yczogW10sXHJcbiAgfTtcclxuXHJcbiAgLyoqIFBhcnRpYWwgaW1wb3J0OiBzb21lIGFkZGVkLCBzb21lIHNraXBwZWQuICovXHJcbiAgc3RhdGljIHJlYWRvbmx5IHBhcnRpYWw6IFJvc3RlclVwbG9hZFJlc3BvbnNlID0ge1xyXG4gICAgdXBsb2FkSm9iSWQ6ICdNT0NLX0pPQl9QQVJUSUFMJyxcclxuICAgIHN0YXR1czogUm9zdGVyVXBsb2FkU3RhdHVzLkNPTVBMRVRFRCxcclxuICAgIHRvdGFsUmVjb3JkczogMzAsXHJcbiAgICBzdWNjZXNzQ291bnQ6IDI1LFxyXG4gICAgZmFpbHVyZUNvdW50OiA1LFxyXG4gICAgcm93RXJyb3JzOiBSb3N0ZXJJbXBvcnRNb2Nrcy5tb2NrUm93RXJyb3JzLFxyXG4gIH07XHJcblxyXG4gIC8qKiBFdmVyeSByb3cgc2tpcHBlZCAoRmlnbWE6IDAgLyAzMCwgXCJBbGwgUm93cyBhcmUgc2tpcHBlZFwiKS4gKi9cclxuICBzdGF0aWMgcmVhZG9ubHkgYWxsU2tpcHBlZDogUm9zdGVyVXBsb2FkUmVzcG9uc2UgPSB7XHJcbiAgICB1cGxvYWRKb2JJZDogJ01PQ0tfSk9CX1NLSVBQRUQnLFxyXG4gICAgc3RhdHVzOiBSb3N0ZXJVcGxvYWRTdGF0dXMuQ09NUExFVEVELFxyXG4gICAgdG90YWxSZWNvcmRzOiAzMCxcclxuICAgIHN1Y2Nlc3NDb3VudDogMCxcclxuICAgIGZhaWx1cmVDb3VudDogMzAsXHJcbiAgICByb3dFcnJvcnM6IFJvc3RlckltcG9ydE1vY2tzLm1vY2tSb3dFcnJvcnMsXHJcbiAgfTtcclxuXHJcbiAgLyoqIEhlYWRlcnMgb25seSwgemVybyBkYXRhIHJvd3MgKEZpZ21hOiBcIk5vIHJvc3RlciBkYXRhIGZvdW5kXCIpLiAqL1xyXG4gIHN0YXRpYyByZWFkb25seSBlbXB0eTogUm9zdGVyVXBsb2FkUmVzcG9uc2UgPSB7XHJcbiAgICB1cGxvYWRKb2JJZDogJ01PQ0tfSk9CX0VNUFRZJyxcclxuICAgIHN0YXR1czogUm9zdGVyVXBsb2FkU3RhdHVzLkNPTVBMRVRFRCxcclxuICAgIHRvdGFsUmVjb3JkczogMCxcclxuICAgIHN1Y2Nlc3NDb3VudDogMCxcclxuICAgIGZhaWx1cmVDb3VudDogMCxcclxuICAgIHJvd0Vycm9yczogW10sXHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogUmV0dXJucyB0aGUgbW9jayB1cGxvYWQgcmVzcG9uc2UgZm9yIGEgZ2l2ZW4gc2NlbmFyaW8uXHJcbiAgICogQHBhcmFtIHtSb3N0ZXJJbXBvcnRNb2NrU2NlbmFyaW99IHNjZW5hcmlvIC0gVGhlIHNjZW5hcmlvIHRvIHNpbXVsYXRlLlxyXG4gICAqIEByZXR1cm4ge1Jvc3RlclVwbG9hZFJlc3BvbnNlfVxyXG4gICAqL1xyXG4gIHN0YXRpYyBnZXRNb2NrUmVzcG9uc2UoXHJcbiAgICBzY2VuYXJpbzogUm9zdGVySW1wb3J0TW9ja1NjZW5hcmlvXHJcbiAgKTogUm9zdGVyVXBsb2FkUmVzcG9uc2Uge1xyXG4gICAgc3dpdGNoIChzY2VuYXJpbykge1xyXG4gICAgICBjYXNlIFJvc3RlckltcG9ydE1vY2tTY2VuYXJpby5BTExfU1VDQ0VTUzpcclxuICAgICAgICByZXR1cm4gUm9zdGVySW1wb3J0TW9ja3MuYWxsU3VjY2VzcztcclxuICAgICAgY2FzZSBSb3N0ZXJJbXBvcnRNb2NrU2NlbmFyaW8uUEFSVElBTDpcclxuICAgICAgICByZXR1cm4gUm9zdGVySW1wb3J0TW9ja3MucGFydGlhbDtcclxuICAgICAgY2FzZSBSb3N0ZXJJbXBvcnRNb2NrU2NlbmFyaW8uQUxMX1NLSVBQRUQ6XHJcbiAgICAgICAgcmV0dXJuIFJvc3RlckltcG9ydE1vY2tzLmFsbFNraXBwZWQ7XHJcbiAgICAgIGNhc2UgUm9zdGVySW1wb3J0TW9ja1NjZW5hcmlvLkVNUFRZOlxyXG4gICAgICAgIHJldHVybiBSb3N0ZXJJbXBvcnRNb2Nrcy5lbXB0eTtcclxuICAgICAgZGVmYXVsdDpcclxuICAgICAgICByZXR1cm4gUm9zdGVySW1wb3J0TW9ja3MuYWxsU3VjY2VzcztcclxuICAgIH1cclxuICB9XHJcbn1cclxuIl19
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { RosterImportMockScenario, RosterUploadError, RosterUploadResponse } from '../models/roster-import.model';
|
|
2
|
-
/**
|
|
3
|
-
* Mock responses for the roster import flow, used to build and exercise the UI
|
|
4
|
-
* before the real backend API is available. Each scenario maps to one of the
|
|
5
|
-
* Figma result screens.
|
|
6
|
-
*
|
|
7
|
-
* Once the API is wired up, `RosterImportComponent` will call the real service
|
|
8
|
-
* method instead of `RosterImportMocks.getMockResponse(...)`.
|
|
9
|
-
*/
|
|
10
|
-
export declare class RosterImportMocks {
|
|
11
|
-
/** Row errors mirroring the Figma "All Rows are skipped" screen. */
|
|
12
|
-
static readonly mockRowErrors: RosterUploadError[];
|
|
13
|
-
/** All 30 rows added successfully (Figma: 30 / 0). */
|
|
14
|
-
static readonly allSuccess: RosterUploadResponse;
|
|
15
|
-
/** Partial import: some added, some skipped. */
|
|
16
|
-
static readonly partial: RosterUploadResponse;
|
|
17
|
-
/** Every row skipped (Figma: 0 / 30, "All Rows are skipped"). */
|
|
18
|
-
static readonly allSkipped: RosterUploadResponse;
|
|
19
|
-
/** Headers only, zero data rows (Figma: "No roster data found"). */
|
|
20
|
-
static readonly empty: RosterUploadResponse;
|
|
21
|
-
/**
|
|
22
|
-
* Returns the mock upload response for a given scenario.
|
|
23
|
-
* @param {RosterImportMockScenario} scenario - The scenario to simulate.
|
|
24
|
-
* @return {RosterUploadResponse}
|
|
25
|
-
*/
|
|
26
|
-
static getMockResponse(scenario: RosterImportMockScenario): RosterUploadResponse;
|
|
27
|
-
}
|