@dotcms/angular 0.0.1-beta.25 → 0.0.1-beta.27

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.
@@ -1,12 +1,15 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { inject, ViewContainerRef, TemplateRef, Directive, Input, Renderer2, ElementRef, SecurityContext, Component, ViewChild, HostListener, ChangeDetectionStrategy, computed, signal, Injectable, HostBinding } from '@angular/core';
3
- import { UVE_MODE, DotCMSUVEAction } from '@dotcms/types';
4
- import { getUVEState, sendMessageToUVE } from '@dotcms/uve';
3
+ import { UVE_MODE, DotCMSUVEAction, UVEEventType } from '@dotcms/types';
4
+ import { getUVEState, sendMessageToUVE, initUVE, createUVESubscription } from '@dotcms/uve';
5
5
  import { IMAGE_LOADER, NgComponentOutlet, AsyncPipe, NgTemplateOutlet, NgStyle } from '@angular/common';
6
6
  import { TINYMCE_SCRIPT_SRC, EditorComponent } from '@tinymce/tinymce-angular';
7
7
  import { DomSanitizer } from '@angular/platform-browser';
8
8
  import { __DOTCMS_UVE_EVENT__, BlockEditorDefaultBlocks } from '@dotcms/types/internal';
9
- import { isValidBlocks, PRODUCTION_MODE, DEVELOPMENT_MODE, EMPTY_CONTAINER_STYLE_ANGULAR, getDotContentletAttributes, CUSTOM_NO_COMPONENT, getDotContainerAttributes, getContainersData, getContentletsInContainer, getColumnPositionClasses, combineClasses } from '@dotcms/uve/internal';
9
+ import { __DEFAULT_TINYMCE_CONFIG__, __BASE_TINYMCE_CONFIG_WITH_NO_DEFAULT__, __TINYMCE_PATH_ON_DOTCMS__, isValidBlocks, PRODUCTION_MODE, DEVELOPMENT_MODE, EMPTY_CONTAINER_STYLE_ANGULAR, getDotContentletAttributes, CUSTOM_NO_COMPONENT, getDotContainerAttributes, getContainersData, getContentletsInContainer, getColumnPositionClasses, combineClasses } from '@dotcms/uve/internal';
10
+ import { Subject, of } from 'rxjs';
11
+ import { finalize } from 'rxjs/operators';
12
+ import { updateNavigation } from '@dotcms/client';
10
13
 
