@firestitch/content 12.2.1 → 12.2.3

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.
Files changed (34) hide show
  1. package/app/interfaces/content-config.d.ts +5 -5
  2. package/app/interfaces/content-page.d.ts +1 -0
  3. package/app/interfaces/content-style.d.ts +4 -0
  4. package/app/interfaces/index.d.ts +2 -1
  5. package/app/modules/content/components/content/content.component.d.ts +7 -3
  6. package/app/modules/content/components/content-renderer/content-renderer.component.d.ts +11 -9
  7. package/app/modules/content-layouts/components/content-layouts/content-layouts.component.d.ts +3 -2
  8. package/app/modules/content-pages/components/content-pages/content-pages.component.d.ts +2 -0
  9. package/app/modules/content-style/components/content-style/content-style.component.d.ts +27 -0
  10. package/app/modules/content-style/components/content-style/index.d.ts +1 -0
  11. package/app/modules/content-style/fs-content-style.module.d.ts +14 -0
  12. package/app/modules/editor/components/editor/editor.component.d.ts +33 -22
  13. package/app/modules/editor/fs-content-editor.module.d.ts +8 -5
  14. package/bundles/firestitch-content.umd.js +635 -521
  15. package/bundles/firestitch-content.umd.js.map +1 -1
  16. package/esm2015/app/interfaces/content-config.js +1 -1
  17. package/esm2015/app/interfaces/content-page.js +1 -1
  18. package/esm2015/app/interfaces/content-style.js +2 -0
  19. package/esm2015/app/interfaces/index.js +3 -2
  20. package/esm2015/app/modules/content/components/content/content.component.js +35 -20
  21. package/esm2015/app/modules/content/components/content-renderer/content-renderer.component.js +21 -19
  22. package/esm2015/app/modules/content-layouts/components/content-layouts/content-layouts.component.js +22 -18
  23. package/esm2015/app/modules/content-pages/components/content-pages/content-pages.component.js +20 -11
  24. package/esm2015/app/modules/content-pages/fs-content-pages.module.js +1 -1
  25. package/esm2015/app/modules/content-style/components/content-style/content-style.component.js +71 -0
  26. package/esm2015/app/modules/content-style/components/content-style/index.js +2 -0
  27. package/esm2015/app/modules/content-style/fs-content-style.module.js +50 -0
  28. package/esm2015/app/modules/editor/components/editor/editor.component.js +78 -107
  29. package/esm2015/app/modules/editor/fs-content-editor.module.js +19 -7
  30. package/esm2015/public_api.js +5 -3
  31. package/fesm2015/firestitch-content.js +449 -339
  32. package/fesm2015/firestitch-content.js.map +1 -1
  33. package/package.json +6 -5
  34. package/public_api.d.ts +5 -3
@@ -1,232 +1,146 @@
1
- import * as i10 from '@angular/common';
1
+ import * as i10$1 from '@angular/common';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { InjectionToken, Component, ChangeDetectionStrategy, Inject, ViewChildren, ElementRef, ViewChild, NgModule, Input } from '@angular/core';
5
- import * as i9 from '@angular/forms';
4
+ import { Component, ChangeDetectionStrategy, Inject, NgModule, InjectionToken, ViewChildren, ViewChild, Input, ElementRef } from '@angular/core';
5
+ import * as i7$1 from '@angular/forms';
6
6
  import { FormsModule } from '@angular/forms';
7
- import * as i4$1 from '@angular/material/button';
7
+ import * as i4 from '@angular/material/button';
8
8
  import { MatButtonModule } from '@angular/material/button';
9
- import * as i9$1 from '@angular/material/button-toggle';
10
- import { MatButtonToggleModule } from '@angular/material/button-toggle';
11
9
  import * as i1 from '@angular/material/dialog';
12
10
  import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
13
- import * as i4 from '@angular/material/form-field';
11
+ import * as i4$1 from '@angular/material/form-field';
14
12
  import { MatFormFieldModule } from '@angular/material/form-field';
15
- import * as i5$1 from '@angular/material/icon';
16
- import { MatIconModule } from '@angular/material/icon';
17
- import * as i11 from '@angular/material/input';
13
+ import * as i8$1 from '@angular/material/input';
18
14
  import { MatInputModule } from '@angular/material/input';
19
- import * as i5 from '@angular/material/select';
20
- import { MatSelectModule } from '@angular/material/select';
21
15
  import { MatTabsModule } from '@angular/material/tabs';
22
16
  import * as i3$1 from '@firestitch/date';
23
17
  import { FsDateModule } from '@firestitch/date';
24
18
  import * as i3 from '@firestitch/dialog';
25
19
  import { FsDialogModule } from '@firestitch/dialog';
26
- import * as i7 from '@firestitch/form';
27
- import { FsFormDirective, FsFormModule } from '@firestitch/form';
20
+ import * as i5$1 from '@firestitch/form';
21
+ import { FsFormModule, FsFormDirective } from '@firestitch/form';
28
22
  import { FsHtmlEditorModule } from '@firestitch/html-editor';
29
- import * as i6$1 from '@firestitch/label';
30
- import { FsLabelModule } from '@firestitch/label';
31
23
  import * as i2$1 from '@firestitch/list';
32
24
  import { FsListModule, FsListComponent } from '@firestitch/list';
33
- import * as i8 from '@firestitch/skeleton';
25
+ import * as i8 from '@firestitch/text-editor';
26
+ import { FsTextEditorModule, FsTextEditorComponent } from '@firestitch/text-editor';
27
+ import * as i10 from '@angular/material/button-toggle';
28
+ import { MatButtonToggleModule } from '@angular/material/button-toggle';
29
+ import * as i5 from '@angular/material/icon';
30
+ import { MatIconModule } from '@angular/material/icon';
31
+ import * as i5$2 from '@angular/material/select';
32
+ import { MatSelectModule } from '@angular/material/select';
33
+ import * as i7 from '@firestitch/label';
34
+ import { FsLabelModule } from '@firestitch/label';
35
+ import * as i13 from '@firestitch/skeleton';
34
36
  import { FsSkeletonModule } from '@firestitch/skeleton';
35
- import * as i7$1 from '@firestitch/text-editor';
36
- import { FsTextEditorComponent, FsTextEditorModule } from '@firestitch/text-editor';
37
+ import * as i12 from '@firestitch/common';
38
+ import { FsCommonModule, index } from '@firestitch/common';
39
+ import * as i6 from 'angular-split';
40
+ import { AngularSplitModule } from 'angular-split';
37
41
  import * as i2 from '@firestitch/message';
38
- import { Subject, of, fromEvent } from 'rxjs';
39
- import { tap, switchMap, takeUntil, finalize, take, filter, map } from 'rxjs/operators';
40
- import * as i6 from '@angular/material/core';
41
- import { index } from '@firestitch/common';
42
+ import { Subject, of } from 'rxjs';
43
+ import { tap, takeUntil, switchMap, filter, map } from 'rxjs/operators';
42
44
  import { ItemType } from '@firestitch/filter';
45
+ import * as i6$1 from '@angular/material/core';
43
46
  import * as i1$1 from '@angular/platform-browser';
44
47
  import * as i2$2 from '@angular/router';
45
48
  import { NavigationEnd } from '@angular/router';
46
-
47
- var PageType;
48
- (function (PageType) {
49
- PageType["StandardPage"] = "standardPage";
50
- PageType["BlogPost"] = "blogPost";
51
- PageType["HomePage"] = "homePage";
52
- PageType["NotFoundPage"] = "notFoundPage";
53
- })(PageType || (PageType = {}));
54
-
55
- const PageTypes = [
56
- { name: 'Standard Page', value: PageType.StandardPage },
57
- { name: 'Home Page', value: PageType.HomePage },
58
- { name: 'Not Found Page', value: PageType.NotFoundPage },
59
- { name: 'Blog Post', value: PageType.BlogPost },
60
- ];
61
-
62
- const FS_CONTENT_CONFIG = new InjectionToken('fs-content-config');
63
-
64
- class ContentPageComponent {
65
- constructor(_config, _data, _dialogRef, _message, _cdRef) {
66
- this._config = _config;
67
- this._data = _data;
68
- this._dialogRef = _dialogRef;
69
- this._message = _message;
70
- this._cdRef = _cdRef;
71
- this.contentPage = null;
72
- this.PageTypes = PageTypes;
73
- this.editors = { content: true, styles: true };
74
- this._destroy$ = new Subject();
75
- this.save = () => {
76
- return this._config.saveContentPage(this.contentPage)
77
- .pipe(tap((contentPage) => {
78
- this._message.success('Saved Changes');
79
- this._dialogRef.close(contentPage);
80
- }));
81
- };
82
- }
83
- ngOnInit() {
84
- this._dialogRef.updateSize('600px');
85
- this._fetchData();
86
- }
87
- ngOnDestroy() {
88
- this._destroy$.next();
89
- this._destroy$.complete();
90
- }
91
- _fetchData() {
92
- this._config.loadContentLayouts()
93
- .subscribe((contentLayouts) => {
94
- this.contentLayouts = contentLayouts;
95
- this._cdRef.markForCheck();
96
- });
97
- of(this._data.contentPage)
98
- .pipe(switchMap((contentPage) => {
99
- return of(contentPage);
100
- }), takeUntil(this._destroy$))
101
- .subscribe((contentPage) => {
102
- this.contentPage = Object.assign({}, contentPage);
103
- this._cdRef.markForCheck();
104
- });
105
- }
106
- }
107
- ContentPageComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ContentPageComponent, deps: [{ token: FS_CONTENT_CONFIG }, { token: MAT_DIALOG_DATA }, { token: i1.MatDialogRef }, { token: i2.FsMessage }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
108
- ContentPageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: ContentPageComponent, selector: "ng-component", viewQueries: [{ propertyName: "textEditors", predicate: FsTextEditorComponent, descendants: true }], ngImport: i0, template: "<form fsForm [submit]=\"save\" *fsSkeletonForm=\"contentPage\">\n <fs-dialog>\n <h1 mat-dialog-title>{{contentPage.id ? 'Page' : 'Create Page'}}</h1>\n <div mat-dialog-content>\n <div class=\"fs-column\">\n <mat-form-field>\n <mat-select\n [(ngModel)]=\"contentPage.type\"\n name=\"type\"\n required\n placeholder=\"Type\">\n <mat-option\n *ngFor=\"let item of PageTypes\"\n [value]=\"item.value\">\n {{ item.name }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field *ngIf=\"contentLayouts\">\n <mat-select\n [(ngModel)]=\"contentPage.contentLayoutId\"\n required\n name=\"contentLayoutId\"\n placeholder=\"Layout\">\n <mat-option\n *ngFor=\"let item of contentLayouts\"\n [value]=\"item.id\">\n {{ item.name }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field>\n <input\n matInput\n [(ngModel)]=\"contentPage.name\"\n name=\"name\"\n required\n placeholder=\"Name\">\n </mat-form-field>\n <mat-form-field>\n <input\n matInput\n [(ngModel)]=\"contentPage.path\"\n name=\"path\"\n required\n placeholder=\"Path\">\n </mat-form-field>\n <mat-form-field>\n <input\n matInput\n [(ngModel)]=\"contentPage.title\"\n name=\"title\"\n placeholder=\"Title\">\n </mat-form-field>\n </div>\n </div>\n\n <div mat-dialog-actions>\n <fs-form-dialog-actions>\n </fs-form-dialog-actions>\n </div>\n </fs-dialog>\n</form>\n", styles: [""], components: [{ type: i3.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileActionPlacement", "mobileWidth", "mode"] }, { type: i4.MatFormField, selector: "mat-form-field", inputs: ["color", "floatLabel", "appearance", "hideRequiredMarker", "hintLabel"], exportAs: ["matFormField"] }, { type: i5.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i6.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { type: i7.FsFormDialogActionsComponent, selector: "fs-form-dialog-actions", inputs: ["save", "create", "close", "done", "closeData", "name"] }], directives: [{ type: i8.FsSkeletonFormDirective, selector: "[fsSkeletonForm]", inputs: ["fsSkeletonForm", "fsSkeletonFormLines"] }, { type: i9.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i9.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i9.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i7.FsFormDirective, selector: "[fsForm]", inputs: ["wrapperSelector", "messageSelector", "hintSelector", "labelSelector", "autocomplete", "shortcuts", "confirm", "confirmDialog", "confirmDrawer", "confirmBrowser", "confirmTabs", "dirtySubmitButton", "submit", "successDelay", "errorDelay", "tabGroup", "deactivationGuard"], outputs: ["fsForm", "invalid", "valid", "submitted", "reseted", "cleared"], exportAs: ["fsForm"] }, { type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i9.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i9.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i9.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i7.FsFormRequiredDirective, selector: "[fsFormRequired],[ngModel][required]", inputs: ["fsFormRequired", "required", "fsFormRequiredMessage"] }, { type: i10.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i10.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i11.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["id", "disabled", "required", "type", "value", "readonly", "placeholder", "errorStateMatcher", "aria-describedby"], exportAs: ["matInput"] }, { type: i9.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i7.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
109
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ContentPageComponent, decorators: [{
110
- type: Component,
111
- args: [{
112
- templateUrl: './content-page.component.html',
113
- styleUrls: ['./content-page.component.scss'],
114
- changeDetection: ChangeDetectionStrategy.OnPush,
115
- }]
116
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
117
- type: Inject,
118
- args: [FS_CONTENT_CONFIG]
119
- }] }, { type: undefined, decorators: [{
120
- type: Inject,
121
- args: [MAT_DIALOG_DATA]
122
- }] }, { type: i1.MatDialogRef }, { type: i2.FsMessage }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { textEditors: [{
123
- type: ViewChildren,
124
- args: [FsTextEditorComponent]
125
- }] } });
49
+ import * as i3$2 from '@firestitch/body';
126
50
 
