@firestitch/content 12.2.2 → 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 +2 -1
  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 +24 -22
  13. package/app/modules/editor/fs-content-editor.module.d.ts +8 -5
  14. package/bundles/firestitch-content.umd.js +620 -523
  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 +11 -8
  23. package/esm2015/app/modules/content-pages/components/content-pages/content-pages.component.js +16 -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 +76 -116
  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 +446 -353
  32. package/fesm2015/firestitch-content.js.map +1 -1
  33. package/package.json +6 -5
  34. package/public_api.d.ts +5 -3
@@ -1,243 +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';
49
+ import * as i3$2 from '@firestitch/body';
46
50
 
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;
51
+ class EditorComponent {
52
+ constructor(_data, _dialogRef, _message, _cdRef) {
67
53
  this._data = _data;
68
54
  this._dialogRef = _dialogRef;
69
55
  this._message = _message;
70
56
  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
- }));
57
+ this.resizing = false;
58
+ this.editors = {
59
+ html: true,
60
+ scss: true,
61
+ js: false,
62
+ globalScss: false,
81
63
  };
64
+ this._destroy$ = new Subject();
82
65
  }
83
66
  ngOnInit() {
84
- this._dialogRef.updateSize('600px');
85
- this._fetchData();
67
+ this._dialogRef.addPanelClass('fs-content-editor-overlay-pane');
68
+ this.title = this._data.title;
69
+ this.contentPage = this._data.contentPage;
70
+ this._config = this._data.contentConfig;
71
+ this._save = this._data.save;
72
+ this.initTextEditors();
73
+ this.initGlobalContentStyle();
74
+ }
75
+ editorToggleChange(event) {
76
+ this.editors[event.value] = !this.editors[event.value];
86
77
  }
87
78
  ngOnDestroy() {
88
79
  this._destroy$.next();
89
80
  this._destroy$.complete();
90
81
  }
91
- _fetchData() {
92
- this._config.loadContentLayouts()
93
- .subscribe((contentLayouts) => {
94
- this.contentLayouts = contentLayouts;
82
+ globalScssChange() {
83
+ this._config.saveContentStyle(this.contentStyle)
84
+ .subscribe((contentStyle) => {
85
+ this.contentStyle = contentStyle;
86
+ this._message.success('Saved Changes');
95
87
  this._cdRef.markForCheck();
96
88
  });
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
- }] } });
126
-
127
- class EditorComponent {
128
- constructor(_data, _dialogRef, _dialog, _message, _cdRef) {
129
- this._data = _data;
130
- this._dialogRef = _dialogRef;
131
- this._dialog = _dialog;
132
- this._message = _message;
133
- this._cdRef = _cdRef;
134
- this.resizing = false;
135
- this.editors = { content: true, styles: true };
136
- this._destroy$ = new Subject();
137
- this.save = () => {
138
- return this._save({
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
- }));
148
- };
149
89
  }
