@candy-kingdom/bonnie-cms 0.26.16 → 0.27.0
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.
|
@@ -1,91 +1,16 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import { CommonModule, DecimalPipe, JsonPipe } from '@angular/common';
|
|
5
|
-
import { Subject, debounceTime, map, last, catchError, Observable, of, combineLatest, mergeMap, merge } from 'rxjs';
|
|
2
|
+
import { input, Component, output, model, signal, computed, effect, HostBinding, forwardRef, Directive, contentChildren, inject, DestroyRef, viewChildren, viewChild, InjectionToken, Injectable, ViewContainerRef, afterNextRender } from '@angular/core';
|
|
3
|
+
import { JsonPipe, DecimalPipe, NgTemplateOutlet } from '@angular/common';
|
|
6
4
|
import * as i1 from '@angular/forms';
|
|
7
5
|
import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
|
|
6
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
7
|
+
import { Subject, debounceTime, map, last, catchError, Observable, of, combineLatest, mergeMap, merge } from 'rxjs';
|
|
8
8
|
import { CdkTextareaAutosize } from '@angular/cdk/text-field';
|
|
9
|
-
import { DomSanitizer } from '@angular/platform-browser';
|
|
10
9
|
import { HttpClient, HttpRequest, HttpEventType } from '@angular/common/http';
|
|
10
|
+
import { DomSanitizer } from '@angular/platform-browser';
|
|
11
11
|
import { LottieComponent } from 'ngx-lottie';
|
|
12
12
|
import { MediaObjectFit, MarcyMediaComponent } from '@candy-kingdom/bonnie';
|
|
13
13
|
|
|
14
|
-
/**
|
|
15
|
-
* This is a TypeGen auto-generated file.
|
|
16
|
-
* Any changes made to this file can be lost when this file is regenerated.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* This is a TypeGen auto-generated file.
|
|
21
|
-
* Any changes made to this file can be lost when this file is regenerated.
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* This is a TypeGen auto-generated file.
|
|
26
|
-
* Any changes made to this file can be lost when this file is regenerated.
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* This is a TypeGen auto-generated file.
|
|
31
|
-
* Any changes made to this file can be lost when this file is regenerated.
|
|
32
|
-
*/
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* This is a TypeGen auto-generated file.
|
|
36
|
-
* Any changes made to this file can be lost when this file is regenerated.
|
|
37
|
-
*/
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* This is a TypeGen auto-generated file.
|
|
41
|
-
* Any changes made to this file can be lost when this file is regenerated.
|
|
42
|
-
*/
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* This is a TypeGen auto-generated file.
|
|
46
|
-
* Any changes made to this file can be lost when this file is regenerated.
|
|
47
|
-
*/
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* This is a TypeGen auto-generated file.
|
|
51
|
-
* Any changes made to this file can be lost when this file is regenerated.
|
|
52
|
-
*/
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* This is a TypeGen auto-generated file.
|
|
56
|
-
* Any changes made to this file can be lost when this file is regenerated.
|
|
57
|
-
*/
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* This is a TypeGen auto-generated file.
|
|
61
|
-
* Any changes made to this file can be lost when this file is regenerated.
|
|
62
|
-
*/
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* This is a TypeGen auto-generated file.
|
|
66
|
-
* Any changes made to this file can be lost when this file is regenerated.
|
|
67
|
-
*/
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* This is a TypeGen auto-generated file.
|
|
71
|
-
* Any changes made to this file can be lost when this file is regenerated.
|
|
72
|
-
*/
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* This is a TypeGen auto-generated file.
|
|
76
|
-
* Any changes made to this file can be lost when this file is regenerated.
|
|
77
|
-
*/
|
|
78
|
-
var TextSettingType;
|
|
79
|
-
(function (TextSettingType) {
|
|
80
|
-
TextSettingType[TextSettingType["SingleLine"] = 0] = "SingleLine";
|
|
81
|
-
TextSettingType[TextSettingType["MultiLine"] = 1] = "MultiLine";
|
|
82
|
-
})(TextSettingType || (TextSettingType = {}));
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* This is a TypeGen auto-generated file.
|
|
86
|
-
* Any changes made to this file can be lost when this file is regenerated.
|
|
87
|
-
*/
|
|
88
|
-
|
|
89
14
|
var DeviceType;
|
|
90
15
|
(function (DeviceType) {
|
|
91
16
|
DeviceType[DeviceType["NotSet"] = 0] = "NotSet";
|
|
@@ -94,6 +19,15 @@ var DeviceType;
|
|
|
94
19
|
DeviceType[DeviceType["Desktop"] = 3] = "Desktop";
|
|
95
20
|
})(DeviceType || (DeviceType = {}));
|
|
96
21
|
|
|
22
|
+
var DeviceVisibility;
|
|
23
|
+
(function (DeviceVisibility) {
|
|
24
|
+
DeviceVisibility[DeviceVisibility["None"] = 0] = "None";
|
|
25
|
+
DeviceVisibility[DeviceVisibility["Desktop"] = 1] = "Desktop";
|
|
26
|
+
DeviceVisibility[DeviceVisibility["Tablet"] = 2] = "Tablet";
|
|
27
|
+
DeviceVisibility[DeviceVisibility["Mobile"] = 4] = "Mobile";
|
|
28
|
+
DeviceVisibility[DeviceVisibility["All"] = 7] = "All";
|
|
29
|
+
})(DeviceVisibility || (DeviceVisibility = {}));
|
|
30
|
+
|
|
97
31
|
var TextEditorField;
|
|
98
32
|
(function (TextEditorField) {
|
|
99
33
|
TextEditorField[TextEditorField["NotSet"] = 0] = "NotSet";
|
|
@@ -102,13 +36,13 @@ var TextEditorField;
|
|
|
102
36
|
})(TextEditorField || (TextEditorField = {}));
|
|
103
37
|
|
|
104
38
|
// tslint:disable-next-line: max-line-length
|
|
105
|
-
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/,
|
|
39
|
+
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");
|
|
106
40
|
function isLocalUrlString(url) {
|
|
107
41
|
if (url === undefined || url === null || url.trim().length === 0)
|
|
108
42
|
return true;
|
|
109
|
-
if (url.startsWith(
|
|
43
|
+
if (url.startsWith("//"))
|
|
110
44
|
return false;
|
|
111
|
-
if (url.startsWith(
|
|
45
|
+
if (url.startsWith("./") || url.startsWith("/"))
|
|
112
46
|
return true;
|
|
113
47
|
return false;
|
|
114
48
|
}
|
|
@@ -119,67 +53,225 @@ function setOrRemoveFlag(value, flag, enabled) {
|
|
|
119
53
|
return (enabled ? value | flag : value & ~flag);
|
|
120
54
|
}
|
|
121
55
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
56
|
+
class AdminControlsComponent {
|
|
57
|
+
DeviceType = DeviceType;
|
|
58
|
+
editableGroup = input.required(...(ngDevMode ? [{ debugName: "editableGroup" }] : []));
|
|
59
|
+
deviceControls = input(false, ...(ngDevMode ? [{ debugName: "deviceControls" }] : []));
|
|
60
|
+
locale = "en";
|
|
61
|
+
device = this.DeviceType.Desktop;
|
|
62
|
+
changeLocale() {
|
|
63
|
+
this.locale = this.locale === "en" ? "ru" : "en"; // move locales to CMS config
|
|
64
|
+
}
|
|
65
|
+
changeDevice() {
|
|
66
|
+
switch (this.device) {
|
|
67
|
+
case DeviceType.Desktop:
|
|
68
|
+
this.device = DeviceType.Tablet;
|
|
69
|
+
return;
|
|
70
|
+
case DeviceType.Tablet:
|
|
71
|
+
this.device = DeviceType.Mobile;
|
|
72
|
+
return;
|
|
73
|
+
case DeviceType.Mobile:
|
|
74
|
+
this.device = DeviceType.Desktop;
|
|
75
|
+
return;
|
|
76
|
+
default:
|
|
77
|
+
this.device = DeviceType.Desktop;
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: AdminControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
82
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: AdminControlsComponent, isStandalone: true, selector: "bonc-admin-controls", inputs: { editableGroup: { classPropertyName: "editableGroup", publicName: "editableGroup", isSignal: true, isRequired: true, transformFunction: null }, deviceControls: { classPropertyName: "deviceControls", publicName: "deviceControls", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"page-controls\">\n <a (click)=\"changeLocale()\" class=\"locale\">Locale: {{locale}}</a>\n\n <!-- todo: return this functionality -->\n <!-- <a *ngIf=\"deviceControls\" (click)=\"changeDevice()\" class=\"device\">\n <span *ngIf=\"device === DeviceType.Desktop\">DESKTOP</span>\n <span *ngIf=\"device === DeviceType.Tablet\">TABLET</span>\n <span *ngIf=\"device === DeviceType.Mobile\">MOBILE</span>\n </a> -->\n\n @if (editableGroup() && editableGroup().inEditMode()) {\n <a (click)=\"editableGroup().saveAll()\"\n class=\"save\">Save all</a>\n\n <a (click)=\"editableGroup().cancelAll()\"\n class=\"cancel\">Cancel all</a>\n }\n</div>\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"] });
|
|
83
|
+
}
|
|
84
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: AdminControlsComponent, decorators: [{
|
|
85
|
+
type: Component,
|
|
86
|
+
args: [{ selector: "bonc-admin-controls", template: "<div class=\"page-controls\">\n <a (click)=\"changeLocale()\" class=\"locale\">Locale: {{locale}}</a>\n\n <!-- todo: return this functionality -->\n <!-- <a *ngIf=\"deviceControls\" (click)=\"changeDevice()\" class=\"device\">\n <span *ngIf=\"device === DeviceType.Desktop\">DESKTOP</span>\n <span *ngIf=\"device === DeviceType.Tablet\">TABLET</span>\n <span *ngIf=\"device === DeviceType.Mobile\">MOBILE</span>\n </a> -->\n\n @if (editableGroup() && editableGroup().inEditMode()) {\n <a (click)=\"editableGroup().saveAll()\"\n class=\"save\">Save all</a>\n\n <a (click)=\"editableGroup().cancelAll()\"\n class=\"cancel\">Cancel all</a>\n }\n</div>\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"] }]
|
|
87
|
+
}], propDecorators: { editableGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "editableGroup", required: true }] }], deviceControls: [{ type: i0.Input, args: [{ isSignal: true, alias: "deviceControls", required: false }] }] } });
|
|
88
|
+
|
|
89
|
+
class BoneEditorBaseComponent {
|
|
90
|
+
editing = output();
|
|
91
|
+
saved = output();
|
|
92
|
+
removed = output();
|
|
93
|
+
boneEtalon = model.required(...(ngDevMode ? [{ debugName: "boneEtalon" }] : []));
|
|
94
|
+
locale = input.required(...(ngDevMode ? [{ debugName: "locale" }] : []));
|
|
95
|
+
device = input(DeviceType.NotSet, ...(ngDevMode ? [{ debugName: "device" }] : []));
|
|
96
|
+
_presets = signal([], ...(ngDevMode ? [{ debugName: "_presets" }] : []));
|
|
97
|
+
presets = this._presets.asReadonly();
|
|
98
|
+
_currentPreset = signal(undefined, ...(ngDevMode ? [{ debugName: "_currentPreset" }] : []));
|
|
99
|
+
currentPreset = this._currentPreset.asReadonly();
|
|
100
|
+
_isDirty = signal(false, ...(ngDevMode ? [{ debugName: "_isDirty" }] : []));
|
|
101
|
+
isDirty = this._isDirty.asReadonly();
|
|
102
|
+
_isEditing = signal(false, ...(ngDevMode ? [{ debugName: "_isEditing" }] : []));
|
|
103
|
+
isEditing = this._isEditing.asReadonly();
|
|
104
|
+
noPresets = computed(() => this.presets().length === 0, ...(ngDevMode ? [{ debugName: "noPresets" }] : []));
|
|
105
|
+
// effect gonna fix this undefined value
|
|
106
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
107
|
+
bone = signal(undefined, ...(ngDevMode ? [{ debugName: "bone" }] : []));
|
|
108
|
+
_storedBoneJson = "";
|
|
109
|
+
constructor() {
|
|
110
|
+
effect(() => {
|
|
111
|
+
const newData = this.boneEtalon();
|
|
112
|
+
this._isDirty.set(false);
|
|
113
|
+
this._storedBoneJson = JSON.stringify(newData);
|
|
114
|
+
this.bone.set(JSON.parse(this._storedBoneJson));
|
|
115
|
+
this.updatePresetByData();
|
|
116
|
+
});
|
|
117
|
+
const presets = this.getPresets();
|
|
118
|
+
if (presets.length === 0) {
|
|
119
|
+
presets.push({
|
|
120
|
+
title: "default",
|
|
121
|
+
isActive: () => true,
|
|
122
|
+
transformer: (bone) => bone,
|
|
123
|
+
clean: (bone) => bone,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
// todo: remove this, use just regular presets
|
|
127
|
+
this._presets.set(presets);
|
|
128
|
+
}
|
|
129
|
+
get isMobile() {
|
|
130
|
+
return this.device() === DeviceType.Mobile;
|
|
131
|
+
}
|
|
132
|
+
get isTablet() {
|
|
133
|
+
return this.device() === DeviceType.Tablet;
|
|
134
|
+
}
|
|
135
|
+
get isDesktop() {
|
|
136
|
+
return this.device() === DeviceType.Desktop;
|
|
137
|
+
}
|
|
138
|
+
resetData() {
|
|
139
|
+
this._isEditing.set(false);
|
|
140
|
+
this.boneEtalon.set(JSON.parse(this._storedBoneJson));
|
|
141
|
+
this.updatePresetByData();
|
|
142
|
+
if (this.onReset !== undefined)
|
|
143
|
+
this.onReset();
|
|
144
|
+
this.editing.emit(false);
|
|
145
|
+
}
|
|
146
|
+
updateDirty() {
|
|
147
|
+
this._isDirty.set(JSON.stringify(this.bone()) !== this._storedBoneJson);
|
|
148
|
+
}
|
|
149
|
+
markAsDirty() {
|
|
150
|
+
this._isDirty.set(true);
|
|
151
|
+
}
|
|
152
|
+
remove() {
|
|
153
|
+
this.removed.emit();
|
|
154
|
+
}
|
|
155
|
+
save() {
|
|
156
|
+
if (!this.isDirty())
|
|
157
|
+
return;
|
|
158
|
+
this._isDirty.set(false);
|
|
159
|
+
this.finishEditing();
|
|
160
|
+
this._storedBoneJson = JSON.stringify(this.bone());
|
|
161
|
+
const clonedData = JSON.parse(this._storedBoneJson);
|
|
162
|
+
this.saved.emit(clonedData);
|
|
163
|
+
}
|
|
164
|
+
startEditing() {
|
|
165
|
+
if (this.isEditing()) {
|
|
166
|
+
this.updateDirty();
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
this._isEditing.set(true);
|
|
170
|
+
this.updateDirty();
|
|
171
|
+
this.editing.emit(true);
|
|
172
|
+
}
|
|
173
|
+
finishEditing() {
|
|
174
|
+
if (this._isDirty())
|
|
175
|
+
throw new Error("Нельзя закрывать редактирование когда есть изменения. Надо сохранить либо зарезетить.");
|
|
176
|
+
if (this.onFinishEditing !== undefined)
|
|
177
|
+
this.onFinishEditing();
|
|
178
|
+
this._isEditing.set(false);
|
|
179
|
+
}
|
|
180
|
+
nextPreset() {
|
|
181
|
+
const currentPreset = this.currentPreset();
|
|
182
|
+
const newIndex = currentPreset === undefined ? 0 : this.presets().indexOf(currentPreset) + 1;
|
|
183
|
+
this.applyPresetAtIndex(newIndex);
|
|
184
|
+
}
|
|
185
|
+
applyPresetAtIndex = (newIndex) => {
|
|
186
|
+
newIndex = newIndex < 0 ? 0 : newIndex % this.presets().length;
|
|
187
|
+
const currentPreset = this.currentPreset();
|
|
188
|
+
const currentIndex = currentPreset === undefined ? -1 : this.presets().indexOf(currentPreset);
|
|
189
|
+
if (currentIndex === newIndex)
|
|
190
|
+
return;
|
|
191
|
+
const newPreset = this.presets()[newIndex];
|
|
192
|
+
this._currentPreset.set(newPreset);
|
|
193
|
+
newPreset.transformer(this.bone());
|
|
194
|
+
this.updateDirty();
|
|
195
|
+
};
|
|
196
|
+
updatePresetByData = () => {
|
|
197
|
+
const countOfActive = this.presets()
|
|
198
|
+
.map((p) => p.isActive(this.bone()))
|
|
199
|
+
.filter((p) => p).length;
|
|
200
|
+
if (countOfActive !== 1)
|
|
201
|
+
throw new Error(`active preset count should be equal 1, but it was: ${countOfActive}. ${this.constructor.name}`);
|
|
202
|
+
for (let i = 0; i < this.presets().length; i++) {
|
|
203
|
+
const preset = this.presets()[i];
|
|
204
|
+
if (preset.isActive(this.bone())) {
|
|
205
|
+
this.applyPresetAtIndex(i);
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: BoneEditorBaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
211
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.6", type: BoneEditorBaseComponent, isStandalone: true, selector: "ng-component", inputs: { boneEtalon: { classPropertyName: "boneEtalon", publicName: "boneEtalon", isSignal: true, isRequired: true, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: true, transformFunction: null }, device: { classPropertyName: "device", publicName: "device", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { editing: "editing", saved: "saved", removed: "removed", boneEtalon: "boneEtalonChange" }, host: { properties: { "class.mobile": "this.isMobile", "class.tablet": "this.isTablet", "class.desktop": "this.isDesktop" } }, ngImport: i0, template: "", isInline: true });
|
|
212
|
+
}
|
|
213
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: BoneEditorBaseComponent, decorators: [{
|
|
214
|
+
type: Component,
|
|
215
|
+
args: [{ template: "" }]
|
|
216
|
+
}], ctorParameters: () => [], propDecorators: { editing: [{ type: i0.Output, args: ["editing"] }], saved: [{ type: i0.Output, args: ["saved"] }], removed: [{ type: i0.Output, args: ["removed"] }], boneEtalon: [{ type: i0.Input, args: [{ isSignal: true, alias: "boneEtalon", required: true }] }, { type: i0.Output, args: ["boneEtalonChange"] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: true }] }], device: [{ type: i0.Input, args: [{ isSignal: true, alias: "device", required: false }] }], isMobile: [{
|
|
217
|
+
type: HostBinding,
|
|
218
|
+
args: ["class.mobile"]
|
|
219
|
+
}], isTablet: [{
|
|
220
|
+
type: HostBinding,
|
|
221
|
+
args: ["class.tablet"]
|
|
222
|
+
}], isDesktop: [{
|
|
223
|
+
type: HostBinding,
|
|
224
|
+
args: ["class.desktop"]
|
|
225
|
+
}] } });
|
|
226
|
+
|
|
227
|
+
class UnknownBoneEditorComponent extends BoneEditorBaseComponent {
|
|
228
|
+
onFinishEditing() {
|
|
229
|
+
// no-op for unknown bone type
|
|
230
|
+
}
|
|
231
|
+
onReset() {
|
|
232
|
+
// no-op for unknown bone type
|
|
233
|
+
}
|
|
234
|
+
getPresets() {
|
|
235
|
+
return [];
|
|
236
|
+
}
|
|
237
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: UnknownBoneEditorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
238
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: UnknownBoneEditorComponent, isStandalone: true, selector: "bonc-unknown-bone-editor", usesInheritance: true, ngImport: i0, template: "<p>Unknown Bone Editor | bone type: {{bone().type}}</p>\n<pre>{{bone() | json}}</pre>\n", styles: [":host{display:block;background-color:#dc143c}\n"], dependencies: [{ kind: "pipe", type: JsonPipe, name: "json" }] });
|
|
239
|
+
}
|
|
240
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: UnknownBoneEditorComponent, decorators: [{
|
|
241
|
+
type: Component,
|
|
242
|
+
args: [{ selector: "bonc-unknown-bone-editor", imports: [JsonPipe], template: "<p>Unknown Bone Editor | bone type: {{bone().type}}</p>\n<pre>{{bone() | json}}</pre>\n", styles: [":host{display:block;background-color:#dc143c}\n"] }]
|
|
243
|
+
}] });
|
|
130
244
|
|
|
131
245
|
class EditableDirective {
|
|
132
|
-
saved =
|
|
133
|
-
editModeChange =
|
|
134
|
-
externalSaveCall =
|
|
135
|
-
canceled =
|
|
136
|
-
valueChange =
|
|
246
|
+
saved = output();
|
|
247
|
+
editModeChange = output();
|
|
248
|
+
externalSaveCall = output();
|
|
249
|
+
canceled = output();
|
|
250
|
+
valueChange = output();
|
|
251
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
137
252
|
propagateChange = () => { };
|
|
138
|
-
_inEditMode = false;
|
|
139
|
-
|
|
253
|
+
_inEditMode = signal(false, ...(ngDevMode ? [{ debugName: "_inEditMode" }] : []));
|
|
254
|
+
inEditMode = this._inEditMode.asReadonly();
|
|
255
|
+
_isDirty = signal(false, ...(ngDevMode ? [{ debugName: "_isDirty" }] : []));
|
|
256
|
+
isDirty = this._isDirty.asReadonly();
|
|
140
257
|
_value;
|
|
141
258
|
_originalValue;
|
|
142
259
|
_storedData;
|
|
143
|
-
get inEditMode() {
|
|
144
|
-
return this._inEditMode;
|
|
145
|
-
}
|
|
146
|
-
subscribe(params) {
|
|
147
|
-
const subscriptions = [];
|
|
148
|
-
if (params.onValueChange !== undefined && params.onValueChange !== null) {
|
|
149
|
-
subscriptions.push(this.valueChange.subscribe((x) => {
|
|
150
|
-
if (params.onValueChange)
|
|
151
|
-
params.onValueChange(x);
|
|
152
|
-
}));
|
|
153
|
-
}
|
|
154
|
-
if (params.onEditModeChange !== undefined) {
|
|
155
|
-
subscriptions.push(this.editModeChange.subscribe((x) => {
|
|
156
|
-
if (params.onEditModeChange)
|
|
157
|
-
params.onEditModeChange(x);
|
|
158
|
-
}));
|
|
159
|
-
}
|
|
160
|
-
if (params.onSaveRequest !== undefined) {
|
|
161
|
-
subscriptions.push(this.externalSaveCall.subscribe(() => {
|
|
162
|
-
if (params.onSaveRequest)
|
|
163
|
-
params.onSaveRequest();
|
|
164
|
-
}));
|
|
165
|
-
}
|
|
166
|
-
return subscriptions;
|
|
167
|
-
}
|
|
168
260
|
requestSave() {
|
|
169
261
|
this.externalSaveCall.emit();
|
|
170
262
|
}
|
|
171
263
|
startEditing = () => {
|
|
172
|
-
if (this.
|
|
264
|
+
if (this.inEditMode()) {
|
|
173
265
|
this.updateDirty();
|
|
174
266
|
return;
|
|
175
267
|
}
|
|
176
|
-
this._inEditMode
|
|
268
|
+
this._inEditMode.set(true);
|
|
177
269
|
this.updateDirty();
|
|
178
270
|
this.editModeChange.emit(true);
|
|
179
271
|
};
|
|
180
272
|
save(newData) {
|
|
181
|
-
if (!this.
|
|
182
|
-
console.warn(
|
|
273
|
+
if (!this.inEditMode()) {
|
|
274
|
+
console.warn("save before edit mode"); //todo: fix that
|
|
183
275
|
}
|
|
184
276
|
this.finishEditing();
|
|
185
277
|
const newUnqieNotEmptyData = this.value === newData || newData === undefined
|
|
@@ -194,20 +286,19 @@ class EditableDirective {
|
|
|
194
286
|
if (this._originalValue === undefined || this._originalValue === null)
|
|
195
287
|
return;
|
|
196
288
|
if (typeof this._originalValue !== "object") {
|
|
197
|
-
console.warn(
|
|
289
|
+
console.warn("patch save called on not object type");
|
|
198
290
|
return;
|
|
199
291
|
}
|
|
200
292
|
this._originalValue[propName] = newDataParts;
|
|
201
293
|
this.setOriginal(this._originalValue);
|
|
202
294
|
this.updateDirty();
|
|
203
|
-
if (!this.isDirty)
|
|
295
|
+
if (!this.isDirty())
|
|
204
296
|
this.close();
|
|
205
297
|
}
|
|
206
298
|
// change model without opening or closing the editor
|
|
207
299
|
silentPatch(dict) {
|
|
208
300
|
for (const key in dict) {
|
|
209
|
-
|
|
210
|
-
if (!dict.hasOwnProperty(key))
|
|
301
|
+
if (!Object.hasOwn(dict, key))
|
|
211
302
|
continue;
|
|
212
303
|
const propVal = dict[key];
|
|
213
304
|
if (this._value !== undefined && this._value !== null) {
|
|
@@ -220,7 +311,7 @@ class EditableDirective {
|
|
|
220
311
|
this._storedData = JSON.stringify(this._originalValue);
|
|
221
312
|
}
|
|
222
313
|
cancel() {
|
|
223
|
-
if (!this.
|
|
314
|
+
if (!this.inEditMode())
|
|
224
315
|
return;
|
|
225
316
|
this.finishEditing();
|
|
226
317
|
// reset value
|
|
@@ -231,15 +322,16 @@ class EditableDirective {
|
|
|
231
322
|
this.finishEditing();
|
|
232
323
|
}
|
|
233
324
|
finishEditing() {
|
|
234
|
-
if (!this.
|
|
325
|
+
if (!this.inEditMode())
|
|
235
326
|
return;
|
|
236
|
-
this._inEditMode
|
|
327
|
+
this._inEditMode.set(false);
|
|
237
328
|
this.editModeChange.emit(false);
|
|
238
329
|
}
|
|
239
330
|
setValue(newValue) {
|
|
240
|
-
this._value =
|
|
241
|
-
|
|
242
|
-
|
|
331
|
+
this._value =
|
|
332
|
+
newValue === null || newValue === undefined
|
|
333
|
+
? undefined
|
|
334
|
+
: JSON.parse(JSON.stringify(newValue));
|
|
243
335
|
this.valueChange.emit(this._value);
|
|
244
336
|
}
|
|
245
337
|
set value(newValue) {
|
|
@@ -249,13 +341,10 @@ class EditableDirective {
|
|
|
249
341
|
return this._value;
|
|
250
342
|
}
|
|
251
343
|
updateDirty() {
|
|
252
|
-
this._isDirty
|
|
344
|
+
this._isDirty.set(JSON.stringify(this._value) !== this._storedData);
|
|
253
345
|
}
|
|
254
346
|
markAsDirty() {
|
|
255
|
-
this._isDirty
|
|
256
|
-
}
|
|
257
|
-
get isDirty() {
|
|
258
|
-
return this._isDirty;
|
|
347
|
+
this._isDirty.set(true);
|
|
259
348
|
}
|
|
260
349
|
setOriginal(newOriginalValue) {
|
|
261
350
|
this._originalValue = newOriginalValue;
|
|
@@ -265,10 +354,11 @@ class EditableDirective {
|
|
|
265
354
|
writeValue(newValue) {
|
|
266
355
|
this.finishEditing();
|
|
267
356
|
this.setOriginal(newValue);
|
|
268
|
-
this._isDirty
|
|
357
|
+
this._isDirty.set(false);
|
|
269
358
|
this.setValue(newValue);
|
|
270
359
|
}
|
|
271
360
|
setDisabledState() {
|
|
361
|
+
// required by ControlValueAccessor
|
|
272
362
|
}
|
|
273
363
|
registerOnChange(tellAngularThatSomethingIsChanged) {
|
|
274
364
|
this.propagateChange = (newValue) => {
|
|
@@ -276,139 +366,106 @@ class EditableDirective {
|
|
|
276
366
|
};
|
|
277
367
|
}
|
|
278
368
|
registerOnTouched() {
|
|
369
|
+
// required by ControlValueAccessor
|
|
279
370
|
}
|
|
280
371
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: EditableDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
281
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.6", type: EditableDirective, isStandalone: true, selector: "[boncEditable]", outputs: { saved: "saved", editModeChange: "editModeChange", externalSaveCall: "externalSaveCall", canceled: "canceled", valueChange: "valueChange" }, providers: [
|
|
372
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.6", type: EditableDirective, isStandalone: true, selector: "[boncEditable]", outputs: { saved: "saved", editModeChange: "editModeChange", externalSaveCall: "externalSaveCall", canceled: "canceled", valueChange: "valueChange" }, providers: [
|
|
373
|
+
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => EditableDirective), multi: true },
|
|
374
|
+
], ngImport: i0 });
|
|
282
375
|
}
|
|
283
376
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: EditableDirective, decorators: [{
|
|
284
377
|
type: Directive,
|
|
285
378
|
args: [{
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
379
|
+
selector: "[boncEditable]",
|
|
380
|
+
providers: [
|
|
381
|
+
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => EditableDirective), multi: true },
|
|
382
|
+
],
|
|
289
383
|
}]
|
|
290
|
-
}], propDecorators: { saved: [{
|
|
291
|
-
type: Output
|
|
292
|
-
}], editModeChange: [{
|
|
293
|
-
type: Output
|
|
294
|
-
}], externalSaveCall: [{
|
|
295
|
-
type: Output
|
|
296
|
-
}], canceled: [{
|
|
297
|
-
type: Output
|
|
298
|
-
}], valueChange: [{
|
|
299
|
-
type: Output
|
|
300
|
-
}] } });
|
|
384
|
+
}], propDecorators: { saved: [{ type: i0.Output, args: ["saved"] }], editModeChange: [{ type: i0.Output, args: ["editModeChange"] }], externalSaveCall: [{ type: i0.Output, args: ["externalSaveCall"] }], canceled: [{ type: i0.Output, args: ["canceled"] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
|
|
301
385
|
|
|
302
386
|
class EditableGroupComponent {
|
|
303
|
-
editModeChange =
|
|
304
|
-
saved =
|
|
305
|
-
requestEditorClose =
|
|
306
|
-
editables;
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
this.
|
|
387
|
+
editModeChange = output();
|
|
388
|
+
saved = output();
|
|
389
|
+
requestEditorClose = output();
|
|
390
|
+
editables = contentChildren(EditableDirective, { ...(ngDevMode ? { debugName: "editables" } : {}), descendants: true });
|
|
391
|
+
_subscriptions = [];
|
|
392
|
+
inEditMode = signal(false, ...(ngDevMode ? [{ debugName: "inEditMode" }] : []));
|
|
393
|
+
_saveSubject = new Subject(); // todo: use signal
|
|
394
|
+
constructor() {
|
|
395
|
+
const saveSubscription = this._saveSubject
|
|
312
396
|
.asObservable()
|
|
313
|
-
.pipe(debounceTime(100))
|
|
314
|
-
.subscribe(() => this.saved.emit());
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
this.clearSubscribtions();
|
|
397
|
+
.pipe(debounceTime(100), takeUntilDestroyed())
|
|
398
|
+
.subscribe(() => this.saved.emit(undefined));
|
|
399
|
+
effect(() => {
|
|
400
|
+
this.clearSubscriptions();
|
|
318
401
|
this.updateSubscriptions();
|
|
319
402
|
});
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
403
|
+
inject(DestroyRef).onDestroy(() => {
|
|
404
|
+
saveSubscription.unsubscribe();
|
|
405
|
+
this.clearSubscriptions();
|
|
406
|
+
});
|
|
323
407
|
}
|
|
324
408
|
saveAll() {
|
|
325
|
-
this.editables.forEach(x => x.requestSave());
|
|
409
|
+
this.editables().forEach((x) => x.requestSave());
|
|
326
410
|
}
|
|
327
411
|
cancelAll() {
|
|
328
|
-
this.editables.forEach(x => x.cancel());
|
|
412
|
+
this.editables().forEach((x) => x.cancel());
|
|
329
413
|
}
|
|
330
414
|
closeAll() {
|
|
331
415
|
this.requestEditorClose.emit(true);
|
|
332
|
-
this.editables.forEach(x => x.close());
|
|
416
|
+
this.editables().forEach((x) => x.close());
|
|
333
417
|
}
|
|
334
|
-
|
|
335
|
-
this.
|
|
336
|
-
this.
|
|
418
|
+
clearSubscriptions() {
|
|
419
|
+
this._subscriptions.forEach((x) => x.unsubscribe());
|
|
420
|
+
this._subscriptions.splice(0, this._subscriptions.length);
|
|
337
421
|
}
|
|
338
422
|
updateSubscriptions() {
|
|
339
|
-
this.editables.forEach(editable => {
|
|
340
|
-
this.
|
|
341
|
-
this.subscriptions.push(...editable.subscribe({
|
|
342
|
-
onEditModeChange: this.updateEditMode.bind(this)
|
|
343
|
-
}));
|
|
423
|
+
this.editables().forEach((editable) => {
|
|
424
|
+
this._subscriptions.push(editable.saved.subscribe(this.onSave.bind(this)), editable.editModeChange.subscribe(this.updateEditMode.bind(this)));
|
|
344
425
|
});
|
|
345
426
|
}
|
|
346
427
|
onSave() {
|
|
347
|
-
this.
|
|
428
|
+
this._saveSubject.next();
|
|
348
429
|
}
|
|
349
430
|
updateEditMode() {
|
|
350
|
-
const newEditMode = this.editables
|
|
351
|
-
|
|
352
|
-
.length > 0;
|
|
353
|
-
if (newEditMode === this._inEditMode)
|
|
431
|
+
const newEditMode = this.editables().filter((x) => x.inEditMode()).length > 0;
|
|
432
|
+
if (newEditMode === this.inEditMode())
|
|
354
433
|
return;
|
|
355
|
-
this.
|
|
356
|
-
this.editModeChange.
|
|
357
|
-
}
|
|
358
|
-
ngOnDestroy() {
|
|
359
|
-
this.clearSubscribtions();
|
|
434
|
+
this.inEditMode.set(newEditMode);
|
|
435
|
+
this.editModeChange.emit(newEditMode);
|
|
360
436
|
}
|
|
361
437
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: EditableGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
362
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
438
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.0.6", type: EditableGroupComponent, isStandalone: true, selector: "bonc-editable-group", outputs: { editModeChange: "editModeChange", saved: "saved", requestEditorClose: "requestEditorClose" }, queries: [{ propertyName: "editables", predicate: EditableDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-content></ng-content>", isInline: true });
|
|
363
439
|
}
|
|
364
440
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: EditableGroupComponent, decorators: [{
|
|
365
441
|
type: Component,
|
|
366
442
|
args: [{
|
|
367
|
-
selector:
|
|
368
|
-
|
|
369
|
-
template: '<ng-content></ng-content>'
|
|
443
|
+
selector: "bonc-editable-group",
|
|
444
|
+
template: "<ng-content></ng-content>",
|
|
370
445
|
}]
|
|
371
|
-
}], propDecorators: { editModeChange: [{
|
|
372
|
-
type: Output
|
|
373
|
-
}], saved: [{
|
|
374
|
-
type: Output
|
|
375
|
-
}], requestEditorClose: [{
|
|
376
|
-
type: Output
|
|
377
|
-
}], editables: [{
|
|
378
|
-
type: ContentChildren,
|
|
379
|
-
args: [EditableDirective, { descendants: true }]
|
|
380
|
-
}] } });
|
|
446
|
+
}], ctorParameters: () => [], propDecorators: { editModeChange: [{ type: i0.Output, args: ["editModeChange"] }], saved: [{ type: i0.Output, args: ["saved"] }], requestEditorClose: [{ type: i0.Output, args: ["requestEditorClose"] }], editables: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => EditableDirective), { ...{ descendants: true }, isSignal: true }] }] } });
|
|
381
447
|
|
|
382
448
|
class FormBaseComponent {
|
|
383
|
-
|
|
384
|
-
name = '';
|
|
385
|
-
_locale = '';
|
|
449
|
+
name = "";
|
|
386
450
|
editable = inject((EditableDirective), { host: true });
|
|
387
|
-
|
|
388
|
-
this._locale = value;
|
|
389
|
-
}
|
|
390
|
-
get locale() {
|
|
391
|
-
return this._locale;
|
|
392
|
-
}
|
|
451
|
+
locale = input("", ...(ngDevMode ? [{ debugName: "locale" }] : []));
|
|
393
452
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FormBaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
394
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
453
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.6", type: FormBaseComponent, isStandalone: true, selector: "ng-component", inputs: { locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "", isInline: true });
|
|
395
454
|
}
|
|
396
455
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FormBaseComponent, decorators: [{
|
|
397
456
|
type: Component,
|
|
398
457
|
args: [{
|
|
399
|
-
template:
|
|
458
|
+
template: "",
|
|
400
459
|
}]
|
|
401
|
-
}], propDecorators: { locale: [{
|
|
402
|
-
type: Input
|
|
403
|
-
}] } });
|
|
460
|
+
}], propDecorators: { locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }] } });
|
|
404
461
|
|
|
405
462
|
class TranslationInputComponent {
|
|
406
|
-
text;
|
|
407
|
-
locale;
|
|
408
|
-
device = DeviceType.NotSet;
|
|
409
|
-
startEditing =
|
|
410
|
-
changed =
|
|
411
|
-
blurred =
|
|
463
|
+
text = input.required(...(ngDevMode ? [{ debugName: "text" }] : []));
|
|
464
|
+
locale = input.required(...(ngDevMode ? [{ debugName: "locale" }] : []));
|
|
465
|
+
device = input(DeviceType.NotSet, ...(ngDevMode ? [{ debugName: "device" }] : []));
|
|
466
|
+
startEditing = output();
|
|
467
|
+
changed = output();
|
|
468
|
+
blurred = output();
|
|
412
469
|
onClick() {
|
|
413
470
|
this.startEditing.emit();
|
|
414
471
|
}
|
|
@@ -419,42 +476,35 @@ class TranslationInputComponent {
|
|
|
419
476
|
this.blurred.emit();
|
|
420
477
|
}
|
|
421
478
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TranslationInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
422
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
479
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.6", type: TranslationInputComponent, isStandalone: true, selector: "bonc-translation-input", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: true, transformFunction: null }, device: { classPropertyName: "device", publicName: "device", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { startEditing: "startEditing", changed: "changed", blurred: "blurred" }, ngImport: i0, template: "<input [(ngModel)]=\"text()[locale()]\"\n (click)=\"onClick()\"\n (keyup)=\"onKeyPress()\"\n (blur)=\"onBlur()\" />\n", styles: [":host{padding:6px 12px;border:1px solid silver}:host:hover{background-color:#333}:host:focus-within{background-color:#555}:host{display:block}:host input{display:block;border:none;background-color:#8080801a;color:var(--text-color)}:host input:hover{background-color:#d3d3d3;cursor:pointer}:host input:focus{outline:none;color:#000;background-color:#cf0}:host input{display:block;width:100%;padding:6px;color:silver;border:1px solid silver;background-color:transparent;box-sizing:border-box}:host input:hover{border-color:transparent;background-color:#333;cursor:pointer}:host input:focus{outline:none;color:#fff;border-color:transparent;background-color:#555}:host input{display:block;box-sizing:border-box;font-family:inherit;width:100%;border:none}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { 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"] }] });
|
|
423
480
|
}
|
|
424
481
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TranslationInputComponent, decorators: [{
|
|
425
482
|
type: Component,
|
|
426
|
-
args: [{ selector:
|
|
427
|
-
}], propDecorators: { text: [{
|
|
428
|
-
type: Input,
|
|
429
|
-
args: [{ required: true }]
|
|
430
|
-
}], locale: [{
|
|
431
|
-
type: Input,
|
|
432
|
-
args: [{ required: true }]
|
|
433
|
-
}], device: [{
|
|
434
|
-
type: Input
|
|
435
|
-
}], startEditing: [{
|
|
436
|
-
type: Output
|
|
437
|
-
}], changed: [{
|
|
438
|
-
type: Output
|
|
439
|
-
}], blurred: [{
|
|
440
|
-
type: Output
|
|
441
|
-
}] } });
|
|
483
|
+
args: [{ selector: "bonc-translation-input", imports: [FormsModule], template: "<input [(ngModel)]=\"text()[locale()]\"\n (click)=\"onClick()\"\n (keyup)=\"onKeyPress()\"\n (blur)=\"onBlur()\" />\n", styles: [":host{padding:6px 12px;border:1px solid silver}:host:hover{background-color:#333}:host:focus-within{background-color:#555}:host{display:block}:host input{display:block;border:none;background-color:#8080801a;color:var(--text-color)}:host input:hover{background-color:#d3d3d3;cursor:pointer}:host input:focus{outline:none;color:#000;background-color:#cf0}:host input{display:block;width:100%;padding:6px;color:silver;border:1px solid silver;background-color:transparent;box-sizing:border-box}:host input:hover{border-color:transparent;background-color:#333;cursor:pointer}:host input:focus{outline:none;color:#fff;border-color:transparent;background-color:#555}:host input{display:block;box-sizing:border-box;font-family:inherit;width:100%;border:none}\n"] }]
|
|
484
|
+
}], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: true }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: true }] }], device: [{ type: i0.Input, args: [{ isSignal: true, alias: "device", required: false }] }], startEditing: [{ type: i0.Output, args: ["startEditing"] }], changed: [{ type: i0.Output, args: ["changed"] }], blurred: [{ type: i0.Output, args: ["blurred"] }] } });
|
|
442
485
|
|
|
443
486
|
class TranslationTextareaComponent {
|
|
444
|
-
autosizeList;
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
device = DeviceType.NotSet;
|
|
450
|
-
startEditing =
|
|
451
|
-
changed =
|
|
452
|
-
blurred =
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
487
|
+
autosizeList = viewChildren(CdkTextareaAutosize, ...(ngDevMode ? [{ debugName: "autosizeList" }] : []));
|
|
488
|
+
text = input.required(...(ngDevMode ? [{ debugName: "text" }] : []));
|
|
489
|
+
locale = input.required(...(ngDevMode ? [{ debugName: "locale" }] : []));
|
|
490
|
+
minRows = input(...(ngDevMode ? [undefined, { debugName: "minRows" }] : []));
|
|
491
|
+
maxRows = input(...(ngDevMode ? [undefined, { debugName: "maxRows" }] : []));
|
|
492
|
+
device = input(DeviceType.NotSet, ...(ngDevMode ? [{ debugName: "device" }] : []));
|
|
493
|
+
startEditing = output();
|
|
494
|
+
changed = output();
|
|
495
|
+
blurred = output();
|
|
496
|
+
constructor() {
|
|
497
|
+
// todo: check if it still necessary
|
|
498
|
+
effect((onCleanup) => {
|
|
499
|
+
this.text();
|
|
500
|
+
this.locale();
|
|
501
|
+
this.minRows();
|
|
502
|
+
this.maxRows();
|
|
503
|
+
const timer = setTimeout(() => this.triggerResize(), 500);
|
|
504
|
+
onCleanup(() => {
|
|
505
|
+
clearTimeout(timer);
|
|
506
|
+
});
|
|
507
|
+
});
|
|
458
508
|
}
|
|
459
509
|
onClick() {
|
|
460
510
|
this.startEditing.emit();
|
|
@@ -466,63 +516,36 @@ class TranslationTextareaComponent {
|
|
|
466
516
|
this.blurred.emit();
|
|
467
517
|
}
|
|
468
518
|
triggerResize() {
|
|
469
|
-
|
|
470
|
-
// todo: investigate is it working or not
|
|
471
|
-
// this.ngZone.onStable.pipe(take(1))
|
|
472
|
-
// .subscribe(() => {
|
|
473
|
-
// this.autosizeList.forEach(x => x.resizeToFitContent(true));
|
|
474
|
-
// });
|
|
519
|
+
this.autosizeList().forEach((x) => x.resizeToFitContent(true));
|
|
475
520
|
}
|
|
476
521
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TranslationTextareaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
477
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
522
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.0.6", type: TranslationTextareaComponent, isStandalone: true, selector: "bonc-translation-textarea", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: true, transformFunction: null }, minRows: { classPropertyName: "minRows", publicName: "minRows", isSignal: true, isRequired: false, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null }, device: { classPropertyName: "device", publicName: "device", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { startEditing: "startEditing", changed: "changed", blurred: "blurred" }, viewQueries: [{ propertyName: "autosizeList", predicate: CdkTextareaAutosize, descendants: true, isSignal: true }], ngImport: i0, template: "<textarea [(ngModel)]=\"text()[locale()]\"\n [cdkAutosizeMinRows]=\"minRows()\"\n [cdkAutosizeMaxRows]=\"maxRows()\"\n (click)=\"onClick()\"\n (keyup)=\"onKeyPress()\"\n (blur)=\"onBlur()\"\n matInput\n cdkTextareaAutosize>\n</textarea>\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}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,#cf00,#cf00 10px,#000 10px 20px) fixed bottom;color:#000}textarea{color:silver;background-color:transparent}textarea:hover{cursor:pointer}textarea:focus{outline:none;color:#fff;cursor:default}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { 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: CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }] });
|
|
478
523
|
}
|
|
479
524
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TranslationTextareaComponent, decorators: [{
|
|
480
525
|
type: Component,
|
|
481
|
-
args: [{ selector:
|
|
482
|
-
}], propDecorators: { autosizeList: [{
|
|
483
|
-
type: ViewChildren,
|
|
484
|
-
args: [CdkTextareaAutosize]
|
|
485
|
-
}], minRows: [{
|
|
486
|
-
type: Input
|
|
487
|
-
}], maxRows: [{
|
|
488
|
-
type: Input
|
|
489
|
-
}], text: [{
|
|
490
|
-
type: Input,
|
|
491
|
-
args: [{ required: true }]
|
|
492
|
-
}], locale: [{
|
|
493
|
-
type: Input,
|
|
494
|
-
args: [{ required: true }]
|
|
495
|
-
}], device: [{
|
|
496
|
-
type: Input
|
|
497
|
-
}], startEditing: [{
|
|
498
|
-
type: Output
|
|
499
|
-
}], changed: [{
|
|
500
|
-
type: Output
|
|
501
|
-
}], blurred: [{
|
|
502
|
-
type: Output
|
|
503
|
-
}] } });
|
|
526
|
+
args: [{ selector: "bonc-translation-textarea", imports: [FormsModule, CdkTextareaAutosize], template: "<textarea [(ngModel)]=\"text()[locale()]\"\n [cdkAutosizeMinRows]=\"minRows()\"\n [cdkAutosizeMaxRows]=\"maxRows()\"\n (click)=\"onClick()\"\n (keyup)=\"onKeyPress()\"\n (blur)=\"onBlur()\"\n matInput\n cdkTextareaAutosize>\n</textarea>\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}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,#cf00,#cf00 10px,#000 10px 20px) fixed bottom;color:#000}textarea{color:silver;background-color:transparent}textarea:hover{cursor:pointer}textarea:focus{outline:none;color:#fff;cursor:default}\n"] }]
|
|
527
|
+
}], ctorParameters: () => [], propDecorators: { autosizeList: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => CdkTextareaAutosize), { isSignal: true }] }], text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: true }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: true }] }], minRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "minRows", required: false }] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }], device: [{ type: i0.Input, args: [{ isSignal: true, alias: "device", required: false }] }], startEditing: [{ type: i0.Output, args: ["startEditing"] }], changed: [{ type: i0.Output, args: ["changed"] }], blurred: [{ type: i0.Output, args: ["blurred"] }] } });
|
|
504
528
|
|
|
505
529
|
class LinkPopupComponent {
|
|
506
530
|
TextEditorField = TextEditorField;
|
|
507
|
-
linkChange = new EventEmitter();
|
|
508
|
-
startEditing = new EventEmitter();
|
|
509
|
-
changed = new EventEmitter();
|
|
510
|
-
blurred = new EventEmitter();
|
|
511
|
-
open = new EventEmitter();
|
|
512
|
-
closed = new EventEmitter();
|
|
513
|
-
field;
|
|
514
531
|
LinkPopupField = TextEditorField;
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
532
|
+
linkChange = output();
|
|
533
|
+
startEditing = output();
|
|
534
|
+
changed = output();
|
|
535
|
+
blurred = output();
|
|
536
|
+
open = output();
|
|
537
|
+
closed = output();
|
|
538
|
+
field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
|
|
539
|
+
maxRows = input(...(ngDevMode ? [undefined, { debugName: "maxRows" }] : []));
|
|
540
|
+
minRows = input(...(ngDevMode ? [undefined, { debugName: "minRows" }] : []));
|
|
541
|
+
linkTitle = input.required(...(ngDevMode ? [{ debugName: "linkTitle" }] : []));
|
|
542
|
+
locale = input.required(...(ngDevMode ? [{ debugName: "locale" }] : []));
|
|
543
|
+
link = input.required(...(ngDevMode ? [{ debugName: "link" }] : []));
|
|
520
544
|
popupIsShown = false;
|
|
521
545
|
onClick() {
|
|
522
546
|
this.startEditing.emit();
|
|
523
547
|
}
|
|
524
548
|
onChange() {
|
|
525
|
-
console.log('change link pop up');
|
|
526
549
|
this.changed.emit();
|
|
527
550
|
}
|
|
528
551
|
onBlur() {
|
|
@@ -537,121 +560,66 @@ class LinkPopupComponent {
|
|
|
537
560
|
this.closed.emit();
|
|
538
561
|
}
|
|
539
562
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: LinkPopupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
540
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
563
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: LinkPopupComponent, isStandalone: true, selector: "bonc-link-popup", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null }, minRows: { classPropertyName: "minRows", publicName: "minRows", isSignal: true, isRequired: false, transformFunction: null }, linkTitle: { classPropertyName: "linkTitle", publicName: "linkTitle", isSignal: true, isRequired: true, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: true, transformFunction: null }, link: { classPropertyName: "link", publicName: "link", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { linkChange: "linkChange", startEditing: "startEditing", changed: "changed", blurred: "blurred", open: "open", closed: "closed" }, ngImport: i0, template: "@switch (field()) {\n @case (TextEditorField.Input) {\n <bonc-translation-input (click)=\"showPopup()\"\n [text]=\"linkTitle()\"\n [locale]=\"locale()\"\n (startEditing)=\"onClick()\"\n (changed)=\"onChange()\"\n (blurred)=\"onBlur()\">\n </bonc-translation-input>\n }\n @case (TextEditorField.Textarea) {\n <bonc-translation-textarea (click)=\"showPopup()\"\n [text]=\"linkTitle()\"\n [locale]=\"locale()\"\n [minRows]=\"minRows()\"\n [maxRows]=\"maxRows()\"\n (startEditing)=\"onClick()\"\n (changed)=\"onChange()\"\n (blurred)=\"onBlur()\">\n </bonc-translation-textarea>\n }\n}\n\n@if (popupIsShown) {\n <div>\n <div class=\"popup\">\n <a (click)=\"hidePopup()\" class=\"close\">close</a>\n\n <label>Link\n <input [(ngModel)]=\"link()[locale()]\"\n (click)=\"onClick()\"\n (keyup)=\"onChange()\"\n (blur)=\"onBlur()\">\n </label>\n\n </div>\n </div>\n}\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;cursor:pointer;padding:3pt 10pt;text-align:center;-webkit-user-select:none;user-select:none}button:hover{border-color:#333;background-color:#333}button:disabled{color:gray}button{color:#000;cursor:pointer}button:hover{background-color:#cf0}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { 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: ["text", "locale", "minRows", "maxRows", "device"], outputs: ["startEditing", "changed", "blurred"] }] });
|
|
541
564
|
}
|
|
542
565
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: LinkPopupComponent, decorators: [{
|
|
543
566
|
type: Component,
|
|
544
|
-
args: [{ selector:
|
|
545
|
-
}], propDecorators: { linkChange: [{
|
|
546
|
-
type: Output
|
|
547
|
-
}], startEditing: [{
|
|
548
|
-
type: Output
|
|
549
|
-
}], changed: [{
|
|
550
|
-
type: Output
|
|
551
|
-
}], blurred: [{
|
|
552
|
-
type: Output
|
|
553
|
-
}], open: [{
|
|
554
|
-
type: Output
|
|
555
|
-
}], closed: [{
|
|
556
|
-
type: Output
|
|
557
|
-
}], field: [{
|
|
558
|
-
type: Input,
|
|
559
|
-
args: [{ required: true }]
|
|
560
|
-
}], maxRows: [{
|
|
561
|
-
type: Input
|
|
562
|
-
}], minRows: [{
|
|
563
|
-
type: Input
|
|
564
|
-
}], linkTitle: [{
|
|
565
|
-
type: Input,
|
|
566
|
-
args: [{ required: true }]
|
|
567
|
-
}], locale: [{
|
|
568
|
-
type: Input,
|
|
569
|
-
args: [{ required: true }]
|
|
570
|
-
}], link: [{
|
|
571
|
-
type: Input,
|
|
572
|
-
args: [{ required: true }]
|
|
573
|
-
}] } });
|
|
574
|
-
|
|
575
|
-
class FormControlsComponent {
|
|
576
|
-
editable;
|
|
577
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FormControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
578
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: FormControlsComponent, isStandalone: true, selector: "bonc-form-controls", inputs: { editable: "editable" }, ngImport: i0, template: "<div [class.edit]=\"editable.inEditMode\" class=\"content\">\n <ng-content></ng-content>\n</div>\n\n<div [class.hidden]=\"!editable.inEditMode\" class=\"controls\">\n <a *ngIf=\"!editable.isDirty\" (click)=\"editable.cancel()\" class=\"close\">close</a>\n <ng-container *ngIf=\"editable.isDirty\">\n <a (click)=\"editable.cancel()\">reset</a>\n <a (click)=\"editable.requestSave()\" class=\"apply\">apply</a>\n </ng-container>\n</div>\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: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
579
|
-
}
|
|
580
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FormControlsComponent, decorators: [{
|
|
581
|
-
type: Component,
|
|
582
|
-
args: [{ selector: 'bonc-form-controls', standalone: true, imports: [CommonModule], template: "<div [class.edit]=\"editable.inEditMode\" class=\"content\">\n <ng-content></ng-content>\n</div>\n\n<div [class.hidden]=\"!editable.inEditMode\" class=\"controls\">\n <a *ngIf=\"!editable.isDirty\" (click)=\"editable.cancel()\" class=\"close\">close</a>\n <ng-container *ngIf=\"editable.isDirty\">\n <a (click)=\"editable.cancel()\">reset</a>\n <a (click)=\"editable.requestSave()\" class=\"apply\">apply</a>\n </ng-container>\n</div>\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"] }]
|
|
583
|
-
}], propDecorators: { editable: [{
|
|
584
|
-
type: Input,
|
|
585
|
-
args: [{ required: true }]
|
|
586
|
-
}] } });
|
|
567
|
+
args: [{ selector: "bonc-link-popup", imports: [FormsModule, TranslationInputComponent, TranslationTextareaComponent], template: "@switch (field()) {\n @case (TextEditorField.Input) {\n <bonc-translation-input (click)=\"showPopup()\"\n [text]=\"linkTitle()\"\n [locale]=\"locale()\"\n (startEditing)=\"onClick()\"\n (changed)=\"onChange()\"\n (blurred)=\"onBlur()\">\n </bonc-translation-input>\n }\n @case (TextEditorField.Textarea) {\n <bonc-translation-textarea (click)=\"showPopup()\"\n [text]=\"linkTitle()\"\n [locale]=\"locale()\"\n [minRows]=\"minRows()\"\n [maxRows]=\"maxRows()\"\n (startEditing)=\"onClick()\"\n (changed)=\"onChange()\"\n (blurred)=\"onBlur()\">\n </bonc-translation-textarea>\n }\n}\n\n@if (popupIsShown) {\n <div>\n <div class=\"popup\">\n <a (click)=\"hidePopup()\" class=\"close\">close</a>\n\n <label>Link\n <input [(ngModel)]=\"link()[locale()]\"\n (click)=\"onClick()\"\n (keyup)=\"onChange()\"\n (blur)=\"onBlur()\">\n </label>\n\n </div>\n </div>\n}\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;cursor:pointer;padding:3pt 10pt;text-align:center;-webkit-user-select:none;user-select:none}button:hover{border-color:#333;background-color:#333}button:disabled{color:gray}button{color:#000;cursor:pointer}button:hover{background-color:#cf0}\n"] }]
|
|
568
|
+
}], propDecorators: { linkChange: [{ type: i0.Output, args: ["linkChange"] }], startEditing: [{ type: i0.Output, args: ["startEditing"] }], changed: [{ type: i0.Output, args: ["changed"] }], blurred: [{ type: i0.Output, args: ["blurred"] }], open: [{ type: i0.Output, args: ["open"] }], closed: [{ type: i0.Output, args: ["closed"] }], field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }], minRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "minRows", required: false }] }], linkTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "linkTitle", required: true }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: true }] }], link: [{ type: i0.Input, args: [{ isSignal: true, alias: "link", required: true }] }] } });
|
|
587
569
|
|
|
588
570
|
class FileUploaderComponent {
|
|
589
|
-
fileInput;
|
|
590
|
-
srcChange =
|
|
591
|
-
uploadUrlMap;
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
571
|
+
fileInput = viewChild.required("fileInput");
|
|
572
|
+
srcChange = output();
|
|
573
|
+
uploadUrlMap = input.required(...(ngDevMode ? [{ debugName: "uploadUrlMap" }] : []));
|
|
574
|
+
src = input(...(ngDevMode ? [undefined, { debugName: "src" }] : []));
|
|
575
|
+
uploadTypes = input([], ...(ngDevMode ? [{ debugName: "uploadTypes" }] : []));
|
|
576
|
+
fileTypeMask = computed(() => {
|
|
577
|
+
const types = this.uploadTypes();
|
|
578
|
+
return types.length === 0 ? undefined : types.join(",");
|
|
579
|
+
}, ...(ngDevMode ? [{ debugName: "fileTypeMask" }] : []));
|
|
580
|
+
progress = signal(0, ...(ngDevMode ? [{ debugName: "progress" }] : []));
|
|
581
|
+
isUploading = signal(false, ...(ngDevMode ? [{ debugName: "isUploading" }] : []));
|
|
582
|
+
clipStyle = signal(undefined, ...(ngDevMode ? [{ debugName: "clipStyle" }] : []));
|
|
599
583
|
sanitizer = inject(DomSanitizer);
|
|
600
584
|
http = inject(HttpClient);
|
|
601
|
-
cd = inject(ChangeDetectorRef);
|
|
602
|
-
set src(newSrc) {
|
|
603
|
-
if (this._src === newSrc)
|
|
604
|
-
return;
|
|
605
|
-
this._src = newSrc;
|
|
606
|
-
}
|
|
607
|
-
get src() {
|
|
608
|
-
return this._src;
|
|
609
|
-
}
|
|
610
|
-
set uploadTypes(newUploadType) {
|
|
611
|
-
this._uploadTypes.splice(0, this._uploadTypes.length);
|
|
612
|
-
this._uploadTypes.push(...newUploadType);
|
|
613
|
-
this.fileTypeMask = this._uploadTypes.length === 0 ? undefined : this._uploadTypes.join(',');
|
|
614
|
-
this.cd.detectChanges();
|
|
615
|
-
}
|
|
616
|
-
get uploadTypes() {
|
|
617
|
-
return this._uploadTypes;
|
|
618
|
-
}
|
|
619
585
|
onFileSelect(fileInput) {
|
|
620
586
|
if (fileInput.files === undefined || fileInput.files === null || fileInput.files.length !== 1)
|
|
621
587
|
return;
|
|
622
588
|
const file = fileInput.files[0];
|
|
623
|
-
const uploadUrl = this.uploadUrlMap.get(file.type) ?? this.uploadUrlMap.get("");
|
|
589
|
+
const uploadUrl = this.uploadUrlMap().get(file.type) ?? this.uploadUrlMap().get("");
|
|
624
590
|
if (uploadUrl === undefined || uploadUrl === null) {
|
|
625
591
|
console.error(`upload map doesn't have url for type '${file.type}'`);
|
|
626
592
|
return;
|
|
627
593
|
}
|
|
628
594
|
const formData = new FormData();
|
|
629
|
-
formData.append(
|
|
630
|
-
this.progress
|
|
631
|
-
this.isUploading
|
|
595
|
+
formData.append("file", file);
|
|
596
|
+
this.progress.set(0);
|
|
597
|
+
this.isUploading.set(true);
|
|
632
598
|
this.updateClip();
|
|
633
|
-
const request = new HttpRequest(
|
|
634
|
-
reportProgress: true
|
|
599
|
+
const request = new HttpRequest("POST", uploadUrl, formData, {
|
|
600
|
+
reportProgress: true,
|
|
635
601
|
});
|
|
636
602
|
this.http
|
|
637
603
|
.request(request)
|
|
638
|
-
.pipe(map(event => this.getEventMessage(event)),
|
|
604
|
+
.pipe(map((event) => this.getEventMessage(event)),
|
|
639
605
|
// tap(message => this.showProgress(message)),
|
|
640
606
|
last(), // return last (completed) message to caller
|
|
641
|
-
catchError(this.handleError(file)))
|
|
607
|
+
catchError(this.handleError(file)))
|
|
608
|
+
.subscribe(() => {
|
|
609
|
+
this.isUploading.set(false);
|
|
610
|
+
});
|
|
642
611
|
}
|
|
643
612
|
selectFile(event) {
|
|
644
|
-
|
|
645
|
-
if (event.target === this.fileInput.nativeElement)
|
|
613
|
+
if (event.target === this.fileInput().nativeElement)
|
|
646
614
|
return;
|
|
647
|
-
this.fileInput.nativeElement.click();
|
|
615
|
+
this.fileInput().nativeElement.click();
|
|
648
616
|
}
|
|
649
617
|
getEventMessage(event) {
|
|
650
618
|
switch (event.type) {
|
|
651
619
|
case HttpEventType.Sent:
|
|
652
620
|
break;
|
|
653
621
|
case HttpEventType.UploadProgress:
|
|
654
|
-
this.progress
|
|
622
|
+
this.progress.set(event.total === undefined ? 0.5 : event.loaded / event.total);
|
|
655
623
|
this.updateClip();
|
|
656
624
|
break;
|
|
657
625
|
case HttpEventType.Response:
|
|
@@ -664,10 +632,9 @@ class FileUploaderComponent {
|
|
|
664
632
|
default:
|
|
665
633
|
break;
|
|
666
634
|
}
|
|
667
|
-
this.cd.detectChanges();
|
|
668
635
|
}
|
|
669
636
|
updateClip() {
|
|
670
|
-
this.clipStyle
|
|
637
|
+
this.clipStyle.set(this.sanitizer.bypassSecurityTrustStyle(`inset(0px 100% 0px 0%)`));
|
|
671
638
|
}
|
|
672
639
|
handleError(file) {
|
|
673
640
|
const func = (error, p2) => {
|
|
@@ -679,85 +646,62 @@ class FileUploaderComponent {
|
|
|
679
646
|
return func;
|
|
680
647
|
}
|
|
681
648
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FileUploaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
682
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
649
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: FileUploaderComponent, isStandalone: true, selector: "bonc-file-uploader", inputs: { uploadUrlMap: { classPropertyName: "uploadUrlMap", publicName: "uploadUrlMap", isSignal: true, isRequired: true, transformFunction: null }, src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, uploadTypes: { classPropertyName: "uploadTypes", publicName: "uploadTypes", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { srcChange: "srcChange" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (src() === undefined || src()?.url === undefined || src()?.url?.length === 0) {\n <div>Upload file</div>\n}\n\n<ng-content></ng-content>\n\n<div (click)=\"selectFile($event)\" (keydown.enter)=\"selectFile($event)\" role=\"button\" tabindex=\"0\" class=\"media-container\">\n <input #fileInput [accept]=\"fileTypeMask()\" (change)=\"onFileSelect(fileInput)\" name=\"media\" type=\"file\" />\n @if (isUploading()) {\n <span [style.clip-path]=\"clipStyle()\"\n [style.-webkit-clip-path]=\"clipStyle()\"\n class=\"loader\"></span>\n <span class=\"loader-text\">\n @if (progress() < 1) {\n <span>{{100 * progress() | number: '1.0-0'}}%</span>\n } @else {\n <span>converting</span>\n }\n </span>\n }\n</div>\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: "pipe", type: DecimalPipe, name: "number" }] });
|
|
683
650
|
}
|
|
684
651
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FileUploaderComponent, decorators: [{
|
|
685
652
|
type: Component,
|
|
686
|
-
args: [{ selector:
|
|
687
|
-
}], propDecorators: { fileInput: [{
|
|
688
|
-
type: ViewChild,
|
|
689
|
-
args: ['fileInput', { static: true }]
|
|
690
|
-
}], srcChange: [{
|
|
691
|
-
type: Output
|
|
692
|
-
}], uploadUrlMap: [{
|
|
693
|
-
type: Input,
|
|
694
|
-
args: [{ required: true }]
|
|
695
|
-
}], src: [{
|
|
696
|
-
type: Input
|
|
697
|
-
}], uploadTypes: [{
|
|
698
|
-
type: Input
|
|
699
|
-
}] } });
|
|
653
|
+
args: [{ selector: "bonc-file-uploader", imports: [DecimalPipe], template: "@if (src() === undefined || src()?.url === undefined || src()?.url?.length === 0) {\n <div>Upload file</div>\n}\n\n<ng-content></ng-content>\n\n<div (click)=\"selectFile($event)\" (keydown.enter)=\"selectFile($event)\" role=\"button\" tabindex=\"0\" class=\"media-container\">\n <input #fileInput [accept]=\"fileTypeMask()\" (change)=\"onFileSelect(fileInput)\" name=\"media\" type=\"file\" />\n @if (isUploading()) {\n <span [style.clip-path]=\"clipStyle()\"\n [style.-webkit-clip-path]=\"clipStyle()\"\n class=\"loader\"></span>\n <span class=\"loader-text\">\n @if (progress() < 1) {\n <span>{{100 * progress() | number: '1.0-0'}}%</span>\n } @else {\n <span>converting</span>\n }\n </span>\n }\n</div>\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"] }]
|
|
654
|
+
}], propDecorators: { fileInput: [{ type: i0.ViewChild, args: ["fileInput", { isSignal: true }] }], srcChange: [{ type: i0.Output, args: ["srcChange"] }], uploadUrlMap: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadUrlMap", required: true }] }], src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], uploadTypes: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadTypes", required: false }] }] } });
|
|
700
655
|
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
656
|
+
class FormControlsComponent {
|
|
657
|
+
editable = input.required(...(ngDevMode ? [{ debugName: "editable" }] : []));
|
|
658
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FormControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
659
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: FormControlsComponent, isStandalone: true, selector: "bonc-form-controls", inputs: { editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div [class.edit]=\"editable().inEditMode()\" class=\"content\">\n <ng-content></ng-content>\n</div>\n\n<div [class.hidden]=\"!editable().inEditMode()\" class=\"controls\">\n @if (!editable().isDirty()) {\n <a (click)=\"editable().cancel()\" class=\"close\">close</a>\n } @else {\n <a (click)=\"editable().cancel()\">reset</a>\n <a (click)=\"editable().requestSave()\" class=\"apply\">apply</a>\n }\n</div>\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"] });
|
|
660
|
+
}
|
|
661
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FormControlsComponent, decorators: [{
|
|
662
|
+
type: Component,
|
|
663
|
+
args: [{ selector: "bonc-form-controls", template: "<div [class.edit]=\"editable().inEditMode()\" class=\"content\">\n <ng-content></ng-content>\n</div>\n\n<div [class.hidden]=\"!editable().inEditMode()\" class=\"controls\">\n @if (!editable().isDirty()) {\n <a (click)=\"editable().cancel()\" class=\"close\">close</a>\n } @else {\n <a (click)=\"editable().cancel()\">reset</a>\n <a (click)=\"editable().requestSave()\" class=\"apply\">apply</a>\n }\n</div>\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"] }]
|
|
664
|
+
}], propDecorators: { editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: true }] }] } });
|
|
665
|
+
|
|
666
|
+
class FileFormComponent extends FormBaseComponent {
|
|
667
|
+
label = input("", ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
668
|
+
uploadTypes = input.required(...(ngDevMode ? [{ debugName: "uploadTypes" }] : []));
|
|
669
|
+
uploadMap = input.required(...(ngDevMode ? [{ debugName: "uploadMap" }] : []));
|
|
670
|
+
constructor() {
|
|
671
|
+
super();
|
|
709
672
|
this.editable.externalSaveCall.subscribe(() => {
|
|
710
673
|
this.editable.save();
|
|
711
674
|
});
|
|
712
675
|
}
|
|
713
|
-
|
|
714
|
-
this._pageId = value;
|
|
715
|
-
this.ogImageUploadUrl = `/api/admin/page/Og-Image?pageId=${this.pageId}`; // todo: replace with link to single image api
|
|
716
|
-
}
|
|
717
|
-
get pageId() {
|
|
718
|
-
return this._pageId;
|
|
719
|
-
}
|
|
720
|
-
ResToSrc(res) {
|
|
721
|
-
return res.url;
|
|
722
|
-
}
|
|
723
|
-
replaceImage($event) {
|
|
676
|
+
onFileUploaded(fileSrc) {
|
|
724
677
|
this.editable.startEditing();
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
}
|
|
678
|
+
const svgSrc = fileSrc;
|
|
679
|
+
this.editable.value = svgSrc;
|
|
728
680
|
this.editable.updateDirty();
|
|
729
681
|
}
|
|
730
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type:
|
|
731
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
682
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FileFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
683
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: FileFormComponent, isStandalone: true, selector: "bonc-file-form", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, uploadTypes: { classPropertyName: "uploadTypes", publicName: "uploadTypes", isSignal: true, isRequired: true, transformFunction: null }, uploadMap: { classPropertyName: "uploadMap", publicName: "uploadMap", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, hostDirectives: [{ directive: EditableDirective }], ngImport: i0, template: "<bonc-form-controls [editable]=\"editable\">\n @if (label()) {\n <label>{{ label() }}</label>\n }\n <bonc-file-uploader\n [src]=\"editable.value\"\n [uploadTypes]=\"uploadTypes()\"\n [uploadUrlMap]=\"uploadMap()\"\n (srcChange)=\"onFileUploaded($event)\"\n >\n @let url = editable.value?.url;\n @if (url) {\n <div>{{ url }}</div>\n }\n </bonc-file-uploader>\n\n @let downloadUrl = editable.value?.url;\n @if (downloadUrl) {\n <a [href]=\"downloadUrl\" download target=\"_blank\">Download</a>\n }\n</bonc-form-controls>\n", styles: [":host{display:block}a{color:silver}\n"], dependencies: [{ kind: "component", type: FormControlsComponent, selector: "bonc-form-controls", inputs: ["editable"] }, { kind: "component", type: FileUploaderComponent, selector: "bonc-file-uploader", inputs: ["uploadUrlMap", "src", "uploadTypes"], outputs: ["srcChange"] }] });
|
|
732
684
|
}
|
|
733
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type:
|
|
685
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FileFormComponent, decorators: [{
|
|
734
686
|
type: Component,
|
|
735
|
-
args: [{ selector:
|
|
736
|
-
}], propDecorators: { label: [{
|
|
737
|
-
type: Input
|
|
738
|
-
}], pageId: [{
|
|
739
|
-
type: Input
|
|
740
|
-
}] } });
|
|
687
|
+
args: [{ selector: "bonc-file-form", imports: [FormControlsComponent, FileUploaderComponent], hostDirectives: [EditableDirective], template: "<bonc-form-controls [editable]=\"editable\">\n @if (label()) {\n <label>{{ label() }}</label>\n }\n <bonc-file-uploader\n [src]=\"editable.value\"\n [uploadTypes]=\"uploadTypes()\"\n [uploadUrlMap]=\"uploadMap()\"\n (srcChange)=\"onFileUploaded($event)\"\n >\n @let url = editable.value?.url;\n @if (url) {\n <div>{{ url }}</div>\n }\n </bonc-file-uploader>\n\n @let downloadUrl = editable.value?.url;\n @if (downloadUrl) {\n <a [href]=\"downloadUrl\" download target=\"_blank\">Download</a>\n }\n</bonc-form-controls>\n", styles: [":host{display:block}a{color:silver}\n"] }]
|
|
688
|
+
}], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], uploadTypes: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadTypes", required: true }] }], uploadMap: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadMap", required: true }] }] } });
|
|
741
689
|
|
|
742
|
-
class
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
690
|
+
class LottieFormComponent extends FormBaseComponent {
|
|
691
|
+
LottieMimeType = "application/json";
|
|
692
|
+
// todo: convert to signal
|
|
693
|
+
animOptions;
|
|
694
|
+
label = input("", ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
695
|
+
uploadMap = input.required(...(ngDevMode ? [{ debugName: "uploadMap" }] : []));
|
|
748
696
|
constructor() {
|
|
749
697
|
super();
|
|
750
|
-
this.uploadMap.set(this.SvgMime, this._uploadUrl);
|
|
751
|
-
}
|
|
752
|
-
ngOnInit() {
|
|
753
698
|
this.editable.externalSaveCall.subscribe(() => {
|
|
754
699
|
this.editable.save();
|
|
755
700
|
});
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
this.cd.detectChanges();
|
|
701
|
+
this.editable.valueChange.subscribe((x) => {
|
|
702
|
+
const url = x?.url ?? "";
|
|
703
|
+
this.animOptions = url.length === 0 ? undefined : { path: url };
|
|
704
|
+
});
|
|
761
705
|
}
|
|
762
706
|
onFileUploaded(fileSrc) {
|
|
763
707
|
this.editable.startEditing();
|
|
@@ -765,51 +709,31 @@ class SvgFormComponent extends FormBaseComponent {
|
|
|
765
709
|
this.editable.value = svgSrc;
|
|
766
710
|
this.editable.updateDirty();
|
|
767
711
|
}
|
|
768
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type:
|
|
769
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
712
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: LottieFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
713
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: LottieFormComponent, isStandalone: true, selector: "bonc-lottie-form", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, uploadMap: { classPropertyName: "uploadMap", publicName: "uploadMap", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, hostDirectives: [{ directive: EditableDirective }], ngImport: i0, template: "<bonc-form-controls [editable]=\"editable\">\n @if (label()) {\n <label>{{ label() }}</label>\n }\n <bonc-file-uploader\n [src]=\"editable.value\"\n [uploadTypes]=\"[LottieMimeType]\"\n [uploadUrlMap]=\"uploadMap()\"\n (srcChange)=\"onFileUploaded($event)\"\n >\n @if (animOptions) {\n <ng-lottie [options]=\"animOptions\"></ng-lottie>\n }\n </bonc-file-uploader>\n\n @let downloadUrl = editable.value?.url;\n @if (downloadUrl) {\n <a [href]=\"downloadUrl\" download target=\"_blank\">Download</a>\n }\n</bonc-form-controls>\n", styles: [":host{display:block;max-width:600px}a{color:silver}ng-lottie{background-image:linear-gradient(45deg,#808080 25%,transparent 25%),linear-gradient(-45deg,#808080 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#808080 75%),linear-gradient(-45deg,transparent 75%,#808080 75%);background-size:20px 20px;background-position:0 0,0 10px,10px -10px,-10px 0px;display:block}\n"], dependencies: [{ kind: "component", type: FormControlsComponent, selector: "bonc-form-controls", inputs: ["editable"] }, { kind: "component", type: FileUploaderComponent, selector: "bonc-file-uploader", inputs: ["uploadUrlMap", "src", "uploadTypes"], outputs: ["srcChange"] }, { kind: "component", type: LottieComponent, selector: "ng-lottie", inputs: ["width", "height"] }] });
|
|
770
714
|
}
|
|
771
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type:
|
|
715
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: LottieFormComponent, decorators: [{
|
|
772
716
|
type: Component,
|
|
773
|
-
args: [{ selector:
|
|
774
|
-
}], ctorParameters: () => [], propDecorators: { label: [{
|
|
775
|
-
type: Input
|
|
776
|
-
}], uploadUrl: [{
|
|
777
|
-
type: Input
|
|
778
|
-
}] } });
|
|
717
|
+
args: [{ selector: "bonc-lottie-form", imports: [FormControlsComponent, FileUploaderComponent, LottieComponent], hostDirectives: [EditableDirective], template: "<bonc-form-controls [editable]=\"editable\">\n @if (label()) {\n <label>{{ label() }}</label>\n }\n <bonc-file-uploader\n [src]=\"editable.value\"\n [uploadTypes]=\"[LottieMimeType]\"\n [uploadUrlMap]=\"uploadMap()\"\n (srcChange)=\"onFileUploaded($event)\"\n >\n @if (animOptions) {\n <ng-lottie [options]=\"animOptions\"></ng-lottie>\n }\n </bonc-file-uploader>\n\n @let downloadUrl = editable.value?.url;\n @if (downloadUrl) {\n <a [href]=\"downloadUrl\" download target=\"_blank\">Download</a>\n }\n</bonc-form-controls>\n", styles: [":host{display:block;max-width:600px}a{color:silver}ng-lottie{background-image:linear-gradient(45deg,#808080 25%,transparent 25%),linear-gradient(-45deg,#808080 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#808080 75%),linear-gradient(-45deg,transparent 75%,#808080 75%);background-size:20px 20px;background-position:0 0,0 10px,10px -10px,-10px 0px;display:block}\n"] }]
|
|
718
|
+
}], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], uploadMap: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadMap", required: true }] }] } });
|
|
779
719
|
|
|
780
|
-
const DefaultImageMimeTypes = [
|
|
720
|
+
const DefaultImageMimeTypes = ["image/png", "image/jpeg"];
|
|
781
721
|
class OneImageFormComponent extends FormBaseComponent {
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
722
|
+
label = input("", ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
723
|
+
uploadUrl = input("/api/admin/upload/image", ...(ngDevMode ? [{ debugName: "uploadUrl" }] : []));
|
|
724
|
+
mimeTypes = input(DefaultImageMimeTypes, ...(ngDevMode ? [{ debugName: "mimeTypes" }] : []));
|
|
725
|
+
uploadMap = computed(() => {
|
|
726
|
+
const m = new Map();
|
|
727
|
+
m.set("", this.uploadUrl());
|
|
728
|
+
return m;
|
|
729
|
+
}, ...(ngDevMode ? [{ debugName: "uploadMap" }] : []));
|
|
730
|
+
destroyRef = inject(DestroyRef);
|
|
787
731
|
constructor() {
|
|
788
732
|
super();
|
|
789
|
-
this.
|
|
790
|
-
}
|
|
791
|
-
ngOnInit() {
|
|
792
|
-
this.editable.externalSaveCall.subscribe(() => {
|
|
733
|
+
const sub = this.editable.externalSaveCall.subscribe(() => {
|
|
793
734
|
this.editable.save();
|
|
794
735
|
});
|
|
795
|
-
|
|
796
|
-
set label(newValue) {
|
|
797
|
-
this._label = newValue;
|
|
798
|
-
}
|
|
799
|
-
get label() {
|
|
800
|
-
return this._label;
|
|
801
|
-
}
|
|
802
|
-
set uploadUrl(newValue) {
|
|
803
|
-
this._uploadUrl = newValue;
|
|
804
|
-
this.uploadMap.set('', this._uploadUrl);
|
|
805
|
-
this.cd.detectChanges();
|
|
806
|
-
}
|
|
807
|
-
set mimeTypes(newValue) {
|
|
808
|
-
this._mimeTypes = newValue.length === 0 ? DefaultImageMimeTypes : newValue;
|
|
809
|
-
this.cd.detectChanges();
|
|
810
|
-
}
|
|
811
|
-
get mimeTypes() {
|
|
812
|
-
return this._mimeTypes;
|
|
736
|
+
this.destroyRef.onDestroy(() => sub.unsubscribe());
|
|
813
737
|
}
|
|
814
738
|
onFileUploaded(fileSrc) {
|
|
815
739
|
this.editable.startEditing();
|
|
@@ -818,50 +742,77 @@ class OneImageFormComponent extends FormBaseComponent {
|
|
|
818
742
|
this.editable.updateDirty();
|
|
819
743
|
}
|
|
820
744
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: OneImageFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
821
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
745
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: OneImageFormComponent, isStandalone: true, selector: "bonc-one-image-form", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, uploadUrl: { classPropertyName: "uploadUrl", publicName: "uploadUrl", isSignal: true, isRequired: false, transformFunction: null }, mimeTypes: { classPropertyName: "mimeTypes", publicName: "mimeTypes", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, hostDirectives: [{ directive: EditableDirective }], ngImport: i0, template: "<bonc-form-controls [editable]=\"editable\">\n @if (label()) {\n <label>{{ label() }}</label>\n }\n <bonc-file-uploader\n [src]=\"editable.value\"\n [uploadTypes]=\"mimeTypes()\"\n [uploadUrlMap]=\"uploadMap()\"\n (srcChange)=\"onFileUploaded($event)\"\n >\n @let url = editable.value?.url;\n @if (url) {\n <img [src]=\"url\" />\n }\n </bonc-file-uploader>\n\n @let downloadUrl = editable.value?.url;\n @if (downloadUrl) {\n <a [href]=\"downloadUrl\" download target=\"_blank\">Download</a>\n }\n</bonc-form-controls>\n", styles: [":host{display:block}img{background-image:linear-gradient(45deg,#808080 25%,transparent 25%),linear-gradient(-45deg,#808080 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#808080 75%),linear-gradient(-45deg,transparent 75%,#808080 75%);background-size:20px 20px;background-position:0 0,0 10px,10px -10px,-10px 0px;display:block;width:100%}a{color:silver}\n"], dependencies: [{ kind: "component", type: FormControlsComponent, selector: "bonc-form-controls", inputs: ["editable"] }, { kind: "component", type: FileUploaderComponent, selector: "bonc-file-uploader", inputs: ["uploadUrlMap", "src", "uploadTypes"], outputs: ["srcChange"] }] });
|
|
822
746
|
}
|
|
823
747
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: OneImageFormComponent, decorators: [{
|
|
824
748
|
type: Component,
|
|
825
|
-
args: [{ selector:
|
|
826
|
-
}], ctorParameters: () => [], propDecorators: { label: [{
|
|
827
|
-
type: Input
|
|
828
|
-
}], uploadUrl: [{
|
|
829
|
-
type: Input
|
|
830
|
-
}], mimeTypes: [{
|
|
831
|
-
type: Input
|
|
832
|
-
}] } });
|
|
749
|
+
args: [{ selector: "bonc-one-image-form", imports: [FormControlsComponent, FileUploaderComponent], hostDirectives: [EditableDirective], template: "<bonc-form-controls [editable]=\"editable\">\n @if (label()) {\n <label>{{ label() }}</label>\n }\n <bonc-file-uploader\n [src]=\"editable.value\"\n [uploadTypes]=\"mimeTypes()\"\n [uploadUrlMap]=\"uploadMap()\"\n (srcChange)=\"onFileUploaded($event)\"\n >\n @let url = editable.value?.url;\n @if (url) {\n <img [src]=\"url\" />\n }\n </bonc-file-uploader>\n\n @let downloadUrl = editable.value?.url;\n @if (downloadUrl) {\n <a [href]=\"downloadUrl\" download target=\"_blank\">Download</a>\n }\n</bonc-form-controls>\n", styles: [":host{display:block}img{background-image:linear-gradient(45deg,#808080 25%,transparent 25%),linear-gradient(-45deg,#808080 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#808080 75%),linear-gradient(-45deg,transparent 75%,#808080 75%);background-size:20px 20px;background-position:0 0,0 10px,10px -10px,-10px 0px;display:block;width:100%}a{color:silver}\n"] }]
|
|
750
|
+
}], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], uploadUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadUrl", required: false }] }], mimeTypes: [{ type: i0.Input, args: [{ isSignal: true, alias: "mimeTypes", required: false }] }] } });
|
|
833
751
|
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
752
|
+
const defaultUploadMap = new Map();
|
|
753
|
+
defaultUploadMap.set("", `/api/admin/upload/image?width=${1200}&height=${630}&format=image/jpeg`);
|
|
754
|
+
class SeoFormComponent extends FormBaseComponent {
|
|
755
|
+
uploadMap = defaultUploadMap;
|
|
756
|
+
label = input("", ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
757
|
+
pageId = input("", ...(ngDevMode ? [{ debugName: "pageId" }] : []));
|
|
758
|
+
ogImageUploadUrl = computed(() => `/api/admin/page/Og-Image?pageId=${this.pageId()}`, ...(ngDevMode ? [{ debugName: "ogImageUploadUrl" }] : []));
|
|
759
|
+
constructor() {
|
|
760
|
+
super();
|
|
761
|
+
this.editable.externalSaveCall.subscribe(() => {
|
|
762
|
+
this.editable.save();
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
ResToSrc(res) {
|
|
766
|
+
return res.url;
|
|
767
|
+
}
|
|
768
|
+
replaceImage($event) {
|
|
769
|
+
this.editable.startEditing();
|
|
770
|
+
if (this.editable.value !== undefined) {
|
|
771
|
+
this.editable.value.image[this.locale()] = $event;
|
|
772
|
+
}
|
|
773
|
+
this.editable.updateDirty();
|
|
774
|
+
}
|
|
775
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SeoFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
776
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: SeoFormComponent, isStandalone: true, selector: "bonc-seo-form", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, pageId: { classPropertyName: "pageId", publicName: "pageId", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, hostDirectives: [{ directive: EditableDirective }], ngImport: i0, template: "@if (editable.value !== undefined && editable.value !== null) {\n <bonc-form-controls [editable]=\"editable\">\n @if (label()) {\n <h2>{{label()}}</h2>\n }\n\n <div class=\"form-group\">\n <label>Title</label>\n <bonc-translation-input [text]=\"editable.value.title\"\n [locale]=\"locale()\"\n (startEditing)=\"editable.startEditing()\"\n (changed)=\"editable.updateDirty()\"\n (blurred)=\"editable.updateDirty()\">\n </bonc-translation-input>\n </div>\n\n <div class=\"form-group\">\n <label>Description</label>\n <bonc-translation-textarea [text]=\"editable.value.description\"\n [locale]=\"locale()\"\n (startEditing)=\"editable.startEditing()\"\n (changed)=\"editable.updateDirty()\"\n (blurred)=\"editable.updateDirty()\">\n </bonc-translation-textarea>\n </div>\n\n <div class=\"form-group\">\n <label>Share image | 1200x630</label>\n\n <bonc-file-uploader [src]=\"editable.value.image[locale()]\"\n [uploadTypes]=\"['image/png', 'image/jpeg']\"\n [uploadUrlMap]=\"uploadMap\"\n (srcChange)=\"replaceImage($event)\">\n @let imageUrl = editable.value.image[locale()]?.url;\n @if (imageUrl) {\n <img [src]=\"imageUrl\" />\n }\n </bonc-file-uploader>\n\n @let downloadUrl = editable.value.image[locale()]?.url;\n @if (downloadUrl) {\n <a [href]=\"downloadUrl\" download target=\"_blank\">Download</a>\n }\n </div>\n\n </bonc-form-controls>\n} @else {\n <div>Editable Value canot be null or undefined</div>\n}\n", styles: [":host{display:block}bonc-one-image-form{max-width:600px}img{display:block;width:100%}\n"], dependencies: [{ kind: "component", type: FormControlsComponent, selector: "bonc-form-controls", inputs: ["editable"] }, { 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: ["text", "locale", "minRows", "maxRows", "device"], outputs: ["startEditing", "changed", "blurred"] }, { kind: "component", type: FileUploaderComponent, selector: "bonc-file-uploader", inputs: ["uploadUrlMap", "src", "uploadTypes"], outputs: ["srcChange"] }] });
|
|
777
|
+
}
|
|
778
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SeoFormComponent, decorators: [{
|
|
779
|
+
type: Component,
|
|
780
|
+
args: [{ selector: "bonc-seo-form", imports: [
|
|
781
|
+
FormControlsComponent,
|
|
782
|
+
TranslationInputComponent,
|
|
783
|
+
TranslationTextareaComponent,
|
|
784
|
+
FileUploaderComponent,
|
|
785
|
+
], hostDirectives: [EditableDirective], template: "@if (editable.value !== undefined && editable.value !== null) {\n <bonc-form-controls [editable]=\"editable\">\n @if (label()) {\n <h2>{{label()}}</h2>\n }\n\n <div class=\"form-group\">\n <label>Title</label>\n <bonc-translation-input [text]=\"editable.value.title\"\n [locale]=\"locale()\"\n (startEditing)=\"editable.startEditing()\"\n (changed)=\"editable.updateDirty()\"\n (blurred)=\"editable.updateDirty()\">\n </bonc-translation-input>\n </div>\n\n <div class=\"form-group\">\n <label>Description</label>\n <bonc-translation-textarea [text]=\"editable.value.description\"\n [locale]=\"locale()\"\n (startEditing)=\"editable.startEditing()\"\n (changed)=\"editable.updateDirty()\"\n (blurred)=\"editable.updateDirty()\">\n </bonc-translation-textarea>\n </div>\n\n <div class=\"form-group\">\n <label>Share image | 1200x630</label>\n\n <bonc-file-uploader [src]=\"editable.value.image[locale()]\"\n [uploadTypes]=\"['image/png', 'image/jpeg']\"\n [uploadUrlMap]=\"uploadMap\"\n (srcChange)=\"replaceImage($event)\">\n @let imageUrl = editable.value.image[locale()]?.url;\n @if (imageUrl) {\n <img [src]=\"imageUrl\" />\n }\n </bonc-file-uploader>\n\n @let downloadUrl = editable.value.image[locale()]?.url;\n @if (downloadUrl) {\n <a [href]=\"downloadUrl\" download target=\"_blank\">Download</a>\n }\n </div>\n\n </bonc-form-controls>\n} @else {\n <div>Editable Value canot be null or undefined</div>\n}\n", styles: [":host{display:block}bonc-one-image-form{max-width:600px}img{display:block;width:100%}\n"] }]
|
|
786
|
+
}], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], pageId: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageId", required: false }] }] } });
|
|
787
|
+
|
|
788
|
+
class SvgFormComponent extends FormBaseComponent {
|
|
789
|
+
SvgMime = "image/svg+xml";
|
|
790
|
+
label = input("", ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
791
|
+
uploadUrl = input("/api/admin/upload/image/svg", ...(ngDevMode ? [{ debugName: "uploadUrl" }] : []));
|
|
792
|
+
uploadMap = computed(() => {
|
|
793
|
+
const m = new Map();
|
|
794
|
+
m.set(this.SvgMime, this.uploadUrl());
|
|
795
|
+
return m;
|
|
796
|
+
}, ...(ngDevMode ? [{ debugName: "uploadMap" }] : []));
|
|
797
|
+
constructor() {
|
|
798
|
+
super();
|
|
837
799
|
this.editable.externalSaveCall.subscribe(() => {
|
|
838
800
|
this.editable.save();
|
|
839
801
|
});
|
|
840
802
|
}
|
|
841
|
-
uploadTypes = [];
|
|
842
|
-
uploadMap = new Map();
|
|
843
|
-
;
|
|
844
803
|
onFileUploaded(fileSrc) {
|
|
845
804
|
this.editable.startEditing();
|
|
846
805
|
const svgSrc = fileSrc;
|
|
847
806
|
this.editable.value = svgSrc;
|
|
848
807
|
this.editable.updateDirty();
|
|
849
808
|
}
|
|
850
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type:
|
|
851
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
809
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SvgFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
810
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: SvgFormComponent, isStandalone: true, selector: "bonc-svg-form", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, uploadUrl: { classPropertyName: "uploadUrl", publicName: "uploadUrl", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, hostDirectives: [{ directive: EditableDirective }], ngImport: i0, template: "<bonc-form-controls [editable]=\"editable\">\n @if (label()) {\n <label>{{label()}}</label>\n }\n <bonc-file-uploader [src]=\"editable.value\"\n [uploadTypes]=\"[SvgMime]\"\n [uploadUrlMap]=\"uploadMap()\"\n (srcChange)=\"onFileUploaded($event)\">\n @let url = editable.value?.url;\n @if (url) {\n <img [src]=\"url\" alt=\"\" />\n }\n </bonc-file-uploader>\n\n @let downloadUrl = editable.value?.url;\n @if (downloadUrl) {\n <a [href]=\"downloadUrl\" download target=\"_blank\">Download</a>\n }\n\n</bonc-form-controls>\n", styles: [":host{display:block}img{background-image:linear-gradient(45deg,#808080 25%,transparent 25%),linear-gradient(-45deg,#808080 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#808080 75%),linear-gradient(-45deg,transparent 75%,#808080 75%);background-size:20px 20px;background-position:0 0,0 10px,10px -10px,-10px 0px;display:block;width:100%}a{color:silver}\n"], dependencies: [{ kind: "component", type: FormControlsComponent, selector: "bonc-form-controls", inputs: ["editable"] }, { kind: "component", type: FileUploaderComponent, selector: "bonc-file-uploader", inputs: ["uploadUrlMap", "src", "uploadTypes"], outputs: ["srcChange"] }] });
|
|
852
811
|
}
|
|
853
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type:
|
|
812
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SvgFormComponent, decorators: [{
|
|
854
813
|
type: Component,
|
|
855
|
-
args: [{ selector:
|
|
856
|
-
}], propDecorators: { label: [{
|
|
857
|
-
type: Input
|
|
858
|
-
}], uploadTypes: [{
|
|
859
|
-
type: Input,
|
|
860
|
-
args: [{ required: true }]
|
|
861
|
-
}], uploadMap: [{
|
|
862
|
-
type: Input,
|
|
863
|
-
args: [{ required: true }]
|
|
864
|
-
}] } });
|
|
814
|
+
args: [{ selector: "bonc-svg-form", imports: [FormControlsComponent, FileUploaderComponent], hostDirectives: [EditableDirective], template: "<bonc-form-controls [editable]=\"editable\">\n @if (label()) {\n <label>{{label()}}</label>\n }\n <bonc-file-uploader [src]=\"editable.value\"\n [uploadTypes]=\"[SvgMime]\"\n [uploadUrlMap]=\"uploadMap()\"\n (srcChange)=\"onFileUploaded($event)\">\n @let url = editable.value?.url;\n @if (url) {\n <img [src]=\"url\" alt=\"\" />\n }\n </bonc-file-uploader>\n\n @let downloadUrl = editable.value?.url;\n @if (downloadUrl) {\n <a [href]=\"downloadUrl\" download target=\"_blank\">Download</a>\n }\n\n</bonc-form-controls>\n", styles: [":host{display:block}img{background-image:linear-gradient(45deg,#808080 25%,transparent 25%),linear-gradient(-45deg,#808080 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#808080 75%),linear-gradient(-45deg,transparent 75%,#808080 75%);background-size:20px 20px;background-position:0 0,0 10px,10px -10px,-10px 0px;display:block;width:100%}a{color:silver}\n"] }]
|
|
815
|
+
}], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], uploadUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadUrl", required: false }] }] } });
|
|
865
816
|
|
|
866
817
|
var TextInputStyle;
|
|
867
818
|
(function (TextInputStyle) {
|
|
@@ -872,336 +823,218 @@ var TextInputStyle;
|
|
|
872
823
|
|
|
873
824
|
class TextFormComponent extends FormBaseComponent {
|
|
874
825
|
TextInputStyle = TextInputStyle;
|
|
875
|
-
label =
|
|
876
|
-
type = TextInputStyle.SingleLine;
|
|
877
|
-
|
|
826
|
+
label = input("", ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
827
|
+
type = input(TextInputStyle.SingleLine, ...(ngDevMode ? [{ debugName: "type" }] : []));
|
|
828
|
+
constructor() {
|
|
829
|
+
super();
|
|
878
830
|
this.editable.externalSaveCall.subscribe(() => {
|
|
879
831
|
this.editable.save();
|
|
880
832
|
});
|
|
881
833
|
}
|
|
882
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TextFormComponent, deps:
|
|
883
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
834
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TextFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
835
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: TextFormComponent, isStandalone: true, selector: "bonc-text-form", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, hostDirectives: [{ directive: EditableDirective }], ngImport: i0, template: "<bonc-form-controls [editable]=\"editable\">\n @if (label()) {\n <label>{{label()}}</label>\n }\n @if (editable) {\n @switch (type()) {\n @case (TextInputStyle.SingleLine) {\n <input [(ngModel)]=\"editable.value\"\n [attr.aria-label]=\"label()\"\n (click)=\"editable.startEditing()\"\n (keyup)=\"editable.updateDirty()\"\n (blur)=\"editable.updateDirty()\" />\n }\n @case (TextInputStyle.MultiLine) {\n <textarea [(ngModel)]=\"editable.value\"\n [attr.aria-label]=\"label()\"\n (click)=\"editable.startEditing()\"\n (keyup)=\"editable.updateDirty()\"\n (blur)=\"editable.updateDirty()\">\n </textarea>\n }\n }\n }\n</bonc-form-controls>\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}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}input,textarea{font-size:inherit}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { 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"] }] });
|
|
884
836
|
}
|
|
885
837
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TextFormComponent, decorators: [{
|
|
886
838
|
type: Component,
|
|
887
|
-
args: [{ selector:
|
|
888
|
-
}], propDecorators: { label: [{
|
|
889
|
-
type: Input
|
|
890
|
-
}], type: [{
|
|
891
|
-
type: Input
|
|
892
|
-
}] } });
|
|
893
|
-
|
|
894
|
-
class LottieFormComponent extends FormBaseComponent {
|
|
895
|
-
LottieMimeType = 'application/json';
|
|
896
|
-
animOptions;
|
|
897
|
-
label = '';
|
|
898
|
-
ngOnInit() {
|
|
899
|
-
this.editable.externalSaveCall.subscribe(() => {
|
|
900
|
-
this.editable.save();
|
|
901
|
-
});
|
|
902
|
-
this.editable.valueChange.subscribe(x => {
|
|
903
|
-
const url = x?.url ?? '';
|
|
904
|
-
this.animOptions = url.length === 0 ? undefined : { path: url };
|
|
905
|
-
});
|
|
906
|
-
}
|
|
907
|
-
uploadMap = new Map();
|
|
908
|
-
;
|
|
909
|
-
onFileUploaded(fileSrc) {
|
|
910
|
-
this.editable.startEditing();
|
|
911
|
-
const svgSrc = fileSrc;
|
|
912
|
-
this.editable.value = svgSrc;
|
|
913
|
-
this.editable.updateDirty();
|
|
914
|
-
}
|
|
915
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: LottieFormComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
916
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: LottieFormComponent, isStandalone: true, selector: "bonc-lottie-form", inputs: { label: "label", uploadMap: "uploadMap" }, usesInheritance: true, hostDirectives: [{ directive: EditableDirective }], ngImport: i0, template: "<bonc-form-controls [editable]=\"editable\">\n <label *ngIf=\"label\">{{label}}</label>\n <bonc-file-uploader [src]=\"editable.value\"\n [uploadTypes]=\"[LottieMimeType]\"\n [uploadUrlMap]=\"uploadMap\"\n (srcChange)=\"onFileUploaded($event)\">\n\n <ng-lottie *ngIf=\"animOptions\"\n [options]=\"animOptions\"></ng-lottie>\n\n\n </bonc-file-uploader>\n\n <a *ngIf=\"editable.value?.url?.length ?? 0 > 0\" [href]=\"editable.value!.url\" download target=\"_blank\">Download</a>\n</bonc-form-controls>\n", styles: [":host{display:block;max-width:600px}a{color:silver}ng-lottie{background-image:linear-gradient(45deg,#808080 25%,transparent 25%),linear-gradient(-45deg,#808080 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#808080 75%),linear-gradient(-45deg,transparent 75%,#808080 75%);background-size:20px 20px;background-position:0 0,0 10px,10px -10px,-10px 0px;display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FormControlsComponent, selector: "bonc-form-controls", inputs: ["editable"] }, { kind: "component", type: FileUploaderComponent, selector: "bonc-file-uploader", inputs: ["uploadUrlMap", "src", "uploadTypes"], outputs: ["srcChange"] }, { kind: "component", type: LottieComponent, selector: "ng-lottie", inputs: ["width", "height"] }] });
|
|
917
|
-
}
|
|
918
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: LottieFormComponent, decorators: [{
|
|
919
|
-
type: Component,
|
|
920
|
-
args: [{ selector: 'bonc-lottie-form', standalone: true, imports: [CommonModule, FormControlsComponent, FileUploaderComponent, LottieComponent], hostDirectives: [EditableDirective], template: "<bonc-form-controls [editable]=\"editable\">\n <label *ngIf=\"label\">{{label}}</label>\n <bonc-file-uploader [src]=\"editable.value\"\n [uploadTypes]=\"[LottieMimeType]\"\n [uploadUrlMap]=\"uploadMap\"\n (srcChange)=\"onFileUploaded($event)\">\n\n <ng-lottie *ngIf=\"animOptions\"\n [options]=\"animOptions\"></ng-lottie>\n\n\n </bonc-file-uploader>\n\n <a *ngIf=\"editable.value?.url?.length ?? 0 > 0\" [href]=\"editable.value!.url\" download target=\"_blank\">Download</a>\n</bonc-form-controls>\n", styles: [":host{display:block;max-width:600px}a{color:silver}ng-lottie{background-image:linear-gradient(45deg,#808080 25%,transparent 25%),linear-gradient(-45deg,#808080 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#808080 75%),linear-gradient(-45deg,transparent 75%,#808080 75%);background-size:20px 20px;background-position:0 0,0 10px,10px -10px,-10px 0px;display:block}\n"] }]
|
|
921
|
-
}], propDecorators: { label: [{
|
|
922
|
-
type: Input
|
|
923
|
-
}], uploadMap: [{
|
|
924
|
-
type: Input,
|
|
925
|
-
args: [{ required: true }]
|
|
926
|
-
}] } });
|
|
839
|
+
args: [{ selector: "bonc-text-form", imports: [FormsModule, FormControlsComponent], hostDirectives: [EditableDirective], template: "<bonc-form-controls [editable]=\"editable\">\n @if (label()) {\n <label>{{label()}}</label>\n }\n @if (editable) {\n @switch (type()) {\n @case (TextInputStyle.SingleLine) {\n <input [(ngModel)]=\"editable.value\"\n [attr.aria-label]=\"label()\"\n (click)=\"editable.startEditing()\"\n (keyup)=\"editable.updateDirty()\"\n (blur)=\"editable.updateDirty()\" />\n }\n @case (TextInputStyle.MultiLine) {\n <textarea [(ngModel)]=\"editable.value\"\n [attr.aria-label]=\"label()\"\n (click)=\"editable.startEditing()\"\n (keyup)=\"editable.updateDirty()\"\n (blur)=\"editable.updateDirty()\">\n </textarea>\n }\n }\n }\n</bonc-form-controls>\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}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}input,textarea{font-size:inherit}\n"] }]
|
|
840
|
+
}], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }] } });
|
|
927
841
|
|
|
928
842
|
class TranslationFormComponent extends FormBaseComponent {
|
|
929
843
|
TextEditorField = TextEditorField;
|
|
930
|
-
field;
|
|
931
|
-
label;
|
|
932
|
-
|
|
844
|
+
field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
|
|
845
|
+
label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
|
|
846
|
+
constructor() {
|
|
847
|
+
super();
|
|
933
848
|
this.editable.externalSaveCall.subscribe(() => {
|
|
934
849
|
this.editable.save();
|
|
935
850
|
});
|
|
936
851
|
}
|
|
937
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TranslationFormComponent, deps:
|
|
938
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
852
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TranslationFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
853
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: TranslationFormComponent, isStandalone: true, selector: "bonc-translation-form", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, hostDirectives: [{ directive: EditableDirective }], ngImport: i0, template: "@if (editable.value) {\n <bonc-form-controls [editable]=\"editable\">\n @if (label()) {\n <label>{{label()}}</label>\n }\n\n @switch (field()) {\n @case (TextEditorField.Input) {\n <bonc-translation-input [text]=\"editable.value\"\n [locale]=\"locale()\"\n (startEditing)=\"editable.startEditing()\"\n (changed)=\"editable.updateDirty()\"\n (blurred)=\"editable.updateDirty()\">\n </bonc-translation-input>\n }\n @case (TextEditorField.Textarea) {\n <bonc-translation-textarea [text]=\"editable.value\"\n [minRows]=\"2\"\n [locale]=\"locale()\"\n (startEditing)=\"editable.startEditing()\"\n (changed)=\"editable.updateDirty()\"\n (blurred)=\"editable.updateDirty()\">\n </bonc-translation-textarea>\n }\n }\n </bonc-form-controls>\n} @else {\n <div>Editable value canot be undefined</div>\n}\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: FormControlsComponent, selector: "bonc-form-controls", inputs: ["editable"] }, { 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: ["text", "locale", "minRows", "maxRows", "device"], outputs: ["startEditing", "changed", "blurred"] }] });
|
|
939
854
|
}
|
|
940
855
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TranslationFormComponent, decorators: [{
|
|
941
856
|
type: Component,
|
|
942
|
-
args: [{ selector:
|
|
943
|
-
}], propDecorators: { field: [{
|
|
944
|
-
type: Input,
|
|
945
|
-
args: [{ required: true }]
|
|
946
|
-
}], label: [{
|
|
947
|
-
type: Input
|
|
948
|
-
}] } });
|
|
857
|
+
args: [{ selector: "bonc-translation-form", imports: [FormControlsComponent, TranslationInputComponent, TranslationTextareaComponent], hostDirectives: [EditableDirective], template: "@if (editable.value) {\n <bonc-form-controls [editable]=\"editable\">\n @if (label()) {\n <label>{{label()}}</label>\n }\n\n @switch (field()) {\n @case (TextEditorField.Input) {\n <bonc-translation-input [text]=\"editable.value\"\n [locale]=\"locale()\"\n (startEditing)=\"editable.startEditing()\"\n (changed)=\"editable.updateDirty()\"\n (blurred)=\"editable.updateDirty()\">\n </bonc-translation-input>\n }\n @case (TextEditorField.Textarea) {\n <bonc-translation-textarea [text]=\"editable.value\"\n [minRows]=\"2\"\n [locale]=\"locale()\"\n (startEditing)=\"editable.startEditing()\"\n (changed)=\"editable.updateDirty()\"\n (blurred)=\"editable.updateDirty()\">\n </bonc-translation-textarea>\n }\n }\n </bonc-form-controls>\n} @else {\n <div>Editable value canot be undefined</div>\n}\n", styles: [":host{display:block}\n"] }]
|
|
858
|
+
}], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }] } });
|
|
949
859
|
|
|
950
860
|
class UnknownFormComponent extends FormBaseComponent {
|
|
951
|
-
label =
|
|
952
|
-
|
|
861
|
+
label = input("", ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
862
|
+
constructor() {
|
|
863
|
+
super();
|
|
953
864
|
this.editable.externalSaveCall.subscribe(() => {
|
|
954
865
|
this.editable.save();
|
|
955
866
|
});
|
|
956
867
|
}
|
|
957
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: UnknownFormComponent, deps:
|
|
958
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
868
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: UnknownFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
869
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.6", type: UnknownFormComponent, isStandalone: true, selector: "bonc-unknown-form", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, hostDirectives: [{ directive: EditableDirective }], ngImport: i0, template: "<label>Unknown form:<b>{{label()}}</b></label>\n<pre><ng-content></ng-content></pre>\n", styles: [":host{display:block;color:#000;padding:20px;background-color:#dc143c;margin-bottom:10px}\n"] });
|
|
959
870
|
}
|
|
960
871
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: UnknownFormComponent, decorators: [{
|
|
961
872
|
type: Component,
|
|
962
|
-
args: [{ selector:
|
|
963
|
-
}], propDecorators: { label: [{
|
|
964
|
-
type: Input
|
|
965
|
-
}] } });
|
|
873
|
+
args: [{ selector: "bonc-unknown-form", hostDirectives: [EditableDirective], template: "<label>Unknown form:<b>{{label()}}</b></label>\n<pre><ng-content></ng-content></pre>\n", styles: [":host{display:block;color:#000;padding:20px;background-color:#dc143c;margin-bottom:10px}\n"] }]
|
|
874
|
+
}], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }] } });
|
|
966
875
|
|
|
967
|
-
|
|
876
|
+
/**
|
|
877
|
+
* This is a TypeGen auto-generated file.
|
|
878
|
+
* Any changes made to this file can be lost when this file is regenerated.
|
|
879
|
+
*/
|
|
968
880
|
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
const pageOb = this.getSkeleton(`${this.baseHref}api/views/${viewCode}`);
|
|
974
|
-
return pageOb;
|
|
975
|
-
}
|
|
976
|
-
getPage(pageRoute) {
|
|
977
|
-
const pageUrl = `/${pageRoute}`;
|
|
978
|
-
const pageOb = this.getSkeleton(`${this.baseHref}api/pages/?url=${encodeURIComponent(pageUrl)}`);
|
|
979
|
-
return pageOb;
|
|
980
|
-
}
|
|
981
|
-
getSettings(ids) {
|
|
982
|
-
const pageOb = this.http.get(`${this.baseHref}api/settings`, {
|
|
983
|
-
params: { ids: ids }
|
|
984
|
-
});
|
|
985
|
-
return pageOb;
|
|
986
|
-
}
|
|
987
|
-
getSkeleton(url) {
|
|
988
|
-
const skeletonOb = this.http.get(url);
|
|
989
|
-
const routeDataObs = skeletonOb
|
|
990
|
-
.pipe(map(x => {
|
|
991
|
-
const notEmptyDataRoutes = x.bones
|
|
992
|
-
.map(b => ('dataRoute' in b) && typeof (b.dataRoute) === 'string' ? b.dataRoute : '')
|
|
993
|
-
.filter(x => x.length > 0);
|
|
994
|
-
if (notEmptyDataRoutes.length === 0) {
|
|
995
|
-
const emptyData = {};
|
|
996
|
-
return { page: of(x), data: of(emptyData) };
|
|
997
|
-
}
|
|
998
|
-
return {
|
|
999
|
-
page: of(x),
|
|
1000
|
-
data: combineLatest(notEmptyDataRoutes
|
|
1001
|
-
.map(dataRoute => {
|
|
1002
|
-
const url = `${this.baseHref}api/Pages/Children/?url=${dataRoute}`;
|
|
1003
|
-
return {
|
|
1004
|
-
route: dataRoute,
|
|
1005
|
-
json: this.http.get(url)
|
|
1006
|
-
};
|
|
1007
|
-
})
|
|
1008
|
-
.reduce((prev, curr) => {
|
|
1009
|
-
prev[curr.route] = curr.json;
|
|
1010
|
-
return prev;
|
|
1011
|
-
}, {}))
|
|
1012
|
-
};
|
|
1013
|
-
}), map(x => combineLatest(x)), mergeMap(res => merge(res)), map(x => {
|
|
1014
|
-
for (const bone of x.page.bones) {
|
|
1015
|
-
if (!('dataRoute' in bone) || typeof bone.dataRoute !== 'string' || bone.dataRoute.length === 0)
|
|
1016
|
-
continue;
|
|
1017
|
-
const data = x.data[bone.dataRoute];
|
|
1018
|
-
if (data === undefined || data === null)
|
|
1019
|
-
throw new Error(`Data ${bone.dataRoute} have not been preloaded`);
|
|
1020
|
-
bone.data = data; // todo: fix
|
|
1021
|
-
}
|
|
1022
|
-
return x.page;
|
|
1023
|
-
}));
|
|
1024
|
-
return routeDataObs;
|
|
1025
|
-
}
|
|
1026
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DataService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1027
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DataService });
|
|
1028
|
-
}
|
|
1029
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DataService, decorators: [{
|
|
1030
|
-
type: Injectable
|
|
1031
|
-
}] });
|
|
881
|
+
/**
|
|
882
|
+
* This is a TypeGen auto-generated file.
|
|
883
|
+
* Any changes made to this file can be lost when this file is regenerated.
|
|
884
|
+
*/
|
|
1032
885
|
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
console.log('baseHref: ' + this.baseHref);
|
|
1038
|
-
}
|
|
1039
|
-
getSettingGroups() {
|
|
1040
|
-
const pageOb = this.http.get(`${this.baseHref}api/admin/settings`);
|
|
1041
|
-
return pageOb;
|
|
1042
|
-
}
|
|
1043
|
-
getPage(url) {
|
|
1044
|
-
const pageOb = this.http.get(`${this.baseHref}api/admin/pages/${url}`);
|
|
1045
|
-
return pageOb;
|
|
1046
|
-
}
|
|
1047
|
-
storePage(page) {
|
|
1048
|
-
const ob = this.http.post(`${this.baseHref}api/admin/pages`, page);
|
|
1049
|
-
return ob;
|
|
1050
|
-
}
|
|
1051
|
-
updateSettings(settings) {
|
|
1052
|
-
const ob = this.http.post(`${this.baseHref}api/admin/settings`, settings);
|
|
1053
|
-
return ob;
|
|
1054
|
-
}
|
|
1055
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: AdminDataService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1056
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: AdminDataService });
|
|
1057
|
-
}
|
|
1058
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: AdminDataService, decorators: [{
|
|
1059
|
-
type: Injectable
|
|
1060
|
-
}], ctorParameters: () => [] });
|
|
886
|
+
/**
|
|
887
|
+
* This is a TypeGen auto-generated file.
|
|
888
|
+
* Any changes made to this file can be lost when this file is regenerated.
|
|
889
|
+
*/
|
|
1061
890
|
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
}], deviceControls: [{
|
|
1097
|
-
type: Input
|
|
1098
|
-
}] } });
|
|
891
|
+
/**
|
|
892
|
+
* This is a TypeGen auto-generated file.
|
|
893
|
+
* Any changes made to this file can be lost when this file is regenerated.
|
|
894
|
+
*/
|
|
895
|
+
|
|
896
|
+
/**
|
|
897
|
+
* This is a TypeGen auto-generated file.
|
|
898
|
+
* Any changes made to this file can be lost when this file is regenerated.
|
|
899
|
+
*/
|
|
900
|
+
|
|
901
|
+
/**
|
|
902
|
+
* This is a TypeGen auto-generated file.
|
|
903
|
+
* Any changes made to this file can be lost when this file is regenerated.
|
|
904
|
+
*/
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* This is a TypeGen auto-generated file.
|
|
908
|
+
* Any changes made to this file can be lost when this file is regenerated.
|
|
909
|
+
*/
|
|
910
|
+
|
|
911
|
+
/**
|
|
912
|
+
* This is a TypeGen auto-generated file.
|
|
913
|
+
* Any changes made to this file can be lost when this file is regenerated.
|
|
914
|
+
*/
|
|
915
|
+
|
|
916
|
+
/**
|
|
917
|
+
* This is a TypeGen auto-generated file.
|
|
918
|
+
* Any changes made to this file can be lost when this file is regenerated.
|
|
919
|
+
*/
|
|
920
|
+
|
|
921
|
+
/**
|
|
922
|
+
* This is a TypeGen auto-generated file.
|
|
923
|
+
* Any changes made to this file can be lost when this file is regenerated.
|
|
924
|
+
*/
|
|
1099
925
|
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
926
|
+
/**
|
|
927
|
+
* This is a TypeGen auto-generated file.
|
|
928
|
+
* Any changes made to this file can be lost when this file is regenerated.
|
|
929
|
+
*/
|
|
930
|
+
|
|
931
|
+
/**
|
|
932
|
+
* This is a TypeGen auto-generated file.
|
|
933
|
+
* Any changes made to this file can be lost when this file is regenerated.
|
|
934
|
+
*/
|
|
935
|
+
|
|
936
|
+
/**
|
|
937
|
+
* This is a TypeGen auto-generated file.
|
|
938
|
+
* Any changes made to this file can be lost when this file is regenerated.
|
|
939
|
+
*/
|
|
940
|
+
var TextSettingType;
|
|
941
|
+
(function (TextSettingType) {
|
|
942
|
+
TextSettingType[TextSettingType["SingleLine"] = 0] = "SingleLine";
|
|
943
|
+
TextSettingType[TextSettingType["MultiLine"] = 1] = "MultiLine";
|
|
944
|
+
})(TextSettingType || (TextSettingType = {}));
|
|
945
|
+
|
|
946
|
+
/**
|
|
947
|
+
* This is a TypeGen auto-generated file.
|
|
948
|
+
* Any changes made to this file can be lost when this file is regenerated.
|
|
949
|
+
*/
|
|
950
|
+
|
|
951
|
+
const imageMimeTypes = ["image/png", "image/jpeg"];
|
|
952
|
+
const videoMimeTypes = ["video/mp4"];
|
|
953
|
+
const imageFileTypes = imageMimeTypes.join(",");
|
|
954
|
+
const videoFileTypes = videoMimeTypes.join(",");
|
|
1104
955
|
const allMediaFileTypes = `${imageFileTypes},${videoFileTypes}`;
|
|
1105
956
|
class MediaUploaderComponent {
|
|
1106
957
|
MediaObjectFit = MediaObjectFit;
|
|
1107
|
-
fileInput;
|
|
1108
|
-
srcChange =
|
|
1109
|
-
uploadUrlMap;
|
|
1110
|
-
forceRatio;
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
fileTypeMask = allMediaFileTypes;
|
|
1116
|
-
_uploadType;
|
|
1117
|
-
_src;
|
|
1118
|
-
sanitizer = inject(DomSanitizer);
|
|
1119
|
-
http = inject(HttpClient);
|
|
1120
|
-
cd = inject(ChangeDetectorRef);
|
|
1121
|
-
set src(newSrc) {
|
|
1122
|
-
if (this._src === newSrc)
|
|
1123
|
-
return;
|
|
1124
|
-
this._src = newSrc;
|
|
1125
|
-
}
|
|
1126
|
-
get src() {
|
|
1127
|
-
return this._src;
|
|
1128
|
-
}
|
|
1129
|
-
set uploadType(newUploadType) {
|
|
1130
|
-
switch (newUploadType) {
|
|
958
|
+
fileInput = viewChild.required("fileInput");
|
|
959
|
+
srcChange = output();
|
|
960
|
+
uploadUrlMap = input.required(...(ngDevMode ? [{ debugName: "uploadUrlMap" }] : []));
|
|
961
|
+
forceRatio = input(...(ngDevMode ? [undefined, { debugName: "forceRatio" }] : []));
|
|
962
|
+
src = input(...(ngDevMode ? [undefined, { debugName: "src" }] : []));
|
|
963
|
+
uploadType = input(...(ngDevMode ? [undefined, { debugName: "uploadType" }] : []));
|
|
964
|
+
fileTypeMask = computed(() => {
|
|
965
|
+
switch (this.uploadType()) {
|
|
1131
966
|
case "image":
|
|
1132
|
-
|
|
1133
|
-
this.fileTypeMask = imageFileTypes;
|
|
1134
|
-
break;
|
|
967
|
+
return imageFileTypes;
|
|
1135
968
|
case "video":
|
|
1136
|
-
|
|
1137
|
-
this.fileTypeMask = videoFileTypes;
|
|
1138
|
-
break;
|
|
1139
|
-
case undefined:
|
|
969
|
+
return videoFileTypes;
|
|
1140
970
|
default:
|
|
1141
|
-
|
|
1142
|
-
this.fileTypeMask = allMediaFileTypes;
|
|
1143
|
-
break;
|
|
971
|
+
return allMediaFileTypes;
|
|
1144
972
|
}
|
|
1145
|
-
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
}
|
|
973
|
+
}, ...(ngDevMode ? [{ debugName: "fileTypeMask" }] : []));
|
|
974
|
+
progress = signal(0, ...(ngDevMode ? [{ debugName: "progress" }] : []));
|
|
975
|
+
isUploading = signal(false, ...(ngDevMode ? [{ debugName: "isUploading" }] : []));
|
|
976
|
+
clipStyle = signal(undefined, ...(ngDevMode ? [{ debugName: "clipStyle" }] : []));
|
|
977
|
+
sanitizer = inject(DomSanitizer);
|
|
978
|
+
http = inject(HttpClient);
|
|
1149
979
|
onFileSelect(fileInput) {
|
|
1150
980
|
if (fileInput.files === undefined || fileInput.files === null || fileInput.files.length !== 1)
|
|
1151
981
|
return;
|
|
1152
982
|
const file = fileInput.files[0];
|
|
1153
983
|
let uploadingMediaType;
|
|
1154
|
-
|
|
1155
|
-
|
|
984
|
+
const uploadType = this.uploadType();
|
|
985
|
+
if (uploadType !== undefined && uploadType !== null) {
|
|
986
|
+
uploadingMediaType = uploadType;
|
|
1156
987
|
}
|
|
1157
988
|
else if (imageMimeTypes.includes(file.type)) {
|
|
1158
|
-
uploadingMediaType =
|
|
989
|
+
uploadingMediaType = "image";
|
|
1159
990
|
}
|
|
1160
991
|
else if (videoMimeTypes.includes(file.type)) {
|
|
1161
|
-
uploadingMediaType =
|
|
992
|
+
uploadingMediaType = "video";
|
|
1162
993
|
}
|
|
1163
994
|
else {
|
|
1164
995
|
console.error(`unknown media type ${file.type} (${file.name})`);
|
|
1165
996
|
return;
|
|
1166
997
|
}
|
|
1167
|
-
const uploadUrl = this.uploadUrlMap.get(uploadingMediaType);
|
|
998
|
+
const uploadUrl = this.uploadUrlMap().get(uploadingMediaType);
|
|
1168
999
|
if (uploadUrl === undefined || uploadUrl === null) {
|
|
1169
1000
|
console.error(`upload map doesn't have url for type ${uploadingMediaType}`);
|
|
1170
1001
|
return;
|
|
1171
1002
|
}
|
|
1172
1003
|
const formData = new FormData();
|
|
1173
|
-
formData.append(
|
|
1174
|
-
formData.append(
|
|
1175
|
-
this.progress
|
|
1176
|
-
this.isUploading
|
|
1004
|
+
formData.append("file", file);
|
|
1005
|
+
formData.append("ratio", `${this.forceRatio() ?? 0}`);
|
|
1006
|
+
this.progress.set(0);
|
|
1007
|
+
this.isUploading.set(true);
|
|
1177
1008
|
this.updateClip();
|
|
1178
|
-
const request = new HttpRequest(
|
|
1179
|
-
reportProgress: true
|
|
1009
|
+
const request = new HttpRequest("POST", uploadUrl, formData, {
|
|
1010
|
+
reportProgress: true,
|
|
1180
1011
|
});
|
|
1181
1012
|
this.http
|
|
1182
1013
|
.request(request)
|
|
1183
|
-
.pipe(map(event => this.getEventMessage(event)),
|
|
1014
|
+
.pipe(map((event) => this.getEventMessage(event)),
|
|
1184
1015
|
// tap(message => this.showProgress(message)),
|
|
1185
1016
|
last(), // return last (completed) message to caller
|
|
1186
|
-
catchError(this.handleError(file)))
|
|
1017
|
+
catchError(this.handleError(file)))
|
|
1018
|
+
.subscribe(() => {
|
|
1019
|
+
this.isUploading.set(false);
|
|
1020
|
+
});
|
|
1187
1021
|
}
|
|
1188
1022
|
selectFile(event) {
|
|
1189
|
-
|
|
1190
|
-
if (event.target === this.fileInput.nativeElement)
|
|
1023
|
+
if (event.target === this.fileInput().nativeElement)
|
|
1191
1024
|
return;
|
|
1192
|
-
this.fileInput.nativeElement.click();
|
|
1025
|
+
this.fileInput().nativeElement.click();
|
|
1193
1026
|
}
|
|
1194
1027
|
getEventMessage(event) {
|
|
1195
1028
|
switch (event.type) {
|
|
1196
1029
|
case HttpEventType.Sent:
|
|
1197
1030
|
break;
|
|
1198
1031
|
case HttpEventType.UploadProgress:
|
|
1199
|
-
this.progress
|
|
1032
|
+
this.progress.set(event.total === undefined ? 0.5 : event.loaded / event.total);
|
|
1200
1033
|
this.updateClip();
|
|
1201
1034
|
break;
|
|
1202
1035
|
case HttpEventType.Response:
|
|
1203
1036
|
if (event.body === undefined || event.body === null) {
|
|
1204
|
-
console.error(
|
|
1037
|
+
console.error("media deserialization error. Response body in undefined");
|
|
1205
1038
|
}
|
|
1206
1039
|
else {
|
|
1207
1040
|
// remove this
|
|
@@ -1216,10 +1049,9 @@ class MediaUploaderComponent {
|
|
|
1216
1049
|
default:
|
|
1217
1050
|
break;
|
|
1218
1051
|
}
|
|
1219
|
-
this.cd.detectChanges();
|
|
1220
1052
|
}
|
|
1221
1053
|
updateClip() {
|
|
1222
|
-
this.clipStyle
|
|
1054
|
+
this.clipStyle.set(this.sanitizer.bypassSecurityTrustStyle(`inset(0px 100% 0px 0%)`));
|
|
1223
1055
|
}
|
|
1224
1056
|
handleError(file) {
|
|
1225
1057
|
const func = (error, p2) => {
|
|
@@ -1231,256 +1063,180 @@ class MediaUploaderComponent {
|
|
|
1231
1063
|
return func;
|
|
1232
1064
|
}
|
|
1233
1065
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: MediaUploaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1234
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
1066
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: MediaUploaderComponent, isStandalone: true, selector: "bonc-media-uploader", inputs: { uploadUrlMap: { classPropertyName: "uploadUrlMap", publicName: "uploadUrlMap", isSignal: true, isRequired: true, transformFunction: null }, forceRatio: { classPropertyName: "forceRatio", publicName: "forceRatio", isSignal: true, isRequired: false, transformFunction: null }, src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, uploadType: { classPropertyName: "uploadType", publicName: "uploadType", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { srcChange: "srcChange" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<bon-media [src]=\"src()\" [objectFit]=\"MediaObjectFit.Cover\"></bon-media>\n\n@if (src()?.sources?.length===0) {\n <div>Upload media</div>\n}\n\n<div (click)=\"selectFile($event)\" (keydown.enter)=\"selectFile($event)\" role=\"button\" tabindex=\"0\" class=\"media-container\">\n <input #fileInput [accept]=\"fileTypeMask()\" (change)=\"onFileSelect(fileInput)\" name=\"media\" type=\"file\" />\n @if (isUploading()) {\n <span [style.clip-path]=\"clipStyle()\"\n [style.-webkit-clip-path]=\"clipStyle()\"\n class=\"loader\"></span>\n <span class=\"loader-text\">\n @if (progress() < 1) {\n <span>{{100 * progress() | number: '1.0-0'}}%</span>\n } @else {\n <span>converting</span>\n }\n </span>\n }\n</div>\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: "component", type: MarcyMediaComponent, selector: "bon-media", inputs: ["src", "objectFit"], outputs: ["isLoaded"] }, { kind: "pipe", type: DecimalPipe, name: "number" }] });
|
|
1235
1067
|
}
|
|
1236
1068
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: MediaUploaderComponent, decorators: [{
|
|
1237
1069
|
type: Component,
|
|
1238
|
-
args: [{ selector:
|
|
1239
|
-
}], propDecorators: { fileInput: [{
|
|
1240
|
-
type: ViewChild,
|
|
1241
|
-
args: ['fileInput', { static: true }]
|
|
1242
|
-
}], srcChange: [{
|
|
1243
|
-
type: Output
|
|
1244
|
-
}], uploadUrlMap: [{
|
|
1245
|
-
type: Input,
|
|
1246
|
-
args: [{ required: true }]
|
|
1247
|
-
}], forceRatio: [{
|
|
1248
|
-
type: Input
|
|
1249
|
-
}], src: [{
|
|
1250
|
-
type: Input
|
|
1251
|
-
}], uploadType: [{
|
|
1252
|
-
type: Input
|
|
1253
|
-
}] } });
|
|
1070
|
+
args: [{ selector: "bonc-media-uploader", imports: [DecimalPipe, MarcyMediaComponent], template: "<bon-media [src]=\"src()\" [objectFit]=\"MediaObjectFit.Cover\"></bon-media>\n\n@if (src()?.sources?.length===0) {\n <div>Upload media</div>\n}\n\n<div (click)=\"selectFile($event)\" (keydown.enter)=\"selectFile($event)\" role=\"button\" tabindex=\"0\" class=\"media-container\">\n <input #fileInput [accept]=\"fileTypeMask()\" (change)=\"onFileSelect(fileInput)\" name=\"media\" type=\"file\" />\n @if (isUploading()) {\n <span [style.clip-path]=\"clipStyle()\"\n [style.-webkit-clip-path]=\"clipStyle()\"\n class=\"loader\"></span>\n <span class=\"loader-text\">\n @if (progress() < 1) {\n <span>{{100 * progress() | number: '1.0-0'}}%</span>\n } @else {\n <span>converting</span>\n }\n </span>\n }\n</div>\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"] }]
|
|
1071
|
+
}], propDecorators: { fileInput: [{ type: i0.ViewChild, args: ["fileInput", { isSignal: true }] }], srcChange: [{ type: i0.Output, args: ["srcChange"] }], uploadUrlMap: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadUrlMap", required: true }] }], forceRatio: [{ type: i0.Input, args: [{ isSignal: true, alias: "forceRatio", required: false }] }], src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], uploadType: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadType", required: false }] }] } });
|
|
1254
1072
|
|
|
1255
|
-
|
|
1256
|
-
viewContainerRef = inject(ViewContainerRef);
|
|
1257
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SkeletonEditorAnchorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1258
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.6", type: SkeletonEditorAnchorDirective, isStandalone: true, selector: "[boncSkeletonEditorAnchor]", ngImport: i0 });
|
|
1259
|
-
}
|
|
1260
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SkeletonEditorAnchorDirective, decorators: [{
|
|
1261
|
-
type: Directive,
|
|
1262
|
-
args: [{
|
|
1263
|
-
selector: '[boncSkeletonEditorAnchor]',
|
|
1264
|
-
standalone: true
|
|
1265
|
-
}]
|
|
1266
|
-
}] });
|
|
1073
|
+
const API_BASE_URL = new InjectionToken("ApiBaseUrl");
|
|
1267
1074
|
|
|
1268
|
-
class
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
removed = new EventEmitter();
|
|
1272
|
-
noPresets;
|
|
1273
|
-
locale;
|
|
1274
|
-
device = DeviceType.NotSet;
|
|
1275
|
-
_bone;
|
|
1276
|
-
_storedData = '';
|
|
1277
|
-
_currentPreset;
|
|
1278
|
-
presets;
|
|
1279
|
-
_isDirty = false;
|
|
1280
|
-
_isEditing = false;
|
|
1075
|
+
class AdminDataService {
|
|
1076
|
+
_http = inject(HttpClient);
|
|
1077
|
+
_baseHref = inject(API_BASE_URL);
|
|
1281
1078
|
constructor() {
|
|
1282
|
-
|
|
1283
|
-
if (this.presets === undefined || this.presets === null)
|
|
1284
|
-
throw new Error('presets cannot be undefined in ContentPreset constructor');
|
|
1285
|
-
if (this.presets.length === 0) {
|
|
1286
|
-
this.presets = [
|
|
1287
|
-
{
|
|
1288
|
-
title: 'default',
|
|
1289
|
-
isActive: () => true,
|
|
1290
|
-
transformer: bone => bone,
|
|
1291
|
-
clean: bone => bone,
|
|
1292
|
-
}
|
|
1293
|
-
];
|
|
1294
|
-
}
|
|
1295
|
-
this.noPresets = this.presets.length === 1;
|
|
1079
|
+
console.log(`baseHref: ${this._baseHref}`);
|
|
1296
1080
|
}
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
get isTablet() {
|
|
1301
|
-
return this.device !== undefined && this.device === DeviceType.Tablet;
|
|
1302
|
-
}
|
|
1303
|
-
get isDesktop() {
|
|
1304
|
-
return this.device !== undefined && this.device === DeviceType.Desktop;
|
|
1305
|
-
}
|
|
1306
|
-
get currentPreset() {
|
|
1307
|
-
return this._currentPreset;
|
|
1308
|
-
}
|
|
1309
|
-
get bone() {
|
|
1310
|
-
return this._bone;
|
|
1311
|
-
}
|
|
1312
|
-
set bone(newData) {
|
|
1313
|
-
this._isDirty = false;
|
|
1314
|
-
this._storedData = JSON.stringify(newData);
|
|
1315
|
-
this._bone = JSON.parse(this._storedData);
|
|
1316
|
-
this.updatePresetByData();
|
|
1317
|
-
}
|
|
1318
|
-
get isDirty() {
|
|
1319
|
-
return this._isDirty;
|
|
1320
|
-
}
|
|
1321
|
-
get isEditing() {
|
|
1322
|
-
return this._isEditing;
|
|
1323
|
-
}
|
|
1324
|
-
resetData() {
|
|
1325
|
-
this._isEditing = false;
|
|
1326
|
-
this.bone = JSON.parse(this._storedData);
|
|
1327
|
-
if (this.onReset !== undefined)
|
|
1328
|
-
this.onReset();
|
|
1329
|
-
this.editing.emit(false);
|
|
1330
|
-
}
|
|
1331
|
-
updateDirty() {
|
|
1332
|
-
this._isDirty = JSON.stringify(this._bone) !== this._storedData;
|
|
1081
|
+
getSettingGroups() {
|
|
1082
|
+
const pageOb = this._http.get(`${this._baseHref}api/admin/settings`);
|
|
1083
|
+
return pageOb;
|
|
1333
1084
|
}
|
|
1334
|
-
|
|
1335
|
-
|
|
1085
|
+
getPage(url) {
|
|
1086
|
+
const pageOb = this._http.get(`${this._baseHref}api/admin/pages/${url}`);
|
|
1087
|
+
return pageOb;
|
|
1336
1088
|
}
|
|
1337
|
-
|
|
1338
|
-
this.
|
|
1089
|
+
storePage(page) {
|
|
1090
|
+
const ob = this._http.post(`${this._baseHref}api/admin/pages`, page);
|
|
1091
|
+
return ob;
|
|
1339
1092
|
}
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
this._isDirty = false;
|
|
1344
|
-
this.finishEditing();
|
|
1345
|
-
this._storedData = JSON.stringify(this._bone);
|
|
1346
|
-
const clonedData = JSON.parse(this._storedData);
|
|
1347
|
-
this.saved.emit(clonedData);
|
|
1093
|
+
updateSettings(settings) {
|
|
1094
|
+
const ob = this._http.post(`${this._baseHref}api/admin/settings`, settings);
|
|
1095
|
+
return ob;
|
|
1348
1096
|
}
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1097
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: AdminDataService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1098
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: AdminDataService });
|
|
1099
|
+
}
|
|
1100
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: AdminDataService, decorators: [{
|
|
1101
|
+
type: Injectable
|
|
1102
|
+
}], ctorParameters: () => [] });
|
|
1103
|
+
|
|
1104
|
+
class DataService {
|
|
1105
|
+
http = inject(HttpClient);
|
|
1106
|
+
baseHref = inject(API_BASE_URL);
|
|
1107
|
+
getView(viewCode) {
|
|
1108
|
+
const pageOb = this.getSkeleton(`${this.baseHref}api/views/${viewCode}`);
|
|
1109
|
+
return pageOb;
|
|
1357
1110
|
}
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
this.onFinishEditing();
|
|
1363
|
-
this._isEditing = false;
|
|
1111
|
+
getPage(pageRoute) {
|
|
1112
|
+
const pageUrl = `/${pageRoute}`;
|
|
1113
|
+
const pageOb = this.getSkeleton(`${this.baseHref}api/pages/?url=${encodeURIComponent(pageUrl)}`);
|
|
1114
|
+
return pageOb;
|
|
1364
1115
|
}
|
|
1365
|
-
|
|
1366
|
-
const
|
|
1367
|
-
|
|
1116
|
+
getSettings(ids) {
|
|
1117
|
+
const pageOb = this.http.get(`${this.baseHref}api/settings`, {
|
|
1118
|
+
params: { ids: ids },
|
|
1119
|
+
});
|
|
1120
|
+
return pageOb;
|
|
1368
1121
|
}
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
const
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
updatePresetByData = () => {
|
|
1379
|
-
const countOfActive = this.presets.map(p => p.isActive(this._bone)).filter(p => p).length;
|
|
1380
|
-
if (countOfActive !== 1)
|
|
1381
|
-
throw new Error(`active preset count should be equal 1, but it was: ${countOfActive}. ${this.constructor.name}`);
|
|
1382
|
-
for (let i = 0; this.presets.length; i++) {
|
|
1383
|
-
const preset = this.presets[i];
|
|
1384
|
-
if (preset.isActive(this._bone)) {
|
|
1385
|
-
this.applyPresetAtIndex(i);
|
|
1386
|
-
break;
|
|
1122
|
+
getSkeleton(url) {
|
|
1123
|
+
const skeletonOb = this.http.get(url);
|
|
1124
|
+
const routeDataObs = skeletonOb.pipe(map((x) => {
|
|
1125
|
+
const notEmptyDataRoutes = x.bones
|
|
1126
|
+
.map((b) => ("dataRoute" in b && typeof b.dataRoute === "string" ? b.dataRoute : ""))
|
|
1127
|
+
.filter((x) => x.length > 0);
|
|
1128
|
+
if (notEmptyDataRoutes.length === 0) {
|
|
1129
|
+
const emptyData = {};
|
|
1130
|
+
return { page: of(x), data: of(emptyData) };
|
|
1387
1131
|
}
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1132
|
+
return {
|
|
1133
|
+
page: of(x),
|
|
1134
|
+
data: combineLatest(notEmptyDataRoutes
|
|
1135
|
+
.map((dataRoute) => {
|
|
1136
|
+
const url = `${this.baseHref}api/Pages/Children/?url=${dataRoute}`;
|
|
1137
|
+
return {
|
|
1138
|
+
route: dataRoute,
|
|
1139
|
+
json: this.http.get(url),
|
|
1140
|
+
};
|
|
1141
|
+
})
|
|
1142
|
+
.reduce((prev, curr) => {
|
|
1143
|
+
prev[curr.route] = curr.json;
|
|
1144
|
+
return prev;
|
|
1145
|
+
}, {})),
|
|
1146
|
+
};
|
|
1147
|
+
}), map((x) => combineLatest(x)), mergeMap((res) => merge(res)), map((x) => {
|
|
1148
|
+
for (const bone of x.page.bones) {
|
|
1149
|
+
if (!("dataRoute" in bone) ||
|
|
1150
|
+
typeof bone.dataRoute !== "string" ||
|
|
1151
|
+
bone.dataRoute.length === 0)
|
|
1152
|
+
continue;
|
|
1153
|
+
const data = x.data[bone.dataRoute];
|
|
1154
|
+
if (data === undefined || data === null)
|
|
1155
|
+
throw new Error(`Data ${bone.dataRoute} have not been preloaded`);
|
|
1156
|
+
bone.data = data; // todo: fix
|
|
1157
|
+
}
|
|
1158
|
+
return x.page;
|
|
1159
|
+
}));
|
|
1160
|
+
return routeDataObs;
|
|
1161
|
+
}
|
|
1162
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DataService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1163
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DataService });
|
|
1392
1164
|
}
|
|
1393
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type:
|
|
1394
|
-
type:
|
|
1395
|
-
|
|
1396
|
-
}], ctorParameters: () => [], propDecorators: { locale: [{
|
|
1397
|
-
type: Input,
|
|
1398
|
-
args: [{ required: true }]
|
|
1399
|
-
}], isMobile: [{
|
|
1400
|
-
type: HostBinding,
|
|
1401
|
-
args: ['class.mobile']
|
|
1402
|
-
}], isTablet: [{
|
|
1403
|
-
type: HostBinding,
|
|
1404
|
-
args: ['class.tablet']
|
|
1405
|
-
}], isDesktop: [{
|
|
1406
|
-
type: HostBinding,
|
|
1407
|
-
args: ['class.desktop']
|
|
1408
|
-
}], bone: [{
|
|
1409
|
-
type: Input,
|
|
1410
|
-
args: [{ required: true }]
|
|
1411
|
-
}] } });
|
|
1165
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DataService, decorators: [{
|
|
1166
|
+
type: Injectable
|
|
1167
|
+
}] });
|
|
1412
1168
|
|
|
1413
|
-
class
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
return [];
|
|
1418
|
-
}
|
|
1419
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: UnknownBoneEditorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
1420
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: UnknownBoneEditorComponent, isStandalone: true, selector: "bonc-unknown-bone-editor", usesInheritance: true, ngImport: i0, template: "<p>Unknown Bone Editor | bone type: {{bone.type}}</p>\n<pre>{{bone | json}}</pre>\n", styles: [":host{display:block;background-color:#dc143c}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i2.JsonPipe, name: "json" }] });
|
|
1169
|
+
class SkeletonEditorAnchorDirective {
|
|
1170
|
+
viewContainerRef = inject(ViewContainerRef);
|
|
1171
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SkeletonEditorAnchorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1172
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.6", type: SkeletonEditorAnchorDirective, isStandalone: true, selector: "[boncSkeletonEditorAnchor]", ngImport: i0 });
|
|
1421
1173
|
}
|
|
1422
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type:
|
|
1423
|
-
type:
|
|
1424
|
-
args: [{
|
|
1174
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SkeletonEditorAnchorDirective, decorators: [{
|
|
1175
|
+
type: Directive,
|
|
1176
|
+
args: [{
|
|
1177
|
+
selector: "[boncSkeletonEditorAnchor]",
|
|
1178
|
+
}]
|
|
1425
1179
|
}] });
|
|
1426
1180
|
|
|
1427
|
-
// todo: rename class
|
|
1428
1181
|
class BoneEditorContainerComponent {
|
|
1429
|
-
anchor;
|
|
1430
|
-
removed =
|
|
1431
|
-
saved =
|
|
1432
|
-
editing =
|
|
1182
|
+
anchor = viewChild.required(SkeletonEditorAnchorDirective);
|
|
1183
|
+
removed = output();
|
|
1184
|
+
saved = output();
|
|
1185
|
+
editing = output();
|
|
1433
1186
|
DeviceType = DeviceType;
|
|
1434
1187
|
editor;
|
|
1435
1188
|
themePopupIsShown = false;
|
|
1436
|
-
|
|
1189
|
+
bone = input.required(...(ngDevMode ? [{ debugName: "bone" }] : []));
|
|
1190
|
+
locale = input.required(...(ngDevMode ? [{ debugName: "locale" }] : []));
|
|
1191
|
+
device = input(DeviceType.NotSet, ...(ngDevMode ? [{ debugName: "device" }] : []));
|
|
1192
|
+
map = input.required(...(ngDevMode ? [{ debugName: "map" }] : []));
|
|
1193
|
+
boneEditorRef;
|
|
1437
1194
|
removeSubscription;
|
|
1438
1195
|
saveSubscription;
|
|
1439
1196
|
changedSubscription;
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
this.
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
this.
|
|
1465
|
-
this.
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
this.removeSubscription = this.editor.removed.subscribe(() => {
|
|
1475
|
-
this.removed.next();
|
|
1476
|
-
});
|
|
1477
|
-
this.changedSubscription = this.editor.editing.subscribe((isEditing) => {
|
|
1478
|
-
this.editing.next(isEditing);
|
|
1197
|
+
viewReady = signal(false, ...(ngDevMode ? [{ debugName: "viewReady" }] : []));
|
|
1198
|
+
constructor() {
|
|
1199
|
+
afterNextRender(() => this.viewReady.set(true));
|
|
1200
|
+
effect(() => {
|
|
1201
|
+
if (!this.viewReady()) {
|
|
1202
|
+
return;
|
|
1203
|
+
}
|
|
1204
|
+
const newBone = this.bone();
|
|
1205
|
+
const editorMap = this.map();
|
|
1206
|
+
if (this.removeSubscription) {
|
|
1207
|
+
this.removeSubscription.unsubscribe();
|
|
1208
|
+
this.removeSubscription = undefined;
|
|
1209
|
+
}
|
|
1210
|
+
if (this.saveSubscription) {
|
|
1211
|
+
this.saveSubscription.unsubscribe();
|
|
1212
|
+
this.saveSubscription = undefined;
|
|
1213
|
+
}
|
|
1214
|
+
if (this.changedSubscription) {
|
|
1215
|
+
this.changedSubscription.unsubscribe();
|
|
1216
|
+
this.changedSubscription = undefined;
|
|
1217
|
+
}
|
|
1218
|
+
const viewContainerRef = this.anchor().viewContainerRef;
|
|
1219
|
+
viewContainerRef.clear();
|
|
1220
|
+
const componentType = editorMap.get(newBone.type) ?? UnknownBoneEditorComponent;
|
|
1221
|
+
this.boneEditorRef = viewContainerRef.createComponent(componentType);
|
|
1222
|
+
this.editor = this.boneEditorRef.instance;
|
|
1223
|
+
this.boneEditorRef.setInput("boneEtalon", newBone);
|
|
1224
|
+
this.boneEditorRef.setInput("locale", this.locale());
|
|
1225
|
+
this.boneEditorRef.setInput("device", this.device());
|
|
1226
|
+
this.removeSubscription = this.editor.removed.subscribe(() => {
|
|
1227
|
+
this.removed.emit();
|
|
1228
|
+
});
|
|
1229
|
+
this.changedSubscription = this.editor.editing.subscribe((isEditing) => this.editing.emit(isEditing));
|
|
1230
|
+
this.saveSubscription = this.editor.saved.subscribe((newBoneValue) => this.saved.emit(newBoneValue));
|
|
1479
1231
|
});
|
|
1480
|
-
|
|
1481
|
-
this.
|
|
1232
|
+
effect(() => {
|
|
1233
|
+
const locale = this.locale();
|
|
1234
|
+
const device = this.device();
|
|
1235
|
+
if (this.boneEditorRef) {
|
|
1236
|
+
this.boneEditorRef.setInput("locale", locale);
|
|
1237
|
+
this.boneEditorRef.setInput("device", device);
|
|
1238
|
+
}
|
|
1482
1239
|
});
|
|
1483
|
-
this.ngOnChanges();
|
|
1484
1240
|
}
|
|
1485
1241
|
nextPreset = () => {
|
|
1486
1242
|
if (this.editor === undefined || this.editor === null)
|
|
@@ -1500,9 +1256,13 @@ class BoneEditorContainerComponent {
|
|
|
1500
1256
|
// this.editor.bone.visibility = setOrRemoveFlag(this.editor.bone.visibility, DeviceVisibility.Mobile, !disabled);
|
|
1501
1257
|
// this.editor.updateDirty();
|
|
1502
1258
|
// }
|
|
1259
|
+
// todo: use this feature
|
|
1260
|
+
// its not working now
|
|
1503
1261
|
get disabled() {
|
|
1504
|
-
if (this.editor === undefined || this.editor === null)
|
|
1505
|
-
|
|
1262
|
+
if (this.editor === undefined || this.editor === null) {
|
|
1263
|
+
console.warn("editor should have been set before disabled is called");
|
|
1264
|
+
return false;
|
|
1265
|
+
}
|
|
1506
1266
|
return false;
|
|
1507
1267
|
// todo: add or remove visibility feature
|
|
1508
1268
|
// const visibility = this.editor.bone.visibility;
|
|
@@ -1515,59 +1275,51 @@ class BoneEditorContainerComponent {
|
|
|
1515
1275
|
// return true;
|
|
1516
1276
|
}
|
|
1517
1277
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: BoneEditorContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1518
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
1278
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: BoneEditorContainerComponent, isStandalone: true, selector: "bonc-bone-editor-container", inputs: { bone: { classPropertyName: "bone", publicName: "bone", isSignal: true, isRequired: true, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: true, transformFunction: null }, device: { classPropertyName: "device", publicName: "device", isSignal: true, isRequired: false, transformFunction: null }, map: { classPropertyName: "map", publicName: "map", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { removed: "removed", saved: "saved", editing: "editing" }, viewQueries: [{ propertyName: "anchor", first: true, predicate: SkeletonEditorAnchorDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (editor) {\n <div class=\"left bar\" [class.inactive]=\"editor.noPresets()\">\n <!-- <a *ngFor=\"let control of editor.controls\" (click)=\"control.activate()\">{{control.label}}</a> -->\n <!-- <a (click)=\"setDisabled(!disabled)\" class=\"disabled\">block {{disabled ? 'disabled' : 'enabled'}} ({{editor.bone.visibility}})</a> -->\n @if (editor.currentPreset() && !editor.noPresets()) {\n <a (click)=\"nextPreset()\" class=\"preset\">style:<br />{{editor.currentPreset()?.title}}</a>\n }\n </div>\n}@else {\n EDITOR COMPONENTS IS NOT DEFINED\n}\n\n<div class=\"editor-container\"\n [class.disabled]=\"disabled\"\n [style.width]=\"\n device() === DeviceType.Desktop ? '75vw'\n : device() === DeviceType.Tablet ? '55vw'\n : device() === DeviceType.Mobile ? '35vw'\n : '75vw' \">\n <ng-template boncSkeletonEditorAnchor>\n </ng-template>\n</div>\n\n@if (editor) {\n <div [class.active]=\"editor.isEditing() || editor.isDirty()\" class=\"right bar\">\n <!-- <a *ngIf=\"!editor.isEditing\" (click)=\"editor.remove()\" class=\"delete\">!!! remove</a> -->\n @if (editor.isDirty()) {\n <a (click)=\"editor.resetData()\" class=\"reset\">reset</a>\n <a (click)=\"editor.save()\" class=\"save\">apply</a>\n } @else if (editor.isEditing()) {\n <a (click)=\"editor.finishEditing()\" class=\"close\">close</a>\n }\n </div>\n}\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: SkeletonEditorAnchorDirective, selector: "[boncSkeletonEditorAnchor]" }] });
|
|
1519
1279
|
}
|
|
1520
1280
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: BoneEditorContainerComponent, decorators: [{
|
|
1521
1281
|
type: Component,
|
|
1522
|
-
args: [{ selector:
|
|
1523
|
-
}], propDecorators: { anchor: [{
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
type: Input,
|
|
1534
|
-
args: [{ required: true }]
|
|
1535
|
-
}], device: [{
|
|
1536
|
-
type: Input
|
|
1537
|
-
}], map: [{
|
|
1538
|
-
type: Input,
|
|
1539
|
-
args: [{ required: true }]
|
|
1540
|
-
}], bone: [{
|
|
1541
|
-
type: Input,
|
|
1542
|
-
args: [{ required: true }]
|
|
1543
|
-
}] } });
|
|
1282
|
+
args: [{ selector: "bonc-bone-editor-container", imports: [SkeletonEditorAnchorDirective], template: "@if (editor) {\n <div class=\"left bar\" [class.inactive]=\"editor.noPresets()\">\n <!-- <a *ngFor=\"let control of editor.controls\" (click)=\"control.activate()\">{{control.label}}</a> -->\n <!-- <a (click)=\"setDisabled(!disabled)\" class=\"disabled\">block {{disabled ? 'disabled' : 'enabled'}} ({{editor.bone.visibility}})</a> -->\n @if (editor.currentPreset() && !editor.noPresets()) {\n <a (click)=\"nextPreset()\" class=\"preset\">style:<br />{{editor.currentPreset()?.title}}</a>\n }\n </div>\n}@else {\n EDITOR COMPONENTS IS NOT DEFINED\n}\n\n<div class=\"editor-container\"\n [class.disabled]=\"disabled\"\n [style.width]=\"\n device() === DeviceType.Desktop ? '75vw'\n : device() === DeviceType.Tablet ? '55vw'\n : device() === DeviceType.Mobile ? '35vw'\n : '75vw' \">\n <ng-template boncSkeletonEditorAnchor>\n </ng-template>\n</div>\n\n@if (editor) {\n <div [class.active]=\"editor.isEditing() || editor.isDirty()\" class=\"right bar\">\n <!-- <a *ngIf=\"!editor.isEditing\" (click)=\"editor.remove()\" class=\"delete\">!!! remove</a> -->\n @if (editor.isDirty()) {\n <a (click)=\"editor.resetData()\" class=\"reset\">reset</a>\n <a (click)=\"editor.save()\" class=\"save\">apply</a>\n } @else if (editor.isEditing()) {\n <a (click)=\"editor.finishEditing()\" class=\"close\">close</a>\n }\n </div>\n}\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"] }]
|
|
1283
|
+
}], ctorParameters: () => [], propDecorators: { anchor: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SkeletonEditorAnchorDirective), { isSignal: true }] }], removed: [{ type: i0.Output, args: ["removed"] }], saved: [{ type: i0.Output, args: ["saved"] }], editing: [{ type: i0.Output, args: ["editing"] }], bone: [{ type: i0.Input, args: [{ isSignal: true, alias: "bone", required: true }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: true }] }], device: [{ type: i0.Input, args: [{ isSignal: true, alias: "device", required: false }] }], map: [{ type: i0.Input, args: [{ isSignal: true, alias: "map", required: true }] }] } });
|
|
1284
|
+
|
|
1285
|
+
function createPreset(params) {
|
|
1286
|
+
return {
|
|
1287
|
+
title: params.title,
|
|
1288
|
+
isActive: (x) => x.style === params.style,
|
|
1289
|
+
transformer: (bone) => (bone.style = params.style),
|
|
1290
|
+
clean: (bone) => (bone.style = params.style),
|
|
1291
|
+
};
|
|
1292
|
+
}
|
|
1544
1293
|
|
|
1545
|
-
// todo: rename class
|
|
1546
1294
|
class SkeletonEditorComponent {
|
|
1547
|
-
boneEditorContainerList;
|
|
1548
|
-
locale;
|
|
1549
|
-
device = DeviceType.NotSet;
|
|
1295
|
+
boneEditorContainerList = viewChildren("boneEditorContainer", ...(ngDevMode ? [{ debugName: "boneEditorContainerList" }] : []));
|
|
1296
|
+
locale = input.required(...(ngDevMode ? [{ debugName: "locale" }] : []));
|
|
1297
|
+
device = input(DeviceType.NotSet, ...(ngDevMode ? [{ debugName: "device" }] : []));
|
|
1298
|
+
map = input.required(...(ngDevMode ? [{ debugName: "map" }] : []));
|
|
1299
|
+
templates = input.required(...(ngDevMode ? [{ debugName: "templates" }] : []));
|
|
1550
1300
|
templatesAreShown = [];
|
|
1551
1301
|
editable = inject((EditableDirective), { host: true });
|
|
1552
|
-
|
|
1302
|
+
constructor() {
|
|
1303
|
+
effect(() => {
|
|
1304
|
+
this.map();
|
|
1305
|
+
this.templates();
|
|
1306
|
+
this.templatesAreShown.splice(0, this.templatesAreShown.length);
|
|
1307
|
+
const bones = this.editable.value ?? [];
|
|
1308
|
+
if (bones === undefined) {
|
|
1309
|
+
return;
|
|
1310
|
+
}
|
|
1311
|
+
bones.forEach(() => this.templatesAreShown.push(false));
|
|
1312
|
+
this.templatesAreShown.push(false);
|
|
1313
|
+
});
|
|
1553
1314
|
this.editable.externalSaveCall.subscribe(() => {
|
|
1554
|
-
this.boneEditorContainerList.forEach(editorContainer => editorContainer.editor?.save());
|
|
1315
|
+
this.boneEditorContainerList().forEach((editorContainer) => editorContainer.editor?.save());
|
|
1555
1316
|
this.editable.save();
|
|
1556
1317
|
});
|
|
1557
1318
|
this.editable.canceled.subscribe(() => {
|
|
1558
|
-
this.boneEditorContainerList.forEach(editorContainer => editorContainer.editor?.resetData());
|
|
1319
|
+
this.boneEditorContainerList().forEach((editorContainer) => editorContainer.editor?.resetData());
|
|
1559
1320
|
this.editable.save();
|
|
1560
1321
|
});
|
|
1561
1322
|
}
|
|
1562
|
-
map;
|
|
1563
|
-
ngOnChanges() {
|
|
1564
|
-
this.templatesAreShown.splice(0, this.templatesAreShown.length);
|
|
1565
|
-
if (this.bones === undefined)
|
|
1566
|
-
return;
|
|
1567
|
-
this.bones.forEach(() => this.templatesAreShown.push(false));
|
|
1568
|
-
this.templatesAreShown.push(false);
|
|
1569
|
-
}
|
|
1570
|
-
templates;
|
|
1571
1323
|
get bones() {
|
|
1572
1324
|
return this.editable?.value ?? [];
|
|
1573
1325
|
}
|
|
@@ -1575,11 +1327,9 @@ class SkeletonEditorComponent {
|
|
|
1575
1327
|
if (isEditing)
|
|
1576
1328
|
this.editable.startEditing();
|
|
1577
1329
|
else {
|
|
1578
|
-
const allClosed = this.boneEditorContainerList
|
|
1579
|
-
.filter(x => x.editor !== undefined && x.editor.isEditing)
|
|
1580
|
-
.length === 0;
|
|
1330
|
+
const allClosed = this.boneEditorContainerList().filter((x) => x.editor?.isEditing).length === 0;
|
|
1581
1331
|
this.editable.updateDirty();
|
|
1582
|
-
if (!this.editable.isDirty && allClosed)
|
|
1332
|
+
if (!this.editable.isDirty() && allClosed)
|
|
1583
1333
|
this.editable.close();
|
|
1584
1334
|
}
|
|
1585
1335
|
}
|
|
@@ -1592,10 +1342,10 @@ class SkeletonEditorComponent {
|
|
|
1592
1342
|
removeBone(boneIndex) {
|
|
1593
1343
|
if (this.bones === undefined || this.bones === null)
|
|
1594
1344
|
return;
|
|
1595
|
-
if (!confirm(
|
|
1345
|
+
if (!confirm("Вы уверены, что хотите удалить компонент?"))
|
|
1596
1346
|
return;
|
|
1597
1347
|
this.bones.splice(boneIndex, 1);
|
|
1598
|
-
if (!this.editable.inEditMode)
|
|
1348
|
+
if (!this.editable.inEditMode())
|
|
1599
1349
|
this.editable.startEditing();
|
|
1600
1350
|
this.editable.save();
|
|
1601
1351
|
}
|
|
@@ -1621,35 +1371,12 @@ class SkeletonEditorComponent {
|
|
|
1621
1371
|
this.bones[index2] = tempBone;
|
|
1622
1372
|
}
|
|
1623
1373
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SkeletonEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1624
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
1374
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: SkeletonEditorComponent, isStandalone: true, selector: "bonc-skeleton-editor", inputs: { locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: true, transformFunction: null }, device: { classPropertyName: "device", publicName: "device", isSignal: true, isRequired: false, transformFunction: null }, map: { classPropertyName: "map", publicName: "map", isSignal: true, isRequired: true, transformFunction: null }, templates: { classPropertyName: "templates", publicName: "templates", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "boneEditorContainerList", predicate: ["boneEditorContainer"], descendants: true, isSignal: true }], hostDirectives: [{ directive: EditableDirective }], ngImport: i0, template: "<ng-template #controls let-index='index'>\n <div [class.appearable]=\"index > 0 && index < bones.length\" class=\"controls\">\n @if (index < bones.length) {\n <div class=\"up-down\">\n @if (index > 0) {\n <a (click)=\"moveDown(index - 1)\" class=\"down\">move down</a>\n <a (click)=\"moveUp(index)\" class=\"up\">move up</a>\n }\n </div>\n }\n <a (click)=\"templatesAreShown[index] = true\" class=\"add\">create</a>\n @if (index < bones.length) {\n <a (click)=\"removeBone(index)\" class=\"remove\">remove</a>\n }\n </div>\n\n @if (templatesAreShown[index]) {\n <div class=\"templates\">\n @for (template of templates(); track template.title) {\n <a (click)=\"templatesAreShown[index] = false; createBone(index,template);\">{{template.title}}</a>\n }\n <a (click)=\"templatesAreShown[index] = false\">Close</a>\n </div>\n }\n</ng-template>\n\n<!-- todo: add trackby -->\n@for (bone of bones; track $index) {\n <ng-container>\n <ng-container *ngTemplateOutlet=\"controls; context: {index: $index}\"></ng-container>\n </ng-container>\n\n <bonc-bone-editor-container #boneEditorContainer\n [map]=\"map()\"\n [bone]=\"bone\"\n [locale]=\"locale()\"\n [device]=\"device()\"\n (removed)=\"removeBone($index)\"\n (editing)=\"boneEditHandler($event)\"\n (saved)=\"boneChangeHandler($index, $event)\">\n </bonc-bone-editor-container>\n}\n\n<ng-container *ngTemplateOutlet=\"controls; context: {index: bones.length}\"></ng-container>\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 *{opacity:1}.controls.appearable:hover{background-color:#222}.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: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: BoneEditorContainerComponent, selector: "bonc-bone-editor-container", inputs: ["bone", "locale", "device", "map"], outputs: ["removed", "saved", "editing"] }] });
|
|
1625
1375
|
}
|
|
1626
1376
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SkeletonEditorComponent, decorators: [{
|
|
1627
1377
|
type: Component,
|
|
1628
|
-
args: [{ selector:
|
|
1629
|
-
}], propDecorators: { boneEditorContainerList: [{
|
|
1630
|
-
type: ViewChildren,
|
|
1631
|
-
args: ['boneEditorContainer']
|
|
1632
|
-
}], locale: [{
|
|
1633
|
-
type: Input,
|
|
1634
|
-
args: [{ required: true }]
|
|
1635
|
-
}], device: [{
|
|
1636
|
-
type: Input
|
|
1637
|
-
}], map: [{
|
|
1638
|
-
type: Input,
|
|
1639
|
-
args: [{ required: true }]
|
|
1640
|
-
}], templates: [{
|
|
1641
|
-
type: Input,
|
|
1642
|
-
args: [{ required: true }]
|
|
1643
|
-
}] } });
|
|
1644
|
-
|
|
1645
|
-
function createPreset(params) {
|
|
1646
|
-
return {
|
|
1647
|
-
title: params.title,
|
|
1648
|
-
isActive: x => x.style === params.style,
|
|
1649
|
-
transformer: bone => bone.style = params.style,
|
|
1650
|
-
clean: bone => bone.style = params.style,
|
|
1651
|
-
};
|
|
1652
|
-
}
|
|
1378
|
+
args: [{ selector: "bonc-skeleton-editor", imports: [NgTemplateOutlet, BoneEditorContainerComponent], hostDirectives: [EditableDirective], template: "<ng-template #controls let-index='index'>\n <div [class.appearable]=\"index > 0 && index < bones.length\" class=\"controls\">\n @if (index < bones.length) {\n <div class=\"up-down\">\n @if (index > 0) {\n <a (click)=\"moveDown(index - 1)\" class=\"down\">move down</a>\n <a (click)=\"moveUp(index)\" class=\"up\">move up</a>\n }\n </div>\n }\n <a (click)=\"templatesAreShown[index] = true\" class=\"add\">create</a>\n @if (index < bones.length) {\n <a (click)=\"removeBone(index)\" class=\"remove\">remove</a>\n }\n </div>\n\n @if (templatesAreShown[index]) {\n <div class=\"templates\">\n @for (template of templates(); track template.title) {\n <a (click)=\"templatesAreShown[index] = false; createBone(index,template);\">{{template.title}}</a>\n }\n <a (click)=\"templatesAreShown[index] = false\">Close</a>\n </div>\n }\n</ng-template>\n\n<!-- todo: add trackby -->\n@for (bone of bones; track $index) {\n <ng-container>\n <ng-container *ngTemplateOutlet=\"controls; context: {index: $index}\"></ng-container>\n </ng-container>\n\n <bonc-bone-editor-container #boneEditorContainer\n [map]=\"map()\"\n [bone]=\"bone\"\n [locale]=\"locale()\"\n [device]=\"device()\"\n (removed)=\"removeBone($index)\"\n (editing)=\"boneEditHandler($event)\"\n (saved)=\"boneChangeHandler($index, $event)\">\n </bonc-bone-editor-container>\n}\n\n<ng-container *ngTemplateOutlet=\"controls; context: {index: bones.length}\"></ng-container>\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 *{opacity:1}.controls.appearable:hover{background-color:#222}.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"] }]
|
|
1379
|
+
}], ctorParameters: () => [], propDecorators: { boneEditorContainerList: [{ type: i0.ViewChildren, args: ["boneEditorContainer", { isSignal: true }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: true }] }], device: [{ type: i0.Input, args: [{ isSignal: true, alias: "device", required: false }] }], map: [{ type: i0.Input, args: [{ isSignal: true, alias: "map", required: true }] }], templates: [{ type: i0.Input, args: [{ isSignal: true, alias: "templates", required: true }] }] } });
|
|
1653
1380
|
|
|
1654
1381
|
/**
|
|
1655
1382
|
* Generated bundle index. Do not edit.
|