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