@candy-kingdom/bonnie-cms 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/README.md +7 -0
  2. package/esm2022/candy-kingdom-bonnie-cms.mjs +5 -0
  3. package/esm2022/index.mjs +16 -0
  4. package/esm2022/lib/admin-controls/admin-controls.component.mjs +44 -0
  5. package/esm2022/lib/admin-controls/index.mjs +2 -0
  6. package/esm2022/lib/bone-editors/bone-editor-base.component.mjs +143 -0
  7. package/esm2022/lib/bone-editors/index.mjs +3 -0
  8. package/esm2022/lib/bone-editors/unknown-bone-editor/index.mjs +2 -0
  9. package/esm2022/lib/bone-editors/unknown-bone-editor/unknown-bone-editor.component.mjs +18 -0
  10. package/esm2022/lib/bonnie-cms.module.mjs +105 -0
  11. package/esm2022/lib/core/DeviceType.mjs +8 -0
  12. package/esm2022/lib/core/DeviceVisibility.mjs +9 -0
  13. package/esm2022/lib/core/MediaType.mjs +2 -0
  14. package/esm2022/lib/core/TextEditorField.mjs +7 -0
  15. package/esm2022/lib/core/Utils.mjs +18 -0
  16. package/esm2022/lib/core/index.mjs +6 -0
  17. package/esm2022/lib/core-components/editable-group.mjs +84 -0
  18. package/esm2022/lib/core-components/editable.directive.mjs +173 -0
  19. package/esm2022/lib/core-components/form-base.component.mjs +34 -0
  20. package/esm2022/lib/core-components/index.mjs +5 -0
  21. package/esm2022/lib/core-components/link-popup/index.mjs +2 -0
  22. package/esm2022/lib/core-components/link-popup/link-popup.component.mjs +73 -0
  23. package/esm2022/lib/form-controls/form-controls.component.mjs +16 -0
  24. package/esm2022/lib/form-controls/index.mjs +2 -0
  25. package/esm2022/lib/generated/i-equatable.mjs +6 -0
  26. package/esm2022/lib/generated/i-setting.mjs +6 -0
  27. package/esm2022/lib/generated/index.mjs +14 -0
  28. package/esm2022/lib/generated/localized-text-setting-data.mjs +6 -0
  29. package/esm2022/lib/generated/setting-base.mjs +6 -0
  30. package/esm2022/lib/generated/setting-data.mjs +6 -0
  31. package/esm2022/lib/generated/setting-group.mjs +6 -0
  32. package/esm2022/lib/generated/setting.mjs +6 -0
  33. package/esm2022/lib/generated/text-setting-data.mjs +6 -0
  34. package/esm2022/lib/generated/text-setting-type.mjs +10 -0
  35. package/esm2022/lib/media-uploader/index.mjs +2 -0
  36. package/esm2022/lib/media-uploader/media-uploader.component.mjs +159 -0
  37. package/esm2022/lib/seo-form/index.mjs +2 -0
  38. package/esm2022/lib/seo-form/seo-form.component.mjs +42 -0
  39. package/esm2022/lib/skeleton-editor/BoneEditorMap.mjs +2 -0
  40. package/esm2022/lib/skeleton-editor/ContentPreset.mjs +9 -0
  41. package/esm2022/lib/skeleton-editor/IBoneEditor.mjs +2 -0
  42. package/esm2022/lib/skeleton-editor/IBoneTemplate.mjs +2 -0
  43. package/esm2022/lib/skeleton-editor/bone-editor-container/bone-editor-container.component.mjs +119 -0
  44. package/esm2022/lib/skeleton-editor/index.mjs +9 -0
  45. package/esm2022/lib/skeleton-editor/skeleton-editor-anchor.directive.mjs +16 -0
  46. package/esm2022/lib/skeleton-editor/skeleton-editor.component.mjs +107 -0
  47. package/esm2022/lib/text-form/TextInputStyle.mjs +7 -0
  48. package/esm2022/lib/text-form/index.mjs +3 -0
  49. package/esm2022/lib/text-form/text-form.component.mjs +33 -0
  50. package/esm2022/lib/translation-form/index.mjs +2 -0
  51. package/esm2022/lib/translation-form/translation-form.component.mjs +32 -0
  52. package/esm2022/lib/translation-input/index.mjs +2 -0
  53. package/esm2022/lib/translation-input/translation-input.component.mjs +42 -0
  54. package/esm2022/lib/translation-textarea/index.mjs +2 -0
  55. package/esm2022/lib/translation-textarea/translation-textarea.component.mjs +66 -0
  56. package/esm2022/lib/unknown-form/index.mjs +2 -0
  57. package/esm2022/lib/unknown-form/unknown-form.component.mjs +23 -0
  58. package/fesm2022/candy-kingdom-bonnie-cms.mjs +1343 -0
  59. package/fesm2022/candy-kingdom-bonnie-cms.mjs.map +1 -0
  60. package/index.d.ts +15 -0
  61. package/lib/admin-controls/admin-controls.component.d.ts +14 -0
  62. package/lib/admin-controls/index.d.ts +1 -0
  63. package/lib/bone-editors/bone-editor-base.component.d.ts +44 -0
  64. package/lib/bone-editors/index.d.ts +2 -0
  65. package/lib/bone-editors/unknown-bone-editor/index.d.ts +1 -0
  66. package/lib/bone-editors/unknown-bone-editor/unknown-bone-editor.component.d.ts +11 -0
  67. package/lib/bonnie-cms.module.d.ts +26 -0
  68. package/lib/core/DeviceType.d.ts +6 -0
  69. package/lib/core/DeviceVisibility.d.ts +7 -0
  70. package/lib/core/MediaType.d.ts +2 -0
  71. package/lib/core/TextEditorField.d.ts +5 -0
  72. package/lib/core/Utils.d.ts +4 -0
  73. package/lib/core/index.d.ts +5 -0
  74. package/lib/core-components/editable-group.d.ts +24 -0
  75. package/lib/core-components/editable.directive.d.ts +43 -0
  76. package/lib/core-components/form-base.component.d.ts +15 -0
  77. package/lib/core-components/index.d.ts +4 -0
  78. package/lib/core-components/link-popup/index.d.ts +1 -0
  79. package/lib/core-components/link-popup/link-popup.component.d.ts +28 -0
  80. package/lib/form-controls/form-controls.component.d.ts +7 -0
  81. package/lib/form-controls/index.d.ts +1 -0
  82. package/lib/generated/i-equatable.d.ts +6 -0
  83. package/lib/generated/i-setting.d.ts +8 -0
  84. package/lib/generated/index.d.ts +13 -0
  85. package/lib/generated/localized-text-setting-data.d.ts +11 -0
  86. package/lib/generated/setting-base.d.ts +8 -0
  87. package/lib/generated/setting-data.d.ts +8 -0
  88. package/lib/generated/setting-group.d.ts +10 -0
  89. package/lib/generated/setting.d.ts +9 -0
  90. package/lib/generated/text-setting-data.d.ts +10 -0
  91. package/lib/generated/text-setting-type.d.ts +8 -0
  92. package/lib/media-uploader/index.d.ts +1 -0
  93. package/lib/media-uploader/media-uploader.component.d.ts +34 -0
  94. package/lib/seo-form/index.d.ts +1 -0
  95. package/lib/seo-form/seo-form.component.d.ts +18 -0
  96. package/lib/skeleton-editor/BoneEditorMap.d.ts +3 -0
  97. package/lib/skeleton-editor/ContentPreset.d.ts +11 -0
  98. package/lib/skeleton-editor/IBoneEditor.d.ts +26 -0
  99. package/lib/skeleton-editor/IBoneTemplate.d.ts +5 -0
  100. package/lib/skeleton-editor/bone-editor-container/bone-editor-container.component.d.ts +32 -0
  101. package/lib/skeleton-editor/index.d.ts +8 -0
  102. package/lib/skeleton-editor/skeleton-editor-anchor.directive.d.ts +8 -0
  103. package/lib/skeleton-editor/skeleton-editor.component.d.ts +31 -0
  104. package/lib/text-form/TextInputStyle.d.ts +5 -0
  105. package/lib/text-form/index.d.ts +2 -0
  106. package/lib/text-form/text-form.component.d.ts +13 -0
  107. package/lib/translation-form/index.d.ts +1 -0
  108. package/lib/translation-form/translation-form.component.d.ts +14 -0
  109. package/lib/translation-input/index.d.ts +1 -0
  110. package/lib/translation-input/translation-input.component.d.ts +17 -0
  111. package/lib/translation-textarea/index.d.ts +1 -0
  112. package/lib/translation-textarea/translation-textarea.component.d.ts +26 -0
  113. package/lib/unknown-form/index.d.ts +1 -0
  114. package/lib/unknown-form/unknown-form.component.d.ts +9 -0
  115. package/package.json +25 -0
  116. package/styles/@candy-kingdom/bonnie/variables.scss +0 -0
  117. package/styles/admin-styles.scss +139 -0
  118. package/styles/admin-variables.scss +445 -0
  119. package/styles/variables.scss +415 -0
