@forgeroute/ui 0.4.32 → 0.4.34

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.32",
3
+ "version": "0.4.34",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=22.0.0",
6
6
  "@angular/core": ">=22.0.0",
@@ -2571,6 +2571,8 @@ export declare class SkeletonComponent {
2571
2571
  /**
2572
2572
  * Hover / focus tooltip for any element: `<span uiTooltip="Saved">`.
2573
2573
  * Empty text shows nothing. Line breaks (`\n`) are kept. Escape or leaving the element closes it.
2574
+ * Only one tooltip is open at a time anywhere on the page: opening one closes the previous (e.g. a tooltip on a container and on a control inside
2575
+ * it never both show; the innermost one the pointer entered last wins).
2574
2576
  * The bubble is rendered on `document.body` (position: fixed) so table/panel overflow never clips it.
2575
2577
  */
2576
2578
  export declare class TooltipDirective {
@@ -3941,10 +3943,36 @@ export declare class ButtonComponent {
3941
3943
  };
3942
3944
  }, {}, never, ["*"], true, never>;
3943
3945
  }
3946
+ /** A small icon button shown inside a toggle badge, after the label (e.g. Configure, Analytics). */
3947
+ export interface ToggleBadgeAction {
3948
+ /** Emitted by `(action)` when the button is clicked. */
3949
+ id: string;
3950
+ /** Accessible name of the button (also used as the tooltip when `tooltip` is empty). */
3951
+ label: string;
3952
+ /** SVG path data (`d`) of a 24x24 stroked icon. Several shapes can be joined in one string (`M..M..`). */
3953
+ icon: string;
3954
+ /** Text of the hover / focus tooltip. */
3955
+ tooltip?: string;
3956
+ disabled?: boolean;
3957
+ }
3958
+ /**
3959
+ * Pill that toggles on / off. Optional `actions` put small icon buttons INSIDE the pill, after the label and a divider, each with its own
3960
+ * tooltip; the label button and the icon buttons are separate buttons (never nested). Clicking an icon button emits `(action)` with its id and
3961
+ * never `(toggle)`. Content projected into the component (an icon) goes before the label, as before.
3962
+ */
3944
3963
  export declare class ToggleBadgeComponent {
3945
3964
  readonly label: import("@angular/core").InputSignal<string>;
3946
3965
  readonly active: import("@angular/core").InputSignal<boolean>;
3966
+ /** Icon buttons shown inside the pill after the label. Empty (default) = a plain pill, exactly as before. */
3967
+ readonly actions: import("@angular/core").InputSignal<ToggleBadgeAction[]>;
3968
+ /**
3969
+ * Hover / focus tooltip of the LABEL button only. Use this instead of `uiTooltip` on `<ui-toggle-badge>` when the badge has `actions`:
3970
+ * a tooltip on the host would also open while the pointer is over an icon button and stack on top of that icon's own tooltip.
3971
+ */
3972
+ readonly tooltip: import("@angular/core").InputSignal<string>;
3947
3973
  readonly toggle: import("@angular/core").OutputEmitterRef<void>;
3974
+ /** An icon button was clicked: its `id`. Never emits `toggle`. */
3975
+ readonly action: import("@angular/core").OutputEmitterRef<string>;
3948
3976
  static ɵfac: i0.ɵɵFactoryDeclaration<ToggleBadgeComponent, never>;
3949
3977
  static ɵcmp: i0.ɵɵComponentDeclaration<ToggleBadgeComponent, "ui-toggle-badge", never, {
3950
3978
  "label": {
@@ -3957,8 +3985,19 @@ export declare class ToggleBadgeComponent {
3957
3985
  "required": false;
3958
3986
  "isSignal": true;
3959
3987
  };
3988
+ "actions": {
3989
+ "alias": "actions";
3990
+ "required": false;
3991
+ "isSignal": true;
3992
+ };
3993
+ "tooltip": {
3994
+ "alias": "tooltip";
3995
+ "required": false;
3996
+ "isSignal": true;
3997
+ };
3960
3998
  }, {
3961
3999
  "toggle": "toggle";
4000
+ "action": "action";
3962
4001
  }, never, ["*"], true, never>;
3963
4002
  }
3964
4003
  export interface PillTab {
@@ -7436,7 +7475,7 @@ export declare class AlertComponent {
7436
7475
  /** The SVG path (24×24 stroke icon) for an icon key, or undefined when the key is unknown. */
7437
7476
  export declare function iconPath(name: string): string | undefined;
7438
7477
  /** Keys with an icon of their own (the data-table action keys are accepted too — see `builtInActionIcon`). */
7439
- export type IconName = 'add' | 'close' | 'check' | 'upload' | 'image' | 'chevron-up' | 'chevron-down' | 'arrow-left' | 'bell' | 'print' | 'lock' | 'shield' | 'arrow-up' | 'arrow-down' | 'arrow-right' | 'document' | 'grip' | 'card' | 'bank' | 'view' | 'view-off' | 'edit' | 'delete' | 'download' | 'duplicate' | 'archive' | 'restore' | 'share' | 'email' | 'message' | 'call' | 'refund' | 'chevron-right' | 'link' | 'save' | 'chart' | 'clipboard';
7478
+ export type IconName = 'add' | 'close' | 'check' | 'upload' | 'image' | 'chevron-up' | 'chevron-down' | 'arrow-left' | 'bell' | 'print' | 'lock' | 'shield' | 'arrow-up' | 'arrow-down' | 'arrow-right' | 'document' | 'grip' | 'card' | 'bank' | 'view' | 'view-off' | 'edit' | 'delete' | 'download' | 'duplicate' | 'archive' | 'restore' | 'share' | 'email' | 'message' | 'call' | 'refund' | 'chevron-right' | 'link' | 'save' | 'chart' | 'clipboard' | 'unlink' | 'send' | 'refresh';
7440
7479
  /**
7441
7480
  * A clickable icon. The host passes a key (`name="delete"`) and the library draws that icon; clicking it emits
7442
7481
  * `iconClick`, and the host does the actual work (delete the row, open a panel, …).
@@ -11115,8 +11154,12 @@ export interface SetupIntegration {
11115
11154
  title: string;
11116
11155
  /** Shown while the integration is not connected. */
11117
11156
  description: string;
11118
- /** Library `ui-list-item` icon name (default 'link'). */
11157
+ /** Library icon name drawn in the tile when there is no `letter` (default 'link'). */
11119
11158
  icon?: string;
11159
+ /** One letter shown in the coloured tile (like the source cards of an import step); takes the place of `icon`. */
11160
+ letter?: string;
11161
+ /** Background of the tile (any CSS colour; default slate). */
11162
+ color?: string;
11120
11163
  /** GET answering `{ connected: boolean, ... }` (relative to the API base URL of `FORGEROUTE_CONFIG`). */
11121
11164
  statusEndpoint: string;
11122
11165
  /** When one status endpoint answers several providers (`{ gmail: {...}, outlook: {...} }`), the property that belongs to this one. */
@@ -11179,7 +11222,7 @@ export interface SetupStep {
11179
11222
  cardTitle?: string;
11180
11223
  /** The paragraph under the heading. */
11181
11224
  description?: string;
11182
- /** `custom` shows the app's own `<ng-template uiSetupStep="key">`; `import` and `integrations` are built in. */
11225
+ /** `custom` shows the app's own `<ng-template uiSetupStep="key">`; `import` and `integrations` are built in (an app template with the step's key is shown above the built-in content). */
11183
11226
  kind: 'custom' | 'import' | 'integrations';
11184
11227
  /** Shows "Skip for now" (default true). The first step of a wizard usually sets this to false. */
11185
11228
  skippable?: boolean;
@@ -11208,6 +11251,8 @@ export interface SetupWizardApi {
11208
11251
  saveAndContinue(): Promise<void>;
11209
11252
  /** True while a save is running. */
11210
11253
  readonly busy: () => boolean;
11254
+ /** Marks steps as done (check mark, counted in the progress) without the user visiting them; unknown keys are ignored. For example a live sync that already brought in the data of later steps. */
11255
+ markCompleted(...keys: string[]): void;
11211
11256
  }
11212
11257
  /**
11213
11258
  * The integrations every app can offer in a setup step. The endpoints follow the convention the apps' backends already use (`GET <x>/status`,
@@ -11224,6 +11269,8 @@ export declare function setupIntegrations(...keys: (keyof typeof SETUP_INTEGRATI
11224
11269
  * <ng-template uiSetupStep="profile"> …the app's own form… </ng-template>
11225
11270
  * </ui-setup-wizard>
11226
11271
  *
11272
+ * An `import` or `integrations` step with a template of its key shows it ABOVE the built-in content (for example a "connect your CRM" panel above the source cards).
11273
+ *
11227
11274
  * A step with `ownActions: true` draws its own continue button: `<ng-template uiSetupStep="profile" let-wizard>` … `(click)="wizard.saveAndContinue()"`.
11228
11275
  */
11229
11276
  export declare class SetupWizardStepDirective {
@@ -11346,6 +11393,8 @@ export declare class SetupWizardComponent {
11346
11393
  private advanceFrom;
11347
11394
  protected back(): void;
11348
11395
  protected skip(): void;
11396
+ /** Marks the given steps done (ignoring keys that are not steps of this wizard). */
11397
+ private markStepsCompleted;
11349
11398
  private markCompleted;
11350
11399
  /** "Save & Continue" of a custom or integrations step: runs the step's hook, then moves on. */
11351
11400
  saveAndContinue(): Promise<void>;
@@ -11395,12 +11444,6 @@ export interface EmailTemplateAssignmentOption {
11395
11444
  name: string;
11396
11445
  description: string;
11397
11446
  }
11398
- /** The channels a template is assigned to for one trigger. */
11399
- export interface EmailTemplateAssignmentChannels {
11400
- key: string;
11401
- email: boolean;
11402
- text: boolean;
11403
- }
11404
11447
  /** A template as the editor shows it. `id` is null/absent for a template that is not stored yet (new, or a copy of another). */
11405
11448
  export interface EmailTemplateValue {
11406
11449
  id?: string | null;
@@ -11416,8 +11459,8 @@ export interface EmailTemplateValue {
11416
11459
  body: string;
11417
11460
  videoId?: string | null;
11418
11461
  videoTitle?: string | null;
11419
- /** The channels per trigger; a trigger that is missing is not assigned. */
11420
- assignments?: EmailTemplateAssignmentChannels[];
11462
+ /** The keys of the triggers (`EmailTemplateAssignmentOption.key`) this template is assigned to. */
11463
+ assignments?: string[];
11421
11464
  }
11422
11465
  /** What `(save)` emits. Dates are the raw `YYYY-MM-DD` values (null while "all year" is on); the host maps them to its API. */
11423
11466
  export interface EmailTemplateSavePayload {
@@ -11429,8 +11472,8 @@ export interface EmailTemplateSavePayload {
11429
11472
  activeFrom: string | null;
11430
11473
  activeTo: string | null;
11431
11474
  videoId: string | null;
11432
- /** Only the triggers with at least one channel on. */
11433
- assignments: EmailTemplateAssignmentChannels[];
11475
+ /** The keys of the triggers this template is assigned to. */
11476
+ assignments: string[];
11434
11477
  }
11435
11478
  export interface EmailTemplateBlock {
11436
11479
  key: string;
@@ -11479,8 +11522,7 @@ interface EmailBlock {
11479
11522
  spacing?: string;
11480
11523
  }
11481
11524
  interface AssignmentView extends EmailTemplateAssignmentOption {
11482
- email: boolean;
11483
- text: boolean;
11525
+ assigned: boolean;
11484
11526
  }
11485
11527
  type EditorTab = 'edit' | 'preview' | 'mobile';
11486
11528
  type RightTab = 'blocks' | 'variables' | 'video';
@@ -11499,7 +11541,6 @@ type RightTab = 'blocks' | 'variables' | 'video';
11499
11541
  export declare class EmailTemplateEditorComponent {
11500
11542
  private readonly host;
11501
11543
  private readonly injector;
11502
- private readonly toast;
11503
11544
  /** The template to edit. `null` = a blank new template. An object without `id` is a new template that starts from those values (e.g. a copy). */
11504
11545
  readonly template: import("@angular/core").InputSignal<EmailTemplateValue | null>;
11505
11546
  readonly categories: import("@angular/core").InputSignal<SelectOption<string>[]>;
@@ -11508,9 +11549,10 @@ export declare class EmailTemplateEditorComponent {
11508
11549
  /** The assignment shown first (e.g. the trigger the user came from). */
11509
11550
  readonly featuredAssignmentKey: import("@angular/core").InputSignal<string | null>;
11510
11551
  readonly assignmentsDescription: import("@angular/core").InputSignal<string>;
11511
- readonly textEnabled: import("@angular/core").InputSignal<boolean>;
11512
11552
  readonly variableGroups: import("@angular/core").InputSignal<EmailTemplateVariableGroup[]>;
11513
11553
  readonly blockGroups: import("@angular/core").InputSignal<EmailTemplateBlockGroup[]>;
11554
+ /** Page heading shown at the start of the actions row (e.g. "Create Your Template"). Empty (default) = no heading; the buttons stay right aligned. */
11555
+ readonly heading: import("@angular/core").InputSignal<string>;
11514
11556
  readonly namePlaceholder: import("@angular/core").InputSignal<string>;
11515
11557
  readonly subjectPlaceholder: import("@angular/core").InputSignal<string>;
11516
11558
  readonly systemNote: import("@angular/core").InputSignal<string>;
@@ -11555,8 +11597,8 @@ export declare class EmailTemplateEditorComponent {
11555
11597
  readonly activeTo: import("@angular/core").WritableSignal<string>;
11556
11598
  readonly videoId: import("@angular/core").WritableSignal<string | null>;
11557
11599
  readonly videoTitle: import("@angular/core").WritableSignal<string | null>;
11558
- /** The channels the template has per trigger; the rows shown are `assignmentOptions` with these applied. */
11559
- private readonly assignmentChannels;
11600
+ /** The triggers this template is assigned to (an email template is only ever assigned for email); the rows shown are `assignmentOptions` with this applied. */
11601
+ private readonly assignedKeys;
11560
11602
  private readonly assignmentState;
11561
11603
  readonly blocks: import("@angular/core").WritableSignal<EmailBlock[]>;
11562
11604
  readonly selectedBlockId: import("@angular/core").WritableSignal<string | null>;
@@ -11594,10 +11636,6 @@ export declare class EmailTemplateEditorComponent {
11594
11636
  readonly imageAlt: import("@angular/core").WritableSignal<string>;
11595
11637
  readonly showTestSendDialog: import("@angular/core").WritableSignal<boolean>;
11596
11638
  readonly testSendEmail: import("@angular/core").WritableSignal<string>;
11597
- readonly showAssignmentConfig: import("@angular/core").WritableSignal<boolean>;
11598
- readonly configTarget: import("@angular/core").WritableSignal<AssignmentView | null>;
11599
- readonly configEmail: import("@angular/core").WritableSignal<boolean>;
11600
- readonly configText: import("@angular/core").WritableSignal<boolean>;
11601
11639
  readonly activeEditorTab: import("@angular/core").WritableSignal<EditorTab>;
11602
11640
  readonly activeRightTab: import("@angular/core").WritableSignal<RightTab>;
11603
11641
  readonly blockSearch: import("@angular/core").WritableSignal<string>;
@@ -11726,8 +11764,8 @@ export declare class EmailTemplateEditorComponent {
11726
11764
  insertVideo(video: EmailTemplateVideo): void;
11727
11765
  formatDuration(seconds: number | null | undefined): string;
11728
11766
  categoryLabel(cat: string | null | undefined): string;
11729
- openAssignmentConfig(item: AssignmentView): void;
11730
- saveAssignmentConfig(): void;
11767
+ /** Click / Enter / Space on a row: assign this template to that automation, or take it off again. */
11768
+ toggleAssignment(item: AssignmentView): void;
11731
11769
  isOpen(id: string): boolean;
11732
11770
  toggleGroup(id: string): void;
11733
11771
  insertBlock(block: EmailTemplateBlock): void;
@@ -11765,11 +11803,6 @@ export declare class EmailTemplateEditorComponent {
11765
11803
  "required": false;
11766
11804
  "isSignal": true;
11767
11805
  };
11768
- "textEnabled": {
11769
- "alias": "textEnabled";
11770
- "required": false;
11771
- "isSignal": true;
11772
- };
11773
11806
  "variableGroups": {
11774
11807
  "alias": "variableGroups";
11775
11808
  "required": false;
@@ -11780,6 +11813,11 @@ export declare class EmailTemplateEditorComponent {
11780
11813
  "required": false;
11781
11814
  "isSignal": true;
11782
11815
  };
11816
+ "heading": {
11817
+ "alias": "heading";
11818
+ "required": false;
11819
+ "isSignal": true;
11820
+ };
11783
11821
  "namePlaceholder": {
11784
11822
  "alias": "namePlaceholder";
11785
11823
  "required": false;