127
51
  class EditorComponent {
128
- constructor(_data, _dialogRef, _dialog, _message, _cdRef) {
52
+ constructor(_data, _dialogRef, _message, _cdRef) {
129
53
  this._data = _data;
130
54
  this._dialogRef = _dialogRef;
131
- this._dialog = _dialog;
132
55
  this._message = _message;
133
56
  this._cdRef = _cdRef;
134
57
  this.resizing = false;
135
- this.editors = { content: true, styles: true };
136
- this._destroy$ = new Subject();
137
- this.save = () => {
138
- return this._config.saveContentPage({
139
- id: this.contentPage.id,
140
- styles: this.contentPage.styles,
141
- content: this.contentPage.content,
142
- })
143
- .pipe(tap((contentPage) => {
144
- this.contentPage = Object.assign(Object.assign({}, this.contentPage), contentPage);
145
- this._cdRef.markForCheck();
146
- this._message.success('Saved Changes');
147
- }));
58
+ this.editors = {
59
+ html: true,
60
+ scss: true,
61
+ js: false,
62
+ globalScss: false,
148
63
  };
64
+ this._destroy$ = new Subject();
149
65
  }
150
66
  ngOnInit() {
67
+ this._dialogRef.addPanelClass('fs-content-editor-overlay-pane');
68
+ this.title = this._data.title;
151
69
  this.contentPage = this._data.contentPage;
152
- this._config = this._data.config;
153
- this._initSeparator();
70
+ this._config = this._data.contentConfig;
71
+ this._save = this._data.save;
72
+ this.initTextEditors();
73
+ this.initGlobalContentStyle();
154
74
  }
155
75
  editorToggleChange(event) {
156
76
  this.editors[event.value] = !this.editors[event.value];
157
- this.updateEditorLayouts();
158
- }
159
- updateEditorLayouts() {
160
- setTimeout(() => {
161
- if (this.editors.content) {
162
- this.contentEditor.updateLayout();
163
- }
164
- if (this.editors.styles) {
165
- this.styleEditor.updateLayout();
166
- }
167
- });
168
77
  }
169
78
  ngOnDestroy() {
170
79
  this._destroy$.next();
171
80
  this._destroy$.complete();
172
81
  }
173
- stylesChanged() {
174
- this.form.triggerSubmit();
82
+ globalScssChange() {
83
+ this._config.saveContentStyle(this.contentStyle)
84
+ .subscribe((contentStyle) => {
85
+ this.contentStyle = contentStyle;
86
+ this._message.success('Saved Changes');
87
+ this._cdRef.markForCheck();
88
+ });
175
89
  }
176
- contentChanged() {
177
- this.form.triggerSubmit();
90
+ initTextEditors() {
91
+ this.scssConfig = {
92
+ tabSize: 2,
93
+ language: 'scss',
94
+ height: '100%',
95
+ };
96
+ this.jsConfig = {
97
+ tabSize: 2,
98
+ language: 'js',
99
+ height: '100%',
100
+ };
101
+ this.htmlConfig = {
102
+ tabSize: 2,
103
+ language: 'html',
104
+ height: '100%',
105
+ };
106
+ this.globalScssConfig = {
107
+ tabSize: 2,
108
+ language: 'scss',
109
+ height: '100%',
110
+ };
178
111
  }
179
- openSettings() {
180
- this._dialog.open(ContentPageComponent, {
181
- data: {
182
- contentPage: this.contentPage,
183
- },
112
+ initGlobalContentStyle() {
113
+ this._config.loadContentStyle()
114
+ .subscribe((contentStyle) => {
115
+ this.contentStyle = contentStyle;
116
+ this._cdRef.markForCheck();
117
+ });
118
+ }
119
+ saveContentPage() {
120
+ this._save({
121
+ id: this.contentPage.id,
122
+ styles: this.contentPage.styles,
123
+ content: this.contentPage.content,
124
+ js: this.contentPage.js,
184
125
  })
185
- .afterClosed()
186
- .pipe(takeUntil(this._destroy$))
187
- .subscribe((contentPage) => {
126
+ .pipe(tap((contentPage) => {
188
127
  this.contentPage = Object.assign(Object.assign({}, this.contentPage), contentPage);
189
128
  this._cdRef.markForCheck();
190
- });
129
+ this._message.success('Saved Changes');
130
+ }))
131
+ .subscribe();
191
132
  }
192
- _initSeparator() {
193
- fromEvent(this.separator.nativeElement, 'mousedown')
133
+ openSettings() {
134
+ this._data.openSettings(this.contentPage)
194
135
  .pipe(takeUntil(this._destroy$))
195
- .subscribe((e) => {
196
- this._moveSeparator(e);
197
- });
198
- }
199
- _moveSeparator(separatorEvent) {
200
- let mouseDown = {
201
- clientX: separatorEvent.clientX,
202
- clientY: separatorEvent.clientY,
203
- offsetLeft: Number(this.separator.nativeElement.offsetLeft),
204
- offsetTop: Number(this.separator.nativeElement.offsetTop),
205
- firstWidth: Number(this.contentContainer.nativeElement.offsetWidth),
206
- secondWidth: Number(this.styleContainer.nativeElement.offsetWidth),
207
- };
208
- this.resizing = true;
209
- this._cdRef.markForCheck();
210
- fromEvent(document, 'mousemove')
211
- .pipe(finalize(() => {
212
- mouseDown = null;
213
- this.resizing = false;
136
+ .subscribe((contentPage) => {
137
+ this.contentPage = Object.assign(Object.assign({}, this.contentPage), contentPage);
214
138
  this._cdRef.markForCheck();
215
- this.updateEditorLayouts();
216
- }), takeUntil(fromEvent(this.separator.nativeElement, 'mouseup')
217
- .pipe(take(1), takeUntil(this._destroy$))), takeUntil(this._destroy$))
218
- .subscribe((e) => {
219
- const delta = { x: e.clientX - mouseDown.clientX,
220
- y: e.clientY - mouseDown.clientY };
221
- delta.x = Math.min(Math.max(delta.x, -mouseDown.firstWidth), mouseDown.secondWidth);
222
- this.separator.nativeElement.style.left = `${mouseDown.offsetLeft + delta.x}px`;
223
- this.contentContainer.nativeElement.style.width = `${mouseDown.firstWidth + delta.x}px`;
224
- this.styleContainer.nativeElement.style.width = `${mouseDown.secondWidth - delta.x}px`;
225
139
  });
226
140
  }
227
141
  }
228
- EditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: EditorComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1.MatDialogRef }, { token: i1.MatDialog }, { token: i2.FsMessage }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
229
- EditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: EditorComponent, selector: "ng-component", viewQueries: [{ propertyName: "form", first: true, predicate: FsFormDirective, descendants: true }, { propertyName: "styleEditor", first: true, predicate: ["styleEditor"], descendants: true }, { propertyName: "contentEditor", first: true, predicate: ["contentEditor"], descendants: true }, { propertyName: "separator", first: true, predicate: ["separator"], descendants: true, read: ElementRef, static: true }, { propertyName: "contentContainer", first: true, predicate: ["contentContainer"], descendants: true, read: ElementRef, static: true }, { propertyName: "styleContainer", first: true, predicate: ["styleContainer"], descendants: true, read: ElementRef, static: true }], ngImport: i0, template: "<form fsForm [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n <div class=\"title-container\">\n <div class=\"title\">\n Page\n <div class=\"small\">{{contentPage.name}}</div> \n </div>\n <a\n (click)=\"openSettings()\"\n mat-icon-button>\n <mat-icon>settings</mat-icon>\n </a> \n </div>\n </h1>\n <div mat-dialog-content>\n <div class=\"container\">\n <div class=\"editors\" [ngClass]=\"{ resizing: resizing, 'separator-enabled': editors.styles && editors.content }\">\n <div #contentContainer class=\"editor editor-content\" [ngClass]=\"{ 'content-enabled': editors.content }\">\n <fs-label>Content</fs-label>\n <div class=\"editor-container\">\n <fs-text-editor \n #contentEditor\n [(ngModel)]=\"contentPage.content\" \n (blur)=\"contentChanged()\"\n name=\"content\"\n [config]=\"{ tabSize: 2, language: 'html' }\">\n </fs-text-editor> \n </div>\n </div>\n <div \n #separator\n class=\"separator\">\n <mat-icon>drag_indicator</mat-icon>\n </div>\n <div \n #styleContainer \n class=\"editor editor-styles\" \n [ngClass]=\"{ 'styles-enabled': editors.styles }\"\n [style.width]=\"'600px'\">\n <fs-label>Styles</fs-label>\n <div class=\"editor-container\">\n <fs-text-editor \n #styleEditor\n [(ngModel)]=\"contentPage.styles\" \n (blur)=\"stylesChanged()\"\n name=\"styles\"\n [config]=\"{ tabSize: 2, language: 'scss' }\">\n </fs-text-editor> \n </div>\n </div> \n </div>\n </div>\n </div>\n\n <div mat-dialog-actions>\n <fs-form-dialog-actions\n [save]=\"false\"\n [done]=\"true\">\n </fs-form-dialog-actions>\n <div class=\"toggles\">\n <mat-button-toggle-group multiple>\n <mat-button-toggle value=\"content\" [checked]=\"editors.content\" (change)=\"editorToggleChange($event)\">Content</mat-button-toggle>\n <mat-button-toggle value=\"styles\" [checked]=\"editors.styles\" (change)=\"editorToggleChange($event)\">Styles</mat-button-toggle>\n </mat-button-toggle-group> \n </div>\n </div>\n </fs-dialog>\n</form>\n\n", styles: ["form{display:block;height:100%}form fs-dialog{display:flex;flex-direction:column;height:100%}form ::ng-deep .mat-dialog-content{max-height:none;flex:1}.mat-dialog-actions fs-form-dialog-actions{width:auto}.mat-dialog-actions .toggles{display:flex;justify-content:flex-end;justify-self:baseline;flex:1}.container{height:100%;display:flex;flex-direction:column}.editors{width:5000px;max-width:100%;height:100%;display:flex;min-height:0}.editors:not(.separator-enabled) .separator{display:none}.editors:not(.separator-enabled) .editor{width:100%!important}.editors .separator{display:flex;align-items:center;justify-content:center;cursor:col-resize;background-color:#fff;width:40px;height:100%;-webkit-user-select:none;user-select:none;flex-shrink:0}.editors .editor{height:100%;display:flex;min-width:0;width:100%;flex-direction:column}.editors .editor.editor-styles:not(.styles-enabled),.editors .editor.editor-content:not(.content-enabled){display:none}.editors .editor .editor-container{height:100%;overflow:hidden;background:#1E1E1E;border-radius:5px}.editors .editor .editor-container fs-text-editor{display:block}.editors .editor+.editor{margin-left:20px}.editors .editor fs-label{background-color:#fff;padding-bottom:5px}.title-container{display:flex;align-items:center}.title-container .title{flex:1}.title-container .title .small{line-height:normal}\n"], components: [{ type: i3.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileActionPlacement", "mobileWidth", "mode"] }, { type: i4$1.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { type: i5$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i6$1.FsLabelComponent, selector: "fs-label" }, { type: i7$1.FsTextEditorComponent, selector: "fs-text-editor", inputs: ["config", "scrollable"], outputs: ["init", "blur"] }, { type: i7.FsFormDialogActionsComponent, selector: "fs-form-dialog-actions", inputs: ["save", "create", "close", "done", "closeData", "name"] }, { type: i9$1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["disableRipple", "aria-labelledby", "tabIndex", "appearance", "checked", "disabled", "id", "name", "aria-label", "value"], outputs: ["change"], exportAs: ["matButtonToggle"] }], directives: [{ type: i9.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i9.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i9.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i7.FsFormDirective, selector: "[fsForm]", inputs: ["wrapperSelector", "messageSelector", "hintSelector", "labelSelector", "autocomplete", "shortcuts", "confirm", "confirmDialog", "confirmDrawer", "confirmBrowser", "confirmTabs", "dirtySubmitButton", "submit", "successDelay", "errorDelay", "tabGroup", "deactivationGuard"], outputs: ["fsForm", "invalid", "valid", "submitted", "reseted", "cleared"], exportAs: ["fsForm"] }, { type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i10.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i9.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i9.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i7.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }, { type: i9$1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
142
+ EditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: EditorComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1.MatDialogRef }, { token: i2.FsMessage }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
143
+ EditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: EditorComponent, selector: "ng-component", ngImport: i0, template: "<fs-dialog>\n <h1 mat-dialog-title>\n <div class=\"title-container\">\n <div class=\"title\">\n {{title}}\n <div class=\"small\">{{contentPage.name}}</div> \n </div>\n <a\n (click)=\"openSettings()\"\n mat-icon-button>\n <mat-icon>settings</mat-icon>\n </a> \n </div>\n </h1>\n <div mat-dialog-content>\n <div class=\"container\">\n <as-split [unit]=\"'percent'\" [gutterSize]=\"25\"> \n <as-split-area [size]=\"70\" [visible]=\"editors.html\" [order]=\"1\">\n <div class=\"editor-container\">\n <fs-label>HTML</fs-label>\n <fs-text-editor \n [(ngModel)]=\"contentPage.content\" \n name=\"html\"\n [fsModelChangeOptions]=\"{ debounce: 300 }\"\n (fsModelChange)=\"saveContentPage()\"\n [config]=\"htmlConfig\">\n </fs-text-editor> \n </div>\n </as-split-area>\n <as-split-area [size]=\"30\" [visible]=\"editors.scss\" [order]=\"2\">\n <div class=\"editor-container\">\n <fs-label>SCSS</fs-label>\n <fs-text-editor \n [(ngModel)]=\"contentPage.styles\" \n name=\"scss\"\n [fsModelChangeOptions]=\"{ debounce: 300 }\"\n (fsModelChange)=\"saveContentPage()\"\n [config]=\"scssConfig\">\n </fs-text-editor> \n </div>\n </as-split-area>\n <as-split-area [size]=\"30\" [visible]=\"editors.js\" [order]=\"3\">\n <div class=\"editor-container\">\n <fs-label>JS</fs-label>\n <fs-text-editor \n [(ngModel)]=\"contentPage.js\" \n name=\"js\"\n [fsModelChangeOptions]=\"{ debounce: 300 }\"\n (fsModelChange)=\"saveContentPage()\"\n [config]=\"jsConfig\">\n </fs-text-editor> \n </div>\n </as-split-area>\n <as-split-area [size]=\"30\" [visible]=\"editors.globalScss\" [order]=\"4\">\n <div class=\"editor-container\">\n <fs-label>Global SCSS</fs-label>\n <ng-container *fsSkeleton=\"contentStyle\">\n <fs-text-editor \n [(ngModel)]=\"contentStyle.scss\" \n name=\"globalScss\"\n [fsModelChangeOptions]=\"{ debounce: 300 }\"\n (fsModelChange)=\"globalScssChange()\"\n [config]=\"globalScssConfig\">\n </fs-text-editor> \n </ng-container> \n </div>\n </as-split-area>\n </as-split>\n </div>\n </div>\n\n <div mat-dialog-actions>\n <fs-form-dialog-actions\n [save]=\"false\"\n [done]=\"true\">\n </fs-form-dialog-actions>\n <div class=\"toggles\">\n <mat-button-toggle-group multiple>\n <mat-button-toggle value=\"html\" [checked]=\"editors.html\" (change)=\"editorToggleChange($event)\">HTML</mat-button-toggle>\n <mat-button-toggle value=\"scss\" [checked]=\"editors.scss\" (change)=\"editorToggleChange($event)\">SCSS</mat-button-toggle>\n <mat-button-toggle value=\"js\" [checked]=\"editors.js\" (change)=\"editorToggleChange($event)\">JS</mat-button-toggle>\n <mat-button-toggle value=\"globalScss\" [checked]=\"editors.globalScss\" (change)=\"editorToggleChange($event)\">Global SCSS</mat-button-toggle>\n </mat-button-toggle-group> \n </div>\n </div>\n</fs-dialog>\n\n", styles: ["::ng-deep .fs-content-editor-overlay-pane .mat-dialog-container{border-radius:0}:host ::ng-deep .as-split-gutter{background-color:unset!important}fs-dialog{display:flex;height:100%;flex-direction:column}fs-dialog ::ng-deep .mat-dialog-content{max-height:none;flex:1;overflow:hidden}.mat-dialog-actions fs-form-dialog-actions{width:auto}.mat-dialog-actions .toggles{display:flex;justify-content:flex-end;justify-self:baseline;flex:1}.container{height:100%;display:flex;flex-direction:column}.editor-container{height:100%;border-radius:5px;display:flex;flex-direction:column}.editor-container fs-text-editor{flex:1}.title-container{display:flex;align-items:center}.title-container .title{flex:1}.title-container .title .small{line-height:normal}\n"], components: [{ type: i3.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileActionPlacement", "mobileWidth", "mode"] }, { type: i4.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i6.SplitComponent, selector: "as-split", inputs: ["direction", "unit", "gutterSize", "gutterStep", "restrictMove", "useTransition", "disabled", "dir", "gutterDblClickDuration", "gutterClickDeltaPx", "gutterAriaLabel"], outputs: ["transitionEnd", "dragStart", "dragEnd", "gutterClick", "gutterDblClick"], exportAs: ["asSplit"] }, { type: i7.FsLabelComponent, selector: "fs-label" }, { type: i8.FsTextEditorComponent, selector: "fs-text-editor", inputs: ["config", "scrollable"], outputs: ["ready", "blur"] }, { type: i5$1.FsFormDialogActionsComponent, selector: "fs-form-dialog-actions", inputs: ["save", "create", "close", "done", "closeData", "name"] }, { type: i10.MatButtonToggle, selector: "mat-button-toggle", inputs: ["disableRipple", "aria-labelledby", "tabIndex", "appearance", "checked", "disabled", "id", "name", "aria-label", "value"], outputs: ["change"], exportAs: ["matButtonToggle"] }], directives: [{ type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i6.SplitAreaDirective, selector: "as-split-area, [as-split-area]", inputs: ["order", "size", "minSize", "maxSize", "lockSize", "visible"], exportAs: ["asSplitArea"] }, { type: i7$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i7$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i5$1.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { type: i12.FsModelChangeDirective, selector: "[fsModelChange]", inputs: ["fsModelChangeOptions"], outputs: ["fsModelChange"] }, { type: i13.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }, { type: i10.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
230
144
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: EditorComponent, decorators: [{
231
145
  type: Component,
232
146
  args: [{
@@ -237,25 +151,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
237
151
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
238
152
  type: Inject,
239
153
  args: [MAT_DIALOG_DATA]
240
- }] }, { type: i1.MatDialogRef }, { type: i1.MatDialog }, { type: i2.FsMessage }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { form: [{
241
- type: ViewChild,
242
- args: [FsFormDirective]
243
- }], styleEditor: [{
244
- type: ViewChild,
245
- args: ['styleEditor']
246
- }], contentEditor: [{
247
- type: ViewChild,
248
- args: ['contentEditor']
249
- }], separator: [{
250
- type: ViewChild,
251
- args: ['separator', { static: true, read: ElementRef }]
252
- }], contentContainer: [{
253
- type: ViewChild,
254
- args: ['contentContainer', { static: true, read: ElementRef }]
255
- }], styleContainer: [{
256
- type: ViewChild,
257
- args: ['styleContainer', { static: true, read: ElementRef }]
258
- }] } });
154
+ }] }, { type: i1.MatDialogRef }, { type: i2.FsMessage }, { type: i0.ChangeDetectorRef }]; } });
259
155
 
260
156
  class FsContentEditorModule {
261
157
  }
@@ -269,10 +165,13 @@ FsContentEditorModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", v
269
165
  MatButtonToggleModule,
270
166
  FsListModule,
271
167
  FsFormModule,
168
+ FsSkeletonModule,
272
169
  FsLabelModule,
273
170
  FsHtmlEditorModule,
171
+ FsCommonModule,
274
172
  FsDialogModule,
275
- FsTextEditorModule], exports: [EditorComponent] });
173
+ FsTextEditorModule,
174
+ AngularSplitModule], exports: [EditorComponent] });
276
175
  FsContentEditorModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentEditorModule, imports: [[
277
176
  CommonModule,
278
177
  FormsModule,
@@ -283,10 +182,13 @@ FsContentEditorModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", v
283
182
  MatButtonToggleModule,
284
183
  FsListModule,
285
184
  FsFormModule,
185
+ FsSkeletonModule,
286
186
  FsLabelModule,
287
187
  FsHtmlEditorModule,
188
+ FsCommonModule,
288
189
  FsDialogModule,
289
190
  FsTextEditorModule,
191
+ AngularSplitModule,
290
192
  ]] });