@@ -0,0 +1,1343 @@
1
+ import * as i0 from '@angular/core';
2
+ import { EventEmitter, forwardRef, Directive, Output, Component, ContentChildren, Host, Input, ViewChildren, ViewChild, HostBinding, NgModule } from '@angular/core';
3
+ import { Subject, debounceTime, map, last, catchError, Observable } from 'rxjs';
4
+ import * as i1 from '@angular/forms';
5
+ import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
6
+ import * as i2 from '@angular/common/http';
7
+ import { HttpRequest, HttpEventType } from '@angular/common/http';
8
+ import * as i2$2 from '@angular/common';
9
+ import { CommonModule } from '@angular/common';
10
+ import * as i2$1 from '@angular/cdk/text-field';
11
+ import { CdkTextareaAutosize } from '@angular/cdk/text-field';
12
+ import { take } from 'rxjs/operators';
13
+ import * as i1$1 from '@angular/platform-browser';
14
+ import * as i4 from '@candy-kingdom/bonnie';
15
+ import { MediaObjectFit, BonnieModule } from '@candy-kingdom/bonnie';
16
+
17
+ /**
18
+ * This is a TypeGen auto-generated file.
19
+ * Any changes made to this file can be lost when this file is regenerated.
20
+ */
21
+
22
+ /**
23
+ * This is a TypeGen auto-generated file.
24
+ * Any changes made to this file can be lost when this file is regenerated.
25
+ */
26
+
27
+ /**
28
+ * This is a TypeGen auto-generated file.
29
+ * Any changes made to this file can be lost when this file is regenerated.
30
+ */
31
+
32
+ /**
33
+ * This is a TypeGen auto-generated file.
34
+ * Any changes made to this file can be lost when this file is regenerated.
35
+ */
36
+
37
+ /**
38
+ * This is a TypeGen auto-generated file.
39
+ * Any changes made to this file can be lost when this file is regenerated.
40
+ */
41
+
42
+ /**
43
+ * This is a TypeGen auto-generated file.
44
+ * Any changes made to this file can be lost when this file is regenerated.
45
+ */
46
+
47
+ /**
48
+ * This is a TypeGen auto-generated file.
49
+ * Any changes made to this file can be lost when this file is regenerated.
50
+ */
51
+
52
+ /**
53
+ * This is a TypeGen auto-generated file.
54
+ * Any changes made to this file can be lost when this file is regenerated.
55
+ */
56
+
57
+ /**
58
+ * This is a TypeGen auto-generated file.
59
+ * Any changes made to this file can be lost when this file is regenerated.
60
+ */
61
+ var TextSettingType;
62
+ (function (TextSettingType) {
63
+ TextSettingType[TextSettingType["SingleLine"] = 0] = "SingleLine";
64
+ TextSettingType[TextSettingType["MultiLine"] = 1] = "MultiLine";
65
+ })(TextSettingType || (TextSettingType = {}));
66
+
67
+ /**
68
+ * This is a TypeGen auto-generated file.
69
+ * Any changes made to this file can be lost when this file is regenerated.
70
+ */
71
+
72
+ var DeviceType;
73
+ (function (DeviceType) {
74
+ DeviceType[DeviceType["NotSet"] = 0] = "NotSet";
75
+ DeviceType[DeviceType["Mobile"] = 1] = "Mobile";
76
+ DeviceType[DeviceType["Tablet"] = 2] = "Tablet";
77
+ DeviceType[DeviceType["Desktop"] = 3] = "Desktop";
78
+ })(DeviceType || (DeviceType = {}));
79
+
80
+ var TextEditorField;
81
+ (function (TextEditorField) {
82
+ TextEditorField[TextEditorField["NotSet"] = 0] = "NotSet";
83
+ TextEditorField[TextEditorField["Input"] = 1] = "Input";
84
+ TextEditorField[TextEditorField["Textarea"] = 2] = "Textarea";
85
+ })(TextEditorField || (TextEditorField = {}));
86
+
87
+ // tslint:disable-next-line: max-line-length
88
+ const regExpIsMobile = new RegExp(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/, 'i');
89
+ function isLocalUrlString(url) {
90
+ if (url === undefined || url === null || url.trim().length === 0)
91
+ return true;
92
+ if (url.startsWith('//'))
93
+ return false;
94
+ if (url.startsWith('./') || url.startsWith('/'))
95
+ return true;
96
+ return false;
97
+ }
98
+ function hasFlag(value, flag) {
99
+ return (value & flag) === flag;
100
+ }
101
+ function setOrRemoveFlag(value, flag, enabled) {
102
+ return (enabled ? value | flag : value & ~flag);
103
+ }
104
+
105
+ var DeviceVisibility;
106
+ (function (DeviceVisibility) {
107
+ DeviceVisibility[DeviceVisibility["None"] = 0] = "None";
108
+ DeviceVisibility[DeviceVisibility["Desktop"] = 1] = "Desktop";
109
+ DeviceVisibility[DeviceVisibility["Tablet"] = 2] = "Tablet";
110
+ DeviceVisibility[DeviceVisibility["Mobile"] = 4] = "Mobile";
111
+ DeviceVisibility[DeviceVisibility["All"] = 7] = "All";
112
+ })(DeviceVisibility || (DeviceVisibility = {}));
113
+
114
+ class EditableDirective {
115
+ constructor() {
116
+ this.saved = new EventEmitter();
117
+ this.editModeChange = new EventEmitter();
118
+ this.externalSaveCall = new EventEmitter();
119
+ this.canceled = new EventEmitter();
120
+ this.valueChange = new EventEmitter();
121
+ this.propagateChange = () => { };
122
+ this._inEditMode = false;
123
+ this._isDirty = false;
124
+ this.startEditing = () => {
125
+ if (this._inEditMode) {
126
+ this.updateDirty();
127
+ return;
128
+ }
129
+ this._inEditMode = true;
130
+ this.updateDirty();
131
+ this.editModeChange.emit(true);
132
+ };
133
+ }
134
+ get inEditMode() {
135
+ return this._inEditMode;
136
+ }
137
+ subscribe(params) {
138
+ const subscriptions = [];
139
+ if (params.onValueChange !== undefined && params.onValueChange !== null) {
140
+ subscriptions.push(this.valueChange.subscribe((x) => {
141
+ if (params.onValueChange)
142
+ params.onValueChange(x);
143
+ }));
144
+ }
145
+ if (params.onEditModeChange !== undefined) {
146
+ subscriptions.push(this.editModeChange.subscribe((x) => {
147
+ if (params.onEditModeChange)
148
+ params.onEditModeChange(x);
149
+ }));
150
+ }
151
+ if (params.onSaveRequest !== undefined) {
152
+ subscriptions.push(this.externalSaveCall.subscribe(() => {
153
+ if (params.onSaveRequest)
154
+ params.onSaveRequest();
155
+ }));
156
+ }
157
+ return subscriptions;
158
+ }
159
+ requestSave() {
160
+ this.externalSaveCall.emit();
161
+ }
162
+ save(newData) {
163
+ if (!this._inEditMode) {
164
+ console.warn('save before edit mode'); //todo: fix that
165
+ }
166
+ this.finishEditing();
167
+ const newUnqieNotEmptyData = this.value === newData || newData === undefined
168
+ ? JSON.parse(JSON.stringify(this.value))
169
+ : newData;
170
+ this.setOriginal(newUnqieNotEmptyData);
171
+ this.updateDirty();
172
+ this.saved.emit(newUnqieNotEmptyData);
173
+ this.propagateChange(newUnqieNotEmptyData);
174
+ }
175
+ patchSave(propName, newDataParts) {
176
+ if (this._originalValue === undefined || this._originalValue === null)
177
+ return;
178
+ if (typeof this._originalValue !== "object") {
179
+ console.warn('patch save called on not object type');
180
+ return;
181
+ }
182
+ this._originalValue[propName] = newDataParts;
183
+ this.setOriginal(this._originalValue);
184
+ this.updateDirty();
185
+ if (!this.isDirty)
186
+ this.close();
187
+ }
188
+ // change model without opening or closing the editor
189
+ silentPatch(dict) {
190
+ for (const key in dict) {
191
+ // eslint-disable-next-line no-prototype-builtins
192
+ if (!dict.hasOwnProperty(key))
193
+ continue;
194
+ const propVal = dict[key];
195
+ if (this._value !== undefined && this._value !== null) {
196
+ this._value[key] = propVal;
197
+ }
198
+ if (this._originalValue !== undefined && this._originalValue !== null) {
199
+ this._originalValue[key] = propVal;
200
+ }
201
+ }
202
+ this._storedData = JSON.stringify(this._originalValue);
203
+ }
204
+ cancel() {
205
+ if (!this._inEditMode)
206
+ return;
207
+ this.finishEditing();
208
+ // reset value
209
+ this.setValue(this._originalValue);
210
+ this.canceled.emit();
211
+ }
212
+ close() {
213
+ this.finishEditing();
214
+ }
215
+ finishEditing() {
216
+ if (!this._inEditMode)
217
+ return;
218
+ this._inEditMode = false;
219
+ this.editModeChange.emit(false);
220
+ }
221
+ setValue(newValue) {
222
+ this._value = (newValue === null || newValue === undefined)
223
+ ? undefined
224
+ : JSON.parse(JSON.stringify(newValue));
225
+ this.valueChange.emit(this._value);
226
+ }
227
+ set value(newValue) {
228
+ this.setValue(newValue);
229
+ }
230
+ get value() {
231
+ return this._value;
232
+ }
233
+ updateDirty() {
234
+ this._isDirty = JSON.stringify(this._value) !== this._storedData;
235
+ }
236
+ markAsDirty() {
237
+ this._isDirty = true;
238
+ }
239
+ get isDirty() {
240
+ return this._isDirty;
241
+ }
242
+ setOriginal(newOriginalValue) {
243
+ this._originalValue = newOriginalValue;
244
+ this._storedData = JSON.stringify(newOriginalValue);
245
+ }
246
+ // #region ngModel
247
+ writeValue(newValue) {
248
+ this.finishEditing();
249
+ this.setOriginal(newValue);
250
+ this._isDirty = false;
251
+ this.setValue(newValue);
252
+ }
253
+ setDisabledState() {
254
+ }
255
+ registerOnChange(tellAngularThatSomethingIsChanged) {
256
+ this.propagateChange = (newValue) => {
257
+ tellAngularThatSomethingIsChanged(newValue);
258
+ };
259
+ }
260
+ registerOnTouched() {
261
+ }
262
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: EditableDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
263
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.8", type: EditableDirective, isStandalone: true, selector: "[boncEditable]", outputs: { saved: "saved", editModeChange: "editModeChange", externalSaveCall: "externalSaveCall", canceled: "canceled", valueChange: "valueChange" }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => EditableDirective), multi: true }], ngImport: i0 }); }
264
+ }
265
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: EditableDirective, decorators: [{
266
+ type: Directive,
267
+ args: [{
268
+ standalone: true,
269
+ selector: '[boncEditable]',
270
+ providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => EditableDirective), multi: true }]
271
+ }]
272
+ }], propDecorators: { saved: [{
273
+ type: Output
274
+ }], editModeChange: [{
275
+ type: Output
276
+ }], externalSaveCall: [{
277
+ type: Output
278
+ }], canceled: [{
279
+ type: Output
280
+ }], valueChange: [{
281
+ type: Output
282
+ }] } });
283
+
284
+ class EditableGroupComponent {
285
+ constructor() {
286
+ this.editModeChange = new EventEmitter();
287
+ this.saved = new EventEmitter();
288
+ this.requestEditorClose = new EventEmitter();
289
+ this.subscriptions = [];
290
+ this._inEditMode = false;
291
+ this.saveSubject = new Subject();
292
+ }
293
+ ngAfterContentInit() {
294
+ this.saveSubject
295
+ .asObservable()
296
+ .pipe(debounceTime(100))
297
+ .subscribe(() => this.saved.emit());
298
+ this.updateSubscriptions();
299
+ this.editables.changes.subscribe(() => {
300
+ this.clearSubscribtions();
301
+ this.updateSubscriptions();
302
+ });
303
+ }
304
+ get inEditMode() {
305
+ return this._inEditMode;
306
+ }
307
+ saveAll() {
308
+ this.editables.forEach(x => x.requestSave());
309
+ }
310
+ cancelAll() {
311
+ this.editables.forEach(x => x.cancel());
312
+ }
313
+ closeAll() {
314
+ this.requestEditorClose.emit(true);
315
+ this.editables.forEach(x => x.close());
316
+ }
317
+ clearSubscribtions() {
318
+ this.subscriptions.forEach(x => x.unsubscribe());
319
+ this.subscriptions.splice(0, this.subscriptions.length);
320
+ }
321
+ updateSubscriptions() {
322
+ this.editables.forEach(editable => {
323
+ this.subscriptions.push(editable.saved.subscribe(() => this.onSave()));
324
+ this.subscriptions.push(...editable.subscribe({
325
+ onEditModeChange: this.updateEditMode.bind(this)
326
+ }));
327
+ });
328
+ }
329
+ onSave() {
330
+ this.saveSubject.next();
331
+ }
332
+ updateEditMode() {
333
+ const newEditMode = this.editables
334
+ .filter(x => x.inEditMode)
335
+ .length > 0;
336
+ if (newEditMode === this._inEditMode)
337
+ return;
338
+ this._inEditMode = newEditMode;
339
+ this.editModeChange.next(newEditMode);
340
+ }
341
+ ngOnDestroy() {
342
+ this.clearSubscribtions();
343
+ }
344
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: EditableGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
345
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: EditableGroupComponent, selector: "bonc-editable-group", outputs: { editModeChange: "editModeChange", saved: "saved", requestEditorClose: "requestEditorClose" }, queries: [{ propertyName: "editables", predicate: EditableDirective, descendants: true }], ngImport: i0, template: '<ng-content></ng-content>', isInline: true }); }
346
+ }
347
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: EditableGroupComponent, decorators: [{
348
+ type: Component,
349
+ args: [{
350
+ selector: 'bonc-editable-group',
351
+ template: '<ng-content></ng-content>'
352
+ }]
353
+ }], propDecorators: { editModeChange: [{
354
+ type: Output
355
+ }], saved: [{
356
+ type: Output
357
+ }], requestEditorClose: [{
358
+ type: Output
359
+ }], editables: [{
360
+ type: ContentChildren,
361
+ args: [EditableDirective, { descendants: true }]
362
+ }] } });
363
+
364
+ class FormBaseComponent {
365
+ static { this.inputs = ['locale']; }
366
+ constructor(editable, http) {
367
+ this.editable = editable;
368
+ this.http = http;
369
+ this.name = '';
370
+ this._locale = '';
371
+ }
372
+ set locale(value) {
373
+ this._locale = value;
374
+ }
375
+ get locale() {
376
+ return this._locale;
377
+ }
378
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: FormBaseComponent, deps: [{ token: EditableDirective, host: true }, { token: i2.HttpClient }], target: i0.ɵɵFactoryTarget.Component }); }
379
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: FormBaseComponent, selector: "ng-component", inputs: { locale: "locale" }, ngImport: i0, template: '', isInline: true }); }
380
+ }
381
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: FormBaseComponent, decorators: [{
382
+ type: Component,
383
+ args: [{
384
+ template: ''
385
+ }]
386
+ }], ctorParameters: () => [{ type: EditableDirective, decorators: [{
387
+ type: Host
388
+ }] }, { type: i2.HttpClient }], propDecorators: { locale: [{
389
+ type: Input
390
+ }] } });
391
+
392
+ class TranslationInputComponent {
393
+ constructor() {
394
+ this.device = DeviceType.NotSet;
395
+ this.startEditing = new EventEmitter();
396
+ this.changed = new EventEmitter();
397
+ this.blurred = new EventEmitter();
398
+ }
399
+ onClick() {
400
+ this.startEditing.emit();
401
+ }
402
+ onKeyPress() {
403
+ this.changed.emit();
404
+ }
405
+ onBlur() {
406
+ this.blurred.emit();
407
+ }
408
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: TranslationInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
409
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: TranslationInputComponent, selector: "bonc-translation-input", inputs: { text: "text", locale: "locale", device: "device" }, outputs: { startEditing: "startEditing", changed: "changed", blurred: "blurred" }, ngImport: i0, template: "<input [(ngModel)]=\"text[locale]\"\r\n (click)=\"onClick()\"\r\n (keyup)=\"onKeyPress()\"\r\n (blur)=\"onBlur()\" />\r\n", styles: [":host{padding:6px 12px;border:1px solid silver;display:block}:host:hover{background-color:#333}:host:focus-within{background-color:#555}:host input{background-color:#8080801a;color:var(--text-color);padding:6px;color:silver;border:1px solid silver;background-color:transparent;display:block;box-sizing:border-box;font-family:inherit;width:100%;border:none}:host input:hover{background-color:#d3d3d3;cursor:pointer}:host input:focus{outline:none;color:#000;background-color:#cf0}:host input:hover{border-color:transparent;background-color:#333;cursor:pointer}:host input:focus{outline:none;color:#fff;border-color:transparent;background-color:#555}\n"], dependencies: [{ kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
410
+ }
411
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: TranslationInputComponent, decorators: [{
412
+ type: Component,
413
+ args: [{ selector: 'bonc-translation-input', template: "<input [(ngModel)]=\"text[locale]\"\r\n (click)=\"onClick()\"\r\n (keyup)=\"onKeyPress()\"\r\n (blur)=\"onBlur()\" />\r\n", styles: [":host{padding:6px 12px;border:1px solid silver;display:block}:host:hover{background-color:#333}:host:focus-within{background-color:#555}:host input{background-color:#8080801a;color:var(--text-color);padding:6px;color:silver;border:1px solid silver;background-color:transparent;display:block;box-sizing:border-box;font-family:inherit;width:100%;border:none}:host input:hover{background-color:#d3d3d3;cursor:pointer}:host input:focus{outline:none;color:#000;background-color:#cf0}:host input:hover{border-color:transparent;background-color:#333;cursor:pointer}:host input:focus{outline:none;color:#fff;border-color:transparent;background-color:#555}\n"] }]
414
+ }], propDecorators: { text: [{
415
+ type: Input,
416
+ args: [{ required: true }]
417
+ }], locale: [{
418
+ type: Input,
419
+ args: [{ required: true }]
420
+ }], device: [{
421
+ type: Input
422
+ }], startEditing: [{
423
+ type: Output
424
+ }], changed: [{
425
+ type: Output
426
+ }], blurred: [{
427
+ type: Output
428
+ }] } });
429
+
430
+ class TranslationTextareaComponent {
431
+ constructor(ngZone) {
432
+ this.ngZone = ngZone;
433
+ this.device = DeviceType.NotSet;
434
+ this.startEditing = new EventEmitter();
435
+ this.changed = new EventEmitter();
436
+ this.blurred = new EventEmitter();
437
+ }
438
+ ngAfterViewInit() {
439
+ setTimeout(this.triggerResize.bind(this));
440
+ }
441
+ ngOnChanges() {
442
+ setTimeout(this.triggerResize.bind(this), 500);
443
+ }
444
+ onClick() {
445
+ this.startEditing.emit();
446
+ }
447
+ onKeyPress() {
448
+ this.changed.emit();
449
+ }
450
+ onBlur() {
451
+ this.blurred.emit();
452
+ }
453
+ triggerResize() {
454
+ // console.log('trigger resize!');
455
+ this.ngZone.onStable.pipe(take(1))
456
+ .subscribe(() => {
457
+ this.autosizeList.forEach(x => x.resizeToFitContent(true));
458
+ });
459
+ }
460
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: TranslationTextareaComponent, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
461
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: TranslationTextareaComponent, selector: "bonc-translation-textarea", inputs: { minRows: "minRows", maxRows: "maxRows", text: "text", locale: "locale", device: "device" }, outputs: { startEditing: "startEditing", changed: "changed", blurred: "blurred" }, viewQueries: [{ propertyName: "autosizeList", predicate: CdkTextareaAutosize, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<textarea [(ngModel)]=\"text[locale]\"\r\n [cdkAutosizeMinRows]=\"minRows\"\r\n [cdkAutosizeMaxRows]=\"maxRows\"\r\n (click)=\"onClick()\"\r\n (keyup)=\"onKeyPress()\"\r\n (blur)=\"onBlur()\"\r\n matInput\r\n cdkTextareaAutosize>\r\n</textarea>\r\n", styles: [":host{display:block;padding:6px 12px;border:1px solid silver}:host:hover{background-color:#333}:host:focus-within{background-color:#555}textarea{display:block;width:100%;line-height:140%;padding:2px 0;margin:0;box-sizing:content-box;border:none;resize:none;color:silver;background-color:transparent}textarea:focus{outline:none}textarea[readonly]{cursor:pointer}textarea[readonly]::selection{-webkit-user-select:none;user-select:none}textarea[readonly]:hover{background:repeating-linear-gradient(-45deg,#ccff00,#ccff00 10px,rgba(0,0,0,0) 10px,rgba(0,0,0,0) 20px) fixed bottom;color:#000}textarea:hover{cursor:pointer}textarea:focus{outline:none;color:#fff;cursor:default}\n"], dependencies: [{ kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2$1.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }] }); }
462
+ }
463
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: TranslationTextareaComponent, decorators: [{
464
+ type: Component,
465
+ args: [{ selector: 'bonc-translation-textarea', template: "<textarea [(ngModel)]=\"text[locale]\"\r\n [cdkAutosizeMinRows]=\"minRows\"\r\n [cdkAutosizeMaxRows]=\"maxRows\"\r\n (click)=\"onClick()\"\r\n (keyup)=\"onKeyPress()\"\r\n (blur)=\"onBlur()\"\r\n matInput\r\n cdkTextareaAutosize>\r\n</textarea>\r\n", styles: [":host{display:block;padding:6px 12px;border:1px solid silver}:host:hover{background-color:#333}:host:focus-within{background-color:#555}textarea{display:block;width:100%;line-height:140%;padding:2px 0;margin:0;box-sizing:content-box;border:none;resize:none;color:silver;background-color:transparent}textarea:focus{outline:none}textarea[readonly]{cursor:pointer}textarea[readonly]::selection{-webkit-user-select:none;user-select:none}textarea[readonly]:hover{background:repeating-linear-gradient(-45deg,#ccff00,#ccff00 10px,rgba(0,0,0,0) 10px,rgba(0,0,0,0) 20px) fixed bottom;color:#000}textarea:hover{cursor:pointer}textarea:focus{outline:none;color:#fff;cursor:default}\n"] }]
466
+ }], ctorParameters: () => [{ type: i0.NgZone }], propDecorators: { autosizeList: [{
467
+ type: ViewChildren,
468
+ args: [CdkTextareaAutosize]
469
+ }], minRows: [{
470
+ type: Input
471
+ }], maxRows: [{
472
+ type: Input
473
+ }], text: [{
474
+ type: Input,
475
+ args: [{ required: true }]
476
+ }], locale: [{
477
+ type: Input,
478
+ args: [{ required: true }]
479
+ }], device: [{
480
+ type: Input
481
+ }], startEditing: [{
482
+ type: Output
483
+ }], changed: [{
484
+ type: Output
485
+ }], blurred: [{
486
+ type: Output
487
+ }] } });
488
+
489
+ class LinkPopupComponent {
490
+ constructor() {
491
+ this.TextEditorField = TextEditorField;
492
+ this.linkChange = new EventEmitter();
493
+ this.startEditing = new EventEmitter();
494
+ this.changed = new EventEmitter();
495
+ this.blurred = new EventEmitter();
496
+ this.open = new EventEmitter();
497
+ this.closed = new EventEmitter();
498
+ this.LinkPopupField = TextEditorField;
499
+ this.popupIsShown = false;
500
+ }
501
+ onClick() {
502
+ this.startEditing.emit();
503
+ }
504
+ onChange() {
505
+ console.log('change link pop up');
506
+ this.changed.emit();
507
+ }
508
+ onBlur() {
509
+ this.blurred.emit();
510
+ }
511
+ showPopup() {
512
+ this.popupIsShown = true;
513
+ this.open.emit();
514
+ }
515
+ hidePopup() {
516
+ this.popupIsShown = false;
517
+ this.closed.emit();
518
+ }
519
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: LinkPopupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
520
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: LinkPopupComponent, selector: "bonc-link-popup", inputs: { field: "field", maxRows: "maxRows", minRows: "minRows", linkTitle: "linkTitle", locale: "locale", link: "link" }, outputs: { linkChange: "linkChange", startEditing: "startEditing", changed: "changed", blurred: "blurred", open: "open", closed: "closed" }, ngImport: i0, template: "<bonc-translation-input *ngIf=\"field === TextEditorField.Input\"\r\n (click)=\"showPopup()\"\r\n [text]=\"linkTitle\"\r\n [locale]=\"locale\"\r\n (startEditing)=\"onClick()\"\r\n (changed)=\"onChange()\"\r\n (blurred)=\"onBlur()\">\r\n</bonc-translation-input>\r\n\r\n<bonc-translation-textarea *ngIf=\"field === TextEditorField.Textarea\"\r\n (click)=\"showPopup()\"\r\n [text]=\"linkTitle\"\r\n [locale]=\"locale\"\r\n [minRows]=\"minRows\"\r\n [maxRows]=\"maxRows\"\r\n (startEditing)=\"onClick()\"\r\n (changed)=\"onChange()\"\r\n (blurred)=\"onBlur()\">\r\n</bonc-translation-textarea>\r\n\r\n<div *ngIf=\"popupIsShown\">\r\n <div class=\"popup\">\r\n <a (click)=\"hidePopup()\" class=\"close\">close</a>\r\n\r\n <label>Link\r\n <input [(ngModel)]=\"link[locale]\"\r\n (click)=\"onClick()\"\r\n (keyup)=\"onChange()\"\r\n (blur)=\"onBlur()\">\r\n </label>\r\n\r\n </div>\r\n</div>\r\n", styles: [":host{display:flex;flex-direction:column;position:relative}:host translation-input{z-index:1}.popup{position:absolute;display:flex;flex-direction:column;justify-content:center;width:350px;padding:20px;box-sizing:border-box;color:#000;background-color:#fff;z-index:5;border:2px solid black}.popup a{cursor:pointer}.popup a:hover{background-color:#cf0}.popup a.close{position:absolute;top:10px;right:10px}.popup label+label{margin-top:20px}.popup input{width:100%;margin-top:5px;padding:6px;font-size:12px;box-sizing:border-box;border:1px solid #222}.popup input:hover,.popup input:focus{background-color:silver;color:#333;border-color:silver;outline:none}button{display:block;color:#fff;background-color:transparent;box-shadow:none;border:none;outline:none;text-decoration:none;padding:3pt 10pt;text-align:center;-webkit-user-select:none;user-select:none;color:#000;cursor:pointer}button:hover{border-color:#333;background-color:#333}button:disabled{color:gray}button:hover{background-color:#cf0}\n"], dependencies: [{ kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: TranslationInputComponent, selector: "bonc-translation-input", inputs: ["text", "locale", "device"], outputs: ["startEditing", "changed", "blurred"] }, { kind: "component", type: TranslationTextareaComponent, selector: "bonc-translation-textarea", inputs: ["minRows", "maxRows", "text", "locale", "device"], outputs: ["startEditing", "changed", "blurred"] }] }); }
521
+ }
522
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: LinkPopupComponent, decorators: [{
523
+ type: Component,
524
+ args: [{ selector: 'bonc-link-popup', template: "<bonc-translation-input *ngIf=\"field === TextEditorField.Input\"\r\n (click)=\"showPopup()\"\r\n [text]=\"linkTitle\"\r\n [locale]=\"locale\"\r\n (startEditing)=\"onClick()\"\r\n (changed)=\"onChange()\"\r\n (blurred)=\"onBlur()\">\r\n</bonc-translation-input>\r\n\r\n<bonc-translation-textarea *ngIf=\"field === TextEditorField.Textarea\"\r\n (click)=\"showPopup()\"\r\n [text]=\"linkTitle\"\r\n [locale]=\"locale\"\r\n [minRows]=\"minRows\"\r\n [maxRows]=\"maxRows\"\r\n (startEditing)=\"onClick()\"\r\n (changed)=\"onChange()\"\r\n (blurred)=\"onBlur()\">\r\n</bonc-translation-textarea>\r\n\r\n<div *ngIf=\"popupIsShown\">\r\n <div class=\"popup\">\r\n <a (click)=\"hidePopup()\" class=\"close\">close</a>\r\n\r\n <label>Link\r\n <input [(ngModel)]=\"link[locale]\"\r\n (click)=\"onClick()\"\r\n (keyup)=\"onChange()\"\r\n (blur)=\"onBlur()\">\r\n </label>\r\n\r\n </div>\r\n</div>\r\n", styles: [":host{display:flex;flex-direction:column;position:relative}:host translation-input{z-index:1}.popup{position:absolute;display:flex;flex-direction:column;justify-content:center;width:350px;padding:20px;box-sizing:border-box;color:#000;background-color:#fff;z-index:5;border:2px solid black}.popup a{cursor:pointer}.popup a:hover{background-color:#cf0}.popup a.close{position:absolute;top:10px;right:10px}.popup label+label{margin-top:20px}.popup input{width:100%;margin-top:5px;padding:6px;font-size:12px;box-sizing:border-box;border:1px solid #222}.popup input:hover,.popup input:focus{background-color:silver;color:#333;border-color:silver;outline:none}button{display:block;color:#fff;background-color:transparent;box-shadow:none;border:none;outline:none;text-decoration:none;padding:3pt 10pt;text-align:center;-webkit-user-select:none;user-select:none;color:#000;cursor:pointer}button:hover{border-color:#333;background-color:#333}button:disabled{color:gray}button:hover{background-color:#cf0}\n"] }]
525
+ }], propDecorators: { linkChange: [{
526
+ type: Output
527
+ }], startEditing: [{
528
+ type: Output
529
+ }], changed: [{
530
+ type: Output
531
+ }], blurred: [{
532
+ type: Output
533
+ }], open: [{
534
+ type: Output
535
+ }], closed: [{
536
+ type: Output
537
+ }], field: [{
538
+ type: Input,
539
+ args: [{ required: true }]
540
+ }], maxRows: [{
541
+ type: Input
542
+ }], minRows: [{
543
+ type: Input
544
+ }], linkTitle: [{
545
+ type: Input,
546
+ args: [{ required: true }]
547
+ }], locale: [{
548
+ type: Input,
549
+ args: [{ required: true }]
550
+ }], link: [{
551
+ type: Input,
552
+ args: [{ required: true }]
553
+ }] } });
554
+
555
+ class AdminControlsComponent {
556
+ constructor() {
557
+ this.DeviceType = DeviceType;
558
+ this.deviceControls = false;
559
+ this.locale = 'en';
560
+ this.device = this.DeviceType.Desktop;
561
+ }
562
+ changeLocale() {
563
+ this.locale = this.locale === 'en' ? 'ru' : 'en';
564
+ }
565
+ changeDevice() {
566
+ switch (this.device) {
567
+ case DeviceType.Desktop:
568
+ this.device = DeviceType.Tablet;
569
+ return;
570
+ case DeviceType.Tablet:
571
+ this.device = DeviceType.Mobile;
572
+ return;
573
+ case DeviceType.Mobile:
574
+ this.device = DeviceType.Desktop;
575
+ return;
576
+ default:
577
+ this.device = DeviceType.Desktop;
578
+ return;
579
+ }
580
+ }
581
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: AdminControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
582
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: AdminControlsComponent, selector: "bonc-admin-controls", inputs: { editableGroup: "editableGroup", deviceControls: "deviceControls" }, ngImport: i0, template: "<div class=\"page-controls\">\r\n <a (click)=\"changeLocale()\" class=\"locale\">Locale: {{locale}}</a>\r\n\r\n <!-- todo: return this functionality -->\r\n <!-- <a *ngIf=\"deviceControls\" (click)=\"changeDevice()\" class=\"device\">\r\n <span *ngIf=\"device === DeviceType.Desktop\">DESKTOP</span>\r\n <span *ngIf=\"device === DeviceType.Tablet\">TABLET</span>\r\n <span *ngIf=\"device === DeviceType.Mobile\">MOBILE</span>\r\n </a> -->\r\n\r\n <a *ngIf=\"editableGroup && editableGroup.inEditMode\"\r\n (click)=\"editableGroup.saveAll()\"\r\n class=\"save\">Save all</a>\r\n\r\n <a *ngIf=\"editableGroup && editableGroup.inEditMode\"\r\n (click)=\"editableGroup.cancelAll()\"\r\n class=\"cancel\">Cancel all</a>\r\n</div>\r\n", styles: [":host{display:block;position:sticky;top:0;width:100%;z-index:1000}.page-controls{background-color:#111;height:60px;display:flex;align-items:center;justify-content:center}.page-controls a{color:silver;padding:4px;cursor:pointer;-webkit-user-select:none;user-select:none;text-align:center}.page-controls a:hover{color:#000;background-color:#cf0}.page-controls a.device{width:80px}.page-controls a+a{margin-left:6px}\n"], dependencies: [{ kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
583
+ }
584
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: AdminControlsComponent, decorators: [{
585
+ type: Component,
586
+ args: [{ selector: 'bonc-admin-controls', template: "<div class=\"page-controls\">\r\n <a (click)=\"changeLocale()\" class=\"locale\">Locale: {{locale}}</a>\r\n\r\n <!-- todo: return this functionality -->\r\n <!-- <a *ngIf=\"deviceControls\" (click)=\"changeDevice()\" class=\"device\">\r\n <span *ngIf=\"device === DeviceType.Desktop\">DESKTOP</span>\r\n <span *ngIf=\"device === DeviceType.Tablet\">TABLET</span>\r\n <span *ngIf=\"device === DeviceType.Mobile\">MOBILE</span>\r\n </a> -->\r\n\r\n <a *ngIf=\"editableGroup && editableGroup.inEditMode\"\r\n (click)=\"editableGroup.saveAll()\"\r\n class=\"save\">Save all</a>\r\n\r\n <a *ngIf=\"editableGroup && editableGroup.inEditMode\"\r\n (click)=\"editableGroup.cancelAll()\"\r\n class=\"cancel\">Cancel all</a>\r\n</div>\r\n", styles: [":host{display:block;position:sticky;top:0;width:100%;z-index:1000}.page-controls{background-color:#111;height:60px;display:flex;align-items:center;justify-content:center}.page-controls a{color:silver;padding:4px;cursor:pointer;-webkit-user-select:none;user-select:none;text-align:center}.page-controls a:hover{color:#000;background-color:#cf0}.page-controls a.device{width:80px}.page-controls a+a{margin-left:6px}\n"] }]
587
+ }], propDecorators: { editableGroup: [{
588
+ type: Input,
589
+ args: [{ required: true }]
590
+ }], deviceControls: [{
591
+ type: Input
592
+ }] } });
593
+
594
+ class FormControlsComponent {
595
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: FormControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
596
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: FormControlsComponent, selector: "bonc-form-controls", inputs: { editable: "editable" }, ngImport: i0, template: "<div [class.edit]=\"editable.inEditMode\" class=\"content\">\r\n <ng-content></ng-content>\r\n</div>\r\n\r\n<div [class.hidden]=\"!editable.inEditMode\" class=\"controls\">\r\n <a *ngIf=\"!editable.isDirty\" (click)=\"editable.cancel()\" class=\"close\">close</a>\r\n <ng-container *ngIf=\"editable.isDirty\">\r\n <a (click)=\"editable.cancel()\">reset</a>\r\n <a (click)=\"editable.requestSave()\" class=\"apply\">apply</a>\r\n </ng-container>\r\n</div>\r\n", styles: [":host{display:flex;background-color:#222;color:silver}.content{flex:1;padding:10px}.content.edit{background-color:#111}.controls{display:flex;flex-direction:column;width:100px;background-color:#111}.controls.hidden{opacity:0;pointer-events:none}.controls a{display:block}.controls a.apply{flex:1}\n"], dependencies: [{ kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
597
+ }
598
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: FormControlsComponent, decorators: [{
599
+ type: Component,
600
+ args: [{ selector: 'bonc-form-controls', template: "<div [class.edit]=\"editable.inEditMode\" class=\"content\">\r\n <ng-content></ng-content>\r\n</div>\r\n\r\n<div [class.hidden]=\"!editable.inEditMode\" class=\"controls\">\r\n <a *ngIf=\"!editable.isDirty\" (click)=\"editable.cancel()\" class=\"close\">close</a>\r\n <ng-container *ngIf=\"editable.isDirty\">\r\n <a (click)=\"editable.cancel()\">reset</a>\r\n <a (click)=\"editable.requestSave()\" class=\"apply\">apply</a>\r\n </ng-container>\r\n</div>\r\n", styles: [":host{display:flex;background-color:#222;color:silver}.content{flex:1;padding:10px}.content.edit{background-color:#111}.controls{display:flex;flex-direction:column;width:100px;background-color:#111}.controls.hidden{opacity:0;pointer-events:none}.controls a{display:block}.controls a.apply{flex:1}\n"] }]
601
+ }], propDecorators: { editable: [{
602
+ type: Input,
603
+ args: [{ required: true }]
604
+ }] } });
605
+
606
+ const imageMimeTypes = ['image/png', 'image/jpeg'];
607
+ const videoMimeTypes = ['video/mp4'];
608
+ const imageFileTypes = imageMimeTypes.join(',');
609
+ const videoFileTypes = videoMimeTypes.join(',');
610
+ const allMediaFileTypes = `${imageFileTypes},${videoFileTypes}`;
611
+ class MediaUploaderComponent {
612
+ constructor(sanitizer, http) {
613
+ this.sanitizer = sanitizer;
614
+ this.http = http;
615
+ this.MediaObjectFit = MediaObjectFit;
616
+ this.srcChange = new EventEmitter();
617
+ this.progress = 0;
618
+ this.isUploading = false;
619
+ this.autoplay = true;
620
+ this.fileTypeMask = allMediaFileTypes;
621
+ }
622
+ set src(newSrc) {
623
+ if (this._src === newSrc)
624
+ return;
625
+ this._src = newSrc;
626
+ }
627
+ get src() {
628
+ return this._src;
629
+ }
630
+ set uploadType(newUploadType) {
631
+ switch (newUploadType) {
632
+ case "image":
633
+ this._uploadType = newUploadType;
634
+ this.fileTypeMask = imageFileTypes;
635
+ break;
636
+ case "video":
637
+ this._uploadType = newUploadType;
638
+ this.fileTypeMask = videoFileTypes;
639
+ break;
640
+ case undefined:
641
+ default:
642
+ this._uploadType = newUploadType;
643
+ this.fileTypeMask = allMediaFileTypes;
644
+ break;
645
+ }
646
+ }
647
+ get uploadType() {
648
+ return this._uploadType;
649
+ }
650
+ onFileSelect(fileInput) {
651
+ if (fileInput.files === undefined || fileInput.files === null || fileInput.files.length !== 1)
652
+ return;
653
+ const file = fileInput.files[0];
654
+ let uploadingMediaType;
655
+ if (this._uploadType !== undefined && this._uploadType !== null) {
656
+ uploadingMediaType = this._uploadType;
657
+ }
658
+ else if (imageMimeTypes.includes(file.type)) {
659
+ uploadingMediaType = 'image';
660
+ }
661
+ else if (videoMimeTypes.includes(file.type)) {
662
+ uploadingMediaType = 'video';
663
+ }
664
+ else {
665
+ console.error(`unknown media type ${file.type} (${file.name})`);
666
+ return;
667
+ }
668
+ const uploadUrl = this.uploadUrlMap.get(uploadingMediaType);
669
+ if (uploadUrl === undefined || uploadUrl === null) {
670
+ console.error(`upload map doesn't have url for type ${uploadingMediaType}`);
671
+ return;
672
+ }
673
+ const formData = new FormData();
674
+ formData.append('file', file);
675
+ formData.append('ratio', `${this.forceRatio ?? 0}`);
676
+ this.progress = 0;
677
+ this.isUploading = true;
678
+ this.updateClip();
679
+ const request = new HttpRequest('POST', uploadUrl, formData, {
680
+ reportProgress: true
681
+ });
682
+ this.http
683
+ .request(request)
684
+ .pipe(map(event => this.getEventMessage(event)),
685
+ // tap(message => this.showProgress(message)),
686
+ last(), // return last (completed) message to caller
687
+ catchError(this.handleError(file))).subscribe(() => { this.isUploading = false; });
688
+ }
689
+ selectFile(event) {
690
+ // ignore buble click on file picker
691
+ if (event.target === this.fileInput.nativeElement)
692
+ return;
693
+ this.fileInput.nativeElement.click();
694
+ }
695
+ getEventMessage(event) {
696
+ switch (event.type) {
697
+ case HttpEventType.Sent:
698
+ return;
699
+ case HttpEventType.UploadProgress:
700
+ this.progress = event.total === undefined ? 0.5 : event.loaded / event.total;
701
+ this.updateClip();
702
+ return;
703
+ case HttpEventType.Response:
704
+ if (event.body === undefined || event.body === null) {
705
+ console.error('media deserialization error. Response body in undefined');
706
+ }
707
+ else {
708
+ // remove this
709
+ // needed for C# deserialization
710
+ const pixmedia = {
711
+ $type: event.body.type,
712
+ ...event.body,
713
+ };
714
+ this.srcChange.emit(pixmedia);
715
+ }
716
+ return;
717
+ default:
718
+ return;
719
+ }
720
+ }
721
+ updateClip() {
722
+ this.clipStyle = this.sanitizer.bypassSecurityTrustStyle(`inset(0px 100% 0px 0%)`);
723
+ }
724
+ handleError(file) {
725
+ const func = (error, p2) => {
726
+ const message = `error uploadingFile ${file.name}.`;
727
+ console.error(message, error, p2);
728
+ alert(message);
729
+ return new Observable();
730
+ };
731
+ return func;
732
+ }
733
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: MediaUploaderComponent, deps: [{ token: i1$1.DomSanitizer }, { token: i2.HttpClient }], target: i0.ɵɵFactoryTarget.Component }); }
734
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: MediaUploaderComponent, selector: "bonc-media-uploader", inputs: { uploadUrlMap: "uploadUrlMap", forceRatio: "forceRatio", src: "src", uploadType: "uploadType" }, outputs: { srcChange: "srcChange" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, static: true }], ngImport: i0, template: "<bon-media [src]=\"src\" [objectFit]=\"MediaObjectFit.Cover\"></bon-media>\r\n\r\n<div *ngIf=\"src?.sources?.length===0\">NO MEDIA</div>\r\n\r\n<div (click)=\"selectFile($event)\" class=\"media-container\">\r\n\r\n <input #fileInput [accept]=\"fileTypeMask\" (change)=\"onFileSelect(fileInput)\" name=\"media\" type=\"file\" />\r\n <span *ngIf=\"isUploading\"\r\n [style.clip-path]=\"clipStyle\"\r\n [style.-webkit-clip-path]=\"clipStyle\"\r\n class=\"loader\"></span>\r\n\r\n <span *ngIf=\"isUploading\" class=\"loader-text\">\r\n <span *ngIf=\"progress < 1\">{{100 * progress | number: '1.0-0'}}%</span>\r\n <span *ngIf=\"progress >= 1\">converting</span>\r\n </span>\r\n</div>\r\n", styles: [":host{display:block;background-color:#000;position:relative}.media-container{display:block;position:absolute;inset:0;cursor:pointer}.media-container:hover:hover:after{display:flex;justify-content:center;align-items:center;content:\"\";position:absolute;color:silver;inset:0;font-weight:700;font-size:50pt;pointer-events:none;background-color:#ccff00b3}.media-container img,.media-container video{display:block;position:absolute;top:0;left:0;width:100%;height:100%;object-fit:cover}input[type=file]{display:none}.loader{position:absolute;inset:0;background-color:#cf0}.loader-text{background-color:#000;position:absolute;top:50%;left:0;right:0;text-align:center;font-size:20pt;margin-top:-10pt;color:#fff}\n"], dependencies: [{ kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MarcyMediaComponent, selector: "bon-media", inputs: ["src", "objectFit"], outputs: ["isLoaded"] }, { kind: "pipe", type: i2$2.DecimalPipe, name: "number" }] }); }
735
+ }
736
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: MediaUploaderComponent, decorators: [{
737
+ type: Component,
738
+ args: [{ selector: 'bonc-media-uploader', template: "<bon-media [src]=\"src\" [objectFit]=\"MediaObjectFit.Cover\"></bon-media>\r\n\r\n<div *ngIf=\"src?.sources?.length===0\">NO MEDIA</div>\r\n\r\n<div (click)=\"selectFile($event)\" class=\"media-container\">\r\n\r\n <input #fileInput [accept]=\"fileTypeMask\" (change)=\"onFileSelect(fileInput)\" name=\"media\" type=\"file\" />\r\n <span *ngIf=\"isUploading\"\r\n [style.clip-path]=\"clipStyle\"\r\n [style.-webkit-clip-path]=\"clipStyle\"\r\n class=\"loader\"></span>\r\n\r\n <span *ngIf=\"isUploading\" class=\"loader-text\">\r\n <span *ngIf=\"progress < 1\">{{100 * progress | number: '1.0-0'}}%</span>\r\n <span *ngIf=\"progress >= 1\">converting</span>\r\n </span>\r\n</div>\r\n", styles: [":host{display:block;background-color:#000;position:relative}.media-container{display:block;position:absolute;inset:0;cursor:pointer}.media-container:hover:hover:after{display:flex;justify-content:center;align-items:center;content:\"\";position:absolute;color:silver;inset:0;font-weight:700;font-size:50pt;pointer-events:none;background-color:#ccff00b3}.media-container img,.media-container video{display:block;position:absolute;top:0;left:0;width:100%;height:100%;object-fit:cover}input[type=file]{display:none}.loader{position:absolute;inset:0;background-color:#cf0}.loader-text{background-color:#000;position:absolute;top:50%;left:0;right:0;text-align:center;font-size:20pt;margin-top:-10pt;color:#fff}\n"] }]
739
+ }], ctorParameters: () => [{ type: i1$1.DomSanitizer }, { type: i2.HttpClient }], propDecorators: { fileInput: [{
740
+ type: ViewChild,
741
+ args: ['fileInput', { static: true }]
742
+ }], srcChange: [{
743
+ type: Output
744
+ }], uploadUrlMap: [{
745
+ type: Input,
746
+ args: [{ required: true }]
747
+ }], forceRatio: [{
748
+ type: Input
749
+ }], src: [{
750
+ type: Input
751
+ }], uploadType: [{
752
+ type: Input
753
+ }] } });
754
+
755
+ var TextInputStyle;
756
+ (function (TextInputStyle) {
757
+ TextInputStyle[TextInputStyle["NotSet"] = 0] = "NotSet";
758
+ TextInputStyle[TextInputStyle["SingleLine"] = 1] = "SingleLine";
759
+ TextInputStyle[TextInputStyle["MultiLine"] = 2] = "MultiLine";
760
+ })(TextInputStyle || (TextInputStyle = {}));
761
+
762
+ class TextFormComponent extends FormBaseComponent {
763
+ constructor() {
764
+ super(...arguments);
765
+ this.TextInputStyle = TextInputStyle;
766
+ this.label = '';
767
+ this.type = TextInputStyle.SingleLine;
768
+ }
769
+ ngOnInit() {
770
+ this.editable.externalSaveCall.subscribe(() => {
771
+ this.editable.save();
772
+ });
773
+ }
774
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: TextFormComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
775
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: TextFormComponent, selector: "bonc-text-form", inputs: { locale: "locale", label: "label", type: "type" }, usesInheritance: true, hostDirectives: [{ directive: EditableDirective }], ngImport: i0, template: "<bonc-form-controls [editable]=\"editable\">\r\n <label *ngIf=\"label\">{{label}}</label>\r\n\r\n <input *ngIf=\"editable && type === TextInputStyle.SingleLine\"\r\n [(ngModel)]=\"editable.value\"\r\n (click)=\"editable.startEditing()\"\r\n (keyup)=\"editable.updateDirty()\"\r\n (blur)=\"editable.updateDirty()\" />\r\n\r\n <textarea *ngIf=\"editable && type === TextInputStyle.MultiLine\"\r\n [(ngModel)]=\"editable.value\"\r\n (click)=\"editable.startEditing()\"\r\n (keyup)=\"editable.updateDirty()\"\r\n (blur)=\"editable.updateDirty()\">\r\n </textarea>\r\n</bonc-form-controls>\r\n", styles: [":host{display:block}input,textarea{display:block;width:100%;padding:6px;color:silver;border:1px solid silver;background-color:transparent;box-sizing:border-box;font-size:inherit}input:hover,textarea:hover{border-color:transparent;background-color:#333;cursor:pointer}input:focus,textarea:focus{outline:none;color:#fff;border-color:transparent;background-color:#555}\n"], dependencies: [{ kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: FormControlsComponent, selector: "bonc-form-controls", inputs: ["editable"] }] }); }
776
+ }
777
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: TextFormComponent, decorators: [{
778
+ type: Component,
779
+ args: [{ selector: 'bonc-text-form', inputs: FormBaseComponent.inputs, hostDirectives: [EditableDirective], template: "<bonc-form-controls [editable]=\"editable\">\r\n <label *ngIf=\"label\">{{label}}</label>\r\n\r\n <input *ngIf=\"editable && type === TextInputStyle.SingleLine\"\r\n [(ngModel)]=\"editable.value\"\r\n (click)=\"editable.startEditing()\"\r\n (keyup)=\"editable.updateDirty()\"\r\n (blur)=\"editable.updateDirty()\" />\r\n\r\n <textarea *ngIf=\"editable && type === TextInputStyle.MultiLine\"\r\n [(ngModel)]=\"editable.value\"\r\n (click)=\"editable.startEditing()\"\r\n (keyup)=\"editable.updateDirty()\"\r\n (blur)=\"editable.updateDirty()\">\r\n </textarea>\r\n</bonc-form-controls>\r\n", styles: [":host{display:block}input,textarea{display:block;width:100%;padding:6px;color:silver;border:1px solid silver;background-color:transparent;box-sizing:border-box;font-size:inherit}input:hover,textarea:hover{border-color:transparent;background-color:#333;cursor:pointer}input:focus,textarea:focus{outline:none;color:#fff;border-color:transparent;background-color:#555}\n"] }]
780
+ }], propDecorators: { label: [{
781
+ type: Input
782
+ }], type: [{
783
+ type: Input
784
+ }] } });
785
+
786
+ class SeoFormComponent extends FormBaseComponent {
787
+ constructor() {
788
+ super(...arguments);
789
+ this._pageId = '';
790
+ this.ogImageUploadUrl = '';
791
+ this.label = '';
792
+ }
793
+ ngOnInit() {
794
+ this.editable.externalSaveCall.subscribe(() => {
795
+ this.editable.save();
796
+ });
797
+ }
798
+ set pageId(value) {
799
+ this._pageId = value;
800
+ this.ogImageUploadUrl = `/api/admin/page/Og-Image?pageId=${this.pageId}`; // todo: replace with link to single image api
801
+ }
802
+ get pageId() {
803
+ return this._pageId;
804
+ }
805
+ ResToSrc(res) {
806
+ return res.url;
807
+ }
808
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: SeoFormComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
809
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: SeoFormComponent, selector: "bonc-seo-form", inputs: { label: "label", pageId: "pageId" }, usesInheritance: true, hostDirectives: [{ directive: EditableDirective }], ngImport: i0, template: "<bonc-form-controls *ngIf=\"editable.value\" [editable]=\"editable\">\r\n <h2 *ngIf=\"label\">{{label}}</h2>\r\n\r\n <div class=\"form-group\">\r\n <label>Title</label>\r\n <bonc-translation-input [text]=\"editable.value.title\"\r\n [locale]=\"locale\"\r\n (startEditing)=\"editable.startEditing()\"\r\n (changed)=\"editable.updateDirty()\"\r\n (blurred)=\"editable.updateDirty()\">\r\n </bonc-translation-input>\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <label>Description</label>\r\n <bonc-translation-textarea [text]=\"editable.value.description\"\r\n [locale]=\"locale\"\r\n (startEditing)=\"editable.startEditing()\"\r\n (changed)=\"editable.updateDirty()\"\r\n (blurred)=\"editable.updateDirty()\">\r\n </bonc-translation-textarea>\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <label>Share image | 1200x630px</label>\r\n <!-- <simple-file-uploader *ngIf=\"locale === 'en'\"\r\n [(src)]=\"editable.value.ogImage.en\"\r\n [forceUploadUrl]=\"ogImageUploadUrl\"\r\n [uploadType]=\"MediaType.Image\"\r\n [needDelete]=\"true\"\r\n (deleteFile)=\"deleteOgImage()\"\r\n [ratio]=\"1200/630\"\r\n [resToSrc]=\"ResToSrc\"\r\n (srcChange)=\"editable.startEditing(); editable.patchSave('ogImage',editable.value.ogImage)\">\r\n </simple-file-uploader>\r\n\r\n <simple-file-uploader *ngIf=\"locale === 'ru'\"\r\n [(src)]=\"editable.value.ogImage.ru\"\r\n [forceUploadUrl]=\"ogImageUploadUrl\"\r\n [uploadType]=\"MediaType.Image\"\r\n [needDelete]=\"true\"\r\n (deleteFile)=\"deleteOgImage()\"\r\n [ratio]=\"1200/630\"\r\n [resToSrc]=\"ResToSrc\"\r\n (srcChange)=\"editable.startEditing(); editable.patchSave('ogImage',editable.value.ogImage)\">\r\n </simple-file-uploader> -->\r\n\r\n </div>\r\n\r\n</bonc-form-controls>\r\n\r\n<div *ngIf=\"!editable.value\">Editable Value canot be null or undefined</div>\r\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: TranslationInputComponent, selector: "bonc-translation-input", inputs: ["text", "locale", "device"], outputs: ["startEditing", "changed", "blurred"] }, { kind: "component", type: TranslationTextareaComponent, selector: "bonc-translation-textarea", inputs: ["minRows", "maxRows", "text", "locale", "device"], outputs: ["startEditing", "changed", "blurred"] }, { kind: "component", type: FormControlsComponent, selector: "bonc-form-controls", inputs: ["editable"] }] }); }
810
+ }
811
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: SeoFormComponent, decorators: [{
812
+ type: Component,
813
+ args: [{ selector: 'bonc-seo-form', hostDirectives: [EditableDirective], template: "<bonc-form-controls *ngIf=\"editable.value\" [editable]=\"editable\">\r\n <h2 *ngIf=\"label\">{{label}}</h2>\r\n\r\n <div class=\"form-group\">\r\n <label>Title</label>\r\n <bonc-translation-input [text]=\"editable.value.title\"\r\n [locale]=\"locale\"\r\n (startEditing)=\"editable.startEditing()\"\r\n (changed)=\"editable.updateDirty()\"\r\n (blurred)=\"editable.updateDirty()\">\r\n </bonc-translation-input>\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <label>Description</label>\r\n <bonc-translation-textarea [text]=\"editable.value.description\"\r\n [locale]=\"locale\"\r\n (startEditing)=\"editable.startEditing()\"\r\n (changed)=\"editable.updateDirty()\"\r\n (blurred)=\"editable.updateDirty()\">\r\n </bonc-translation-textarea>\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <label>Share image | 1200x630px</label>\r\n <!-- <simple-file-uploader *ngIf=\"locale === 'en'\"\r\n [(src)]=\"editable.value.ogImage.en\"\r\n [forceUploadUrl]=\"ogImageUploadUrl\"\r\n [uploadType]=\"MediaType.Image\"\r\n [needDelete]=\"true\"\r\n (deleteFile)=\"deleteOgImage()\"\r\n [ratio]=\"1200/630\"\r\n [resToSrc]=\"ResToSrc\"\r\n (srcChange)=\"editable.startEditing(); editable.patchSave('ogImage',editable.value.ogImage)\">\r\n </simple-file-uploader>\r\n\r\n <simple-file-uploader *ngIf=\"locale === 'ru'\"\r\n [(src)]=\"editable.value.ogImage.ru\"\r\n [forceUploadUrl]=\"ogImageUploadUrl\"\r\n [uploadType]=\"MediaType.Image\"\r\n [needDelete]=\"true\"\r\n (deleteFile)=\"deleteOgImage()\"\r\n [ratio]=\"1200/630\"\r\n [resToSrc]=\"ResToSrc\"\r\n (srcChange)=\"editable.startEditing(); editable.patchSave('ogImage',editable.value.ogImage)\">\r\n </simple-file-uploader> -->\r\n\r\n </div>\r\n\r\n</bonc-form-controls>\r\n\r\n<div *ngIf=\"!editable.value\">Editable Value canot be null or undefined</div>\r\n", styles: [":host{display:block}\n"] }]
814
+ }], propDecorators: { label: [{
815
+ type: Input
816
+ }], pageId: [{
817
+ type: Input
818
+ }] } });
819
+
820
+ class UnknownFormComponent extends FormBaseComponent {
821
+ constructor() {
822
+ super(...arguments);
823
+ this.label = '';
824
+ }
825
+ ngOnInit() {
826
+ this.editable.externalSaveCall.subscribe(() => {
827
+ this.editable.save();
828
+ });
829
+ }
830
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: UnknownFormComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
831
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: UnknownFormComponent, selector: "bonc-unknown-form", inputs: { locale: "locale", label: "label" }, usesInheritance: true, ngImport: i0, template: "<label>Unknown form:<b>{{label}}</b></label>\r\n<pre><ng-content></ng-content></pre>\r\n", styles: [":host{display:block;color:#000;padding:20px;background-color:#dc143c;margin-bottom:10px}\n"] }); }
832
+ }
833
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: UnknownFormComponent, decorators: [{
834
+ type: Component,
835
+ args: [{ selector: 'bonc-unknown-form', inputs: FormBaseComponent.inputs, template: "<label>Unknown form:<b>{{label}}</b></label>\r\n<pre><ng-content></ng-content></pre>\r\n", styles: [":host{display:block;color:#000;padding:20px;background-color:#dc143c;margin-bottom:10px}\n"] }]
836
+ }], propDecorators: { label: [{
837
+ type: Input
838
+ }] } });
839
+
840
+ class TranslationFormComponent extends FormBaseComponent {
841
+ constructor() {
842
+ super(...arguments);
843
+ this.TextEditorField = TextEditorField;
844
+ }
845
+ ngOnInit() {
846
+ this.editable.externalSaveCall.subscribe(() => {
847
+ this.editable.save();
848
+ });
849
+ }
850
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: TranslationFormComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
851
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: TranslationFormComponent, selector: "bonc-translation-form", inputs: { locale: "locale", field: "field", label: "label" }, usesInheritance: true, hostDirectives: [{ directive: EditableDirective }], ngImport: i0, template: "<bonc-form-controls *ngIf=\"editable.value\" [editable]=\"editable\">\r\n <label *ngIf=\"label\">{{label}}</label>\r\n\r\n <bonc-translation-input *ngIf=\"field === TextEditorField.Input\"\r\n [text]=\"editable.value\"\r\n [locale]=\"locale\"\r\n (startEditing)=\"editable.startEditing()\"\r\n (changed)=\"editable.updateDirty()\"\r\n (blurred)=\"editable.updateDirty()\">\r\n </bonc-translation-input>\r\n\r\n\r\n <bonc-translation-textarea *ngIf=\"field === TextEditorField.Textarea\"\r\n [text]=\"editable.value\"\r\n [minRows]=\"2\"\r\n [locale]=\"locale\"\r\n (startEditing)=\"editable.startEditing()\"\r\n (changed)=\"editable.updateDirty()\"\r\n (blurred)=\"editable.updateDirty()\">\r\n </bonc-translation-textarea>\r\n</bonc-form-controls>\r\n\r\n<div *ngIf=\"editable.value===undefined\">Editable value canot be undefined</div>\r\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: TranslationInputComponent, selector: "bonc-translation-input", inputs: ["text", "locale", "device"], outputs: ["startEditing", "changed", "blurred"] }, { kind: "component", type: TranslationTextareaComponent, selector: "bonc-translation-textarea", inputs: ["minRows", "maxRows", "text", "locale", "device"], outputs: ["startEditing", "changed", "blurred"] }, { kind: "component", type: FormControlsComponent, selector: "bonc-form-controls", inputs: ["editable"] }] }); }
852
+ }
853
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: TranslationFormComponent, decorators: [{
854
+ type: Component,
855
+ args: [{ selector: 'bonc-translation-form', inputs: FormBaseComponent.inputs, hostDirectives: [EditableDirective], template: "<bonc-form-controls *ngIf=\"editable.value\" [editable]=\"editable\">\r\n <label *ngIf=\"label\">{{label}}</label>\r\n\r\n <bonc-translation-input *ngIf=\"field === TextEditorField.Input\"\r\n [text]=\"editable.value\"\r\n [locale]=\"locale\"\r\n (startEditing)=\"editable.startEditing()\"\r\n (changed)=\"editable.updateDirty()\"\r\n (blurred)=\"editable.updateDirty()\">\r\n </bonc-translation-input>\r\n\r\n\r\n <bonc-translation-textarea *ngIf=\"field === TextEditorField.Textarea\"\r\n [text]=\"editable.value\"\r\n [minRows]=\"2\"\r\n [locale]=\"locale\"\r\n (startEditing)=\"editable.startEditing()\"\r\n (changed)=\"editable.updateDirty()\"\r\n (blurred)=\"editable.updateDirty()\">\r\n </bonc-translation-textarea>\r\n</bonc-form-controls>\r\n\r\n<div *ngIf=\"editable.value===undefined\">Editable value canot be undefined</div>\r\n", styles: [":host{display:block}\n"] }]
856
+ }], propDecorators: { field: [{
857
+ type: Input,
858
+ args: [{ required: true }]
859
+ }], label: [{
860
+ type: Input
861
+ }] } });
862
+
863
+ class SkeletonEditorAnchorDirective {
864
+ constructor(viewContainerRef) {
865
+ this.viewContainerRef = viewContainerRef;
866
+ }
867
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: SkeletonEditorAnchorDirective, deps: [{ token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive }); }
868
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.8", type: SkeletonEditorAnchorDirective, selector: "[boncSkeletonEditorAnchor]", ngImport: i0 }); }
869
+ }
870
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: SkeletonEditorAnchorDirective, decorators: [{
871
+ type: Directive,
872
+ args: [{
873
+ selector: '[boncSkeletonEditorAnchor]'
874
+ }]
875
+ }], ctorParameters: () => [{ type: i0.ViewContainerRef }] });
876
+
877
+ class BoneEditorBaseComponent {
878
+ constructor() {
879
+ this.editing = new EventEmitter();
880
+ this.saved = new EventEmitter();
881
+ this.removed = new EventEmitter();
882
+ this.device = DeviceType.NotSet;
883
+ this._storedData = '';
884
+ this._isDirty = false;
885
+ this._isEditing = false;
886
+ this.applyPresetAtIndex = (newIndex) => {
887
+ newIndex = newIndex < 0 ? 0 : newIndex % this.presets.length;
888
+ const currentIndex = this._currentPreset === undefined ? -1 : this.presets.indexOf(this._currentPreset);
889
+ if (currentIndex === newIndex)
890
+ return;
891
+ this._currentPreset = this.presets[newIndex];
892
+ this._currentPreset.transformer(this._bone);
893
+ this.updateDirty();
894
+ };
895
+ this.updatePresetByData = () => {
896
+ const countOfActive = this.presets.map(p => p.isActive(this._bone)).filter(p => p).length;
897
+ if (countOfActive !== 1)
898
+ throw new Error(`active preset count should be equal 1, but it was: ${countOfActive}. ${this.constructor.name}`);
899
+ for (let i = 0; this.presets.length; i++) {
900
+ const preset = this.presets[i];
901
+ if (preset.isActive(this._bone)) {
902
+ this.applyPresetAtIndex(i);
903
+ break;
904
+ }
905
+ }
906
+ };
907
+ this.presets = this.getPresets();
908
+ if (this.presets === undefined || this.presets === null)
909
+ throw new Error('presets cannot be undefined in ContentPreset constructor');
910
+ if (this.presets.length === 0) {
911
+ this.presets = [
912
+ {
913
+ title: 'default',
914
+ isActive: () => true,
915
+ transformer: bone => bone,
916
+ clean: bone => bone,
917
+ }
918
+ ];
919
+ }
920
+ this.noPresets = this.presets.length === 1;
921
+ }
922
+ get isMobile() {
923
+ return this.device !== undefined && this.device === DeviceType.Mobile;
924
+ }
925
+ get isTablet() {
926
+ return this.device !== undefined && this.device === DeviceType.Tablet;
927
+ }
928
+ get isDesktop() {
929
+ return this.device !== undefined && this.device === DeviceType.Desktop;
930
+ }
931
+ get currentPreset() {
932
+ return this._currentPreset;
933
+ }
934
+ get bone() {
935
+ return this._bone;
936
+ }
937
+ set bone(newData) {
938
+ this._isDirty = false;
939
+ this._storedData = JSON.stringify(newData);
940
+ this._bone = JSON.parse(this._storedData);
941
+ this.updatePresetByData();
942
+ }
943
+ get isDirty() {
944
+ return this._isDirty;
945
+ }
946
+ get isEditing() {
947
+ return this._isEditing;
948
+ }
949
+ resetData() {
950
+ this._isEditing = false;
951
+ this.bone = JSON.parse(this._storedData);
952
+ if (this.onReset !== undefined)
953
+ this.onReset();
954
+ this.editing.emit(false);
955
+ }
956
+ updateDirty() {
957
+ this._isDirty = JSON.stringify(this._bone) !== this._storedData;
958
+ }
959
+ markAsDirty() {
960
+ this._isDirty = true;
961
+ }
962
+ remove() {
963
+ this.removed.next();
964
+ }
965
+ save() {
966
+ if (!this.isDirty)
967
+ return;
968
+ this._isDirty = false;
969
+ this.finishEditing();
970
+ this._storedData = JSON.stringify(this._bone);
971
+ const clonedData = JSON.parse(this._storedData);
972
+ this.saved.emit(clonedData);
973
+ }
974
+ startEditing() {
975
+ if (this._isEditing) {
976
+ this.updateDirty();
977
+ return;
978
+ }
979
+ this._isEditing = true;
980
+ this.updateDirty();
981
+ this.editing.emit(true);
982
+ }
983
+ finishEditing() {
984
+ if (this._isDirty)
985
+ throw new Error('Нельзя закрывать редактирование когда есть изменения. Надо сохранить либо зарезетить.');
986
+ if (this.onFinishEditing !== undefined)
987
+ this.onFinishEditing();
988
+ this._isEditing = false;
989
+ }
990
+ nextPreset() {
991
+ const newIndex = this._currentPreset === undefined ? 0 : this.presets.indexOf(this._currentPreset) + 1;
992
+ this.applyPresetAtIndex(newIndex);
993
+ }
994
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: BoneEditorBaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
995
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: BoneEditorBaseComponent, selector: "ng-component", inputs: { locale: "locale", bone: "bone" }, host: { properties: { "class.mobile": "this.isMobile", "class.tablet": "this.isTablet", "class.desktop": "this.isDesktop" } }, ngImport: i0, template: '', isInline: true }); }
996
+ }
997
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: BoneEditorBaseComponent, decorators: [{
998
+ type: Component,
999
+ args: [{ template: '' }]
1000
+ }], ctorParameters: () => [], propDecorators: { locale: [{
1001
+ type: Input,
1002
+ args: [{ required: true }]
1003
+ }], isMobile: [{
1004
+ type: HostBinding,
1005
+ args: ['class.mobile']
1006
+ }], isTablet: [{
1007
+ type: HostBinding,
1008
+ args: ['class.tablet']
1009
+ }], isDesktop: [{
1010
+ type: HostBinding,
1011
+ args: ['class.desktop']
1012
+ }], bone: [{
1013
+ type: Input,
1014
+ args: [{ required: true }]
1015
+ }] } });
1016
+
1017
+ class UnknownBoneEditorComponent extends BoneEditorBaseComponent {
1018
+ onFinishEditing() { }
1019
+ onReset() { }
1020
+ getPresets() {
1021
+ return [];
1022
+ }
1023
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: UnknownBoneEditorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1024
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: UnknownBoneEditorComponent, selector: "bonc-unknown-bone-editor", usesInheritance: true, ngImport: i0, template: "<p>Unknown Bone Editor | bone type: {{bone.type}}</p>\r\n<pre>{{bone | json}}</pre>\r\n", styles: [":host{display:block;background-color:#dc143c}\n"], dependencies: [{ kind: "pipe", type: i2$2.JsonPipe, name: "json" }] }); }
1025
+ }
1026
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: UnknownBoneEditorComponent, decorators: [{
1027
+ type: Component,
1028
+ args: [{ selector: 'bonc-unknown-bone-editor', template: "<p>Unknown Bone Editor | bone type: {{bone.type}}</p>\r\n<pre>{{bone | json}}</pre>\r\n", styles: [":host{display:block;background-color:#dc143c}\n"] }]
1029
+ }] });
1030
+
1031
+ // todo: rename class
1032
+ class BoneEditorContainerComponent {
1033
+ constructor(componentFactoryResolver) {
1034
+ this.componentFactoryResolver = componentFactoryResolver;
1035
+ this.removed = new EventEmitter();
1036
+ this.saved = new EventEmitter();
1037
+ this.editing = new EventEmitter();
1038
+ this.DeviceType = DeviceType;
1039
+ this.themePopupIsShown = false;
1040
+ this.device = DeviceType.NotSet;
1041
+ this.nextPreset = () => {
1042
+ if (this.editor === undefined || this.editor === null)
1043
+ return;
1044
+ this.editor.nextPreset();
1045
+ };
1046
+ }
1047
+ ngOnChanges() {
1048
+ if (this.editor === undefined || this.editor === null)
1049
+ return;
1050
+ this.editor.locale = this.locale;
1051
+ this.editor.device = this.device;
1052
+ }
1053
+ get bone() {
1054
+ return this._bone;
1055
+ }
1056
+ set bone(newBone) {
1057
+ this._bone = newBone;
1058
+ if (this.removeSubscription) {
1059
+ this.removeSubscription.unsubscribe();
1060
+ this.removeSubscription = undefined;
1061
+ }
1062
+ if (this.saveSubscription) {
1063
+ this.saveSubscription.unsubscribe();
1064
+ this.saveSubscription = undefined;
1065
+ }
1066
+ if (this.changedSubscription) {
1067
+ this.changedSubscription.unsubscribe();
1068
+ this.changedSubscription = undefined;
1069
+ }
1070
+ const viewContainerRef = this.anchor.viewContainerRef;
1071
+ viewContainerRef.clear();
1072
+ const componentType = this.map.get(newBone.type) ?? UnknownBoneEditorComponent;
1073
+ const componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentType);
1074
+ const boneEditorRef = viewContainerRef.createComponent(componentFactory);
1075
+ this.editor = boneEditorRef.instance;
1076
+ this.editor.bone = newBone;
1077
+ this.removeSubscription = this.editor.removed.subscribe(() => {
1078
+ this.removed.next();
1079
+ });
1080
+ this.changedSubscription = this.editor.editing.subscribe((isEditing) => {
1081
+ this.editing.next(isEditing);
1082
+ });
1083
+ this.saveSubscription = this.editor.saved.subscribe((newBoneValue) => {
1084
+ this.saved.next(newBoneValue);
1085
+ });
1086
+ this.ngOnChanges();
1087
+ }
1088
+ // todo: add or remove visibility feature
1089
+ // public setDisabled = (disabled: boolean): void => {
1090
+ // if (this.editor === undefined || this.editor === null)
1091
+ // return;
1092
+ // this.editor.startEditing();
1093
+ // if (this.device === DeviceType.Desktop)
1094
+ // this.editor.bone.visibility = setOrRemoveFlag(this.editor.bone.visibility, DeviceVisibility.Desktop, !disabled);
1095
+ // else if (this.device === DeviceType.Tablet)
1096
+ // this.editor.bone.visibility = setOrRemoveFlag(this.editor.bone.visibility, DeviceVisibility.Tablet, !disabled);
1097
+ // else if (this.device === DeviceType.Mobile)
1098
+ // this.editor.bone.visibility = setOrRemoveFlag(this.editor.bone.visibility, DeviceVisibility.Mobile, !disabled);
1099
+ // this.editor.updateDirty();
1100
+ // }
1101
+ get disabled() {
1102
+ if (this.editor === undefined || this.editor === null)
1103
+ throw new Error('editor should have been set');
1104
+ return false;
1105
+ // todo: add or remove visibility feature
1106
+ // const visibility = this.editor.bone.visibility;
1107
+ // if (this.device === DeviceType.Desktop && hasFlag(visibility, DeviceVisibility.Desktop))
1108
+ // return false;
1109
+ // if (this.device === DeviceType.Tablet && hasFlag(visibility, DeviceVisibility.Tablet))
1110
+ // return false;
1111
+ // if (this.device === DeviceType.Mobile && hasFlag(visibility, DeviceVisibility.Mobile))
1112
+ // return false;
1113
+ // return true;
1114
+ }
1115
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: BoneEditorContainerComponent, deps: [{ token: i0.ComponentFactoryResolver }], target: i0.ɵɵFactoryTarget.Component }); }
1116
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: BoneEditorContainerComponent, selector: "bonc-bone-editor-container", inputs: { locale: "locale", device: "device", map: "map", bone: "bone" }, outputs: { removed: "removed", saved: "saved", editing: "editing" }, viewQueries: [{ propertyName: "anchor", first: true, predicate: SkeletonEditorAnchorDirective, descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"editor\" class=\"left bar\" [class.inactive]=\"editor.noPresets\">\r\n <!-- <a *ngFor=\"let control of editor.controls\" (click)=\"control.activate()\">{{control.label}}</a> -->\r\n <!-- <a (click)=\"setDisabled(!disabled)\" class=\"disabled\">block {{disabled ? 'disabled' : 'enabled'}} ({{editor.bone.visibility}})</a> -->\r\n <a *ngIf=\"editor.currentPreset && !editor.noPresets\" (click)=\"nextPreset()\" class=\"preset\">style:<br />{{editor.currentPreset.title}}</a>\r\n</div>\r\n\r\n<div class=\"editor-container\"\r\n [class.disabled]=\"disabled\"\r\n [style.width]=\"\r\n device === DeviceType.Desktop ? '75vw'\r\n : device === DeviceType.Tablet ? '55vw'\r\n : device === DeviceType.Mobile ? '35vw'\r\n : '75vw' \">\r\n <ng-template boncSkeletonEditorAnchor>\r\n </ng-template>\r\n</div>\r\n\r\n<div *ngIf=\"editor\" [class.active]=\"editor.isEditing || editor.isDirty\" class=\"right bar\">\r\n <!-- <a *ngIf=\"!editor.isEditing\" (click)=\"editor.remove()\" class=\"delete\">!!! remove</a> -->\r\n <a *ngIf=\"editor.isDirty\" (click)=\"editor.resetData()\" class=\"reset\">reset</a>\r\n <a *ngIf=\"editor.isEditing && !editor.isDirty\" (click)=\"editor.finishEditing()\" class=\"close\">close</a>\r\n <a *ngIf=\"editor.isDirty\" (click)=\"editor.save()\" class=\"save\">apply</a>\r\n</div>\r\n", styles: [":host{display:flex}.editor-container{background-color:var(--bg-color)}.editor-container.disabled{opacity:.1;pointer-events:none}.editor-container.mobile{width:350px}.preset{white-space:pre-line}.bar{width:120px;display:flex;flex-direction:column;pointer-events:all}.bar.left:hover,.bar.active{background-color:#111}.bar.hidden{opacity:.2}.bar.left{position:relative;border-right:none}.bar.right{border-left:none;text-align:right}.bar.right .delete{display:none}.bar.right .delete:hover{color:#ff355e}.bar.right.active .delete,.bar.right:hover .delete{display:block}.left.bar.inactive a:hover{cursor:initial;color:#444}.popup{position:absolute;top:0;right:-350px;display:flex;flex-direction:column;width:350px;padding:20px;color:#222;background-color:#fff;border:2px solid black;box-sizing:border-box;z-index:3}.popup a{padding:0!important;cursor:pointer!important}.popup a.close{position:absolute;top:10px;right:10px;color:#666}.popup a.close:hover{background-color:#cf0!important}.popup a.reset{align-self:flex-start;margin-top:30px}.popup a.reset:hover{background-color:#cf0!important}.color-group{display:flex}.color-group:first-of-type{margin-top:20px}.color-group label{flex:1}.color-group input{border:1px solid #222;padding:6px;cursor:pointer}.color-group input:hover,.color-group input:focus{outline:none}.color-group+.color-group{margin-top:10px}\n"], dependencies: [{ kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: SkeletonEditorAnchorDirective, selector: "[boncSkeletonEditorAnchor]" }] }); }
1117
+ }
1118
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: BoneEditorContainerComponent, decorators: [{
1119
+ type: Component,
1120
+ args: [{ selector: 'bonc-bone-editor-container', template: "<div *ngIf=\"editor\" class=\"left bar\" [class.inactive]=\"editor.noPresets\">\r\n <!-- <a *ngFor=\"let control of editor.controls\" (click)=\"control.activate()\">{{control.label}}</a> -->\r\n <!-- <a (click)=\"setDisabled(!disabled)\" class=\"disabled\">block {{disabled ? 'disabled' : 'enabled'}} ({{editor.bone.visibility}})</a> -->\r\n <a *ngIf=\"editor.currentPreset && !editor.noPresets\" (click)=\"nextPreset()\" class=\"preset\">style:<br />{{editor.currentPreset.title}}</a>\r\n</div>\r\n\r\n<div class=\"editor-container\"\r\n [class.disabled]=\"disabled\"\r\n [style.width]=\"\r\n device === DeviceType.Desktop ? '75vw'\r\n : device === DeviceType.Tablet ? '55vw'\r\n : device === DeviceType.Mobile ? '35vw'\r\n : '75vw' \">\r\n <ng-template boncSkeletonEditorAnchor>\r\n </ng-template>\r\n</div>\r\n\r\n<div *ngIf=\"editor\" [class.active]=\"editor.isEditing || editor.isDirty\" class=\"right bar\">\r\n <!-- <a *ngIf=\"!editor.isEditing\" (click)=\"editor.remove()\" class=\"delete\">!!! remove</a> -->\r\n <a *ngIf=\"editor.isDirty\" (click)=\"editor.resetData()\" class=\"reset\">reset</a>\r\n <a *ngIf=\"editor.isEditing && !editor.isDirty\" (click)=\"editor.finishEditing()\" class=\"close\">close</a>\r\n <a *ngIf=\"editor.isDirty\" (click)=\"editor.save()\" class=\"save\">apply</a>\r\n</div>\r\n", styles: [":host{display:flex}.editor-container{background-color:var(--bg-color)}.editor-container.disabled{opacity:.1;pointer-events:none}.editor-container.mobile{width:350px}.preset{white-space:pre-line}.bar{width:120px;display:flex;flex-direction:column;pointer-events:all}.bar.left:hover,.bar.active{background-color:#111}.bar.hidden{opacity:.2}.bar.left{position:relative;border-right:none}.bar.right{border-left:none;text-align:right}.bar.right .delete{display:none}.bar.right .delete:hover{color:#ff355e}.bar.right.active .delete,.bar.right:hover .delete{display:block}.left.bar.inactive a:hover{cursor:initial;color:#444}.popup{position:absolute;top:0;right:-350px;display:flex;flex-direction:column;width:350px;padding:20px;color:#222;background-color:#fff;border:2px solid black;box-sizing:border-box;z-index:3}.popup a{padding:0!important;cursor:pointer!important}.popup a.close{position:absolute;top:10px;right:10px;color:#666}.popup a.close:hover{background-color:#cf0!important}.popup a.reset{align-self:flex-start;margin-top:30px}.popup a.reset:hover{background-color:#cf0!important}.color-group{display:flex}.color-group:first-of-type{margin-top:20px}.color-group label{flex:1}.color-group input{border:1px solid #222;padding:6px;cursor:pointer}.color-group input:hover,.color-group input:focus{outline:none}.color-group+.color-group{margin-top:10px}\n"] }]
1121
+ }], ctorParameters: () => [{ type: i0.ComponentFactoryResolver }], propDecorators: { anchor: [{
1122
+ type: ViewChild,
1123
+ args: [SkeletonEditorAnchorDirective, { static: true }]
1124
+ }], removed: [{
1125
+ type: Output
1126
+ }], saved: [{
1127
+ type: Output
1128
+ }], editing: [{
1129
+ type: Output
1130
+ }], locale: [{
1131
+ type: Input,
1132
+ args: [{ required: true }]
1133
+ }], device: [{
1134
+ type: Input
1135
+ }], map: [{
1136
+ type: Input,
1137
+ args: [{ required: true }]
1138
+ }], bone: [{
1139
+ type: Input,
1140
+ args: [{ required: true }]
1141
+ }] } });
1142
+
1143
+ // todo: rename class
1144
+ class SkeletonEditorComponent {
1145
+ constructor(editable) {
1146
+ this.editable = editable;
1147
+ this.device = DeviceType.NotSet;
1148
+ this.templatesAreShown = [];
1149
+ }
1150
+ ngOnInit() {
1151
+ this.editable.externalSaveCall.subscribe(() => {
1152
+ this.boneEditorContainerList.forEach(editorContainer => editorContainer.editor?.save());
1153
+ this.editable.save();
1154
+ });
1155
+ this.editable.canceled.subscribe(() => {
1156
+ this.boneEditorContainerList.forEach(editorContainer => editorContainer.editor?.resetData());
1157
+ this.editable.save();
1158
+ });
1159
+ }
1160
+ ngOnChanges() {
1161
+ this.templatesAreShown.splice(0, this.templatesAreShown.length);
1162
+ if (this.bones === undefined)
1163
+ return;
1164
+ this.bones.forEach(() => this.templatesAreShown.push(false));
1165
+ this.templatesAreShown.push(false);
1166
+ }
1167
+ get bones() {
1168
+ return this.editable?.value ?? [];
1169
+ }
1170
+ boneEditHandler(isEditing) {
1171
+ if (isEditing)
1172
+ this.editable.startEditing();
1173
+ else {
1174
+ const allClosed = this.boneEditorContainerList
1175
+ .filter(x => x.editor !== undefined && x.editor.isEditing)
1176
+ .length === 0;
1177
+ this.editable.updateDirty();
1178
+ if (!this.editable.isDirty && allClosed)
1179
+ this.editable.close();
1180
+ }
1181
+ }
1182
+ boneChangeHandler(index, newBoneValue) {
1183
+ if (Array.isArray(this.editable.value)) {
1184
+ this.editable.value[index] = newBoneValue;
1185
+ }
1186
+ this.editable.save();
1187
+ }
1188
+ removeBone(boneIndex) {
1189
+ if (this.bones === undefined || this.bones === null)
1190
+ return;
1191
+ if (!confirm('Вы уверены, что хотите удалить компонент?'))
1192
+ return;
1193
+ this.bones.splice(boneIndex, 1);
1194
+ if (!this.editable.inEditMode)
1195
+ this.editable.startEditing();
1196
+ this.editable.save();
1197
+ }
1198
+ moveDown(boneIndex) {
1199
+ if (boneIndex >= this.bones.length - 1)
1200
+ return;
1201
+ this.swapBones(boneIndex, boneIndex + 1);
1202
+ }
1203
+ moveUp(boneIndex) {
1204
+ if (boneIndex <= 0)
1205
+ return;
1206
+ this.swapBones(boneIndex - 1, boneIndex);
1207
+ }
1208
+ createBone(index, selectedTemplate) {
1209
+ const newBone = selectedTemplate.boneFactory();
1210
+ this.bones.splice(index, 0, newBone);
1211
+ }
1212
+ swapBones(index1, index2) {
1213
+ if (index1 < 0 || index2 < 0 || index1 >= this.bones.length || index2 >= this.bones.length)
1214
+ throw new Error(`ошибка swapBones. неправильные индексы ${index1} и ${index2}. bone count: ${this.bones.length}`);
1215
+ const tempBone = this.bones[index1];
1216
+ this.bones[index1] = this.bones[index2];
1217
+ this.bones[index2] = tempBone;
1218
+ }
1219
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: SkeletonEditorComponent, deps: [{ token: EditableDirective, host: true }], target: i0.ɵɵFactoryTarget.Component }); }
1220
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: SkeletonEditorComponent, selector: "bonc-skeleton-editor", inputs: { locale: "locale", device: "device", map: "map", templates: "templates" }, viewQueries: [{ propertyName: "boneEditorContainerList", predicate: ["boneEditorContainer"], descendants: true }], usesOnChanges: true, hostDirectives: [{ directive: EditableDirective }], ngImport: i0, template: "<ng-template #controls let-index='index'>\r\n <div [class.appearable]=\"index > 0 && index < bones.length\" class=\"controls\">\r\n <div *ngIf=\"index < bones.length\" class=\"up-down\">\r\n <a *ngIf=\"index > 0\" (click)=\"moveDown(index - 1)\" class=\"down\">move down</a>\r\n <a *ngIf=\"index > 0\" (click)=\"moveUp(index)\" class=\"up\">move up</a>\r\n </div>\r\n <a (click)=\"templatesAreShown[index] = true\" class=\"add\">create</a>\r\n <a *ngIf=\"index < bones.length\" (click)=\"removeBone(index)\" class=\"remove\">remove</a>\r\n </div>\r\n\r\n <div *ngIf=\"templatesAreShown[index]\" class=\"templates\">\r\n <a *ngFor=\"let template of templates\" (click)=\"templatesAreShown[index] = false; createBone(index,template);\">{{template.title}}</a>\r\n <a (click)=\"templatesAreShown[index] = false\">Close</a>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- todo: add trackby -->\r\n<ng-container *ngFor=\"let bone of bones; let i = index\">\r\n <ng-container>\r\n <ng-container *ngTemplateOutlet=\"controls; context: {index: i}\"></ng-container>\r\n </ng-container>\r\n\r\n <bonc-bone-editor-container #boneEditorContainer\r\n [map]=\"map\"\r\n [bone]=\"bone\"\r\n [locale]=\"locale\"\r\n [device]=\"device\"\r\n (removed)=\"removeBone(i)\"\r\n (editing)=\"boneEditHandler($event)\"\r\n (saved)=\"boneChangeHandler(i, $event)\">\r\n </bonc-bone-editor-container>\r\n\r\n</ng-container>\r\n\r\n<ng-container *ngTemplateOutlet=\"controls; context: {index: bones.length}\"></ng-container>\r\n", styles: [":host{display:block}.controls{height:62px;display:flex;align-items:center;justify-content:space-between;margin:0 120px}.controls.appearable{background-color:var(--bg-color)}.controls.appearable *{opacity:0}.controls.appearable:hover{background-color:#222}.controls.appearable:hover *{opacity:1}.controls .up-down{width:100px;align-self:stretch;display:flex;flex-direction:column;justify-content:space-between}.controls a{display:flex;align-items:center;justify-content:center;color:#000;background-color:#cf0;-webkit-user-select:none;user-select:none;cursor:pointer}.controls a.add{padding:10px 30px}.controls a.up,.controls a.down,.controls a.remove{padding:4px 8px}.controls a.remove{align-self:flex-end}.controls a:hover{color:#cf0;background-color:#333}.controls a.remove:hover{color:#fff;background-color:#ff355e}.templates{width:220px;height:380px;position:absolute;left:50%;display:flex;flex-direction:column;margin-left:-110px;margin-top:-190px;z-index:10;padding:6px;background-color:#cf0;box-shadow:0 0 78px #000000bf}.templates a{display:flex;flex:1;align-items:center;justify-content:center;background-color:#cf0;text-align:center;cursor:pointer;text-transform:lowercase}.templates a:hover{text-decoration:underline;font-weight:700}\n"], dependencies: [{ kind: "directive", type: i2$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: BoneEditorContainerComponent, selector: "bonc-bone-editor-container", inputs: ["locale", "device", "map", "bone"], outputs: ["removed", "saved", "editing"] }] }); }
1221
+ }
1222
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: SkeletonEditorComponent, decorators: [{
1223
+ type: Component,
1224
+ args: [{ selector: 'bonc-skeleton-editor', hostDirectives: [EditableDirective], template: "<ng-template #controls let-index='index'>\r\n <div [class.appearable]=\"index > 0 && index < bones.length\" class=\"controls\">\r\n <div *ngIf=\"index < bones.length\" class=\"up-down\">\r\n <a *ngIf=\"index > 0\" (click)=\"moveDown(index - 1)\" class=\"down\">move down</a>\r\n <a *ngIf=\"index > 0\" (click)=\"moveUp(index)\" class=\"up\">move up</a>\r\n </div>\r\n <a (click)=\"templatesAreShown[index] = true\" class=\"add\">create</a>\r\n <a *ngIf=\"index < bones.length\" (click)=\"removeBone(index)\" class=\"remove\">remove</a>\r\n </div>\r\n\r\n <div *ngIf=\"templatesAreShown[index]\" class=\"templates\">\r\n <a *ngFor=\"let template of templates\" (click)=\"templatesAreShown[index] = false; createBone(index,template);\">{{template.title}}</a>\r\n <a (click)=\"templatesAreShown[index] = false\">Close</a>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- todo: add trackby -->\r\n<ng-container *ngFor=\"let bone of bones; let i = index\">\r\n <ng-container>\r\n <ng-container *ngTemplateOutlet=\"controls; context: {index: i}\"></ng-container>\r\n </ng-container>\r\n\r\n <bonc-bone-editor-container #boneEditorContainer\r\n [map]=\"map\"\r\n [bone]=\"bone\"\r\n [locale]=\"locale\"\r\n [device]=\"device\"\r\n (removed)=\"removeBone(i)\"\r\n (editing)=\"boneEditHandler($event)\"\r\n (saved)=\"boneChangeHandler(i, $event)\">\r\n </bonc-bone-editor-container>\r\n\r\n</ng-container>\r\n\r\n<ng-container *ngTemplateOutlet=\"controls; context: {index: bones.length}\"></ng-container>\r\n", styles: [":host{display:block}.controls{height:62px;display:flex;align-items:center;justify-content:space-between;margin:0 120px}.controls.appearable{background-color:var(--bg-color)}.controls.appearable *{opacity:0}.controls.appearable:hover{background-color:#222}.controls.appearable:hover *{opacity:1}.controls .up-down{width:100px;align-self:stretch;display:flex;flex-direction:column;justify-content:space-between}.controls a{display:flex;align-items:center;justify-content:center;color:#000;background-color:#cf0;-webkit-user-select:none;user-select:none;cursor:pointer}.controls a.add{padding:10px 30px}.controls a.up,.controls a.down,.controls a.remove{padding:4px 8px}.controls a.remove{align-self:flex-end}.controls a:hover{color:#cf0;background-color:#333}.controls a.remove:hover{color:#fff;background-color:#ff355e}.templates{width:220px;height:380px;position:absolute;left:50%;display:flex;flex-direction:column;margin-left:-110px;margin-top:-190px;z-index:10;padding:6px;background-color:#cf0;box-shadow:0 0 78px #000000bf}.templates a{display:flex;flex:1;align-items:center;justify-content:center;background-color:#cf0;text-align:center;cursor:pointer;text-transform:lowercase}.templates a:hover{text-decoration:underline;font-weight:700}\n"] }]
1225
+ }], ctorParameters: () => [{ type: EditableDirective, decorators: [{
1226
+ type: Host
1227
+ }] }], propDecorators: { boneEditorContainerList: [{
1228
+ type: ViewChildren,
1229
+ args: ['boneEditorContainer']
1230
+ }], locale: [{
1231
+ type: Input,
1232
+ args: [{ required: true }]
1233
+ }], device: [{
1234
+ type: Input
1235
+ }], map: [{
1236
+ type: Input,
1237
+ args: [{ required: true }]
1238
+ }], templates: [{
1239
+ type: Input,
1240
+ args: [{ required: true }]
1241
+ }] } });
1242
+
1243
+ function createPreset(params) {
1244
+ return {
1245
+ title: params.title,
1246
+ isActive: x => x.style === params.style,
1247
+ transformer: bone => bone.style = params.style,
1248
+ clean: bone => bone.style = params.style,
1249
+ };
1250
+ }
1251
+
1252
+ const components = [
1253
+ TranslationInputComponent,
1254
+ TranslationTextareaComponent,
1255
+ AdminControlsComponent,
1256
+ EditableGroupComponent,
1257
+ FormControlsComponent,
1258
+ TranslationFormComponent,
1259
+ TextFormComponent,
1260
+ SeoFormComponent,
1261
+ UnknownFormComponent,
1262
+ SkeletonEditorComponent,
1263
+ SkeletonEditorAnchorDirective,
1264
+ BoneEditorContainerComponent,
1265
+ UnknownBoneEditorComponent,
1266
+ MediaUploaderComponent,
1267
+ LinkPopupComponent
1268
+ ];
1269
+ const standaloneDirectives = [
1270
+ EditableDirective
1271
+ ];
1272
+ class BonnieCmsModule {
1273
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: BonnieCmsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1274
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.8", ngImport: i0, type: BonnieCmsModule, declarations: [TranslationInputComponent,
1275
+ TranslationTextareaComponent,
1276
+ AdminControlsComponent,
1277
+ EditableGroupComponent,
1278
+ FormControlsComponent,
1279
+ TranslationFormComponent,
1280
+ TextFormComponent,
1281
+ SeoFormComponent,
1282
+ UnknownFormComponent,
1283
+ SkeletonEditorComponent,
1284
+ SkeletonEditorAnchorDirective,
1285
+ BoneEditorContainerComponent,
1286
+ UnknownBoneEditorComponent,
1287
+ MediaUploaderComponent,
1288
+ LinkPopupComponent], imports: [CommonModule,
1289
+ FormsModule,
1290
+ CdkTextareaAutosize,
1291
+ BonnieModule, EditableDirective], exports: [CommonModule,
1292
+ FormsModule,
1293
+ BonnieModule, TranslationInputComponent,
1294
+ TranslationTextareaComponent,
1295
+ AdminControlsComponent,
1296
+ EditableGroupComponent,
1297
+ FormControlsComponent,
1298
+ TranslationFormComponent,
1299
+ TextFormComponent,
1300
+ SeoFormComponent,
1301
+ UnknownFormComponent,
1302
+ SkeletonEditorComponent,
1303
+ SkeletonEditorAnchorDirective,
1304
+ BoneEditorContainerComponent,
1305
+ UnknownBoneEditorComponent,
1306
+ MediaUploaderComponent,
1307
+ LinkPopupComponent, EditableDirective] }); }
1308
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: BonnieCmsModule, imports: [CommonModule,
1309
+ FormsModule,
1310
+ BonnieModule, CommonModule,
1311
+ FormsModule,
1312
+ BonnieModule] }); }
1313
+ } // todo: move to standalone
1314
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: BonnieCmsModule, decorators: [{
1315
+ type: NgModule,
1316
+ args: [{
1317
+ declarations: [
1318
+ ...components,
1319
+ ],
1320
+ providers: [],
1321
+ imports: [
1322
+ CommonModule,
1323
+ FormsModule,
1324
+ CdkTextareaAutosize,
1325
+ BonnieModule,
1326
+ ...standaloneDirectives
1327
+ ],
1328
+ exports: [
1329
+ CommonModule,
1330
+ FormsModule,
1331
+ BonnieModule,
1332
+ ...components,
1333
+ ...standaloneDirectives
1334
+ ]
1335
+ }]
1336
+ }] });
1337
+
1338
+ /**
1339
+ * Generated bundle index. Do not edit.
1340
+ */
1341
+
1342
+ export { AdminControlsComponent, BoneEditorBaseComponent, BoneEditorContainerComponent, BonnieCmsModule, DeviceType, DeviceVisibility, EditableDirective, EditableGroupComponent, FormBaseComponent, FormControlsComponent, LinkPopupComponent, MediaUploaderComponent, SeoFormComponent, SkeletonEditorAnchorDirective, SkeletonEditorComponent, TextEditorField, TextFormComponent, TextInputStyle, TextSettingType, TranslationFormComponent, TranslationInputComponent, TranslationTextareaComponent, UnknownBoneEditorComponent, UnknownFormComponent, createPreset, hasFlag, isLocalUrlString, regExpIsMobile, setOrRemoveFlag };
1343
+ //# sourceMappingURL=candy-kingdom-bonnie-cms.mjs.map