@forgeroute/ui 0.4.35 → 0.4.37

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.35",
3
+ "version": "0.4.37",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=22.0.0",
6
6
  "@angular/core": ">=22.0.0",
@@ -4348,6 +4348,94 @@ export declare class ImportSourceGridComponent {
4348
4348
  "sourceSelect": "sourceSelect";
4349
4349
  }, never, never, true, never>;
4350
4350
  }
4351
+ /**
4352
+ * One option the user can pick or connect: a coloured tile (a letter, or a library icon), a title, a short description and a small action button.
4353
+ * The same card is used for the source cards of an import step, the provider cards of the setup wizard (calendar, email, tools) and a CRM
4354
+ * live-sync option, so they all look and behave alike. Anything inside the tag is shown under the row (an expanding form, a result).
4355
+ *
4356
+ * <ui-option-card title="Gmail" letter="G" color="#ea4335" description="Connect your Google account" actionLabel="Connect" (action)="connect()" />
4357
+ * <ui-option-card title="Follow Up Boss" letter="F" actionLabel="Sync live" (action)="open()"> <form>…</form> </ui-option-card>
4358
+ *
4359
+ * Inputs: `title` (required), `description`, `letter` (one character in the tile) or `icon` (a library icon name, used when there is no letter),
4360
+ * `color` (tile background, default slate), `actionLabel` (no label = no button), `actionVariant` (default secondary), `actionAriaLabel`,
4361
+ * `actionTestId`, `actionLoading`, `disabled`. Output: `action`.
4362
+ */
4363
+ export declare class OptionCardComponent {
4364
+ readonly title: import("@angular/core").InputSignal<string>;
4365
+ readonly description: import("@angular/core").InputSignal<string>;
4366
+ readonly letter: import("@angular/core").InputSignal<string>;
4367
+ readonly icon: import("@angular/core").InputSignal<string>;
4368
+ readonly color: import("@angular/core").InputSignal<string>;
4369
+ readonly actionLabel: import("@angular/core").InputSignal<string>;
4370
+ readonly actionVariant: import("@angular/core").InputSignal<"primary" | "secondary">;
4371
+ readonly actionAriaLabel: import("@angular/core").InputSignal<string>;
4372
+ readonly actionTestId: import("@angular/core").InputSignal<string>;
4373
+ readonly actionLoading: import("@angular/core").InputSignal<boolean>;
4374
+ readonly disabled: import("@angular/core").InputSignal<boolean>;
4375
+ /** The action button was pressed. */
4376
+ readonly action: import("@angular/core").OutputEmitterRef<void>;
4377
+ protected iconD(): string | null;
4378
+ static ɵfac: i0.ɵɵFactoryDeclaration<OptionCardComponent, never>;
4379
+ static ɵcmp: i0.ɵɵComponentDeclaration<OptionCardComponent, "ui-option-card", never, {
4380
+ "title": {
4381
+ "alias": "title";
4382
+ "required": true;
4383
+ "isSignal": true;
4384
+ };
4385
+ "description": {
4386
+ "alias": "description";
4387
+ "required": false;
4388
+ "isSignal": true;
4389
+ };
4390
+ "letter": {
4391
+ "alias": "letter";
4392
+ "required": false;
4393
+ "isSignal": true;
4394
+ };
4395
+ "icon": {
4396
+ "alias": "icon";
4397
+ "required": false;
4398
+ "isSignal": true;
4399
+ };
4400
+ "color": {
4401
+ "alias": "color";
4402
+ "required": false;
4403
+ "isSignal": true;
4404
+ };
4405
+ "actionLabel": {
4406
+ "alias": "actionLabel";
4407
+ "required": false;
4408
+ "isSignal": true;
4409
+ };
4410
+ "actionVariant": {
4411
+ "alias": "actionVariant";
4412
+ "required": false;
4413
+ "isSignal": true;
4414
+ };
4415
+ "actionAriaLabel": {
4416
+ "alias": "actionAriaLabel";
4417
+ "required": false;
4418
+ "isSignal": true;
4419
+ };
4420
+ "actionTestId": {
4421
+ "alias": "actionTestId";
4422
+ "required": false;
4423
+ "isSignal": true;
4424
+ };
4425
+ "actionLoading": {
4426
+ "alias": "actionLoading";
4427
+ "required": false;
4428
+ "isSignal": true;
4429
+ };
4430
+ "disabled": {
4431
+ "alias": "disabled";
4432
+ "required": false;
4433
+ "isSignal": true;
4434
+ };
4435
+ }, {
4436
+ "action": "action";
4437
+ }, never, ["*"], true, never>;
4438
+ }
4351
4439
  export interface ActiveConfirm {
4352
4440
  title: string;
4353
4441
  message: string;
@@ -11169,6 +11257,11 @@ export interface SetupIntegration {
11169
11257
  /** The "Connected — …" detail built from the status payload (default: just "Connected"). */
11170
11258
  connectedDetail?: (status: Record<string, unknown>) => string;
11171
11259
  connect: SetupIntegrationConnect;
11260
+ /**
11261
+ * Runs when the user presses Connect, before anything else (before the redirect to the provider, or before the area-code box opens): save what the
11262
+ * step collected so the redirect does not lose it. Resolve to go on; throw / error to stop (the message is shown in the step's alert).
11263
+ */
11264
+ beforeConnect?: () => Observable<unknown> | Promise<unknown> | void;
11172
11265
  }
11173
11266
  /** Texts of the built-in controls; every one has an English default and every one can be replaced by the app. */
11174
11267
  export interface SetupWizardTexts {
@@ -11186,6 +11279,12 @@ export interface SetupWizardTexts {
11186
11279
  selectSource: string;
11187
11280
  connected: string;
11188
11281
  importMore: string;
11282
+ /** Shown (and described by the disabled Continue) on an import step with `requireImport` until data came in. */
11283
+ importRequired: string;
11284
+ /** 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. */
11285
+ importErrorsTitle: (errors: number) => string;
11286
+ importErrorsText: (imported: number, errors: number) => string;
11287
+ importAgain: string;
11189
11288
  whatGetsImported: string;
11190
11289
  doneTitle: string;
11191
11290
  doneDescription: string;
@@ -11234,6 +11333,18 @@ export interface SetupStep {
11234
11333
  canContinue?: () => boolean;
11235
11334
  /** `custom`: text of the continue button (default "Save & Continue"). */
11236
11335
  saveLabel?: string;
11336
+ /**
11337
+ * Import / integrations steps with app content (`<ng-template uiSetupStep>`): show two tabs below the intro, one card at a time. The first tab holds the app's
11338
+ * content in a card titled `extraTitle`, the second the step's own card. Tab labels: `extraTab` / `mainTab` (default `extraTitle` / `cardTitle`).
11339
+ */
11340
+ splitLayout?: boolean;
11341
+ extraTitle?: string;
11342
+ extraTab?: string;
11343
+ mainTab?: string;
11344
+ /** Status line under the app content of a `splitLayout` step (e.g. "Not connected yet"); read on every render, so it can follow signals. */
11345
+ extraFooter?: () => string;
11346
+ /** Import steps: Continue stays disabled until the data came in (CSV import done with no refused rows, or the app called `markCompleted(key)` after a live sync). Skip stays available. */
11347
+ requireImport?: boolean;
11237
11348
  /**
11238
11349
  * `custom`: the step draws its own continue button (for example in the footer of a `ui-detail-card`), so the wizard does not show its own. The step's
11239
11350
  * template receives the wizard as `let-wizard` and calls `wizard.saveAndContinue()` (runs `save`, then moves on) and reads `wizard.busy()`.
@@ -11343,6 +11454,18 @@ export declare class SetupWizardComponent {
11343
11454
  private readonly http;
11344
11455
  private readonly apiBase;
11345
11456
  private readonly destroyRef;
11457
+ /** Phone layout: the step's Back / Skip / Continue buttons fill the width and stack (primary on top). */
11458
+ protected readonly narrow: import("@angular/core").WritableSignal<boolean>;
11459
+ /** A step with `splitLayout`: the app's own content gets its own card, side by side with the step card on a wide screen. */
11460
+ /** An import step with `requireImport` keeps Continue off until something came in (a CSV import or `markCompleted`, e.g. a live sync). */
11461
+ protected readonly importBlocked: import("@angular/core").Signal<boolean>;
11462
+ /** 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). */
11463
+ protected readonly splitTab: import("@angular/core").WritableSignal<"main" | "extra">;
11464
+ protected readonly splitTabs: import("@angular/core").Signal<{
11465
+ key: string;
11466
+ label: string;
11467
+ }[]>;
11468
+ protected readonly split: import("@angular/core").Signal<boolean>;
11346
11469
  /** The steps in walking order. A `done` summary step is appended automatically. */
11347
11470
  readonly steps: import("@angular/core").InputSignal<SetupStep[]>;
11348
11471
  /** Replaces any of the built-in texts. */
@@ -11355,12 +11478,15 @@ export declare class SetupWizardComponent {
11355
11478
  readonly stepChange: import("@angular/core").OutputEmitterRef<string>;
11356
11479
  protected readonly stepTemplates: import("@angular/core").Signal<readonly SetupWizardStepDirective[]>;
11357
11480
  protected readonly headerTemplates: import("@angular/core").Signal<readonly SetupWizardStepHeaderDirective[]>;
11481
+ private readonly injector;
11482
+ private readonly stepTitle;
11358
11483
  protected readonly importers: import("@angular/core").Signal<readonly ImportExportComponent[]>;
11359
11484
  protected readonly t: import("@angular/core").Signal<SetupWizardTexts>;
11360
11485
  protected readonly currentKey: import("@angular/core").WritableSignal<string>;
11361
11486
  private readonly completed;
11362
11487
  private readonly skipped;
11363
11488
  private readonly imports;
11489
+ private readonly importErrors;
11364
11490
  private readonly statuses;
11365
11491
  readonly busy: import("@angular/core").WritableSignal<boolean>;
11366
11492
  /** What a custom step's template receives (`let-wizard`). */
@@ -11408,6 +11534,7 @@ export declare class SetupWizardComponent {
11408
11534
  protected openImport(key: string): void;
11409
11535
  protected onImported(key: string): void;
11410
11536
  protected importResult(key: string): number | null;
11537
+ protected importErrorCount(key: string): number;
11411
11538
  protected clearImport(key: string): void;
11412
11539
  protected importTitle(key: string): string;
11413
11540
  protected continueFromImport(): void;
@@ -11416,6 +11543,7 @@ export declare class SetupWizardComponent {
11416
11543
  protected isConnected(i: SetupIntegration): boolean;
11417
11544
  protected detailFor(i: SetupIntegration): string;
11418
11545
  protected connect(i: SetupIntegration): void;
11546
+ private startConnect;
11419
11547
  /** SVG path of a library icon (the buttons' leading / trailing glyph). */
11420
11548
  protected iconD(name: string): string;
11421
11549
  protected areaCodeLabelFor(i: SetupIntegration): string;
@@ -11492,6 +11620,8 @@ export interface EmailTemplateVariable {
11492
11620
  key: string;
11493
11621
  label: string;
11494
11622
  example: string;
11623
+ /** Optional one-line explanation of what the variable is filled with; shown under the example. */
11624
+ description?: string;
11495
11625
  }
11496
11626
  export interface EmailTemplateVariableGroup {
11497
11627
  name: string;