150
- ngOnInit() {
151
- this.stylesConfig = {
90
+ initTextEditors() {
91
+ this.scssConfig = {
152
92
  tabSize: 2,
153
93
  language: 'scss',
154
94
  height: '100%',
155
95
  };
156
- this.contentConfig = {
96
+ this.jsConfig = {
97
+ tabSize: 2,
98
+ language: 'js',
99
+ height: '100%',
100
+ };
101
+ this.htmlConfig = {
157
102
  tabSize: 2,
158
103
  language: 'html',
159
104
  height: '100%',
160
105
  };
161
- this.title = this._data.title;
162
- this.contentPage = this._data.contentPage;
163
- this._save = this._data.save;
164
- this._initSeparator();
165
- }
166
- editorToggleChange(event) {
167
- this.editors[event.value] = !this.editors[event.value];
168
- this.updateEditorLayouts();
106
+ this.globalScssConfig = {
107
+ tabSize: 2,
108
+ language: 'scss',
109
+ height: '100%',
110
+ };
169
111
  }
170
- updateEditorLayouts() {
171
- setTimeout(() => {
172
- if (this.editors.content) {
173
- this.contentEditor.updateLayout();
174
- }
175
- if (this.editors.styles) {
176
- this.styleEditor.updateLayout();
177
- }
112
+ initGlobalContentStyle() {
113
+ this._config.loadContentStyle()
114
+ .subscribe((contentStyle) => {
115
+ this.contentStyle = contentStyle;
116
+ this._cdRef.markForCheck();
178
117
  });
179
118
  }
180
- ngOnDestroy() {
181
- this._destroy$.next();
182
- this._destroy$.complete();
183
- }
184
- stylesChanged() {
185
- this.form.triggerSubmit();
186
- }
187
- contentChanged() {
188
- this.form.triggerSubmit();
189
- }
190
- openSettings() {
191
- this._dialog.open(ContentPageComponent, {
192
- data: {
193
- contentPage: this.contentPage,
194
- },
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,
195
125
  })
196
- .afterClosed()
197
- .pipe(takeUntil(this._destroy$))
198
- .subscribe((contentPage) => {
126
+ .pipe(tap((contentPage) => {
199
127
  this.contentPage = Object.assign(Object.assign({}, this.contentPage), contentPage);
200
128
  this._cdRef.markForCheck();
201
- });
129
+ this._message.success('Saved Changes');
130
+ }))
131
+ .subscribe();
202
132
  }
203
- _initSeparator() {
204
- fromEvent(this.separator.nativeElement, 'mousedown')
133
+ openSettings() {
134
+ this._data.openSettings(this.contentPage)
205
135
  .pipe(takeUntil(this._destroy$))
206
- .subscribe((e) => {
207
- this._moveSeparator(e);
208
- });
209
- }
210
- _moveSeparator(separatorEvent) {
211
- let mouseDown = {
212
- clientX: separatorEvent.clientX,
213
- clientY: separatorEvent.clientY,
214
- offsetLeft: Number(this.separator.nativeElement.offsetLeft),
215
- offsetTop: Number(this.separator.nativeElement.offsetTop),
216
- firstWidth: Number(this.contentContainer.nativeElement.offsetWidth),
217
- secondWidth: Number(this.styleContainer.nativeElement.offsetWidth),
218
- };
219
- this.resizing = true;
220
- this._cdRef.markForCheck();
221
- fromEvent(document, 'mousemove')
222
- .pipe(finalize(() => {
223
- mouseDown = null;
224
- this.resizing = false;
136
+ .subscribe((contentPage) => {
137
+ this.contentPage = Object.assign(Object.assign({}, this.contentPage), contentPage);
225
138
  this._cdRef.markForCheck();
226
- this.updateEditorLayouts();
227
- }), takeUntil(fromEvent(this.separator.nativeElement, 'mouseup')
228
- .pipe(take(1), takeUntil(this._destroy$))), takeUntil(this._destroy$))
229
- .subscribe((e) => {
230
- const delta = { x: e.clientX - mouseDown.clientX,
231
- y: e.clientY - mouseDown.clientY };
232
- delta.x = Math.min(Math.max(delta.x, -mouseDown.firstWidth), mouseDown.secondWidth);
233
- this.separator.nativeElement.style.left = `${mouseDown.offsetLeft + delta.x}px`;
234
- this.contentContainer.nativeElement.style.width = `${mouseDown.firstWidth + delta.x}px`;
235
- this.styleContainer.nativeElement.style.width = `${mouseDown.secondWidth - delta.x}px`;
236
139
  });
237
140
  }
238
141
  }
239
- 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 });
240
- 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 {{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 <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>HTML</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]=\"contentConfig\">\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>SCSS</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]=\"stylesConfig\">\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;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}.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;flex-grow:1}.editors .editor.editor-styles:not(.styles-enabled),.editors .editor.editor-content:not(.content-enabled){display:none}.editors .editor .editor-container{height:100%;background:#1E1E1E;border-radius:5px}.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: ["ready", "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 });
241
144
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: EditorComponent, decorators: [{
242
145
  type: Component,
243
146
  args: [{
@@ -248,25 +151,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
248
151
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
249
152
  type: Inject,
250
153
  args: [MAT_DIALOG_DATA]
251
- }] }, { type: i1.MatDialogRef }, { type: i1.MatDialog }, { type: i2.FsMessage }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { form: [{
252
- type: ViewChild,
253
- args: [FsFormDirective]
254
- }], styleEditor: [{
255
- type: ViewChild,
256
- args: ['styleEditor']
257
- }], contentEditor: [{
258
- type: ViewChild,
259
- args: ['contentEditor']
260
- }], separator: [{
261
- type: ViewChild,
262
- args: ['separator', { static: true, read: ElementRef }]
263
- }], contentContainer: [{
264
- type: ViewChild,
265
- args: ['contentContainer', { static: true, read: ElementRef }]
266
- }], styleContainer: [{
267
- type: ViewChild,
268
- args: ['styleContainer', { static: true, read: ElementRef }]
269
- }] } });
154
+ }] }, { type: i1.MatDialogRef }, { type: i2.FsMessage }, { type: i0.ChangeDetectorRef }]; } });
270
155
 
