@ieeesa-npm/groups 0.15.9 → 0.15.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/esm2022/lib/assets/constants.json +87 -4
  2. package/esm2022/lib/components/interest-form/interest-form.component.mjs +104 -0
  3. package/esm2022/lib/components/interest-form-management/interest-form-management.component.mjs +63 -0
  4. package/esm2022/lib/components/interested-rosters/interested-rosters.component.mjs +28 -0
  5. package/esm2022/lib/components/roster-import/roster-import.component.mjs +243 -84
  6. package/esm2022/lib/components/roster-import-history/roster-import-history.component.mjs +232 -0
  7. package/esm2022/lib/components/tree-view/tree-view.component.mjs +26 -5
  8. package/esm2022/lib/components/view-roster/view-roster.component.mjs +10 -3
  9. package/esm2022/lib/groups.component.mjs +82 -6
  10. package/esm2022/lib/models/group-action.model.mjs +2 -1
  11. package/esm2022/lib/models/group-function-type.model.mjs +2 -1
  12. package/esm2022/lib/models/permission-type.model.mjs +2 -1
  13. package/esm2022/lib/models/roster-import.model.mjs +34 -17
  14. package/esm2022/lib/services/groups.service.mjs +24 -1
  15. package/esm2022/lib/services/roster-import-api.service.mjs +174 -0
  16. package/esm2022/public-api.mjs +6 -1
  17. package/fesm2022/ieeesa-npm-groups.mjs +1081 -213
  18. package/fesm2022/ieeesa-npm-groups.mjs.map +1 -1
  19. package/lib/components/interest-form/interest-form.component.d.ts +75 -0
  20. package/lib/components/interest-form-management/interest-form-management.component.d.ts +31 -0
  21. package/lib/components/interested-rosters/interested-rosters.component.d.ts +17 -0
  22. package/lib/components/roster-import/roster-import.component.d.ts +116 -37
  23. package/lib/components/roster-import-history/roster-import-history.component.d.ts +102 -0
  24. package/lib/components/tree-view/tree-view.component.d.ts +6 -3
  25. package/lib/components/view-roster/view-roster.component.d.ts +5 -0
  26. package/lib/groups.component.d.ts +31 -1
  27. package/lib/models/group-action.model.d.ts +2 -1
  28. package/lib/models/group-function-type.model.d.ts +2 -1
  29. package/lib/models/permission-type.model.d.ts +2 -1
  30. package/lib/models/roster-import.model.d.ts +107 -21
  31. package/lib/services/groups.service.d.ts +24 -0
  32. package/lib/services/roster-import-api.service.d.ts +108 -0
  33. package/package.json +1 -1
  34. package/public-api.d.ts +5 -0
  35. package/esm2022/lib/assets/roster-import-mocks.mjs +0 -98
  36. package/lib/assets/roster-import-mocks.d.ts +0 -27
@@ -1,5 +1,104 @@
1
1
  /**
2
- * Terminal status of a roster bulk-upload job.
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 from the BE `error_report` JSONB column. Observed to arrive
59
+ * EITHER as a parsed object `{ rows: RosterImportErrorReport[] }` OR as a raw
60
+ * JSON string of the same shape (depending on serialization). A bare array is
61
+ * also tolerated. `null` when there are no row errors. The client normalizes
62
+ * all of these — see RosterImportComponent.parseErrorReport.
63
+ */
64
+ errorReport?: any;
65
+ }
66
+ /**
67
+ * Per-row validation outcome in a validate/preview response. Mirrors the BE
68
+ * `RosterImportRowOutcome` POJO.
69
+ */
70
+ export interface RosterImportRowOutcome {
71
+ /** 1-based data-row number in the uploaded file. */
72
+ row: number;
73
+ /** Whether this row passed validation. */
74
+ valid: boolean;
75
+ /** The field/column the error relates to, for an invalid row. */
76
+ field?: string;
77
+ /** Validation error message, for an invalid row. */
78
+ error?: string;
79
+ }
80
+ /**
81
+ * Validation preview returned by validate / preview. Mirrors the BE
82
+ * `RosterImportPreview` POJO. Building a preview commits no roster changes.
83
+ * `rows` is never null (BE guarantees an empty list at minimum).
84
+ */
85
+ export interface RosterImportPreview {
86
+ /** Import job identifier. */
87
+ importId: string;
88
+ /** Current status (see {@link RosterImportStatus}). */
89
+ status: string;
90
+ /** Total data rows (`totalRows = successRows + failedRows`). */
91
+ totalRows: number;
92
+ /** Rows that passed validation. */
93
+ successRows: number;
94
+ /** Rows that failed validation. */
95
+ failedRows: number;
96
+ /** Per-row outcomes (never null). */
97
+ rows: RosterImportRowOutcome[];
98
+ }
99
+ /**
100
+ * @deprecated Use {@link RosterImportStatus} instead. Retained for backward
101
+ * compatibility with the pre-BE-integration public API.
3
102
  */