291
193
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentEditorModule, decorators: [{
292
194
  type: NgModule,
@@ -301,10 +203,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
301
203
  MatButtonToggleModule,
302
204
  FsListModule,
303
205
  FsFormModule,
206
+ FsSkeletonModule,
304
207
  FsLabelModule,
305
208
  FsHtmlEditorModule,
209
+ FsCommonModule,
306
210
  FsDialogModule,
307
211
  FsTextEditorModule,
212
+ AngularSplitModule,
308
213
  ],
309
214
  exports: [
310
215
  EditorComponent,
@@ -315,40 +220,112 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
315
220
  }]
316
221
  }] });
317
222
 
318
- class FsContentPagesComponent {
223
+ const FS_CONTENT_CONFIG = new InjectionToken('fs-content-config');
224
+
225
+ class ContentLayoutComponent {
226
+ constructor(_config, _data, _dialogRef, _message, _cdRef) {
227
+ this._config = _config;
228
+ this._data = _data;
229
+ this._dialogRef = _dialogRef;
230
+ this._message = _message;
231
+ this._cdRef = _cdRef;
232
+ this.contentLayout = null;
233
+ this.editors = { content: true, styles: true };
234
+ this._destroy$ = new Subject();
235
+ this.save = () => {
236
+ return this._config.saveContentLayout(this.contentLayout)
237
+ .pipe(tap((contentLayout) => {
238
+ this._message.success('Saved Changes');
239
+ this._dialogRef.close(contentLayout);
240
+ }));
241
+ };
242
+ }
243
+ ngOnInit() {
244
+ this._fetchData();
245
+ }
246
+ ngOnDestroy() {
247
+ this._destroy$.next();
248
+ this._destroy$.complete();
249
+ }
250
+ _fetchData() {
251
+ of(this._data.contentLayout)
252
+ .pipe(switchMap((contentLayout) => {
253
+ return of(contentLayout);
254
+ }), takeUntil(this._destroy$))
255
+ .subscribe((contentLayout) => {
256
+ this.contentLayout = Object.assign({}, contentLayout);
257
+ this._cdRef.markForCheck();
258
+ });
259
+ }
260
+ }
261
+ ContentLayoutComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ContentLayoutComponent, deps: [{ token: FS_CONTENT_CONFIG }, { token: MAT_DIALOG_DATA }, { token: i1.MatDialogRef }, { token: i2.FsMessage }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
262
+ ContentLayoutComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: ContentLayoutComponent, selector: "ng-component", viewQueries: [{ propertyName: "textEditors", predicate: FsTextEditorComponent, descendants: true }], ngImport: i0, template: "<form fsForm [submit]=\"save\" *fsSkeletonForm=\"contentLayout\">\n <fs-dialog>\n <h1 mat-dialog-title>{{contentLayout.id ? 'Layout' : 'Layout Page'}}</h1>\n <div mat-dialog-content>\n <div class=\"fs-column\">\n <mat-form-field>\n <input\n matInput\n [(ngModel)]=\"contentLayout.name\"\n name=\"name\"\n required\n placeholder=\"Name\">\n </mat-form-field>\n <mat-form-field>\n <input\n matInput\n [(ngModel)]=\"contentLayout.tag\"\n name=\"tag\"\n placeholder=\"Tag\">\n </mat-form-field>\n </div>\n </div>\n\n <div mat-dialog-actions>\n <fs-form-dialog-actions>\n </fs-form-dialog-actions>\n </div>\n </fs-dialog>\n</form>\n", styles: [""], components: [{ type: i3.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileActionPlacement", "mobileWidth", "mode"] }, { type: i4$1.MatFormField, selector: "mat-form-field", inputs: ["color", "floatLabel", "appearance", "hideRequiredMarker", "hintLabel"], exportAs: ["matFormField"] }, { type: i5$1.FsFormDialogActionsComponent, selector: "fs-form-dialog-actions", inputs: ["save", "create", "close", "done", "closeData", "name"] }], directives: [{ type: i13.FsSkeletonFormDirective, selector: "[fsSkeletonForm]", inputs: ["fsSkeletonForm", "fsSkeletonFormLines"] }, { type: i7$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i7$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i7$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5$1.FsFormDirective, selector: "[fsForm]", inputs: ["wrapperSelector", "messageSelector", "hintSelector", "labelSelector", "autocomplete", "shortcuts", "confirm", "confirmDialog", "confirmDrawer", "confirmBrowser", "confirmTabs", "dirtySubmitButton", "submit", "successDelay", "errorDelay", "tabGroup", "deactivationGuard"], outputs: ["fsForm", "invalid", "valid", "submitted", "reseted", "cleared"], exportAs: ["fsForm"] }, { type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i8$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["id", "disabled", "required", "type", "value", "readonly", "placeholder", "errorStateMatcher", "aria-describedby"], exportAs: ["matInput"] }, { type: i7$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i7$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i7$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i7$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i5$1.FsFormRequiredDirective, selector: "[fsFormRequired],[ngModel][required]", inputs: ["fsFormRequired", "required", "fsFormRequiredMessage"] }, { type: i5$1.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
263
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ContentLayoutComponent, decorators: [{
264
+ type: Component,
265
+ args: [{
266
+ templateUrl: './content-layout.component.html',
267
+ styleUrls: ['./content-layout.component.scss'],
268
+ changeDetection: ChangeDetectionStrategy.OnPush,
269
+ }]
270
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
271
+ type: Inject,
272
+ args: [FS_CONTENT_CONFIG]
273
+ }] }, { type: undefined, decorators: [{
274
+ type: Inject,
275
+ args: [MAT_DIALOG_DATA]
276
+ }] }, { type: i1.MatDialogRef }, { type: i2.FsMessage }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { textEditors: [{
277
+ type: ViewChildren,
278
+ args: [FsTextEditorComponent]
279
+ }] } });
280
+
281
+ class FsContentLayoutsComponent {
319
282
  constructor(_config, _dialog) {
320
283
  this._config = _config;
321
284
  this._dialog = _dialog;
322
- this.pageTypes = index(PageTypes, 'value', 'name');
323
285
  this._destroy$ = new Subject();
324
286
  }
325
287
  ngOnInit() {
326
288
  this._initListConfig();
327
289
  }
328
- openEditor(contentPage) {
290
+ openEditor(contentLayout) {
329
291
  this._dialog.open(EditorComponent, {
330
- data: {
331
- contentPage,
332
- config: this._config,
333
- },
334
292
  maxWidth: '100vw',
335
- maxHeight: '100vw',
336
293
  width: '100%',
337
294
  height: '100%',
338
- autoFocus: false,
295
+ data: {
296
+ contentPage: contentLayout,
297
+ title: 'Layout',
298
+ contentConfig: this._config,
299
+ save: (data) => {
300
+ return this._config.saveContentLayout(Object.assign({ id: contentLayout.id }, data));
301
+ },
302
+ openSettings: (data) => {
303
+ return this.openLayout(data);
304
+ },
305
+ },
339
306
  })
340
307
  .afterClosed()
341
- .pipe(filter((_contentPage) => !!_contentPage), takeUntil(this._destroy$))
308
+ .pipe(takeUntil(this._destroy$))
342
309
  .subscribe(() => {
343
310
  this.listComponent.reload();
344
311
  });
345
312
  }
313
+ openLayout(contentLayout) {
314
+ return this._dialog.open(ContentLayoutComponent, {
315
+ data: {
316
+ contentLayout,
317
+ },
318
+ })
319
+ .afterClosed()
320
+ .pipe(filter((_contentLayout) => !!_contentLayout), takeUntil(this._destroy$));
321
+ }
346
322
  ngOnDestroy() {
347
323
  this._destroy$.next();
348
324
  this._destroy$.complete();
349
325
  }
350
326
  _initListConfig() {
351
327
  this.listConfig = {
328
+ paging: false,
352
329
  filters: [
353
330
  {
354
331
  name: 'keyword',
@@ -360,17 +337,8 @@ class FsContentPagesComponent {
360
337
  {
361
338
  label: 'Create',
362
339
  click: () => {
363
- this._dialog.open(ContentPageComponent, {
364
- data: {
365
- contentPage: {
366
- type: PageType.StandardPage,
367
- },
368
- },
369
- })
370
- .afterClosed()
371
- .pipe(filter((contentPage) => !!contentPage), takeUntil(this._destroy$))
372
- .subscribe((contentPage) => {
373
- this.openEditor(contentPage);
340
+ this.openLayout({})
341
+ .subscribe(() => {
374
342
  this.listComponent.reload();
375
343
  });
376
344
  },
@@ -379,7 +347,7 @@ class FsContentPagesComponent {
379
347
  rowActions: [
380
348
  {
381
349
  click: (data) => {
382
- return this._config.deleteContentPage(data);
350
+ return this._config.deleteContentLayout(data);
383
351
  },
384
352
  remove: {
385
353
  title: 'Confirm',
@@ -390,9 +358,9 @@ class FsContentPagesComponent {
390
358
  },
391
359
  ],
392
360
  fetch: (query) => {
393
- return this._config.loadContentPages(query)
394
- .pipe(map((response) => {
395
- return { data: response.contentPages, paging: response.paging };
361
+ return this._config.loadContentLayouts(query)
362
+ .pipe(map((contentLayouts) => {
363
+ return { data: contentLayouts };
396
364
  }));
397
365
  },
398
366
  restore: {
@@ -401,42 +369,35 @@ class FsContentPagesComponent {
401
369
  menuLabel: 'Restore',
402
370
  reload: true,
403
371
  click: (row) => {
404
- return this._config.saveContentPage({ id: row.id, state: 'active' });
372
+ return this._config.saveContentLayout({ id: row.id, state: 'active' });
405
373
  },
406
374
  },
407
375
  };
408
376
  }
409
377
  }
410
- FsContentPagesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentPagesComponent, deps: [{ token: FS_CONTENT_CONFIG }, { token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
411
- FsContentPagesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: FsContentPagesComponent, selector: "fs-content-pages", inputs: { htmlEditorConfig: "htmlEditorConfig" }, viewQueries: [{ propertyName: "listComponent", first: true, predicate: FsListComponent, descendants: true }], ngImport: i0, template: "<fs-list [config]=\"listConfig\">\n <fs-list-column name=\"name\" title=\"Name\" [sortable]=\"true\">\n <ng-template fs-list-cell let-row=\"row\">\n <a (click)=\"openEditor(row)\">{{row.name}}</a>\n </ng-template>\n </fs-list-column>\n <fs-list-column name=\"path\" title=\"Path\" [sortable]=\"true\">\n <ng-template fs-list-cell let-row=\"row\">\n <a [href]=\"'/' + row.path\" target=\"_black\">/{{row.path}}</a>\n </ng-template>\n </fs-list-column>\n <fs-list-column name=\"type\" title=\"Type\" [sortable]=\"true\">\n <ng-template fs-list-cell let-row=\"row\">\n {{pageTypes[row.type]}}\n </ng-template>\n </fs-list-column>\n <fs-list-column name=\"modify_date\" title=\"Modified\" [sortable]=\"true\">\n <ng-template fs-list-cell let-row=\"row\">\n {{row.modifyDate | fsDate: 'date-time-yearless'}}\n </ng-template>\n </fs-list-column>\n</fs-list>\n", styles: [":host ::ng-deep .modified,:host ::ng-deep .name{width:1%;white-space:nowrap}:host ::ng-deep .preview-content img{display:none}.preview-content{position:relative;max-height:100px;max-width:100%;overflow:hidden;-webkit-mask-image:-webkit-gradient(linear,left 60%,left bottom,from(black),to(rgba(0,0,0,0)))}\n"], components: [{ type: i2$1.FsListComponent, selector: "fs-list", inputs: ["config", "loaderLines"], outputs: ["filtersReady"] }], directives: [{ type: i2$1.FsListColumnDirective, selector: "fs-list-column", inputs: ["show", "title", "name", "customize", "sortable", "sortableDefault", "direction", "align", "width", "class"] }, { type: i2$1.FsListCellDirective, selector: "[fs-list-cell]", inputs: ["colspan", "align", "class"] }], pipes: { "fsDate": i3$1.FsDatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
412
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentPagesComponent, decorators: [{
378
+ FsContentLayoutsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentLayoutsComponent, deps: [{ token: FS_CONTENT_CONFIG }, { token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
379
+ FsContentLayoutsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: FsContentLayoutsComponent, selector: "fs-content-layouts", viewQueries: [{ propertyName: "listComponent", first: true, predicate: FsListComponent, descendants: true }], ngImport: i0, template: "<fs-list [config]=\"listConfig\">\n <fs-list-column name=\"name\" title=\"Name\" [sortable]=\"true\">\n <ng-template fs-list-cell let-row=\"row\">\n <a (click)=\"openEditor(row)\">{{row.name}}</a>\n </ng-template>\n </fs-list-column>\n <fs-list-column name=\"modify_date\" title=\"Modified\" [sortable]=\"true\">\n <ng-template fs-list-cell let-row=\"row\">\n {{row.modifyDate | fsDate: 'date-time-yearless'}}\n </ng-template>\n </fs-list-column>\n</fs-list>\n", styles: [""], components: [{ type: i2$1.FsListComponent, selector: "fs-list", inputs: ["config", "loaderLines"], outputs: ["filtersReady"] }], directives: [{ type: i2$1.FsListColumnDirective, selector: "fs-list-column", inputs: ["show", "title", "name", "customize", "sortable", "sortableDefault", "direction", "align", "width", "class"] }, { type: i2$1.FsListCellDirective, selector: "[fs-list-cell]", inputs: ["colspan", "align", "class"] }], pipes: { "fsDate": i3$1.FsDatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
380
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentLayoutsComponent, decorators: [{
413
381
  type: Component,
414
382
  args: [{
415
- selector: 'fs-content-pages',
416
- templateUrl: './content-pages.component.html',
417
- styleUrls: ['./content-pages.component.scss'],
383
+ selector: 'fs-content-layouts',
384
+ templateUrl: './content-layouts.component.html',
385
+ styleUrls: ['./content-layouts.component.scss'],
418
386
  changeDetection: ChangeDetectionStrategy.OnPush,
419
387
  }]
420
388
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
421
389
  type: Inject,
422
390
  args: [FS_CONTENT_CONFIG]
423
- }] }, { type: i1.MatDialog }]; }, propDecorators: { htmlEditorConfig: [{
424
- type: Input
425
- }], listComponent: [{
391
+ }] }, { type: i1.MatDialog }]; }, propDecorators: { listComponent: [{
426
392
  type: ViewChild,
427
393
  args: [FsListComponent]
428
394
  }] } });
429
395
 
430
- class FsContentPagesModule {
431
- static forRoot() {
432
- return {
433
- ngModule: FsContentPagesModule,
434
- };
435
- }
396
+ class FsContentLayoutsModule {
436
397
  }
437
- FsContentPagesModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentPagesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
438
- FsContentPagesModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentPagesModule, declarations: [FsContentPagesComponent,
439
- ContentPageComponent], imports: [CommonModule,
398
+ FsContentLayoutsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentLayoutsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
399
+ FsContentLayoutsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentLayoutsModule, declarations: [ContentLayoutComponent,
400
+ FsContentLayoutsComponent], imports: [CommonModule,
440
401
  FormsModule,
441
402
  MatDialogModule,
442
403
  MatInputModule,
@@ -454,8 +415,8 @@ FsContentPagesModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", ve
454
415
  FsHtmlEditorModule,
455
416
  FsDialogModule,
456
417
  FsTextEditorModule,
457
- FsContentEditorModule], exports: [FsContentPagesComponent] });
458
- FsContentPagesModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentPagesModule, imports: [[
418
+ FsContentEditorModule], exports: [FsContentLayoutsComponent] });
419
+ FsContentLayoutsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentLayoutsModule, imports: [[
459
420
  CommonModule,
460
421
  FormsModule,
461
422
  MatDialogModule,
@@ -476,7 +437,7 @@ FsContentPagesModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", ve
476
437
  FsTextEditorModule,
477
438
  FsContentEditorModule,
478
439
  ]] });
479
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentPagesModule, decorators: [{
440
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentLayoutsModule, decorators: [{
480
441
  type: NgModule,
481
442
  args: [{
482
443
  imports: [
@@ -501,34 +462,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
501
462
  FsContentEditorModule,
502
463
  ],
503
464
  exports: [
504
- FsContentPagesComponent,
465
+ FsContentLayoutsComponent,
505
466
  ],
506
467
  declarations: [
507
- FsContentPagesComponent,
508
- ContentPageComponent,
468
+ ContentLayoutComponent,
469
+ FsContentLayoutsComponent,
509
470
  ],
510
471
  }]
511
472
  }] });
512
473
 
513
- class ContentLayoutComponent {
474
+ var PageType;
475
+ (function (PageType) {
476
+ PageType["StandardPage"] = "standardPage";
477
+ PageType["BlogPost"] = "blogPost";
478
+ PageType["HomePage"] = "homePage";
479
+ PageType["NotFoundPage"] = "notFoundPage";
480
+ })(PageType || (PageType = {}));
481
+
482
+ const PageTypes = [
483
+ { name: 'Standard Page', value: PageType.StandardPage },
484
+ { name: 'Home Page', value: PageType.HomePage },
485
+ { name: 'Not Found Page', value: PageType.NotFoundPage },
486
+ { name: 'Blog Post', value: PageType.BlogPost },
487
+ ];
488
+
489
+ class ContentPageComponent {
514
490
  constructor(_config, _data, _dialogRef, _message, _cdRef) {
515
491
  this._config = _config;
516
492
  this._data = _data;
517
493
  this._dialogRef = _dialogRef;
518
494
  this._message = _message;
519
495
  this._cdRef = _cdRef;
520
- this.contentLayout = null;
496
+ this.contentPage = null;
497
+ this.PageTypes = PageTypes;
521
498
  this.editors = { content: true, styles: true };
522
499
  this._destroy$ = new Subject();
523
500
  this.save = () => {
524
- return this._config.saveContentLayout(this.contentLayout)
525
- .pipe(tap((contentLayout) => {
501
+ return this._config.saveContentPage(this.contentPage)
502
+ .pipe(tap((contentPage) => {
526
503
  this._message.success('Saved Changes');
527
- this._dialogRef.close(contentLayout);
504
+ this._dialogRef.close(contentPage);
528
505
  }));
529
506
  };
530
507
  }
531
508
  ngOnInit() {
509
+ this._dialogRef.updateSize('600px');
532
510
  this._fetchData();
533
511
  }
534
512
  ngOnDestroy() {
@@ -536,23 +514,28 @@ class ContentLayoutComponent {
536
514
  this._destroy$.complete();
537
515
  }
538
516
  _fetchData() {
539
- of(this._data.contentLayout)
540
- .pipe(switchMap((contentLayout) => {
541
- return of(contentLayout);
517
+ this._config.loadContentLayouts()
518
+ .subscribe((contentLayouts) => {
519
+ this.contentLayouts = contentLayouts;
520
+ this._cdRef.markForCheck();
521
+ });
522
+ of(this._data.contentPage)
523
+ .pipe(switchMap((contentPage) => {
524
+ return of(contentPage);
542
525
  }), takeUntil(this._destroy$))
543
- .subscribe((contentLayout) => {
544
- this.contentLayout = Object.assign({}, contentLayout);
526
+ .subscribe((contentPage) => {
527
+ this.contentPage = Object.assign({}, contentPage);
545
528
  this._cdRef.markForCheck();
546
529
  });
547
530
  }
548
531
  }
549
- ContentLayoutComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ContentLayoutComponent, deps: [{ token: FS_CONTENT_CONFIG }, { token: MAT_DIALOG_DATA }, { token: i1.MatDialogRef }, { token: i2.FsMessage }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
550
- ContentLayoutComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: ContentLayoutComponent, selector: "ng-component", viewQueries: [{ propertyName: "textEditors", predicate: FsTextEditorComponent, descendants: true }], ngImport: i0, template: "<form fsForm [submit]=\"save\" *fsSkeletonForm=\"contentLayout\">\n <fs-dialog>\n <h1 mat-dialog-title>{{contentLayout.id ? 'Layout' : 'Layout Page'}}</h1>\n <div mat-dialog-content>\n <div class=\"fs-column\">\n <mat-form-field>\n <input\n matInput\n [(ngModel)]=\"contentLayout.name\"\n name=\"name\"\n required\n placeholder=\"Name\">\n </mat-form-field>\n <mat-form-field>\n <input\n matInput\n [(ngModel)]=\"contentLayout.tag\"\n name=\"tag\"\n placeholder=\"Tag\">\n </mat-form-field>\n </div>\n </div>\n\n <div mat-dialog-actions>\n <fs-form-dialog-actions>\n </fs-form-dialog-actions>\n </div>\n </fs-dialog>\n</form>\n", styles: [""], components: [{ type: i3.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileActionPlacement", "mobileWidth", "mode"] }, { type: i4.MatFormField, selector: "mat-form-field", inputs: ["color", "floatLabel", "appearance", "hideRequiredMarker", "hintLabel"], exportAs: ["matFormField"] }, { type: i7.FsFormDialogActionsComponent, selector: "fs-form-dialog-actions", inputs: ["save", "create", "close", "done", "closeData", "name"] }], directives: [{ type: i8.FsSkeletonFormDirective, selector: "[fsSkeletonForm]", inputs: ["fsSkeletonForm", "fsSkeletonFormLines"] }, { type: i9.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i9.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i9.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i7.FsFormDirective, selector: "[fsForm]", inputs: ["wrapperSelector", "messageSelector", "hintSelector", "labelSelector", "autocomplete", "shortcuts", "confirm", "confirmDialog", "confirmDrawer", "confirmBrowser", "confirmTabs", "dirtySubmitButton", "submit", "successDelay", "errorDelay", "tabGroup", "deactivationGuard"], outputs: ["fsForm", "invalid", "valid", "submitted", "reseted", "cleared"], exportAs: ["fsForm"] }, { type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i11.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["id", "disabled", "required", "type", "value", "readonly", "placeholder", "errorStateMatcher", "aria-describedby"], exportAs: ["matInput"] }, { type: i9.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i9.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i9.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i9.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i7.FsFormRequiredDirective, selector: "[fsFormRequired],[ngModel][required]", inputs: ["fsFormRequired", "required", "fsFormRequiredMessage"] }, { type: i7.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
551
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ContentLayoutComponent, decorators: [{
532
+ ContentPageComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ContentPageComponent, deps: [{ token: FS_CONTENT_CONFIG }, { token: MAT_DIALOG_DATA }, { token: i1.MatDialogRef }, { token: i2.FsMessage }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
533
+ ContentPageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: ContentPageComponent, selector: "ng-component", viewQueries: [{ propertyName: "textEditors", predicate: FsTextEditorComponent, descendants: true }], ngImport: i0, template: "<form fsForm [submit]=\"save\" *fsSkeletonForm=\"contentPage\">\n <fs-dialog>\n <h1 mat-dialog-title>{{contentPage.id ? 'Page' : 'Create Page'}}</h1>\n <div mat-dialog-content>\n <div class=\"fs-column\">\n <mat-form-field>\n <mat-select\n [(ngModel)]=\"contentPage.type\"\n name=\"type\"\n required\n placeholder=\"Type\">\n <mat-option\n *ngFor=\"let item of PageTypes\"\n [value]=\"item.value\">\n {{ item.name }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field *ngIf=\"contentLayouts\">\n <mat-select\n [(ngModel)]=\"contentPage.contentLayoutId\"\n required\n name=\"contentLayoutId\"\n placeholder=\"Layout\">\n <mat-option\n *ngFor=\"let item of contentLayouts\"\n [value]=\"item.id\">\n {{ item.name }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field>\n <input\n matInput\n [(ngModel)]=\"contentPage.name\"\n name=\"name\"\n required\n placeholder=\"Name\">\n </mat-form-field>\n <mat-form-field>\n <input\n matInput\n [(ngModel)]=\"contentPage.path\"\n name=\"path\"\n required\n placeholder=\"Path\">\n </mat-form-field>\n <mat-form-field>\n <input\n matInput\n [(ngModel)]=\"contentPage.title\"\n name=\"title\"\n placeholder=\"Title\">\n </mat-form-field>\n </div>\n </div>\n\n <div mat-dialog-actions>\n <fs-form-dialog-actions>\n </fs-form-dialog-actions>\n </div>\n </fs-dialog>\n</form>\n", styles: [""], components: [{ type: i3.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileActionPlacement", "mobileWidth", "mode"] }, { type: i4$1.MatFormField, selector: "mat-form-field", inputs: ["color", "floatLabel", "appearance", "hideRequiredMarker", "hintLabel"], exportAs: ["matFormField"] }, { type: i5$2.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i6$1.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { type: i5$1.FsFormDialogActionsComponent, selector: "fs-form-dialog-actions", inputs: ["save", "create", "close", "done", "closeData", "name"] }], directives: [{ type: i13.FsSkeletonFormDirective, selector: "[fsSkeletonForm]", inputs: ["fsSkeletonForm", "fsSkeletonFormLines"] }, { type: i7$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i7$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i7$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5$1.FsFormDirective, selector: "[fsForm]", inputs: ["wrapperSelector", "messageSelector", "hintSelector", "labelSelector", "autocomplete", "shortcuts", "confirm", "confirmDialog", "confirmDrawer", "confirmBrowser", "confirmTabs", "dirtySubmitButton", "submit", "successDelay", "errorDelay", "tabGroup", "deactivationGuard"], outputs: ["fsForm", "invalid", "valid", "submitted", "reseted", "cleared"], exportAs: ["fsForm"] }, { type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i7$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i7$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i7$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i5$1.FsFormRequiredDirective, selector: "[fsFormRequired],[ngModel][required]", inputs: ["fsFormRequired", "required", "fsFormRequiredMessage"] }, { type: i10$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i10$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["id", "disabled", "required", "type", "value", "readonly", "placeholder", "errorStateMatcher", "aria-describedby"], exportAs: ["matInput"] }, { type: i7$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i5$1.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
534
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ContentPageComponent, decorators: [{
552
535
  type: Component,
553
536
  args: [{
554
- templateUrl: './content-layout.component.html',
555
- styleUrls: ['./content-layout.component.scss'],
537
+ templateUrl: './content-page.component.html',
538
+ styleUrls: ['./content-page.component.scss'],
556
539
  changeDetection: ChangeDetectionStrategy.OnPush,
557
540
  }]
558
541
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
@@ -566,41 +549,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
566
549
  args: [FsTextEditorComponent]
567
550
  }] } });
568
551
 
569
- class FsContentLayoutsComponent {
552
+ class FsContentPagesComponent {
570
553
  constructor(_config, _dialog) {
571
554
  this._config = _config;
572
555
  this._dialog = _dialog;
556
+ this.pageTypes = index(PageTypes, 'value', 'name');
573
557
  this._destroy$ = new Subject();
574
558
  }
575
559
  ngOnInit() {
576
560
  this._initListConfig();
577
561
  }
578
- openEditor(contentLayout) {
562
+ openEditor(contentPage) {
579
563
  this._dialog.open(EditorComponent, {
580
- maxWidth: null,
581
- maxHeight: null,
582
564
  data: {
583
- styles: contentLayout.styles,
584
- content: contentLayout.content,
565
+ contentPage,
566
+ config: this._config,
567
+ title: 'Page',
568
+ contentConfig: this._config,
585
569
  save: (data) => {
586
- return this._config.saveContentLayout(Object.assign({ id: contentLayout.id }, data));
570
+ return this._config.saveContentPage(data);
571
+ },
572
+ openSettings: (data) => {
573
+ return this.openContentPage(data);
587
574
  },
588
575
  },
576
+ maxWidth: '100vw',
577
+ width: '100%',
578
+ height: '100%',
579
+ autoFocus: false,
589
580
  })
590
581
  .afterClosed()
591
- .pipe(takeUntil(this._destroy$))
592
- .subscribe(() => {
593
- this.listComponent.reload();
594
- });
595
- }
596
- openLayout(contentLayout) {
597
- this._dialog.open(ContentLayoutComponent, {
598
- data: {
599
- contentLayout,
600
- },
601
- })
602
- .afterClosed()
603
- .pipe(filter((_contentLayout) => !!_contentLayout), takeUntil(this._destroy$))
582
+ .pipe(filter((_contentPage) => !!_contentPage), takeUntil(this._destroy$))
604
583
  .subscribe(() => {
605
584
  this.listComponent.reload();
606
585
  });
@@ -609,9 +588,15 @@ class FsContentLayoutsComponent {
609
588
  this._destroy$.next();
610
589
  this._destroy$.complete();
611
590
  }
591
+ openContentPage(contentPage) {
592
+ return this._dialog.open(ContentPageComponent, {
593
+ data: { contentPage },
594
+ })
595
+ .afterClosed()
596
+ .pipe(takeUntil(this._destroy$));
597
+ }
612
598
  _initListConfig() {
613
599
  this.listConfig = {
614
- paging: false,
615
600
  filters: [
616
601
  {
617
602
  name: 'keyword',
@@ -623,14 +608,21 @@ class FsContentLayoutsComponent {
623
608
  {
624
609
  label: 'Create',
625
610
  click: () => {
626
- this.openLayout({});
611
+ this.openContentPage({
612
+ type: PageType.StandardPage,
613
+ })
614
+ .pipe(filter((contentPage) => !!contentPage))
615
+ .subscribe((contentPage) => {
616
+ this.openEditor(contentPage);
617
+ this.listComponent.reload();
618
+ });
627
619
  },
628
620
  },
629
621
  ],
630
622
  rowActions: [
631
623
  {
632
624
  click: (data) => {
633
- return this._config.deleteContentLayout(data);
625
+ return this._config.deleteContentPage(data);
634
626
  },
635
627
  remove: {
636
628
  title: 'Confirm',
@@ -641,9 +633,9 @@ class FsContentLayoutsComponent {
641
633
  },
642
634
  ],
643
635
  fetch: (query) => {
644
- return this._config.loadContentLayouts(query)
645
- .pipe(map((contentLayouts) => {
646
- return { data: contentLayouts };
636
+ return this._config.loadContentPages(query)
637
+ .pipe(map((response) => {
638
+ return { data: response.contentPages, paging: response.paging };
647
639
  }));
648
640
  },
649
641
  restore: {
@@ -652,35 +644,42 @@ class FsContentLayoutsComponent {
652
644
  menuLabel: 'Restore',
653
645
  reload: true,
654
646
  click: (row) => {
655
- return this._config.saveContentLayout({ id: row.id, state: 'active' });
647
+ return this._config.saveContentPage({ id: row.id, state: 'active' });
656
648
  },
657
649
  },
658
650
  };
659
651
  }
660
652
  }
661
- FsContentLayoutsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentLayoutsComponent, deps: [{ token: FS_CONTENT_CONFIG }, { token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
662
- FsContentLayoutsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: FsContentLayoutsComponent, selector: "fs-content-layouts", viewQueries: [{ propertyName: "listComponent", first: true, predicate: FsListComponent, descendants: true }], ngImport: i0, template: "<fs-list [config]=\"listConfig\">\n <fs-list-column name=\"design\" width=\"1%\">\n <ng-template fs-list-cell let-row=\"row\">\n <a (click)=\"openEditor(row)\"><mat-icon>design_services</mat-icon></a>\n </ng-template>\n </fs-list-column>\n <fs-list-column name=\"name\" title=\"Name\" [sortable]=\"true\">\n <ng-template fs-list-cell let-row=\"row\">\n <a (click)=\"openLayout(row)\">{{row.name}}</a>\n </ng-template>\n </fs-list-column>\n <fs-list-column name=\"modify_date\" title=\"Modified\" [sortable]=\"true\">\n <ng-template fs-list-cell let-row=\"row\">\n {{row.modifyDate | fsDate: 'date-time-yearless'}}\n </ng-template>\n </fs-list-column>\n</fs-list>\n", styles: [""], components: [{ type: i2$1.FsListComponent, selector: "fs-list", inputs: ["config", "loaderLines"], outputs: ["filtersReady"] }, { type: i5$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i2$1.FsListColumnDirective, selector: "fs-list-column", inputs: ["show", "title", "name", "customize", "sortable", "sortableDefault", "direction", "align", "width", "class"] }, { type: i2$1.FsListCellDirective, selector: "[fs-list-cell]", inputs: ["colspan", "align", "class"] }], pipes: { "fsDate": i3$1.FsDatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
663
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentLayoutsComponent, decorators: [{
653
+ FsContentPagesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentPagesComponent, deps: [{ token: FS_CONTENT_CONFIG }, { token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
654
+ FsContentPagesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: FsContentPagesComponent, selector: "fs-content-pages", inputs: { htmlEditorConfig: "htmlEditorConfig" }, viewQueries: [{ propertyName: "listComponent", first: true, predicate: FsListComponent, descendants: true }], ngImport: i0, template: "<fs-list [config]=\"listConfig\">\n <fs-list-column name=\"name\" title=\"Name\" [sortable]=\"true\">\n <ng-template fs-list-cell let-row=\"row\">\n <a (click)=\"openEditor(row)\">{{row.name}}</a>\n </ng-template>\n </fs-list-column>\n <fs-list-column name=\"path\" title=\"Path\" [sortable]=\"true\">\n <ng-template fs-list-cell let-row=\"row\">\n <a [href]=\"'/' + row.path\" target=\"_black\">/{{row.path}}</a>\n </ng-template>\n </fs-list-column>\n <fs-list-column name=\"type\" title=\"Type\" [sortable]=\"true\">\n <ng-template fs-list-cell let-row=\"row\">\n {{pageTypes[row.type]}}\n </ng-template>\n </fs-list-column>\n <fs-list-column name=\"modify_date\" title=\"Modified\" [sortable]=\"true\">\n <ng-template fs-list-cell let-row=\"row\">\n {{row.modifyDate | fsDate: 'date-time-yearless'}}\n </ng-template>\n </fs-list-column>\n</fs-list>\n", styles: [":host ::ng-deep .modified,:host ::ng-deep .name{width:1%;white-space:nowrap}:host ::ng-deep .preview-content img{display:none}.preview-content{position:relative;max-height:100px;max-width:100%;overflow:hidden;-webkit-mask-image:-webkit-gradient(linear,left 60%,left bottom,from(black),to(rgba(0,0,0,0)))}\n"], components: [{ type: i2$1.FsListComponent, selector: "fs-list", inputs: ["config", "loaderLines"], outputs: ["filtersReady"] }], directives: [{ type: i2$1.FsListColumnDirective, selector: "fs-list-column", inputs: ["show", "title", "name", "customize", "sortable", "sortableDefault", "direction", "align", "width", "class"] }, { type: i2$1.FsListCellDirective, selector: "[fs-list-cell]", inputs: ["colspan", "align", "class"] }], pipes: { "fsDate": i3$1.FsDatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
655
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentPagesComponent, decorators: [{
664
656
  type: Component,
665
657
  args: [{
666
- selector: 'fs-content-layouts',
667
- templateUrl: './content-layouts.component.html',
668
- styleUrls: ['./content-layouts.component.scss'],
658
+ selector: 'fs-content-pages',
659
+ templateUrl: './content-pages.component.html',
660
+ styleUrls: ['./content-pages.component.scss'],
669
661
  changeDetection: ChangeDetectionStrategy.OnPush,
670
662
  }]
671
663
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
672
664
  type: Inject,
673
665
  args: [FS_CONTENT_CONFIG]
674
- }] }, { type: i1.MatDialog }]; }, propDecorators: { listComponent: [{
666
+ }] }, { type: i1.MatDialog }]; }, propDecorators: { htmlEditorConfig: [{
667
+ type: Input
668
+ }], listComponent: [{
675
669
  type: ViewChild,
676
670
  args: [FsListComponent]
677
671
  }] } });
678
672
 
679
- class FsContentLayoutsModule {
673
+ class FsContentPagesModule {
674
+ static forRoot() {
675
+ return {
676
+ ngModule: FsContentPagesModule,
677
+ };
678
+ }
680
679
  }
681
- FsContentLayoutsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentLayoutsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
682
- FsContentLayoutsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentLayoutsModule, declarations: [ContentLayoutComponent,
683
- FsContentLayoutsComponent], imports: [CommonModule,
680
+ FsContentPagesModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentPagesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
681
+ FsContentPagesModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentPagesModule, declarations: [FsContentPagesComponent,
682
+ ContentPageComponent], imports: [CommonModule,
684
683
  FormsModule,
685
684
  MatDialogModule,
686
685
  MatInputModule,
@@ -698,8 +697,8 @@ FsContentLayoutsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0",
698
697
  FsHtmlEditorModule,
699
698
  FsDialogModule,
700
699
  FsTextEditorModule,
701
- FsContentEditorModule], exports: [FsContentLayoutsComponent] });
702
- FsContentLayoutsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentLayoutsModule, imports: [[
700
+ FsContentEditorModule], exports: [FsContentPagesComponent] });
701
+ FsContentPagesModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentPagesModule, imports: [[
703
702
  CommonModule,
704
703
  FormsModule,
705
704
  MatDialogModule,
@@ -720,7 +719,7 @@ FsContentLayoutsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0",
720
719
  FsTextEditorModule,
721
720
  FsContentEditorModule,
722
721
  ]] });
723
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentLayoutsModule, decorators: [{
722
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentPagesModule, decorators: [{
724
723
  type: NgModule,
725
724
  args: [{
726
725
  imports: [
@@ -745,37 +744,132 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
745
744
  FsContentEditorModule,
746
745
  ],
747
746
  exports: [
748
- FsContentLayoutsComponent,
747
+ FsContentPagesComponent,
749
748
  ],
750
749
  declarations: [
751
- ContentLayoutComponent,
752
- FsContentLayoutsComponent,
750
+ FsContentPagesComponent,
751
+ ContentPageComponent,
752
+ ],
753
+ }]
754
+ }] });
755
+
756
+ class ContentStyleComponent {
757
+ constructor(_config, _message, _cdRef) {
758
+ this._config = _config;
759
+ this._message = _message;
760
+ this._cdRef = _cdRef;
761
+ this.height = '100%';
762
+ this.contentStyle = null;
763
+ this.styleConfig = {
764
+ tabSize: 2,
765
+ language: 'scss',
766
+ height: '100%',
767
+ };
768
+ this._destroy$ = new Subject();
769
+ }
770
+ ngOnInit() {
771
+ this.styleConfig.height = this.height;
772
+ this._config.loadContentStyle()
773
+ .subscribe((contentStyle) => {
774
+ this.contentStyle = contentStyle;
775
+ this._cdRef.markForCheck();
776
+ });
777
+ }
778
+ ngOnDestroy() {
779
+ this._destroy$.next();
780
+ this._destroy$.complete();
781
+ }
782
+ save() {
783
+ this._config.saveContentStyle(this.contentStyle)
784
+ .pipe(tap((contentStyle) => {
785
+ this.contentStyle = Object.assign(Object.assign({}, this.contentStyle), contentStyle);
786
+ this._cdRef.markForCheck();
787
+ this._message.success('Saved Changes');
788
+ })).subscribe();
789
+ }
790
+ }
791
+ ContentStyleComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ContentStyleComponent, deps: [{ token: FS_CONTENT_CONFIG }, { token: i2.FsMessage }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
792
+ ContentStyleComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: ContentStyleComponent, selector: "fs-content-style", inputs: { height: "height" }, viewQueries: [{ propertyName: "textEditors", first: true, predicate: FsTextEditorComponent, descendants: true }, { propertyName: "form", first: true, predicate: FsFormDirective, descendants: true }], ngImport: i0, template: "<ng-container *fsSkeletonForm=\"contentStyle\">\n <fs-text-editor \n [(ngModel)]=\"contentStyle.scss\" \n name=\"contentStyle\"\n [fsModelChangeOptions]=\"{ debounce: 300 }\"\n (fsModelChange)=\"save()\"\n [config]=\"styleConfig\">\n </fs-text-editor> \n</ng-container>\n", styles: [""], components: [{ type: i8.FsTextEditorComponent, selector: "fs-text-editor", inputs: ["config", "scrollable"], outputs: ["ready", "blur"] }], directives: [{ type: i13.FsSkeletonFormDirective, selector: "[fsSkeletonForm]", inputs: ["fsSkeletonForm", "fsSkeletonFormLines"] }, { type: i7$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i7$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i12.FsModelChangeDirective, selector: "[fsModelChange]", inputs: ["fsModelChangeOptions"], outputs: ["fsModelChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
793
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ContentStyleComponent, decorators: [{
794
+ type: Component,
795
+ args: [{
796
+ selector: 'fs-content-style',
797
+ templateUrl: './content-style.component.html',
798
+ styleUrls: ['./content-style.component.scss'],
799
+ changeDetection: ChangeDetectionStrategy.OnPush,
800
+ }]
801
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
802
+ type: Inject,
803
+ args: [FS_CONTENT_CONFIG]
804
+ }] }, { type: i2.FsMessage }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { textEditors: [{
805
+ type: ViewChild,
806
+ args: [FsTextEditorComponent]
807
+ }], form: [{
808
+ type: ViewChild,
809
+ args: [FsFormDirective]
810
+ }], height: [{
811
+ type: Input
812
+ }] } });
813
+
814
+ class FsContentStyleModule {
815
+ }
816
+ FsContentStyleModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentStyleModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
817
+ FsContentStyleModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentStyleModule, declarations: [ContentStyleComponent], imports: [CommonModule,
818
+ FormsModule,
819
+ MatButtonModule,
820
+ FsTextEditorModule,
821
+ FsSkeletonModule,
822
+ FsCommonModule,
823
+ FsContentEditorModule], exports: [ContentStyleComponent] });
824
+ FsContentStyleModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentStyleModule, imports: [[
825
+ CommonModule,
826
+ FormsModule,
827
+ MatButtonModule,
828
+ FsTextEditorModule,
829
+ FsSkeletonModule,
830
+ FsCommonModule,
831
+ FsContentEditorModule,
832
+ ]] });
833
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentStyleModule, decorators: [{
834
+ type: NgModule,
835
+ args: [{
836
+ imports: [
837
+ CommonModule,
838
+ FormsModule,
839
+ MatButtonModule,
840
+ FsTextEditorModule,
841
+ FsSkeletonModule,
842
+ FsCommonModule,
843
+ FsContentEditorModule,
844
+ ],
845
+ exports: [
846
+ ContentStyleComponent,
847
+ ],
848
+ declarations: [
849
+ ContentStyleComponent,
753
850
  ],
754
851
  }]
755
852
  }] });
756
853
 
757
854
  class ContentRendererComponent {
758
- constructor(_sanitizer, _router, _el) {
855
+ constructor(_sanitizer, _router, _el, _htmlRenderer) {
759
856
  this._sanitizer = _sanitizer;
760
857
  this._router = _router;
761
858
  this._el = _el;
859
+ this._htmlRenderer = _htmlRenderer;
762
860
  this._destroy$ = new Subject();
763
861
  }
764
- set contentPage(contentPage) {
765
- if (contentPage) {
766
- this.content = this._sanitizer.bypassSecurityTrustHtml(contentPage.content);
767
- this.styles = contentPage.styles;
768
- }
862
+ ngOnInit() {
863
+ this._htmlRenderer.addStyle(this.contentPage.styles, { id: 'contentPageStyles' });
864
+ this.content = this._sanitizer.bypassSecurityTrustHtml(this.contentPage.content);
769
865
  }
770
866
  ngAfterViewChecked() {
771
- let el = document.querySelector('#contentPageStyles');
772
- if (!el) {
773
- el = document.createElement('style');
774
- el.setAttribute('id', 'contentPageStyles');
775
- document.getElementsByTagName('head')[0].appendChild(el);
776
- }
777
- el.innerHTML = this.styles;
778
867
  this.registerHrefs();
868
+ if (this.contentPage.js) {
869
+ const script = document.createElement('script');
870
+ script.text = this.contentPage.js;
871
+ this.script.nativeElement.after(script);
872
+ }
779
873
  }
780
874
  registerHrefs() {
781
875
  Array.from(this.el.querySelectorAll('a[href]'))
@@ -807,8 +901,8 @@ class ContentRendererComponent {
807
901
  }
808
902
  }
809
903
  }
810
- ContentRendererComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ContentRendererComponent, deps: [{ token: i1$1.DomSanitizer }, { token: i2$2.Router }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
811
- ContentRendererComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: ContentRendererComponent, selector: "fs-content-renderer", inputs: { contentPage: "contentPage" }, ngImport: i0, template: "<div *ngIf=\"content\" [innerHTML]=\"content\"></div>\n", styles: [""], directives: [{ type: i10.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
904
+ ContentRendererComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ContentRendererComponent, deps: [{ token: i1$1.DomSanitizer }, { token: i2$2.Router }, { token: i0.ElementRef }, { token: i3$2.HtmlRenderer }], target: i0.ɵɵFactoryTarget.Component });
905
+ ContentRendererComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: ContentRendererComponent, selector: "fs-content-renderer", inputs: { contentPage: "contentPage" }, viewQueries: [{ propertyName: "script", first: true, predicate: ["script"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div *ngIf=\"content\" [innerHTML]=\"content\"></div>\n<span #script></span>", styles: [""], directives: [{ type: i10$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
812
906
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ContentRendererComponent, decorators: [{
813
907
  type: Component,
814
908
  args: [{
@@ -817,28 +911,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
817
911
  styleUrls: ['./content-renderer.component.scss'],
818
912
  changeDetection: ChangeDetectionStrategy.OnPush,
819
913
  }]
820
- }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }, { type: i2$2.Router }, { type: i0.ElementRef }]; }, propDecorators: { contentPage: [{
914
+ }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }, { type: i2$2.Router }, { type: i0.ElementRef }, { type: i3$2.HtmlRenderer }]; }, propDecorators: { script: [{
915
+ type: ViewChild,
916
+ args: ['script', { read: ElementRef }]
917
+ }], contentPage: [{
821
918
  type: Input
822
919
  }] } });
823
920
 
824
921
  class FsContentComponent {
825
- constructor(_config, _title, _cdRef, _router, _el) {
922
+ constructor(_config, _title, _cdRef, _router, _el, _htmlRenderer) {
826
923
  this._config = _config;
827
924
  this._title = _title;
828
925
  this._cdRef = _cdRef;
829
926
  this._router = _router;
830
927
  this._el = _el;
928
+ this._htmlRenderer = _htmlRenderer;
831
929
  this._destroy$ = new Subject();
832
930
  }
833
931
  ngOnInit() {
834
- this.load();
932
+ this._initContent();
933
+ this._initStyles();
934
+ }
935
+ get el() {
936
+ return this._el.nativeElement;
937
+ }
938
+ ngOnDestroy() {
939
+ this._destroy$.next();
940
+ this._destroy$.complete();
941
+ this._title.setTitle('');
942
+ }
943
+ _initStyles() {
944
+ if (this._config.loadContentStyleCss) {
945
+ this._config.loadContentStyleCss()
946
+ .subscribe((styles) => {
947
+ this._htmlRenderer.addStyle(styles, { id: 'content-sytle' });
948
+ });
949
+ }
950
+ }
951
+ _initContent() {
952
+ this._loadContent();
835
953
  this._router.events
836
954
  .pipe(filter((e) => e instanceof NavigationEnd), takeUntil(this._destroy$))
837
- .subscribe(() => {
838
- this.load();
955
+ .subscribe((e) => {
956
+ this._loadContent();
839
957
  });
840
958
  }
841
- load() {
959
+ _loadContent() {
842
960
  const path = window.location.pathname;
843
961
  this._config.loadContent(path)
844
962
  .subscribe((contentPage) => {
@@ -856,17 +974,9 @@ class FsContentComponent {
856
974
  this._cdRef.markForCheck();
857
975
  });
858
976
  }
859
- get el() {
860
- return this._el.nativeElement;
861
- }
862
- ngOnDestroy() {
863
- this._destroy$.next();
864
- this._destroy$.complete();
865
- this._title.setTitle('');
866
- }
867
977
  }
868
- FsContentComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentComponent, deps: [{ token: FS_CONTENT_CONFIG }, { token: i1$1.Title }, { token: i0.ChangeDetectorRef }, { token: i2$2.Router }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
869
- FsContentComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: FsContentComponent, selector: "fs-content", ngImport: i0, template: "<fs-content-renderer *ngIf=\"contentPage\" [contentPage]=\"contentPage\"></fs-content-renderer>", styles: [""], components: [{ type: ContentRendererComponent, selector: "fs-content-renderer", inputs: ["contentPage"] }], directives: [{ type: i10.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
978
+ FsContentComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentComponent, deps: [{ token: FS_CONTENT_CONFIG }, { token: i1$1.Title }, { token: i0.ChangeDetectorRef }, { token: i2$2.Router }, { token: i0.ElementRef }, { token: i3$2.HtmlRenderer }], target: i0.ɵɵFactoryTarget.Component });
979
+ FsContentComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: FsContentComponent, selector: "fs-content", ngImport: i0, template: "<ng-container *ngIf=\"contentPage\">\n <fs-content-renderer [contentPage]=\"contentPage\"></fs-content-renderer>\n</ng-container>", styles: [""], components: [{ type: ContentRendererComponent, selector: "fs-content-renderer", inputs: ["contentPage"] }], directives: [{ type: i10$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
870
980
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentComponent, decorators: [{
871
981
  type: Component,
872
982
  args: [{
@@ -878,7 +988,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
878
988
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
879
989
  type: Inject,
880
990
  args: [FS_CONTENT_CONFIG]
881
- }] }, { type: i1$1.Title }, { type: i0.ChangeDetectorRef }, { type: i2$2.Router }, { type: i0.ElementRef }]; } });
991
+ }] }, { type: i1$1.Title }, { type: i0.ChangeDetectorRef }, { type: i2$2.Router }, { type: i0.ElementRef }, { type: i3$2.HtmlRenderer }]; } });
882
992
 
883
993
  class FsContentModule {
884
994
  }
@@ -911,5 +1021,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
911
1021
  * Generated bundle index. Do not edit.
912
1022
  */
913
1023
 
914
- export { FS_CONTENT_CONFIG, FsContentComponent, FsContentLayoutsComponent, FsContentLayoutsModule, FsContentModule, FsContentPagesComponent, FsContentPagesModule };
1024
+ export { ContentStyleComponent, FS_CONTENT_CONFIG, FsContentComponent, FsContentLayoutsComponent, FsContentLayoutsModule, FsContentModule, FsContentPagesComponent, FsContentPagesModule, FsContentStyleModule };
915
1025
  //# sourceMappingURL=firestitch-content.js.map