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