@rolatech/angular-onboarding 20.3.0-beta.2 → 20.3.0-beta.3

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 (41) hide show
  1. package/fesm2022/rolatech-angular-onboarding-admin-onboarding-detail-page-DD-5SdjA.mjs +708 -0
  2. package/fesm2022/rolatech-angular-onboarding-admin-onboarding-detail-page-DD-5SdjA.mjs.map +1 -0
  3. package/fesm2022/rolatech-angular-onboarding-admin-onboarding-index-page-DP7wffLd.mjs +313 -0
  4. package/fesm2022/rolatech-angular-onboarding-admin-onboarding-index-page-DP7wffLd.mjs.map +1 -0
  5. package/fesm2022/rolatech-angular-onboarding-agent-apply-form-page-y02hYlN_.mjs +446 -0
  6. package/fesm2022/rolatech-angular-onboarding-agent-apply-form-page-y02hYlN_.mjs.map +1 -0
  7. package/fesm2022/rolatech-angular-onboarding-agent-apply-result-page-CEL4nWb_.mjs +141 -0
  8. package/fesm2022/rolatech-angular-onboarding-agent-apply-result-page-CEL4nWb_.mjs.map +1 -0
  9. package/fesm2022/rolatech-angular-onboarding-agent-apply-review-page-DG_D03YW.mjs +453 -0
  10. package/fesm2022/rolatech-angular-onboarding-agent-apply-review-page-DG_D03YW.mjs.map +1 -0
  11. package/fesm2022/{rolatech-angular-onboarding-agent-apply-shell-page-DibWYeD1.mjs → rolatech-angular-onboarding-agent-apply-shell-page-CaTvnFzk.mjs} +27 -40
  12. package/fesm2022/rolatech-angular-onboarding-agent-apply-shell-page-CaTvnFzk.mjs.map +1 -0
  13. package/fesm2022/{rolatech-angular-onboarding-agent-apply-start-page-DC7gyOnS.mjs → rolatech-angular-onboarding-agent-apply-start-page-BfqO2YWB.mjs} +31 -29
  14. package/fesm2022/rolatech-angular-onboarding-agent-apply-start-page-BfqO2YWB.mjs.map +1 -0
  15. package/fesm2022/{rolatech-angular-onboarding-agent-onboarding-documents-page-DWBGTj5J.mjs → rolatech-angular-onboarding-agent-onboarding-documents-page-BKDYZE0e.mjs} +79 -6
  16. package/fesm2022/rolatech-angular-onboarding-agent-onboarding-documents-page-BKDYZE0e.mjs.map +1 -0
  17. package/fesm2022/rolatech-angular-onboarding.mjs +2252 -234
  18. package/fesm2022/rolatech-angular-onboarding.mjs.map +1 -1
  19. package/package.json +1 -1
  20. package/types/rolatech-angular-onboarding.d.ts +219 -12
  21. package/fesm2022/rolatech-angular-onboarding-admin-onboarding-detail-page-DKJQX3cs.mjs +0 -224
  22. package/fesm2022/rolatech-angular-onboarding-admin-onboarding-detail-page-DKJQX3cs.mjs.map +0 -1
  23. package/fesm2022/rolatech-angular-onboarding-admin-onboarding-index-page-BO4pC_NU.mjs +0 -206
  24. package/fesm2022/rolatech-angular-onboarding-admin-onboarding-index-page-BO4pC_NU.mjs.map +0 -1
  25. package/fesm2022/rolatech-angular-onboarding-admin-onboarding-review-page-BERcLBeQ.mjs +0 -419
  26. package/fesm2022/rolatech-angular-onboarding-admin-onboarding-review-page-BERcLBeQ.mjs.map +0 -1
  27. package/fesm2022/rolatech-angular-onboarding-agent-apply-banking-page-VYNfR4fy.mjs +0 -133
  28. package/fesm2022/rolatech-angular-onboarding-agent-apply-banking-page-VYNfR4fy.mjs.map +0 -1
  29. package/fesm2022/rolatech-angular-onboarding-agent-apply-financial-page-Ck3Rowke.mjs +0 -132
  30. package/fesm2022/rolatech-angular-onboarding-agent-apply-financial-page-Ck3Rowke.mjs.map +0 -1
  31. package/fesm2022/rolatech-angular-onboarding-agent-apply-profile-page-DNepDxHu.mjs +0 -122
  32. package/fesm2022/rolatech-angular-onboarding-agent-apply-profile-page-DNepDxHu.mjs.map +0 -1
  33. package/fesm2022/rolatech-angular-onboarding-agent-apply-qualification-page-CSwupuKt.mjs +0 -108
  34. package/fesm2022/rolatech-angular-onboarding-agent-apply-qualification-page-CSwupuKt.mjs.map +0 -1
  35. package/fesm2022/rolatech-angular-onboarding-agent-apply-review-page-DugCjfvK.mjs +0 -182
  36. package/fesm2022/rolatech-angular-onboarding-agent-apply-review-page-DugCjfvK.mjs.map +0 -1
  37. package/fesm2022/rolatech-angular-onboarding-agent-apply-shell-page-DibWYeD1.mjs.map +0 -1
  38. package/fesm2022/rolatech-angular-onboarding-agent-apply-start-page-DC7gyOnS.mjs.map +0 -1
  39. package/fesm2022/rolatech-angular-onboarding-agent-apply-submitted-page-BMkV2V8K.mjs +0 -55
  40. package/fesm2022/rolatech-angular-onboarding-agent-apply-submitted-page-BMkV2V8K.mjs.map +0 -1
  41. package/fesm2022/rolatech-angular-onboarding-agent-onboarding-documents-page-DWBGTj5J.mjs.map +0 -1
