@forgeroute/ui 0.4.28 → 0.4.31
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/fesm2022/forgeroute-ui.mjs +222 -373
- package/fesm2022/forgeroute-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/forgeroute-ui.d.ts +76 -74
package/package.json
CHANGED
package/types/forgeroute-ui.d.ts
CHANGED
|
@@ -2491,7 +2491,7 @@ export declare class AudioPlayerComponent {
|
|
|
2491
2491
|
/** Accessible name of the player. */
|
|
2492
2492
|
readonly ariaLabel: import("@angular/core").InputSignal<string>;
|
|
2493
2493
|
/** How much to load before play: 'metadata' (default), 'auto' or 'none'. */
|
|
2494
|
-
readonly preload: import("@angular/core").InputSignal<"
|
|
2494
|
+
readonly preload: import("@angular/core").InputSignal<"none" | "auto" | "metadata">;
|
|
2495
2495
|
/** Fires when the browser can't load or decode the source. */
|
|
2496
2496
|
readonly playbackError: import("@angular/core").OutputEmitterRef<void>;
|
|
2497
2497
|
protected readonly failed: import("@angular/core").WritableSignal<boolean>;
|
|
@@ -3766,7 +3766,7 @@ export declare class ButtonComponent {
|
|
|
3766
3766
|
* `ghost-start`: a ghost button for list / section toggles - a full-width row with its content aligned to the start, transparent
|
|
3767
3767
|
* background, hover tint and the normal focus ring. Pair it with `ariaExpanded` / `ariaPressed`; the label may contain a heading element.
|
|
3768
3768
|
*/
|
|
3769
|
-
readonly variant: import("@angular/core").InputSignal<"
|
|
3769
|
+
readonly variant: import("@angular/core").InputSignal<"primary" | "secondary" | "danger" | "warning" | "link" | "ghost" | "ghost-start" | "tab" | "icon" | "icon-danger">;
|
|
3770
3770
|
/** 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`). */
|
|
3771
3771
|
readonly routerLink: import("@angular/core").InputSignal<string | readonly unknown[] | null>;
|
|
3772
3772
|
/** Query params of the `routerLink` (e.g. `{ section: 'deal-defaults' }`). */
|
|
@@ -3787,7 +3787,7 @@ export declare class ButtonComponent {
|
|
|
3787
3787
|
*/
|
|
3788
3788
|
readonly href: import("@angular/core").InputSignal<string | null>;
|
|
3789
3789
|
/** Where to open the `href` (`_blank` = a new tab). */
|
|
3790
|
-
readonly target: import("@angular/core").InputSignal<"
|
|
3790
|
+
readonly target: import("@angular/core").InputSignal<"_self" | "_blank" | "_parent" | "_top" | null>;
|
|
3791
3791
|
/** `rel` of the `href` link. A `_blank` target always gets `noopener noreferrer` added. */
|
|
3792
3792
|
readonly rel: import("@angular/core").InputSignal<string | null>;
|
|
3793
3793
|
/** The href when it is allowed (http, https, mailto, tel, sms or a relative URL), else null. */
|
|
@@ -3812,7 +3812,7 @@ export declare class ButtonComponent {
|
|
|
3812
3812
|
readonly color: import("@angular/core").InputSignal<string | undefined>;
|
|
3813
3813
|
readonly active: import("@angular/core").InputSignal<boolean>;
|
|
3814
3814
|
readonly size: import("@angular/core").InputSignal<"sm" | "md" | "lg" | "xs">;
|
|
3815
|
-
readonly type: import("@angular/core").InputSignal<"
|
|
3815
|
+
readonly type: import("@angular/core").InputSignal<"reset" | "submit" | "button">;
|
|
3816
3816
|
readonly disabled: import("@angular/core").InputSignal<boolean>;
|
|
3817
3817
|
readonly loading: import("@angular/core").InputSignal<boolean>;
|
|
3818
3818
|
readonly fullWidth: import("@angular/core").InputSignal<boolean>;
|
|
@@ -4427,7 +4427,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
|
|
|
4427
4427
|
readonly passwordRequirements: import("@angular/core").InputSignal<boolean>;
|
|
4428
4428
|
/** Rules for `passwordRequirements`; default = the library's five rules (8+ characters, upper, lower, digit, special). */
|
|
4429
4429
|
readonly passwordRules: import("@angular/core").InputSignal<readonly PasswordRule[] | undefined>;
|
|
4430
|
-
readonly type: import("@angular/core").InputSignal<"number" | "text" | "
|
|
4430
|
+
readonly type: import("@angular/core").InputSignal<"number" | "text" | "email" | "tel" | "password" | "url">;
|
|
4431
4431
|
readonly maxlength: import("@angular/core").InputSignal<number | undefined>;
|
|
4432
4432
|
readonly required: import("@angular/core").InputSignal<boolean>;
|
|
4433
4433
|
readonly autocomplete: import("@angular/core").InputSignal<string>;
|
|
@@ -4436,7 +4436,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
|
|
|
4436
4436
|
* `search`, `text`, `none`). Empty (default) = the browser's default for the field, except `type="tel"`, which keeps `tel`.
|
|
4437
4437
|
* It only picks the keyboard; it does not restrict what can be typed or pasted.
|
|
4438
4438
|
*/
|
|
4439
|
-
readonly inputmode: import("@angular/core").InputSignal<"" | "
|
|
4439
|
+
readonly inputmode: import("@angular/core").InputSignal<"" | "none" | "text" | "search" | "email" | "tel" | "url" | "decimal" | "numeric">;
|
|
4440
4440
|
readonly readonly: import("@angular/core").InputSignal<boolean>;
|
|
4441
4441
|
readonly hint: import("@angular/core").InputSignal<string>;
|
|
4442
4442
|
readonly error: import("@angular/core").InputSignal<string>;
|
|
@@ -4500,7 +4500,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
|
|
|
4500
4500
|
protected readonly _stepAttr: import("@angular/core").Signal<string | null>;
|
|
4501
4501
|
protected readonly _revealable: import("@angular/core").Signal<boolean>;
|
|
4502
4502
|
protected readonly _shown: import("@angular/core").WritableSignal<boolean>;
|
|
4503
|
-
protected readonly _inputType: import("@angular/core").Signal<"number" | "text" | "
|
|
4503
|
+
protected readonly _inputType: import("@angular/core").Signal<"number" | "text" | "email" | "tel" | "password" | "url">;
|
|
4504
4504
|
protected readonly _eyePath: string;
|
|
4505
4505
|
protected readonly _eyeOffPath: string;
|
|
4506
4506
|
protected readonly _showRequirements: import("@angular/core").Signal<boolean>;
|
|
@@ -5848,7 +5848,7 @@ export declare class DropdownComponent {
|
|
|
5848
5848
|
readonly loader: import("@angular/core").InputSignal<(() => Promise<DropdownItem[]>) | null>;
|
|
5849
5849
|
readonly active: import("@angular/core").InputSignal<boolean>;
|
|
5850
5850
|
readonly activeValue: import("@angular/core").InputSignal<string>;
|
|
5851
|
-
readonly variant: import("@angular/core").InputSignal<"
|
|
5851
|
+
readonly variant: import("@angular/core").InputSignal<"badge" | "button">;
|
|
5852
5852
|
readonly menuWidth: import("@angular/core").InputSignal<string>;
|
|
5853
5853
|
/**
|
|
5854
5854
|
* Accessible name. Set it when the trigger has no meaningful visible text. Applied as `aria-label` on the
|
|
@@ -6046,7 +6046,7 @@ export declare class FormRowComponent {
|
|
|
6046
6046
|
* child simply takes the full width. Keep a numeric span within the row's `cols` (use `all` for the whole row).
|
|
6047
6047
|
*/
|
|
6048
6048
|
export declare class FormColSpanDirective {
|
|
6049
|
-
readonly uiColSpan: import("@angular/core").InputSignal<"" | "
|
|
6049
|
+
readonly uiColSpan: import("@angular/core").InputSignal<"" | "2" | "3" | 2 | 3 | "all">;
|
|
6050
6050
|
protected readonly _class: import("@angular/core").Signal<string>;
|
|
6051
6051
|
static ɵfac: i0.ɵɵFactoryDeclaration<FormColSpanDirective, never>;
|
|
6052
6052
|
static ɵdir: i0.ɵɵDirectiveDeclaration<FormColSpanDirective, "[uiColSpan]", never, {
|
|
@@ -7076,7 +7076,7 @@ export declare class ChipGroupComponent {
|
|
|
7076
7076
|
readonly spaceAbove: import("@angular/core").InputSignal<"none" | "sm" | "md">;
|
|
7077
7077
|
/** Space below the chip group. */
|
|
7078
7078
|
readonly spaceBelow: import("@angular/core").InputSignal<"none" | "sm" | "md">;
|
|
7079
|
-
protected readonly _gap: import("@angular/core").Signal<"
|
|
7079
|
+
protected readonly _gap: import("@angular/core").Signal<"6px" | "12px" | "8px">;
|
|
7080
7080
|
protected readonly _spaceAbove: import("@angular/core").Signal<"0" | "6px" | "12px">;
|
|
7081
7081
|
protected readonly _spaceBelow: import("@angular/core").Signal<"0" | "6px" | "12px">;
|
|
7082
7082
|
static ɵfac: i0.ɵɵFactoryDeclaration<ChipGroupComponent, never>;
|
|
@@ -11129,6 +11129,12 @@ export interface SetupStep {
|
|
|
11129
11129
|
canContinue?: () => boolean;
|
|
11130
11130
|
/** `custom`: text of the continue button (default "Save & Continue"). */
|
|
11131
11131
|
saveLabel?: string;
|
|
11132
|
+
/**
|
|
11133
|
+
* `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
|
|
11134
|
+
* template receives the wizard as `let-wizard` and calls `wizard.saveAndContinue()` (runs `save`, then moves on) and reads `wizard.busy()`.
|
|
11135
|
+
* Back / Skip stay the wizard's.
|
|
11136
|
+
*/
|
|
11137
|
+
ownActions?: boolean;
|
|
11132
11138
|
import?: SetupImportStep;
|
|
11133
11139
|
integrations?: SetupIntegration[];
|
|
11134
11140
|
/** `integrations`: runs when the step is left with Continue (e.g. to save sender settings). */
|
|
@@ -11136,6 +11142,13 @@ export interface SetupStep {
|
|
|
11136
11142
|
/** Called when the step is shown (load data for a custom step). */
|
|
11137
11143
|
onEnter?: () => void;
|
|
11138
11144
|
}
|
|
11145
|
+
/** What a custom step's template gets as `let-wizard` when the step draws its own continue button (`ownActions`). */
|
|
11146
|
+
export interface SetupWizardApi {
|
|
11147
|
+
/** Runs the step's `save` hook (and shows its error), then moves to the next step. */
|
|
11148
|
+
saveAndContinue(): Promise<void>;
|
|
11149
|
+
/** True while a save is running. */
|
|
11150
|
+
readonly busy: () => boolean;
|
|
11151
|
+
}
|
|
11139
11152
|
/**
|
|
11140
11153
|
* The integrations every app can offer in a setup step. The endpoints follow the convention the apps' backends already use (`GET <x>/status`,
|
|
11141
11154
|
* `GET <x>/authorize` answering `{ url }`); an app whose routes differ spreads a preset and overrides what differs:
|
|
@@ -11150,11 +11163,19 @@ export declare function setupIntegrations(...keys: (keyof typeof SETUP_INTEGRATI
|
|
|
11150
11163
|
* <ui-setup-wizard [steps]="steps()">
|
|
11151
11164
|
* <ng-template uiSetupStep="profile"> …the app's own form… </ng-template>
|
|
11152
11165
|
* </ui-setup-wizard>
|
|
11166
|
+
*
|
|
11167
|
+
* A step with `ownActions: true` draws its own continue button: `<ng-template uiSetupStep="profile" let-wizard>` … `(click)="wizard.saveAndContinue()"`.
|
|
11153
11168
|
*/
|
|
11154
11169
|
export declare class SetupWizardStepDirective {
|
|
11155
11170
|
/** The `key` of the step this template belongs to. */
|
|
11156
11171
|
readonly key: import("@angular/core").InputSignal<string>;
|
|
11157
|
-
readonly template: TemplateRef<
|
|
11172
|
+
readonly template: TemplateRef<{
|
|
11173
|
+
$implicit: SetupWizardApi;
|
|
11174
|
+
}>;
|
|
11175
|
+
/** Types `let-wizard` in the step's template as `SetupWizardApi`. */
|
|
11176
|
+
static ngTemplateContextGuard(_dir: SetupWizardStepDirective, _ctx: unknown): _ctx is {
|
|
11177
|
+
$implicit: SetupWizardApi;
|
|
11178
|
+
};
|
|
11158
11179
|
static ɵfac: i0.ɵɵFactoryDeclaration<SetupWizardStepDirective, never>;
|
|
11159
11180
|
static ɵdir: i0.ɵɵDirectiveDeclaration<SetupWizardStepDirective, "ng-template[uiSetupStep]", never, {
|
|
11160
11181
|
"key": {
|
|
@@ -11164,6 +11185,11 @@ export declare class SetupWizardStepDirective {
|
|
|
11164
11185
|
};
|
|
11165
11186
|
}, {}, never, never, true, never>;
|
|
11166
11187
|
}
|
|
11188
|
+
/** Splits a description into its first sentence (title) and the rest (text). A single sentence is all title. */
|
|
11189
|
+
export declare function splitIntro(description: string): {
|
|
11190
|
+
title: string;
|
|
11191
|
+
text: string;
|
|
11192
|
+
};
|
|
11167
11193
|
/** The key of the summary step the wizard appends to the app's steps. */
|
|
11168
11194
|
export declare const SETUP_DONE_KEY = "done";
|
|
11169
11195
|
/**
|
|
@@ -11204,7 +11230,9 @@ export declare class SetupWizardComponent {
|
|
|
11204
11230
|
private readonly skipped;
|
|
11205
11231
|
private readonly imports;
|
|
11206
11232
|
private readonly statuses;
|
|
11207
|
-
|
|
11233
|
+
readonly busy: import("@angular/core").WritableSignal<boolean>;
|
|
11234
|
+
/** What a custom step's template receives (`let-wizard`). */
|
|
11235
|
+
protected readonly api: SetupWizardApi;
|
|
11208
11236
|
protected readonly error: import("@angular/core").WritableSignal<string>;
|
|
11209
11237
|
protected readonly areaCodeOpen: import("@angular/core").WritableSignal<string>;
|
|
11210
11238
|
protected readonly areaCode: import("@angular/core").WritableSignal<string>;
|
|
@@ -11214,12 +11242,19 @@ export declare class SetupWizardComponent {
|
|
|
11214
11242
|
protected readonly allSteps: import("@angular/core").Signal<SetupStep[]>;
|
|
11215
11243
|
protected readonly index: import("@angular/core").Signal<number>;
|
|
11216
11244
|
protected readonly current: import("@angular/core").Signal<SetupStep>;
|
|
11245
|
+
/** The step's description as a blue header: its first sentence is the title, the rest the text under it. */
|
|
11246
|
+
protected readonly intro: import("@angular/core").Signal<{
|
|
11247
|
+
title: string;
|
|
11248
|
+
text: string;
|
|
11249
|
+
} | null>;
|
|
11217
11250
|
protected readonly isDone: import("@angular/core").Signal<boolean>;
|
|
11218
11251
|
protected readonly completedCount: import("@angular/core").Signal<number>;
|
|
11219
11252
|
protected readonly stepperSteps: import("@angular/core").Signal<StepperStep[]>;
|
|
11220
11253
|
protected readonly summarySections: import("@angular/core").Signal<PanelInfoSection[]>;
|
|
11221
11254
|
constructor();
|
|
11222
|
-
protected templateFor(key: string): import("@angular/core").TemplateRef<
|
|
11255
|
+
protected templateFor(key: string): import("@angular/core").TemplateRef<{
|
|
11256
|
+
$implicit: SetupWizardApi;
|
|
11257
|
+
}> | null;
|
|
11223
11258
|
protected goTo(key: string): void;
|
|
11224
11259
|
private enter;
|
|
11225
11260
|
private advanceFrom;
|
|
@@ -11227,7 +11262,7 @@ export declare class SetupWizardComponent {
|
|
|
11227
11262
|
protected skip(): void;
|
|
11228
11263
|
private markCompleted;
|
|
11229
11264
|
/** "Save & Continue" of a custom or integrations step: runs the step's hook, then moves on. */
|
|
11230
|
-
|
|
11265
|
+
saveAndContinue(): Promise<void>;
|
|
11231
11266
|
private run;
|
|
11232
11267
|
/** The message to show for a failure: the server's own `{ message }` (or a thrown error's message); never the HTTP client's technical text. */
|
|
11233
11268
|
private messageOf;
|
|
@@ -11242,6 +11277,8 @@ export declare class SetupWizardComponent {
|
|
|
11242
11277
|
protected isConnected(i: SetupIntegration): boolean;
|
|
11243
11278
|
protected detailFor(i: SetupIntegration): string;
|
|
11244
11279
|
protected connect(i: SetupIntegration): void;
|
|
11280
|
+
/** SVG path of a library icon (the buttons' leading / trailing glyph). */
|
|
11281
|
+
protected iconD(name: string): string;
|
|
11245
11282
|
protected areaCodeLabelFor(i: SetupIntegration): string;
|
|
11246
11283
|
/** Sends the browser to the provider's authorization page. */
|
|
11247
11284
|
protected redirect(url: string): void;
|
|
@@ -11361,14 +11398,12 @@ type EditorTab = 'edit' | 'preview' | 'mobile';
|
|
|
11361
11398
|
type RightTab = 'blocks' | 'variables' | 'video';
|
|
11362
11399
|
/**
|
|
11363
11400
|
* `ui-email-template-editor` - the full-page, block-based email template editor (details, assignments, block canvas with drag and drop,
|
|
11364
|
-
* rich-text toolbar, preview / mobile preview, content blocks, merge variables, video library, test send
|
|
11401
|
+
* rich-text toolbar, preview / mobile preview, content blocks, merge variables, video library, test send).
|
|
11365
11402
|
*
|
|
11366
11403
|
* The component owns the editing behaviour and holds no HTTP: the host loads the template (`[template]`), supplies what differs per app
|
|
11367
11404
|
* (`categories`, `assignmentOptions`, `variableGroups`, `blockGroups`, `videos`, `videoDefaults`, `maxBodyLength`, permissions) and reacts to
|
|
11368
|
-
* `(save)`, `(testSend)`, `(
|
|
11369
|
-
* `markSaved(id)` (a create succeeded)
|
|
11370
|
-
*
|
|
11371
|
-
* Project an element with the `uiSubjectAction` attribute to put a host control (e.g. an AI copy button) at the end of the Subject label line.
|
|
11405
|
+
* `(save)`, `(testSend)`, `(videosRequested)` and `(useAsMine)`. After a request the host calls back:
|
|
11406
|
+
* `markSaved(id)` (a create succeeded) and `closeTestSend()`.
|
|
11372
11407
|
*
|
|
11373
11408
|
* Message limit: `maxBodyLength` is measured on the serialised HTML. An untouched stored body that is already longer than the limit is
|
|
11374
11409
|
* accepted unchanged (legacy rows), exactly as the server does.
|
|
@@ -11388,12 +11423,8 @@ export declare class EmailTemplateEditorComponent {
|
|
|
11388
11423
|
readonly textEnabled: import("@angular/core").InputSignal<boolean>;
|
|
11389
11424
|
readonly variableGroups: import("@angular/core").InputSignal<EmailTemplateVariableGroup[]>;
|
|
11390
11425
|
readonly blockGroups: import("@angular/core").InputSignal<EmailTemplateBlockGroup[]>;
|
|
11391
|
-
readonly aiExamples: import("@angular/core").InputSignal<string[]>;
|
|
11392
11426
|
readonly namePlaceholder: import("@angular/core").InputSignal<string>;
|
|
11393
11427
|
readonly subjectPlaceholder: import("@angular/core").InputSignal<string>;
|
|
11394
|
-
readonly backLabel: import("@angular/core").InputSignal<string>;
|
|
11395
|
-
readonly createLabel: import("@angular/core").InputSignal<string>;
|
|
11396
|
-
readonly editLabel: import("@angular/core").InputSignal<string>;
|
|
11397
11428
|
readonly systemNote: import("@angular/core").InputSignal<string>;
|
|
11398
11429
|
readonly readOnlyNote: import("@angular/core").InputSignal<string>;
|
|
11399
11430
|
/** Prefix of the ids of the field errors the editor renders (`<prefix>-body-error`). */
|
|
@@ -11405,21 +11436,24 @@ export declare class EmailTemplateEditorComponent {
|
|
|
11405
11436
|
readonly fullAccess: import("@angular/core").InputSignal<boolean>;
|
|
11406
11437
|
/** A built-in template: shown read-only; a member with full access can copy it ((useAsMine)). */
|
|
11407
11438
|
readonly systemTemplate: import("@angular/core").InputSignal<boolean>;
|
|
11408
|
-
readonly aiEnabled: import("@angular/core").InputSignal<boolean>;
|
|
11409
11439
|
readonly testSendEnabled: import("@angular/core").InputSignal<boolean>;
|
|
11410
|
-
readonly videosEnabled: import("@angular/core").InputSignal<boolean>;
|
|
11411
11440
|
readonly saving: import("@angular/core").InputSignal<boolean>;
|
|
11412
11441
|
readonly testSending: import("@angular/core").InputSignal<boolean>;
|
|
11413
|
-
|
|
11414
|
-
|
|
11442
|
+
/**
|
|
11443
|
+
* The host's videos. `null` (the default) = this app has no videos: the Video tab is not shown at all. Any list - even an empty one while the
|
|
11444
|
+
* host loads it on demand (see `(videosRequested)`) - turns the Video tab on.
|
|
11445
|
+
*/
|
|
11446
|
+
readonly videos: import("@angular/core").InputSignal<EmailTemplateVideo[] | null>;
|
|
11447
|
+
/** Hides the Video tab completely even when `videos` is passed. */
|
|
11448
|
+
readonly hideVideos: import("@angular/core").InputSignal<boolean>;
|
|
11449
|
+
readonly videosEnabled: import("@angular/core").Signal<boolean>;
|
|
11450
|
+
protected readonly videoList: import("@angular/core").Signal<EmailTemplateVideo[]>;
|
|
11415
11451
|
readonly videosLoading: import("@angular/core").InputSignal<boolean>;
|
|
11416
11452
|
readonly videoDefaults: import("@angular/core").InputSignal<EmailTemplateVideoDefaults>;
|
|
11417
11453
|
readonly videoLink: import("@angular/core").InputSignal<EmailTemplateVideoLinkFn>;
|
|
11418
11454
|
readonly noVideosHint: import("@angular/core").InputSignal<string>;
|
|
11419
|
-
readonly back: import("@angular/core").OutputEmitterRef<void>;
|
|
11420
11455
|
readonly save: import("@angular/core").OutputEmitterRef<EmailTemplateSavePayload>;
|
|
11421
11456
|
readonly testSend: import("@angular/core").OutputEmitterRef<string>;
|
|
11422
|
-
readonly aiGenerate: import("@angular/core").OutputEmitterRef<string>;
|
|
11423
11457
|
/** The Video tab was opened (the host loads the library once). */
|
|
11424
11458
|
readonly videosRequested: import("@angular/core").OutputEmitterRef<void>;
|
|
11425
11459
|
readonly useAsMine: import("@angular/core").OutputEmitterRef<void>;
|
|
@@ -11472,8 +11506,6 @@ export declare class EmailTemplateEditorComponent {
|
|
|
11472
11506
|
readonly imageAlt: import("@angular/core").WritableSignal<string>;
|
|
11473
11507
|
readonly showTestSendDialog: import("@angular/core").WritableSignal<boolean>;
|
|
11474
11508
|
readonly testSendEmail: import("@angular/core").WritableSignal<string>;
|
|
11475
|
-
readonly showAiPanel: import("@angular/core").WritableSignal<boolean>;
|
|
11476
|
-
readonly aiPrompt: import("@angular/core").WritableSignal<string>;
|
|
11477
11509
|
readonly showAssignmentConfig: import("@angular/core").WritableSignal<boolean>;
|
|
11478
11510
|
readonly configTarget: import("@angular/core").WritableSignal<AssignmentView | null>;
|
|
11479
11511
|
readonly configEmail: import("@angular/core").WritableSignal<boolean>;
|
|
@@ -11507,7 +11539,15 @@ export declare class EmailTemplateEditorComponent {
|
|
|
11507
11539
|
readonly bodyError: import("@angular/core").Signal<string>;
|
|
11508
11540
|
/** "Active From / To" only apply when the template is not "all year"; when both are given To may not be before From. */
|
|
11509
11541
|
readonly datesError: import("@angular/core").Signal<"" | "Active To must be on or after Active From.">;
|
|
11542
|
+
/** Errors are held back until the user has had a chance to act: a field is blurred, the message is edited, or Save was clicked while something is invalid. */
|
|
11543
|
+
readonly submitAttempted: import("@angular/core").WritableSignal<boolean>;
|
|
11544
|
+
readonly nameTouched: import("@angular/core").WritableSignal<boolean>;
|
|
11545
|
+
readonly subjectTouched: import("@angular/core").WritableSignal<boolean>;
|
|
11546
|
+
readonly nameErrorShown: import("@angular/core").Signal<string>;
|
|
11547
|
+
readonly subjectErrorShown: import("@angular/core").Signal<string>;
|
|
11548
|
+
readonly bodyErrorShown: import("@angular/core").Signal<string>;
|
|
11510
11549
|
readonly canSave: import("@angular/core").Signal<boolean>;
|
|
11550
|
+
/** Save is offered to members who can write; clicking it while a rule fails shows the messages instead of sending anything. */
|
|
11511
11551
|
readonly saveDisabled: import("@angular/core").Signal<boolean>;
|
|
11512
11552
|
private normalizedLink;
|
|
11513
11553
|
/** Why Insert is disabled: nothing for an empty field, a message for an address that is not a link. */
|
|
@@ -11519,20 +11559,16 @@ export declare class EmailTemplateEditorComponent {
|
|
|
11519
11559
|
readonly canSendTest: import("@angular/core").Signal<boolean>;
|
|
11520
11560
|
/** The test email is the SAVED template: true when the editor holds changes that were not saved yet. */
|
|
11521
11561
|
readonly hasUnsavedChanges: import("@angular/core").Signal<boolean>;
|
|
11522
|
-
readonly canGenerate: import("@angular/core").Signal<boolean>;
|
|
11523
11562
|
constructor();
|
|
11524
11563
|
/** A create succeeded: the template now has an id (Test Send becomes available) and what is on screen is the saved version. */
|
|
11525
11564
|
markSaved(id?: string | null): void;
|
|
11526
11565
|
/** The test email was sent: close the dialog. */
|
|
11527
11566
|
closeTestSend(): void;
|
|
11528
|
-
/** The AI draft arrived: add it as a new block and close the AI panel. */
|
|
11529
|
-
addGeneratedHtml(html: string): void;
|
|
11530
11567
|
private applyTemplate;
|
|
11531
11568
|
onSave(): void;
|
|
11532
11569
|
private snapshot;
|
|
11533
11570
|
private serialize;
|
|
11534
11571
|
private htmlToBlocks;
|
|
11535
|
-
private stripBlockWrappers;
|
|
11536
11572
|
private genId;
|
|
11537
11573
|
private editorFor;
|
|
11538
11574
|
/** Copies each block's HTML from its DOM element (before saving / preview). */
|
|
@@ -11598,8 +11634,6 @@ export declare class EmailTemplateEditorComponent {
|
|
|
11598
11634
|
insertImageFromUrl(): void;
|
|
11599
11635
|
openTestSendDialog(): void;
|
|
11600
11636
|
onTestSend(): void;
|
|
11601
|
-
openAiPanel(): void;
|
|
11602
|
-
onAiGenerate(): void;
|
|
11603
11637
|
openVideoTab(): void;
|
|
11604
11638
|
insertVideo(video: EmailTemplateVideo): void;
|
|
11605
11639
|
formatDuration(seconds: number | null | undefined): string;
|
|
@@ -11658,11 +11692,6 @@ export declare class EmailTemplateEditorComponent {
|
|
|
11658
11692
|
"required": false;
|
|
11659
11693
|
"isSignal": true;
|
|
11660
11694
|
};
|
|
11661
|
-
"aiExamples": {
|
|
11662
|
-
"alias": "aiExamples";
|
|
11663
|
-
"required": false;
|
|
11664
|
-
"isSignal": true;
|
|
11665
|
-
};
|
|
11666
11695
|
"namePlaceholder": {
|
|
11667
11696
|
"alias": "namePlaceholder";
|
|
11668
11697
|
"required": false;
|
|
@@ -11673,21 +11702,6 @@ export declare class EmailTemplateEditorComponent {
|
|
|
11673
11702
|
"required": false;
|
|
11674
11703
|
"isSignal": true;
|
|
11675
11704
|
};
|
|
11676
|
-
"backLabel": {
|
|
11677
|
-
"alias": "backLabel";
|
|
11678
|
-
"required": false;
|
|
11679
|
-
"isSignal": true;
|
|
11680
|
-
};
|
|
11681
|
-
"createLabel": {
|
|
11682
|
-
"alias": "createLabel";
|
|
11683
|
-
"required": false;
|
|
11684
|
-
"isSignal": true;
|
|
11685
|
-
};
|
|
11686
|
-
"editLabel": {
|
|
11687
|
-
"alias": "editLabel";
|
|
11688
|
-
"required": false;
|
|
11689
|
-
"isSignal": true;
|
|
11690
|
-
};
|
|
11691
11705
|
"systemNote": {
|
|
11692
11706
|
"alias": "systemNote";
|
|
11693
11707
|
"required": false;
|
|
@@ -11723,21 +11737,11 @@ export declare class EmailTemplateEditorComponent {
|
|
|
11723
11737
|
"required": false;
|
|
11724
11738
|
"isSignal": true;
|
|
11725
11739
|
};
|
|
11726
|
-
"aiEnabled": {
|
|
11727
|
-
"alias": "aiEnabled";
|
|
11728
|
-
"required": false;
|
|
11729
|
-
"isSignal": true;
|
|
11730
|
-
};
|
|
11731
11740
|
"testSendEnabled": {
|
|
11732
11741
|
"alias": "testSendEnabled";
|
|
11733
11742
|
"required": false;
|
|
11734
11743
|
"isSignal": true;
|
|
11735
11744
|
};
|
|
11736
|
-
"videosEnabled": {
|
|
11737
|
-
"alias": "videosEnabled";
|
|
11738
|
-
"required": false;
|
|
11739
|
-
"isSignal": true;
|
|
11740
|
-
};
|
|
11741
11745
|
"saving": {
|
|
11742
11746
|
"alias": "saving";
|
|
11743
11747
|
"required": false;
|
|
@@ -11748,13 +11752,13 @@ export declare class EmailTemplateEditorComponent {
|
|
|
11748
11752
|
"required": false;
|
|
11749
11753
|
"isSignal": true;
|
|
11750
11754
|
};
|
|
11751
|
-
"
|
|
11752
|
-
"alias": "
|
|
11755
|
+
"videos": {
|
|
11756
|
+
"alias": "videos";
|
|
11753
11757
|
"required": false;
|
|
11754
11758
|
"isSignal": true;
|
|
11755
11759
|
};
|
|
11756
|
-
"
|
|
11757
|
-
"alias": "
|
|
11760
|
+
"hideVideos": {
|
|
11761
|
+
"alias": "hideVideos";
|
|
11758
11762
|
"required": false;
|
|
11759
11763
|
"isSignal": true;
|
|
11760
11764
|
};
|
|
@@ -11779,13 +11783,11 @@ export declare class EmailTemplateEditorComponent {
|
|
|
11779
11783
|
"isSignal": true;
|
|
11780
11784
|
};
|
|
11781
11785
|
}, {
|
|
11782
|
-
"back": "back";
|
|
11783
11786
|
"save": "save";
|
|
11784
11787
|
"testSend": "testSend";
|
|
11785
|
-
"aiGenerate": "aiGenerate";
|
|
11786
11788
|
"videosRequested": "videosRequested";
|
|
11787
11789
|
"useAsMine": "useAsMine";
|
|
11788
|
-
}, never,
|
|
11790
|
+
}, never, never, true, never>;
|
|
11789
11791
|
}
|
|
11790
11792
|
/** The text a new template's first block starts with: it is a prompt, not content, so a template still holding only this has no message. */
|
|
11791
11793
|
export declare const EMAIL_TEMPLATE_START_TEXT = "Start writing your email...";
|