@forgeroute/ui 0.4.41 → 0.4.43

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgeroute/ui",
3
- "version": "0.4.41",
3
+ "version": "0.4.43",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=22.0.0",
6
6
  "@angular/core": ">=22.0.0",
@@ -115,7 +115,7 @@ export declare class TemplatePickerComponent {
115
115
  private readonly host;
116
116
  private readonly search$;
117
117
  /** Filter results to a specific channel: 'email', 'text', or omit for all. */
118
- readonly channel: import("@angular/core").InputSignal<"" | "text" | "email">;
118
+ readonly channel: import("@angular/core").InputSignal<"" | "email" | "text">;
119
119
  readonly selectedId: import("@angular/core").InputSignal<string | null>;
120
120
  readonly label: import("@angular/core").InputSignal<string>;
121
121
  /** Shows the red required asterisk (same as the library inputs) — e.g. when a template must be picked to send. */
@@ -543,7 +543,7 @@ export declare class DocumentSendOptionsComponent implements UiFieldValidity {
543
543
  /** API root from FORGEROUTE_CONFIG (e.g. a cross-origin prod API); falls back to same-origin `/api`. */
544
544
  private readonly apiBase;
545
545
  /** `email` → purpose select + attachment allowed; `text` → link only (purpose fixed to e-signature). */
546
- readonly channel: import("@angular/core").InputSignal<"text" | "email">;
546
+ readonly channel: import("@angular/core").InputSignal<"email" | "text">;
547
547
  readonly label: import("@angular/core").InputSignal<string>;
548
548
  /** When true, at least one document must be chosen. The message forms leave it false: documents are optional there. */
549
549
  readonly required: import("@angular/core").InputSignal<boolean>;
@@ -608,7 +608,7 @@ export declare class DocumentSendOptionsComponent implements UiFieldValidity {
608
608
  /** Roles of documents whose row had no `signerRoles` and that the host resolves (`signers().resolveRoles`). */
609
609
  readonly roleStates: import("@angular/core").WritableSignal<Record<string, RoleState>>;
610
610
  /** The envelope's documents: `loading` / `error` while the panel reads them (`loadDocuments`), `ready` once known. */
611
- readonly envelopeStatus: import("@angular/core").WritableSignal<"error" | "loading" | "ready" | "idle">;
611
+ readonly envelopeStatus: import("@angular/core").WritableSignal<"idle" | "loading" | "ready" | "error">;
612
612
  private envelopeSub;
613
613
  private readonly roleSubs;
614
614
  /** The sender opened the collapsed "Signing options" line. */
@@ -1029,6 +1029,12 @@ declare class SendEmailComponent implements OnInit {
1029
1029
  readonly videoDefaults: import("@angular/core").InputSignal<VideoDefaults | null>;
1030
1030
  /** false hides Attach Files and "Schedule for later" (for a host whose send function can't deliver them). */
1031
1031
  readonly attachmentsAndScheduling: import("@angular/core").InputSignal<boolean>;
1032
+ /** false hides the Subject field (and Send no longer needs one): for a host whose send function has no subject. Default true. */
1033
+ readonly showSubject: import("@angular/core").InputSignal<boolean>;
1034
+ /** false hides the "Use Existing Template" tab: the form is Create Message only, and the template picker (`GET /templates`) is never shown. Default true. */
1035
+ readonly showTemplates: import("@angular/core").InputSignal<boolean>;
1036
+ /** false hides the Video section (and its picker, `GET /video-messages`). Default true. */
1037
+ readonly showVideo: import("@angular/core").InputSignal<boolean>;
1032
1038
  readonly sent: import("@angular/core").OutputEmitterRef<void>;
1033
1039
  readonly emailAdded: import("@angular/core").OutputEmitterRef<string>;
1034
1040
  readonly validChange: import("@angular/core").OutputEmitterRef<boolean>;
@@ -1340,6 +1346,21 @@ declare class SendEmailComponent implements OnInit {
1340
1346
  "required": false;
1341
1347
  "isSignal": true;
1342
1348
  };
1349
+ "showSubject": {
1350
+ "alias": "showSubject";
1351
+ "required": false;
1352
+ "isSignal": true;
1353
+ };
1354
+ "showTemplates": {
1355
+ "alias": "showTemplates";
1356
+ "required": false;
1357
+ "isSignal": true;
1358
+ };
1359
+ "showVideo": {
1360
+ "alias": "showVideo";
1361
+ "required": false;
1362
+ "isSignal": true;
1363
+ };
1343
1364
  }, {
1344
1365
  "sent": "sent";
1345
1366
  "emailAdded": "emailAdded";
@@ -1348,6 +1369,87 @@ declare class SendEmailComponent implements OnInit {
1348
1369
  "mapFieldsClick": "mapFieldsClick";
1349
1370
  }, never, never, true, never>;
1350
1371
  }
1372
+ /** What the in-app form sends to the host's `sendFn`: there is no address, only who it is for and what was written. */
1373
+ interface SendInAppPayload {
1374
+ contactName: string;
1375
+ contactId?: string;
1376
+ /** Only present when the Subject field is shown. */
1377
+ subject?: string;
1378
+ body: string;
1379
+ }
1380
+ /**
1381
+ * The form of a message that is not delivered by email or text but handed to the host's own function (e.g. a client portal message to the
1382
+ * agent): "To" card with the name only, an optional Subject, the Message. No address, templates, video, attachments or scheduling, and it makes
1383
+ * no request of its own: `sendFn` does the sending. Used by `<ui-send-message-panel recipientMode="in-app">`.
1384
+ */
1385
+ declare class SendInAppComponent implements OnInit {
1386
+ private readonly destroyRef;
1387
+ private readonly toast;
1388
+ readonly contactName: import("@angular/core").InputSignal<string>;
1389
+ readonly contactId: import("@angular/core").InputSignal<string>;
1390
+ /** Prefills Subject / Message. */
1391
+ readonly defaultSubject: import("@angular/core").InputSignal<string>;
1392
+ readonly defaultBody: import("@angular/core").InputSignal<string>;
1393
+ /** false hides the Subject field; Send then needs only a Message. */
1394
+ readonly showSubject: import("@angular/core").InputSignal<boolean>;
1395
+ /** Longest Message the host's backend accepts (the field stops there and shows "Too long"); null = no limit. */
1396
+ readonly maxLength: import("@angular/core").InputSignal<number | null>;
1397
+ /** The host's sender; this form makes no request of its own. */
1398
+ /** `maxLength` when it is a positive number, else 0 (no limit). */
1399
+ protected readonly limit: import("@angular/core").Signal<number>;
1400
+ readonly sendFn: import("@angular/core").InputSignal<((payload: SendInAppPayload) => Observable<unknown>) | null>;
1401
+ readonly sent: import("@angular/core").OutputEmitterRef<void>;
1402
+ readonly validChange: import("@angular/core").OutputEmitterRef<boolean>;
1403
+ readonly MAX_SUBJECT = 255;
1404
+ readonly sending: import("@angular/core").WritableSignal<boolean>;
1405
+ subject: string;
1406
+ body: string;
1407
+ ngOnInit(): void;
1408
+ get canSend(): boolean;
1409
+ notifyValid(): void;
1410
+ submit(): void;
1411
+ static ɵfac: i0.ɵɵFactoryDeclaration<SendInAppComponent, never>;
1412
+ static ɵcmp: i0.ɵɵComponentDeclaration<SendInAppComponent, "ui-send-in-app", never, {
1413
+ "contactName": {
1414
+ "alias": "contactName";
1415
+ "required": false;
1416
+ "isSignal": true;
1417
+ };
1418
+ "contactId": {
1419
+ "alias": "contactId";
1420
+ "required": false;
1421
+ "isSignal": true;
1422
+ };
1423
+ "defaultSubject": {
1424
+ "alias": "defaultSubject";
1425
+ "required": false;
1426
+ "isSignal": true;
1427
+ };
1428
+ "defaultBody": {
1429
+ "alias": "defaultBody";
1430
+ "required": false;
1431
+ "isSignal": true;
1432
+ };
1433
+ "showSubject": {
1434
+ "alias": "showSubject";
1435
+ "required": false;
1436
+ "isSignal": true;
1437
+ };
1438
+ "maxLength": {
1439
+ "alias": "maxLength";
1440
+ "required": false;
1441
+ "isSignal": true;
1442
+ };
1443
+ "sendFn": {
1444
+ "alias": "sendFn";
1445
+ "required": false;
1446
+ "isSignal": true;
1447
+ };
1448
+ }, {
1449
+ "sent": "sent";
1450
+ "validChange": "validChange";
1451
+ }, never, never, true, never>;
1452
+ }
1351
1453
  /** What the text form sends — the default `POST <baseUrl>/text-messages` body, or the host's `sendFn` argument. */
1352
1454
  interface SendTextPayload {
1353
1455
  contactName: string;
@@ -1392,6 +1494,10 @@ declare class SendTextComponent implements OnInit {
1392
1494
  readonly documents: import("@angular/core").InputSignal<boolean>;
1393
1495
  /** false hides Attach Image and "Schedule for later" (for a host whose send function can't deliver them). */
1394
1496
  readonly attachmentsAndScheduling: import("@angular/core").InputSignal<boolean>;
1497
+ /** false hides the "Use Existing Template" tab: the form is Create Message only. Default true. */
1498
+ readonly showTemplates: import("@angular/core").InputSignal<boolean>;
1499
+ /** false hides the Video section (and its picker, `GET /video-messages`). Default true. */
1500
+ readonly showVideo: import("@angular/core").InputSignal<boolean>;
1395
1501
  /** Purposes the app's backend supports for documents (default all). The text form only sends `ESIGN`; without it the section is unavailable. */
1396
1502
  readonly documentPurposes: import("@angular/core").InputSignal<DocumentSendPurpose[]>;
1397
1503
  /** Documents already chosen in the Documents section when the form opens. */
@@ -1594,6 +1700,16 @@ declare class SendTextComponent implements OnInit {
1594
1700
  "required": false;
1595
1701
  "isSignal": true;
1596
1702
  };
1703
+ "showTemplates": {
1704
+ "alias": "showTemplates";
1705
+ "required": false;
1706
+ "isSignal": true;
1707
+ };
1708
+ "showVideo": {
1709
+ "alias": "showVideo";
1710
+ "required": false;
1711
+ "isSignal": true;
1712
+ };
1597
1713
  "documentPurposes": {
1598
1714
  "alias": "documentPurposes";
1599
1715
  "required": false;
@@ -1698,6 +1814,24 @@ export declare class SendMessagePanelComponent {
1698
1814
  readonly documentsEnabled: import("@angular/core").InputSignal<boolean>;
1699
1815
  /** Email tab only: adds a CC field; the addresses are sent as `SendEmailPayload.cc`. */
1700
1816
  readonly showCc: import("@angular/core").InputSignal<boolean>;
1817
+ /**
1818
+ * `'contact'` (default) = the message goes by email or text to the contact's address. `'in-app'` = the message is NOT delivered by email or
1819
+ * text but handed to the host's `sendMessage` function (e.g. a client portal message to the agent): the contact needs no email or phone, the
1820
+ * panel never shows the "add an email" form, the channel toggle, the contact picker, notices, templates, video, attachments or scheduling,
1821
+ * and makes no request of its own. The `contact` must be passed (its `name` is shown in "To"); the footer button says `Send Message`.
1822
+ */
1823
+ readonly recipientMode: import("@angular/core").InputSignal<"contact" | "in-app">;
1824
+ /** `recipientMode="in-app"` only: sends the message (the form shows no address; it calls this and then toasts "Message sent"). */
1825
+ readonly sendMessage: import("@angular/core").InputSignal<((payload: SendInAppPayload) => Observable<unknown>) | null>;
1826
+ /** `recipientMode="in-app"` only: the longest Message the host's backend accepts; null (default) = no limit. */
1827
+ readonly maxBodyLength: import("@angular/core").InputSignal<number | null>;
1828
+ /** false hides the Subject field in the email form and the in-app form (Send then needs only a Message). Default true. */
1829
+ readonly showSubject: import("@angular/core").InputSignal<boolean>;
1830
+ /** false hides the "Use Existing Template" tab in the email and text forms (Create Message only; the template picker, `GET /templates`, is never used). Default true. */
1831
+ readonly showTemplates: import("@angular/core").InputSignal<boolean>;
1832
+ /** false hides the Video section (picker, `GET /video-messages`) in the email and text forms. Default true. */
1833
+ readonly showVideo: import("@angular/core").InputSignal<boolean>;
1834
+ protected readonly inApp: import("@angular/core").Signal<boolean>;
1701
1835
  /** false hides Attach Files / Attach Image and "Schedule for later" in both forms (a host `sendEmail` / `sendText` that can't deliver them). */
1702
1836
  readonly attachmentsAndScheduling: import("@angular/core").InputSignal<boolean>;
1703
1837
  /** Purposes the app's backend supports for documents (default all three); `['ESIGN']` hides the purpose select. */
@@ -1801,6 +1935,7 @@ export declare class SendMessagePanelComponent {
1801
1935
  readonly phoneAdded: import("@angular/core").OutputEmitterRef<string>;
1802
1936
  readonly sendEmailRef: import("@angular/core").Signal<SendEmailComponent | undefined>;
1803
1937
  readonly sendTextRef: import("@angular/core").Signal<SendTextComponent | undefined>;
1938
+ readonly sendInAppRef: import("@angular/core").Signal<SendInAppComponent | undefined>;
1804
1939
  private readonly destroyRef;
1805
1940
  readonly jobSearch$: Subject<string>;
1806
1941
  readonly jobOptions: import("@angular/core").WritableSignal<ComboboxOption<unknown>[]>;
@@ -1813,7 +1948,7 @@ export declare class SendMessagePanelComponent {
1813
1948
  readonly activeContact: import("@angular/core").WritableSignal<MessageContact | null>;
1814
1949
  /** What the sender should know about the picked contact before sending (why a channel is missing, what to add). */
1815
1950
  readonly contactNotices: import("@angular/core").Signal<string[]>;
1816
- readonly channel: import("@angular/core").WritableSignal<"text" | "email">;
1951
+ readonly channel: import("@angular/core").WritableSignal<"email" | "text">;
1817
1952
  readonly valid: import("@angular/core").WritableSignal<boolean>;
1818
1953
  /** Bumped on every fresh open / new contact — re-creates the email and text forms so no draft carries over. */
1819
1954
  readonly formEpoch: import("@angular/core").WritableSignal<number>;
@@ -1913,6 +2048,36 @@ export declare class SendMessagePanelComponent {
1913
2048
  "required": false;
1914
2049
  "isSignal": true;
1915
2050
  };
2051
+ "recipientMode": {
2052
+ "alias": "recipientMode";
2053
+ "required": false;
2054
+ "isSignal": true;
2055
+ };
2056
+ "sendMessage": {
2057
+ "alias": "sendMessage";
2058
+ "required": false;
2059
+ "isSignal": true;
2060
+ };
2061
+ "maxBodyLength": {
2062
+ "alias": "maxBodyLength";
2063
+ "required": false;
2064
+ "isSignal": true;
2065
+ };
2066
+ "showSubject": {
2067
+ "alias": "showSubject";
2068
+ "required": false;
2069
+ "isSignal": true;
2070
+ };
2071
+ "showTemplates": {
2072
+ "alias": "showTemplates";
2073
+ "required": false;
2074
+ "isSignal": true;
2075
+ };
2076
+ "showVideo": {
2077
+ "alias": "showVideo";
2078
+ "required": false;
2079
+ "isSignal": true;
2080
+ };
1916
2081
  "attachmentsAndScheduling": {
1917
2082
  "alias": "attachmentsAndScheduling";
1918
2083
  "required": false;
@@ -2162,4 +2327,4 @@ export declare class DocumentMergeCheckComponent {
2162
2327
  "warningsChange": "warningsChange";
2163
2328
  }, never, never, true, never>;
2164
2329
  }
2165
- export type { CreateDocumentRequestBody, DocuSignSendBody, DocumentSentInfo, DocumentSentMessage, DocumentsPayloadExtras, ExistingEnvelopeSendBody, SendDocumentsPayload, SendEmailPayload, SendTextPayload, VideoDefaults, VideoLinkOptions };
2330
+ export type { CreateDocumentRequestBody, DocuSignSendBody, DocumentSentInfo, DocumentSentMessage, DocumentsPayloadExtras, ExistingEnvelopeSendBody, SendDocumentsPayload, SendEmailPayload, SendInAppPayload, SendTextPayload, VideoDefaults, VideoLinkOptions };
@@ -451,8 +451,10 @@ export declare class StripePaymentComponent {
451
451
  readonly disabled: import("@angular/core").InputSignal<boolean>;
452
452
  /** The host is still creating the intent: show the loading skeleton. */
453
453
  readonly pending: import("@angular/core").InputSignal<boolean>;
454
- /** Accessible name of the payment form. */
454
+ /** Accessible name of the payment form (also its visible heading when `required` is set). */
455
455
  readonly label: import("@angular/core").InputSignal<string>;
456
+ /** The payment details are required (a required wizard step): a visible heading with a red asterisk is shown above the form. Not shown in `mountOnly` mode. */
457
+ readonly required: import("@angular/core").InputSignal<boolean>;
456
458
  /** The `id` of the element container (an app's e2e selector such as `#payment-element`). */
457
459
  readonly mountId: import("@angular/core").InputSignal<string>;
458
460
  /** Extra CSS classes on the element container. */
@@ -752,6 +754,11 @@ export declare class StripePaymentComponent {
752
754
  "required": false;
753
755
  "isSignal": true;
754
756
  };
757
+ "required": {
758
+ "alias": "required";
759
+ "required": false;
760
+ "isSignal": true;
761
+ };
755
762
  "mountId": {
756
763
  "alias": "mountId";
757
764
  "required": false;
@@ -1270,6 +1277,8 @@ export declare class StripeConnectComponent {
1270
1277
  /** The details were submitted and Stripe is reviewing them. Two-way: set by `check()` / `resume()`. */
1271
1278
  readonly detailsSubmitted: import("@angular/core").ModelSignal<boolean>;
1272
1279
  readonly title: import("@angular/core").InputSignal<string>;
1280
+ /** No card around the content: the text and the button sit directly in the host's own card (the setup wizard's step card). `title` is not shown then. */
1281
+ readonly bare: import("@angular/core").InputSignal<boolean>;
1273
1282
  /** Shows the card (with "Set Up Payment Account") while there is no account yet. Default false: hosts with their own entry point show nothing and call `start()`. */
1274
1283
  readonly showWhenNoAccount: import("@angular/core").InputSignal<boolean>;
1275
1284
  readonly startTitle: import("@angular/core").InputSignal<string>;
@@ -1332,6 +1341,11 @@ export declare class StripeConnectComponent {
1332
1341
  "required": false;
1333
1342
  "isSignal": true;
1334
1343
  };
1344
+ "bare": {
1345
+ "alias": "bare";
1346
+ "required": false;
1347
+ "isSignal": true;
1348
+ };
1335
1349
  "showWhenNoAccount": {
1336
1350
  "alias": "showWhenNoAccount";
1337
1351
  "required": false;
@@ -1,8 +1,8 @@
1
1
  import * as i0 from "@angular/core";
2
2
  import { EnvironmentProviders, InjectionToken, OnDestroy, OnInit, Signal, TemplateRef, WritableSignal } from "@angular/core";
3
3
  import { UrlTree } from "@angular/router";
4
- import { AbstractControl, ControlValueAccessor, FormControl, ValidationErrors, Validator } from "@angular/forms";
5
4
  import { Observable } from "rxjs";
5
+ import { AbstractControl, ControlValueAccessor, FormControl, ValidationErrors, Validator } from "@angular/forms";
6
6
  import { HttpInterceptorFn } from "@angular/common/http";
7
7
  import { SafeHtml } from "@angular/platform-browser";
8
8
  export interface ForgerouteConfig {
@@ -1222,6 +1222,8 @@ export interface ImportExportConfig {
1222
1222
  importFields?: ImportFieldDef[];
1223
1223
  columnAliases?: Record<string, string[]>;
1224
1224
  templateSampleRows?: string[][];
1225
+ /** Text of the template download button inside the import window, e.g. "Download Cases CSV Template" (default: "Download template"). */
1226
+ templateLabel?: string;
1225
1227
  /** When true, the Export button appears in the More Actions dropdown instead of as a standalone button. */
1226
1228
  exportInMoreActions?: boolean;
1227
1229
  }
@@ -1229,12 +1231,37 @@ interface ImportError {
1229
1231
  row: number;
1230
1232
  message: string;
1231
1233
  }
1234
+ export interface ImportSubmitRequest {
1235
+ file: File | null;
1236
+ records: Record<string, string>[];
1237
+ mapping: Record<string, string>;
1238
+ }
1239
+ export interface ImportSubmitResult {
1240
+ imported: number;
1241
+ errors?: {
1242
+ row: number;
1243
+ message: string;
1244
+ }[];
1245
+ warnings?: {
1246
+ row: number;
1247
+ message: string;
1248
+ }[];
1249
+ }
1232
1250
  type ImportStep = 'source' | 'upload' | 'mapping' | 'preview' | 'result';
1233
1251
  export declare class ImportExportComponent {
1234
1252
  readonly _configInput: import("@angular/core").InputSignal<ImportExportConfig | null>;
1235
1253
  readonly importSources: import("@angular/core").InputSignal<ImportSource[] | undefined>;
1236
1254
  readonly exportParams: import("@angular/core").InputSignal<Record<string, string>>;
1237
1255
  readonly exportOnly: import("@angular/core").InputSignal<boolean>;
1256
+ /** The window's footer has one Close button that closes it at once, never Back / Cancel (the setup wizard). */
1257
+ readonly closeOnly: import("@angular/core").InputSignal<boolean>;
1258
+ /**
1259
+ * Replaces the built-in `POST importEndpoint { records }` for an app whose import runs differently (e.g. the server reads the CSV file itself):
1260
+ * receives the chosen file, the parsed rows (field key -> value) and the mapping (field key -> CSV column) and answers the result.
1261
+ */
1262
+ readonly submit: import("@angular/core").InputSignal<((request: ImportSubmitRequest) => Observable<ImportSubmitResult>) | null>;
1263
+ /** Fired when the user presses Done after an import, with what the import answered (also `imported`). */
1264
+ readonly finished: import("@angular/core").OutputEmitterRef<ImportSubmitResult>;
1238
1265
  readonly imported: import("@angular/core").OutputEmitterRef<void>;
1239
1266
  config: ImportExportConfig;
1240
1267
  private readonly http;
@@ -1273,6 +1300,7 @@ export declare class ImportExportComponent {
1273
1300
  closeImport(): void;
1274
1301
  finishImport(): void;
1275
1302
  onFileChange(event: Event): void;
1303
+ private csvFile;
1276
1304
  private readCsvFile;
1277
1305
  private autoMap;
1278
1306
  get canSubmit(): boolean;
@@ -1308,7 +1336,18 @@ export declare class ImportExportComponent {
1308
1336
  "required": false;
1309
1337
  "isSignal": true;
1310
1338
  };
1339
+ "closeOnly": {
1340
+ "alias": "closeOnly";
1341
+ "required": false;
1342
+ "isSignal": true;
1343
+ };
1344
+ "submit": {
1345
+ "alias": "submit";
1346
+ "required": false;
1347
+ "isSignal": true;
1348
+ };
1311
1349
  }, {
1350
+ "finished": "finished";
1312
1351
  "imported": "imported";
1313
1352
  }, never, never, true, never>;
1314
1353
  }
@@ -2167,7 +2206,7 @@ export declare class ModalComponent implements OnInit, OnDestroy {
2167
2206
  readonly title: import("@angular/core").InputSignal<string>;
2168
2207
  readonly description: import("@angular/core").InputSignal<string>;
2169
2208
  readonly maxWidth: import("@angular/core").InputSignal<string>;
2170
- readonly bodyOverflow: import("@angular/core").InputSignal<"hidden" | "auto" | "visible">;
2209
+ readonly bodyOverflow: import("@angular/core").InputSignal<"hidden" | "visible" | "auto">;
2171
2210
  /** `data-testid` of the dialog element itself (the host `<ui-modal>` is always in the page, the dialog only while open). None when empty. */
2172
2211
  readonly dialogTestId: import("@angular/core").InputSignal<string>;
2173
2212
  /** Hides the header X button (e.g. while a request is running). Escape and a backdrop click still close unless `closable` is false. */
@@ -2805,7 +2844,7 @@ export declare class CheckboxComponent implements ControlValueAccessor, Validato
2805
2844
  * clicking it still toggles the box - e.g. a product name that is both the heading of its card and the label of its checkbox.
2806
2845
  * Default null: plain label text, exactly as before. Single mode only.
2807
2846
  */
2808
- readonly headingLevel: import("@angular/core").InputSignal<1 | 2 | 3 | 4 | 5 | 6 | null>;
2847
+ readonly headingLevel: import("@angular/core").InputSignal<1 | 3 | 4 | 2 | 5 | 6 | null>;
2809
2848
  readonly indeterminate: import("@angular/core").InputSignal<boolean>;
2810
2849
  readonly checked: import("@angular/core").ModelSignal<boolean>;
2811
2850
  /**
@@ -3716,7 +3755,7 @@ export declare class PhoneNumberPickerComponent {
3716
3755
  protected readonly modeCtl: FormControl<string>;
3717
3756
  protected readonly zipCtl: FormControl<string>;
3718
3757
  protected readonly areaCtl: FormControl<string>;
3719
- protected readonly step: import("@angular/core").WritableSignal<1 | 2 | 3>;
3758
+ protected readonly step: import("@angular/core").WritableSignal<1 | 3 | 2>;
3720
3759
  protected readonly mode: import("@angular/core").WritableSignal<PhoneNumberSearchMode>;
3721
3760
  private readonly _zip;
3722
3761
  private readonly _area;
@@ -3830,7 +3869,7 @@ export declare class ButtonComponent {
3830
3869
  * `ghost-start`: a ghost button for list / section toggles - a full-width row with its content aligned to the start, transparent
3831
3870
  * background, hover tint and the normal focus ring. Pair it with `ariaExpanded` / `ariaPressed`; the label may contain a heading element.
3832
3871
  */
3833
- readonly variant: import("@angular/core").InputSignal<"primary" | "secondary" | "danger" | "warning" | "link" | "ghost" | "ghost-start" | "tab" | "icon" | "icon-danger">;
3872
+ readonly variant: import("@angular/core").InputSignal<"link" | "primary" | "secondary" | "danger" | "warning" | "ghost" | "ghost-start" | "tab" | "icon" | "icon-danger">;
3834
3873
  /** Renders an anchor to this route instead of a button (use with `variant="link"` for an inline text link). `['/settings']` or `'/settings'`. While `disabled` or `loading` it renders a non-clickable `<span role="link" aria-disabled>` with no href (like `href`). */
3835
3874
  readonly routerLink: import("@angular/core").InputSignal<string | readonly unknown[] | null>;
3836
3875
  /** Query params of the `routerLink` (e.g. `{ section: 'deal-defaults' }`). */
@@ -3851,7 +3890,7 @@ export declare class ButtonComponent {
3851
3890
  */
3852
3891
  readonly href: import("@angular/core").InputSignal<string | null>;
3853
3892
  /** Where to open the `href` (`_blank` = a new tab). */
3854
- readonly target: import("@angular/core").InputSignal<"_self" | "_blank" | "_parent" | "_top" | null>;
3893
+ readonly target: import("@angular/core").InputSignal<"_blank" | "_self" | "_parent" | "_top" | null>;
3855
3894
  /** `rel` of the `href` link. A `_blank` target always gets `noopener noreferrer` added. */
3856
3895
  readonly rel: import("@angular/core").InputSignal<string | null>;
3857
3896
  /** The href when it is allowed (http, https, mailto, tel, sms or a relative URL), else null. */
@@ -3876,7 +3915,7 @@ export declare class ButtonComponent {
3876
3915
  readonly color: import("@angular/core").InputSignal<string | undefined>;
3877
3916
  readonly active: import("@angular/core").InputSignal<boolean>;
3878
3917
  readonly size: import("@angular/core").InputSignal<"sm" | "md" | "lg" | "xs">;
3879
- readonly type: import("@angular/core").InputSignal<"reset" | "submit" | "button">;
3918
+ readonly type: import("@angular/core").InputSignal<"button" | "reset" | "submit">;
3880
3919
  readonly disabled: import("@angular/core").InputSignal<boolean>;
3881
3920
  readonly loading: import("@angular/core").InputSignal<boolean>;
3882
3921
  readonly fullWidth: import("@angular/core").InputSignal<boolean>;
@@ -4672,7 +4711,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
4672
4711
  readonly passwordRequirements: import("@angular/core").InputSignal<boolean>;
4673
4712
  /** Rules for `passwordRequirements`; default = the library's five rules (8+ characters, upper, lower, digit, special). */
4674
4713
  readonly passwordRules: import("@angular/core").InputSignal<readonly PasswordRule[] | undefined>;
4675
- readonly type: import("@angular/core").InputSignal<"number" | "text" | "email" | "tel" | "password" | "url">;
4714
+ readonly type: import("@angular/core").InputSignal<"number" | "text" | "email" | "password" | "tel" | "url">;
4676
4715
  readonly maxlength: import("@angular/core").InputSignal<number | undefined>;
4677
4716
  readonly required: import("@angular/core").InputSignal<boolean>;
4678
4717
  readonly autocomplete: import("@angular/core").InputSignal<string>;
@@ -4681,7 +4720,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
4681
4720
  * `search`, `text`, `none`). Empty (default) = the browser's default for the field, except `type="tel"`, which keeps `tel`.
4682
4721
  * It only picks the keyboard; it does not restrict what can be typed or pasted.
4683
4722
  */
4684
- readonly inputmode: import("@angular/core").InputSignal<"" | "none" | "text" | "search" | "email" | "tel" | "url" | "decimal" | "numeric">;
4723
+ readonly inputmode: import("@angular/core").InputSignal<"" | "search" | "text" | "email" | "none" | "tel" | "url" | "decimal" | "numeric">;
4685
4724
  readonly readonly: import("@angular/core").InputSignal<boolean>;
4686
4725
  readonly hint: import("@angular/core").InputSignal<string>;
4687
4726
  readonly error: import("@angular/core").InputSignal<string>;
@@ -4745,7 +4784,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
4745
4784
  protected readonly _stepAttr: import("@angular/core").Signal<string | null>;
4746
4785
  protected readonly _revealable: import("@angular/core").Signal<boolean>;
4747
4786
  protected readonly _shown: import("@angular/core").WritableSignal<boolean>;
4748
- protected readonly _inputType: import("@angular/core").Signal<"number" | "text" | "email" | "tel" | "password" | "url">;
4787
+ protected readonly _inputType: import("@angular/core").Signal<"number" | "text" | "email" | "password" | "tel" | "url">;
4749
4788
  protected readonly _eyePath: string;
4750
4789
  protected readonly _eyeOffPath: string;
4751
4790
  protected readonly _showRequirements: import("@angular/core").Signal<boolean>;
@@ -6097,7 +6136,7 @@ export declare class DropdownComponent {
6097
6136
  readonly loader: import("@angular/core").InputSignal<(() => Promise<DropdownItem[]>) | null>;
6098
6137
  readonly active: import("@angular/core").InputSignal<boolean>;
6099
6138
  readonly activeValue: import("@angular/core").InputSignal<string>;
6100
- readonly variant: import("@angular/core").InputSignal<"badge" | "button">;
6139
+ readonly variant: import("@angular/core").InputSignal<"button" | "badge">;
6101
6140
  readonly menuWidth: import("@angular/core").InputSignal<string>;
6102
6141
  /**
6103
6142
  * Accessible name. Set it when the trigger has no meaningful visible text. Applied as `aria-label` on the
@@ -6296,7 +6335,7 @@ export declare class FormSectionComponent {
6296
6335
  }, {}, never, ["*"], true, never>;
6297
6336
  }
6298
6337
  export declare class FormRowComponent {
6299
- readonly cols: import("@angular/core").InputSignal<1 | 2 | 3 | 4>;
6338
+ readonly cols: import("@angular/core").InputSignal<1 | 3 | 4 | 2>;
6300
6339
  static ɵfac: i0.ɵɵFactoryDeclaration<FormRowComponent, never>;
6301
6340
  static ɵcmp: i0.ɵɵComponentDeclaration<FormRowComponent, "ui-form-row", never, {
6302
6341
  "cols": {
@@ -6313,7 +6352,7 @@ export declare class FormRowComponent {
6313
6352
  * child simply takes the full width. Keep a numeric span within the row's `cols` (use `all` for the whole row).
6314
6353
  */
6315
6354
  export declare class FormColSpanDirective {
6316
- readonly uiColSpan: import("@angular/core").InputSignal<"" | "2" | "3" | 2 | 3 | "all">;
6355
+ readonly uiColSpan: import("@angular/core").InputSignal<"" | "2" | "3" | 3 | 2 | "all">;
6317
6356
  protected readonly _class: import("@angular/core").Signal<string>;
6318
6357
  static ɵfac: i0.ɵɵFactoryDeclaration<FormColSpanDirective, never>;
6319
6358
  static ɵdir: i0.ɵɵDirectiveDeclaration<FormColSpanDirective, "[uiColSpan]", never, {
@@ -9254,7 +9293,7 @@ export declare class DetailCardComponent {
9254
9293
  /** true (default) = the title is displayed in capitals (CSS only); false = shown as written. The text, aria-label and heading name are never changed. */
9255
9294
  readonly uppercaseTitle: import("@angular/core").InputSignal<boolean>;
9256
9295
  /** 1-6 makes the title a real heading for screen readers (role=heading, aria-level); null keeps it plain text. */
9257
- readonly headingLevel: import("@angular/core").InputSignal<1 | 2 | 3 | 4 | 5 | 6 | null>;
9296
+ readonly headingLevel: import("@angular/core").InputSignal<1 | 3 | 4 | 2 | 5 | 6 | null>;
9258
9297
  /** Optional id for the title text; the card is then labelled by it. Without it the title is the card's aria-label. */
9259
9298
  readonly titleId: import("@angular/core").InputSignal<string>;
9260
9299
  /** Accessible name of the card when the header gives none (no header, or no title). A visible title wins; blank = no name. */
@@ -11422,10 +11461,10 @@ export interface SetupWizardTexts {
11422
11461
  selectSource: string;
11423
11462
  connected: string;
11424
11463
  importMore: string;
11425
- /** The link on an import step (before data came in) that downloads the template CSV: the header row and the config's `templateSampleRows`, so the user can add their data to it. */
11426
- downloadSample: string;
11427
11464
  /** Shown (and described by the disabled Continue) on an import step with `requireImport` until data came in. */
11428
11465
  importRequired: string;
11466
+ /** Shown (and described by the disabled Save & Continue) on an integrations step with `requireConnection` until one integration is connected. */
11467
+ connectRequired: string;
11429
11468
  /** An import where some rows were refused: the warning's title and text (rows that failed must be fixed and imported again before Continue) and the button that returns to the sources. */
11430
11469
  importErrorsTitle: (errors: number) => string;
11431
11470
  importErrorsText: (imported: number, errors: number) => string;
@@ -11453,8 +11492,8 @@ export interface SetupImportStep {
11453
11492
  buttonLabel: string;
11454
11493
  /** Hint above the button. */
11455
11494
  hint?: string;
11456
- /** Text of the template download link, e.g. "Download Products/Services CSV Template" (default: the `downloadSample` text, "Download CSV Template"). The file is this step's own template: the config's field labels and `templateSampleRows`. */
11457
- templateLabel?: string;
11495
+ /** Runs the import instead of `config.importEndpoint` (see `ImportExportComponent.submit`), e.g. when the server reads the CSV file itself. */
11496
+ submit?: (request: ImportSubmitRequest) => Observable<ImportSubmitResult>;
11458
11497
  /** Result alert title, built from the number imported (default `${n} ${config.entityNamePlural.toLowerCase()} imported successfully.`). */
11459
11498
  resultTitle?: (imported: number) => string;
11460
11499
  /** Result alert body. */
@@ -11502,6 +11541,8 @@ export interface SetupStep {
11502
11541
  ownActions?: boolean;
11503
11542
  import?: SetupImportStep;
11504
11543
  integrations?: SetupIntegration[];
11544
+ /** Integrations steps: Save & Continue stays disabled until at least one of the step's integrations is connected. Skip stays available. */
11545
+ requireConnection?: boolean;
11505
11546
  /** `integrations`: runs when the step is left with Continue (e.g. to save sender settings). */
11506
11547
  onContinue?: () => Observable<unknown> | Promise<unknown> | void;
11507
11548
  /** Called when the step is shown (load data for a custom step). */
@@ -11609,6 +11650,8 @@ export declare class SetupWizardComponent {
11609
11650
  protected readonly narrow: import("@angular/core").WritableSignal<boolean>;
11610
11651
  /** A step with `splitLayout`: the app's own content gets its own card, side by side with the step card on a wide screen. */
11611
11652
  /** An import step with `requireImport` keeps Continue off until something came in (a CSV import or `markCompleted`, e.g. a live sync). */
11653
+ /** An integrations step with `requireConnection` keeps Save & Continue off until at least one of its integrations is connected (Skip stays the way past). */
11654
+ protected readonly connectBlocked: import("@angular/core").Signal<boolean>;
11612
11655
  protected readonly importBlocked: import("@angular/core").Signal<boolean>;
11613
11656
  /** The step's own two parts (`splitLayout`) show as two tabs, one card at a time; this is the open one (it starts on the app's part on every visit). */
11614
11657
  protected readonly splitTab: import("@angular/core").WritableSignal<"main" | "extra">;
@@ -11695,8 +11738,6 @@ export declare class SetupWizardComponent {
11695
11738
  private messageOf;
11696
11739
  /** A source card was picked on the step itself: opens the import window already past its source step (at the upload step for that source). */
11697
11740
  protected startImport(key: string, source: string): void;
11698
- /** The sample CSV (the import window's template): the field labels as the header row and the config's example rows. */
11699
- protected downloadSample(): void;
11700
11741
  protected openImport(key: string): void;
11701
11742
  protected onImported(key: string): void;
11702
11743
  protected importResult(key: string): number | null;