4
103
  export declare enum RosterUploadStatus {
5
104
  PROCESSING = "PROCESSING",
@@ -7,7 +106,9 @@ export declare enum RosterUploadStatus {
7
106
  FAILED = "FAILED"
8
107
  }
9
108
  /**
10
- * A single row-level error from the roster import validation.
109
+ * @deprecated Use {@link RosterImportErrorReport} (`{ row, field, message }`)
110
+ * or {@link RosterImportRowOutcome} instead. Retained for backward
111
+ * compatibility with the pre-BE-integration public API.
11
112
  */
12
113
  export interface RosterUploadError {
13
114
  /** 1-based row number in the uploaded file. */
@@ -20,13 +121,12 @@ export interface RosterUploadError {
20
121
  errorMessage: string;
21
122
  }
22
123
  /**
23
- * Terminal result of a roster bulk-upload job.
24
- *
25
- * NOTE: This is a MOCK-friendly shape used to build the UI before the real API
26
- * is available. It will be reconciled with the backend contract once shared.
124
+ * @deprecated Use {@link RosterImportJob} (confirm/history) or
125
+ * {@link RosterImportPreview} (validate) instead. Retained for backward
126
+ * compatibility with the pre-BE-integration public API.
27
127
  */
28
128
  export interface RosterUploadResponse {
29
- /** Job identifier (unused by the mock flow, kept for parity with the API). */
129
+ /** Job identifier. */
30
130
  uploadJobId?: string;
31
131
  /** Terminal job status. */
32
132
  status: RosterUploadStatus;
@@ -39,17 +139,3 @@ export interface RosterUploadResponse {
39
139
  /** Row-level errors (present when failureCount > 0). */
40
140
  rowErrors: RosterUploadError[];
41
141
  }
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
- }
@@ -77,6 +77,11 @@ export declare class GroupsService {
77
77
  "1037": string;
78
78
  "1038": string;
79
79
  "1039": string;
80
+ "1071": string;
81
+ "1072": string;
82
+ "1073": string;
83
+ "1074": string;
84
+ "1075": string;
80
85
  "2001": string;
81
86
  "2002": string;
82
87
  "2010": string;
@@ -102,6 +107,13 @@ export declare class GroupsService {
102
107
  };
103
108
  apiBaseUrl: string;
104
109
  userPermission: any;
110
+ /**
111
+ * Tenant-level required profile fields (e.g. ['phone','address','employer'])
112
+ * supplied by the host app from its cached tenant configuration. Consumed by
113
+ * the roster import to append tenant-mandated columns to the required-column
114
+ * list and the sample file. Empty when the tenant has none configured.
115
+ */
116
+ requiredProfileFields: string[];
105
117
  selectedGroupInfo: GroupInfo | undefined;
106
118
  groupFunctionType: GroupFunctionType;
107
119
  selectedGroupParentInfo: GroupInfo | undefined;
@@ -118,6 +130,18 @@ export declare class GroupsService {
118
130
  representingOrganizations: RepresentingOrganization[];
119
131
  constructor(httpService: HttpService, userPermissionsService: UserPermissionsService, groupPermissionsService: GroupPermissionsMapService, alertService: AlertsService);
120
132
  setAppConfig(apiBaseUrl: string, userPermission: any): void;
133
+ /**
134
+ * Stores the tenant-level required profile fields provided by the host app.
135
+ * @param {string[]} requiredProfileFields - Field keys (e.g. 'phone').
136
+ * @memberof GroupsService
137
+ */
138
+ setRequiredProfileFields(requiredProfileFields: string[]): void;
139
+ /**
140
+ * Returns the tenant-level required profile fields (never null).
141
+ * @return {string[]}
142
+ * @memberof GroupsService
143
+ */
144
+ getRequiredProfileFields(): string[];
121
145
  /**
122
146
  * Gets application group types from API and returns it as an observable.
123
147
  * @return {Observable<GroupTypeResponse>} -It returns group types if success else error.
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ieeesa-npm/groups",
3
- "version": "0.15.9",
3
+ "version": "0.15.11",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^16.1.0",
6
6
  "@angular/core": "^16.1.0"
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
- }