271
156
  class FsContentEditorModule {
272
157
  }
@@ -280,10 +165,13 @@ FsContentEditorModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", v
280
165
  MatButtonToggleModule,
281
166
  FsListModule,
282
167
  FsFormModule,
168
+ FsSkeletonModule,
283
169
  FsLabelModule,
284
170
  FsHtmlEditorModule,
171
+ FsCommonModule,
285
172
  FsDialogModule,
286
- FsTextEditorModule], exports: [EditorComponent] });
173
+ FsTextEditorModule,
174
+ AngularSplitModule], exports: [EditorComponent] });
287
175
  FsContentEditorModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentEditorModule, imports: [[
288
176
  CommonModule,
289
177
  FormsModule,
@@ -294,10 +182,13 @@ FsContentEditorModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", v
294
182
  MatButtonToggleModule,
295
183
  FsListModule,
296
184
  FsFormModule,
185
+ FsSkeletonModule,
297
186
  FsLabelModule,
298
187
  FsHtmlEditorModule,
188
+ FsCommonModule,
299
189
  FsDialogModule,
300
190
  FsTextEditorModule,
191
+ AngularSplitModule,
301
192
  ]] });
302
193
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentEditorModule, decorators: [{
303
194
  type: NgModule,
@@ -312,10 +203,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
312
203
  MatButtonToggleModule,
313
204
  FsListModule,
314
205
  FsFormModule,
206
+ FsSkeletonModule,
315
207
  FsLabelModule,
316
208
  FsHtmlEditorModule,
209
+ FsCommonModule,
317
210
  FsDialogModule,
318
211
  FsTextEditorModule,
212
+ AngularSplitModule,
319
213
  ],
320
214
  exports: [
321
215
  EditorComponent,
@@ -326,44 +220,112 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
326
220
  }]
327
221
  }] });
328
222
 
