@firestitch/content 12.2.1 → 12.2.3

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