@acorex-platform/module-content-management-client 0.0.56 → 0.0.58

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.
@@ -12,8 +12,8 @@ import { AXTextAreaModule } from '@acorex/components/text-area';
12
12
  import * as i5 from '@acorex/components/text-box';
13
13
  import { AXTextBoxModule } from '@acorex/components/text-box';
14
14
  import { AXToastService } from '@acorex/components/toast';
15
- import * as i6 from '@acorex/components/wysiwyg';
16
- import { AXWysiwygModule } from '@acorex/components/wysiwyg';
15
+ import * as i6 from '@acorex/components/text-editor';
16
+ import { AXTextEditorModule } from '@acorex/components/text-editor';
17
17
  import * as i2$1 from '@acorex/core/translation';
18
18
  import { AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
19
19
  import { AXValidationModule } from '@acorex/core/validation';
@@ -108,17 +108,17 @@ class AXMTemplateContentEditorWidgetEditComponent extends AXPValueWidgetComponen
108
108
  /** Dedupes in-flight preview loads when effect re-runs. */
109
109
  this.previewRequestSeq = 0;
110
110
  /**
111
- * Quill `text-change` is debounced (~300ms) and `commitValue(html, true)` marks
112
- * hydration as a user edit. Ignore writes until that timer elapses after a programmatic sync.
111
+ * TipTap `commitValue(html, true)` marks hydration as a user edit.
112
+ * Ignore writes until that timer elapses after a programmatic sync.
113
113
  */
114
- this.suppressWysiwygWrites = false;
115
- this.suppressWysiwygWritesTimer = null;
114
+ this.suppressEditorWrites = false;
115
+ this.suppressEditorWritesTimer = null;
116
116
  this.lastSyncedChannel = null;
117
117
  this.lastSyncedViewMode = null;
118
118
  /** Drops the ax-tabs init event so it cannot overwrite the content-channel tab. */
119
119
  this.ignoreNextChannelTabChange = false;
120
- this.wysiwygRef = viewChild('wysiwygRef', /* @ts-ignore */
121
- ...(ngDevMode ? [{ debugName: "wysiwygRef" }] : /* istanbul ignore next */ []));
120
+ this.editorRef = viewChild('editorRef', /* @ts-ignore */
121
+ ...(ngDevMode ? [{ debugName: "editorRef" }] : /* istanbul ignore next */ []));
122
122
  this.bodyTextareaRef = viewChild('bodyTextarea', { ...(ngDevMode ? { debugName: "bodyTextareaRef" } : /* istanbul ignore next */ {}), read: (ElementRef) });
123
123
  this.availableChannels = signal([], /* @ts-ignore */
124
124
  ...(ngDevMode ? [{ debugName: "availableChannels" }] : /* istanbul ignore next */ []));
@@ -169,7 +169,7 @@ class AXMTemplateContentEditorWidgetEditComponent extends AXPValueWidgetComponen
169
169
  }
170
170
  });
171
171
  /**
172
- * Quill keeps its own DOM; one-way ngModel does not refresh it when the entity
172
+ * TipTap keeps its own document; one-way ngModel does not refresh it when the entity
173
173
  * loads, the user discards, or the active channel tab changes.
174
174
  */
175
175
  effect(() => {
@@ -177,29 +177,29 @@ class AXMTemplateContentEditorWidgetEditComponent extends AXPValueWidgetComponen
177
177
  const channel = this.activeChannel();
178
178
  const changeState = this.contextService.changeEvent().state;
179
179
  const body = channel ? this.getChannelBody(channel.name) : '';
180
- const editor = this.wysiwygRef();
180
+ const editor = this.editorRef();
181
181
  if (viewMode !== 'edit' || !channel || channel.type === 'plain' || !editor) {
182
182
  this.lastSyncedViewMode = viewMode;
183
183
  return;
184
184
  }
185
185
  const channelChanged = channel.name !== this.lastSyncedChannel;
186
186
  const viewModeChanged = viewMode !== this.lastSyncedViewMode;
187
- const editorChanged = editor !== this.lastSyncedWysiwyg;
188
- const contextReload = this.shouldSyncWysiwygFromContext(changeState);
187
+ const editorChanged = editor !== this.lastSyncedEditor;
188
+ const contextReload = this.shouldSyncEditorFromContext(changeState);
189
189
  if (!channelChanged && !viewModeChanged && !editorChanged && !contextReload) {
190
190
  return;
191
191
  }
192
192
  untracked(() => {
193
193
  this.lastSyncedChannel = channel.name;
194
194
  this.lastSyncedViewMode = viewMode;
195
- this.lastSyncedWysiwyg = editor;
196
- void this.applyWysiwygContentWhenReady(editor, body);
195
+ this.lastSyncedEditor = editor;
196
+ void this.applyEditorContentWhenReady(editor, body);
197
197
  });
198
198
  });
199
199
  this.settingsService.onChanged.subscribe(() => {
200
200
  void this.refreshChannelConfiguration();
201
201
  });
202
- this.destroyRef.onDestroy(() => this.clearSuppressWysiwygWritesTimer());
202
+ this.destroyRef.onDestroy(() => this.clearSuppressEditorWritesTimer());
203
203
  }