329
- 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 {
330
282
  constructor(_config, _dialog) {
331
283
  this._config = _config;
332
284
  this._dialog = _dialog;
333
- this.pageTypes = index(PageTypes, 'value', 'name');
334
285
  this._destroy$ = new Subject();
335
286
  }
336
287
  ngOnInit() {
337
288
  this._initListConfig();
338
289
  }
339
- openEditor(contentPage) {
290
+ openEditor(contentLayout) {
340
291
  this._dialog.open(EditorComponent, {
292
+ maxWidth: '100vw',
293
+ width: '100%',
294
+ height: '100%',
341
295
  data: {
342
- contentPage,
343
- config: this._config,
344
- title: 'Page',
296
+ contentPage: contentLayout,
297
+ title: 'Layout',
298
+ contentConfig: this._config,
345
299
  save: (data) => {
346
- return this._config.saveContentPage(data);
300
+ return this._config.saveContentLayout(Object.assign({ id: contentLayout.id }, data));
301
+ },
302
+ openSettings: (data) => {
303
+ return this.openLayout(data);
347
304
  },
348
305
  },
349
- maxWidth: '100vw',
350
- maxHeight: '100vw',
351
- width: '100%',
352
- height: '100%',
353
- autoFocus: false,
354
306
  })
355
307
  .afterClosed()
356
- .pipe(filter((_contentPage) => !!_contentPage), takeUntil(this._destroy$))
308
+ .pipe(takeUntil(this._destroy$))
357
309
  .subscribe(() => {
358
310
  this.listComponent.reload();
359
311
  });
360
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
+ }
361
322
  ngOnDestroy() {
362
323
  this._destroy$.next();
363
324
  this._destroy$.complete();
364
325
  }
365
326
  _initListConfig() {
366
327
  this.listConfig = {
328
+ paging: false,
367
329
  filters: [
368
330
  {
369
331
  name: 'keyword',
@@ -375,17 +337,8 @@ class FsContentPagesComponent {
375
337
  {
376
338
  label: 'Create',
377
339
  click: () => {
378
- this._dialog.open(ContentPageComponent, {
379
- data: {
380
- contentPage: {
381
- type: PageType.StandardPage,
382
- },
383
- },
384
- })
385
- .afterClosed()
386
- .pipe(filter((contentPage) => !!contentPage), takeUntil(this._destroy$))
387
- .subscribe((contentPage) => {
388
- this.openEditor(contentPage);
340
+ this.openLayout({})
341
+ .subscribe(() => {
389
342
  this.listComponent.reload();
390
343
  });
391
344
  },
@@ -394,7 +347,7 @@ class FsContentPagesComponent {
394
347
  rowActions: [
395
348
  {
396
349
  click: (data) => {
397
- return this._config.deleteContentPage(data);
350
+ return this._config.deleteContentLayout(data);
398
351
  },
399
352
  remove: {
400
353
  title: 'Confirm',
@@ -405,9 +358,9 @@ class FsContentPagesComponent {
405
358
  },
406
359
  ],
407
360
  fetch: (query) => {
408
- return this._config.loadContentPages(query)
409
- .pipe(map((response) => {
410
- return { data: response.contentPages, paging: response.paging };
361
+ return this._config.loadContentLayouts(query)
362
+ .pipe(map((contentLayouts) => {
363
+ return { data: contentLayouts };
411
364
  }));
412
365
  },
413
366
  restore: {
@@ -416,42 +369,35 @@ class FsContentPagesComponent {
416
369
  menuLabel: 'Restore',
417
370
  reload: true,
418
371
  click: (row) => {
419
- return this._config.saveContentPage({ id: row.id, state: 'active' });
372
+ return this._config.saveContentLayout({ id: row.id, state: 'active' });
420
373
  },
421
374
  },
422
375
  };
423
376
  }
424
377
  }
425
- 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 });
426
- 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 });
427
- 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: [{
428
381
  type: Component,
429
382
  args: [{
430
- selector: 'fs-content-pages',
431
- templateUrl: './content-pages.component.html',
432
- styleUrls: ['./content-pages.component.scss'],
383
+ selector: 'fs-content-layouts',
384
+ templateUrl: './content-layouts.component.html',
385
+ styleUrls: ['./content-layouts.component.scss'],
433
386
  changeDetection: ChangeDetectionStrategy.OnPush,
434
387
  }]
435
388
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
436
389
  type: Inject,
437
390
  args: [FS_CONTENT_CONFIG]
438
- }] }, { type: i1.MatDialog }]; }, propDecorators: { htmlEditorConfig: [{
439
- type: Input
440
- }], listComponent: [{
441
- type: ViewChild,
442
- args: [FsListComponent]
443
- }] } });
444
-
445
- class FsContentPagesModule {
446
- static forRoot() {
447
- return {
448
- ngModule: FsContentPagesModule,
449
- };
450
- }
391
+ }] }, { type: i1.MatDialog }]; }, propDecorators: { listComponent: [{
392
+ type: ViewChild,
393
+ args: [FsListComponent]
394
+ }] } });
395
+
396
+ class FsContentLayoutsModule {
451
397
  }
452
- FsContentPagesModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentPagesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
453
- FsContentPagesModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentPagesModule, declarations: [FsContentPagesComponent,
454
- 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,
455
401
  FormsModule,
456
402
  MatDialogModule,
457
403
  MatInputModule,
@@ -469,8 +415,8 @@ FsContentPagesModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", ve
469
415
  FsHtmlEditorModule,
470
416
  FsDialogModule,
471
417
  FsTextEditorModule,
472
- FsContentEditorModule], exports: [FsContentPagesComponent] });
473
- 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: [[
474
420
  CommonModule,
475
421
  FormsModule,
476
422
  MatDialogModule,
@@ -491,7 +437,7 @@ FsContentPagesModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", ve
491
437
  FsTextEditorModule,
492
438
  FsContentEditorModule,
493
439
  ]] });
494
- 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: [{
495
441
  type: NgModule,
496
442
  args: [{
497
443
  imports: [
@@ -516,34 +462,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
516
462
  FsContentEditorModule,
517
463
  ],
518
464
  exports: [
519
- FsContentPagesComponent,
465
+ FsContentLayoutsComponent,
520
466
  ],
521
467
  declarations: [
522
- FsContentPagesComponent,
523
- ContentPageComponent,
468
+ ContentLayoutComponent,
469
+ FsContentLayoutsComponent,
524
470
  ],
525
471
  }]
526
472
  }] });
527
473
 