11
14
  /**
12
15
  * Directive to show a template when the UVE is in a specific mode.
@@ -127,45 +130,21 @@ function createDotCMSURL(config, path) {
127
130
  }
128
131
 
129
132
  const DEFAULT_TINYMCE_CONFIG = {
130
- menubar: false,
131
- inline: true,
132
- valid_styles: {
133
- '*': 'font-size,font-family,color,text-decoration,text-align'
134
- },
135
- powerpaste_word_import: 'clean',
136
- powerpaste_html_import: 'clean',
137
- suffix: '.min', // Suffix to use when loading resources
138
- license_key: 'gpl'
133
+ ...__DEFAULT_TINYMCE_CONFIG__,
134
+ license_key: 'gpl' // Using self-hosted license key
139
135
  };
140
136
  const TINYMCE_CONFIG = {
141
137
  minimal: {
142
138
  ...DEFAULT_TINYMCE_CONFIG,
143
- plugins: 'link autolink',
144
- toolbar: 'bold italic underline | link',
145
- valid_elements: 'strong,em,span[style],a[href]'
139
+ ...__BASE_TINYMCE_CONFIG_WITH_NO_DEFAULT__.minimal
146
140
  },
147
141
  full: {
148
142
  ...DEFAULT_TINYMCE_CONFIG,
149
- plugins: 'link lists autolink charmap',
150
- style_formats: [
151
- { title: 'Paragraph', format: 'p' },
152
- { title: 'Header 1', format: 'h1' },
153
- { title: 'Header 2', format: 'h2' },
154
- { title: 'Header 3', format: 'h3' },
155
- { title: 'Header 4', format: 'h4' },
156
- { title: 'Header 5', format: 'h5' },
157
- { title: 'Header 6', format: 'h6' },
158
- { title: 'Pre', format: 'pre' },
159
- { title: 'Code', format: 'code' }
160
- ],
161
- toolbar: [
162
- 'styleselect undo redo | bold italic underline | forecolor backcolor | alignleft aligncenter alignright alignfull | numlist bullist outdent indent | hr charmap removeformat | link'
163
- ]
143
+ ...__BASE_TINYMCE_CONFIG_WITH_NO_DEFAULT__.full
164
144
  },
165
145
  plain: {
166
146
  ...DEFAULT_TINYMCE_CONFIG,
167
- plugins: '',
168
- toolbar: ''
147
+ ...__BASE_TINYMCE_CONFIG_WITH_NO_DEFAULT__.plain
169
148
  }
170
149
  };
171
150
 
@@ -374,7 +353,7 @@ class DotCMSEditableTextComponent {
374
353
  provide: TINYMCE_SCRIPT_SRC,
375
354
  useFactory: () => {
376
355
  const { dotCMSHost } = getUVEState() || {};
377
- return `${dotCMSHost || ''}/ext/tinymcev7/tinymce.min.js`;
356
+ return `${dotCMSHost || ''}${__TINYMCE_PATH_ON_DOTCMS__}`;
378
357
  }
379
358
  }
380
359
  ], viewQueries: [{ propertyName: "editorComponent", first: true, predicate: EditorComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (isEditMode) {\n <editor\n #tinyEditor\n [init]=\"init\"\n [initialValue]=\"content\"\n (onMouseDown)=\"onMouseDown($event)\"\n (onFocusOut)=\"onFocusOut()\" />\n}\n", styles: [":host ::ng-deep .mce-content-body:not(.mce-edit-focus):hover{outline:2px solid #006ce7;border-radius:4px}\n"], dependencies: [{ kind: "component", type: EditorComponent, selector: "editor", inputs: ["cloudChannel", "apiKey", "init", "id", "initialValue", "outputFormat", "inline", "tagName", "plugins", "toolbar", "modelEvents", "allowedEvents", "ignoreEvents", "disabled"] }] }); }
@@ -386,7 +365,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImpor
386
365
  provide: TINYMCE_SCRIPT_SRC,
387
366
  useFactory: () => {
388
367
  const { dotCMSHost } = getUVEState() || {};
389
- return `${dotCMSHost || ''}/ext/tinymcev7/tinymce.min.js`;
368
+ return `${dotCMSHost || ''}${__TINYMCE_PATH_ON_DOTCMS__}`;
390
369
  }
391
370
  }
392
371
  ], template: "@if (isEditMode) {\n <editor\n #tinyEditor\n [init]=\"init\"\n [initialValue]=\"content\"\n (onMouseDown)=\"onMouseDown($event)\"\n (onFocusOut)=\"onFocusOut()\" />\n}\n", styles: [":host ::ng-deep .mce-content-body:not(.mce-edit-focus):hover{outline:2px solid #006ce7;border-radius:4px}\n"] }]
@@ -1296,7 +1275,7 @@ class ContentletComponent {
1296
1275
  const contentlet = this.$contentlet();
1297
1276
  if (!contentlet || !this.$isDevMode())
1298
1277
  return {};
1299
- return getDotContentletAttributes(contentlet, this.container);
1278
+ return getDotContentletAttributes(contentlet, this.containerData.identifier);
1300
1279
  });
1301
1280
  this.identifier = null;
1302
1281
  this.basetype = null;
@@ -1316,7 +1295,7 @@ class ContentletComponent {
1316
1295
  this.title = this.$dotAttributes()['data-dot-title'];
1317
1296
  this.inode = this.$dotAttributes()['data-dot-inode'];
1318
1297
  this.type = this.$dotAttributes()['data-dot-type'];
1319
- this.containerAttribute = this.$dotAttributes()['data-dot-container'];
1298
+ this.containerAttribute = JSON.stringify(this.containerData);
1320
1299
  this.onNumberOfPages = this.$dotAttributes()['data-dot-on-number-of-pages'];
1321
1300
  this.styleAttribute = this.$style();
1322
1301
  }
@@ -1340,7 +1319,7 @@ class ContentletComponent {
1340
1319
  }
1341
1320
  }
1342
1321
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ContentletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1343
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: ContentletComponent, isStandalone: true, selector: "dotcms-contentlet", inputs: { contentlet: "contentlet", container: "container" }, host: { properties: { "attr.data-dot-object": "this.dotObject", "attr.data-dot-identifier": "this.identifier", "attr.data-dot-basetype": "this.basetype", "attr.data-dot-title": "this.title", "attr.data-dot-inode": "this.inode", "attr.data-dot-type": "this.type", "attr.data-dot-container": "this.containerAttribute", "attr.data-dot-on-number-of-pages": "this.onNumberOfPages", "style": "this.styleAttribute" } }, viewQueries: [{ propertyName: "contentletRef", first: true, predicate: ["contentletRef"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
1322
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: ContentletComponent, isStandalone: true, selector: "dotcms-contentlet", inputs: { contentlet: "contentlet", containerData: "containerData" }, host: { properties: { "attr.data-dot-object": "this.dotObject", "attr.data-dot-identifier": "this.identifier", "attr.data-dot-basetype": "this.basetype", "attr.data-dot-title": "this.title", "attr.data-dot-inode": "this.inode", "attr.data-dot-type": "this.type", "attr.data-dot-container": "this.containerAttribute", "attr.data-dot-on-number-of-pages": "this.onNumberOfPages", "style": "this.styleAttribute" } }, viewQueries: [{ propertyName: "contentletRef", first: true, predicate: ["contentletRef"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
1344
1323
  @if ($UserComponent()) {
1345
1324
  <ng-container
1346
1325
  *ngComponentOutlet="
@@ -1378,7 +1357,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImpor
1378
1357
  }], propDecorators: { contentlet: [{
1379
1358
  type: Input,
1380
1359
  args: [{ required: true }]
1381
- }], container: [{
1360
+ }], containerData: [{
1382
1361
  type: Input,
1383
1362
  args: [{ required: true }]
1384
1363
  }], contentletRef: [{
@@ -1461,10 +1440,10 @@ class ContainerComponent {
1461
1440
  <dotcms-empty-container />
1462
1441
  } @else {
1463
1442
  @for (contentlet of $contentlets(); track contentlet.identifier) {
1464
- <dotcms-contentlet [contentlet]="contentlet" [container]="container.identifier" />
1443
+ <dotcms-contentlet [contentlet]="contentlet" [containerData]="$containerData()!" />
1465
1444
  }
1466
1445
  }
1467
- `, isInline: true, dependencies: [{ kind: "component", type: ContainerNotFoundComponent, selector: "dotcms-container-not-found", inputs: ["identifier"] }, { kind: "component", type: EmptyContainerComponent, selector: "dotcms-empty-container" }, { kind: "component", type: ContentletComponent, selector: "dotcms-contentlet", inputs: ["contentlet", "container"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1446
+ `, isInline: true, dependencies: [{ kind: "component", type: ContainerNotFoundComponent, selector: "dotcms-container-not-found", inputs: ["identifier"] }, { kind: "component", type: EmptyContainerComponent, selector: "dotcms-empty-container" }, { kind: "component", type: ContentletComponent, selector: "dotcms-contentlet", inputs: ["contentlet", "containerData"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1468
1447
  }
1469
1448
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ContainerComponent, decorators: [{
1470
1449
  type: Component,
@@ -1479,7 +1458,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImpor
1479
1458
  <dotcms-empty-container />
1480
1459
  } @else {
1481
1460
  @for (contentlet of $contentlets(); track contentlet.identifier) {
1482
- <dotcms-contentlet [contentlet]="contentlet" [container]="container.identifier" />
1461
+ <dotcms-contentlet [contentlet]="contentlet" [containerData]="$containerData()!" />
1483
1462
  }
1484
1463
  }
1485
1464
  `,
@@ -1652,9 +1631,91 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImpor
1652
1631
  type: Input
1653
1632
  }] } });
1654
1633
 
1634
+ class DotCMSEditablePageService {
1635
+ /**
1636
+ * Subject that emits the current editable page asset or null.
1637
+ * Used internally to track changes to the page data.
1638
+ *
1639
+ * @private
1640
+ * @type {Subject<DotCMSEditablePage | null>}
1641
+ */
1642
+ #pageAssetSubject = new Subject();
1643
+ /**
1644
+ * Observable stream of the page asset changes.
1645
+ * Exposes the pageAssetSubject as an Observable for subscribers.
1646
+ *
1647
+ * @private
1648
+ * @type {Observable<DotCMSEditablePage | null>}
1649
+ */
1650
+ #pageAsset$ = this.#pageAssetSubject.asObservable();
1651
+ /**
1652
+ * Listens for changes to an editable page and returns an Observable that emits the updated page data.
1653
+ * This method initializes the UVE (Universal Visual Editor) and sets up subscriptions to track content changes.
1654
+ *
1655
+ * @example
1656
+ * ```ts
1657
+ * // Import the service
1658
+ * import { DotCMSEditablePageService } from '@dotcms/angular';
1659
+ *
1660
+ * // Inject the service
1661
+ * constructor(private editablePageService: DotCMSEditablePageService) {}
1662
+ *
1663
+ * // Get the page data from your API call
1664
+ * const page = await client.page.get('/');
1665
+ *
1666
+ * // Listen for changes
1667
+ * const subscription = this.editablePageService.listen(page).subscribe(updatedPage => {
1668
+ * if (updatedPage) {
1669
+ * // Handle updated page data
1670
+ * console.log('Page updated:', updatedPage);
1671
+ * }
1672
+ * });
1673
+ *
1674
+ * // When done listening, unsubscribe
1675
+ * subscription.unsubscribe();
1676
+ * ```
1677
+ *
1678
+ * @param pageAsset Optional initial page data
1679
+ * @returns Observable that emits the updated page data or null
1680
+ */
1681
+ listen(pageAsset) {
1682
+ if (!getUVEState()) {
1683
+ return of(pageAsset || null);
1684
+ }
1685
+ const pageURI = pageAsset?.page?.pageURI ?? '/';
1686
+ initUVE(pageAsset);
1687
+ updateNavigation(pageURI);
1688
+ const unsubscribeUVEChanges = this.#listenUVEChanges();
1689
+ return this.#pageAsset$.pipe(finalize(() => {
1690
+ unsubscribeUVEChanges();
1691
+ }));
1692
+ }
1693
+ /**
1694
+ * Sets up a subscription to listen for UVE content changes and updates the page asset subject.
1695
+ * This is an internal method used by listenEditablePage() to handle UVE events.
1696
+ *
1697
+ * @returns {UVEUnsubscribeFunction} Function to unsubscribe from the UVE content changes
1698
+ * @private
1699
+ */
1700
+ #listenUVEChanges() {
1701
+ const { unsubscribe } = createUVESubscription(UVEEventType.CONTENT_CHANGES, (payload) => {
1702
+ this.#pageAssetSubject.next(payload);
1703
+ });
1704
+ return unsubscribe;
1705
+ }
1706
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSEditablePageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1707
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSEditablePageService, providedIn: 'root' }); }
1708
+ }
1709
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSEditablePageService, decorators: [{
1710
+ type: Injectable,
1711
+ args: [{
1712
+ providedIn: 'root'
1713
+ }]
1714
+ }] });
1715
+
1655
1716
  /**
1656
1717
  * Generated bundle index. Do not edit.
1657
1718
  */
1658
1719
 
1659
- export { DotCMSBlockEditorRendererComponent, DotCMSEditableTextComponent, DotCMSLayoutBodyComponent, DotCMSShowWhenDirective, provideDotCMSImageLoader };
1720
+ export { DotCMSBlockEditorRendererComponent, DotCMSEditablePageService, DotCMSEditableTextComponent, DotCMSLayoutBodyComponent, DotCMSShowWhenDirective, provideDotCMSImageLoader };
1660
1721
  //# sourceMappingURL=dotcms-angular-next.mjs.map