204
204
  isChannelConfigured(name) {
205
205
  return this.channelConfigured()[name] ?? true;
@@ -309,7 +309,7 @@ class AXMTemplateContentEditorWidgetEditComponent extends AXPValueWidgetComponen
309
309
  const idx = chs.findIndex((c) => names.includes(c.name));
310
310
  if (idx >= 0) {
311
311
  this.ignoreNextChannelTabChange = true;
312
- this.beginSuppressWysiwygWrites();
312
+ this.beginSuppressEditorWrites();
313
313
  this.activeTabIndex.set(idx);
314
314
  setTimeout(() => {
315
315
  this.ignoreNextChannelTabChange = false;
@@ -321,7 +321,7 @@ class AXMTemplateContentEditorWidgetEditComponent extends AXPValueWidgetComponen
321
321
  if (this.ignoreNextChannelTabChange || index === this.activeTabIndex()) {
322
322
  return;
323
323
  }
324
- this.beginSuppressWysiwygWrites();
324
+ this.beginSuppressEditorWrites();
325
325
  this.activeTabIndex.set(index);
326
326
  }
327
327
  /** Capture cursor/selection before dropdown opens (runs in mousedown capture phase) */
@@ -397,8 +397,8 @@ class AXMTemplateContentEditorWidgetEditComponent extends AXPValueWidgetComponen
397
397
  ? startNode.parentElement
398
398
  : startNode;
399
399
  const editable = elem?.closest?.('[contenteditable="true"]');
400
- const wysiwyg = this.wysiwygRef();
401
- const target = editable ?? wysiwyg?.getHostElement()?.querySelector?.('[contenteditable="true"]');
400
+ const editorHost = this.editorRef();
401
+ const target = editable ?? editorHost?.getHostElement()?.querySelector?.('[contenteditable="true"]');
402
402
  if (target) {
403
403
  target.focus();
404
404
  const sel = document.getSelection();
@@ -441,7 +441,7 @@ class AXMTemplateContentEditorWidgetEditComponent extends AXPValueWidgetComponen
441
441
  this.setChannelBody(targetName, this.getChannelBody(sourceName));
442
442
  const active = this.activeChannel();
443
443
  if (active?.name === targetName && active.type === 'rich') {
444
- void this.applyWysiwygContentWhenReady(this.wysiwygRef(), this.getChannelBody(targetName));
444
+ void this.applyEditorContentWhenReady(this.editorRef(), this.getChannelBody(targetName));
445
445
  }
446
446
  }
447
447
  getChannelSubject(name) {
@@ -481,8 +481,8 @@ class AXMTemplateContentEditorWidgetEditComponent extends AXPValueWidgetComponen
481
481
  }
482
482
  this.setChannelBody(name, e.value ?? '');
483
483
  }
484
- handleWysiwygChange(name, e) {
485
- if (this.suppressWysiwygWrites || !e.isUserInteraction) {
484
+ handleEditorChange(name, e) {
485
+ if (this.suppressEditorWrites || !e.isUserInteraction) {
486
486
  return;
487
487
  }
488
488
  const val = typeof e === 'object' && e !== null && 'value' in e
@@ -517,39 +517,34 @@ class AXMTemplateContentEditorWidgetEditComponent extends AXPValueWidgetComponen
517
517
  }
518
518
  this.setValue(nextValue);
519
519
  }
520
- shouldSyncWysiwygFromContext(state) {
520
+ shouldSyncEditorFromContext(state) {
521
521
  return state === 'restored' || state === 'initiated';
522
522
  }
523
- beginSuppressWysiwygWrites() {
524
- this.suppressWysiwygWrites = true;
525
- this.clearSuppressWysiwygWritesTimer();
526
- this.suppressWysiwygWritesTimer = setTimeout(() => {
527
- this.suppressWysiwygWrites = false;
528
- this.suppressWysiwygWritesTimer = null;
523
+ beginSuppressEditorWrites() {
524
+ this.suppressEditorWrites = true;
525
+ this.clearSuppressEditorWritesTimer();
526
+ this.suppressEditorWritesTimer = setTimeout(() => {
527
+ this.suppressEditorWrites = false;
528
+ this.suppressEditorWritesTimer = null;
529
529
  }, 500);
530
530
  }
531
- clearSuppressWysiwygWritesTimer() {
532
- if (this.suppressWysiwygWritesTimer) {
533
- clearTimeout(this.suppressWysiwygWritesTimer);
534
- this.suppressWysiwygWritesTimer = null;
531
+ clearSuppressEditorWritesTimer() {
532
+ if (this.suppressEditorWritesTimer) {
533
+ clearTimeout(this.suppressEditorWritesTimer);
534
+ this.suppressEditorWritesTimer = null;
535
535
  }
536
536
  }
537
- async applyWysiwygContentWhenReady(wysiwyg, text) {
537
+ async applyEditorContentWhenReady(host, text) {
538
538
  const content = text ?? '';
539
539
  for (let attempt = 0; attempt < 30; attempt++) {
540
- const editor = this.wysiwygRef() ?? wysiwyg;
541
- if (!editor) {
540
+ const editor = this.editorRef() ?? host;
541
+ if (!editor?.getEditor()) {
542
542
  await new Promise((resolve) => setTimeout(resolve, 50));
543
543
  continue;
544
544
  }
545
- try {
546
- this.beginSuppressWysiwygWrites();
547
- editor.setWysiwygContent(content);
548
- return;
549
- }
550
- catch {
551
- await new Promise((resolve) => setTimeout(resolve, 50));
552
- }
545
+ this.beginSuppressEditorWrites();
546
+ editor.getEditorService().setContent(content, false);
547
+ return;
553
548
  }
554
549
  }
555
550
  /**
@@ -796,7 +791,7 @@ class AXMTemplateContentEditorWidgetEditComponent extends AXPValueWidgetComponen
796
791
  .replace(/\n/g, '<br/>');
797
792
  }
798
793
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMTemplateContentEditorWidgetEditComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
799
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMTemplateContentEditorWidgetEditComponent, isStandalone: true, selector: "axm-template-content-editor-widget-edit", viewQueries: [{ propertyName: "wysiwygRef", first: true, predicate: ["wysiwygRef"], descendants: true, isSignal: true }, { propertyName: "bodyTextareaRef", first: true, predicate: ["bodyTextarea"], descendants: true, read: ElementRef, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<!-- Template Content Editor: Channel tabs and content per channel -->\n<div class=\"flex flex-col gap-4 w-full\">\n <!-- Channel tabs navigation -->\n <div class=\"flex items-center gap-2 flex-wrap\">\n <ax-tabs\n [look]=\"'with-line'\"\n (onActiveTabChanged)=\"onChannelTabChanged($event.index)\"\n class=\"flex-1 min-w-0\"\n >\n @for (ch of availableChannels(); track ch.name; let i = $index) {\n <ax-tab-item\n [text]=\"(ch.title | translate | async) ?? ch.name\"\n [key]=\"i.toString()\"\n [active]=\"activeTabIndex() === i\"\n ></ax-tab-item>\n }\n </ax-tabs>\n </div>\n\n @if (activeChannel(); as ch) {\n <!-- Channel content area: Edit mode or Preview mode -->\n <div class=\"mb-4 p-4\">\n @if (!isChannelConfigured(ch.name) && ch.notConfiguredMessageKey) {\n <div\n class=\"mb-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 p-3 rounded border border-amber-300 bg-amber-50 dark:border-amber-700 dark:bg-amber-950/30\"\n >\n <p class=\"text-sm text-amber-900 dark:text-amber-100\">\n {{ ch.notConfiguredMessageKey | translate | async }}\n </p>\n @if (ch.configureSettings) {\n <ax-button\n [text]=\"\n '@content-management:templates.actions.configure-channel'\n | translate\n | async\n \"\n look=\"outline\"\n color=\"primary\"\n size=\"sm\"\n (onClick)=\"openChannelConfigure(ch)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-gear\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n </div>\n }\n\n @if (viewMode() === 'edit') {\n <!-- Edit mode: Subject field (for channels that support it, e.g. Email) -->\n @if (ch.hasSubject) {\n <div class=\"mb-3\">\n <label class=\"block text-sm mb-1\">\n {{\n '@content-management:templates.entities.text-template.fields.subject.title'\n | translate\n | async\n }}\n </label>\n <ax-text-box\n [ngModel]=\"getChannelSubject(ch.name)\"\n (onValueChanged)=\"handleSubjectChange(ch.name, $event)\"\n [placeholder]=\"\n ('@content-management:templates.entities.text-template.fields.subject.placeholder'\n | translate\n | async)!\n \"\n ></ax-text-box>\n </div>\n }\n\n <!-- Edit mode: Body field (plain text or rich WYSIWYG) -->\n <div>\n <label class=\"block text-sm mb-1\">\n {{\n '@content-management:templates.entities.text-template.fields.body.title'\n | translate\n | async\n }}\n </label>\n <!--->\n <!-- ----- Plain-text body for SMS-style channels ----- -->\n @if (ch.type === 'plain') {\n <ax-text-area\n #bodyTextarea\n [ngModel]=\"getChannelBody(ch.name)\"\n (onValueChanged)=\"handlePlainBodyChange(ch.name, $event)\"\n [rows]=\"8\"\n [placeholder]=\"\n ('@content-management:templates.entities.text-template.fields.body-placeholder.plain'\n | translate\n | async)!\n \"\n ></ax-text-area>\n }\n <!-- ----- Recreate Quill per channel so tab switches do not keep the previous HTML ----- -->\n @else {\n @for (channelName of [ch.name]; track channelName) {\n <ax-wysiwyg-container\n #wysiwygRef\n [placeHolder]=\"\n ('@content-management:templates.entities.text-template.fields.body-placeholder.rich'\n | translate\n | async)!\n \"\n [ngModel]=\"getChannelBody(channelName)\"\n (onValueChanged)=\"handleWysiwygChange(channelName, $event)\"\n [look]=\"'solid'\"\n >\n <ax-wysiwyg-view [style.min-height.px]=\"200\"></ax-wysiwyg-view>\n <ax-wysiwyg-toolbar>\n <ax-prefix>\n <ax-wysiwyg-history></ax-wysiwyg-history>\n <ax-wysiwyg-font-style></ax-wysiwyg-font-style>\n <ax-wysiwyg-list></ax-wysiwyg-list>\n </ax-prefix>\n </ax-wysiwyg-toolbar>\n </ax-wysiwyg-container>\n }\n }\n </div>\n } @else {\n <!-- Preview mode: Rendered content with variable placeholders replaced by sample values -->\n <div class=\"space-y-2\">\n @if (ch.hasSubject && previewSubject(ch.name)) {\n <div>\n <span class=\"text-xs text-gray-500\"\n >{{\n '@content-management:templates.entities.text-template.fields.subject.title'\n | translate\n | async\n }}:\n </span>\n <span class=\"text-sm\">{{ previewSubject(ch.name) }}</span>\n </div>\n }\n <!-- ----- Rich email keeps inline styles; plain channels use pre-wrap ----- -->\n <div\n class=\"text-sm p-3 bg-gray-100 dark:bg-gray-900 rounded border overflow-auto\"\n [class.whitespace-pre-wrap]=\"ch.type !== 'rich'\"\n [innerHTML]=\"previewBodyHtml(ch.name)\"\n ></div>\n </div>\n }\n </div>\n\n <!-- Footer: Action buttons (left) + Edit/Preview toggle (right) in single row -->\n <div\n class=\"flex flex-nowrap items-center justify-between gap-3 pt-3 mt-1 border-t border-gray-200 dark:border-gray-700\"\n >\n <div class=\"flex flex-nowrap items-center gap-2 min-w-0\">\n @if (viewMode() === 'edit') {\n <!-- ----- Insert variable dropdown from platform tokens ----- -->\n <div data-insert-var-trigger>\n <ax-button\n [text]=\"\n '@content-management:templates.actions.insert-variable'\n | translate\n | async\n \"\n look=\"twotone\"\n color=\"default\"\n size=\"sm\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-code\"></ax-icon>\n </ax-prefix>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (v of availableVariables(); track v.name) {\n <ax-button-item\n look=\"blank\"\n color=\"default\"\n [text]=\"(v.title || v.name) + ' ({{' + v.name + '}})'\"\n (onClick)=\"insertVariable(ch.name, v.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"getVariableIcon(v)\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n <ax-suffix>\n <ax-icon icon=\"fa-light fa-chevron-down\"></ax-icon>\n </ax-suffix>\n </ax-button>\n </div>\n <!--->\n <!-- ----- Insert reserved [content] slot for master templates ----- -->\n @if (isMasterKind()) {\n <div data-insert-var-trigger>\n <ax-button\n [text]=\"\n '@content-management:templates.actions.insert-content-slot'\n | translate\n | async\n \"\n look=\"twotone\"\n color=\"default\"\n size=\"sm\"\n (onClick)=\"insertContentSlot(ch.name)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-layer-group\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n }\n <!--->\n <!-- ----- Copy subject/body from another channel ----- -->\n @if (otherChannelsWithContent(ch.name).length > 0) {\n <ax-button\n [text]=\"\n '@content-management:templates.actions.copy-from'\n | translate\n | async\n \"\n look=\"twotone\"\n color=\"default\"\n size=\"sm\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-copy\"></ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-icon icon=\"fa-light fa-chevron-down\"></ax-icon>\n </ax-suffix>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (\n src of otherChannelsWithContent(ch.name);\n track src.name\n ) {\n <ax-button-item\n look=\"blank\"\n color=\"default\"\n [text]=\"(src.title | translate | async) ?? src.name\"\n (onClick)=\"copyFromChannel(ch.name, src.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"getChannelIcon(src)\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n }\n </div>\n <div>\n <ax-tabs [look]=\"'default'\">\n <ax-tab-item\n [text]=\"\n ('@content-management:templates.actions.edit'\n | translate\n | async) ?? 'Edit'\n \"\n [active]=\"viewMode() === 'edit'\"\n (onClick)=\"viewMode.set('edit')\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-pen\" class=\"text-current\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n <ax-tab-item\n [text]=\"\n ('@content-management:templates.actions.preview'\n | translate\n | async) ?? 'Preview'\n \"\n [active]=\"viewMode() === 'preview'\"\n (onClick)=\"viewMode.set('preview')\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-eye\" class=\"text-current\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n </ax-tabs>\n </div>\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "ngmodule", type: AXTabsModule }, { kind: "component", type: i3.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "reorderable", "reorderDelay", "renderMode", "stacked", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged", "onTabsReordered"] }, { kind: "component", type: i3.AXTabItemComponent, selector: "ax-tab-item", inputs: ["disabled", "text", "key", "headerTemplate", "active"], outputs: ["disabledChange", "onClick", "onBlur", "onFocus", "activeChange"] }, { kind: "ngmodule", type: AXTextAreaModule }, { kind: "component", type: i4.AXTextAreaComponent, selector: "ax-text-area", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "placeholder", "maxLength", "look", "rows", "allowResize", "showCounter", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "component", type: i5.AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "maskPattern", "customTokens", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress", "onMaskChanged"] }, { kind: "ngmodule", type: AXWysiwygModule }, { kind: "component", type: i6.AXWysiwygContainerComponent, selector: "ax-wysiwyg-container", inputs: ["look", "readonly", "disabled", "value", "placeHolder", "initialLine", "mode"], outputs: ["onValueChanged"] }, { kind: "component", type: i6.AXWysiwygViewComponent, selector: "ax-wysiwyg-view" }, { kind: "component", type: i6.AXWysiwygFontStyleComponent, selector: "ax-wysiwyg-font-style", inputs: ["headingLevels", "buttons", "menuItems"] }, { kind: "component", type: i6.AXWysiwygHistoryComponent, selector: "ax-wysiwyg-history", inputs: ["buttons"] }, { kind: "component", type: i6.AXWysiwygListComponent, selector: "ax-wysiwyg-list", inputs: ["buttons"] }, { kind: "component", type: i6.AXWysiwygToolbarComponent, selector: "ax-wysiwyg-toolbar" }, { kind: "ngmodule", type: AXValidationModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i7.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i7.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i7.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i8.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i2$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
794
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMTemplateContentEditorWidgetEditComponent, isStandalone: true, selector: "axm-template-content-editor-widget-edit", viewQueries: [{ propertyName: "editorRef", first: true, predicate: ["editorRef"], descendants: true, isSignal: true }, { propertyName: "bodyTextareaRef", first: true, predicate: ["bodyTextarea"], descendants: true, read: ElementRef, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<!-- Template Content Editor: Channel tabs and content per channel -->\n<div class=\"flex flex-col gap-4 w-full\">\n <!-- Channel tabs navigation -->\n <div class=\"flex items-center gap-2 flex-wrap\">\n <ax-tabs\n [look]=\"'with-line'\"\n (onActiveTabChanged)=\"onChannelTabChanged($event.index)\"\n class=\"flex-1 min-w-0\"\n >\n @for (ch of availableChannels(); track ch.name; let i = $index) {\n <ax-tab-item\n [text]=\"(ch.title | translate | async) ?? ch.name\"\n [key]=\"i.toString()\"\n [active]=\"activeTabIndex() === i\"\n ></ax-tab-item>\n }\n </ax-tabs>\n </div>\n\n @if (activeChannel(); as ch) {\n <!-- Channel content area: Edit mode or Preview mode -->\n <div class=\"mb-4 p-4\">\n @if (!isChannelConfigured(ch.name) && ch.notConfiguredMessageKey) {\n <div\n class=\"mb-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 p-3 rounded border border-amber-300 bg-amber-50 dark:border-amber-700 dark:bg-amber-950/30\"\n >\n <p class=\"text-sm text-amber-900 dark:text-amber-100\">\n {{ ch.notConfiguredMessageKey | translate | async }}\n </p>\n @if (ch.configureSettings) {\n <ax-button\n [text]=\"\n '@content-management:templates.actions.configure-channel'\n | translate\n | async\n \"\n look=\"outline\"\n color=\"primary\"\n size=\"sm\"\n (onClick)=\"openChannelConfigure(ch)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-gear\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n </div>\n }\n\n @if (viewMode() === 'edit') {\n <!-- Edit mode: Subject field (for channels that support it, e.g. Email) -->\n @if (ch.hasSubject) {\n <div class=\"mb-3\">\n <label class=\"block text-sm mb-1\">\n {{\n '@content-management:templates.entities.text-template.fields.subject.title'\n | translate\n | async\n }}\n </label>\n <ax-text-box\n [ngModel]=\"getChannelSubject(ch.name)\"\n (onValueChanged)=\"handleSubjectChange(ch.name, $event)\"\n [placeholder]=\"\n ('@content-management:templates.entities.text-template.fields.subject.placeholder'\n | translate\n | async)!\n \"\n ></ax-text-box>\n </div>\n }\n\n <!-- Edit mode: Body field (plain text or rich text-editor) -->\n <div>\n <label class=\"block text-sm mb-1\">\n {{\n '@content-management:templates.entities.text-template.fields.body.title'\n | translate\n | async\n }}\n </label>\n <!--->\n <!-- ----- Plain-text body for SMS-style channels ----- -->\n @if (ch.type === 'plain') {\n <ax-text-area\n #bodyTextarea\n [ngModel]=\"getChannelBody(ch.name)\"\n (onValueChanged)=\"handlePlainBodyChange(ch.name, $event)\"\n [rows]=\"8\"\n [placeholder]=\"\n ('@content-management:templates.entities.text-template.fields.body-placeholder.plain'\n | translate\n | async)!\n \"\n ></ax-text-area>\n }\n <!-- ----- Recreate the rich editor per channel so tab switches do not keep the previous HTML ----- -->\n @else {\n @for (channelName of [ch.name]; track channelName) {\n <ax-text-editor\n #editorRef\n outputFormat=\"html\"\n [placeHolder]=\"\n ('@content-management:templates.entities.text-template.fields.body-placeholder.rich'\n | translate\n | async)!\n \"\n [ngModel]=\"getChannelBody(channelName)\"\n (onValueChanged)=\"handleEditorChange(channelName, $event)\"\n [look]=\"'solid'\"\n [initialLine]=\"8\"\n >\n <ax-text-editor-content [style.min-height.px]=\"200\"></ax-text-editor-content>\n <ax-text-editor-toolbar>\n <ax-prefix>\n <ax-text-editor-history></ax-text-editor-history>\n <ax-text-editor-font-style></ax-text-editor-font-style>\n <ax-text-editor-list></ax-text-editor-list>\n </ax-prefix>\n </ax-text-editor-toolbar>\n </ax-text-editor>\n }\n }\n </div>\n } @else {\n <!-- Preview mode: Rendered content with variable placeholders replaced by sample values -->\n <div class=\"space-y-2\">\n @if (ch.hasSubject && previewSubject(ch.name)) {\n <div>\n <span class=\"text-xs text-gray-500\"\n >{{\n '@content-management:templates.entities.text-template.fields.subject.title'\n | translate\n | async\n }}:\n </span>\n <span class=\"text-sm\">{{ previewSubject(ch.name) }}</span>\n </div>\n }\n <!-- ----- Rich email keeps inline styles; plain channels use pre-wrap ----- -->\n <div\n class=\"text-sm p-3 bg-gray-100 dark:bg-gray-900 rounded border overflow-auto\"\n [class.whitespace-pre-wrap]=\"ch.type !== 'rich'\"\n [innerHTML]=\"previewBodyHtml(ch.name)\"\n ></div>\n </div>\n }\n </div>\n\n <!-- Footer: Action buttons (left) + Edit/Preview toggle (right) in single row -->\n <div\n class=\"flex flex-nowrap items-center justify-between gap-3 pt-3 mt-1 border-t border-gray-200 dark:border-gray-700\"\n >\n <div class=\"flex flex-nowrap items-center gap-2 min-w-0\">\n @if (viewMode() === 'edit') {\n <!-- ----- Insert variable dropdown from platform tokens ----- -->\n <div data-insert-var-trigger>\n <ax-button\n [text]=\"\n '@content-management:templates.actions.insert-variable'\n | translate\n | async\n \"\n look=\"twotone\"\n color=\"default\"\n size=\"sm\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-code\"></ax-icon>\n </ax-prefix>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (v of availableVariables(); track v.name) {\n <ax-button-item\n look=\"blank\"\n color=\"default\"\n [text]=\"(v.title || v.name) + ' ({{' + v.name + '}})'\"\n (onClick)=\"insertVariable(ch.name, v.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"getVariableIcon(v)\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n <ax-suffix>\n <ax-icon icon=\"fa-light fa-chevron-down\"></ax-icon>\n </ax-suffix>\n </ax-button>\n </div>\n <!--->\n <!-- ----- Insert reserved [content] slot for master templates ----- -->\n @if (isMasterKind()) {\n <div data-insert-var-trigger>\n <ax-button\n [text]=\"\n '@content-management:templates.actions.insert-content-slot'\n | translate\n | async\n \"\n look=\"twotone\"\n color=\"default\"\n size=\"sm\"\n (onClick)=\"insertContentSlot(ch.name)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-layer-group\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n }\n <!--->\n <!-- ----- Copy subject/body from another channel ----- -->\n @if (otherChannelsWithContent(ch.name).length > 0) {\n <ax-button\n [text]=\"\n '@content-management:templates.actions.copy-from'\n | translate\n | async\n \"\n look=\"twotone\"\n color=\"default\"\n size=\"sm\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-copy\"></ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-icon icon=\"fa-light fa-chevron-down\"></ax-icon>\n </ax-suffix>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (\n src of otherChannelsWithContent(ch.name);\n track src.name\n ) {\n <ax-button-item\n look=\"blank\"\n color=\"default\"\n [text]=\"(src.title | translate | async) ?? src.name\"\n (onClick)=\"copyFromChannel(ch.name, src.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"getChannelIcon(src)\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n }\n </div>\n <div>\n <ax-tabs [look]=\"'default'\">\n <ax-tab-item\n [text]=\"\n ('@content-management:templates.actions.edit'\n | translate\n | async) ?? 'Edit'\n \"\n [active]=\"viewMode() === 'edit'\"\n (onClick)=\"viewMode.set('edit')\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-pen\" class=\"text-current\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n <ax-tab-item\n [text]=\"\n ('@content-management:templates.actions.preview'\n | translate\n | async) ?? 'Preview'\n \"\n [active]=\"viewMode() === 'preview'\"\n (onClick)=\"viewMode.set('preview')\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-eye\" class=\"text-current\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n </ax-tabs>\n </div>\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "ngmodule", type: AXTabsModule }, { kind: "component", type: i3.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "reorderable", "reorderDelay", "renderMode", "stacked", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged", "onTabsReordered"] }, { kind: "component", type: i3.AXTabItemComponent, selector: "ax-tab-item", inputs: ["disabled", "text", "key", "headerTemplate", "active"], outputs: ["disabledChange", "onClick", "onBlur", "onFocus", "activeChange"] }, { kind: "ngmodule", type: AXTextAreaModule }, { kind: "component", type: i4.AXTextAreaComponent, selector: "ax-text-area", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "placeholder", "maxLength", "look", "rows", "allowResize", "showCounter", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "component", type: i5.AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "maskPattern", "customTokens", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress", "onMaskChanged"] }, { kind: "ngmodule", type: AXTextEditorModule }, { kind: "component", type: i6.AXTextEditorComponent, selector: "ax-text-editor", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "look", "placeHolder", "outputFormat", "initialLine"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange"] }, { kind: "component", type: i6.AXTextEditorToolbarComponent, selector: "ax-text-editor-toolbar", inputs: ["orientation"] }, { kind: "component", type: i6.AXTextEditorContentComponent, selector: "ax-text-editor-content" }, { kind: "component", type: i6.AXTextEditorHistoryComponent, selector: "ax-text-editor-history" }, { kind: "component", type: i6.AXTextEditorFontStyleComponent, selector: "ax-text-editor-font-style" }, { kind: "component", type: i6.AXTextEditorListComponent, selector: "ax-text-editor-list" }, { kind: "ngmodule", type: AXValidationModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i7.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i7.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i7.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i8.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i2$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
800
795
  }
801
796
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMTemplateContentEditorWidgetEditComponent, decorators: [{
802
797
  type: Component,
@@ -808,13 +803,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
808
803
  AXTabsModule,
809
804
  AXTextAreaModule,
810
805
  AXTextBoxModule,
811
- AXWysiwygModule,
806
+ AXTextEditorModule,
812
807
  AXValidationModule,
813
808
  AXTranslationModule,
814
809
  AXButtonModule,
815
810
  AXDropdownModule,
816
- ], template: "<!-- Template Content Editor: Channel tabs and content per channel -->\n<div class=\"flex flex-col gap-4 w-full\">\n <!-- Channel tabs navigation -->\n <div class=\"flex items-center gap-2 flex-wrap\">\n <ax-tabs\n [look]=\"'with-line'\"\n (onActiveTabChanged)=\"onChannelTabChanged($event.index)\"\n class=\"flex-1 min-w-0\"\n >\n @for (ch of availableChannels(); track ch.name; let i = $index) {\n <ax-tab-item\n [text]=\"(ch.title | translate | async) ?? ch.name\"\n [key]=\"i.toString()\"\n [active]=\"activeTabIndex() === i\"\n ></ax-tab-item>\n }\n </ax-tabs>\n </div>\n\n @if (activeChannel(); as ch) {\n <!-- Channel content area: Edit mode or Preview mode -->\n <div class=\"mb-4 p-4\">\n @if (!isChannelConfigured(ch.name) && ch.notConfiguredMessageKey) {\n <div\n class=\"mb-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 p-3 rounded border border-amber-300 bg-amber-50 dark:border-amber-700 dark:bg-amber-950/30\"\n >\n <p class=\"text-sm text-amber-900 dark:text-amber-100\">\n {{ ch.notConfiguredMessageKey | translate | async }}\n </p>\n @if (ch.configureSettings) {\n <ax-button\n [text]=\"\n '@content-management:templates.actions.configure-channel'\n | translate\n | async\n \"\n look=\"outline\"\n color=\"primary\"\n size=\"sm\"\n (onClick)=\"openChannelConfigure(ch)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-gear\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n </div>\n }\n\n @if (viewMode() === 'edit') {\n <!-- Edit mode: Subject field (for channels that support it, e.g. Email) -->\n @if (ch.hasSubject) {\n <div class=\"mb-3\">\n <label class=\"block text-sm mb-1\">\n {{\n '@content-management:templates.entities.text-template.fields.subject.title'\n | translate\n | async\n }}\n </label>\n <ax-text-box\n [ngModel]=\"getChannelSubject(ch.name)\"\n (onValueChanged)=\"handleSubjectChange(ch.name, $event)\"\n [placeholder]=\"\n ('@content-management:templates.entities.text-template.fields.subject.placeholder'\n | translate\n | async)!\n \"\n ></ax-text-box>\n </div>\n }\n\n <!-- Edit mode: Body field (plain text or rich WYSIWYG) -->\n <div>\n <label class=\"block text-sm mb-1\">\n {{\n '@content-management:templates.entities.text-template.fields.body.title'\n | translate\n | async\n }}\n </label>\n <!--->\n <!-- ----- Plain-text body for SMS-style channels ----- -->\n @if (ch.type === 'plain') {\n <ax-text-area\n #bodyTextarea\n [ngModel]=\"getChannelBody(ch.name)\"\n (onValueChanged)=\"handlePlainBodyChange(ch.name, $event)\"\n [rows]=\"8\"\n [placeholder]=\"\n ('@content-management:templates.entities.text-template.fields.body-placeholder.plain'\n | translate\n | async)!\n \"\n ></ax-text-area>\n }\n <!-- ----- Recreate Quill per channel so tab switches do not keep the previous HTML ----- -->\n @else {\n @for (channelName of [ch.name]; track channelName) {\n <ax-wysiwyg-container\n #wysiwygRef\n [placeHolder]=\"\n ('@content-management:templates.entities.text-template.fields.body-placeholder.rich'\n | translate\n | async)!\n \"\n [ngModel]=\"getChannelBody(channelName)\"\n (onValueChanged)=\"handleWysiwygChange(channelName, $event)\"\n [look]=\"'solid'\"\n >\n <ax-wysiwyg-view [style.min-height.px]=\"200\"></ax-wysiwyg-view>\n <ax-wysiwyg-toolbar>\n <ax-prefix>\n <ax-wysiwyg-history></ax-wysiwyg-history>\n <ax-wysiwyg-font-style></ax-wysiwyg-font-style>\n <ax-wysiwyg-list></ax-wysiwyg-list>\n </ax-prefix>\n </ax-wysiwyg-toolbar>\n </ax-wysiwyg-container>\n }\n }\n </div>\n } @else {\n <!-- Preview mode: Rendered content with variable placeholders replaced by sample values -->\n <div class=\"space-y-2\">\n @if (ch.hasSubject && previewSubject(ch.name)) {\n <div>\n <span class=\"text-xs text-gray-500\"\n >{{\n '@content-management:templates.entities.text-template.fields.subject.title'\n | translate\n | async\n }}:\n </span>\n <span class=\"text-sm\">{{ previewSubject(ch.name) }}</span>\n </div>\n }\n <!-- ----- Rich email keeps inline styles; plain channels use pre-wrap ----- -->\n <div\n class=\"text-sm p-3 bg-gray-100 dark:bg-gray-900 rounded border overflow-auto\"\n [class.whitespace-pre-wrap]=\"ch.type !== 'rich'\"\n [innerHTML]=\"previewBodyHtml(ch.name)\"\n ></div>\n </div>\n }\n </div>\n\n <!-- Footer: Action buttons (left) + Edit/Preview toggle (right) in single row -->\n <div\n class=\"flex flex-nowrap items-center justify-between gap-3 pt-3 mt-1 border-t border-gray-200 dark:border-gray-700\"\n >\n <div class=\"flex flex-nowrap items-center gap-2 min-w-0\">\n @if (viewMode() === 'edit') {\n <!-- ----- Insert variable dropdown from platform tokens ----- -->\n <div data-insert-var-trigger>\n <ax-button\n [text]=\"\n '@content-management:templates.actions.insert-variable'\n | translate\n | async\n \"\n look=\"twotone\"\n color=\"default\"\n size=\"sm\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-code\"></ax-icon>\n </ax-prefix>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (v of availableVariables(); track v.name) {\n <ax-button-item\n look=\"blank\"\n color=\"default\"\n [text]=\"(v.title || v.name) + ' ({{' + v.name + '}})'\"\n (onClick)=\"insertVariable(ch.name, v.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"getVariableIcon(v)\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n <ax-suffix>\n <ax-icon icon=\"fa-light fa-chevron-down\"></ax-icon>\n </ax-suffix>\n </ax-button>\n </div>\n <!--->\n <!-- ----- Insert reserved [content] slot for master templates ----- -->\n @if (isMasterKind()) {\n <div data-insert-var-trigger>\n <ax-button\n [text]=\"\n '@content-management:templates.actions.insert-content-slot'\n | translate\n | async\n \"\n look=\"twotone\"\n color=\"default\"\n size=\"sm\"\n (onClick)=\"insertContentSlot(ch.name)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-layer-group\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n }\n <!--->\n <!-- ----- Copy subject/body from another channel ----- -->\n @if (otherChannelsWithContent(ch.name).length > 0) {\n <ax-button\n [text]=\"\n '@content-management:templates.actions.copy-from'\n | translate\n | async\n \"\n look=\"twotone\"\n color=\"default\"\n size=\"sm\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-copy\"></ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-icon icon=\"fa-light fa-chevron-down\"></ax-icon>\n </ax-suffix>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (\n src of otherChannelsWithContent(ch.name);\n track src.name\n ) {\n <ax-button-item\n look=\"blank\"\n color=\"default\"\n [text]=\"(src.title | translate | async) ?? src.name\"\n (onClick)=\"copyFromChannel(ch.name, src.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"getChannelIcon(src)\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n }\n </div>\n <div>\n <ax-tabs [look]=\"'default'\">\n <ax-tab-item\n [text]=\"\n ('@content-management:templates.actions.edit'\n | translate\n | async) ?? 'Edit'\n \"\n [active]=\"viewMode() === 'edit'\"\n (onClick)=\"viewMode.set('edit')\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-pen\" class=\"text-current\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n <ax-tab-item\n [text]=\"\n ('@content-management:templates.actions.preview'\n | translate\n | async) ?? 'Preview'\n \"\n [active]=\"viewMode() === 'preview'\"\n (onClick)=\"viewMode.set('preview')\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-eye\" class=\"text-current\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n </ax-tabs>\n </div>\n </div>\n }\n</div>\n" }]
817
- }], ctorParameters: () => [], propDecorators: { wysiwygRef: [{ type: i0.ViewChild, args: ['wysiwygRef', { isSignal: true }] }], bodyTextareaRef: [{ type: i0.ViewChild, args: ['bodyTextarea', { ...{ read: (ElementRef) }, isSignal: true }] }] } });
811
+ ], template: "<!-- Template Content Editor: Channel tabs and content per channel -->\n<div class=\"flex flex-col gap-4 w-full\">\n <!-- Channel tabs navigation -->\n <div class=\"flex items-center gap-2 flex-wrap\">\n <ax-tabs\n [look]=\"'with-line'\"\n (onActiveTabChanged)=\"onChannelTabChanged($event.index)\"\n class=\"flex-1 min-w-0\"\n >\n @for (ch of availableChannels(); track ch.name; let i = $index) {\n <ax-tab-item\n [text]=\"(ch.title | translate | async) ?? ch.name\"\n [key]=\"i.toString()\"\n [active]=\"activeTabIndex() === i\"\n ></ax-tab-item>\n }\n </ax-tabs>\n </div>\n\n @if (activeChannel(); as ch) {\n <!-- Channel content area: Edit mode or Preview mode -->\n <div class=\"mb-4 p-4\">\n @if (!isChannelConfigured(ch.name) && ch.notConfiguredMessageKey) {\n <div\n class=\"mb-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 p-3 rounded border border-amber-300 bg-amber-50 dark:border-amber-700 dark:bg-amber-950/30\"\n >\n <p class=\"text-sm text-amber-900 dark:text-amber-100\">\n {{ ch.notConfiguredMessageKey | translate | async }}\n </p>\n @if (ch.configureSettings) {\n <ax-button\n [text]=\"\n '@content-management:templates.actions.configure-channel'\n | translate\n | async\n \"\n look=\"outline\"\n color=\"primary\"\n size=\"sm\"\n (onClick)=\"openChannelConfigure(ch)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-gear\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n </div>\n }\n\n @if (viewMode() === 'edit') {\n <!-- Edit mode: Subject field (for channels that support it, e.g. Email) -->\n @if (ch.hasSubject) {\n <div class=\"mb-3\">\n <label class=\"block text-sm mb-1\">\n {{\n '@content-management:templates.entities.text-template.fields.subject.title'\n | translate\n | async\n }}\n </label>\n <ax-text-box\n [ngModel]=\"getChannelSubject(ch.name)\"\n (onValueChanged)=\"handleSubjectChange(ch.name, $event)\"\n [placeholder]=\"\n ('@content-management:templates.entities.text-template.fields.subject.placeholder'\n | translate\n | async)!\n \"\n ></ax-text-box>\n </div>\n }\n\n <!-- Edit mode: Body field (plain text or rich text-editor) -->\n <div>\n <label class=\"block text-sm mb-1\">\n {{\n '@content-management:templates.entities.text-template.fields.body.title'\n | translate\n | async\n }}\n </label>\n <!--->\n <!-- ----- Plain-text body for SMS-style channels ----- -->\n @if (ch.type === 'plain') {\n <ax-text-area\n #bodyTextarea\n [ngModel]=\"getChannelBody(ch.name)\"\n (onValueChanged)=\"handlePlainBodyChange(ch.name, $event)\"\n [rows]=\"8\"\n [placeholder]=\"\n ('@content-management:templates.entities.text-template.fields.body-placeholder.plain'\n | translate\n | async)!\n \"\n ></ax-text-area>\n }\n <!-- ----- Recreate the rich editor per channel so tab switches do not keep the previous HTML ----- -->\n @else {\n @for (channelName of [ch.name]; track channelName) {\n <ax-text-editor\n #editorRef\n outputFormat=\"html\"\n [placeHolder]=\"\n ('@content-management:templates.entities.text-template.fields.body-placeholder.rich'\n | translate\n | async)!\n \"\n [ngModel]=\"getChannelBody(channelName)\"\n (onValueChanged)=\"handleEditorChange(channelName, $event)\"\n [look]=\"'solid'\"\n [initialLine]=\"8\"\n >\n <ax-text-editor-content [style.min-height.px]=\"200\"></ax-text-editor-content>\n <ax-text-editor-toolbar>\n <ax-prefix>\n <ax-text-editor-history></ax-text-editor-history>\n <ax-text-editor-font-style></ax-text-editor-font-style>\n <ax-text-editor-list></ax-text-editor-list>\n </ax-prefix>\n </ax-text-editor-toolbar>\n </ax-text-editor>\n }\n }\n </div>\n } @else {\n <!-- Preview mode: Rendered content with variable placeholders replaced by sample values -->\n <div class=\"space-y-2\">\n @if (ch.hasSubject && previewSubject(ch.name)) {\n <div>\n <span class=\"text-xs text-gray-500\"\n >{{\n '@content-management:templates.entities.text-template.fields.subject.title'\n | translate\n | async\n }}:\n </span>\n <span class=\"text-sm\">{{ previewSubject(ch.name) }}</span>\n </div>\n }\n <!-- ----- Rich email keeps inline styles; plain channels use pre-wrap ----- -->\n <div\n class=\"text-sm p-3 bg-gray-100 dark:bg-gray-900 rounded border overflow-auto\"\n [class.whitespace-pre-wrap]=\"ch.type !== 'rich'\"\n [innerHTML]=\"previewBodyHtml(ch.name)\"\n ></div>\n </div>\n }\n </div>\n\n <!-- Footer: Action buttons (left) + Edit/Preview toggle (right) in single row -->\n <div\n class=\"flex flex-nowrap items-center justify-between gap-3 pt-3 mt-1 border-t border-gray-200 dark:border-gray-700\"\n >\n <div class=\"flex flex-nowrap items-center gap-2 min-w-0\">\n @if (viewMode() === 'edit') {\n <!-- ----- Insert variable dropdown from platform tokens ----- -->\n <div data-insert-var-trigger>\n <ax-button\n [text]=\"\n '@content-management:templates.actions.insert-variable'\n | translate\n | async\n \"\n look=\"twotone\"\n color=\"default\"\n size=\"sm\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-code\"></ax-icon>\n </ax-prefix>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (v of availableVariables(); track v.name) {\n <ax-button-item\n look=\"blank\"\n color=\"default\"\n [text]=\"(v.title || v.name) + ' ({{' + v.name + '}})'\"\n (onClick)=\"insertVariable(ch.name, v.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"getVariableIcon(v)\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n <ax-suffix>\n <ax-icon icon=\"fa-light fa-chevron-down\"></ax-icon>\n </ax-suffix>\n </ax-button>\n </div>\n <!--->\n <!-- ----- Insert reserved [content] slot for master templates ----- -->\n @if (isMasterKind()) {\n <div data-insert-var-trigger>\n <ax-button\n [text]=\"\n '@content-management:templates.actions.insert-content-slot'\n | translate\n | async\n \"\n look=\"twotone\"\n color=\"default\"\n size=\"sm\"\n (onClick)=\"insertContentSlot(ch.name)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-layer-group\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n }\n <!--->\n <!-- ----- Copy subject/body from another channel ----- -->\n @if (otherChannelsWithContent(ch.name).length > 0) {\n <ax-button\n [text]=\"\n '@content-management:templates.actions.copy-from'\n | translate\n | async\n \"\n look=\"twotone\"\n color=\"default\"\n size=\"sm\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-copy\"></ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-icon icon=\"fa-light fa-chevron-down\"></ax-icon>\n </ax-suffix>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (\n src of otherChannelsWithContent(ch.name);\n track src.name\n ) {\n <ax-button-item\n look=\"blank\"\n color=\"default\"\n [text]=\"(src.title | translate | async) ?? src.name\"\n (onClick)=\"copyFromChannel(ch.name, src.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"getChannelIcon(src)\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n }\n </div>\n <div>\n <ax-tabs [look]=\"'default'\">\n <ax-tab-item\n [text]=\"\n ('@content-management:templates.actions.edit'\n | translate\n | async) ?? 'Edit'\n \"\n [active]=\"viewMode() === 'edit'\"\n (onClick)=\"viewMode.set('edit')\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-pen\" class=\"text-current\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n <ax-tab-item\n [text]=\"\n ('@content-management:templates.actions.preview'\n | translate\n | async) ?? 'Preview'\n \"\n [active]=\"viewMode() === 'preview'\"\n (onClick)=\"viewMode.set('preview')\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-eye\" class=\"text-current\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n </ax-tabs>\n </div>\n </div>\n }\n</div>\n" }]
812
+ }], ctorParameters: () => [], propDecorators: { editorRef: [{ type: i0.ViewChild, args: ['editorRef', { isSignal: true }] }], bodyTextareaRef: [{ type: i0.ViewChild, args: ['bodyTextarea', { ...{ read: (ElementRef) }, isSignal: true }] }] } });
818
813
 
819
814
  export { AXMTemplateContentEditorWidgetEditComponent };
820
- //# sourceMappingURL=acorex-platform-module-content-management-client-template-content-editor-widget-edit.component-CphFsFSd.mjs.map
815
+ //# sourceMappingURL=acorex-platform-module-content-management-client-template-content-editor-widget-edit.component-h5ING7pF.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-module-content-management-client-template-content-editor-widget-edit.component-h5ING7pF.mjs","sources":["../../../../libs/modules/content-management/client/src/lib/features/template-content-editor/template-content-editor-widget-edit.component.ts","../../../../libs/modules/content-management/client/src/lib/features/template-content-editor/template-content-editor-widget-edit.component.html"],"sourcesContent":["import { AXButtonModule } from '@acorex/components/button';\nimport { AXDecoratorModule } from '@acorex/components/decorators';\nimport { AXDropdownModule } from '@acorex/components/dropdown';\nimport { AXFormModule } from '@acorex/components/form';\nimport { AXTabsModule } from '@acorex/components/tabs';\nimport { AXTextAreaModule } from '@acorex/components/text-area';\nimport { AXTextBoxModule } from '@acorex/components/text-box';\nimport { AXToastService } from '@acorex/components/toast';\nimport { AXTextEditorComponent, AXTextEditorModule } from '@acorex/components/text-editor';\nimport { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';\nimport { AXValidationModule } from '@acorex/core/validation';\nimport { AXPSettingsService, AXPTokenDefinitionService } from '@acorex-platform/framework-client/common';\nimport { AXPEntityService } from '@acorex-platform/framework-client/layout/entity';\nimport { AXPValueWidgetComponent } from '@acorex-platform/framework-client/layout/widget-core';\nimport { AXPCommandExecutor } from '@acorex-platform/framework-client/runtime';\nimport { CommonModule } from '@angular/common';\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n ElementRef,\n effect,\n inject,\n OnInit,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { DomSanitizer, type SafeHtml } from '@angular/platform-browser';\nimport { FormsModule } from '@angular/forms';\nimport { AXValueChangedEvent } from '@acorex/cdk/common';\nimport {\n AXPContextState,\n AXPPlatformScope,\n isFormValueEqual,\n runtimeCommandPayloadData,\n type AXPMultiLanguageString,\n} from '@acorex-platform/framework-shared/core';\nimport {\n AXM_TEXT_TEMPLATE_PREVIEW_COMMAND_KEY,\n RootConfig,\n type AXMTextTemplatePreviewRequest,\n type AXMTextTemplatePreviewResult,\n} from '@acorex-platform/module-content-management-client/contracts';\nimport { AXP_TEXT_TEMPLATE_CHANNEL_DEFINITION_PROVIDER } from './channel-definition.provider';\nimport {\n AXMTextTemplateChannelDefinition,\n AXMTextTemplateChannelsValue,\n} from './channel-definition.types';\nimport {\n AXM_TEXT_TEMPLATE_CONTENT_SLOT,\n AXM_TEXT_TEMPLATE_KIND,\n AXM_TEXT_TEMPLATE_MAX_PARENT_DEPTH,\n collectTextTemplatePlaceholderNames,\n composeTextTemplateBodyChain,\n renderTextTemplateSource,\n replaceTextTemplatePlaceholders,\n resolveTextTemplateLocalizedString,\n type AXMTextTemplateEntityModel,\n} from './text-template-placeholder.util';\n\n/** Variable definition from PlatformManagement.Tokens for template preview and Insert variable */\ninterface TemplateVariable {\n name: string;\n title: string;\n sampleValue?: string;\n kind?: string;\n dataType?: string;\n}\n\n@Component({\n selector: 'axm-template-content-editor-widget-edit',\n templateUrl: './template-content-editor-widget-edit.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n CommonModule,\n AXDecoratorModule,\n FormsModule,\n AXFormModule,\n AXTabsModule,\n AXTextAreaModule,\n AXTextBoxModule,\n AXTextEditorModule,\n AXValidationModule,\n AXTranslationModule,\n AXButtonModule,\n AXDropdownModule,\n ],\n})\nexport class AXMTemplateContentEditorWidgetEditComponent\n extends AXPValueWidgetComponent<AXMTextTemplateChannelsValue | null>\n implements OnInit, AfterViewInit\n{\n /** Stored cursor/selection state before Insert Variable dropdown opens */\n private storedCursor: {\n channelName: string;\n isPlain: boolean;\n selectionStart?: number;\n selectionEnd?: number;\n range?: Range;\n } | null = null;\n private readonly channelProviders = inject(AXP_TEXT_TEMPLATE_CHANNEL_DEFINITION_PROVIDER, {\n optional: true,\n });\n private readonly settingsService = inject(AXPSettingsService);\n private readonly translationService = inject(AXTranslationService);\n private readonly entityService = inject(AXPEntityService);\n private readonly tokenDefinitionService = inject(AXPTokenDefinitionService, { optional: true });\n private readonly commandExecutor = inject(AXPCommandExecutor);\n private readonly toastService = inject(AXToastService);\n private readonly sanitizer = inject(DomSanitizer);\n private readonly destroyRef = inject(DestroyRef);\n private readonly hostRef = inject(ElementRef<HTMLElement>);\n\n /** Dedupes in-flight preview loads when effect re-runs. */\n private previewRequestSeq = 0;\n\n /**\n * TipTap `commitValue(html, true)` marks hydration as a user edit.\n * Ignore writes until that timer elapses after a programmatic sync.\n */\n private suppressEditorWrites = false;\n private suppressEditorWritesTimer: ReturnType<typeof setTimeout> | null = null;\n\n private lastSyncedChannel: string | null = null;\n private lastSyncedViewMode: 'edit' | 'preview' | null = null;\n private lastSyncedEditor: AXTextEditorComponent | undefined;\n /** Drops the ax-tabs init event so it cannot overwrite the content-channel tab. */\n private ignoreNextChannelTabChange = false;\n\n protected editorRef = viewChild<AXTextEditorComponent>('editorRef');\n protected bodyTextareaRef = viewChild('bodyTextarea', { read: ElementRef<HTMLElement> });\n\n protected availableChannels = signal<AXMTextTemplateChannelDefinition[]>([]);\n protected channelConfigured = signal<Record<string, boolean>>({});\n protected availableVariables = signal<TemplateVariable[]>([]);\n protected activeTabIndex = signal<number>(0);\n protected viewMode = signal<'edit' | 'preview'>('edit');\n\n /** Resolved values for local preview fallback: expression/token evaluation, then sampleValue */\n protected resolvedPreviewValues = signal<Record<string, string>>({});\n\n /** Parent-chain bodies (leaf → root) for the active locale, keyed by channel (local fallback). */\n protected composedPreviewBodies = signal<Record<string, string>>({});\n\n /** Server Preview results keyed by channel (preferred over local compose). */\n protected serverPreviewByChannel = signal<\n Record<string, { subject?: string; body: string }>\n >({});\n\n protected activeChannel = computed(() => {\n const idx = this.activeTabIndex();\n const chs = this.availableChannels();\n return chs[idx] ?? null;\n });\n\n /** True when the host entity form has Kind = Master. */\n protected isMasterKind = computed(() => {\n this.contextService.changeEvent();\n const kind = this.contextService.getValue('kind');\n return kind === AXM_TEXT_TEMPLATE_KIND.Master;\n });\n\n protected otherChannelsWithContent = (currentName: string) =>\n this.availableChannels().filter(\n (c) => c.name !== currentName && (this.getChannelBody(c.name) || (c.hasSubject && this.getChannelSubject(c.name)))\n );\n\n /** Returns icon class for a variable/token based on kind and dataType */\n protected getVariableIcon(v: TemplateVariable): string {\n const kindMap: Record<string, string> = {\n Static: 'fa-light fa-database',\n Context: 'fa-light fa-layer-group',\n Event: 'fa-light fa-bolt',\n Computed: 'fa-light fa-calculator',\n Secret: 'fa-light fa-key',\n };\n const dataTypeMap: Record<string, string> = {\n String: 'fa-light fa-font',\n Integer: 'fa-light fa-hashtag',\n Boolean: 'fa-light fa-toggle-on',\n Decimal: 'fa-light fa-calculator',\n DateTime: 'fa-light fa-clock',\n Json: 'fa-light fa-braces',\n };\n const byKind = v.kind && kindMap[v.kind];\n if (byKind) return byKind;\n const byDataType = v.dataType && dataTypeMap[v.dataType];\n if (byDataType) return byDataType;\n return 'fa-light fa-code';\n }\n\n /** Returns icon class for a channel based on name and type */\n protected getChannelIcon(ch: AXMTextTemplateChannelDefinition): string {\n const nameMap: Record<string, string> = {\n email: 'fa-light fa-envelope',\n sms: 'fa-light fa-comment-sms',\n whatsapp: 'fa-brands fa-whatsapp',\n push: 'fa-light fa-bell',\n telegram: 'fa-brands fa-telegram',\n 'in-app': 'fa-light fa-inbox',\n };\n const byName = nameMap[ch.name?.toLowerCase() ?? ''];\n if (byName) return byName;\n return ch.type === 'rich' ? 'fa-light fa-file-lines' : 'fa-light fa-align-left';\n }\n\n private getTemplateLocale(): string {\n return this.translationService.getActiveLang() ?? 'en-US';\n }\n\n /**\n * Builds a mutable locale map from a stored channel field (string legacy or ML object).\n */\n private normalizeChannelFieldToMl(\n existing: AXPMultiLanguageString | string | undefined,\n ): Record<string, string> {\n if (existing == null || existing === '') {\n return {};\n }\n if (typeof existing === 'string') {\n const s = existing;\n return { 'en-US': s, 'fa-IR': s };\n }\n return { ...(existing as Record<string, string>) };\n }\n\n constructor() {\n super();\n effect(() => {\n this.viewMode();\n this.activeTabIndex();\n this.getValue();\n this.contextService.changeEvent();\n if (this.viewMode() === 'preview') {\n void this.loadServerPreview();\n } else {\n this.previewRequestSeq += 1;\n this.resolvedPreviewValues.set({});\n this.composedPreviewBodies.set({});\n this.serverPreviewByChannel.set({});\n }\n });\n\n /**\n * TipTap keeps its own document; one-way ngModel does not refresh it when the entity\n * loads, the user discards, or the active channel tab changes.\n */\n effect(() => {\n const viewMode = this.viewMode();\n const channel = this.activeChannel();\n const changeState = this.contextService.changeEvent().state;\n const body = channel ? this.getChannelBody(channel.name) : '';\n const editor = this.editorRef();\n\n if (viewMode !== 'edit' || !channel || channel.type === 'plain' || !editor) {\n this.lastSyncedViewMode = viewMode;\n return;\n }\n\n const channelChanged = channel.name !== this.lastSyncedChannel;\n const viewModeChanged = viewMode !== this.lastSyncedViewMode;\n const editorChanged = editor !== this.lastSyncedEditor;\n const contextReload = this.shouldSyncEditorFromContext(changeState);\n\n if (!channelChanged && !viewModeChanged && !editorChanged && !contextReload) {\n return;\n }\n\n untracked(() => {\n this.lastSyncedChannel = channel.name;\n this.lastSyncedViewMode = viewMode;\n this.lastSyncedEditor = editor;\n void this.applyEditorContentWhenReady(editor, body);\n });\n });\n\n this.settingsService.onChanged.subscribe(() => {\n void this.refreshChannelConfiguration();\n });\n\n this.destroyRef.onDestroy(() => this.clearSuppressEditorWritesTimer());\n }\n\n protected isChannelConfigured(name: string): boolean {\n return this.channelConfigured()[name] ?? true;\n }\n\n protected async openChannelConfigure(channel: AXMTextTemplateChannelDefinition): Promise<void> {\n const configure = channel.configureSettings;\n if (!configure) {\n return;\n }\n\n const saved = await this.settingsService.showSectionPopup({\n scope: configure.scope,\n section: configure.section,\n group: configure.group,\n });\n if (saved) {\n await this.refreshChannelConfiguration();\n }\n }\n\n private async refreshChannelConfiguration(): Promise<void> {\n const channels = this.availableChannels();\n const next: Record<string, boolean> = {};\n for (const channel of channels) {\n next[channel.name] = await this.isChannelConfiguredInternal(channel);\n }\n this.channelConfigured.set(next);\n }\n\n private async isChannelConfiguredInternal(channel: AXMTextTemplateChannelDefinition): Promise<boolean> {\n const requiredKeys = channel.requiredSettingKeys ?? [];\n if (!requiredKeys.length) {\n return true;\n }\n const scopeKey = channel.configureSettings?.scope ?? 'T';\n const scoped = this.settingsService.scope(scopeKey as AXPPlatformScope);\n for (const key of requiredKeys) {\n const value = await scoped.get(key);\n if (!this.hasNonEmptySettingValue(value)) {\n return false;\n }\n }\n return true;\n }\n\n private hasNonEmptySettingValue(value: unknown): boolean {\n if (value == null) {\n return false;\n }\n if (typeof value === 'string') {\n return value.trim().length > 0;\n }\n if (typeof value === 'number') {\n return Number.isFinite(value);\n }\n if (typeof value === 'boolean') {\n return true;\n }\n if (typeof value === 'object' && 'value' in value) {\n return this.hasNonEmptySettingValue((value as { value?: unknown }).value);\n }\n return String(value).trim().length > 0;\n }\n\n ngAfterViewInit(): void {\n const el = this.hostRef.nativeElement;\n const handleMousedown = (e: MouseEvent) => {\n const target = e.target as Node;\n if (!target || !el.contains(target)) return;\n const trigger = (target as Element).closest?.('[data-insert-var-trigger]');\n if (!trigger) return;\n this.captureCursorBeforeInsert();\n };\n el.addEventListener('mousedown', handleMousedown, { capture: true });\n this.destroyRef.onDestroy(() =>\n el.removeEventListener('mousedown', handleMousedown, { capture: true })\n );\n }\n\n override async ngOnInit(): Promise<void> {\n super.ngOnInit();\n const rawCh = this.channelProviders;\n const chProviders = rawCh == null ? [] : Array.isArray(rawCh) ? rawCh : [rawCh];\n const allChannels: AXMTextTemplateChannelDefinition[] = [];\n for (const p of chProviders) {\n if (p?.getChannels) allChannels.push(...p.getChannels());\n }\n this.availableChannels.set(\n Array.from(new Map(allChannels.map((c) => [c.name, c])).values())\n );\n await this.refreshChannelConfiguration();\n\n try {\n const tokensAccessor = this.entityService.withEntity('PlatformManagement', 'Tokens').data();\n const result = await tokensAccessor.query({ skip: 0, take: 500 });\n const items = (result.items ?? []) as Array<{\n name?: string;\n title?: string;\n sampleValue?: string;\n kind?: string;\n dataType?: string;\n }>;\n const vars: TemplateVariable[] = items\n .map((t) => ({\n name: String(t.name ?? ''),\n title: String(t.title ?? t.name ?? ''),\n sampleValue: t.sampleValue != null ? String(t.sampleValue) : undefined,\n kind: t.kind,\n dataType: t.dataType,\n }))\n .filter((v) => v.name);\n this.availableVariables.set(Array.from(new Map(vars.map((v) => [v.name, v])).values()));\n } catch {\n this.availableVariables.set([]);\n }\n\n const value = this.getValue();\n if (value && typeof value === 'object' && Object.keys(value).length > 0) {\n const names = Object.keys(value);\n const chs = this.availableChannels();\n const idx = chs.findIndex((c) => names.includes(c.name));\n if (idx >= 0) {\n this.ignoreNextChannelTabChange = true;\n this.beginSuppressEditorWrites();\n this.activeTabIndex.set(idx);\n setTimeout(() => {\n this.ignoreNextChannelTabChange = false;\n });\n }\n }\n }\n\n protected onChannelTabChanged(index: number): void {\n if (this.ignoreNextChannelTabChange || index === this.activeTabIndex()) {\n return;\n }\n this.beginSuppressEditorWrites();\n this.activeTabIndex.set(index);\n }\n\n /** Capture cursor/selection before dropdown opens (runs in mousedown capture phase) */\n private captureCursorBeforeInsert(): void {\n const ch = this.activeChannel();\n if (!ch) return;\n this.storedCursor = null;\n const active = document.activeElement as HTMLElement | null;\n if (!active) return;\n if (ch.type === 'plain') {\n const textarea = this.getTextareaElement(active);\n if (textarea) {\n this.storedCursor = {\n channelName: ch.name,\n isPlain: true,\n selectionStart: textarea.selectionStart,\n selectionEnd: textarea.selectionEnd,\n };\n }\n } else {\n const editable = this.getContentEditableElement(active);\n if (editable) {\n const sel = document.getSelection();\n if (sel && sel.rangeCount > 0) {\n const range = sel.getRangeAt(0).cloneRange();\n this.storedCursor = {\n channelName: ch.name,\n isPlain: false,\n range,\n };\n }\n }\n }\n }\n\n private getTextareaElement(el: HTMLElement): HTMLTextAreaElement | null {\n if (el instanceof HTMLTextAreaElement) return el;\n return el.querySelector?.('textarea') ?? null;\n }\n\n private getContentEditableElement(el: HTMLElement): HTMLElement | null {\n if (el.isContentEditable) return el;\n return el.closest?.('[contenteditable=\"true\"]') ?? null;\n }\n\n protected insertVariable(channelName: string, varName: string): void {\n this.insertToken(channelName, `{{${varName}}}`);\n }\n\n protected insertContentSlot(channelName: string): void {\n this.insertToken(channelName, AXM_TEXT_TEMPLATE_CONTENT_SLOT);\n }\n\n private insertToken(channelName: string, token: string): void {\n const current = this.getChannelBody(channelName);\n const stored = this.storedCursor;\n this.storedCursor = null;\n\n if (stored && stored.channelName === channelName) {\n if (stored.isPlain) {\n const start = stored.selectionStart ?? current.length;\n const end = stored.selectionEnd ?? start;\n const before = current.slice(0, start);\n const after = current.slice(end);\n const newBody = before + token + after;\n this.setChannelBody(channelName, newBody);\n const newCursor = start + token.length;\n queueMicrotask(() => this.restoreTextareaCursor(newCursor));\n } else if (stored.range) {\n try {\n const startNode = stored.range.startContainer;\n const elem = startNode.nodeType === Node.TEXT_NODE\n ? (startNode as Text).parentElement\n : (startNode as Element);\n const editable = elem?.closest?.('[contenteditable=\"true\"]') as HTMLElement | null;\n const editorHost = this.editorRef();\n const target = editable ?? editorHost?.getHostElement()?.querySelector?.('[contenteditable=\"true\"]');\n if (target) {\n (target as HTMLElement).focus();\n const sel = document.getSelection();\n if (sel) {\n sel.removeAllRanges();\n sel.addRange(stored.range);\n document.execCommand('insertText', false, token);\n }\n } else {\n this.setChannelBody(channelName, current + token);\n }\n } catch {\n this.setChannelBody(channelName, current + token);\n }\n }\n } else {\n this.setChannelBody(channelName, current + token);\n }\n }\n\n private restoreTextareaCursor(position: number): void {\n const ref = this.bodyTextareaRef();\n const el = ref?.nativeElement;\n const textarea = el?.querySelector?.('textarea') ?? (el instanceof HTMLTextAreaElement ? el : null);\n if (textarea) {\n textarea.focus();\n textarea.setSelectionRange(position, position);\n }\n }\n\n protected copyFromChannel(targetName: string, sourceName: string): void {\n const ch = this.availableChannels().find((c) => c.name === sourceName);\n if (!ch) return;\n const hasSubject = ch.hasSubject;\n if (hasSubject) {\n this.setChannelSubject(targetName, this.getChannelSubject(sourceName));\n }\n this.setChannelBody(targetName, this.getChannelBody(sourceName));\n const active = this.activeChannel();\n if (active?.name === targetName && active.type === 'rich') {\n void this.applyEditorContentWhenReady(this.editorRef(), this.getChannelBody(targetName));\n }\n }\n\n protected getChannelSubject(name: string): string {\n const v = this.getValue()?.[name];\n const raw =\n v && typeof v === 'object' && 'subject' in v ? (v as { subject?: AXPMultiLanguageString }).subject : undefined;\n return resolveTextTemplateLocalizedString(raw, this.getTemplateLocale());\n }\n\n protected handleSubjectChange(name: string, e: AXValueChangedEvent<string>): void {\n if (!e.isUserInteraction) {\n return;\n }\n this.setChannelSubject(name, e.value ?? '');\n }\n\n protected setChannelSubject(name: string, value: string): void {\n const nextText = value ?? '';\n if (this.getChannelSubject(name) === nextText) {\n return;\n }\n const current = this.getValue() || {};\n if (!current[name] && !nextText.trim()) {\n return;\n }\n const ch = current[name] || { body: '' };\n const locale = this.getTemplateLocale();\n const ml = this.normalizeChannelFieldToMl(ch.subject);\n ml[locale] = nextText;\n this.commitChannelValue(current, name, { ...ch, subject: ml });\n }\n\n protected getChannelBody(name: string): string {\n const v = this.getValue()?.[name];\n const raw =\n v && typeof v === 'object' && 'body' in v ? (v as { body?: AXPMultiLanguageString }).body : undefined;\n return resolveTextTemplateLocalizedString(raw, this.getTemplateLocale());\n }\n\n protected handlePlainBodyChange(name: string, e: AXValueChangedEvent<string>): void {\n if (!e.isUserInteraction) {\n return;\n }\n this.setChannelBody(name, e.value ?? '');\n }\n\n protected handleEditorChange(name: string, e: AXValueChangedEvent<string>): void {\n if (this.suppressEditorWrites || !e.isUserInteraction) {\n return;\n }\n const val =\n typeof e === 'object' && e !== null && 'value' in e\n ? ((e as { value: string | null }).value ?? '')\n : String(e ?? '');\n this.setChannelBody(name, val);\n }\n\n protected setChannelBody(name: string, value: string): void {\n const nextText = value ?? '';\n if (this.getChannelBody(name) === nextText) {\n return;\n }\n const current = this.getValue() || {};\n if (!current[name] && !nextText.trim()) {\n return;\n }\n const ch = current[name] || { body: '' };\n const locale = this.getTemplateLocale();\n const ml = this.normalizeChannelFieldToMl(ch.body);\n ml[locale] = nextText;\n this.commitChannelValue(current, name, { ...ch, body: ml });\n }\n\n private commitChannelValue(\n current: AXMTextTemplateChannelsValue,\n name: string,\n nextChannel: AXMTextTemplateChannelsValue[string],\n ): void {\n const nextValue = { ...current, [name]: nextChannel };\n if (isFormValueEqual(nextValue, current)) {\n return;\n }\n const path = this.fullPath();\n const saved = path ? this.contextService.getSavedValue(path) : undefined;\n if (saved !== undefined && isFormValueEqual(nextValue, saved)) {\n return;\n }\n this.setValue(nextValue);\n }\n\n private shouldSyncEditorFromContext(state: AXPContextState): boolean {\n return state === 'restored' || state === 'initiated';\n }\n\n private beginSuppressEditorWrites(): void {\n this.suppressEditorWrites = true;\n this.clearSuppressEditorWritesTimer();\n this.suppressEditorWritesTimer = setTimeout(() => {\n this.suppressEditorWrites = false;\n this.suppressEditorWritesTimer = null;\n }, 500);\n }\n\n private clearSuppressEditorWritesTimer(): void {\n if (this.suppressEditorWritesTimer) {\n clearTimeout(this.suppressEditorWritesTimer);\n this.suppressEditorWritesTimer = null;\n }\n }\n\n private async applyEditorContentWhenReady(\n host: AXTextEditorComponent | undefined,\n text: string,\n ): Promise<void> {\n const content = text ?? '';\n\n for (let attempt = 0; attempt < 30; attempt++) {\n const editor = this.editorRef() ?? host;\n if (!editor?.getEditor()) {\n await new Promise((resolve) => setTimeout(resolve, 50));\n continue;\n }\n\n this.beginSuppressEditorWrites();\n editor.getEditorService().setContent(content, false);\n return;\n }\n }\n\n /**\n * Prefer server draft Preview (Context tokens + Event samples + parent composition).\n * Falls back to local compose when the command fails.\n */\n private async loadServerPreview(): Promise<void> {\n const requestSeq = ++this.previewRequestSeq;\n const value = this.getValue();\n const channel = this.activeChannel()?.name?.trim() || '';\n if (!value || typeof value !== 'object' || !channel) {\n this.serverPreviewByChannel.set({});\n this.composedPreviewBodies.set({});\n return;\n }\n\n const locale = this.getTemplateLocale();\n const parentIdRaw = this.contextService.getValue('parentId');\n const parentId = typeof parentIdRaw === 'string' ? parentIdRaw.trim() : '';\n const kindRaw = this.contextService.getValue('kind');\n const kind = typeof kindRaw === 'string' ? kindRaw.trim() : undefined;\n\n const request: AXMTextTemplatePreviewRequest = {\n channels: value,\n channel,\n locale,\n ...(parentId ? { parentId } : {}),\n ...(kind ? { kind } : {}),\n };\n\n try {\n const result = await this.commandExecutor.execute<\n AXMTextTemplatePreviewRequest,\n AXMTextTemplatePreviewResult\n >(AXM_TEXT_TEMPLATE_PREVIEW_COMMAND_KEY, request);\n\n if (requestSeq !== this.previewRequestSeq) {\n return;\n }\n\n const preview = runtimeCommandPayloadData(result);\n if (preview?.body != null) {\n this.serverPreviewByChannel.update((prev) => ({\n ...prev,\n [channel]: {\n ...(preview.subject != null ? { subject: preview.subject } : {}),\n body: preview.body,\n },\n }));\n return;\n }\n\n const message =\n typeof result?.message?.text === 'string' && result.message.text.trim()\n ? result.message.text.trim()\n : undefined;\n await this.fallbackToLocalPreview(channel, message);\n } catch (error) {\n if (requestSeq !== this.previewRequestSeq) {\n return;\n }\n const message = error instanceof Error ? error.message : undefined;\n await this.fallbackToLocalPreview(channel, message);\n }\n }\n\n private async fallbackToLocalPreview(channel: string, errorMessage?: string): Promise<void> {\n const title = await this.translationService.translateAsync(\n '@content-management:templates.messages.preview-failed.title',\n );\n const content = await this.translationService.translateAsync(\n '@content-management:templates.messages.preview-failed.content',\n );\n this.toastService.show({\n color: 'warning',\n title,\n content: errorMessage ? `${content} ${errorMessage}` : content,\n closeButton: true,\n timeOut: 5000,\n });\n\n this.serverPreviewByChannel.update((prev) => {\n const next = { ...prev };\n delete next[channel];\n return next;\n });\n await this.resolveComposedPreviewBodies();\n }\n\n /** Resolve variable values for local preview fallback */\n private async resolvePreviewVariables(): Promise<void> {\n const value = this.getValue();\n if (!value || typeof value !== 'object') return;\n const locale = this.getTemplateLocale();\n const parts: string[] = [];\n for (const v of Object.values(value)) {\n if (v != null && typeof v === 'object' && 'body' in v) {\n const o = v as { subject?: AXPMultiLanguageString; body?: AXPMultiLanguageString };\n parts.push(resolveTextTemplateLocalizedString(o.subject, locale));\n parts.push(resolveTextTemplateLocalizedString(o.body, locale));\n }\n }\n for (const body of Object.values(this.composedPreviewBodies())) {\n parts.push(body);\n }\n const allText = parts.join('');\n const varNames = collectTextTemplatePlaceholderNames(allText);\n if (varNames.length === 0) return;\n const vars = this.availableVariables();\n const resolved: Record<string, string> = {};\n const svc = this.tokenDefinitionService;\n for (const name of varNames) {\n try {\n if (svc) {\n const val = await svc.getValue(name);\n resolved[name] = val != null ? String(val) : '';\n }\n } catch {\n /* use fallback */\n }\n if (!(name in resolved) || !resolved[name]) {\n const v = vars.find((x) => x.name === name);\n if (v?.sampleValue != null) {\n resolved[name] = v.sampleValue;\n } else if (!(name in resolved)) {\n resolved[name] = '';\n }\n }\n }\n this.resolvedPreviewValues.update((prev) => ({ ...prev, ...resolved }));\n }\n\n /**\n * Local fallback: loads optional parent masters and stores leaf→root body chains per channel.\n */\n private async resolveComposedPreviewBodies(): Promise<void> {\n const value = this.getValue();\n if (!value || typeof value !== 'object') {\n this.composedPreviewBodies.set({});\n return;\n }\n\n const parentIdRaw = this.contextService.getValue('parentId');\n const parentId = typeof parentIdRaw === 'string' ? parentIdRaw.trim() : '';\n const locale = this.getTemplateLocale();\n const next: Record<string, string> = {};\n\n if (!parentId) {\n for (const channelName of Object.keys(value)) {\n next[channelName] = this.getChannelBody(channelName);\n }\n this.composedPreviewBodies.set(next);\n await this.resolvePreviewVariables();\n return;\n }\n\n const parentBodiesByChannel: Record<string, string[]> = {};\n try {\n const accessor = this.entityService\n .withEntity(RootConfig.module.name, RootConfig.entities.textTemplate.name)\n .data<\n string,\n AXMTextTemplateEntityModel,\n AXMTextTemplateEntityModel,\n AXMTextTemplateEntityModel,\n AXMTextTemplateEntityModel\n >();\n\n const visited = new Set<string>();\n const selfIdRaw = this.contextService.getValue('id');\n const selfId = typeof selfIdRaw === 'string' ? selfIdRaw.trim() : '';\n if (selfId) {\n visited.add(selfId);\n }\n\n let currentId: string | null = parentId;\n let depth = 1;\n while (currentId && depth <= AXM_TEXT_TEMPLATE_MAX_PARENT_DEPTH) {\n if (visited.has(currentId)) {\n break;\n }\n visited.add(currentId);\n const parent = await accessor.byKey(currentId);\n if (!parent?.channels) {\n break;\n }\n for (const [channelName, channelDef] of Object.entries(parent.channels)) {\n const body = resolveTextTemplateLocalizedString(channelDef?.body, locale);\n if (!body) continue;\n (parentBodiesByChannel[channelName] ??= []).push(body);\n }\n currentId = parent.parentId?.trim() || null;\n depth += 1;\n }\n } catch {\n /* keep leaf-only preview */\n }\n\n for (const channelName of Object.keys(value)) {\n const leafBody = this.getChannelBody(channelName);\n const parents = parentBodiesByChannel[channelName] ?? [];\n next[channelName] = composeTextTemplateBodyChain([leafBody, ...parents]);\n }\n this.composedPreviewBodies.set(next);\n await this.resolvePreviewVariables();\n }\n\n /** Get preview value for variable: expression/token first, then sampleValue */\n private getPreviewValue(varName: string): string {\n const resolved = this.resolvedPreviewValues()[varName];\n if (resolved !== undefined && resolved !== '') return resolved;\n const v = this.availableVariables().find((x) => x.name === varName);\n return v?.sampleValue ?? `{{${varName}}}`;\n }\n\n /**\n * Merge map for interpolating `{{ path }}` in `text`.\n * When `escapeMergeValuesForHtml` is true, substitution values are escaped for safe `innerHTML` fragments.\n */\n private previewMergeFor(text: string, escapeMergeValuesForHtml: boolean): Record<string, string> {\n const out: Record<string, string> = {};\n for (const name of collectTextTemplatePlaceholderNames(text)) {\n let v = this.getPreviewValue(name);\n if (escapeMergeValuesForHtml) {\n v = v.replace(/</g, '&lt;').replace(/>/g, '&gt;');\n }\n out[name] = v;\n }\n return out;\n }\n\n protected previewSubject(channelName: string): string {\n const server = this.serverPreviewByChannel()[channelName];\n if (server?.subject != null) {\n return server.subject;\n }\n return this.previewText(this.getChannelSubject(channelName));\n }\n\n protected previewText(text: string): string {\n return replaceTextTemplatePlaceholders(text, this.previewMergeFor(text, false));\n }\n\n /**\n * Email/rich preview must bypass Angular's default innerHTML sanitizer;\n * otherwise inline `style` (colors, gradients, header bar) is stripped and\n * the preview diverges from the real sent email.\n */\n protected previewBodyHtml(channelName: string): SafeHtml | string {\n const ch = this.availableChannels().find((c) => c.name === channelName);\n const server = this.serverPreviewByChannel()[channelName];\n if (server?.body != null) {\n if (ch?.type === 'rich') {\n return this.sanitizer.bypassSecurityTrustHtml(server.body);\n }\n return server.body\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\\n/g, '<br/>');\n }\n\n const composed = this.composedPreviewBodies()[channelName];\n const body = composed ?? this.getChannelBody(channelName);\n // Local fallback: do not escape data for rich HTML (logo mark / styled shells).\n const merged = renderTextTemplateSource(\n body,\n this.previewMergeFor(body, ch?.type !== 'rich'),\n );\n if (ch?.type === 'rich') {\n return this.sanitizer.bypassSecurityTrustHtml(merged);\n }\n return merged\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\\n/g, '<br/>');\n }\n}\n","<!-- Template Content Editor: Channel tabs and content per channel -->\n<div class=\"flex flex-col gap-4 w-full\">\n <!-- Channel tabs navigation -->\n <div class=\"flex items-center gap-2 flex-wrap\">\n <ax-tabs\n [look]=\"'with-line'\"\n (onActiveTabChanged)=\"onChannelTabChanged($event.index)\"\n class=\"flex-1 min-w-0\"\n >\n @for (ch of availableChannels(); track ch.name; let i = $index) {\n <ax-tab-item\n [text]=\"(ch.title | translate | async) ?? ch.name\"\n [key]=\"i.toString()\"\n [active]=\"activeTabIndex() === i\"\n ></ax-tab-item>\n }\n </ax-tabs>\n </div>\n\n @if (activeChannel(); as ch) {\n <!-- Channel content area: Edit mode or Preview mode -->\n <div class=\"mb-4 p-4\">\n @if (!isChannelConfigured(ch.name) && ch.notConfiguredMessageKey) {\n <div\n class=\"mb-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 p-3 rounded border border-amber-300 bg-amber-50 dark:border-amber-700 dark:bg-amber-950/30\"\n >\n <p class=\"text-sm text-amber-900 dark:text-amber-100\">\n {{ ch.notConfiguredMessageKey | translate | async }}\n </p>\n @if (ch.configureSettings) {\n <ax-button\n [text]=\"\n '@content-management:templates.actions.configure-channel'\n | translate\n | async\n \"\n look=\"outline\"\n color=\"primary\"\n size=\"sm\"\n (onClick)=\"openChannelConfigure(ch)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-gear\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n </div>\n }\n\n @if (viewMode() === 'edit') {\n <!-- Edit mode: Subject field (for channels that support it, e.g. Email) -->\n @if (ch.hasSubject) {\n <div class=\"mb-3\">\n <label class=\"block text-sm mb-1\">\n {{\n '@content-management:templates.entities.text-template.fields.subject.title'\n | translate\n | async\n }}\n </label>\n <ax-text-box\n [ngModel]=\"getChannelSubject(ch.name)\"\n (onValueChanged)=\"handleSubjectChange(ch.name, $event)\"\n [placeholder]=\"\n ('@content-management:templates.entities.text-template.fields.subject.placeholder'\n | translate\n | async)!\n \"\n ></ax-text-box>\n </div>\n }\n\n <!-- Edit mode: Body field (plain text or rich text-editor) -->\n <div>\n <label class=\"block text-sm mb-1\">\n {{\n '@content-management:templates.entities.text-template.fields.body.title'\n | translate\n | async\n }}\n </label>\n <!--->\n <!-- ----- Plain-text body for SMS-style channels ----- -->\n @if (ch.type === 'plain') {\n <ax-text-area\n #bodyTextarea\n [ngModel]=\"getChannelBody(ch.name)\"\n (onValueChanged)=\"handlePlainBodyChange(ch.name, $event)\"\n [rows]=\"8\"\n [placeholder]=\"\n ('@content-management:templates.entities.text-template.fields.body-placeholder.plain'\n | translate\n | async)!\n \"\n ></ax-text-area>\n }\n <!-- ----- Recreate the rich editor per channel so tab switches do not keep the previous HTML ----- -->\n @else {\n @for (channelName of [ch.name]; track channelName) {\n <ax-text-editor\n #editorRef\n outputFormat=\"html\"\n [placeHolder]=\"\n ('@content-management:templates.entities.text-template.fields.body-placeholder.rich'\n | translate\n | async)!\n \"\n [ngModel]=\"getChannelBody(channelName)\"\n (onValueChanged)=\"handleEditorChange(channelName, $event)\"\n [look]=\"'solid'\"\n [initialLine]=\"8\"\n >\n <ax-text-editor-content [style.min-height.px]=\"200\"></ax-text-editor-content>\n <ax-text-editor-toolbar>\n <ax-prefix>\n <ax-text-editor-history></ax-text-editor-history>\n <ax-text-editor-font-style></ax-text-editor-font-style>\n <ax-text-editor-list></ax-text-editor-list>\n </ax-prefix>\n </ax-text-editor-toolbar>\n </ax-text-editor>\n }\n }\n </div>\n } @else {\n <!-- Preview mode: Rendered content with variable placeholders replaced by sample values -->\n <div class=\"space-y-2\">\n @if (ch.hasSubject && previewSubject(ch.name)) {\n <div>\n <span class=\"text-xs text-gray-500\"\n >{{\n '@content-management:templates.entities.text-template.fields.subject.title'\n | translate\n | async\n }}:\n </span>\n <span class=\"text-sm\">{{ previewSubject(ch.name) }}</span>\n </div>\n }\n <!-- ----- Rich email keeps inline styles; plain channels use pre-wrap ----- -->\n <div\n class=\"text-sm p-3 bg-gray-100 dark:bg-gray-900 rounded border overflow-auto\"\n [class.whitespace-pre-wrap]=\"ch.type !== 'rich'\"\n [innerHTML]=\"previewBodyHtml(ch.name)\"\n ></div>\n </div>\n }\n </div>\n\n <!-- Footer: Action buttons (left) + Edit/Preview toggle (right) in single row -->\n <div\n class=\"flex flex-nowrap items-center justify-between gap-3 pt-3 mt-1 border-t border-gray-200 dark:border-gray-700\"\n >\n <div class=\"flex flex-nowrap items-center gap-2 min-w-0\">\n @if (viewMode() === 'edit') {\n <!-- ----- Insert variable dropdown from platform tokens ----- -->\n <div data-insert-var-trigger>\n <ax-button\n [text]=\"\n '@content-management:templates.actions.insert-variable'\n | translate\n | async\n \"\n look=\"twotone\"\n color=\"default\"\n size=\"sm\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-code\"></ax-icon>\n </ax-prefix>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (v of availableVariables(); track v.name) {\n <ax-button-item\n look=\"blank\"\n color=\"default\"\n [text]=\"(v.title || v.name) + ' ({{' + v.name + '}})'\"\n (onClick)=\"insertVariable(ch.name, v.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"getVariableIcon(v)\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n <ax-suffix>\n <ax-icon icon=\"fa-light fa-chevron-down\"></ax-icon>\n </ax-suffix>\n </ax-button>\n </div>\n <!--->\n <!-- ----- Insert reserved [content] slot for master templates ----- -->\n @if (isMasterKind()) {\n <div data-insert-var-trigger>\n <ax-button\n [text]=\"\n '@content-management:templates.actions.insert-content-slot'\n | translate\n | async\n \"\n look=\"twotone\"\n color=\"default\"\n size=\"sm\"\n (onClick)=\"insertContentSlot(ch.name)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-layer-group\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n }\n <!--->\n <!-- ----- Copy subject/body from another channel ----- -->\n @if (otherChannelsWithContent(ch.name).length > 0) {\n <ax-button\n [text]=\"\n '@content-management:templates.actions.copy-from'\n | translate\n | async\n \"\n look=\"twotone\"\n color=\"default\"\n size=\"sm\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-copy\"></ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-icon icon=\"fa-light fa-chevron-down\"></ax-icon>\n </ax-suffix>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (\n src of otherChannelsWithContent(ch.name);\n track src.name\n ) {\n <ax-button-item\n look=\"blank\"\n color=\"default\"\n [text]=\"(src.title | translate | async) ?? src.name\"\n (onClick)=\"copyFromChannel(ch.name, src.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"getChannelIcon(src)\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n }\n </div>\n <div>\n <ax-tabs [look]=\"'default'\">\n <ax-tab-item\n [text]=\"\n ('@content-management:templates.actions.edit'\n | translate\n | async) ?? 'Edit'\n \"\n [active]=\"viewMode() === 'edit'\"\n (onClick)=\"viewMode.set('edit')\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-pen\" class=\"text-current\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n <ax-tab-item\n [text]=\"\n ('@content-management:templates.actions.preview'\n | translate\n | async) ?? 'Preview'\n \"\n [active]=\"viewMode() === 'preview'\"\n (onClick)=\"viewMode.set('preview')\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-eye\" class=\"text-current\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n </ax-tabs>\n </div>\n </div>\n }\n</div>\n"],"names":["i9","i10"],"mappings":"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"}
@@ -58,7 +58,7 @@ const AXMTemplateContentEditorWidget = {
58
58
  component: () => import('./acorex-platform-module-content-management-client-template-content-editor-widget-view.component-CfupUZTI.mjs').then((c) => c.AXMTemplateContentEditorWidgetViewComponent),
59
59
  },
60
60
  edit: {
61
- component: () => import('./acorex-platform-module-content-management-client-template-content-editor-widget-edit.component-CphFsFSd.mjs').then((c) => c.AXMTemplateContentEditorWidgetEditComponent),
61
+ component: () => import('./acorex-platform-module-content-management-client-template-content-editor-widget-edit.component-h5ING7pF.mjs').then((c) => c.AXMTemplateContentEditorWidgetEditComponent),
62
62
  },
63
63
  },
64
64
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acorex-platform/module-content-management-client",
3
- "version": "0.0.56",
3
+ "version": "0.0.58",
4
4
  "sideEffects": false,
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0 || ^22.0.0",
@@ -1 +0,0 @@
1
- {"version":3,"file":"acorex-platform-module-content-management-client-template-content-editor-widget-edit.component-CphFsFSd.mjs","sources":["../../../../libs/modules/content-management/client/src/lib/features/template-content-editor/template-content-editor-widget-edit.component.ts","../../../../libs/modules/content-management/client/src/lib/features/template-content-editor/template-content-editor-widget-edit.component.html"],"sourcesContent":["import { AXButtonModule } from '@acorex/components/button';\nimport { AXDecoratorModule } from '@acorex/components/decorators';\nimport { AXDropdownModule } from '@acorex/components/dropdown';\nimport { AXFormModule } from '@acorex/components/form';\nimport { AXTabsModule } from '@acorex/components/tabs';\nimport { AXTextAreaModule } from '@acorex/components/text-area';\nimport { AXTextBoxModule } from '@acorex/components/text-box';\nimport { AXToastService } from '@acorex/components/toast';\nimport {\n AXWysiwygContainerComponent,\n AXWysiwygModule,\n} from '@acorex/components/wysiwyg';\nimport { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';\nimport { AXValidationModule } from '@acorex/core/validation';\nimport { AXPSettingsService, AXPTokenDefinitionService } from '@acorex-platform/framework-client/common';\nimport { AXPEntityService } from '@acorex-platform/framework-client/layout/entity';\nimport { AXPValueWidgetComponent } from '@acorex-platform/framework-client/layout/widget-core';\nimport { AXPCommandExecutor } from '@acorex-platform/framework-client/runtime';\nimport { CommonModule } from '@angular/common';\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n ElementRef,\n effect,\n inject,\n OnInit,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { DomSanitizer, type SafeHtml } from '@angular/platform-browser';\nimport { FormsModule } from '@angular/forms';\nimport { AXValueChangedEvent } from '@acorex/cdk/common';\nimport {\n AXPContextState,\n AXPPlatformScope,\n isFormValueEqual,\n runtimeCommandPayloadData,\n type AXPMultiLanguageString,\n} from '@acorex-platform/framework-shared/core';\nimport {\n AXM_TEXT_TEMPLATE_PREVIEW_COMMAND_KEY,\n RootConfig,\n type AXMTextTemplatePreviewRequest,\n type AXMTextTemplatePreviewResult,\n} from '@acorex-platform/module-content-management-client/contracts';\nimport { AXP_TEXT_TEMPLATE_CHANNEL_DEFINITION_PROVIDER } from './channel-definition.provider';\nimport {\n AXMTextTemplateChannelDefinition,\n AXMTextTemplateChannelsValue,\n} from './channel-definition.types';\nimport {\n AXM_TEXT_TEMPLATE_CONTENT_SLOT,\n AXM_TEXT_TEMPLATE_KIND,\n AXM_TEXT_TEMPLATE_MAX_PARENT_DEPTH,\n collectTextTemplatePlaceholderNames,\n composeTextTemplateBodyChain,\n renderTextTemplateSource,\n replaceTextTemplatePlaceholders,\n resolveTextTemplateLocalizedString,\n type AXMTextTemplateEntityModel,\n} from './text-template-placeholder.util';\n\n/** Variable definition from PlatformManagement.Tokens for template preview and Insert variable */\ninterface TemplateVariable {\n name: string;\n title: string;\n sampleValue?: string;\n kind?: string;\n dataType?: string;\n}\n\n@Component({\n selector: 'axm-template-content-editor-widget-edit',\n templateUrl: './template-content-editor-widget-edit.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n CommonModule,\n AXDecoratorModule,\n FormsModule,\n AXFormModule,\n AXTabsModule,\n AXTextAreaModule,\n AXTextBoxModule,\n AXWysiwygModule,\n AXValidationModule,\n AXTranslationModule,\n AXButtonModule,\n AXDropdownModule,\n ],\n})\nexport class AXMTemplateContentEditorWidgetEditComponent\n extends AXPValueWidgetComponent<AXMTextTemplateChannelsValue | null>\n implements OnInit, AfterViewInit\n{\n /** Stored cursor/selection state before Insert Variable dropdown opens */\n private storedCursor: {\n channelName: string;\n isPlain: boolean;\n selectionStart?: number;\n selectionEnd?: number;\n range?: Range;\n } | null = null;\n private readonly channelProviders = inject(AXP_TEXT_TEMPLATE_CHANNEL_DEFINITION_PROVIDER, {\n optional: true,\n });\n private readonly settingsService = inject(AXPSettingsService);\n private readonly translationService = inject(AXTranslationService);\n private readonly entityService = inject(AXPEntityService);\n private readonly tokenDefinitionService = inject(AXPTokenDefinitionService, { optional: true });\n private readonly commandExecutor = inject(AXPCommandExecutor);\n private readonly toastService = inject(AXToastService);\n private readonly sanitizer = inject(DomSanitizer);\n private readonly destroyRef = inject(DestroyRef);\n private readonly hostRef = inject(ElementRef<HTMLElement>);\n\n /** Dedupes in-flight preview loads when effect re-runs. */\n private previewRequestSeq = 0;\n\n /**\n * Quill `text-change` is debounced (~300ms) and `commitValue(html, true)` marks\n * hydration as a user edit. Ignore writes until that timer elapses after a programmatic sync.\n */\n private suppressWysiwygWrites = false;\n private suppressWysiwygWritesTimer: ReturnType<typeof setTimeout> | null = null;\n\n private lastSyncedChannel: string | null = null;\n private lastSyncedViewMode: 'edit' | 'preview' | null = null;\n private lastSyncedWysiwyg: AXWysiwygContainerComponent | undefined;\n /** Drops the ax-tabs init event so it cannot overwrite the content-channel tab. */\n private ignoreNextChannelTabChange = false;\n\n protected wysiwygRef = viewChild<AXWysiwygContainerComponent>('wysiwygRef');\n protected bodyTextareaRef = viewChild('bodyTextarea', { read: ElementRef<HTMLElement> });\n\n protected availableChannels = signal<AXMTextTemplateChannelDefinition[]>([]);\n protected channelConfigured = signal<Record<string, boolean>>({});\n protected availableVariables = signal<TemplateVariable[]>([]);\n protected activeTabIndex = signal<number>(0);\n protected viewMode = signal<'edit' | 'preview'>('edit');\n\n /** Resolved values for local preview fallback: expression/token evaluation, then sampleValue */\n protected resolvedPreviewValues = signal<Record<string, string>>({});\n\n /** Parent-chain bodies (leaf → root) for the active locale, keyed by channel (local fallback). */\n protected composedPreviewBodies = signal<Record<string, string>>({});\n\n /** Server Preview results keyed by channel (preferred over local compose). */\n protected serverPreviewByChannel = signal<\n Record<string, { subject?: string; body: string }>\n >({});\n\n protected activeChannel = computed(() => {\n const idx = this.activeTabIndex();\n const chs = this.availableChannels();\n return chs[idx] ?? null;\n });\n\n /** True when the host entity form has Kind = Master. */\n protected isMasterKind = computed(() => {\n this.contextService.changeEvent();\n const kind = this.contextService.getValue('kind');\n return kind === AXM_TEXT_TEMPLATE_KIND.Master;\n });\n\n protected otherChannelsWithContent = (currentName: string) =>\n this.availableChannels().filter(\n (c) => c.name !== currentName && (this.getChannelBody(c.name) || (c.hasSubject && this.getChannelSubject(c.name)))\n );\n\n /** Returns icon class for a variable/token based on kind and dataType */\n protected getVariableIcon(v: TemplateVariable): string {\n const kindMap: Record<string, string> = {\n Static: 'fa-light fa-database',\n Context: 'fa-light fa-layer-group',\n Event: 'fa-light fa-bolt',\n Computed: 'fa-light fa-calculator',\n Secret: 'fa-light fa-key',\n };\n const dataTypeMap: Record<string, string> = {\n String: 'fa-light fa-font',\n Integer: 'fa-light fa-hashtag',\n Boolean: 'fa-light fa-toggle-on',\n Decimal: 'fa-light fa-calculator',\n DateTime: 'fa-light fa-clock',\n Json: 'fa-light fa-braces',\n };\n const byKind = v.kind && kindMap[v.kind];\n if (byKind) return byKind;\n const byDataType = v.dataType && dataTypeMap[v.dataType];\n if (byDataType) return byDataType;\n return 'fa-light fa-code';\n }\n\n /** Returns icon class for a channel based on name and type */\n protected getChannelIcon(ch: AXMTextTemplateChannelDefinition): string {\n const nameMap: Record<string, string> = {\n email: 'fa-light fa-envelope',\n sms: 'fa-light fa-comment-sms',\n whatsapp: 'fa-brands fa-whatsapp',\n push: 'fa-light fa-bell',\n telegram: 'fa-brands fa-telegram',\n 'in-app': 'fa-light fa-inbox',\n };\n const byName = nameMap[ch.name?.toLowerCase() ?? ''];\n if (byName) return byName;\n return ch.type === 'rich' ? 'fa-light fa-file-lines' : 'fa-light fa-align-left';\n }\n\n private getTemplateLocale(): string {\n return this.translationService.getActiveLang() ?? 'en-US';\n }\n\n /**\n * Builds a mutable locale map from a stored channel field (string legacy or ML object).\n */\n private normalizeChannelFieldToMl(\n existing: AXPMultiLanguageString | string | undefined,\n ): Record<string, string> {\n if (existing == null || existing === '') {\n return {};\n }\n if (typeof existing === 'string') {\n const s = existing;\n return { 'en-US': s, 'fa-IR': s };\n }\n return { ...(existing as Record<string, string>) };\n }\n\n constructor() {\n super();\n effect(() => {\n this.viewMode();\n this.activeTabIndex();\n this.getValue();\n this.contextService.changeEvent();\n if (this.viewMode() === 'preview') {\n void this.loadServerPreview();\n } else {\n this.previewRequestSeq += 1;\n this.resolvedPreviewValues.set({});\n this.composedPreviewBodies.set({});\n this.serverPreviewByChannel.set({});\n }\n });\n\n /**\n * Quill keeps its own DOM; one-way ngModel does not refresh it when the entity\n * loads, the user discards, or the active channel tab changes.\n */\n effect(() => {\n const viewMode = this.viewMode();\n const channel = this.activeChannel();\n const changeState = this.contextService.changeEvent().state;\n const body = channel ? this.getChannelBody(channel.name) : '';\n const editor = this.wysiwygRef();\n\n if (viewMode !== 'edit' || !channel || channel.type === 'plain' || !editor) {\n this.lastSyncedViewMode = viewMode;\n return;\n }\n\n const channelChanged = channel.name !== this.lastSyncedChannel;\n const viewModeChanged = viewMode !== this.lastSyncedViewMode;\n const editorChanged = editor !== this.lastSyncedWysiwyg;\n const contextReload = this.shouldSyncWysiwygFromContext(changeState);\n\n if (!channelChanged && !viewModeChanged && !editorChanged && !contextReload) {\n return;\n }\n\n untracked(() => {\n this.lastSyncedChannel = channel.name;\n this.lastSyncedViewMode = viewMode;\n this.lastSyncedWysiwyg = editor;\n void this.applyWysiwygContentWhenReady(editor, body);\n });\n });\n\n this.settingsService.onChanged.subscribe(() => {\n void this.refreshChannelConfiguration();\n });\n\n this.destroyRef.onDestroy(() => this.clearSuppressWysiwygWritesTimer());\n }\n\n protected isChannelConfigured(name: string): boolean {\n return this.channelConfigured()[name] ?? true;\n }\n\n protected async openChannelConfigure(channel: AXMTextTemplateChannelDefinition): Promise<void> {\n const configure = channel.configureSettings;\n if (!configure) {\n return;\n }\n\n const saved = await this.settingsService.showSectionPopup({\n scope: configure.scope,\n section: configure.section,\n group: configure.group,\n });\n if (saved) {\n await this.refreshChannelConfiguration();\n }\n }\n\n private async refreshChannelConfiguration(): Promise<void> {\n const channels = this.availableChannels();\n const next: Record<string, boolean> = {};\n for (const channel of channels) {\n next[channel.name] = await this.isChannelConfiguredInternal(channel);\n }\n this.channelConfigured.set(next);\n }\n\n private async isChannelConfiguredInternal(channel: AXMTextTemplateChannelDefinition): Promise<boolean> {\n const requiredKeys = channel.requiredSettingKeys ?? [];\n if (!requiredKeys.length) {\n return true;\n }\n const scopeKey = channel.configureSettings?.scope ?? 'T';\n const scoped = this.settingsService.scope(scopeKey as AXPPlatformScope);\n for (const key of requiredKeys) {\n const value = await scoped.get(key);\n if (!this.hasNonEmptySettingValue(value)) {\n return false;\n }\n }\n return true;\n }\n\n private hasNonEmptySettingValue(value: unknown): boolean {\n if (value == null) {\n return false;\n }\n if (typeof value === 'string') {\n return value.trim().length > 0;\n }\n if (typeof value === 'number') {\n return Number.isFinite(value);\n }\n if (typeof value === 'boolean') {\n return true;\n }\n if (typeof value === 'object' && 'value' in value) {\n return this.hasNonEmptySettingValue((value as { value?: unknown }).value);\n }\n return String(value).trim().length > 0;\n }\n\n ngAfterViewInit(): void {\n const el = this.hostRef.nativeElement;\n const handleMousedown = (e: MouseEvent) => {\n const target = e.target as Node;\n if (!target || !el.contains(target)) return;\n const trigger = (target as Element).closest?.('[data-insert-var-trigger]');\n if (!trigger) return;\n this.captureCursorBeforeInsert();\n };\n el.addEventListener('mousedown', handleMousedown, { capture: true });\n this.destroyRef.onDestroy(() =>\n el.removeEventListener('mousedown', handleMousedown, { capture: true })\n );\n }\n\n override async ngOnInit(): Promise<void> {\n super.ngOnInit();\n const rawCh = this.channelProviders;\n const chProviders = rawCh == null ? [] : Array.isArray(rawCh) ? rawCh : [rawCh];\n const allChannels: AXMTextTemplateChannelDefinition[] = [];\n for (const p of chProviders) {\n if (p?.getChannels) allChannels.push(...p.getChannels());\n }\n this.availableChannels.set(\n Array.from(new Map(allChannels.map((c) => [c.name, c])).values())\n );\n await this.refreshChannelConfiguration();\n\n try {\n const tokensAccessor = this.entityService.withEntity('PlatformManagement', 'Tokens').data();\n const result = await tokensAccessor.query({ skip: 0, take: 500 });\n const items = (result.items ?? []) as Array<{\n name?: string;\n title?: string;\n sampleValue?: string;\n kind?: string;\n dataType?: string;\n }>;\n const vars: TemplateVariable[] = items\n .map((t) => ({\n name: String(t.name ?? ''),\n title: String(t.title ?? t.name ?? ''),\n sampleValue: t.sampleValue != null ? String(t.sampleValue) : undefined,\n kind: t.kind,\n dataType: t.dataType,\n }))\n .filter((v) => v.name);\n this.availableVariables.set(Array.from(new Map(vars.map((v) => [v.name, v])).values()));\n } catch {\n this.availableVariables.set([]);\n }\n\n const value = this.getValue();\n if (value && typeof value === 'object' && Object.keys(value).length > 0) {\n const names = Object.keys(value);\n const chs = this.availableChannels();\n const idx = chs.findIndex((c) => names.includes(c.name));\n if (idx >= 0) {\n this.ignoreNextChannelTabChange = true;\n this.beginSuppressWysiwygWrites();\n this.activeTabIndex.set(idx);\n setTimeout(() => {\n this.ignoreNextChannelTabChange = false;\n });\n }\n }\n }\n\n protected onChannelTabChanged(index: number): void {\n if (this.ignoreNextChannelTabChange || index === this.activeTabIndex()) {\n return;\n }\n this.beginSuppressWysiwygWrites();\n this.activeTabIndex.set(index);\n }\n\n /** Capture cursor/selection before dropdown opens (runs in mousedown capture phase) */\n private captureCursorBeforeInsert(): void {\n const ch = this.activeChannel();\n if (!ch) return;\n this.storedCursor = null;\n const active = document.activeElement as HTMLElement | null;\n if (!active) return;\n if (ch.type === 'plain') {\n const textarea = this.getTextareaElement(active);\n if (textarea) {\n this.storedCursor = {\n channelName: ch.name,\n isPlain: true,\n selectionStart: textarea.selectionStart,\n selectionEnd: textarea.selectionEnd,\n };\n }\n } else {\n const editable = this.getContentEditableElement(active);\n if (editable) {\n const sel = document.getSelection();\n if (sel && sel.rangeCount > 0) {\n const range = sel.getRangeAt(0).cloneRange();\n this.storedCursor = {\n channelName: ch.name,\n isPlain: false,\n range,\n };\n }\n }\n }\n }\n\n private getTextareaElement(el: HTMLElement): HTMLTextAreaElement | null {\n if (el instanceof HTMLTextAreaElement) return el;\n return el.querySelector?.('textarea') ?? null;\n }\n\n private getContentEditableElement(el: HTMLElement): HTMLElement | null {\n if (el.isContentEditable) return el;\n return el.closest?.('[contenteditable=\"true\"]') ?? null;\n }\n\n protected insertVariable(channelName: string, varName: string): void {\n this.insertToken(channelName, `{{${varName}}}`);\n }\n\n protected insertContentSlot(channelName: string): void {\n this.insertToken(channelName, AXM_TEXT_TEMPLATE_CONTENT_SLOT);\n }\n\n private insertToken(channelName: string, token: string): void {\n const current = this.getChannelBody(channelName);\n const stored = this.storedCursor;\n this.storedCursor = null;\n\n if (stored && stored.channelName === channelName) {\n if (stored.isPlain) {\n const start = stored.selectionStart ?? current.length;\n const end = stored.selectionEnd ?? start;\n const before = current.slice(0, start);\n const after = current.slice(end);\n const newBody = before + token + after;\n this.setChannelBody(channelName, newBody);\n const newCursor = start + token.length;\n queueMicrotask(() => this.restoreTextareaCursor(newCursor));\n } else if (stored.range) {\n try {\n const startNode = stored.range.startContainer;\n const elem = startNode.nodeType === Node.TEXT_NODE\n ? (startNode as Text).parentElement\n : (startNode as Element);\n const editable = elem?.closest?.('[contenteditable=\"true\"]') as HTMLElement | null;\n const wysiwyg = this.wysiwygRef();\n const target = editable ?? wysiwyg?.getHostElement()?.querySelector?.('[contenteditable=\"true\"]');\n if (target) {\n (target as HTMLElement).focus();\n const sel = document.getSelection();\n if (sel) {\n sel.removeAllRanges();\n sel.addRange(stored.range);\n document.execCommand('insertText', false, token);\n }\n } else {\n this.setChannelBody(channelName, current + token);\n }\n } catch {\n this.setChannelBody(channelName, current + token);\n }\n }\n } else {\n this.setChannelBody(channelName, current + token);\n }\n }\n\n private restoreTextareaCursor(position: number): void {\n const ref = this.bodyTextareaRef();\n const el = ref?.nativeElement;\n const textarea = el?.querySelector?.('textarea') ?? (el instanceof HTMLTextAreaElement ? el : null);\n if (textarea) {\n textarea.focus();\n textarea.setSelectionRange(position, position);\n }\n }\n\n protected copyFromChannel(targetName: string, sourceName: string): void {\n const ch = this.availableChannels().find((c) => c.name === sourceName);\n if (!ch) return;\n const hasSubject = ch.hasSubject;\n if (hasSubject) {\n this.setChannelSubject(targetName, this.getChannelSubject(sourceName));\n }\n this.setChannelBody(targetName, this.getChannelBody(sourceName));\n const active = this.activeChannel();\n if (active?.name === targetName && active.type === 'rich') {\n void this.applyWysiwygContentWhenReady(this.wysiwygRef(), this.getChannelBody(targetName));\n }\n }\n\n protected getChannelSubject(name: string): string {\n const v = this.getValue()?.[name];\n const raw =\n v && typeof v === 'object' && 'subject' in v ? (v as { subject?: AXPMultiLanguageString }).subject : undefined;\n return resolveTextTemplateLocalizedString(raw, this.getTemplateLocale());\n }\n\n protected handleSubjectChange(name: string, e: AXValueChangedEvent<string>): void {\n if (!e.isUserInteraction) {\n return;\n }\n this.setChannelSubject(name, e.value ?? '');\n }\n\n protected setChannelSubject(name: string, value: string): void {\n const nextText = value ?? '';\n if (this.getChannelSubject(name) === nextText) {\n return;\n }\n const current = this.getValue() || {};\n if (!current[name] && !nextText.trim()) {\n return;\n }\n const ch = current[name] || { body: '' };\n const locale = this.getTemplateLocale();\n const ml = this.normalizeChannelFieldToMl(ch.subject);\n ml[locale] = nextText;\n this.commitChannelValue(current, name, { ...ch, subject: ml });\n }\n\n protected getChannelBody(name: string): string {\n const v = this.getValue()?.[name];\n const raw =\n v && typeof v === 'object' && 'body' in v ? (v as { body?: AXPMultiLanguageString }).body : undefined;\n return resolveTextTemplateLocalizedString(raw, this.getTemplateLocale());\n }\n\n protected handlePlainBodyChange(name: string, e: AXValueChangedEvent<string>): void {\n if (!e.isUserInteraction) {\n return;\n }\n this.setChannelBody(name, e.value ?? '');\n }\n\n protected handleWysiwygChange(name: string, e: AXValueChangedEvent<string>): void {\n if (this.suppressWysiwygWrites || !e.isUserInteraction) {\n return;\n }\n const val =\n typeof e === 'object' && e !== null && 'value' in e\n ? ((e as { value: string | null }).value ?? '')\n : String(e ?? '');\n this.setChannelBody(name, val);\n }\n\n protected setChannelBody(name: string, value: string): void {\n const nextText = value ?? '';\n if (this.getChannelBody(name) === nextText) {\n return;\n }\n const current = this.getValue() || {};\n if (!current[name] && !nextText.trim()) {\n return;\n }\n const ch = current[name] || { body: '' };\n const locale = this.getTemplateLocale();\n const ml = this.normalizeChannelFieldToMl(ch.body);\n ml[locale] = nextText;\n this.commitChannelValue(current, name, { ...ch, body: ml });\n }\n\n private commitChannelValue(\n current: AXMTextTemplateChannelsValue,\n name: string,\n nextChannel: AXMTextTemplateChannelsValue[string],\n ): void {\n const nextValue = { ...current, [name]: nextChannel };\n if (isFormValueEqual(nextValue, current)) {\n return;\n }\n const path = this.fullPath();\n const saved = path ? this.contextService.getSavedValue(path) : undefined;\n if (saved !== undefined && isFormValueEqual(nextValue, saved)) {\n return;\n }\n this.setValue(nextValue);\n }\n\n private shouldSyncWysiwygFromContext(state: AXPContextState): boolean {\n return state === 'restored' || state === 'initiated';\n }\n\n private beginSuppressWysiwygWrites(): void {\n this.suppressWysiwygWrites = true;\n this.clearSuppressWysiwygWritesTimer();\n this.suppressWysiwygWritesTimer = setTimeout(() => {\n this.suppressWysiwygWrites = false;\n this.suppressWysiwygWritesTimer = null;\n }, 500);\n }\n\n private clearSuppressWysiwygWritesTimer(): void {\n if (this.suppressWysiwygWritesTimer) {\n clearTimeout(this.suppressWysiwygWritesTimer);\n this.suppressWysiwygWritesTimer = null;\n }\n }\n\n private async applyWysiwygContentWhenReady(\n wysiwyg: AXWysiwygContainerComponent | undefined,\n text: string,\n ): Promise<void> {\n const content = text ?? '';\n\n for (let attempt = 0; attempt < 30; attempt++) {\n const editor = this.wysiwygRef() ?? wysiwyg;\n if (!editor) {\n await new Promise((resolve) => setTimeout(resolve, 50));\n continue;\n }\n\n try {\n this.beginSuppressWysiwygWrites();\n editor.setWysiwygContent(content);\n return;\n } catch {\n await new Promise((resolve) => setTimeout(resolve, 50));\n }\n }\n }\n\n /**\n * Prefer server draft Preview (Context tokens + Event samples + parent composition).\n * Falls back to local compose when the command fails.\n */\n private async loadServerPreview(): Promise<void> {\n const requestSeq = ++this.previewRequestSeq;\n const value = this.getValue();\n const channel = this.activeChannel()?.name?.trim() || '';\n if (!value || typeof value !== 'object' || !channel) {\n this.serverPreviewByChannel.set({});\n this.composedPreviewBodies.set({});\n return;\n }\n\n const locale = this.getTemplateLocale();\n const parentIdRaw = this.contextService.getValue('parentId');\n const parentId = typeof parentIdRaw === 'string' ? parentIdRaw.trim() : '';\n const kindRaw = this.contextService.getValue('kind');\n const kind = typeof kindRaw === 'string' ? kindRaw.trim() : undefined;\n\n const request: AXMTextTemplatePreviewRequest = {\n channels: value,\n channel,\n locale,\n ...(parentId ? { parentId } : {}),\n ...(kind ? { kind } : {}),\n };\n\n try {\n const result = await this.commandExecutor.execute<\n AXMTextTemplatePreviewRequest,\n AXMTextTemplatePreviewResult\n >(AXM_TEXT_TEMPLATE_PREVIEW_COMMAND_KEY, request);\n\n if (requestSeq !== this.previewRequestSeq) {\n return;\n }\n\n const preview = runtimeCommandPayloadData(result);\n if (preview?.body != null) {\n this.serverPreviewByChannel.update((prev) => ({\n ...prev,\n [channel]: {\n ...(preview.subject != null ? { subject: preview.subject } : {}),\n body: preview.body,\n },\n }));\n return;\n }\n\n const message =\n typeof result?.message?.text === 'string' && result.message.text.trim()\n ? result.message.text.trim()\n : undefined;\n await this.fallbackToLocalPreview(channel, message);\n } catch (error) {\n if (requestSeq !== this.previewRequestSeq) {\n return;\n }\n const message = error instanceof Error ? error.message : undefined;\n await this.fallbackToLocalPreview(channel, message);\n }\n }\n\n private async fallbackToLocalPreview(channel: string, errorMessage?: string): Promise<void> {\n const title = await this.translationService.translateAsync(\n '@content-management:templates.messages.preview-failed.title',\n );\n const content = await this.translationService.translateAsync(\n '@content-management:templates.messages.preview-failed.content',\n );\n this.toastService.show({\n color: 'warning',\n title,\n content: errorMessage ? `${content} ${errorMessage}` : content,\n closeButton: true,\n timeOut: 5000,\n });\n\n this.serverPreviewByChannel.update((prev) => {\n const next = { ...prev };\n delete next[channel];\n return next;\n });\n await this.resolveComposedPreviewBodies();\n }\n\n /** Resolve variable values for local preview fallback */\n private async resolvePreviewVariables(): Promise<void> {\n const value = this.getValue();\n if (!value || typeof value !== 'object') return;\n const locale = this.getTemplateLocale();\n const parts: string[] = [];\n for (const v of Object.values(value)) {\n if (v != null && typeof v === 'object' && 'body' in v) {\n const o = v as { subject?: AXPMultiLanguageString; body?: AXPMultiLanguageString };\n parts.push(resolveTextTemplateLocalizedString(o.subject, locale));\n parts.push(resolveTextTemplateLocalizedString(o.body, locale));\n }\n }\n for (const body of Object.values(this.composedPreviewBodies())) {\n parts.push(body);\n }\n const allText = parts.join('');\n const varNames = collectTextTemplatePlaceholderNames(allText);\n if (varNames.length === 0) return;\n const vars = this.availableVariables();\n const resolved: Record<string, string> = {};\n const svc = this.tokenDefinitionService;\n for (const name of varNames) {\n try {\n if (svc) {\n const val = await svc.getValue(name);\n resolved[name] = val != null ? String(val) : '';\n }\n } catch {\n /* use fallback */\n }\n if (!(name in resolved) || !resolved[name]) {\n const v = vars.find((x) => x.name === name);\n if (v?.sampleValue != null) {\n resolved[name] = v.sampleValue;\n } else if (!(name in resolved)) {\n resolved[name] = '';\n }\n }\n }\n this.resolvedPreviewValues.update((prev) => ({ ...prev, ...resolved }));\n }\n\n /**\n * Local fallback: loads optional parent masters and stores leaf→root body chains per channel.\n */\n private async resolveComposedPreviewBodies(): Promise<void> {\n const value = this.getValue();\n if (!value || typeof value !== 'object') {\n this.composedPreviewBodies.set({});\n return;\n }\n\n const parentIdRaw = this.contextService.getValue('parentId');\n const parentId = typeof parentIdRaw === 'string' ? parentIdRaw.trim() : '';\n const locale = this.getTemplateLocale();\n const next: Record<string, string> = {};\n\n if (!parentId) {\n for (const channelName of Object.keys(value)) {\n next[channelName] = this.getChannelBody(channelName);\n }\n this.composedPreviewBodies.set(next);\n await this.resolvePreviewVariables();\n return;\n }\n\n const parentBodiesByChannel: Record<string, string[]> = {};\n try {\n const accessor = this.entityService\n .withEntity(RootConfig.module.name, RootConfig.entities.textTemplate.name)\n .data<\n string,\n AXMTextTemplateEntityModel,\n AXMTextTemplateEntityModel,\n AXMTextTemplateEntityModel,\n AXMTextTemplateEntityModel\n >();\n\n const visited = new Set<string>();\n const selfIdRaw = this.contextService.getValue('id');\n const selfId = typeof selfIdRaw === 'string' ? selfIdRaw.trim() : '';\n if (selfId) {\n visited.add(selfId);\n }\n\n let currentId: string | null = parentId;\n let depth = 1;\n while (currentId && depth <= AXM_TEXT_TEMPLATE_MAX_PARENT_DEPTH) {\n if (visited.has(currentId)) {\n break;\n }\n visited.add(currentId);\n const parent = await accessor.byKey(currentId);\n if (!parent?.channels) {\n break;\n }\n for (const [channelName, channelDef] of Object.entries(parent.channels)) {\n const body = resolveTextTemplateLocalizedString(channelDef?.body, locale);\n if (!body) continue;\n (parentBodiesByChannel[channelName] ??= []).push(body);\n }\n currentId = parent.parentId?.trim() || null;\n depth += 1;\n }\n } catch {\n /* keep leaf-only preview */\n }\n\n for (const channelName of Object.keys(value)) {\n const leafBody = this.getChannelBody(channelName);\n const parents = parentBodiesByChannel[channelName] ?? [];\n next[channelName] = composeTextTemplateBodyChain([leafBody, ...parents]);\n }\n this.composedPreviewBodies.set(next);\n await this.resolvePreviewVariables();\n }\n\n /** Get preview value for variable: expression/token first, then sampleValue */\n private getPreviewValue(varName: string): string {\n const resolved = this.resolvedPreviewValues()[varName];\n if (resolved !== undefined && resolved !== '') return resolved;\n const v = this.availableVariables().find((x) => x.name === varName);\n return v?.sampleValue ?? `{{${varName}}}`;\n }\n\n /**\n * Merge map for interpolating `{{ path }}` in `text`.\n * When `escapeMergeValuesForHtml` is true, substitution values are escaped for safe `innerHTML` fragments.\n */\n private previewMergeFor(text: string, escapeMergeValuesForHtml: boolean): Record<string, string> {\n const out: Record<string, string> = {};\n for (const name of collectTextTemplatePlaceholderNames(text)) {\n let v = this.getPreviewValue(name);\n if (escapeMergeValuesForHtml) {\n v = v.replace(/</g, '&lt;').replace(/>/g, '&gt;');\n }\n out[name] = v;\n }\n return out;\n }\n\n protected previewSubject(channelName: string): string {\n const server = this.serverPreviewByChannel()[channelName];\n if (server?.subject != null) {\n return server.subject;\n }\n return this.previewText(this.getChannelSubject(channelName));\n }\n\n protected previewText(text: string): string {\n return replaceTextTemplatePlaceholders(text, this.previewMergeFor(text, false));\n }\n\n /**\n * Email/rich preview must bypass Angular's default innerHTML sanitizer;\n * otherwise inline `style` (colors, gradients, header bar) is stripped and\n * the preview diverges from the real sent email.\n */\n protected previewBodyHtml(channelName: string): SafeHtml | string {\n const ch = this.availableChannels().find((c) => c.name === channelName);\n const server = this.serverPreviewByChannel()[channelName];\n if (server?.body != null) {\n if (ch?.type === 'rich') {\n return this.sanitizer.bypassSecurityTrustHtml(server.body);\n }\n return server.body\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\\n/g, '<br/>');\n }\n\n const composed = this.composedPreviewBodies()[channelName];\n const body = composed ?? this.getChannelBody(channelName);\n // Local fallback: do not escape data for rich HTML (logo mark / styled shells).\n const merged = renderTextTemplateSource(\n body,\n this.previewMergeFor(body, ch?.type !== 'rich'),\n );\n if (ch?.type === 'rich') {\n return this.sanitizer.bypassSecurityTrustHtml(merged);\n }\n return merged\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\\n/g, '<br/>');\n }\n}\n","<!-- Template Content Editor: Channel tabs and content per channel -->\n<div class=\"flex flex-col gap-4 w-full\">\n <!-- Channel tabs navigation -->\n <div class=\"flex items-center gap-2 flex-wrap\">\n <ax-tabs\n [look]=\"'with-line'\"\n (onActiveTabChanged)=\"onChannelTabChanged($event.index)\"\n class=\"flex-1 min-w-0\"\n >\n @for (ch of availableChannels(); track ch.name; let i = $index) {\n <ax-tab-item\n [text]=\"(ch.title | translate | async) ?? ch.name\"\n [key]=\"i.toString()\"\n [active]=\"activeTabIndex() === i\"\n ></ax-tab-item>\n }\n </ax-tabs>\n </div>\n\n @if (activeChannel(); as ch) {\n <!-- Channel content area: Edit mode or Preview mode -->\n <div class=\"mb-4 p-4\">\n @if (!isChannelConfigured(ch.name) && ch.notConfiguredMessageKey) {\n <div\n class=\"mb-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 p-3 rounded border border-amber-300 bg-amber-50 dark:border-amber-700 dark:bg-amber-950/30\"\n >\n <p class=\"text-sm text-amber-900 dark:text-amber-100\">\n {{ ch.notConfiguredMessageKey | translate | async }}\n </p>\n @if (ch.configureSettings) {\n <ax-button\n [text]=\"\n '@content-management:templates.actions.configure-channel'\n | translate\n | async\n \"\n look=\"outline\"\n color=\"primary\"\n size=\"sm\"\n (onClick)=\"openChannelConfigure(ch)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-gear\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n </div>\n }\n\n @if (viewMode() === 'edit') {\n <!-- Edit mode: Subject field (for channels that support it, e.g. Email) -->\n @if (ch.hasSubject) {\n <div class=\"mb-3\">\n <label class=\"block text-sm mb-1\">\n {{\n '@content-management:templates.entities.text-template.fields.subject.title'\n | translate\n | async\n }}\n </label>\n <ax-text-box\n [ngModel]=\"getChannelSubject(ch.name)\"\n (onValueChanged)=\"handleSubjectChange(ch.name, $event)\"\n [placeholder]=\"\n ('@content-management:templates.entities.text-template.fields.subject.placeholder'\n | translate\n | async)!\n \"\n ></ax-text-box>\n </div>\n }\n\n <!-- Edit mode: Body field (plain text or rich WYSIWYG) -->\n <div>\n <label class=\"block text-sm mb-1\">\n {{\n '@content-management:templates.entities.text-template.fields.body.title'\n | translate\n | async\n }}\n </label>\n <!--->\n <!-- ----- Plain-text body for SMS-style channels ----- -->\n @if (ch.type === 'plain') {\n <ax-text-area\n #bodyTextarea\n [ngModel]=\"getChannelBody(ch.name)\"\n (onValueChanged)=\"handlePlainBodyChange(ch.name, $event)\"\n [rows]=\"8\"\n [placeholder]=\"\n ('@content-management:templates.entities.text-template.fields.body-placeholder.plain'\n | translate\n | async)!\n \"\n ></ax-text-area>\n }\n <!-- ----- Recreate Quill per channel so tab switches do not keep the previous HTML ----- -->\n @else {\n @for (channelName of [ch.name]; track channelName) {\n <ax-wysiwyg-container\n #wysiwygRef\n [placeHolder]=\"\n ('@content-management:templates.entities.text-template.fields.body-placeholder.rich'\n | translate\n | async)!\n \"\n [ngModel]=\"getChannelBody(channelName)\"\n (onValueChanged)=\"handleWysiwygChange(channelName, $event)\"\n [look]=\"'solid'\"\n >\n <ax-wysiwyg-view [style.min-height.px]=\"200\"></ax-wysiwyg-view>\n <ax-wysiwyg-toolbar>\n <ax-prefix>\n <ax-wysiwyg-history></ax-wysiwyg-history>\n <ax-wysiwyg-font-style></ax-wysiwyg-font-style>\n <ax-wysiwyg-list></ax-wysiwyg-list>\n </ax-prefix>\n </ax-wysiwyg-toolbar>\n </ax-wysiwyg-container>\n }\n }\n </div>\n } @else {\n <!-- Preview mode: Rendered content with variable placeholders replaced by sample values -->\n <div class=\"space-y-2\">\n @if (ch.hasSubject && previewSubject(ch.name)) {\n <div>\n <span class=\"text-xs text-gray-500\"\n >{{\n '@content-management:templates.entities.text-template.fields.subject.title'\n | translate\n | async\n }}:\n </span>\n <span class=\"text-sm\">{{ previewSubject(ch.name) }}</span>\n </div>\n }\n <!-- ----- Rich email keeps inline styles; plain channels use pre-wrap ----- -->\n <div\n class=\"text-sm p-3 bg-gray-100 dark:bg-gray-900 rounded border overflow-auto\"\n [class.whitespace-pre-wrap]=\"ch.type !== 'rich'\"\n [innerHTML]=\"previewBodyHtml(ch.name)\"\n ></div>\n </div>\n }\n </div>\n\n <!-- Footer: Action buttons (left) + Edit/Preview toggle (right) in single row -->\n <div\n class=\"flex flex-nowrap items-center justify-between gap-3 pt-3 mt-1 border-t border-gray-200 dark:border-gray-700\"\n >\n <div class=\"flex flex-nowrap items-center gap-2 min-w-0\">\n @if (viewMode() === 'edit') {\n <!-- ----- Insert variable dropdown from platform tokens ----- -->\n <div data-insert-var-trigger>\n <ax-button\n [text]=\"\n '@content-management:templates.actions.insert-variable'\n | translate\n | async\n \"\n look=\"twotone\"\n color=\"default\"\n size=\"sm\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-code\"></ax-icon>\n </ax-prefix>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (v of availableVariables(); track v.name) {\n <ax-button-item\n look=\"blank\"\n color=\"default\"\n [text]=\"(v.title || v.name) + ' ({{' + v.name + '}})'\"\n (onClick)=\"insertVariable(ch.name, v.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"getVariableIcon(v)\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n <ax-suffix>\n <ax-icon icon=\"fa-light fa-chevron-down\"></ax-icon>\n </ax-suffix>\n </ax-button>\n </div>\n <!--->\n <!-- ----- Insert reserved [content] slot for master templates ----- -->\n @if (isMasterKind()) {\n <div data-insert-var-trigger>\n <ax-button\n [text]=\"\n '@content-management:templates.actions.insert-content-slot'\n | translate\n | async\n \"\n look=\"twotone\"\n color=\"default\"\n size=\"sm\"\n (onClick)=\"insertContentSlot(ch.name)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-layer-group\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n }\n <!--->\n <!-- ----- Copy subject/body from another channel ----- -->\n @if (otherChannelsWithContent(ch.name).length > 0) {\n <ax-button\n [text]=\"\n '@content-management:templates.actions.copy-from'\n | translate\n | async\n \"\n look=\"twotone\"\n color=\"default\"\n size=\"sm\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-copy\"></ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-icon icon=\"fa-light fa-chevron-down\"></ax-icon>\n </ax-suffix>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (\n src of otherChannelsWithContent(ch.name);\n track src.name\n ) {\n <ax-button-item\n look=\"blank\"\n color=\"default\"\n [text]=\"(src.title | translate | async) ?? src.name\"\n (onClick)=\"copyFromChannel(ch.name, src.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"getChannelIcon(src)\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n }\n </div>\n <div>\n <ax-tabs [look]=\"'default'\">\n <ax-tab-item\n [text]=\"\n ('@content-management:templates.actions.edit'\n | translate\n | async) ?? 'Edit'\n \"\n [active]=\"viewMode() === 'edit'\"\n (onClick)=\"viewMode.set('edit')\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-pen\" class=\"text-current\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n <ax-tab-item\n [text]=\"\n ('@content-management:templates.actions.preview'\n | translate\n | async) ?? 'Preview'\n \"\n [active]=\"viewMode() === 'preview'\"\n (onClick)=\"viewMode.set('preview')\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-eye\" class=\"text-current\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n </ax-tabs>\n </div>\n </div>\n }\n</div>\n"],"names":["i9","i10"],"mappings":"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"}