528
- 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 {
529
490
  constructor(_config, _data, _dialogRef, _message, _cdRef) {
530
491
  this._config = _config;
531
492
  this._data = _data;
532
493
  this._dialogRef = _dialogRef;
533
494
  this._message = _message;
534
495
  this._cdRef = _cdRef;
535
- this.contentLayout = null;
496
+ this.contentPage = null;
497
+ this.PageTypes = PageTypes;
536
498
  this.editors = { content: true, styles: true };
537
499
  this._destroy$ = new Subject();
538
500
  this.save = () => {
539
- return this._config.saveContentLayout(this.contentLayout)
540
- .pipe(tap((contentLayout) => {
501
+ return this._config.saveContentPage(this.contentPage)
502
+ .pipe(tap((contentPage) => {
541
503
  this._message.success('Saved Changes');
542
- this._dialogRef.close(contentLayout);
504
+ this._dialogRef.close(contentPage);
543
505
  }));
544
506
  };
545
507
  }
546
508
  ngOnInit() {
509
+ this._dialogRef.updateSize('600px');
547
510
  this._fetchData();
548
511
  }
549
512
  ngOnDestroy() {
@@ -551,23 +514,28 @@ class ContentLayoutComponent {
551
514
  this._destroy$.complete();
552
515
  }
553
516
  _fetchData() {
554
- of(this._data.contentLayout)
555
- .pipe(switchMap((contentLayout) => {
556
- 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);
557
525
  }), takeUntil(this._destroy$))
558
- .subscribe((contentLayout) => {
559
- this.contentLayout = Object.assign({}, contentLayout);
526
+ .subscribe((contentPage) => {
527
+ this.contentPage = Object.assign({}, contentPage);
560
528
  this._cdRef.markForCheck();
561
529
  });
562
530
  }
563
531
  }
564
- 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 });
565
- 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 });
566
- 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: [{
567
535
  type: Component,
568
536
  args: [{
569
- templateUrl: './content-layout.component.html',
570
- styleUrls: ['./content-layout.component.scss'],
537
+ templateUrl: './content-page.component.html',
538
+ styleUrls: ['./content-page.component.scss'],
571
539
  changeDetection: ChangeDetectionStrategy.OnPush,
572
540
  }]
573
541
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
@@ -581,43 +549,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
581
549
  args: [FsTextEditorComponent]
582
550
  }] } });
583
551
 