@@ -0,0 +1,708 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, signal, computed, effect, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { toSignal } from '@angular/core/rxjs-interop';
4
+ import { ActivatedRoute, RouterLink } from '@angular/router';
5
+ import { onboardingApplicantTypeLabel, onboardingStatusLabel, onboardingVatModeLabel, onboardingDocumentTypeLabel } from '@rolatech/angular-services';
6
+ import { PlatformPageHeader, PlatformStatCard } from '@rolatech/angular-platform';
7
+ import { AdminOnboardingReviewFacade, onboardingFieldIssueOptions, onboardingDocumentIssueOptions, OnboardingStatusBadge, OnboardingIssueList, OnboardingTimelineDrawer, OnboardingReviewRow, OnboardingReviewIssuesBanner, OnboardingDocumentPreviewDialog } from './rolatech-angular-onboarding.mjs';
8
+
9
+ class AdminOnboardingDetailPage {
10
+ facade = inject(AdminOnboardingReviewFacade);
11
+ timelineOpen = signal(false, ...(ngDevMode ? [{ debugName: "timelineOpen" }] : []));
12
+ previewOpen = signal(false, ...(ngDevMode ? [{ debugName: "previewOpen" }] : []));
13
+ previewTitle = signal(null, ...(ngDevMode ? [{ debugName: "previewTitle" }] : []));
14
+ previewSubtitle = signal(null, ...(ngDevMode ? [{ debugName: "previewSubtitle" }] : []));
15
+ onboardingApplicantTypeLabel = onboardingApplicantTypeLabel;
16
+ onboardingStatusLabel = onboardingStatusLabel;
17
+ route = inject(ActivatedRoute);
18
+ paramMap = toSignal(this.route.paramMap, {
19
+ initialValue: this.route.snapshot.paramMap,
20
+ });
21
+ subtitle = computed(() => {
22
+ const detail = this.facade.detail();
23
+ if (!detail) {
24
+ return 'Inspect onboarding data and triage approvals inline.';
25
+ }
26
+ return `${detail.organizationName || detail.contactName || 'Applicant'} • ${detail.contactEmail || 'No email'}`;
27
+ }, ...(ngDevMode ? [{ debugName: "subtitle" }] : []));
28
+ title = computed(() => {
29
+ const detail = this.facade.detail();
30
+ if (!detail) {
31
+ return 'Agent Application Review';
32
+ }
33
+ return detail.organizationName || detail.contactName || 'Agent Application Review';
34
+ }, ...(ngDevMode ? [{ debugName: "title" }] : []));
35
+ documentCount = computed(() => this.facade.detail()?.documents.length ?? 0, ...(ngDevMode ? [{ debugName: "documentCount" }] : []));
36
+ timelineCount = computed(() => this.facade.detail()?.timeline.length ?? 0, ...(ngDevMode ? [{ debugName: "timelineCount" }] : []));
37
+ openIssueCount = computed(() => (this.facade.detail()?.issues ?? []).filter((issue) => !issue.resolved).length, ...(ngDevMode ? [{ debugName: "openIssueCount" }] : []));
38
+ profileItems = computed(() => {
39
+ const detail = this.facade.detail();
40
+ if (!detail) {
41
+ return [];
42
+ }
43
+ return [
44
+ ...(detail.applicantType === 'COMPANY'
45
+ ? [{ key: 'organizationName', label: 'Company legal name', value: detail.organizationName, helper: '' }]
46
+ : [{ key: 'contactName', label: 'Applicant name', value: detail.contactName, helper: '' }]),
47
+ ...(detail.applicantType === 'COMPANY'
48
+ ? [{ key: 'contactName', label: 'Primary contact', value: detail.contactName, helper: '' }]
49
+ : []),
50
+ { key: 'contactEmail', label: 'Primary email', value: detail.contactEmail, helper: '' },
51
+ { key: 'contactPhone', label: 'Phone number', value: detail.contactPhone, helper: '' },
52
+ { key: 'countryCode', label: 'Country code', value: detail.countryCode, helper: '' },
53
+ ];
54
+ }, ...(ngDevMode ? [{ debugName: "profileItems" }] : []));
55
+ complianceItems = computed(() => {
56
+ const detail = this.facade.detail();
57
+ if (!detail) {
58
+ return [];
59
+ }
60
+ return [
61
+ { key: 'vatMode', label: 'VAT mode', value: onboardingVatModeLabel(detail.vatMode ?? null), helper: '' },
62
+ { key: 'vatNumber', label: 'VAT number', value: detail.vatNumber || 'Missing', helper: '' },
63
+ { key: 'bankName', label: 'Bank name', value: detail.bankName, helper: '' },
64
+ { key: 'accountHolderName', label: 'Account holder', value: detail.accountHolderName, helper: '' },
65
+ { key: 'sortCode', label: 'Sort code', value: detail.sortCode, helper: '' },
66
+ { key: 'accountNumber', label: 'Account number', value: detail.accountNumber, helper: '' },
67
+ ];
68
+ }, ...(ngDevMode ? [{ debugName: "complianceItems" }] : []));
69
+ documentItems = computed(() => {
70
+ const detail = this.facade.detail();
71
+ if (!detail) {
72
+ return [];
73
+ }
74
+ const requiredItems = this.facade.requiredDocuments().map((spec) => {
75
+ const document = detail.documents.find((item) => item.documentType === spec.type) ?? null;
76
+ return {
77
+ documentType: spec.type,
78
+ label: spec.label,
79
+ helper: spec.helperText ?? '',
80
+ document,
81
+ value: document?.originalFilename ?? 'Missing',
82
+ };
83
+ });
84
+ const requiredTypes = new Set(requiredItems.map((item) => item.documentType));
85
+ const additionalItems = detail.documents
86
+ .filter((item) => !requiredTypes.has(item.documentType))
87
+ .map((item) => ({
88
+ documentType: item.documentType,
89
+ label: `Additional: ${onboardingDocumentTypeLabel(item.documentType)}`,
90
+ helper: 'Supporting document uploaded by the applicant.',
91
+ document: item,
92
+ value: item.originalFilename,
93
+ }));
94
+ return [...requiredItems, ...additionalItems];
95
+ }, ...(ngDevMode ? [{ debugName: "documentItems" }] : []));
96
+ constructor() {
97
+ effect(() => {
98
+ const applicationId = this.paramMap().get('applicationId');
99
+ if (!applicationId) {
100
+ return;
101
+ }
102
+ void this.facade.load(applicationId);
103
+ });
104
+ }
105
+ setComment(event) {
106
+ const target = event.target;
107
+ this.facade.setComment(target.value);
108
+ }
109
+ fieldIssueOptions(fieldKey) {
110
+ return onboardingFieldIssueOptions(fieldKey);
111
+ }
112
+ documentIssueOptions(documentType) {
113
+ return onboardingDocumentIssueOptions(documentType);
114
+ }
115
+ onFieldIssue(fieldKey, draft) {
116
+ this.facade.setFieldIssueDraft(fieldKey, draft);
117
+ }
118
+ fieldExistingIssue(fieldKey) {
119
+ const existing = this.facade.existingFieldIssues();
120
+ return Object.prototype.hasOwnProperty.call(existing, fieldKey) ? existing[fieldKey] : null;
121
+ }
122
+ onFieldPassed(fieldKey, passed) {
123
+ this.facade.toggleFieldPassed(fieldKey, passed);
124
+ }
125
+ onDocumentIssue(documentType, draft) {
126
+ this.facade.setDocumentIssueDraft(documentType, draft);
127
+ }
128
+ documentExistingIssue(documentType) {
129
+ const existing = this.facade.existingDocumentIssues();
130
+ return existing[documentType] ?? null;
131
+ }
132
+ onDocumentPassed(documentType, passed) {
133
+ this.facade.toggleDocumentPassed(documentType, passed);
134
+ }
135
+ async openDocumentPreview(item) {
136
+ if (!item.document) {
137
+ return;
138
+ }
139
+ this.previewTitle.set(item.label);
140
+ this.previewSubtitle.set(item.document.originalFilename || null);
141
+ this.previewOpen.set(true);
142
+ await this.facade.openDocumentPreview(item.document.id);
143
+ }
144
+ async startReview() {
145
+ const applicationId = this.paramMap().get('applicationId');
146
+ if (!applicationId) {
147
+ return;
148
+ }
149
+ await this.facade.startReview(applicationId);
150
+ }
151
+ async needMoreInfo() {
152
+ const applicationId = this.paramMap().get('applicationId');
153
+ if (!applicationId) {
154
+ return;
155
+ }
156
+ await this.facade.requestMoreInfo(applicationId);
157
+ }
158
+ async approve() {
159
+ const applicationId = this.paramMap().get('applicationId');
160
+ if (!applicationId) {
161
+ return;
162
+ }
163
+ await this.facade.approve(applicationId);
164
+ }
165
+ async fail() {
166
+ const applicationId = this.paramMap().get('applicationId');
167
+ if (!applicationId) {
168
+ return;
169
+ }
170
+ await this.facade.fail(applicationId);
171
+ }
172
+ openTimeline() {
173
+ this.timelineOpen.set(true);
174
+ }
175
+ closeTimeline() {
176
+ this.timelineOpen.set(false);
177
+ }
178
+ closeDocumentPreview() {
179
+ this.previewOpen.set(false);
180
+ this.previewTitle.set(null);
181
+ this.previewSubtitle.set(null);
182
+ this.facade.clearDocumentPreview();
183
+ }
184
+ countryLabel(value) {
185
+ switch ((value ?? '').toUpperCase()) {
186
+ case 'CN':
187
+ return 'China';
188
+ case 'UK':
189
+ return 'United Kingdom';
190
+ default:
191
+ return value || '—';
192
+ }
193
+ }
194
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AdminOnboardingDetailPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
195
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: AdminOnboardingDetailPage, isStandalone: true, selector: "rolatech-admin-onboarding-detail-page", host: { classAttribute: "block" }, providers: [AdminOnboardingReviewFacade], ngImport: i0, template: `
196
+ <section class="rt-platform-theme flex flex-col gap-6 bg-(--rt-base-background) p-6 text-(--rt-text-primary)">
197
+ <rolatech-platform-page-header>
198
+ <div header-left class="space-y-2">
199
+ <div class="flex flex-wrap items-center gap-2 text-sm text-muted-foreground">
200
+ <a [routerLink]="['../']" class="hover:underline cursor-pointer">Agent Applications</a>
201
+ @if (facade.detail(); as detail) {
202
+ <span>/</span>
203
+ <span>{{ detail.organizationName || detail.contactName || detail.id }}</span>
204
+ }
205
+ </div>
206
+
207
+ <div>
208
+ <h1 class="text-2xl font-semibold tracking-tight">{{ title() }}</h1>
209
+ <p class="mt-1 text-sm text-muted-foreground">{{ subtitle() }}</p>
210
+ </div>
211
+ </div>
212
+
213
+ <div header-actions>
214
+ @if (facade.detail()?.status || null; as status) {
215
+ <rolatech-onboarding-status-badge [status]="status" />
216
+ }
217
+ <button
218
+ type="button"
219
+ class="inline-flex items-center rounded-xl border border-(--rt-border-color) px-4 py-2 text-sm font-medium"
220
+ (click)="openTimeline()"
221
+ >
222
+ Timeline
223
+ </button>
224
+ </div>
225
+ </rolatech-platform-page-header>
226
+
227
+ <section class="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
228
+ <rolatech-platform-stat-card>
229
+ <div stat-label>Documents</div>
230
+ <div stat-value>{{ documentCount() }}</div>
231
+ </rolatech-platform-stat-card>
232
+
233
+ <rolatech-platform-stat-card>
234
+ <div stat-label>Open Issues</div>
235
+ <div stat-value>{{ openIssueCount() }}</div>
236
+ </rolatech-platform-stat-card>
237
+
238
+ <rolatech-platform-stat-card>
239
+ <div stat-label>Timeline Events</div>
240
+ <div stat-value>{{ timelineCount() }}</div>
241
+ </rolatech-platform-stat-card>
242
+
243
+ <rolatech-platform-stat-card>
244
+ <div stat-label>Draft Issues</div>
245
+ <div stat-value>{{ facade.issueDrafts().length }}</div>
246
+ </rolatech-platform-stat-card>
247
+ </section>
248
+
249
+ @if (facade.error()) {
250
+ <div class="rounded-2xl border border-rose-200 bg-rose-50 px-4 py-3 text-sm text-rose-700">{{ facade.error() }}</div>
251
+ }
252
+
253
+ @if (facade.detail(); as detail) {
254
+ <div class="space-y-4">
255
+ <section class="rounded-2xl border border-(--rt-border-color) bg-card p-5 shadow-sm">
256
+ <div class="flex flex-wrap items-center gap-3 text-sm text-muted-foreground">
257
+ <span>Application ID: <span class="font-semibold text-(--rt-text-primary)">{{ detail.id }}</span></span>
258
+ <span>•</span>
259
+ <span>{{ onboardingStatusLabel(detail.status) }}</span>
260
+ <span>•</span>
261
+ <span>{{ onboardingApplicantTypeLabel(detail.applicantType) }}</span>
262
+ <span>•</span>
263
+ <span>{{ countryLabel(detail.companyCountry) }}</span>
264
+ </div>
265
+ </section>
266
+
267
+ @if (detail.status === 'NEED_MORE_INFO') {
268
+ <rolatech-onboarding-review-issues-banner [issues]="detail.issues" [status]="detail.status" />
269
+ }
270
+
271
+ <section class="space-y-4 rounded-3xl border border-(--rt-border-color) bg-(--rt-base-background) p-6 shadow-sm">
272
+ <div class="flex flex-wrap items-start justify-between gap-4">
273
+ <div class="space-y-2">
274
+ <h2 class="text-lg font-semibold text-(--rt-text-primary)">Inline Review Workspace</h2>
275
+ <p class="max-w-2xl text-sm text-(--rt-text-secondary)">
276
+ Review the application in place. Mark a field or document as passed, or leave an issue directly beside the item that needs correction.
277
+ </p>
278
+ </div>
279
+
280
+ <span class="rounded-full border border-(--rt-border-color) bg-(--rt-raised-background) px-3 py-1 text-xs font-semibold text-(--rt-text-secondary)">
281
+ {{ facade.issueDrafts().length }} draft issues
282
+ </span>
283
+ </div>
284
+
285
+ <label class="grid gap-2">
286
+ <span class="text-sm font-medium text-(--rt-text-secondary)">Review summary</span>
287
+ <textarea
288
+ class="min-h-28 rounded-xl border border-(--rt-border-color) px-3 py-2"
289
+ [value]="facade.reviewComment()"
290
+ (input)="setComment($event)"
291
+ placeholder="Add a high-level review note or final decision context..."
292
+ ></textarea>
293
+ </label>
294
+
295
+ <div class="flex flex-wrap gap-3">
296
+ <button
297
+ type="button"
298
+ class="rounded-xl border border-(--rt-border-color) px-4 py-2 text-sm font-semibold text-(--rt-text-secondary) hover:bg-(--rt-raised-background)"
299
+ [disabled]="facade.saving()"
300
+ (click)="startReview()"
301
+ >
302
+ Start Review
303
+ </button>
304
+
305
+ <button
306
+ type="button"
307
+ class="rounded-xl border border-amber-300 bg-amber-50 px-4 py-2 text-sm font-semibold text-amber-800 hover:bg-amber-100"
308
+ [disabled]="facade.saving()"
309
+ (click)="needMoreInfo()"
310
+ >
311
+ Need More Info
312
+ </button>
313
+
314
+ <button
315
+ type="button"
316
+ class="rounded-xl border border-emerald-300 bg-emerald-50 px-4 py-2 text-sm font-semibold text-emerald-800 hover:bg-emerald-100"
317
+ [disabled]="facade.saving()"
318
+ (click)="approve()"
319
+ >
320
+ Approve
321
+ </button>
322
+
323
+ <button
324
+ type="button"
325
+ class="rounded-xl border border-rose-300 bg-rose-50 px-4 py-2 text-sm font-semibold text-rose-800 hover:bg-rose-100"
326
+ [disabled]="facade.saving()"
327
+ (click)="fail()"
328
+ >
329
+ Fail
330
+ </button>
331
+ </div>
332
+ </section>
333
+
334
+ <section class="space-y-4">
335
+ <div class="space-y-1">
336
+ <h2 class="text-lg font-semibold text-(--rt-text-primary)">Applicant Profile</h2>
337
+ <p class="text-sm text-(--rt-text-secondary)">Check identity, contact, and company information.</p>
338
+ </div>
339
+
340
+ <div class="grid gap-4 lg:grid-cols-2">
341
+ @for (item of profileItems(); track item.key) {
342
+ <rolatech-onboarding-review-row
343
+ [label]="item.label"
344
+ [value]="item.value"
345
+ [helper]="item.helper"
346
+ [issueOptions]="fieldIssueOptions(item.key)"
347
+ [existingIssue]="fieldExistingIssue(item.key)"
348
+ [draftIssue]="facade.fieldDraft(item.key)"
349
+ [passed]="facade.fieldPassed(item.key)"
350
+ [busy]="facade.saving()"
351
+ (passedChange)="onFieldPassed(item.key, $event)"
352
+ (draftIssueChange)="onFieldIssue(item.key, $event)"
353
+ />
354
+ }
355
+ </div>
356
+ </section>
357
+
358
+ <section class="space-y-4">
359
+ <div class="space-y-1">
360
+ <h2 class="text-lg font-semibold text-(--rt-text-primary)">Compliance and Banking</h2>
361
+ <p class="text-sm text-(--rt-text-secondary)">Check VAT setup and settlement account details.</p>
362
+ </div>
363
+
364
+ <div class="grid gap-4 lg:grid-cols-2">
365
+ @for (item of complianceItems(); track item.key) {
366
+ <rolatech-onboarding-review-row
367
+ [label]="item.label"
368
+ [value]="item.value"
369
+ [helper]="item.helper"
370
+ [issueOptions]="fieldIssueOptions(item.key)"
371
+ [existingIssue]="fieldExistingIssue(item.key)"
372
+ [draftIssue]="facade.fieldDraft(item.key)"
373
+ [passed]="facade.fieldPassed(item.key)"
374
+ [busy]="facade.saving()"
375
+ (passedChange)="onFieldPassed(item.key, $event)"
376
+ (draftIssueChange)="onFieldIssue(item.key, $event)"
377
+ />
378
+ }
379
+ </div>
380
+ </section>
381
+
382
+ <section class="space-y-4">
383
+ <div class="space-y-1">
384
+ <h2 class="text-lg font-semibold text-(--rt-text-primary)">Documents</h2>
385
+ <p class="text-sm text-(--rt-text-secondary)">Review required documents and flag anything missing or unreadable.</p>
386
+ </div>
387
+
388
+ <div class="grid gap-4 lg:grid-cols-2">
389
+ @for (item of documentItems(); track item.documentType + item.label) {
390
+ <rolatech-onboarding-review-row
391
+ [label]="item.label"
392
+ [value]="item.value"
393
+ [helper]="item.helper"
394
+ [issueOptions]="documentIssueOptions(item.documentType)"
395
+ [existingIssue]="documentExistingIssue(item.documentType)"
396
+ [draftIssue]="facade.documentDraft(item.documentType)"
397
+ [passed]="facade.documentPassed(item.documentType)"
398
+ [busy]="facade.saving()"
399
+ [actionLabel]="item.document ? 'Preview' : null"
400
+ [actionDisabled]="!item.document"
401
+ (passedChange)="onDocumentPassed(item.documentType, $event)"
402
+ (draftIssueChange)="onDocumentIssue(item.documentType, $event)"
403
+ (actionTriggered)="openDocumentPreview(item)"
404
+ />
405
+ }
406
+ </div>
407
+ </section>
408
+
409
+ <rolatech-onboarding-issue-list [issues]="detail.issues" />
410
+ </div>
411
+ } @else {
412
+ <div class="rounded-2xl border border-(--rt-border-color) bg-(--rt-base-background) p-5 text-sm text-(--rt-text-secondary) shadow-sm">
413
+ Loading application details...
414
+ </div>
415
+ }
416
+
417
+ @if (facade.detail(); as detail) {
418
+ <rolatech-onboarding-timeline-drawer
419
+ floating
420
+ [open]="timelineOpen()"
421
+ [title]="'Application Timeline'"
422
+ [items]="detail.timeline"
423
+ [zIndex]="9100"
424
+ (closeRequested)="closeTimeline()"
425
+ />
426
+ }
427
+
428
+ <rolatech-onboarding-document-preview-dialog
429
+ [open]="previewOpen()"
430
+ [title]="previewTitle()"
431
+ [subtitle]="previewSubtitle()"
432
+ [url]="facade.previewUrl()"
433
+ [loading]="facade.previewLoading()"
434
+ [error]="facade.previewError()"
435
+ (closeRequested)="closeDocumentPreview()"
436
+ />
437
+ </section>
438
+ `, isInline: true, dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: PlatformPageHeader, selector: "rolatech-platform-page-header" }, { kind: "component", type: PlatformStatCard, selector: "rolatech-platform-stat-card" }, { kind: "component", type: OnboardingStatusBadge, selector: "rolatech-onboarding-status-badge", inputs: ["status"] }, { kind: "component", type: OnboardingIssueList, selector: "rolatech-onboarding-issue-list", inputs: ["issues"] }, { kind: "component", type: OnboardingTimelineDrawer, selector: "rolatech-onboarding-timeline-drawer", inputs: ["open", "title", "items", "zIndex"], outputs: ["closeRequested"] }, { kind: "component", type: OnboardingReviewRow, selector: "rolatech-onboarding-review-row", inputs: ["label", "value", "helper", "existingIssue", "issueOptions", "draftIssue", "passed", "busy", "actionLabel", "actionDisabled"], outputs: ["passedChange", "draftIssueChange", "actionTriggered"] }, { kind: "component", type: OnboardingReviewIssuesBanner, selector: "rolatech-onboarding-review-issues-banner", inputs: ["issues", "status"] }, { kind: "component", type: OnboardingDocumentPreviewDialog, selector: "rolatech-onboarding-document-preview-dialog", inputs: ["open", "title", "subtitle", "url", "loading", "error"], outputs: ["closeRequested"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
439
+ }
440
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AdminOnboardingDetailPage, decorators: [{
441
+ type: Component,
442
+ args: [{
443
+ selector: 'rolatech-admin-onboarding-detail-page',
444
+ standalone: true,
445
+ imports: [
446
+ RouterLink,
447
+ PlatformPageHeader,
448
+ PlatformStatCard,
449
+ OnboardingStatusBadge,
450
+ OnboardingIssueList,
451
+ OnboardingTimelineDrawer,
452
+ OnboardingReviewRow,
453
+ OnboardingReviewIssuesBanner,
454
+ OnboardingDocumentPreviewDialog,
455
+ ],
456
+ providers: [AdminOnboardingReviewFacade],
457
+ changeDetection: ChangeDetectionStrategy.OnPush,
458
+ encapsulation: ViewEncapsulation.None,
459
+ host: { class: 'block' },
460
+ template: `
461
+ <section class="rt-platform-theme flex flex-col gap-6 bg-(--rt-base-background) p-6 text-(--rt-text-primary)">
462
+ <rolatech-platform-page-header>
463
+ <div header-left class="space-y-2">
464
+ <div class="flex flex-wrap items-center gap-2 text-sm text-muted-foreground">
465
+ <a [routerLink]="['../']" class="hover:underline cursor-pointer">Agent Applications</a>
466
+ @if (facade.detail(); as detail) {
467
+ <span>/</span>
468
+ <span>{{ detail.organizationName || detail.contactName || detail.id }}</span>
469
+ }
470
+ </div>
471
+
472
+ <div>
473
+ <h1 class="text-2xl font-semibold tracking-tight">{{ title() }}</h1>
474
+ <p class="mt-1 text-sm text-muted-foreground">{{ subtitle() }}</p>
475
+ </div>
476
+ </div>
477
+
478
+ <div header-actions>
479
+ @if (facade.detail()?.status || null; as status) {
480
+ <rolatech-onboarding-status-badge [status]="status" />
481
+ }
482
+ <button
483
+ type="button"
484
+ class="inline-flex items-center rounded-xl border border-(--rt-border-color) px-4 py-2 text-sm font-medium"
485
+ (click)="openTimeline()"
486
+ >
487
+ Timeline
488
+ </button>
489
+ </div>
490
+ </rolatech-platform-page-header>
491
+
492
+ <section class="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
493
+ <rolatech-platform-stat-card>
494
+ <div stat-label>Documents</div>
495
+ <div stat-value>{{ documentCount() }}</div>
496
+ </rolatech-platform-stat-card>
497
+
498
+ <rolatech-platform-stat-card>
499
+ <div stat-label>Open Issues</div>
500
+ <div stat-value>{{ openIssueCount() }}</div>
501
+ </rolatech-platform-stat-card>
502
+
503
+ <rolatech-platform-stat-card>
504
+ <div stat-label>Timeline Events</div>
505
+ <div stat-value>{{ timelineCount() }}</div>
506
+ </rolatech-platform-stat-card>
507
+
508
+ <rolatech-platform-stat-card>
509
+ <div stat-label>Draft Issues</div>
510
+ <div stat-value>{{ facade.issueDrafts().length }}</div>
511
+ </rolatech-platform-stat-card>
512
+ </section>
513
+
514
+ @if (facade.error()) {
515
+ <div class="rounded-2xl border border-rose-200 bg-rose-50 px-4 py-3 text-sm text-rose-700">{{ facade.error() }}</div>
516
+ }
517
+
518
+ @if (facade.detail(); as detail) {
519
+ <div class="space-y-4">
520
+ <section class="rounded-2xl border border-(--rt-border-color) bg-card p-5 shadow-sm">
521
+ <div class="flex flex-wrap items-center gap-3 text-sm text-muted-foreground">
522
+ <span>Application ID: <span class="font-semibold text-(--rt-text-primary)">{{ detail.id }}</span></span>
523
+ <span>•</span>
524
+ <span>{{ onboardingStatusLabel(detail.status) }}</span>
525
+ <span>•</span>
526
+ <span>{{ onboardingApplicantTypeLabel(detail.applicantType) }}</span>
527
+ <span>•</span>
528
+ <span>{{ countryLabel(detail.companyCountry) }}</span>
529
+ </div>
530
+ </section>
531
+
532
+ @if (detail.status === 'NEED_MORE_INFO') {
533
+ <rolatech-onboarding-review-issues-banner [issues]="detail.issues" [status]="detail.status" />
534
+ }
535
+
536
+ <section class="space-y-4 rounded-3xl border border-(--rt-border-color) bg-(--rt-base-background) p-6 shadow-sm">
537
+ <div class="flex flex-wrap items-start justify-between gap-4">
538
+ <div class="space-y-2">
539
+ <h2 class="text-lg font-semibold text-(--rt-text-primary)">Inline Review Workspace</h2>
540
+ <p class="max-w-2xl text-sm text-(--rt-text-secondary)">
541
+ Review the application in place. Mark a field or document as passed, or leave an issue directly beside the item that needs correction.
542
+ </p>
543
+ </div>
544
+
545
+ <span class="rounded-full border border-(--rt-border-color) bg-(--rt-raised-background) px-3 py-1 text-xs font-semibold text-(--rt-text-secondary)">
546
+ {{ facade.issueDrafts().length }} draft issues
547
+ </span>
548
+ </div>
549
+
550
+ <label class="grid gap-2">
551
+ <span class="text-sm font-medium text-(--rt-text-secondary)">Review summary</span>
552
+ <textarea
553
+ class="min-h-28 rounded-xl border border-(--rt-border-color) px-3 py-2"
554
+ [value]="facade.reviewComment()"
555
+ (input)="setComment($event)"
556
+ placeholder="Add a high-level review note or final decision context..."
557
+ ></textarea>
558
+ </label>
559
+
560
+ <div class="flex flex-wrap gap-3">
561
+ <button
562
+ type="button"
563
+ class="rounded-xl border border-(--rt-border-color) px-4 py-2 text-sm font-semibold text-(--rt-text-secondary) hover:bg-(--rt-raised-background)"
564
+ [disabled]="facade.saving()"
565
+ (click)="startReview()"
566
+ >
567
+ Start Review
568
+ </button>
569
+
570
+ <button
571
+ type="button"
572
+ class="rounded-xl border border-amber-300 bg-amber-50 px-4 py-2 text-sm font-semibold text-amber-800 hover:bg-amber-100"
573
+ [disabled]="facade.saving()"
574
+ (click)="needMoreInfo()"
575
+ >
576
+ Need More Info
577
+ </button>
578
+
579
+ <button
580
+ type="button"
581
+ class="rounded-xl border border-emerald-300 bg-emerald-50 px-4 py-2 text-sm font-semibold text-emerald-800 hover:bg-emerald-100"
582
+ [disabled]="facade.saving()"
583
+ (click)="approve()"
584
+ >
585
+ Approve
586
+ </button>
587
+
588
+ <button
589
+ type="button"
590
+ class="rounded-xl border border-rose-300 bg-rose-50 px-4 py-2 text-sm font-semibold text-rose-800 hover:bg-rose-100"
591
+ [disabled]="facade.saving()"
592
+ (click)="fail()"
593
+ >
594
+ Fail
595
+ </button>
596
+ </div>
597
+ </section>
598
+
599
+ <section class="space-y-4">
600
+ <div class="space-y-1">
601
+ <h2 class="text-lg font-semibold text-(--rt-text-primary)">Applicant Profile</h2>
602
+ <p class="text-sm text-(--rt-text-secondary)">Check identity, contact, and company information.</p>
603
+ </div>
604
+
605
+ <div class="grid gap-4 lg:grid-cols-2">
606
+ @for (item of profileItems(); track item.key) {
607
+ <rolatech-onboarding-review-row
608
+ [label]="item.label"
609
+ [value]="item.value"
610
+ [helper]="item.helper"
611
+ [issueOptions]="fieldIssueOptions(item.key)"
612
+ [existingIssue]="fieldExistingIssue(item.key)"
613
+ [draftIssue]="facade.fieldDraft(item.key)"
614
+ [passed]="facade.fieldPassed(item.key)"
615
+ [busy]="facade.saving()"
616
+ (passedChange)="onFieldPassed(item.key, $event)"
617
+ (draftIssueChange)="onFieldIssue(item.key, $event)"
618
+ />
619
+ }
620
+ </div>
621
+ </section>
622
+
623
+ <section class="space-y-4">
624
+ <div class="space-y-1">
625
+ <h2 class="text-lg font-semibold text-(--rt-text-primary)">Compliance and Banking</h2>
626
+ <p class="text-sm text-(--rt-text-secondary)">Check VAT setup and settlement account details.</p>
627
+ </div>
628
+
629
+ <div class="grid gap-4 lg:grid-cols-2">
630
+ @for (item of complianceItems(); track item.key) {
631
+ <rolatech-onboarding-review-row
632
+ [label]="item.label"
633
+ [value]="item.value"
634
+ [helper]="item.helper"
635
+ [issueOptions]="fieldIssueOptions(item.key)"
636
+ [existingIssue]="fieldExistingIssue(item.key)"
637
+ [draftIssue]="facade.fieldDraft(item.key)"
638
+ [passed]="facade.fieldPassed(item.key)"
639
+ [busy]="facade.saving()"
640
+ (passedChange)="onFieldPassed(item.key, $event)"
641
+ (draftIssueChange)="onFieldIssue(item.key, $event)"
642
+ />
643
+ }
644
+ </div>
645
+ </section>
646
+
647
+ <section class="space-y-4">
648
+ <div class="space-y-1">
649
+ <h2 class="text-lg font-semibold text-(--rt-text-primary)">Documents</h2>
650
+ <p class="text-sm text-(--rt-text-secondary)">Review required documents and flag anything missing or unreadable.</p>
651
+ </div>
652
+
653
+ <div class="grid gap-4 lg:grid-cols-2">
654
+ @for (item of documentItems(); track item.documentType + item.label) {
655
+ <rolatech-onboarding-review-row
656
+ [label]="item.label"
657
+ [value]="item.value"
658
+ [helper]="item.helper"
659
+ [issueOptions]="documentIssueOptions(item.documentType)"
660
+ [existingIssue]="documentExistingIssue(item.documentType)"
661
+ [draftIssue]="facade.documentDraft(item.documentType)"
662
+ [passed]="facade.documentPassed(item.documentType)"
663
+ [busy]="facade.saving()"
664
+ [actionLabel]="item.document ? 'Preview' : null"
665
+ [actionDisabled]="!item.document"
666
+ (passedChange)="onDocumentPassed(item.documentType, $event)"
667
+ (draftIssueChange)="onDocumentIssue(item.documentType, $event)"
668
+ (actionTriggered)="openDocumentPreview(item)"
669
+ />
670
+ }
671
+ </div>
672
+ </section>
673
+
674
+ <rolatech-onboarding-issue-list [issues]="detail.issues" />
675
+ </div>
676
+ } @else {
677
+ <div class="rounded-2xl border border-(--rt-border-color) bg-(--rt-base-background) p-5 text-sm text-(--rt-text-secondary) shadow-sm">
678
+ Loading application details...
679
+ </div>
680
+ }
681
+
682
+ @if (facade.detail(); as detail) {
683
+ <rolatech-onboarding-timeline-drawer
684
+ floating
685
+ [open]="timelineOpen()"
686
+ [title]="'Application Timeline'"
687
+ [items]="detail.timeline"
688
+ [zIndex]="9100"
689
+ (closeRequested)="closeTimeline()"
690
+ />
691
+ }
692
+
693
+ <rolatech-onboarding-document-preview-dialog
694
+ [open]="previewOpen()"
695
+ [title]="previewTitle()"
696
+ [subtitle]="previewSubtitle()"
697
+ [url]="facade.previewUrl()"
698
+ [loading]="facade.previewLoading()"
699
+ [error]="facade.previewError()"
700
+ (closeRequested)="closeDocumentPreview()"
701
+ />
702
+ </section>
703
+ `,
704
+ }]
705
+ }], ctorParameters: () => [] });
706
+
707
+ export { AdminOnboardingDetailPage };
708
+ //# sourceMappingURL=rolatech-angular-onboarding-admin-onboarding-detail-page-DD-5SdjA.mjs.map