584
- class FsContentLayoutsComponent {
552
+ class FsContentPagesComponent {
585
553
  constructor(_config, _dialog) {
586
554
  this._config = _config;
587
555
  this._dialog = _dialog;
556
+ this.pageTypes = index(PageTypes, 'value', 'name');
588
557
  this._destroy$ = new Subject();
589
558
  }
590
559
  ngOnInit() {
591
560
  this._initListConfig();
592
561
  }
593
- openEditor(contentLayout) {
562
+ openEditor(contentPage) {
594
563
  this._dialog.open(EditorComponent, {
595
- maxWidth: '100vw',
596
- maxHeight: '100vw',
597
- width: '100%',
598
- height: '100%',
599
564
  data: {
600
- contentPage: contentLayout,
601
- title: 'Layout',
565
+ contentPage,
566
+ config: this._config,
567
+ title: 'Page',
568
+ contentConfig: this._config,
602
569
  save: (data) => {
603
- 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);
604
574
  },
605
575
  },
576
+ maxWidth: '100vw',
577
+ width: '100%',
578
+ height: '100%',
579
+ autoFocus: false,
606
580
  })
607
581
  .afterClosed()
608
- .pipe(takeUntil(this._destroy$))
609
- .subscribe(() => {
610
- this.listComponent.reload();
611
- });
612
- }
613
- openLayout(contentLayout) {
614
- this._dialog.open(ContentLayoutComponent, {
615
- data: {
616
- contentLayout,
617
- },
618
- })
619
- .afterClosed()
620
- .pipe(filter((_contentLayout) => !!_contentLayout), takeUntil(this._destroy$))
582
+ .pipe(filter((_contentPage) => !!_contentPage), takeUntil(this._destroy$))
621
583
  .subscribe(() => {
622
584
  this.listComponent.reload();
623
585
  });
@@ -626,9 +588,15 @@ class FsContentLayoutsComponent {
626
588
  this._destroy$.next();
627
589
  this._destroy$.complete();
628
590
  }
591
+ openContentPage(contentPage) {
592
+ return this._dialog.open(ContentPageComponent, {
593
+ data: { contentPage },
594
+ })
595
+ .afterClosed()
596
+ .pipe(takeUntil(this._destroy$));
597
+ }
629
598
  _initListConfig() {
630
599
  this.listConfig = {
631
- paging: false,
632
600
  filters: [
633
601
  {
634
602
  name: 'keyword',
@@ -640,14 +608,21 @@ class FsContentLayoutsComponent {
640
608
  {
641
609
  label: 'Create',
642
610
  click: () => {
643
- 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
+ });
644
619
  },
645
620
  },
646
621
  ],
647
622
  rowActions: [
648
623
  {
649
624
  click: (data) => {
650
- return this._config.deleteContentLayout(data);
625
+ return this._config.deleteContentPage(data);
651
626
  },
652
627
  remove: {
653
628
  title: 'Confirm',
@@ -658,9 +633,9 @@ class FsContentLayoutsComponent {
658
633
  },
659
634
  ],
660
635
  fetch: (query) => {
661
- return this._config.loadContentLayouts(query)
662
- .pipe(map((contentLayouts) => {
663
- return { data: contentLayouts };
636
+ return this._config.loadContentPages(query)
637
+ .pipe(map((response) => {
638
+ return { data: response.contentPages, paging: response.paging };
664
639
  }));
665
640
  },
666
641
  restore: {
@@ -669,35 +644,42 @@ class FsContentLayoutsComponent {
669
644
  menuLabel: 'Restore',
670
645
  reload: true,
671
646
  click: (row) => {
672
- return this._config.saveContentLayout({ id: row.id, state: 'active' });
647
+ return this._config.saveContentPage({ id: row.id, state: 'active' });
673
648
  },
674
649
  },
675
650
  };
676
651
  }
677
652
  }
678
- 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 });
679
- 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 });
680
- 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: [{
681
656
  type: Component,
682
657
  args: [{
683
- selector: 'fs-content-layouts',
684
- templateUrl: './content-layouts.component.html',
685
- styleUrls: ['./content-layouts.component.scss'],
658
+ selector: 'fs-content-pages',
659
+ templateUrl: './content-pages.component.html',
660
+ styleUrls: ['./content-pages.component.scss'],
686
661
  changeDetection: ChangeDetectionStrategy.OnPush,
687
662
  }]
688
663
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
689
664
  type: Inject,
690
665
  args: [FS_CONTENT_CONFIG]
691
- }] }, { type: i1.MatDialog }]; }, propDecorators: { listComponent: [{
666
+ }] }, { type: i1.MatDialog }]; }, propDecorators: { htmlEditorConfig: [{
667
+ type: Input
668
+ }], listComponent: [{
692
669
  type: ViewChild,
693
670
  args: [FsListComponent]
694
671
  }] } });
695
672
 
696
- class FsContentLayoutsModule {
673
+ class FsContentPagesModule {
674
+ static forRoot() {
675
+ return {
676
+ ngModule: FsContentPagesModule,
677
+ };
678
+ }
697
679
  }
698
- FsContentLayoutsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentLayoutsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
699
- FsContentLayoutsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentLayoutsModule, declarations: [ContentLayoutComponent,
700
- 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,
701
683
  FormsModule,
702
684
  MatDialogModule,
703
685
  MatInputModule,
@@ -715,8 +697,8 @@ FsContentLayoutsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0",
715
697
  FsHtmlEditorModule,
716
698
  FsDialogModule,
717
699
  FsTextEditorModule,
718
- FsContentEditorModule], exports: [FsContentLayoutsComponent] });
719
- 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: [[
720
702
  CommonModule,
721
703
  FormsModule,
722
704
  MatDialogModule,
@@ -737,7 +719,7 @@ FsContentLayoutsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0",
737
719
  FsTextEditorModule,
738
720
  FsContentEditorModule,
739
721
  ]] });
740
- 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: [{
741
723
  type: NgModule,
742
724
  args: [{
743
725
  imports: [
@@ -762,37 +744,132 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
762
744
  FsContentEditorModule,
763
745
  ],
764
746
  exports: [
765
- FsContentLayoutsComponent,
747
+ FsContentPagesComponent,
766
748
  ],
767
749
  declarations: [
768
- ContentLayoutComponent,
769
- 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,
770
850
  ],
771
851
  }]
772
852
  }] });
773
853
 
774
854
  class ContentRendererComponent {
775
- constructor(_sanitizer, _router, _el) {
855
+ constructor(_sanitizer, _router, _el, _htmlRenderer) {
776
856
  this._sanitizer = _sanitizer;
777
857
  this._router = _router;
778
858
  this._el = _el;
859
+ this._htmlRenderer = _htmlRenderer;
779
860
  this._destroy$ = new Subject();
780
861
  }
781
- set contentPage(contentPage) {
782
- if (contentPage) {
783
- this.content = this._sanitizer.bypassSecurityTrustHtml(contentPage.content);
784
- this.styles = contentPage.styles;
785
- }
862
+ ngOnInit() {
863
+ this._htmlRenderer.addStyle(this.contentPage.styles, { id: 'contentPageStyles' });
864
+ this.content = this._sanitizer.bypassSecurityTrustHtml(this.contentPage.content);
786
865
  }
787
866
  ngAfterViewChecked() {
788
- let el = document.querySelector('#contentPageStyles');
789
- if (!el) {
790
- el = document.createElement('style');
791
- el.setAttribute('id', 'contentPageStyles');
792
- document.getElementsByTagName('head')[0].appendChild(el);
793
- }
794
- el.innerHTML = this.styles;
795
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
+ }
796
873
  }
797
874
  registerHrefs() {
798
875
  Array.from(this.el.querySelectorAll('a[href]'))
@@ -824,8 +901,8 @@ class ContentRendererComponent {
824
901
  }
825
902
  }
826
903
  }
827
- 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 });
828
- 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 });
829
906
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ContentRendererComponent, decorators: [{
830
907
  type: Component,
831
908
  args: [{
@@ -834,28 +911,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
834
911
  styleUrls: ['./content-renderer.component.scss'],
835
912
  changeDetection: ChangeDetectionStrategy.OnPush,
836
913
  }]
837
- }], 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: [{
838
918
  type: Input
839
919
  }] } });
840
920
 
841
921
  class FsContentComponent {
842
- constructor(_config, _title, _cdRef, _router, _el) {
922
+ constructor(_config, _title, _cdRef, _router, _el, _htmlRenderer) {
843
923
  this._config = _config;
844
924
  this._title = _title;
845
925
  this._cdRef = _cdRef;
846
926
  this._router = _router;
847
927
  this._el = _el;
928
+ this._htmlRenderer = _htmlRenderer;
848
929
  this._destroy$ = new Subject();
849
930
  }
850
931
  ngOnInit() {
851
- 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();
852
953
  this._router.events
853
954
  .pipe(filter((e) => e instanceof NavigationEnd), takeUntil(this._destroy$))
854
- .subscribe(() => {
855
- this.load();
955
+ .subscribe((e) => {
956
+ this._loadContent();
856
957
  });
857
958
  }
858
- load() {
959
+ _loadContent() {
859
960
  const path = window.location.pathname;
860
961
  this._config.loadContent(path)
861
962
  .subscribe((contentPage) => {
@@ -873,17 +974,9 @@ class FsContentComponent {
873
974
  this._cdRef.markForCheck();
874
975
  });
875
976
  }
876
- get el() {
877
- return this._el.nativeElement;
878
- }
879
- ngOnDestroy() {
880
- this._destroy$.next();
881
- this._destroy$.complete();
882
- this._title.setTitle('');
883
- }
884
977
  }
885
- 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 });
886
- 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 });
887
980
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsContentComponent, decorators: [{
888
981
  type: Component,
889
982
  args: [{
@@ -895,7 +988,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
895
988
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
896
989
  type: Inject,
897
990
  args: [FS_CONTENT_CONFIG]
898
- }] }, { 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 }]; } });
899
992
 
900
993
  class FsContentModule {
901
994
  }
@@ -928,5 +1021,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
928
1021
  * Generated bundle index. Do not edit.
929
1022
  */
930
1023
 
931
- export { FS_CONTENT_CONFIG, FsContentComponent, FsContentLayoutsComponent, FsContentLayoutsModule, FsContentModule, FsContentPagesComponent, FsContentPagesModule };
1024
+ export { ContentStyleComponent, FS_CONTENT_CONFIG, FsContentComponent, FsContentLayoutsComponent, FsContentLayoutsModule, FsContentModule, FsContentPagesComponent, FsContentPagesModule, FsContentStyleModule };
932
1025
  //# sourceMappingURL=firestitch-content.js.map