@wertzui/ngx-restworld-client 2.0.0 → 3.1.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.
- package/{esm2015/lib/constants/link-names.js → esm2020/lib/constants/link-names.mjs} +0 -0
- package/{esm2015/lib/models/api-url.js → esm2020/lib/models/api-url.mjs} +0 -0
- package/{esm2015/lib/models/client-settings.js → esm2020/lib/models/client-settings.mjs} +1 -1
- package/{esm2015/lib/models/problem-details.js → esm2020/lib/models/problem-details.mjs} +0 -0
- package/{esm2015/lib/models/restworld-options.js → esm2020/lib/models/restworld-options.mjs} +0 -0
- package/{esm2015/lib/pipes/as.pipe.js → esm2020/lib/pipes/as.pipe.mjs} +4 -4
- package/{esm2015/lib/pipes/safe-url.pipe.js → esm2020/lib/pipes/safe-url.pipe.mjs} +4 -4
- package/esm2020/lib/restworld-client.module.mjs +200 -0
- package/{esm2015/lib/services/avatar-generator.js → esm2020/lib/services/avatar-generator.mjs} +4 -4
- package/{esm2015/lib/services/form.service.js → esm2020/lib/services/form.service.mjs} +4 -4
- package/esm2020/lib/services/restworld-client-collection.mjs +39 -0
- package/esm2020/lib/services/restworld-client.mjs +165 -0
- package/esm2020/lib/services/settings.service.mjs +39 -0
- package/esm2020/lib/views/restworld-edit-form/restworld-edit-form.component.mjs +230 -0
- package/esm2020/lib/views/restworld-edit-view/restworld-edit-view.component.mjs +313 -0
- package/esm2020/lib/views/restworld-file-view/restworld-file-view.component.mjs +57 -0
- package/esm2020/lib/views/restworld-image-view/restworld-image-view.component.mjs +100 -0
- package/esm2020/lib/views/restworld-list-view/restworld-list-view.component.mjs +341 -0
- package/{esm2015/public-api.js → esm2020/public-api.mjs} +0 -0
- package/{esm2015/wertzui-ngx-restworld-client.js → esm2020/wertzui-ngx-restworld-client.mjs} +0 -0
- package/fesm2015/wertzui-ngx-restworld-client.mjs +1709 -0
- package/fesm2015/wertzui-ngx-restworld-client.mjs.map +1 -0
- package/fesm2020/wertzui-ngx-restworld-client.mjs +1649 -0
- package/fesm2020/wertzui-ngx-restworld-client.mjs.map +1 -0
- package/lib/models/client-settings.d.ts +4 -1
- package/package.json +42 -31
- package/bundles/wertzui-ngx-restworld-client.umd.js +0 -2477
- package/bundles/wertzui-ngx-restworld-client.umd.js.map +0 -1
- package/esm2015/lib/restworld-client.module.js +0 -201
- package/esm2015/lib/services/restworld-client-collection.js +0 -42
- package/esm2015/lib/services/restworld-client.js +0 -183
- package/esm2015/lib/services/settings.service.js +0 -47
- package/esm2015/lib/views/restworld-edit-form/restworld-edit-form.component.js +0 -238
- package/esm2015/lib/views/restworld-edit-view/restworld-edit-view.component.js +0 -335
- package/esm2015/lib/views/restworld-file-view/restworld-file-view.component.js +0 -63
- package/esm2015/lib/views/restworld-image-view/restworld-image-view.component.js +0 -107
- package/esm2015/lib/views/restworld-list-view/restworld-list-view.component.js +0 -353
- package/fesm2015/wertzui-ngx-restworld-client.js +0 -1728
- package/fesm2015/wertzui-ngx-restworld-client.js.map +0 -1
|
@@ -0,0 +1,1709 @@
|
|
|
1
|
+
import * as _ from 'lodash';
|
|
2
|
+
import * as i1$1 from '@wertzui/ngx-hal-client';
|
|
3
|
+
import { Resource, PropertyType, PagedListResource, Link, FormsResource, Template } from '@wertzui/ngx-hal-client';
|
|
4
|
+
import * as i0 from '@angular/core';
|
|
5
|
+
import { Pipe, Injectable, Input, forwardRef, Component, ViewChildren, ContentChild, APP_INITIALIZER, NgModule } from '@angular/core';
|
|
6
|
+
import * as i1 from '@angular/platform-browser';
|
|
7
|
+
import * as i14 from '@angular/forms';
|
|
8
|
+
import { FormGroup, FormArray, FormControl, Validators, NG_VALUE_ACCESSOR, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
9
|
+
import { __awaiter } from 'tslib';
|
|
10
|
+
import * as i1$2 from '@angular/common/http';
|
|
11
|
+
import { HttpHeaders, HttpClient } from '@angular/common/http';
|
|
12
|
+
import * as i2$1 from 'primeng/api';
|
|
13
|
+
import { FilterMatchMode, ConfirmationService, MessageService } from 'primeng/api';
|
|
14
|
+
import * as i4$1 from 'primeng/dropdown';
|
|
15
|
+
import { DropdownModule } from 'primeng/dropdown';
|
|
16
|
+
import * as i5$1 from 'primeng/multiselect';
|
|
17
|
+
import { MultiSelectModule } from 'primeng/multiselect';
|
|
18
|
+
import * as i6 from 'primeng/calendar';
|
|
19
|
+
import { CalendarModule } from 'primeng/calendar';
|
|
20
|
+
import * as i7$1 from 'primeng/inputnumber';
|
|
21
|
+
import { InputNumberModule } from 'primeng/inputnumber';
|
|
22
|
+
import * as i8 from 'primeng/checkbox';
|
|
23
|
+
import { CheckboxModule } from 'primeng/checkbox';
|
|
24
|
+
import * as i9$1 from 'primeng/tristatecheckbox';
|
|
25
|
+
import { TriStateCheckboxModule } from 'primeng/tristatecheckbox';
|
|
26
|
+
import * as i2 from 'primeng/fileupload';
|
|
27
|
+
import { FileUpload, FileUploadModule } from 'primeng/fileupload';
|
|
28
|
+
import * as i1$3 from 'primeng/button';
|
|
29
|
+
import { ButtonModule } from 'primeng/button';
|
|
30
|
+
import * as i3 from 'primeng/dialog';
|
|
31
|
+
import { DialogModule } from 'primeng/dialog';
|
|
32
|
+
import * as i4 from 'ngx-image-cropper';
|
|
33
|
+
import { ImageCropperModule } from 'ngx-image-cropper';
|
|
34
|
+
import * as i5 from 'primeng/colorpicker';
|
|
35
|
+
import { ColorPickerModule } from 'primeng/colorpicker';
|
|
36
|
+
import * as i3$1 from '@angular/common';
|
|
37
|
+
import { CommonModule } from '@angular/common';
|
|
38
|
+
import * as i7 from 'primeng/tooltip';
|
|
39
|
+
import { TooltipModule } from 'primeng/tooltip';
|
|
40
|
+
import * as i9 from 'primeng/inputtext';
|
|
41
|
+
import { InputTextModule } from 'primeng/inputtext';
|
|
42
|
+
import * as i10 from 'primeng/ripple';
|
|
43
|
+
import { RippleModule } from 'primeng/ripple';
|
|
44
|
+
import * as i12 from 'ngx-valdemort';
|
|
45
|
+
import { ValdemortModule } from 'ngx-valdemort';
|
|
46
|
+
import * as i17 from '@angular/cdk/drag-drop';
|
|
47
|
+
import { DragDropModule } from '@angular/cdk/drag-drop';
|
|
48
|
+
import * as i4$2 from '@angular/router';
|
|
49
|
+
import { RouterModule } from '@angular/router';
|
|
50
|
+
import * as i7$2 from 'primeng/tabview';
|
|
51
|
+
import { TabViewModule } from 'primeng/tabview';
|
|
52
|
+
import * as i8$1 from 'primeng/skeleton';
|
|
53
|
+
import { SkeletonModule } from 'primeng/skeleton';
|
|
54
|
+
import * as i10$1 from 'primeng/progressspinner';
|
|
55
|
+
import { ProgressSpinnerModule } from 'primeng/progressspinner';
|
|
56
|
+
import * as i11 from 'primeng/toast';
|
|
57
|
+
import { ToastModule } from 'primeng/toast';
|
|
58
|
+
import * as i12$1 from 'primeng/confirmdialog';
|
|
59
|
+
import { ConfirmDialogModule } from 'primeng/confirmdialog';
|
|
60
|
+
import * as i4$3 from 'primeng/table';
|
|
61
|
+
import { TableModule } from 'primeng/table';
|
|
62
|
+
import * as i5$2 from 'primeng/avatar';
|
|
63
|
+
import { AvatarModule } from 'primeng/avatar';
|
|
64
|
+
import { ScrollingModule } from '@angular/cdk/scrolling';
|
|
65
|
+
import { MessagesModule } from 'primeng/messages';
|
|
66
|
+
import { PanelModule } from 'primeng/panel';
|
|
67
|
+
|
|
68
|
+
var LinkNames;
|
|
69
|
+
(function (LinkNames) {
|
|
70
|
+
LinkNames["get"] = "Get";
|
|
71
|
+
LinkNames["getList"] = "GetList";
|
|
72
|
+
LinkNames["post"] = "Post";
|
|
73
|
+
LinkNames["put"] = "Put";
|
|
74
|
+
LinkNames["delete"] = "Delete";
|
|
75
|
+
LinkNames["new"] = "New";
|
|
76
|
+
})(LinkNames || (LinkNames = {}));
|
|
77
|
+
|
|
78
|
+
class ProblemDetails extends Resource {
|
|
79
|
+
static isProblemDetails(resource) {
|
|
80
|
+
return resource instanceof ProblemDetails;
|
|
81
|
+
}
|
|
82
|
+
static containsProblemDetailsInformation(resource) {
|
|
83
|
+
return resource && (resource instanceof ProblemDetails || (resource instanceof Resource && 'status' in resource && _.isNumber(resource['status']) && resource['status'] >= 100 && resource['status'] < 600));
|
|
84
|
+
}
|
|
85
|
+
static fromResource(resource) {
|
|
86
|
+
if (!ProblemDetails.containsProblemDetailsInformation(resource))
|
|
87
|
+
throw new Error(`The resource ${resource} does not have problem details.`);
|
|
88
|
+
return Object.assign(new ProblemDetails(), resource);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
class RESTworldOptions {
|
|
93
|
+
constructor(BaseUrl, Version) {
|
|
94
|
+
this.BaseUrl = BaseUrl;
|
|
95
|
+
this.Version = Version;
|
|
96
|
+
if (!BaseUrl.endsWith('/'))
|
|
97
|
+
throw new Error(`The provided BaseUrl '${BaseUrl}' does not end with a slash '/'.`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
class SafeUrlPipe {
|
|
102
|
+
constructor(_domSanitizer) {
|
|
103
|
+
this._domSanitizer = _domSanitizer;
|
|
104
|
+
}
|
|
105
|
+
transform(url) {
|
|
106
|
+
if (_.isString(url))
|
|
107
|
+
throw new Error(`The given url '${url}' is not a string.`);
|
|
108
|
+
return this._domSanitizer.bypassSecurityTrustResourceUrl(url);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
SafeUrlPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: SafeUrlPipe, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
|
|
112
|
+
SafeUrlPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: SafeUrlPipe, name: "safeUrl" });
|
|
113
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: SafeUrlPipe, decorators: [{
|
|
114
|
+
type: Pipe,
|
|
115
|
+
args: [{
|
|
116
|
+
name: 'safeUrl'
|
|
117
|
+
}]
|
|
118
|
+
}], ctorParameters: function () { return [{ type: i1.DomSanitizer }]; } });
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Cast super type into type using generics
|
|
122
|
+
* Return Type obtained by optional @param type OR assignment type.
|
|
123
|
+
*/
|
|
124
|
+
class AsPipe {
|
|
125
|
+
/**
|
|
126
|
+
* Cast (S: SuperType) into (T: Type) using @Generics.
|
|
127
|
+
* @param value (S: SuperType) obtained from input type.
|
|
128
|
+
* @optional @param type (T CastingType)
|
|
129
|
+
* type?: { new (): T }
|
|
130
|
+
* type?: new () => T
|
|
131
|
+
*/
|
|
132
|
+
transform(value, type) {
|
|
133
|
+
return value;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
AsPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: AsPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
137
|
+
AsPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: AsPipe, name: "as" });
|
|
138
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: AsPipe, decorators: [{
|
|
139
|
+
type: Pipe,
|
|
140
|
+
args: [{ name: 'as' }]
|
|
141
|
+
}] });
|
|
142
|
+
|
|
143
|
+
class AvatarGenerator {
|
|
144
|
+
constructor() {
|
|
145
|
+
this.getImageOverride = () => '';
|
|
146
|
+
}
|
|
147
|
+
getImage(nameOrEmail) {
|
|
148
|
+
let uri = AvatarGenerator._imageCache.get(nameOrEmail);
|
|
149
|
+
if (!uri) {
|
|
150
|
+
uri = this.getImageOverride(nameOrEmail);
|
|
151
|
+
AvatarGenerator._imageCache.set(nameOrEmail, uri);
|
|
152
|
+
}
|
|
153
|
+
return uri;
|
|
154
|
+
}
|
|
155
|
+
getLabel(nameOrEmail) {
|
|
156
|
+
if (!nameOrEmail)
|
|
157
|
+
return '';
|
|
158
|
+
if (this.getImage(nameOrEmail))
|
|
159
|
+
return '';
|
|
160
|
+
const name = AvatarGenerator.getLocalPartOfEmailAddress(nameOrEmail);
|
|
161
|
+
const initials = AvatarGenerator.getTwoUppercaseLettersFromName(name);
|
|
162
|
+
return initials;
|
|
163
|
+
}
|
|
164
|
+
getStyle(nameOrEmail) {
|
|
165
|
+
if (this.getImage(nameOrEmail))
|
|
166
|
+
return '';
|
|
167
|
+
const foregroundColor = '#ffffff';
|
|
168
|
+
const backgroundColor = AvatarGenerator.getBackgroundColor(nameOrEmail);
|
|
169
|
+
const style = {
|
|
170
|
+
'background-color': backgroundColor,
|
|
171
|
+
color: foregroundColor,
|
|
172
|
+
};
|
|
173
|
+
return style;
|
|
174
|
+
}
|
|
175
|
+
static getLocalPartOfEmailAddress(email) {
|
|
176
|
+
const indexOfAt = email.indexOf('@');
|
|
177
|
+
if (indexOfAt < 2) {
|
|
178
|
+
if (indexOfAt >= 0) {
|
|
179
|
+
if (indexOfAt === email.length - 1)
|
|
180
|
+
return email.substring(0, indexOfAt);
|
|
181
|
+
return email.substring(indexOfAt + 1);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
return email.substring(0, indexOfAt);
|
|
186
|
+
}
|
|
187
|
+
return email;
|
|
188
|
+
}
|
|
189
|
+
static getTwoUppercaseLettersFromName(name) {
|
|
190
|
+
// Too short to do anything besides just returning the name
|
|
191
|
+
if (name.length <= 2) {
|
|
192
|
+
return name.toUpperCase();
|
|
193
|
+
}
|
|
194
|
+
// Try to split by non word characters
|
|
195
|
+
const splittedByNonWord = name.split(AvatarGenerator._nonWordRegex);
|
|
196
|
+
if (splittedByNonWord.length > 1) {
|
|
197
|
+
return (splittedByNonWord[0][0] + splittedByNonWord[1][0]).toUpperCase();
|
|
198
|
+
}
|
|
199
|
+
// Try to split by upper case letters
|
|
200
|
+
const upperCaseLetters = [...name]
|
|
201
|
+
.filter((c) => c.toUpperCase() === c && !AvatarGenerator._nonWordRegex.test(c))
|
|
202
|
+
.join();
|
|
203
|
+
if (upperCaseLetters.length > 1) {
|
|
204
|
+
return upperCaseLetters.substring(0, 2);
|
|
205
|
+
}
|
|
206
|
+
// Just return the first 2 letters
|
|
207
|
+
return name.substring(0, 2).toUpperCase();
|
|
208
|
+
}
|
|
209
|
+
// from https://stackoverflow.com/a/66494926/1378307
|
|
210
|
+
static getBackgroundColor(text, minLightness = 40, maxLightness = 80, minSaturation = 30, maxSaturation = 100) {
|
|
211
|
+
if (!text)
|
|
212
|
+
return '#aaa';
|
|
213
|
+
const hash = [...text].reduce((acc, char) => {
|
|
214
|
+
return char.charCodeAt(0) + ((acc << 5) - acc);
|
|
215
|
+
}, 0);
|
|
216
|
+
return ('hsl(' +
|
|
217
|
+
(hash % 360) +
|
|
218
|
+
', ' +
|
|
219
|
+
((hash % (maxSaturation - minSaturation)) + minSaturation) +
|
|
220
|
+
'%, ' +
|
|
221
|
+
((hash % (maxLightness - minLightness)) + minLightness) +
|
|
222
|
+
'%)');
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
AvatarGenerator._nonWordRegex = new RegExp('\\W');
|
|
226
|
+
AvatarGenerator._imageCache = new Map();
|
|
227
|
+
AvatarGenerator.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: AvatarGenerator, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
228
|
+
AvatarGenerator.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: AvatarGenerator, providedIn: 'root' });
|
|
229
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: AvatarGenerator, decorators: [{
|
|
230
|
+
type: Injectable,
|
|
231
|
+
args: [{
|
|
232
|
+
providedIn: 'root',
|
|
233
|
+
}]
|
|
234
|
+
}], propDecorators: { getImageOverride: [{
|
|
235
|
+
type: Input
|
|
236
|
+
}] } });
|
|
237
|
+
|
|
238
|
+
class FormService {
|
|
239
|
+
createFormGroupsFromTemplates(templates) {
|
|
240
|
+
const tabs = Object.fromEntries(Object.entries(templates).map(([name, template]) => [
|
|
241
|
+
name,
|
|
242
|
+
this.createFormGroupFromTemplate(template)
|
|
243
|
+
]));
|
|
244
|
+
return tabs;
|
|
245
|
+
}
|
|
246
|
+
createFormGroupFromTemplates(templates, ignoredProperties) {
|
|
247
|
+
const controls = Object.fromEntries(Object.entries(templates)
|
|
248
|
+
.filter(([key,]) => !ignoredProperties.some(p => key === p))
|
|
249
|
+
.map(([name, template]) => [
|
|
250
|
+
name,
|
|
251
|
+
this.createFormGroupFromTemplate(template)
|
|
252
|
+
]));
|
|
253
|
+
const formGroup = new FormGroup(controls);
|
|
254
|
+
return formGroup;
|
|
255
|
+
}
|
|
256
|
+
createFormArrayFromTemplates(templates, ignoredProperties) {
|
|
257
|
+
const controls = Object.entries(templates)
|
|
258
|
+
.filter(([key,]) => !ignoredProperties.some(p => key === p))
|
|
259
|
+
.map(([, template]) => this.createFormGroupFromTemplate(template));
|
|
260
|
+
const formArray = new FormArray(controls);
|
|
261
|
+
return formArray;
|
|
262
|
+
}
|
|
263
|
+
createFormGroupFromTemplate(template) {
|
|
264
|
+
const controls = Object.fromEntries(template.properties.map(p => [
|
|
265
|
+
p.name,
|
|
266
|
+
this.createFormControl(p)
|
|
267
|
+
]));
|
|
268
|
+
const formGroup = new FormGroup(controls);
|
|
269
|
+
return formGroup;
|
|
270
|
+
}
|
|
271
|
+
createFormControl(property) {
|
|
272
|
+
if (property.type === PropertyType.Object)
|
|
273
|
+
return this.createFormGroupFromTemplate(property._templates['default']);
|
|
274
|
+
if (property.type === PropertyType.Collection)
|
|
275
|
+
return this.createFormArrayFromTemplates(property._templates, ['default']);
|
|
276
|
+
const control = new FormControl(property.value);
|
|
277
|
+
if (property.max)
|
|
278
|
+
control.addValidators(Validators.max(property.max));
|
|
279
|
+
if (property.maxLength)
|
|
280
|
+
control.addValidators(Validators.maxLength(property.maxLength));
|
|
281
|
+
if (property.min)
|
|
282
|
+
control.addValidators(Validators.min(property.min));
|
|
283
|
+
if (property.minLength)
|
|
284
|
+
control.addValidators(Validators.minLength(property.minLength));
|
|
285
|
+
if (property.regex)
|
|
286
|
+
control.addValidators(Validators.pattern(property.regex));
|
|
287
|
+
if (property.required)
|
|
288
|
+
control.addValidators(Validators.required);
|
|
289
|
+
if (property.type === PropertyType.Email)
|
|
290
|
+
control.addValidators(Validators.email);
|
|
291
|
+
return control;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
FormService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: FormService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
295
|
+
FormService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: FormService, providedIn: 'root' });
|
|
296
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: FormService, decorators: [{
|
|
297
|
+
type: Injectable,
|
|
298
|
+
args: [{
|
|
299
|
+
providedIn: 'root'
|
|
300
|
+
}]
|
|
301
|
+
}] });
|
|
302
|
+
|
|
303
|
+
class RESTworldClient {
|
|
304
|
+
constructor(_halClient, _options) {
|
|
305
|
+
this._halClient = _halClient;
|
|
306
|
+
this._options = _options;
|
|
307
|
+
}
|
|
308
|
+
get halClient() {
|
|
309
|
+
return this._halClient;
|
|
310
|
+
}
|
|
311
|
+
ensureHomeResourceIsSet() {
|
|
312
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
313
|
+
if (!this._homeResource) {
|
|
314
|
+
const response = yield this.getHomeForced();
|
|
315
|
+
if (ProblemDetails.isProblemDetails(response.body)) {
|
|
316
|
+
throw new Error(`Cannot get the home resource from ${this._options.BaseUrl} with Version ${this._options.Version}. Response was: ${response}`);
|
|
317
|
+
}
|
|
318
|
+
if (!response.body)
|
|
319
|
+
throw new Error(`Cannot get the home resource from ${this._options.BaseUrl} with Version ${this._options.Version}. Response was empty.`);
|
|
320
|
+
this._homeResource = response.body;
|
|
321
|
+
this.setDefaultCurie();
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
getHomeForced() {
|
|
326
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
327
|
+
const header = RESTworldClient.createHeaders('application/hal+json', this._options.Version);
|
|
328
|
+
const response = yield this.halClient.get(this._options.BaseUrl, Resource, ProblemDetails, header);
|
|
329
|
+
return response;
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
setDefaultCurie() {
|
|
333
|
+
var _a, _b;
|
|
334
|
+
const curies = (_b = (_a = this._homeResource) === null || _a === void 0 ? void 0 : _a._links) === null || _b === void 0 ? void 0 : _b.curies;
|
|
335
|
+
if (!curies || curies.length === 0 || !curies[0])
|
|
336
|
+
this._defaultCurie = undefined;
|
|
337
|
+
else
|
|
338
|
+
this._defaultCurie = curies[0].name;
|
|
339
|
+
}
|
|
340
|
+
getList(rel, parameters, headers, curie) {
|
|
341
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
342
|
+
const link = this.getLinkFromHome(rel, LinkNames.getList, curie);
|
|
343
|
+
const uri = link.fillTemplate(parameters);
|
|
344
|
+
const response = yield this.halClient.get(uri, PagedListResource, ProblemDetails, headers);
|
|
345
|
+
return response;
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
getListByUri(uri, parameters, headers) {
|
|
349
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
350
|
+
const link = new Link();
|
|
351
|
+
link.href = uri;
|
|
352
|
+
const filledUri = link.fillTemplate(parameters);
|
|
353
|
+
const response = yield this.halClient.get(filledUri, PagedListResource, ProblemDetails, headers);
|
|
354
|
+
return response;
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
getSingle(relOrUri, id, headers, curie) {
|
|
358
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
359
|
+
let uri;
|
|
360
|
+
if (relOrUri.startsWith('http')) {
|
|
361
|
+
if (id !== undefined)
|
|
362
|
+
throw new Error('When supplying a URI, an ID cannot be supplied too.');
|
|
363
|
+
if (curie)
|
|
364
|
+
throw new Error('When supplying a URI, a curie cannot be supplied too.');
|
|
365
|
+
uri = relOrUri;
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
if (!_.isNumber(id))
|
|
369
|
+
throw new Error('When supplying a rel, an ID must be supplied too.');
|
|
370
|
+
const link = this.getLinkFromHome(relOrUri, LinkNames.get, curie);
|
|
371
|
+
uri = link.fillTemplate({ id: id.toString() });
|
|
372
|
+
}
|
|
373
|
+
const response = yield this.halClient.get(uri, Resource, ProblemDetails, headers);
|
|
374
|
+
return response;
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
save(resource) {
|
|
378
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
379
|
+
const saveLink = resource.findLink('save');
|
|
380
|
+
if (!saveLink)
|
|
381
|
+
throw new Error(`The resource ${resource} does not have a save link.`);
|
|
382
|
+
if (!saveLink.name)
|
|
383
|
+
throw new Error(`The save link ${saveLink} does not have a save name.`);
|
|
384
|
+
const uri = saveLink.href;
|
|
385
|
+
const method = saveLink.name.toLowerCase();
|
|
386
|
+
const header = RESTworldClient.createHeaders('application/hal+json', this._options.Version);
|
|
387
|
+
let response;
|
|
388
|
+
switch (method) {
|
|
389
|
+
case 'put':
|
|
390
|
+
response = yield this.halClient.put(uri, resource, Resource, ProblemDetails, header);
|
|
391
|
+
break;
|
|
392
|
+
case 'post':
|
|
393
|
+
response = yield this.halClient.post(uri, resource, Resource, ProblemDetails, header);
|
|
394
|
+
break;
|
|
395
|
+
default:
|
|
396
|
+
throw new Error(`'${method}' is not allowed as link name for the save link. Only 'POST' and 'PUT' are allowed.`);
|
|
397
|
+
}
|
|
398
|
+
return response;
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
getAllForms(resource) {
|
|
402
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
403
|
+
const urls = resource.getFormLinkHrefs();
|
|
404
|
+
const header = RESTworldClient.createHeaders('application/prs.hal-forms+json', this._options.Version);
|
|
405
|
+
const formsPromises = urls.map(url => this._halClient.get(url, FormsResource, ProblemDetails, header));
|
|
406
|
+
const formsAndProblems = yield Promise.all(formsPromises);
|
|
407
|
+
return formsAndProblems;
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
submit(template, formValues) {
|
|
411
|
+
var _a;
|
|
412
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
413
|
+
const uri = template.target || '';
|
|
414
|
+
const method = (_a = template.method) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
415
|
+
const header = RESTworldClient.createHeaders('application/prs.hal-forms+json', this._options.Version);
|
|
416
|
+
let response;
|
|
417
|
+
switch (method) {
|
|
418
|
+
case 'put':
|
|
419
|
+
response = yield this.halClient.put(uri, formValues, FormsResource, ProblemDetails, header);
|
|
420
|
+
break;
|
|
421
|
+
case 'post':
|
|
422
|
+
response = yield this.halClient.post(uri, formValues, FormsResource, ProblemDetails, header);
|
|
423
|
+
break;
|
|
424
|
+
default:
|
|
425
|
+
response = yield this.halClient.get(uri, FormsResource, ProblemDetails, header);
|
|
426
|
+
}
|
|
427
|
+
return response;
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
delete(resource) {
|
|
431
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
432
|
+
const deleteLink = resource.findLink('delete');
|
|
433
|
+
if (!deleteLink)
|
|
434
|
+
throw new Error(`The resource ${resource} does not have a delete link.`);
|
|
435
|
+
const uri = deleteLink.href;
|
|
436
|
+
const header = RESTworldClient.createHeaders('application/hal+json', this._options.Version);
|
|
437
|
+
const response = yield this.halClient.delete(uri, ProblemDetails, header);
|
|
438
|
+
return response;
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
getAllLinksFromHome() {
|
|
442
|
+
if (!this._homeResource)
|
|
443
|
+
throw new Error('Home resource is not set. Call ensureHomeResourceIsSet() first.');
|
|
444
|
+
return this._homeResource._links;
|
|
445
|
+
}
|
|
446
|
+
getLinkFromHome(rel, name, curie) {
|
|
447
|
+
const links = this.getLinksFromHome(rel, curie);
|
|
448
|
+
const link = name ? links.find(l => l.name === name) : links[0];
|
|
449
|
+
if (!link)
|
|
450
|
+
throw new Error(`The home resource does not have a link with the rel '${this.getFullRel(rel, curie)}' and the name '${name}'.`);
|
|
451
|
+
return link;
|
|
452
|
+
}
|
|
453
|
+
getLinksFromHome(rel, curie) {
|
|
454
|
+
if (!this._homeResource)
|
|
455
|
+
throw new Error('Home resource is not set. Call ensureHomeResourceIsSet() first.');
|
|
456
|
+
const fullRel = this.getFullRel(rel, curie);
|
|
457
|
+
const links = this._homeResource._links[fullRel];
|
|
458
|
+
if (!links || links.length === 0)
|
|
459
|
+
throw Error(`The home resource does not have a link with the rel '${fullRel}'.`);
|
|
460
|
+
return links;
|
|
461
|
+
}
|
|
462
|
+
getFullRel(rel, curie) {
|
|
463
|
+
// rel already includes a curie => just return it
|
|
464
|
+
if (rel.includes(':'))
|
|
465
|
+
return rel;
|
|
466
|
+
// No curie given => use default curie.
|
|
467
|
+
if (!curie)
|
|
468
|
+
curie = this._defaultCurie;
|
|
469
|
+
// Combine curie and rel
|
|
470
|
+
const fullRel = `${curie}:${rel}`;
|
|
471
|
+
return fullRel;
|
|
472
|
+
}
|
|
473
|
+
static createHeaders(mediaType, version) {
|
|
474
|
+
if (version)
|
|
475
|
+
return new HttpHeaders({
|
|
476
|
+
'Accept': `${mediaType || 'application/hal+json'}; v=${version}`,
|
|
477
|
+
'Content-Type': `${mediaType || 'application/hal+json'}; v=${version}`
|
|
478
|
+
});
|
|
479
|
+
return new HttpHeaders();
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
class RESTworldClientCollection {
|
|
484
|
+
constructor(_halClient) {
|
|
485
|
+
this._halClient = _halClient;
|
|
486
|
+
this._clients = {};
|
|
487
|
+
}
|
|
488
|
+
containsClient(name) {
|
|
489
|
+
return Object.keys(this._clients).includes(name);
|
|
490
|
+
}
|
|
491
|
+
addOrGetExistingClient(name, options) {
|
|
492
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
493
|
+
if (Object.keys(this._clients).includes(name))
|
|
494
|
+
return this.getClient(name);
|
|
495
|
+
const client = new RESTworldClient(this._halClient, options);
|
|
496
|
+
yield client.ensureHomeResourceIsSet();
|
|
497
|
+
this._clients[name] = client;
|
|
498
|
+
return client;
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
getClient(name) {
|
|
502
|
+
const client = this._clients[name];
|
|
503
|
+
if (!client)
|
|
504
|
+
throw new Error(`No client with the name '${name}' exists.`);
|
|
505
|
+
return client;
|
|
506
|
+
}
|
|
507
|
+
get all() {
|
|
508
|
+
return this._clients;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
RESTworldClientCollection.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RESTworldClientCollection, deps: [{ token: i1$1.HalClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
512
|
+
RESTworldClientCollection.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RESTworldClientCollection, providedIn: 'root' });
|
|
513
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RESTworldClientCollection, decorators: [{
|
|
514
|
+
type: Injectable,
|
|
515
|
+
args: [{
|
|
516
|
+
providedIn: 'root'
|
|
517
|
+
}]
|
|
518
|
+
}], ctorParameters: function () { return [{ type: i1$1.HalClient }]; } });
|
|
519
|
+
|
|
520
|
+
class SettingsService {
|
|
521
|
+
constructor(backend, _clients) {
|
|
522
|
+
this._clients = _clients;
|
|
523
|
+
this._client = new HttpClient(backend);
|
|
524
|
+
}
|
|
525
|
+
get settings() {
|
|
526
|
+
return this._settings;
|
|
527
|
+
}
|
|
528
|
+
initialize() {
|
|
529
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
530
|
+
yield this.ensureSettingsAreLoaded();
|
|
531
|
+
yield this.populateRESTworldClientCollectionFromSettings();
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
ensureSettingsAreLoaded() {
|
|
535
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
536
|
+
this._settings = yield this._client
|
|
537
|
+
.get('/settings')
|
|
538
|
+
.toPromise();
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
populateRESTworldClientCollectionFromSettings() {
|
|
542
|
+
var _a;
|
|
543
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
544
|
+
if (!((_a = this._settings) === null || _a === void 0 ? void 0 : _a.apiUrls))
|
|
545
|
+
return;
|
|
546
|
+
yield Promise.all(this._settings.apiUrls
|
|
547
|
+
.map(api => this._clients.addOrGetExistingClient(api.name, new RESTworldOptions(api.url, api.version))));
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
SettingsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: SettingsService, deps: [{ token: i1$2.HttpBackend }, { token: RESTworldClientCollection }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
552
|
+
SettingsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: SettingsService, providedIn: 'root' });
|
|
553
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: SettingsService, decorators: [{
|
|
554
|
+
type: Injectable,
|
|
555
|
+
args: [{
|
|
556
|
+
providedIn: 'root'
|
|
557
|
+
}]
|
|
558
|
+
}], ctorParameters: function () { return [{ type: i1$2.HttpBackend }, { type: RESTworldClientCollection }]; } });
|
|
559
|
+
|
|
560
|
+
class RESTWorldImageViewComponent {
|
|
561
|
+
constructor() {
|
|
562
|
+
this.maintainAspectRatio = true;
|
|
563
|
+
this.aspectRatio = 1;
|
|
564
|
+
this.resizeToWidth = 0;
|
|
565
|
+
this.resizeToHeight = 0;
|
|
566
|
+
this.onlyScaleDown = false;
|
|
567
|
+
this.containWithinAspectRatio = false;
|
|
568
|
+
this.backgroundColor = "#ffffff";
|
|
569
|
+
this.format = 'png';
|
|
570
|
+
this.disabled = false;
|
|
571
|
+
this.displayCropDialog = false;
|
|
572
|
+
}
|
|
573
|
+
writeValue(obj) {
|
|
574
|
+
this.uri = obj;
|
|
575
|
+
}
|
|
576
|
+
registerOnChange(fn) {
|
|
577
|
+
this.onChange = fn;
|
|
578
|
+
}
|
|
579
|
+
registerOnTouched() {
|
|
580
|
+
// not needed for this component, but needed to implement the interface
|
|
581
|
+
}
|
|
582
|
+
setDisabledState(isDisabled) {
|
|
583
|
+
this.disabled = isDisabled;
|
|
584
|
+
}
|
|
585
|
+
showCropDialog() {
|
|
586
|
+
this.displayCropDialog = true;
|
|
587
|
+
}
|
|
588
|
+
imageChanged(event) {
|
|
589
|
+
this.tempImageFile = event.files[0];
|
|
590
|
+
this.showCropDialog();
|
|
591
|
+
}
|
|
592
|
+
croppedImageChanged(event) {
|
|
593
|
+
this.tempCroppedUri = event.base64;
|
|
594
|
+
}
|
|
595
|
+
acceptCroppedImage() {
|
|
596
|
+
var _a;
|
|
597
|
+
this.uri = this.tempCroppedUri;
|
|
598
|
+
(_a = this.onChange) === null || _a === void 0 ? void 0 : _a.call(this, this.uri);
|
|
599
|
+
this.closeCropDialog();
|
|
600
|
+
}
|
|
601
|
+
closeCropDialog() {
|
|
602
|
+
var _a;
|
|
603
|
+
(_a = this.fileUploads) === null || _a === void 0 ? void 0 : _a.forEach(f => f.clear());
|
|
604
|
+
this.displayCropDialog = false;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
RESTWorldImageViewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RESTWorldImageViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
608
|
+
RESTWorldImageViewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.5", type: RESTWorldImageViewComponent, selector: "rw-image", inputs: { alt: "alt", accept: "accept", fileName: "fileName", maintainAspectRatio: "maintainAspectRatio", aspectRatio: "aspectRatio", resizeToWidth: "resizeToWidth", resizeToHeight: "resizeToHeight", onlyScaleDown: "onlyScaleDown", containWithinAspectRatio: "containWithinAspectRatio", backgroundColor: "backgroundColor", format: "format" }, providers: [{
|
|
609
|
+
provide: NG_VALUE_ACCESSOR,
|
|
610
|
+
useExisting: forwardRef(() => RESTWorldImageViewComponent),
|
|
611
|
+
multi: true
|
|
612
|
+
}], viewQueries: [{ propertyName: "fileUploads", predicate: FileUpload, descendants: true }], ngImport: i0, template: "<div class=\"flex align-items-center\">\r\n <p-button *ngIf=\"!uri\" [disabled]=\"true\" icon=\"pi pi-download\" class=\"mr-1\" pTooltip=\"No image present\"></p-button>\r\n <a *ngIf=\"uri\" [href]=\"uri | safeUrl\" [download]=\"fileName || 'download'\" class=\"mr-1\" pButton pTooltip=\"Download image\" icon=\"pi pi-download\"></a>\r\n <p-fileUpload class=\"mr-1\" chooseIcon=\"pi-upload fas fa-upload\" mode=\"basic\" [auto]=\"true\" [accept]=\"accept || 'false'\" [customUpload]=\"true\" (uploadHandler)=\"imageChanged($event)\" pTooltip=\"Upload new image\"></p-fileUpload>\r\n <img *ngIf=\"uri\" [src]=\"uri\" [alt]=\"alt\" (click)=\"showCropDialog()\" pTooltip=\"Zoom and crop\" />\r\n</div>\r\n\r\n<p-dialog header=\"alt\" [(visible)]=\"displayCropDialog\">\r\n <image-cropper #cropper\r\n [imageFile]=\"tempImageFile!\"\r\n [imageURL]=\"uri!\"\r\n [maintainAspectRatio]=\"maintainAspectRatio\"\r\n [aspectRatio]=\"aspectRatio\"\r\n [resizeToWidth]=\"resizeToWidth\"\r\n [resizeToHeight]=\"resizeToHeight\"\r\n [onlyScaleDown]=\"onlyScaleDown\"\r\n [autoCrop]=\"true\"\r\n [containWithinAspectRatio]=\"containWithinAspectRatio\"\r\n [backgroundColor]=\"backgroundColor\"\r\n [format]=\"format\"\r\n (imageCropped)=\"croppedImageChanged($event)\"></image-cropper>\r\n <div class=\"flex justify-content-end\">\r\n <div class=\"flex-auto align-items-center\">\r\n <span>Background color: </span>\r\n <p-colorPicker [(ngModel)]=\"cropper.backgroundColor\" appendTo=\"body\" class=\"ml-1 mr-1\"></p-colorPicker>\r\n <input pInputText [(ngModel)]=\"cropper.backgroundColor\" />\r\n </div>\r\n <button type=\"button\" pButton pRipple (click)=\"acceptCroppedImage()\" class=\"mr-2\">Ok</button>\r\n <button type=\"button\" pButton pRipple (click)=\"closeCropDialog()\">Cancel</button>\r\n </div>\r\n</p-dialog>\r\n", styles: ["img{height:calc(1rem + 18px);cursor:zoom-in;border-radius:3px}a{text-decoration:none;height:calc(1rem + 18px)}a.p-button-icon-only span.p-button-label{height:1rem!important}\n"], components: [{ type: i1$3.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "style", "styleClass", "badgeClass", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { type: i2.FileUpload, selector: "p-fileUpload", inputs: ["name", "url", "method", "multiple", "accept", "disabled", "auto", "withCredentials", "maxFileSize", "invalidFileSizeMessageSummary", "invalidFileSizeMessageDetail", "invalidFileTypeMessageSummary", "invalidFileTypeMessageDetail", "invalidFileLimitMessageDetail", "invalidFileLimitMessageSummary", "style", "styleClass", "previewWidth", "chooseLabel", "uploadLabel", "cancelLabel", "chooseIcon", "uploadIcon", "cancelIcon", "showUploadButton", "showCancelButton", "mode", "headers", "customUpload", "fileLimit", "files"], outputs: ["onBeforeUpload", "onSend", "onUpload", "onError", "onClear", "onRemove", "onSelect", "onProgress", "uploadHandler"] }, { type: i3.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { type: i4.ImageCropperComponent, selector: "image-cropper", inputs: ["imageChangedEvent", "imageURL", "imageBase64", "imageFile", "format", "transform", "maintainAspectRatio", "aspectRatio", "resizeToWidth", "resizeToHeight", "cropperMinWidth", "cropperMinHeight", "cropperMaxHeight", "cropperMaxWidth", "cropperStaticWidth", "cropperStaticHeight", "canvasRotation", "initialStepSize", "roundCropper", "onlyScaleDown", "imageQuality", "autoCrop", "backgroundColor", "containWithinAspectRatio", "hideResizeSquares", "cropper", "alignImage", "disabled"], outputs: ["imageCropped", "startCropImage", "imageLoaded", "cropperReady", "loadImageFailed"] }, { type: i5.ColorPicker, selector: "p-colorPicker", inputs: ["style", "styleClass", "inline", "format", "appendTo", "disabled", "tabindex", "inputId", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onChange", "onShow", "onHide"] }], directives: [{ type: i3$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i7.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { type: i1$3.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading"] }, { type: i14.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i14.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i14.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i9.InputText, selector: "[pInputText]" }, { type: i10.Ripple, selector: "[pRipple]" }], pipes: { "safeUrl": SafeUrlPipe } });
|
|
613
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RESTWorldImageViewComponent, decorators: [{
|
|
614
|
+
type: Component,
|
|
615
|
+
args: [{ selector: 'rw-image', providers: [{
|
|
616
|
+
provide: NG_VALUE_ACCESSOR,
|
|
617
|
+
useExisting: forwardRef(() => RESTWorldImageViewComponent),
|
|
618
|
+
multi: true
|
|
619
|
+
}], template: "<div class=\"flex align-items-center\">\r\n <p-button *ngIf=\"!uri\" [disabled]=\"true\" icon=\"pi pi-download\" class=\"mr-1\" pTooltip=\"No image present\"></p-button>\r\n <a *ngIf=\"uri\" [href]=\"uri | safeUrl\" [download]=\"fileName || 'download'\" class=\"mr-1\" pButton pTooltip=\"Download image\" icon=\"pi pi-download\"></a>\r\n <p-fileUpload class=\"mr-1\" chooseIcon=\"pi-upload fas fa-upload\" mode=\"basic\" [auto]=\"true\" [accept]=\"accept || 'false'\" [customUpload]=\"true\" (uploadHandler)=\"imageChanged($event)\" pTooltip=\"Upload new image\"></p-fileUpload>\r\n <img *ngIf=\"uri\" [src]=\"uri\" [alt]=\"alt\" (click)=\"showCropDialog()\" pTooltip=\"Zoom and crop\" />\r\n</div>\r\n\r\n<p-dialog header=\"alt\" [(visible)]=\"displayCropDialog\">\r\n <image-cropper #cropper\r\n [imageFile]=\"tempImageFile!\"\r\n [imageURL]=\"uri!\"\r\n [maintainAspectRatio]=\"maintainAspectRatio\"\r\n [aspectRatio]=\"aspectRatio\"\r\n [resizeToWidth]=\"resizeToWidth\"\r\n [resizeToHeight]=\"resizeToHeight\"\r\n [onlyScaleDown]=\"onlyScaleDown\"\r\n [autoCrop]=\"true\"\r\n [containWithinAspectRatio]=\"containWithinAspectRatio\"\r\n [backgroundColor]=\"backgroundColor\"\r\n [format]=\"format\"\r\n (imageCropped)=\"croppedImageChanged($event)\"></image-cropper>\r\n <div class=\"flex justify-content-end\">\r\n <div class=\"flex-auto align-items-center\">\r\n <span>Background color: </span>\r\n <p-colorPicker [(ngModel)]=\"cropper.backgroundColor\" appendTo=\"body\" class=\"ml-1 mr-1\"></p-colorPicker>\r\n <input pInputText [(ngModel)]=\"cropper.backgroundColor\" />\r\n </div>\r\n <button type=\"button\" pButton pRipple (click)=\"acceptCroppedImage()\" class=\"mr-2\">Ok</button>\r\n <button type=\"button\" pButton pRipple (click)=\"closeCropDialog()\">Cancel</button>\r\n </div>\r\n</p-dialog>\r\n", styles: ["img{height:calc(1rem + 18px);cursor:zoom-in;border-radius:3px}a{text-decoration:none;height:calc(1rem + 18px)}a.p-button-icon-only span.p-button-label{height:1rem!important}\n"] }]
|
|
620
|
+
}], propDecorators: { alt: [{
|
|
621
|
+
type: Input
|
|
622
|
+
}], accept: [{
|
|
623
|
+
type: Input
|
|
624
|
+
}], fileName: [{
|
|
625
|
+
type: Input
|
|
626
|
+
}], maintainAspectRatio: [{
|
|
627
|
+
type: Input
|
|
628
|
+
}], aspectRatio: [{
|
|
629
|
+
type: Input
|
|
630
|
+
}], resizeToWidth: [{
|
|
631
|
+
type: Input
|
|
632
|
+
}], resizeToHeight: [{
|
|
633
|
+
type: Input
|
|
634
|
+
}], onlyScaleDown: [{
|
|
635
|
+
type: Input
|
|
636
|
+
}], containWithinAspectRatio: [{
|
|
637
|
+
type: Input
|
|
638
|
+
}], backgroundColor: [{
|
|
639
|
+
type: Input
|
|
640
|
+
}], format: [{
|
|
641
|
+
type: Input
|
|
642
|
+
}], fileUploads: [{
|
|
643
|
+
type: ViewChildren,
|
|
644
|
+
args: [FileUpload]
|
|
645
|
+
}] } });
|
|
646
|
+
|
|
647
|
+
class RESTWorldFileViewComponent {
|
|
648
|
+
constructor() {
|
|
649
|
+
this.disabled = false;
|
|
650
|
+
}
|
|
651
|
+
writeValue(obj) {
|
|
652
|
+
this.uri = obj;
|
|
653
|
+
}
|
|
654
|
+
registerOnChange(fn) {
|
|
655
|
+
this.onChange = fn;
|
|
656
|
+
}
|
|
657
|
+
registerOnTouched() {
|
|
658
|
+
// not needed for this component, but needed to implement the interface
|
|
659
|
+
}
|
|
660
|
+
setDisabledState(isDisabled) {
|
|
661
|
+
this.disabled = isDisabled;
|
|
662
|
+
}
|
|
663
|
+
fileChanged(event) {
|
|
664
|
+
const file = event.files[0];
|
|
665
|
+
const reader = new FileReader();
|
|
666
|
+
reader.onload = () => {
|
|
667
|
+
var _a;
|
|
668
|
+
this.uri = reader.result;
|
|
669
|
+
(_a = this.onChange) === null || _a === void 0 ? void 0 : _a.call(this, this.uri);
|
|
670
|
+
};
|
|
671
|
+
reader.readAsDataURL(file);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
RESTWorldFileViewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RESTWorldFileViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
675
|
+
RESTWorldFileViewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.5", type: RESTWorldFileViewComponent, selector: "rw-file", inputs: { accept: "accept", fileName: "fileName" }, providers: [{
|
|
676
|
+
provide: NG_VALUE_ACCESSOR,
|
|
677
|
+
useExisting: forwardRef(() => RESTWorldFileViewComponent),
|
|
678
|
+
multi: true
|
|
679
|
+
}], viewQueries: [{ propertyName: "fileUploads", predicate: FileUpload, descendants: true }], ngImport: i0, template: "<div class=\"flex align-items-center\">\r\n <p-button *ngIf=\"!uri\" [disabled]=\"true\" icon=\"pi pi-download\" class=\"mr-1\" pTooltip=\"No file present\"></p-button>\r\n <a *ngIf=\"uri\" [href]=\"uri | safeUrl\" [download]=\"fileName || 'download'\" class=\"mr-1\" pButton pTooltip=\"Download file\" icon=\"pi pi-download\"></a>\r\n <p-fileUpload chooseIcon=\"pi-upload fas fa-upload\" pTooltip=\"Upload new file\" mode=\"basic\" [auto]=\"true\" [accept]=\"accept || 'false'\" [customUpload]=\"true\" (uploadHandler)=\"fileChanged($event)\"></p-fileUpload>\r\n</div>\r\n", styles: ["a{text-decoration:none;height:calc(1rem + 18px)}a.p-button-icon-only span.p-button-label{height:1rem!important}\n"], components: [{ type: i1$3.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "style", "styleClass", "badgeClass", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { type: i2.FileUpload, selector: "p-fileUpload", inputs: ["name", "url", "method", "multiple", "accept", "disabled", "auto", "withCredentials", "maxFileSize", "invalidFileSizeMessageSummary", "invalidFileSizeMessageDetail", "invalidFileTypeMessageSummary", "invalidFileTypeMessageDetail", "invalidFileLimitMessageDetail", "invalidFileLimitMessageSummary", "style", "styleClass", "previewWidth", "chooseLabel", "uploadLabel", "cancelLabel", "chooseIcon", "uploadIcon", "cancelIcon", "showUploadButton", "showCancelButton", "mode", "headers", "customUpload", "fileLimit", "files"], outputs: ["onBeforeUpload", "onSend", "onUpload", "onError", "onClear", "onRemove", "onSelect", "onProgress", "uploadHandler"] }], directives: [{ type: i3$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i7.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { type: i1$3.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading"] }], pipes: { "safeUrl": SafeUrlPipe } });
|
|
680
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RESTWorldFileViewComponent, decorators: [{
|
|
681
|
+
type: Component,
|
|
682
|
+
args: [{ selector: 'rw-file', providers: [{
|
|
683
|
+
provide: NG_VALUE_ACCESSOR,
|
|
684
|
+
useExisting: forwardRef(() => RESTWorldFileViewComponent),
|
|
685
|
+
multi: true
|
|
686
|
+
}], template: "<div class=\"flex align-items-center\">\r\n <p-button *ngIf=\"!uri\" [disabled]=\"true\" icon=\"pi pi-download\" class=\"mr-1\" pTooltip=\"No file present\"></p-button>\r\n <a *ngIf=\"uri\" [href]=\"uri | safeUrl\" [download]=\"fileName || 'download'\" class=\"mr-1\" pButton pTooltip=\"Download file\" icon=\"pi pi-download\"></a>\r\n <p-fileUpload chooseIcon=\"pi-upload fas fa-upload\" pTooltip=\"Upload new file\" mode=\"basic\" [auto]=\"true\" [accept]=\"accept || 'false'\" [customUpload]=\"true\" (uploadHandler)=\"fileChanged($event)\"></p-fileUpload>\r\n</div>\r\n", styles: ["a{text-decoration:none;height:calc(1rem + 18px)}a.p-button-icon-only span.p-button-label{height:1rem!important}\n"] }]
|
|
687
|
+
}], propDecorators: { accept: [{
|
|
688
|
+
type: Input
|
|
689
|
+
}], fileName: [{
|
|
690
|
+
type: Input
|
|
691
|
+
}], fileUploads: [{
|
|
692
|
+
type: ViewChildren,
|
|
693
|
+
args: [FileUpload]
|
|
694
|
+
}] } });
|
|
695
|
+
|
|
696
|
+
class RestworldEditFormComponent {
|
|
697
|
+
constructor(_formService, _changeDetectorRef, _messageService, _clients) {
|
|
698
|
+
this._formService = _formService;
|
|
699
|
+
this._changeDetectorRef = _changeDetectorRef;
|
|
700
|
+
this._messageService = _messageService;
|
|
701
|
+
this._clients = _clients;
|
|
702
|
+
this.FormGroup = FormGroup;
|
|
703
|
+
this.FormArray = FormArray;
|
|
704
|
+
this.Number = Number;
|
|
705
|
+
}
|
|
706
|
+
get PropertyType() {
|
|
707
|
+
return PropertyType;
|
|
708
|
+
}
|
|
709
|
+
get dateFormat() {
|
|
710
|
+
return new Date(3333, 10, 22)
|
|
711
|
+
.toLocaleDateString()
|
|
712
|
+
.replace("22", "dd")
|
|
713
|
+
.replace("11", "mm")
|
|
714
|
+
.replace("3333", "yy")
|
|
715
|
+
.replace("33", "y");
|
|
716
|
+
}
|
|
717
|
+
ngOnInit() {
|
|
718
|
+
if (!this.formGroup)
|
|
719
|
+
throw new Error("[formGroup] is required on <rw-form>");
|
|
720
|
+
if (!this.template)
|
|
721
|
+
throw new Error("[template] is required on <rw-form>");
|
|
722
|
+
if (!this.apiName)
|
|
723
|
+
throw new Error("[apiName] is required on <rw-form>");
|
|
724
|
+
}
|
|
725
|
+
getTooltip(resource, keysToExclude) {
|
|
726
|
+
const tooltip = Object.entries(resource)
|
|
727
|
+
.filter(([key]) => !(key.startsWith('_') || ['createdAt', 'createdBy', 'lastChangedAt', 'lastChangedBy', 'timestamp'].includes(key) || (keysToExclude === null || keysToExclude === void 0 ? void 0 : keysToExclude.includes(key))))
|
|
728
|
+
.reduce((prev, [key, value], index) => `${prev}${index === 0 ? '' : '\n'}${key}: ${RestworldEditFormComponent.jsonStringifyWithElipsis(value)}`, '');
|
|
729
|
+
return tooltip;
|
|
730
|
+
}
|
|
731
|
+
static jsonStringifyWithElipsis(value) {
|
|
732
|
+
const maxLength = 200;
|
|
733
|
+
const end = 10;
|
|
734
|
+
const start = maxLength - end - 2;
|
|
735
|
+
const json = JSON.stringify(value);
|
|
736
|
+
const shortened = json.length > maxLength ? json.substring(0, start) + '…' + json.substring(json.length - end) : json;
|
|
737
|
+
return shortened;
|
|
738
|
+
}
|
|
739
|
+
getCollectionEntryTemplates(property) {
|
|
740
|
+
if (!property)
|
|
741
|
+
return [];
|
|
742
|
+
return Object.entries(property._templates)
|
|
743
|
+
.filter(([key,]) => Number.isInteger(Number.parseInt(key)))
|
|
744
|
+
.map(([, value]) => value);
|
|
745
|
+
}
|
|
746
|
+
addNewItemToCollection(property, formArray) {
|
|
747
|
+
if (!(formArray instanceof FormArray))
|
|
748
|
+
throw new Error('formArray is not an instance of FormArray.');
|
|
749
|
+
const maxIndex = Math.max(...Object.keys(property._templates)
|
|
750
|
+
.map(key => Number.parseInt(key))
|
|
751
|
+
.filter(key => Number.isSafeInteger(key)));
|
|
752
|
+
const nextIndex = maxIndex + 1;
|
|
753
|
+
const defaultTemplate = property._templates['default'];
|
|
754
|
+
const copiedTemplateDto = JSON.parse(JSON.stringify(defaultTemplate));
|
|
755
|
+
const copiedTemplate = new Template(copiedTemplateDto);
|
|
756
|
+
copiedTemplate.title = nextIndex.toString();
|
|
757
|
+
property._templates[copiedTemplate.title] = copiedTemplate;
|
|
758
|
+
formArray.push(this._formService.createFormGroupFromTemplate(defaultTemplate));
|
|
759
|
+
}
|
|
760
|
+
deleteItemFromCollection(property, formArray, template) {
|
|
761
|
+
if (!template.title)
|
|
762
|
+
throw new Error(`Cannot delete the item, because the template '${template}' does not have a title.`);
|
|
763
|
+
if (!(formArray instanceof FormArray))
|
|
764
|
+
throw new Error('formArray is not an instance of FormArray.');
|
|
765
|
+
const templates = property._templates;
|
|
766
|
+
delete templates[template.title];
|
|
767
|
+
formArray.removeAt(Number.parseInt(template.title));
|
|
768
|
+
}
|
|
769
|
+
collectionItemDropped($event) {
|
|
770
|
+
const formArray = $event.container.data.formArray;
|
|
771
|
+
const previousIndex = $event.previousIndex;
|
|
772
|
+
const currentIndex = $event.currentIndex;
|
|
773
|
+
const movementDirection = currentIndex > previousIndex ? 1 : -1;
|
|
774
|
+
// Move in FormArray
|
|
775
|
+
// We do not need to move the item in the _templates object
|
|
776
|
+
const movedControl = formArray.at(previousIndex);
|
|
777
|
+
for (let i = previousIndex; i * movementDirection < currentIndex * movementDirection; i = i + movementDirection) {
|
|
778
|
+
formArray.setControl(i, formArray.at(i + movementDirection));
|
|
779
|
+
}
|
|
780
|
+
formArray.setControl(currentIndex, movedControl);
|
|
781
|
+
this._changeDetectorRef.markForCheck();
|
|
782
|
+
console.log($event);
|
|
783
|
+
}
|
|
784
|
+
onOptionsFiltered(property, event) {
|
|
785
|
+
var _a, _b;
|
|
786
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
787
|
+
const options = property === null || property === void 0 ? void 0 : property.options;
|
|
788
|
+
if (!((_a = options === null || options === void 0 ? void 0 : options.link) === null || _a === void 0 ? void 0 : _a.href) || !event.filter || event.filter === '')
|
|
789
|
+
return;
|
|
790
|
+
const templatedUri = options.link.href;
|
|
791
|
+
let filter = `contains(${options.promptField}, '${event.filter}')`;
|
|
792
|
+
if (((_b = options.valueField) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === 'id' && !Number.isNaN(Number.parseInt(event.filter)))
|
|
793
|
+
filter = `(${options.valueField} eq ${event.filter}) or (${filter})`;
|
|
794
|
+
const response = yield this.getClient().getListByUri(templatedUri, { $filter: filter, $top: 10 });
|
|
795
|
+
if (!response.ok || ProblemDetails.isProblemDetails(response.body) || !response.body) {
|
|
796
|
+
const message = `An error occurred while getting the filtered items.`;
|
|
797
|
+
this._messageService.add({ severity: 'error', summary: 'Error', detail: message, data: response });
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
const items = response.body._embedded.items;
|
|
801
|
+
options.inline = items;
|
|
802
|
+
});
|
|
803
|
+
}
|
|
804
|
+
getClient() {
|
|
805
|
+
if (!this.apiName)
|
|
806
|
+
throw new Error('Cannot get a client, because the apiName is not set.');
|
|
807
|
+
return this._clients.getClient(this.apiName);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
RestworldEditFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RestworldEditFormComponent, deps: [{ token: FormService }, { token: i0.ChangeDetectorRef }, { token: i2$1.MessageService }, { token: RESTworldClientCollection }], target: i0.ɵɵFactoryTarget.Component });
|
|
811
|
+
RestworldEditFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.5", type: RestworldEditFormComponent, selector: "rw-form", inputs: { formGroup: "formGroup", template: "template", apiName: "apiName" }, queries: [{ propertyName: "inputOptionsSingleRef", first: true, predicate: ["inputOptionsSingle"], descendants: true }, { propertyName: "inputOptionsMultipleRef", first: true, predicate: ["inputOptionsMultiple"], descendants: true }, { propertyName: "inputOptionsRef", first: true, predicate: ["inputOptions"], descendants: true }, { propertyName: "inputHiddenRef", first: true, predicate: ["inputHidden"], descendants: true }, { propertyName: "inputTextRef", first: true, predicate: ["inputText"], descendants: true }, { propertyName: "inputTextareaRef", first: true, predicate: ["inputTextarea"], descendants: true }, { propertyName: "inputSearchRef", first: true, predicate: ["inputSearch"], descendants: true }, { propertyName: "inputTelRef", first: true, predicate: ["inputTel"], descendants: true }, { propertyName: "inputUrlRef", first: true, predicate: ["inputUrl"], descendants: true }, { propertyName: "inputEmailRef", first: true, predicate: ["inputEmail"], descendants: true }, { propertyName: "inputPasswordRef", first: true, predicate: ["inputPassword"], descendants: true }, { propertyName: "inputDateRef", first: true, predicate: ["inputDate"], descendants: true }, { propertyName: "inputMonthRef", first: true, predicate: ["inputMonth"], descendants: true }, { propertyName: "inputWeekRef", first: true, predicate: ["inputWeek"], descendants: true }, { propertyName: "inputTimeRef", first: true, predicate: ["inputTime"], descendants: true }, { propertyName: "inputDatetimeLocalRef", first: true, predicate: ["inputDatetimeLocal"], descendants: true }, { propertyName: "inputNumberRef", first: true, predicate: ["inputNumber"], descendants: true }, { propertyName: "inputRangeRef", first: true, predicate: ["inputRange"], descendants: true }, { propertyName: "inputColorRef", first: true, predicate: ["inputColor"], descendants: true }, { propertyName: "inputBoolRef", first: true, predicate: ["inputBool"], descendants: true }, { propertyName: "inputDatetimeOffsetRef", first: true, predicate: ["inputDatetimeOffset"], descendants: true }, { propertyName: "inputDurationRef", first: true, predicate: ["inputDuration"], descendants: true }, { propertyName: "inputImageRef", first: true, predicate: ["inputImage"], descendants: true }, { propertyName: "inputFileRef", first: true, predicate: ["inputFile"], descendants: true }, { propertyName: "inputObjectRef", first: true, predicate: ["inputObject"], descendants: true }, { propertyName: "inputCollectionRef", first: true, predicate: ["inputCollection"], descendants: true }, { propertyName: "inputDefaultRef", first: true, predicate: ["inputDefault"], descendants: true }], ngImport: i0, template: "<div *ngFor=\"let property of template.properties\" class=\"grid field\" [formGroup]=\"formGroup\">\r\n <label *ngIf=\"property.type !== PropertyType.Hidden\" [attr.for]=\"property.name\" class=\"col-12 mb-2 md:col-2 md:mb-0\" [class.p-disabled]=\"property.readOnly\" [class.hasChildren]=\"property._templates\">{{property.prompt || property.name}}</label>\r\n <div class=\"col-12 md:col-10\">\r\n\r\n <ng-template #defaultInputOptions let-property=\"property\" let-template=\"template\">\r\n\r\n <ng-template #defaultInputOptionsSingle let-property=\"property\" let-template=\"template\">\r\n <p-dropdown [formControlName]=\"property.name\" [id]=\"property.name\" [options]=\"property.options.inline\" [filterBy]=\"(property.options.promptField || 'prompt') + ',' + (property.options.valueField || 'value')\" [optionValue]=\"property.options.valueField || 'value'\" [readonly]=\"property.readOnly\" [required]=\"property.required || property.options.minItems > 0\" [filter]=\"true\" [autoDisplayFirst]=\"false\" [showClear]=\"!property.required || property.options.minItems <= 0\" (onFilter)=\"onOptionsFiltered(property, $event)\" styleClass=\"w-full\" [filterPlaceholder]=\"property?.options?.link?.href ? 'search for more results' : ''\">\r\n <ng-template let-item pTemplate=\"selectedItem\">\r\n <span [pTooltip]=\"getTooltip(item, [property.options.promptField || 'prompt', property.options.valueField || 'value'])\">{{item[property.options.promptField || 'prompt']}} ({{item[property.options.valueField || 'value']}})</span>\r\n </ng-template>\r\n <ng-template let-item pTemplate=\"item\">\r\n <span [pTooltip]=\"getTooltip(item, [property.options.promptField || 'prompt', property.options.valueField || 'value'])\">{{item[property.options.promptField || 'prompt']}} ({{item[property.options.valueField || 'value']}})</span>\r\n </ng-template>\r\n </p-dropdown>\r\n </ng-template>\r\n <ng-container *ngIf=\"!property.options.maxItems || property.options.maxItems == 1\">\r\n <ng-container *ngTemplateOutlet=\"inputOptionsSingleRef || defaultInputOptionsSingle; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #defaultInputOptionsMultiple let-property=\"property\" let-template=\"template\">\r\n <p-multiSelect [formControlName]=\"property.name\" [id]=\"property.name\" [options]=\"property.options.inline\" [optionLabel]=\"property.options.promptField || 'prompt'\" [optionValue]=\"property.options.valueField || 'value'\" [readonly]=\"property.readOnly\" [selectionLimit]=\"property.options.maxItems\" [required]=\"property.required || property.options.minItems > 0\"></p-multiSelect>\r\n </ng-template>\r\n <ng-container *ngIf=\"property.options.maxItems > 1\">\r\n <ng-container *ngTemplateOutlet=\"inputOptionsMultipleRef || defaultInputOptionsMultiple; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n </ng-template>\r\n <ng-container *ngIf=\"property.options\">\r\n <ng-container *ngTemplateOutlet=\"inputOptionsRef || defaultInputOptions; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n <div *ngIf=\"!property.options\">\r\n <div [ngSwitch]=\"property.type\">\r\n\r\n <ng-template #defaultInputHidden let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"hidden\" [value]=\"property.value\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Hidden\">\r\n <ng-container *ngTemplateOutlet=\"inputHiddenRef || defaultInputHidden; context:{ property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #defaultInputText let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"text\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Text\">\r\n <ng-container *ngTemplateOutlet=\"inputTextRef || defaultInputText; context:{ property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputTextarea let-property=\"property\" let-template=\"template\">\r\n <textarea [formControlName]=\"property.name\" [id]=\"property.name\" pInputTextarea class=\"w-full p-inputtextarea p-inputtext p-component p-element\" [class.p-disabled]=\"property.readOnly\" [cols]=\"property.cols\" [rows]=\"property.rows\"></textarea>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Textarea\">\r\n <ng-container *ngTemplateOutlet=\"inputTextareaRef || defaultInputTextarea; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputSearch let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"search\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Search\">\r\n <ng-container *ngTemplateOutlet=\"inputSearchRef || defaultInputSearch; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputTel let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"tel\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Tel\">\r\n <ng-container *ngTemplateOutlet=\"inputTelRef || defaultInputTel; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputUrl let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"url\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Url\">\r\n <ng-container *ngTemplateOutlet=\"inputUrlRef || defaultInputUrl; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputEmail let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"email\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Email\">\r\n <ng-container *ngTemplateOutlet=\"inputEmailRef || defaultInputEmail; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputPassword let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"password\" pPassword class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Password\">\r\n <ng-container *ngTemplateOutlet=\"inputPasswordRef || defaultInputPassword; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputDate let-property=\"property\" let-template=\"template\">\r\n <p-calendar [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showWeek]=\"true\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Date\">\r\n <ng-container *ngTemplateOutlet=\"inputDateRef || defaultInputDate; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputMonth let-property=\"property\" let-template=\"template\">\r\n <p-calendar [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showWeek]=\"false\" view=\"month\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Month\">\r\n <ng-container *ngTemplateOutlet=\"inputMonthRef || defaultInputMonth; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputWeek let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"week\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Week\">\r\n <ng-container *ngTemplateOutlet=\"inputWeekRef || defaultInputWeek; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputTime let-property=\"property\" let-template=\"template\">\r\n <p-calendar [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showTime]=\"true\" [timeOnly]=\"true\" [showWeek]=\"false\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Time\">\r\n <ng-container *ngTemplateOutlet=\"inputTimeRef || defaultInputTime; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputDatetimeLocal let-property=\"property\" let-template=\"template\">\r\n <p-calendar [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showTime]=\"true\" [showWeek]=\"false\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.DatetimeLocal\">\r\n <ng-container *ngTemplateOutlet=\"inputDatetimeLocalRef || defaultInputDatetimeLocal; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputNumber let-property=\"property\" let-template=\"template\">\r\n <p-inputNumber [formControlName]=\"property.name\" [id]=\"property.name\" mode=\"decimal\" [showButtons]=\"!property.readOnly\" class=\"w-full\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-inputNumber>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Number\">\r\n <ng-container *ngTemplateOutlet=\"inputNumberRef || defaultInputNumber; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputRange let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"range\" [min]=\"property.min\" [max]=\"property.max\" [step]=\"property.step\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Range\">\r\n <ng-container *ngTemplateOutlet=\"inputRangeRef || defaultInputRange; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputColor let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"color\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Color\">\r\n <ng-container *ngTemplateOutlet=\"inputColorRef || defaultInputColor; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputBool let-property=\"property\" let-template=\"template\" let-formGroup=\"formGroup\">\r\n <p-checkbox *ngIf=\"property.required\" [binary]=\"true\" [formControl]=\"formGroup.controls[property.name]\" [id]=\"property.name\" [readonly]=\"property.readOnly\"></p-checkbox>\r\n <p-triStateCheckbox *ngIf=\"!property.required\" [formControl]=\"formGroup.controls[property.name]\" [id]=\"property.name\" [readonly]=\"property.readOnly\"></p-triStateCheckbox>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Bool\">\r\n <ng-container *ngTemplateOutlet=\"inputBoolRef || defaultInputBool; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputDatetimeOffset let-property=\"property\" let-template=\"template\">\r\n <p-calendar [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showTime]=\"true\" [showWeek]=\"false\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.DatetimeOffset\">\r\n <ng-container *ngTemplateOutlet=\"inputDatetimeOffsetRef || defaultInputDatetimeOffset; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputDuration let-property=\"property\" let-template=\"template\">\r\n <p-calendar *ngSwitchCase=\"PropertyType.Duration\" [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showTime]=\"true\" [timeOnly]=\"true\" [showWeek]=\"false\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Duration\">\r\n <ng-container *ngTemplateOutlet=\"inputDurationRef || defaultInputDuration; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputImage let-property=\"property\" let-template=\"template\">\r\n <rw-image [formControlName]=\"property.name\" [accept]=\"property.placeholder\"></rw-image>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Image\">\r\n <ng-container *ngTemplateOutlet=\"inputImageRef || defaultInputImage; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputFile let-property=\"property\" let-template=\"template\">\r\n <rw-file [formControlName]=\"property.name\" [fileName]=\"property.name\" [accept]=\"property.placeholder\"></rw-file>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.File\">\r\n <ng-container *ngTemplateOutlet=\"inputFileRef || defaultInputFile; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputObject let-property=\"property\" let-template=\"template\">\r\n <div class=\"flex align-items-center\">\r\n <div class=\"brace\">\r\n </div>\r\n <div class=\"w-full\">\r\n <rw-form [formGroup]=\"(formGroup.controls[property.name] | as : FormGroup)\" [template]=\"property._templates.default\" [apiName]=\"apiName\"></rw-form>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Object\">\r\n <ng-container *ngTemplateOutlet=\"inputObjectRef || defaultInputObject; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputCollection let-property=\"property\" let-template=\"template\">\r\n <div class=\"flex align-items-center\">\r\n <div class=\"brace\">\r\n </div>\r\n <div class=\"w-full\" cdkDropList [cdkDropListData]=\"{ property: property, formArray: (formGroup.controls[property.name] | as : FormArray)}\" (cdkDropListDropped)=\"collectionItemDropped($event)\">\r\n <div *ngFor=\"let template of getCollectionEntryTemplates(property)\" class=\"flex align-items-center\" cdkDrag>\r\n <i class=\"fas fa-grip-lines\" cdkDragHandle></i>\r\n <div class=\"brace\">\r\n </div>\r\n <div class=\"w-full flex justify-content-end\">\r\n <rw-form [formGroup]=\"((formGroup.controls[property.name] | as : FormArray).controls[Number.parseInt(template.title!)] | as : FormGroup)\" [template]=\"template\" [apiName]=\"apiName\" class=\"w-full\"></rw-form>\r\n <button pButton pRipple type=\"button\" icon=\"fas fa-trash\" class=\"p-button-outlined p-button-danger ml-2 mb-3\" (click)=\"deleteItemFromCollection(property, formGroup.controls[property.name], template)\"></button>\r\n </div>\r\n </div>\r\n <div class=\"flex justify-content-end w-full\">\r\n <button pButton pRipple type=\"button\" icon=\"fas fa-plus\" class=\"p-button-outlined p-button-info\" (click)=\"addNewItemToCollection(property, formGroup.controls[property.name])\"></button>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Collection\">\r\n <ng-container *ngTemplateOutlet=\"inputCollectionRef || defaultInputCollection; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputDefault let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"text\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchDefault>\r\n <ng-container *ngTemplateOutlet=\"inputDefaultRef || defaultInputDefault; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n </div>\r\n </div>\r\n <val-errors [controlName]=\"property.name || null\">\r\n <ng-template valError=\"required\">The field '{{property.prompt || property.name}}' is required.</ng-template>\r\n <ng-template valError=\"email\">The email must be a valid email address.</ng-template>\r\n <ng-template valError=\"min\" let-error=\"error\">'{{property.prompt || property.name}}' must be equal or greater than or equal to {{ error.min }}.</ng-template>\r\n <ng-template valError=\"max\" let-error=\"error\">'{{property.prompt || property.name}}' must be smaller than or equal to {{ error.max }}.</ng-template>\r\n <ng-template valError=\"minlength\" let-error=\"error\">The length of '{{property.prompt || property.name}}' must be equal or greater than or equal to {{ error.requiredLength }}.</ng-template>\r\n <ng-template valError=\"maxlength\" let-error=\"error\">The length of '{{property.prompt || property.name}}' must be shorter than or equal to {{ error.requiredLength }}.</ng-template>\r\n <ng-template valError=\"pattern\" let-error=\"error\">The value for '{{property.prompt || property.name}}' does not match the pattern {{ error }}.</ng-template>\r\n <ng-template valError=\"remote\" let-error=\"error\">{{ error }}</ng-template>\r\n </val-errors>\r\n </div>\r\n</div>\r\n", styles: [".brace{align-self:stretch;margin:.2rem .5rem;border-left:1px solid rgb(206,212,218);border-top:1px solid rgb(206,212,218);border-bottom:1px solid rgb(206,212,218);width:1rem}.cdk-drag-handle{cursor:move}.cdk-drag-preview{background-color:#ffffffd0;border:2px dashed rgb(206,212,218);cursor:move}.cdk-drag-placeholder{border:2px dashed rgb(206,212,218);margin:-2px}\n"], components: [{ type: i4$1.Dropdown, selector: "p-dropdown", inputs: ["scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "filterPlaceholder", "filterLocale", "inputId", "selectId", "dataKey", "filterBy", "autofocus", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "virtualScroll", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "disabled", "options", "filterValue"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear"] }, { type: i5$1.MultiSelect, selector: "p-multiSelect", inputs: ["style", "styleClass", "panelStyle", "panelStyleClass", "inputId", "disabled", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "appendTo", "dataKey", "name", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "autoZIndex", "baseZIndex", "filterBy", "virtualScroll", "itemSize", "showTransitionOptions", "hideTransitionOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "scrollHeight", "defaultLabel", "placeholder", "options", "filterValue"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onPanelShow", "onPanelHide"] }, { type: i6.Calendar, selector: "p-calendar", inputs: ["style", "styleClass", "inputStyle", "inputId", "name", "inputStyleClass", "placeholder", "ariaLabelledBy", "iconAriaLabel", "disabled", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "appendTo", "readonlyInput", "shortYearCutoff", "monthNavigator", "yearNavigator", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "required", "showOnFocus", "showWeek", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "view", "defaultDate", "minDate", "maxDate", "disabledDates", "disabledDays", "yearRange", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "locale"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { type: i7$1.InputNumber, selector: "p-inputNumber", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "style", "placeholder", "size", "maxlength", "tabindex", "title", "ariaLabel", "ariaRequired", "name", "required", "autocomplete", "min", "max", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "step", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "disabled"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown"] }, { type: i8.Checkbox, selector: "p-checkbox", inputs: ["value", "name", "disabled", "binary", "label", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "styleClass", "labelStyleClass", "formControl", "checkboxIcon", "readonly", "required", "trueValue", "falseValue"], outputs: ["onChange"] }, { type: i9$1.TriStateCheckbox, selector: "p-triStateCheckbox", inputs: ["disabled", "name", "ariaLabelledBy", "tabindex", "inputId", "style", "styleClass", "label", "readonly", "checkboxTrueIcon", "checkboxFalseIcon"], outputs: ["onChange"] }, { type: RESTWorldImageViewComponent, selector: "rw-image", inputs: ["alt", "accept", "fileName", "maintainAspectRatio", "aspectRatio", "resizeToWidth", "resizeToHeight", "onlyScaleDown", "containWithinAspectRatio", "backgroundColor", "format"] }, { type: RESTWorldFileViewComponent, selector: "rw-file", inputs: ["accept", "fileName"] }, { type: RestworldEditFormComponent, selector: "rw-form", inputs: ["formGroup", "template", "apiName"] }, { type: i12.ValidationErrorsComponent, selector: "val-errors", inputs: ["control", "controlName", "label"] }], directives: [{ type: i3$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i14.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i14.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i3$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i14.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i14.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i14.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i2$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { type: i7.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { type: i3$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i3$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i14.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i3$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i9.InputText, selector: "[pInputText]" }, { type: i14.RangeValueAccessor, selector: "input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]" }, { type: i14.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { type: i17.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { type: i17.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { type: i17.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { type: i1$3.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading"] }, { type: i10.Ripple, selector: "[pRipple]" }, { type: i3$1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { type: i12.ValidationErrorDirective, selector: "ng-template[valError]", inputs: ["valError"] }], pipes: { "as": AsPipe } });
|
|
812
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RestworldEditFormComponent, decorators: [{
|
|
813
|
+
type: Component,
|
|
814
|
+
args: [{ selector: 'rw-form', template: "<div *ngFor=\"let property of template.properties\" class=\"grid field\" [formGroup]=\"formGroup\">\r\n <label *ngIf=\"property.type !== PropertyType.Hidden\" [attr.for]=\"property.name\" class=\"col-12 mb-2 md:col-2 md:mb-0\" [class.p-disabled]=\"property.readOnly\" [class.hasChildren]=\"property._templates\">{{property.prompt || property.name}}</label>\r\n <div class=\"col-12 md:col-10\">\r\n\r\n <ng-template #defaultInputOptions let-property=\"property\" let-template=\"template\">\r\n\r\n <ng-template #defaultInputOptionsSingle let-property=\"property\" let-template=\"template\">\r\n <p-dropdown [formControlName]=\"property.name\" [id]=\"property.name\" [options]=\"property.options.inline\" [filterBy]=\"(property.options.promptField || 'prompt') + ',' + (property.options.valueField || 'value')\" [optionValue]=\"property.options.valueField || 'value'\" [readonly]=\"property.readOnly\" [required]=\"property.required || property.options.minItems > 0\" [filter]=\"true\" [autoDisplayFirst]=\"false\" [showClear]=\"!property.required || property.options.minItems <= 0\" (onFilter)=\"onOptionsFiltered(property, $event)\" styleClass=\"w-full\" [filterPlaceholder]=\"property?.options?.link?.href ? 'search for more results' : ''\">\r\n <ng-template let-item pTemplate=\"selectedItem\">\r\n <span [pTooltip]=\"getTooltip(item, [property.options.promptField || 'prompt', property.options.valueField || 'value'])\">{{item[property.options.promptField || 'prompt']}} ({{item[property.options.valueField || 'value']}})</span>\r\n </ng-template>\r\n <ng-template let-item pTemplate=\"item\">\r\n <span [pTooltip]=\"getTooltip(item, [property.options.promptField || 'prompt', property.options.valueField || 'value'])\">{{item[property.options.promptField || 'prompt']}} ({{item[property.options.valueField || 'value']}})</span>\r\n </ng-template>\r\n </p-dropdown>\r\n </ng-template>\r\n <ng-container *ngIf=\"!property.options.maxItems || property.options.maxItems == 1\">\r\n <ng-container *ngTemplateOutlet=\"inputOptionsSingleRef || defaultInputOptionsSingle; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #defaultInputOptionsMultiple let-property=\"property\" let-template=\"template\">\r\n <p-multiSelect [formControlName]=\"property.name\" [id]=\"property.name\" [options]=\"property.options.inline\" [optionLabel]=\"property.options.promptField || 'prompt'\" [optionValue]=\"property.options.valueField || 'value'\" [readonly]=\"property.readOnly\" [selectionLimit]=\"property.options.maxItems\" [required]=\"property.required || property.options.minItems > 0\"></p-multiSelect>\r\n </ng-template>\r\n <ng-container *ngIf=\"property.options.maxItems > 1\">\r\n <ng-container *ngTemplateOutlet=\"inputOptionsMultipleRef || defaultInputOptionsMultiple; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n </ng-template>\r\n <ng-container *ngIf=\"property.options\">\r\n <ng-container *ngTemplateOutlet=\"inputOptionsRef || defaultInputOptions; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n <div *ngIf=\"!property.options\">\r\n <div [ngSwitch]=\"property.type\">\r\n\r\n <ng-template #defaultInputHidden let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"hidden\" [value]=\"property.value\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Hidden\">\r\n <ng-container *ngTemplateOutlet=\"inputHiddenRef || defaultInputHidden; context:{ property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #defaultInputText let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"text\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Text\">\r\n <ng-container *ngTemplateOutlet=\"inputTextRef || defaultInputText; context:{ property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputTextarea let-property=\"property\" let-template=\"template\">\r\n <textarea [formControlName]=\"property.name\" [id]=\"property.name\" pInputTextarea class=\"w-full p-inputtextarea p-inputtext p-component p-element\" [class.p-disabled]=\"property.readOnly\" [cols]=\"property.cols\" [rows]=\"property.rows\"></textarea>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Textarea\">\r\n <ng-container *ngTemplateOutlet=\"inputTextareaRef || defaultInputTextarea; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputSearch let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"search\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Search\">\r\n <ng-container *ngTemplateOutlet=\"inputSearchRef || defaultInputSearch; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputTel let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"tel\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Tel\">\r\n <ng-container *ngTemplateOutlet=\"inputTelRef || defaultInputTel; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputUrl let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"url\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Url\">\r\n <ng-container *ngTemplateOutlet=\"inputUrlRef || defaultInputUrl; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputEmail let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"email\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Email\">\r\n <ng-container *ngTemplateOutlet=\"inputEmailRef || defaultInputEmail; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputPassword let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"password\" pPassword class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Password\">\r\n <ng-container *ngTemplateOutlet=\"inputPasswordRef || defaultInputPassword; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputDate let-property=\"property\" let-template=\"template\">\r\n <p-calendar [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showWeek]=\"true\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Date\">\r\n <ng-container *ngTemplateOutlet=\"inputDateRef || defaultInputDate; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputMonth let-property=\"property\" let-template=\"template\">\r\n <p-calendar [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showWeek]=\"false\" view=\"month\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Month\">\r\n <ng-container *ngTemplateOutlet=\"inputMonthRef || defaultInputMonth; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputWeek let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"week\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Week\">\r\n <ng-container *ngTemplateOutlet=\"inputWeekRef || defaultInputWeek; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputTime let-property=\"property\" let-template=\"template\">\r\n <p-calendar [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showTime]=\"true\" [timeOnly]=\"true\" [showWeek]=\"false\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Time\">\r\n <ng-container *ngTemplateOutlet=\"inputTimeRef || defaultInputTime; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputDatetimeLocal let-property=\"property\" let-template=\"template\">\r\n <p-calendar [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showTime]=\"true\" [showWeek]=\"false\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.DatetimeLocal\">\r\n <ng-container *ngTemplateOutlet=\"inputDatetimeLocalRef || defaultInputDatetimeLocal; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputNumber let-property=\"property\" let-template=\"template\">\r\n <p-inputNumber [formControlName]=\"property.name\" [id]=\"property.name\" mode=\"decimal\" [showButtons]=\"!property.readOnly\" class=\"w-full\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-inputNumber>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Number\">\r\n <ng-container *ngTemplateOutlet=\"inputNumberRef || defaultInputNumber; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputRange let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"range\" [min]=\"property.min\" [max]=\"property.max\" [step]=\"property.step\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Range\">\r\n <ng-container *ngTemplateOutlet=\"inputRangeRef || defaultInputRange; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputColor let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"color\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Color\">\r\n <ng-container *ngTemplateOutlet=\"inputColorRef || defaultInputColor; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputBool let-property=\"property\" let-template=\"template\" let-formGroup=\"formGroup\">\r\n <p-checkbox *ngIf=\"property.required\" [binary]=\"true\" [formControl]=\"formGroup.controls[property.name]\" [id]=\"property.name\" [readonly]=\"property.readOnly\"></p-checkbox>\r\n <p-triStateCheckbox *ngIf=\"!property.required\" [formControl]=\"formGroup.controls[property.name]\" [id]=\"property.name\" [readonly]=\"property.readOnly\"></p-triStateCheckbox>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Bool\">\r\n <ng-container *ngTemplateOutlet=\"inputBoolRef || defaultInputBool; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputDatetimeOffset let-property=\"property\" let-template=\"template\">\r\n <p-calendar [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showTime]=\"true\" [showWeek]=\"false\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.DatetimeOffset\">\r\n <ng-container *ngTemplateOutlet=\"inputDatetimeOffsetRef || defaultInputDatetimeOffset; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputDuration let-property=\"property\" let-template=\"template\">\r\n <p-calendar *ngSwitchCase=\"PropertyType.Duration\" [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showTime]=\"true\" [timeOnly]=\"true\" [showWeek]=\"false\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Duration\">\r\n <ng-container *ngTemplateOutlet=\"inputDurationRef || defaultInputDuration; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputImage let-property=\"property\" let-template=\"template\">\r\n <rw-image [formControlName]=\"property.name\" [accept]=\"property.placeholder\"></rw-image>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Image\">\r\n <ng-container *ngTemplateOutlet=\"inputImageRef || defaultInputImage; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputFile let-property=\"property\" let-template=\"template\">\r\n <rw-file [formControlName]=\"property.name\" [fileName]=\"property.name\" [accept]=\"property.placeholder\"></rw-file>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.File\">\r\n <ng-container *ngTemplateOutlet=\"inputFileRef || defaultInputFile; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputObject let-property=\"property\" let-template=\"template\">\r\n <div class=\"flex align-items-center\">\r\n <div class=\"brace\">\r\n </div>\r\n <div class=\"w-full\">\r\n <rw-form [formGroup]=\"(formGroup.controls[property.name] | as : FormGroup)\" [template]=\"property._templates.default\" [apiName]=\"apiName\"></rw-form>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Object\">\r\n <ng-container *ngTemplateOutlet=\"inputObjectRef || defaultInputObject; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputCollection let-property=\"property\" let-template=\"template\">\r\n <div class=\"flex align-items-center\">\r\n <div class=\"brace\">\r\n </div>\r\n <div class=\"w-full\" cdkDropList [cdkDropListData]=\"{ property: property, formArray: (formGroup.controls[property.name] | as : FormArray)}\" (cdkDropListDropped)=\"collectionItemDropped($event)\">\r\n <div *ngFor=\"let template of getCollectionEntryTemplates(property)\" class=\"flex align-items-center\" cdkDrag>\r\n <i class=\"fas fa-grip-lines\" cdkDragHandle></i>\r\n <div class=\"brace\">\r\n </div>\r\n <div class=\"w-full flex justify-content-end\">\r\n <rw-form [formGroup]=\"((formGroup.controls[property.name] | as : FormArray).controls[Number.parseInt(template.title!)] | as : FormGroup)\" [template]=\"template\" [apiName]=\"apiName\" class=\"w-full\"></rw-form>\r\n <button pButton pRipple type=\"button\" icon=\"fas fa-trash\" class=\"p-button-outlined p-button-danger ml-2 mb-3\" (click)=\"deleteItemFromCollection(property, formGroup.controls[property.name], template)\"></button>\r\n </div>\r\n </div>\r\n <div class=\"flex justify-content-end w-full\">\r\n <button pButton pRipple type=\"button\" icon=\"fas fa-plus\" class=\"p-button-outlined p-button-info\" (click)=\"addNewItemToCollection(property, formGroup.controls[property.name])\"></button>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-container *ngSwitchCase=\"PropertyType.Collection\">\r\n <ng-container *ngTemplateOutlet=\"inputCollectionRef || defaultInputCollection; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n\r\n <ng-template #defaultInputDefault let-property=\"property\" let-template=\"template\">\r\n <input [formControlName]=\"property.name\" [id]=\"property.name\" type=\"text\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\r\n </ng-template>\r\n <ng-container *ngSwitchDefault>\r\n <ng-container *ngTemplateOutlet=\"inputDefaultRef || defaultInputDefault; context: { property: property, template: template, formGroup: formGroup, apiName: apiName }\"></ng-container>\r\n </ng-container>\r\n\r\n </div>\r\n </div>\r\n <val-errors [controlName]=\"property.name || null\">\r\n <ng-template valError=\"required\">The field '{{property.prompt || property.name}}' is required.</ng-template>\r\n <ng-template valError=\"email\">The email must be a valid email address.</ng-template>\r\n <ng-template valError=\"min\" let-error=\"error\">'{{property.prompt || property.name}}' must be equal or greater than or equal to {{ error.min }}.</ng-template>\r\n <ng-template valError=\"max\" let-error=\"error\">'{{property.prompt || property.name}}' must be smaller than or equal to {{ error.max }}.</ng-template>\r\n <ng-template valError=\"minlength\" let-error=\"error\">The length of '{{property.prompt || property.name}}' must be equal or greater than or equal to {{ error.requiredLength }}.</ng-template>\r\n <ng-template valError=\"maxlength\" let-error=\"error\">The length of '{{property.prompt || property.name}}' must be shorter than or equal to {{ error.requiredLength }}.</ng-template>\r\n <ng-template valError=\"pattern\" let-error=\"error\">The value for '{{property.prompt || property.name}}' does not match the pattern {{ error }}.</ng-template>\r\n <ng-template valError=\"remote\" let-error=\"error\">{{ error }}</ng-template>\r\n </val-errors>\r\n </div>\r\n</div>\r\n", styles: [".brace{align-self:stretch;margin:.2rem .5rem;border-left:1px solid rgb(206,212,218);border-top:1px solid rgb(206,212,218);border-bottom:1px solid rgb(206,212,218);width:1rem}.cdk-drag-handle{cursor:move}.cdk-drag-preview{background-color:#ffffffd0;border:2px dashed rgb(206,212,218);cursor:move}.cdk-drag-placeholder{border:2px dashed rgb(206,212,218);margin:-2px}\n"] }]
|
|
815
|
+
}], ctorParameters: function () { return [{ type: FormService }, { type: i0.ChangeDetectorRef }, { type: i2$1.MessageService }, { type: RESTworldClientCollection }]; }, propDecorators: { formGroup: [{
|
|
816
|
+
type: Input
|
|
817
|
+
}], template: [{
|
|
818
|
+
type: Input
|
|
819
|
+
}], apiName: [{
|
|
820
|
+
type: Input
|
|
821
|
+
}], inputOptionsSingleRef: [{
|
|
822
|
+
type: ContentChild,
|
|
823
|
+
args: ['inputOptionsSingle', { static: false }]
|
|
824
|
+
}], inputOptionsMultipleRef: [{
|
|
825
|
+
type: ContentChild,
|
|
826
|
+
args: ['inputOptionsMultiple', { static: false }]
|
|
827
|
+
}], inputOptionsRef: [{
|
|
828
|
+
type: ContentChild,
|
|
829
|
+
args: ['inputOptions', { static: false }]
|
|
830
|
+
}], inputHiddenRef: [{
|
|
831
|
+
type: ContentChild,
|
|
832
|
+
args: ['inputHidden', { static: false }]
|
|
833
|
+
}], inputTextRef: [{
|
|
834
|
+
type: ContentChild,
|
|
835
|
+
args: ['inputText', { static: false }]
|
|
836
|
+
}], inputTextareaRef: [{
|
|
837
|
+
type: ContentChild,
|
|
838
|
+
args: ['inputTextarea', { static: false }]
|
|
839
|
+
}], inputSearchRef: [{
|
|
840
|
+
type: ContentChild,
|
|
841
|
+
args: ['inputSearch', { static: false }]
|
|
842
|
+
}], inputTelRef: [{
|
|
843
|
+
type: ContentChild,
|
|
844
|
+
args: ['inputTel', { static: false }]
|
|
845
|
+
}], inputUrlRef: [{
|
|
846
|
+
type: ContentChild,
|
|
847
|
+
args: ['inputUrl', { static: false }]
|
|
848
|
+
}], inputEmailRef: [{
|
|
849
|
+
type: ContentChild,
|
|
850
|
+
args: ['inputEmail', { static: false }]
|
|
851
|
+
}], inputPasswordRef: [{
|
|
852
|
+
type: ContentChild,
|
|
853
|
+
args: ['inputPassword', { static: false }]
|
|
854
|
+
}], inputDateRef: [{
|
|
855
|
+
type: ContentChild,
|
|
856
|
+
args: ['inputDate', { static: false }]
|
|
857
|
+
}], inputMonthRef: [{
|
|
858
|
+
type: ContentChild,
|
|
859
|
+
args: ['inputMonth', { static: false }]
|
|
860
|
+
}], inputWeekRef: [{
|
|
861
|
+
type: ContentChild,
|
|
862
|
+
args: ['inputWeek', { static: false }]
|
|
863
|
+
}], inputTimeRef: [{
|
|
864
|
+
type: ContentChild,
|
|
865
|
+
args: ['inputTime', { static: false }]
|
|
866
|
+
}], inputDatetimeLocalRef: [{
|
|
867
|
+
type: ContentChild,
|
|
868
|
+
args: ['inputDatetimeLocal', { static: false }]
|
|
869
|
+
}], inputNumberRef: [{
|
|
870
|
+
type: ContentChild,
|
|
871
|
+
args: ['inputNumber', { static: false }]
|
|
872
|
+
}], inputRangeRef: [{
|
|
873
|
+
type: ContentChild,
|
|
874
|
+
args: ['inputRange', { static: false }]
|
|
875
|
+
}], inputColorRef: [{
|
|
876
|
+
type: ContentChild,
|
|
877
|
+
args: ['inputColor', { static: false }]
|
|
878
|
+
}], inputBoolRef: [{
|
|
879
|
+
type: ContentChild,
|
|
880
|
+
args: ['inputBool', { static: false }]
|
|
881
|
+
}], inputDatetimeOffsetRef: [{
|
|
882
|
+
type: ContentChild,
|
|
883
|
+
args: ['inputDatetimeOffset', { static: false }]
|
|
884
|
+
}], inputDurationRef: [{
|
|
885
|
+
type: ContentChild,
|
|
886
|
+
args: ['inputDuration', { static: false }]
|
|
887
|
+
}], inputImageRef: [{
|
|
888
|
+
type: ContentChild,
|
|
889
|
+
args: ['inputImage', { static: false }]
|
|
890
|
+
}], inputFileRef: [{
|
|
891
|
+
type: ContentChild,
|
|
892
|
+
args: ['inputFile', { static: false }]
|
|
893
|
+
}], inputObjectRef: [{
|
|
894
|
+
type: ContentChild,
|
|
895
|
+
args: ['inputObject', { static: false }]
|
|
896
|
+
}], inputCollectionRef: [{
|
|
897
|
+
type: ContentChild,
|
|
898
|
+
args: ['inputCollection', { static: false }]
|
|
899
|
+
}], inputDefaultRef: [{
|
|
900
|
+
type: ContentChild,
|
|
901
|
+
args: ['inputDefault', { static: false }]
|
|
902
|
+
}] } });
|
|
903
|
+
|
|
904
|
+
class RESTworldEditViewComponent {
|
|
905
|
+
constructor(_clients, _confirmationService, _messageService, _location, _router, _formService, valdemortConfig) {
|
|
906
|
+
this._clients = _clients;
|
|
907
|
+
this._confirmationService = _confirmationService;
|
|
908
|
+
this._messageService = _messageService;
|
|
909
|
+
this._location = _location;
|
|
910
|
+
this._router = _router;
|
|
911
|
+
this._formService = _formService;
|
|
912
|
+
this._templates = {};
|
|
913
|
+
this._formTabs = {};
|
|
914
|
+
this.isLoading = false;
|
|
915
|
+
valdemortConfig.errorClasses = 'p-error text-sm';
|
|
916
|
+
}
|
|
917
|
+
get PropertyType() {
|
|
918
|
+
return PropertyType;
|
|
919
|
+
}
|
|
920
|
+
get templates() {
|
|
921
|
+
return this._templates;
|
|
922
|
+
}
|
|
923
|
+
get isLoadingForTheFirstTime() {
|
|
924
|
+
return Object.keys(this.templates).length === 0 && this.isLoading;
|
|
925
|
+
}
|
|
926
|
+
get formTabs() {
|
|
927
|
+
return this._formTabs;
|
|
928
|
+
}
|
|
929
|
+
set apiName(value) {
|
|
930
|
+
this._apiName = value;
|
|
931
|
+
this.load();
|
|
932
|
+
}
|
|
933
|
+
get apiName() {
|
|
934
|
+
return this._apiName;
|
|
935
|
+
}
|
|
936
|
+
//@Input()
|
|
937
|
+
//public set rel(value: string | undefined) {
|
|
938
|
+
// this._rel = value;
|
|
939
|
+
//}
|
|
940
|
+
//public get rel(): string | undefined {
|
|
941
|
+
// return this._rel;
|
|
942
|
+
//}
|
|
943
|
+
//private _rel?: string;
|
|
944
|
+
set uri(value) {
|
|
945
|
+
this._uri = value;
|
|
946
|
+
this.load();
|
|
947
|
+
}
|
|
948
|
+
get uri() {
|
|
949
|
+
return this._uri;
|
|
950
|
+
}
|
|
951
|
+
get resource() {
|
|
952
|
+
return this._resource;
|
|
953
|
+
}
|
|
954
|
+
get canSave() {
|
|
955
|
+
var _a, _b;
|
|
956
|
+
const length = (_b = (_a = this.resource) === null || _a === void 0 ? void 0 : _a._links["save"]) === null || _b === void 0 ? void 0 : _b.length;
|
|
957
|
+
return length !== undefined && length > 0;
|
|
958
|
+
}
|
|
959
|
+
get canDelete() {
|
|
960
|
+
var _a, _b;
|
|
961
|
+
const length = (_b = (_a = this.resource) === null || _a === void 0 ? void 0 : _a._links["delete"]) === null || _b === void 0 ? void 0 : _b.length;
|
|
962
|
+
return length !== undefined && length > 0;
|
|
963
|
+
}
|
|
964
|
+
canSubmit(templateName) {
|
|
965
|
+
const form = this.formTabs[templateName];
|
|
966
|
+
return form && form.valid;
|
|
967
|
+
}
|
|
968
|
+
getTooltip(resource, keysToExclude) {
|
|
969
|
+
const tooltip = Object.entries(resource)
|
|
970
|
+
.filter(([key]) => !(key.startsWith('_') || ['createdAt', 'createdBy', 'lastChangedAt', 'lastChangedBy', 'timestamp'].includes(key) || (keysToExclude === null || keysToExclude === void 0 ? void 0 : keysToExclude.includes(key))))
|
|
971
|
+
.reduce((prev, [key, value], index) => `${prev}${index === 0 ? '' : '\n'}${key}: ${RESTworldEditViewComponent.jsonStringifyWithElipsis(value)}`, '');
|
|
972
|
+
return tooltip;
|
|
973
|
+
}
|
|
974
|
+
static jsonStringifyWithElipsis(value) {
|
|
975
|
+
const maxLength = 200;
|
|
976
|
+
const end = 10;
|
|
977
|
+
const start = maxLength - end - 2;
|
|
978
|
+
const json = JSON.stringify(value);
|
|
979
|
+
const shortened = json.length > maxLength ? json.substring(0, start) + '…' + json.substring(json.length - end) : json;
|
|
980
|
+
return shortened;
|
|
981
|
+
}
|
|
982
|
+
getClient() {
|
|
983
|
+
if (!this.apiName)
|
|
984
|
+
throw new Error('Cannot get a client, because the apiName is not set.');
|
|
985
|
+
return this._clients.getClient(this.apiName);
|
|
986
|
+
}
|
|
987
|
+
submit(templateName, template, formValue) {
|
|
988
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
989
|
+
this.isLoading = true;
|
|
990
|
+
try {
|
|
991
|
+
const targetBeforeSave = template.target;
|
|
992
|
+
const response = yield this.getClient().submit(template, formValue);
|
|
993
|
+
if (!response.ok) {
|
|
994
|
+
let summary = 'Error';
|
|
995
|
+
let detail = 'Error while saving the resource.';
|
|
996
|
+
if (ProblemDetails.isProblemDetails(response.body)) {
|
|
997
|
+
const problemDetails = response.body;
|
|
998
|
+
summary = problemDetails.title || summary;
|
|
999
|
+
detail = problemDetails.detail || detail;
|
|
1000
|
+
// display validation errors
|
|
1001
|
+
if (problemDetails['errors']) {
|
|
1002
|
+
const form = this.formTabs[templateName];
|
|
1003
|
+
for (const [key, errorsForKey] of Object.entries(problemDetails['errors'])) {
|
|
1004
|
+
const path = key.split(/\.|\[/).map(e => e.replace("]", ""));
|
|
1005
|
+
const formControl = path.reduce((control, pathElement) => (control instanceof FormGroup ? control.controls[pathElement] : control) || control, form);
|
|
1006
|
+
formControl.setErrors({ remote: errorsForKey });
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
this._messageService.add({ severity: 'error', summary: summary, detail: detail, data: response, life: 10000 });
|
|
1011
|
+
}
|
|
1012
|
+
else {
|
|
1013
|
+
const responseResource = response.body;
|
|
1014
|
+
const targetAfterSave = responseResource._templates[templateName].target;
|
|
1015
|
+
setTimeout(() => this._messageService.add({ severity: 'success', summary: 'Saved', detail: 'The resource has been saved.' }), 100);
|
|
1016
|
+
if (targetBeforeSave !== targetAfterSave) {
|
|
1017
|
+
this._router.navigate(['/edit', this.apiName, responseResource._links.self[0].href]);
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
catch (e) {
|
|
1022
|
+
this._messageService.add({ severity: 'error', summary: 'Error', detail: `An unknown error occurred. ${JSON.stringify(e)}`, life: 10000 });
|
|
1023
|
+
console.log(e);
|
|
1024
|
+
}
|
|
1025
|
+
this.isLoading = false;
|
|
1026
|
+
});
|
|
1027
|
+
}
|
|
1028
|
+
showDeleteConfirmatioModal() {
|
|
1029
|
+
this._confirmationService.confirm({
|
|
1030
|
+
message: 'Do you really want to delete this resource?',
|
|
1031
|
+
header: 'Confirm delete',
|
|
1032
|
+
icon: 'far fa-trash-alt',
|
|
1033
|
+
accept: () => this.delete()
|
|
1034
|
+
});
|
|
1035
|
+
}
|
|
1036
|
+
delete() {
|
|
1037
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1038
|
+
if (!this.apiName || !this.uri || !this.resource)
|
|
1039
|
+
return;
|
|
1040
|
+
Object.assign(this.resource, this.formTabs.value);
|
|
1041
|
+
yield this.getClient().delete(this.resource);
|
|
1042
|
+
setTimeout(() => this._messageService.add({ severity: 'success', summary: 'Deleted', detail: 'The resource has been deleted.' }), 100);
|
|
1043
|
+
this._location.back();
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
load() {
|
|
1047
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1048
|
+
if (!this.apiName || !this.uri)
|
|
1049
|
+
return;
|
|
1050
|
+
this.isLoading = true;
|
|
1051
|
+
const response = yield this.getClient().getSingle(this.uri);
|
|
1052
|
+
if (!response.ok || ProblemDetails.isProblemDetails(response.body) || !response.body) {
|
|
1053
|
+
this._messageService.add({ severity: 'error', summary: 'Error', detail: 'Error while loading the resource from the API.', data: response });
|
|
1054
|
+
}
|
|
1055
|
+
else {
|
|
1056
|
+
this._resource = response.body;
|
|
1057
|
+
this._templates = yield this.getAllTemplates(this._resource);
|
|
1058
|
+
this._formTabs = this._formService.createFormGroupsFromTemplates(this._templates);
|
|
1059
|
+
}
|
|
1060
|
+
this.isLoading = false;
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1063
|
+
setInitialSelectedOptionsElementsForTemplates(templates) {
|
|
1064
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1065
|
+
return Promise.all(Object.values(templates)
|
|
1066
|
+
.map(template => this.setInitialSelectedOptionsElementsForTemplate(template)));
|
|
1067
|
+
});
|
|
1068
|
+
}
|
|
1069
|
+
imageChanged(formControl, event) {
|
|
1070
|
+
const file = event.files[0];
|
|
1071
|
+
console.log(file);
|
|
1072
|
+
const reader = new FileReader();
|
|
1073
|
+
reader.onload = () => {
|
|
1074
|
+
const uri = reader.result;
|
|
1075
|
+
console.log(uri);
|
|
1076
|
+
formControl.setValue(uri);
|
|
1077
|
+
};
|
|
1078
|
+
reader.readAsDataURL(file);
|
|
1079
|
+
}
|
|
1080
|
+
setInitialSelectedOptionsElementsForTemplate(template) {
|
|
1081
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1082
|
+
return Promise.all(template.properties
|
|
1083
|
+
.filter(property => { var _a, _b; return (_b = (_a = property === null || property === void 0 ? void 0 : property.options) === null || _a === void 0 ? void 0 : _a.link) === null || _b === void 0 ? void 0 : _b.href; })
|
|
1084
|
+
.map(property => this.setInitialSelectedOptionsElementForProperty(property)));
|
|
1085
|
+
});
|
|
1086
|
+
}
|
|
1087
|
+
setInitialSelectedOptionsElementForProperty(property) {
|
|
1088
|
+
var _a;
|
|
1089
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1090
|
+
const options = property === null || property === void 0 ? void 0 : property.options;
|
|
1091
|
+
if (!((_a = options === null || options === void 0 ? void 0 : options.link) === null || _a === void 0 ? void 0 : _a.href))
|
|
1092
|
+
return;
|
|
1093
|
+
const templatedUri = options.link.href;
|
|
1094
|
+
const filter = `${options.valueField} eq ${property.value}`;
|
|
1095
|
+
const response = yield this.getClient().getListByUri(templatedUri, { $filter: filter, $top: 10 });
|
|
1096
|
+
if (!response.ok || ProblemDetails.isProblemDetails(response.body) || !response.body) {
|
|
1097
|
+
const message = `An error occurred while getting the filtered items.`;
|
|
1098
|
+
this._messageService.add({ severity: 'error', summary: 'Error', detail: message, data: response });
|
|
1099
|
+
return;
|
|
1100
|
+
}
|
|
1101
|
+
const items = response.body._embedded.items;
|
|
1102
|
+
options.inline = items;
|
|
1103
|
+
});
|
|
1104
|
+
}
|
|
1105
|
+
getAllTemplates(resource) {
|
|
1106
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1107
|
+
const formResponses = yield this.getClient().getAllForms(resource);
|
|
1108
|
+
const failedResponses = formResponses.filter(response => !response.ok || ProblemDetails.isProblemDetails(response.body) || !response.body);
|
|
1109
|
+
if (failedResponses.length !== 0) {
|
|
1110
|
+
for (const response of failedResponses) {
|
|
1111
|
+
this._messageService.add({ severity: 'error', summary: 'Error', detail: 'Error while loading the resource from the API.', data: response });
|
|
1112
|
+
}
|
|
1113
|
+
return Promise.resolve({});
|
|
1114
|
+
}
|
|
1115
|
+
const formTemplates = Object.assign({}, ...formResponses.map(response => response.body._templates));
|
|
1116
|
+
yield this.setInitialSelectedOptionsElementsForTemplates(formTemplates);
|
|
1117
|
+
return formTemplates;
|
|
1118
|
+
});
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
RESTworldEditViewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RESTworldEditViewComponent, deps: [{ token: RESTworldClientCollection }, { token: i2$1.ConfirmationService }, { token: i2$1.MessageService }, { token: i3$1.Location }, { token: i4$2.Router }, { token: FormService }, { token: i12.ValdemortConfig }], target: i0.ɵɵFactoryTarget.Component });
|
|
1122
|
+
RESTworldEditViewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.5", type: RESTworldEditViewComponent, selector: "rw-edit", inputs: { apiName: "apiName", uri: "uri" }, queries: [{ propertyName: "extraTabsRef", first: true, predicate: ["extraTabs"], descendants: true }, { propertyName: "buttonsRef", first: true, predicate: ["buttons"], descendants: true }, { propertyName: "inputOptionsSingleRef", first: true, predicate: ["inputOptionsSingle"], descendants: true }, { propertyName: "inputOptionsMultipleRef", first: true, predicate: ["inputOptionsMultiple"], descendants: true }, { propertyName: "inputOptionsRef", first: true, predicate: ["inputOptions"], descendants: true }, { propertyName: "inputHiddenRef", first: true, predicate: ["inputHidden"], descendants: true }, { propertyName: "inputTextRef", first: true, predicate: ["inputText"], descendants: true }, { propertyName: "inputTextareaRef", first: true, predicate: ["inputTextarea"], descendants: true }, { propertyName: "inputSearchRef", first: true, predicate: ["inputSearch"], descendants: true }, { propertyName: "inputTelRef", first: true, predicate: ["inputTel"], descendants: true }, { propertyName: "inputUrlRef", first: true, predicate: ["inputUrl"], descendants: true }, { propertyName: "inputEmailRef", first: true, predicate: ["inputEmail"], descendants: true }, { propertyName: "inputPasswordRef", first: true, predicate: ["inputPassword"], descendants: true }, { propertyName: "inputDateRef", first: true, predicate: ["inputDate"], descendants: true }, { propertyName: "inputMonthRef", first: true, predicate: ["inputMonth"], descendants: true }, { propertyName: "inputWeekRef", first: true, predicate: ["inputWeek"], descendants: true }, { propertyName: "inputTimeRef", first: true, predicate: ["inputTime"], descendants: true }, { propertyName: "inputDatetimeLocalRef", first: true, predicate: ["inputDatetimeLocal"], descendants: true }, { propertyName: "inputNumberRef", first: true, predicate: ["inputNumber"], descendants: true }, { propertyName: "inputRangeRef", first: true, predicate: ["inputRange"], descendants: true }, { propertyName: "inputColorRef", first: true, predicate: ["inputColor"], descendants: true }, { propertyName: "inputBoolRef", first: true, predicate: ["inputBool"], descendants: true }, { propertyName: "inputDatetimeOffsetRef", first: true, predicate: ["inputDatetimeOffset"], descendants: true }, { propertyName: "inputDurationRef", first: true, predicate: ["inputDuration"], descendants: true }, { propertyName: "inputImageRef", first: true, predicate: ["inputImage"], descendants: true }, { propertyName: "inputFileRef", first: true, predicate: ["inputFile"], descendants: true }, { propertyName: "inputDefaultRef", first: true, predicate: ["inputDefault"], descendants: true }], ngImport: i0, template: "<div class=\"grid\">\r\n <div class=\"col\">\r\n <h1>Edit resource</h1>\r\n </div>\r\n</div>\r\n\r\n<p-tabView>\r\n\r\n <p-tabPanel *ngIf=\"isLoadingForTheFirstTime\" header=\"Loading\">\r\n <div *ngFor=\"let i of [1, 2, 3, 4, 5]\" class=\"grid field\">\r\n <p-skeleton class=\"col-12 mb-2 md:col-2 md:mb-0\" height=\"39px\"></p-skeleton>\r\n <div class=\"col-12 md:col-10\">\r\n <p-skeleton class=\"w-full\" height=\"39px\"></p-skeleton>\r\n </div>\r\n </div>\r\n <div class=\"grid\">\r\n <div class=\"col\">\r\n <div class=\"flex justify-content-end w-full\">\r\n <p-skeleton width=\"120px\" height=\"39px\" class=\"mx-2\"></p-skeleton>\r\n <p-skeleton width=\"120px\" height=\"39px\" class=\"mx-2\"></p-skeleton>\r\n <p-skeleton width=\"120px\" height=\"39px\" class=\"mx-2\"></p-skeleton>\r\n </div>\r\n </div>\r\n </div>\r\n </p-tabPanel>\r\n\r\n <p-tabPanel *ngFor=\"let item of templates | keyvalue\" [header]=\"item.value.title || item.key\" [disabled]=\"isLoading\">\r\n <form [formGroup]=\"formTabs[item.key]\" (ngSubmit)=\"submit(item.key, item.value, formTabs[item.key].value)\">\r\n <div class=\"blockable-container\">\r\n <div class=\"blockable-element\">\r\n <rw-form [formGroup]=\"formTabs[item.key]\" [template]=\"item.value\" [apiName]=\"apiName\"></rw-form>\r\n </div>\r\n <div class=\"blockable-overlay\" *ngIf=\"isLoading\">\r\n <p-progressSpinner></p-progressSpinner>\r\n </div>\r\n </div>\r\n\r\n <div class=\"grid\">\r\n <div class=\"col\">\r\n <div class=\"flex justify-content-end w-full\">\r\n <ng-template #defaultButtons>\r\n <button pButton pRipple type=\"submit\" label=\"Save\" icon=\"far fa-save\" class=\"mx-2 p-button-success\" [disabled]=\"isLoading || !canSubmit(item.key)\"></button>\r\n <button pButton pRipple type=\"button\" label=\"Reload\" icon=\"fas fa-redo\" class=\"mx-2 p-button-info\" (click)=\"load()\" [disabled]=\"isLoading\"></button>\r\n <button pButton pRipple type=\"button\" label=\"Delete\" icon=\"far fa-trash-alt\" class=\"ml-2 p-button-danger\" (click)=\"showDeleteConfirmatioModal()\" [disabled]=\"!resource || isLoading || !canDelete\"></button>\r\n </ng-template>\r\n <ng-container *ngTemplateOutlet=\"buttonsRef || defaultButtons\"></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </form>\r\n </p-tabPanel>\r\n\r\n <ng-template #defaultExtraTabs>\r\n </ng-template>\r\n <ng-container *ngTemplateOutlet=\"extraTabsRef || defaultExtraTabs\"></ng-container>\r\n\r\n</p-tabView>\r\n\r\n<p-toast></p-toast>\r\n<p-confirmDialog></p-confirmDialog>\r\n", styles: ["::ng-deep .p-tooltip{max-width:-moz-fit-content!important;max-width:fit-content!important}.blockable-container{display:grid;place-items:center;grid-template-areas:\"inner\"}.blockable-element{grid-area:inner;width:100%}.blockable-overlay{grid-area:inner;height:100%;width:100%;background-color:#0006;display:flex;align-items:center;justify-content:center;z-index:1}.field.grid>label.hasChildren{border-right:1px solid rgba(0,0,0,.1)}\n"], components: [{ type: i7$2.TabView, selector: "p-tabView", inputs: ["orientation", "style", "styleClass", "controlClose", "scrollable", "activeIndex"], outputs: ["onChange", "onClose", "activeIndexChange"] }, { type: i7$2.TabPanel, selector: "p-tabPanel", inputs: ["closable", "headerStyle", "headerStyleClass", "cache", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "selected", "disabled", "header", "leftIcon", "rightIcon"] }, { type: i8$1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "style", "shape", "animation", "borderRadius", "size", "width", "height"] }, { type: RestworldEditFormComponent, selector: "rw-form", inputs: ["formGroup", "template", "apiName"] }, { type: i10$1.ProgressSpinner, selector: "p-progressSpinner", inputs: ["style", "styleClass", "strokeWidth", "fill", "animationDuration"] }, { type: i11.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { type: i12$1.ConfirmDialog, selector: "p-confirmDialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "visible", "position"], outputs: ["onHide"] }], directives: [{ type: i3$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i14.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i14.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i14.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i1$3.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading"] }, { type: i10.Ripple, selector: "[pRipple]" }, { type: i3$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "keyvalue": i3$1.KeyValuePipe } });
|
|
1123
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RESTworldEditViewComponent, decorators: [{
|
|
1124
|
+
type: Component,
|
|
1125
|
+
args: [{ selector: 'rw-edit', template: "<div class=\"grid\">\r\n <div class=\"col\">\r\n <h1>Edit resource</h1>\r\n </div>\r\n</div>\r\n\r\n<p-tabView>\r\n\r\n <p-tabPanel *ngIf=\"isLoadingForTheFirstTime\" header=\"Loading\">\r\n <div *ngFor=\"let i of [1, 2, 3, 4, 5]\" class=\"grid field\">\r\n <p-skeleton class=\"col-12 mb-2 md:col-2 md:mb-0\" height=\"39px\"></p-skeleton>\r\n <div class=\"col-12 md:col-10\">\r\n <p-skeleton class=\"w-full\" height=\"39px\"></p-skeleton>\r\n </div>\r\n </div>\r\n <div class=\"grid\">\r\n <div class=\"col\">\r\n <div class=\"flex justify-content-end w-full\">\r\n <p-skeleton width=\"120px\" height=\"39px\" class=\"mx-2\"></p-skeleton>\r\n <p-skeleton width=\"120px\" height=\"39px\" class=\"mx-2\"></p-skeleton>\r\n <p-skeleton width=\"120px\" height=\"39px\" class=\"mx-2\"></p-skeleton>\r\n </div>\r\n </div>\r\n </div>\r\n </p-tabPanel>\r\n\r\n <p-tabPanel *ngFor=\"let item of templates | keyvalue\" [header]=\"item.value.title || item.key\" [disabled]=\"isLoading\">\r\n <form [formGroup]=\"formTabs[item.key]\" (ngSubmit)=\"submit(item.key, item.value, formTabs[item.key].value)\">\r\n <div class=\"blockable-container\">\r\n <div class=\"blockable-element\">\r\n <rw-form [formGroup]=\"formTabs[item.key]\" [template]=\"item.value\" [apiName]=\"apiName\"></rw-form>\r\n </div>\r\n <div class=\"blockable-overlay\" *ngIf=\"isLoading\">\r\n <p-progressSpinner></p-progressSpinner>\r\n </div>\r\n </div>\r\n\r\n <div class=\"grid\">\r\n <div class=\"col\">\r\n <div class=\"flex justify-content-end w-full\">\r\n <ng-template #defaultButtons>\r\n <button pButton pRipple type=\"submit\" label=\"Save\" icon=\"far fa-save\" class=\"mx-2 p-button-success\" [disabled]=\"isLoading || !canSubmit(item.key)\"></button>\r\n <button pButton pRipple type=\"button\" label=\"Reload\" icon=\"fas fa-redo\" class=\"mx-2 p-button-info\" (click)=\"load()\" [disabled]=\"isLoading\"></button>\r\n <button pButton pRipple type=\"button\" label=\"Delete\" icon=\"far fa-trash-alt\" class=\"ml-2 p-button-danger\" (click)=\"showDeleteConfirmatioModal()\" [disabled]=\"!resource || isLoading || !canDelete\"></button>\r\n </ng-template>\r\n <ng-container *ngTemplateOutlet=\"buttonsRef || defaultButtons\"></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </form>\r\n </p-tabPanel>\r\n\r\n <ng-template #defaultExtraTabs>\r\n </ng-template>\r\n <ng-container *ngTemplateOutlet=\"extraTabsRef || defaultExtraTabs\"></ng-container>\r\n\r\n</p-tabView>\r\n\r\n<p-toast></p-toast>\r\n<p-confirmDialog></p-confirmDialog>\r\n", styles: ["::ng-deep .p-tooltip{max-width:-moz-fit-content!important;max-width:fit-content!important}.blockable-container{display:grid;place-items:center;grid-template-areas:\"inner\"}.blockable-element{grid-area:inner;width:100%}.blockable-overlay{grid-area:inner;height:100%;width:100%;background-color:#0006;display:flex;align-items:center;justify-content:center;z-index:1}.field.grid>label.hasChildren{border-right:1px solid rgba(0,0,0,.1)}\n"] }]
|
|
1126
|
+
}], ctorParameters: function () { return [{ type: RESTworldClientCollection }, { type: i2$1.ConfirmationService }, { type: i2$1.MessageService }, { type: i3$1.Location }, { type: i4$2.Router }, { type: FormService }, { type: i12.ValdemortConfig }]; }, propDecorators: { apiName: [{
|
|
1127
|
+
type: Input
|
|
1128
|
+
}], uri: [{
|
|
1129
|
+
type: Input
|
|
1130
|
+
}], extraTabsRef: [{
|
|
1131
|
+
type: ContentChild,
|
|
1132
|
+
args: ['extraTabs', { static: false }]
|
|
1133
|
+
}], buttonsRef: [{
|
|
1134
|
+
type: ContentChild,
|
|
1135
|
+
args: ['buttons', { static: false }]
|
|
1136
|
+
}], inputOptionsSingleRef: [{
|
|
1137
|
+
type: ContentChild,
|
|
1138
|
+
args: ['inputOptionsSingle', { static: false }]
|
|
1139
|
+
}], inputOptionsMultipleRef: [{
|
|
1140
|
+
type: ContentChild,
|
|
1141
|
+
args: ['inputOptionsMultiple', { static: false }]
|
|
1142
|
+
}], inputOptionsRef: [{
|
|
1143
|
+
type: ContentChild,
|
|
1144
|
+
args: ['inputOptions', { static: false }]
|
|
1145
|
+
}], inputHiddenRef: [{
|
|
1146
|
+
type: ContentChild,
|
|
1147
|
+
args: ['inputHidden', { static: false }]
|
|
1148
|
+
}], inputTextRef: [{
|
|
1149
|
+
type: ContentChild,
|
|
1150
|
+
args: ['inputText', { static: false }]
|
|
1151
|
+
}], inputTextareaRef: [{
|
|
1152
|
+
type: ContentChild,
|
|
1153
|
+
args: ['inputTextarea', { static: false }]
|
|
1154
|
+
}], inputSearchRef: [{
|
|
1155
|
+
type: ContentChild,
|
|
1156
|
+
args: ['inputSearch', { static: false }]
|
|
1157
|
+
}], inputTelRef: [{
|
|
1158
|
+
type: ContentChild,
|
|
1159
|
+
args: ['inputTel', { static: false }]
|
|
1160
|
+
}], inputUrlRef: [{
|
|
1161
|
+
type: ContentChild,
|
|
1162
|
+
args: ['inputUrl', { static: false }]
|
|
1163
|
+
}], inputEmailRef: [{
|
|
1164
|
+
type: ContentChild,
|
|
1165
|
+
args: ['inputEmail', { static: false }]
|
|
1166
|
+
}], inputPasswordRef: [{
|
|
1167
|
+
type: ContentChild,
|
|
1168
|
+
args: ['inputPassword', { static: false }]
|
|
1169
|
+
}], inputDateRef: [{
|
|
1170
|
+
type: ContentChild,
|
|
1171
|
+
args: ['inputDate', { static: false }]
|
|
1172
|
+
}], inputMonthRef: [{
|
|
1173
|
+
type: ContentChild,
|
|
1174
|
+
args: ['inputMonth', { static: false }]
|
|
1175
|
+
}], inputWeekRef: [{
|
|
1176
|
+
type: ContentChild,
|
|
1177
|
+
args: ['inputWeek', { static: false }]
|
|
1178
|
+
}], inputTimeRef: [{
|
|
1179
|
+
type: ContentChild,
|
|
1180
|
+
args: ['inputTime', { static: false }]
|
|
1181
|
+
}], inputDatetimeLocalRef: [{
|
|
1182
|
+
type: ContentChild,
|
|
1183
|
+
args: ['inputDatetimeLocal', { static: false }]
|
|
1184
|
+
}], inputNumberRef: [{
|
|
1185
|
+
type: ContentChild,
|
|
1186
|
+
args: ['inputNumber', { static: false }]
|
|
1187
|
+
}], inputRangeRef: [{
|
|
1188
|
+
type: ContentChild,
|
|
1189
|
+
args: ['inputRange', { static: false }]
|
|
1190
|
+
}], inputColorRef: [{
|
|
1191
|
+
type: ContentChild,
|
|
1192
|
+
args: ['inputColor', { static: false }]
|
|
1193
|
+
}], inputBoolRef: [{
|
|
1194
|
+
type: ContentChild,
|
|
1195
|
+
args: ['inputBool', { static: false }]
|
|
1196
|
+
}], inputDatetimeOffsetRef: [{
|
|
1197
|
+
type: ContentChild,
|
|
1198
|
+
args: ['inputDatetimeOffset', { static: false }]
|
|
1199
|
+
}], inputDurationRef: [{
|
|
1200
|
+
type: ContentChild,
|
|
1201
|
+
args: ['inputDuration', { static: false }]
|
|
1202
|
+
}], inputImageRef: [{
|
|
1203
|
+
type: ContentChild,
|
|
1204
|
+
args: ['inputImage', { static: false }]
|
|
1205
|
+
}], inputFileRef: [{
|
|
1206
|
+
type: ContentChild,
|
|
1207
|
+
args: ['inputFile', { static: false }]
|
|
1208
|
+
}], inputDefaultRef: [{
|
|
1209
|
+
type: ContentChild,
|
|
1210
|
+
args: ['inputDefault', { static: false }]
|
|
1211
|
+
}] } });
|
|
1212
|
+
|
|
1213
|
+
var ColumnType;
|
|
1214
|
+
(function (ColumnType) {
|
|
1215
|
+
ColumnType["text"] = "text";
|
|
1216
|
+
ColumnType["numeric"] = "numeric";
|
|
1217
|
+
ColumnType["boolean"] = "boolean";
|
|
1218
|
+
ColumnType["date"] = "date";
|
|
1219
|
+
})(ColumnType || (ColumnType = {}));
|
|
1220
|
+
class RESTworldListViewComponent {
|
|
1221
|
+
constructor(_clients, _confirmationService, _messageService, avatarGenerator) {
|
|
1222
|
+
this._clients = _clients;
|
|
1223
|
+
this._confirmationService = _confirmationService;
|
|
1224
|
+
this._messageService = _messageService;
|
|
1225
|
+
this.avatarGenerator = avatarGenerator;
|
|
1226
|
+
this._columns = [];
|
|
1227
|
+
this._editLink = '/edit';
|
|
1228
|
+
this.isLoading = false;
|
|
1229
|
+
this._totalRecords = 0;
|
|
1230
|
+
this.rowsPerPage = [10, 25, 50];
|
|
1231
|
+
this._lastEvent = {
|
|
1232
|
+
rows: this.rowsPerPage[0]
|
|
1233
|
+
};
|
|
1234
|
+
}
|
|
1235
|
+
get columns() {
|
|
1236
|
+
return this._columns;
|
|
1237
|
+
}
|
|
1238
|
+
set editLink(value) {
|
|
1239
|
+
if (value)
|
|
1240
|
+
this._editLink = value;
|
|
1241
|
+
}
|
|
1242
|
+
get editLink() {
|
|
1243
|
+
return this._editLink;
|
|
1244
|
+
}
|
|
1245
|
+
set apiName(value) {
|
|
1246
|
+
this._apiName = value;
|
|
1247
|
+
if (this.apiName && this.rel && this._lastEvent)
|
|
1248
|
+
this.load(this._lastEvent);
|
|
1249
|
+
}
|
|
1250
|
+
get apiName() {
|
|
1251
|
+
return this._apiName;
|
|
1252
|
+
}
|
|
1253
|
+
set rel(value) {
|
|
1254
|
+
this._rel = value;
|
|
1255
|
+
if (this.apiName && this.rel && this._lastEvent)
|
|
1256
|
+
this.load(this._lastEvent);
|
|
1257
|
+
}
|
|
1258
|
+
get rel() {
|
|
1259
|
+
return this._rel;
|
|
1260
|
+
}
|
|
1261
|
+
get value() {
|
|
1262
|
+
var _a, _b;
|
|
1263
|
+
return ((_b = (_a = this.resource) === null || _a === void 0 ? void 0 : _a._embedded) === null || _b === void 0 ? void 0 : _b.items) || [];
|
|
1264
|
+
}
|
|
1265
|
+
get rows() {
|
|
1266
|
+
var _a;
|
|
1267
|
+
return ((_a = this._lastEvent) === null || _a === void 0 ? void 0 : _a.rows) || 0;
|
|
1268
|
+
}
|
|
1269
|
+
get totalRecords() {
|
|
1270
|
+
return this._totalRecords;
|
|
1271
|
+
}
|
|
1272
|
+
set totalRecords(value) {
|
|
1273
|
+
this._totalRecords = value || 0;
|
|
1274
|
+
}
|
|
1275
|
+
get sortOrder() {
|
|
1276
|
+
return this._lastEvent.sortOrder || 0;
|
|
1277
|
+
}
|
|
1278
|
+
get newHref() {
|
|
1279
|
+
var _a, _b;
|
|
1280
|
+
return (_b = (_a = this.resource) === null || _a === void 0 ? void 0 : _a.findLink('new')) === null || _b === void 0 ? void 0 : _b.href;
|
|
1281
|
+
}
|
|
1282
|
+
get dateFormat() {
|
|
1283
|
+
return RESTworldListViewComponent._dateFormat;
|
|
1284
|
+
}
|
|
1285
|
+
getClient() {
|
|
1286
|
+
if (!this.apiName)
|
|
1287
|
+
throw new Error('Cannot get a client, because the apiName is not set.');
|
|
1288
|
+
return this._clients.getClient(this.apiName);
|
|
1289
|
+
}
|
|
1290
|
+
load(event) {
|
|
1291
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1292
|
+
if (!this.apiName || !this.rel)
|
|
1293
|
+
return;
|
|
1294
|
+
this.isLoading = true;
|
|
1295
|
+
this._lastEvent = event;
|
|
1296
|
+
const parameters = this.createParametersFromEvent(event);
|
|
1297
|
+
const response = yield this.getClient().getList(this.rel, parameters);
|
|
1298
|
+
if (!response.ok || ProblemDetails.isProblemDetails(response.body) || !response.body) {
|
|
1299
|
+
this._messageService.add({ severity: 'error', summary: 'Error', detail: 'Error while loading the resources from the API.', data: response });
|
|
1300
|
+
}
|
|
1301
|
+
else if (response.body) {
|
|
1302
|
+
this.resource = response.body;
|
|
1303
|
+
this.totalRecords = this.resource.totalPages && parameters.$top ? this.resource.totalPages * parameters.$top : undefined;
|
|
1304
|
+
this._columns = this.createColumns();
|
|
1305
|
+
}
|
|
1306
|
+
this.isLoading = false;
|
|
1307
|
+
});
|
|
1308
|
+
}
|
|
1309
|
+
showDeleteConfirmatioModal(resource) {
|
|
1310
|
+
this._confirmationService.confirm({
|
|
1311
|
+
message: 'Do you really want to delete this resource?',
|
|
1312
|
+
header: 'Confirm delete',
|
|
1313
|
+
icon: 'far fa-trash-alt',
|
|
1314
|
+
accept: () => this.delete(resource)
|
|
1315
|
+
});
|
|
1316
|
+
}
|
|
1317
|
+
delete(resource) {
|
|
1318
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1319
|
+
if (!this.apiName || !this.rel)
|
|
1320
|
+
return;
|
|
1321
|
+
yield this.getClient().delete(resource);
|
|
1322
|
+
this._messageService.add({ severity: 'success', summary: 'Deleted', detail: 'The resource has been deleted.' });
|
|
1323
|
+
this.load(this._lastEvent);
|
|
1324
|
+
});
|
|
1325
|
+
}
|
|
1326
|
+
createColumns() {
|
|
1327
|
+
if (this.value.length === 0)
|
|
1328
|
+
return this.columns;
|
|
1329
|
+
// Get all distinct properties from all rows
|
|
1330
|
+
// We look at all rows to eliminate possible undefined values
|
|
1331
|
+
const rowsWithProperties = this.value
|
|
1332
|
+
.map(resource => Object.entries(resource)
|
|
1333
|
+
.filter(p => p[0] !== '_links' &&
|
|
1334
|
+
p[0] !== '_embedded' &&
|
|
1335
|
+
p[0] !== 'id' &&
|
|
1336
|
+
p[0] !== 'timestamp'));
|
|
1337
|
+
const distinctProperties = rowsWithProperties[0];
|
|
1338
|
+
for (const propertiesOfRow of rowsWithProperties) {
|
|
1339
|
+
for (const property of propertiesOfRow) {
|
|
1340
|
+
const propertyName = property[0];
|
|
1341
|
+
const propertyValue = property[1];
|
|
1342
|
+
const alreadyFoundPropertyWithSameName = distinctProperties.find(p => p[0] === propertyName);
|
|
1343
|
+
if (!alreadyFoundPropertyWithSameName) // Add new property
|
|
1344
|
+
distinctProperties.push(property);
|
|
1345
|
+
else if (!alreadyFoundPropertyWithSameName[1] && propertyValue) // Use defined value instead of existing undefined value
|
|
1346
|
+
alreadyFoundPropertyWithSameName[1] = propertyValue;
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
// Check if the rows are entities with change tracking
|
|
1350
|
+
const withoutChangeTrackingProperties = distinctProperties.filter(p => p[0] !== 'createdAt' &&
|
|
1351
|
+
p[0] !== 'createdBy' &&
|
|
1352
|
+
p[0] !== 'lastChangedAt' &&
|
|
1353
|
+
p[0] !== 'lastChangedBy');
|
|
1354
|
+
const hasChangeTrackingProperties = withoutChangeTrackingProperties.length < distinctProperties.length;
|
|
1355
|
+
// First the id, then all other properties
|
|
1356
|
+
const sortedProperties = [
|
|
1357
|
+
['id', 0],
|
|
1358
|
+
...withoutChangeTrackingProperties
|
|
1359
|
+
];
|
|
1360
|
+
// And change tracking properties at the end
|
|
1361
|
+
if (hasChangeTrackingProperties) {
|
|
1362
|
+
sortedProperties.push(['createdAt', new Date()]);
|
|
1363
|
+
sortedProperties.push(['createdBy', '']);
|
|
1364
|
+
sortedProperties.push(['lastChangedAt', new Date()]);
|
|
1365
|
+
sortedProperties.push(['lastChangedBy', '']);
|
|
1366
|
+
}
|
|
1367
|
+
const columns = sortedProperties
|
|
1368
|
+
.map(p => ({
|
|
1369
|
+
header: RESTworldListViewComponent.toTitleCase(p[0]),
|
|
1370
|
+
field: p[0],
|
|
1371
|
+
type: RESTworldListViewComponent.getColumnType(p[1]),
|
|
1372
|
+
}));
|
|
1373
|
+
return columns;
|
|
1374
|
+
}
|
|
1375
|
+
static getColumnType(value) {
|
|
1376
|
+
if (value === null || value === undefined)
|
|
1377
|
+
return ColumnType.text;
|
|
1378
|
+
if (_.isNumber(value))
|
|
1379
|
+
return ColumnType.numeric;
|
|
1380
|
+
if (_.isDate(value))
|
|
1381
|
+
return ColumnType.date;
|
|
1382
|
+
if (_.isString(value))
|
|
1383
|
+
return ColumnType.text;
|
|
1384
|
+
if (_.isBoolean(value))
|
|
1385
|
+
return ColumnType.boolean;
|
|
1386
|
+
return ColumnType.text;
|
|
1387
|
+
}
|
|
1388
|
+
static toTitleCase(anyCase) {
|
|
1389
|
+
return anyCase
|
|
1390
|
+
.replace(/(_)+/g, ' ') // underscore to whitespace
|
|
1391
|
+
.replace(/([a-z])([A-Z][a-z])/g, "$1 $2") // insert space before each new word if there is none
|
|
1392
|
+
.replace(/([A-Z][a-z])([A-Z])/g, "$1 $2") // insert space after each word if there is none
|
|
1393
|
+
.replace(/([a-z])([A-Z]+[a-z])/g, "$1 $2") // insert space after single letter word if there is none
|
|
1394
|
+
.replace(/([A-Z]+)([A-Z][a-z][a-z])/g, "$1 $2") // insert space before single letter word if there is none
|
|
1395
|
+
.replace(/([a-z]+)([A-Z0-9]+)/g, "$1 $2") // insert space after numbers
|
|
1396
|
+
.replace(/^./, (match) => match.toUpperCase()); // change first letter to be upper case
|
|
1397
|
+
}
|
|
1398
|
+
createParametersFromEvent(event) {
|
|
1399
|
+
const oDataParameters = {
|
|
1400
|
+
$filter: this.createFilterFromEvent(event),
|
|
1401
|
+
$orderby: RESTworldListViewComponent.createOrderByFromEvent(event),
|
|
1402
|
+
$top: RESTworldListViewComponent.createTopFromEvent(event),
|
|
1403
|
+
$skip: RESTworldListViewComponent.createSkipFromEvent(event)
|
|
1404
|
+
};
|
|
1405
|
+
return oDataParameters;
|
|
1406
|
+
}
|
|
1407
|
+
static createSkipFromEvent(event) {
|
|
1408
|
+
return event.first;
|
|
1409
|
+
}
|
|
1410
|
+
static createTopFromEvent(event) {
|
|
1411
|
+
return event.rows;
|
|
1412
|
+
}
|
|
1413
|
+
static createOrderByFromEvent(event) {
|
|
1414
|
+
if (event.sortField) {
|
|
1415
|
+
const order = !event.sortOrder || event.sortOrder > 0 ? 'asc' : 'desc';
|
|
1416
|
+
return `${event.sortField} ${order}`;
|
|
1417
|
+
}
|
|
1418
|
+
return undefined;
|
|
1419
|
+
}
|
|
1420
|
+
createFilterFromEvent(event) {
|
|
1421
|
+
if (!event.filters)
|
|
1422
|
+
return undefined;
|
|
1423
|
+
const filter = Object.entries(event.filters)
|
|
1424
|
+
// The type definition is wrong, event.filters has values of type FilterMetadata[] and not FilterMetadata.
|
|
1425
|
+
.map(([property, filter]) => ({ property: property, filters: filter }))
|
|
1426
|
+
.map(f => this.createFilterForPropertyArray(f.property, f.filters))
|
|
1427
|
+
.filter(f => !!f)
|
|
1428
|
+
.join(' and ');
|
|
1429
|
+
if (filter === '')
|
|
1430
|
+
return undefined;
|
|
1431
|
+
return `(${filter})`;
|
|
1432
|
+
}
|
|
1433
|
+
createFilterForPropertyArray(property, filters) {
|
|
1434
|
+
const filter = filters
|
|
1435
|
+
.map(f => this.createFilterForProperty(property, f))
|
|
1436
|
+
.filter(f => !!f)
|
|
1437
|
+
.join(` ${filters[0].operator} `);
|
|
1438
|
+
if (filter === '')
|
|
1439
|
+
return undefined;
|
|
1440
|
+
return `(${filter})`;
|
|
1441
|
+
}
|
|
1442
|
+
createFilterForProperty(property, filter) {
|
|
1443
|
+
if (!filter.value)
|
|
1444
|
+
return undefined;
|
|
1445
|
+
const oDataOperator = RESTworldListViewComponent.createODataOperator(filter.matchMode);
|
|
1446
|
+
const comparisonValue = this.createComparisonValue(property, filter.value);
|
|
1447
|
+
switch (oDataOperator) {
|
|
1448
|
+
case 'contains':
|
|
1449
|
+
case 'not contains':
|
|
1450
|
+
case 'startswith':
|
|
1451
|
+
case 'endswith':
|
|
1452
|
+
return `${oDataOperator}(${property}, ${comparisonValue})`;
|
|
1453
|
+
default:
|
|
1454
|
+
return `${property} ${oDataOperator} ${comparisonValue}`;
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
static createODataOperator(matchMode) {
|
|
1458
|
+
switch (matchMode) {
|
|
1459
|
+
case FilterMatchMode.STARTS_WITH:
|
|
1460
|
+
return 'startswith';
|
|
1461
|
+
case FilterMatchMode.CONTAINS:
|
|
1462
|
+
return 'contains';
|
|
1463
|
+
case FilterMatchMode.NOT_CONTAINS:
|
|
1464
|
+
return 'not contains';
|
|
1465
|
+
case FilterMatchMode.ENDS_WITH:
|
|
1466
|
+
return 'endswith';
|
|
1467
|
+
case FilterMatchMode.EQUALS:
|
|
1468
|
+
return 'eq';
|
|
1469
|
+
case FilterMatchMode.NOT_EQUALS:
|
|
1470
|
+
return 'ne';
|
|
1471
|
+
case FilterMatchMode.IN:
|
|
1472
|
+
return 'in';
|
|
1473
|
+
case FilterMatchMode.LESS_THAN:
|
|
1474
|
+
return 'lt';
|
|
1475
|
+
case FilterMatchMode.LESS_THAN_OR_EQUAL_TO:
|
|
1476
|
+
return 'le';
|
|
1477
|
+
case FilterMatchMode.GREATER_THAN:
|
|
1478
|
+
return 'gt';
|
|
1479
|
+
case FilterMatchMode.GREATER_THAN_OR_EQUAL_TO:
|
|
1480
|
+
return 'ge';
|
|
1481
|
+
case FilterMatchMode.IS:
|
|
1482
|
+
return 'eq';
|
|
1483
|
+
case FilterMatchMode.IS_NOT:
|
|
1484
|
+
return 'ne';
|
|
1485
|
+
case FilterMatchMode.BEFORE:
|
|
1486
|
+
return 'lt';
|
|
1487
|
+
case FilterMatchMode.AFTER:
|
|
1488
|
+
return 'gt';
|
|
1489
|
+
case FilterMatchMode.DATE_AFTER:
|
|
1490
|
+
return 'ge';
|
|
1491
|
+
case FilterMatchMode.DATE_BEFORE:
|
|
1492
|
+
return 'lt';
|
|
1493
|
+
case FilterMatchMode.DATE_IS:
|
|
1494
|
+
return 'eq';
|
|
1495
|
+
case FilterMatchMode.DATE_IS_NOT:
|
|
1496
|
+
return 'ne';
|
|
1497
|
+
default:
|
|
1498
|
+
throw Error(`Unknown matchMode ${matchMode}`);
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
createComparisonValue(property, value) {
|
|
1502
|
+
if (value === null || value === undefined)
|
|
1503
|
+
return 'null';
|
|
1504
|
+
const columns = this.columns.filter(c => c.field === property);
|
|
1505
|
+
if (columns.length !== 1)
|
|
1506
|
+
throw new Error(`Cannot find the column for the property ${property} which is specified in the filter.`);
|
|
1507
|
+
const type = columns[0].type;
|
|
1508
|
+
switch (type) {
|
|
1509
|
+
case ColumnType.boolean:
|
|
1510
|
+
return `${value}`;
|
|
1511
|
+
case ColumnType.date:
|
|
1512
|
+
return `cast(${value.toISOString()}, Edm.DateTimeOffset)`;
|
|
1513
|
+
case ColumnType.numeric:
|
|
1514
|
+
return `${value}`;
|
|
1515
|
+
case ColumnType.text:
|
|
1516
|
+
return `'${value}'`;
|
|
1517
|
+
default:
|
|
1518
|
+
throw new Error(`Unknown column type '${type}'`);
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
RESTworldListViewComponent._dateFormat = new Date(3333, 10, 22)
|
|
1523
|
+
.toLocaleDateString()
|
|
1524
|
+
.replace("22", "dd")
|
|
1525
|
+
.replace("11", "MM")
|
|
1526
|
+
.replace("3333", "y")
|
|
1527
|
+
.replace("33", "yy");
|
|
1528
|
+
RESTworldListViewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RESTworldListViewComponent, deps: [{ token: RESTworldClientCollection }, { token: i2$1.ConfirmationService }, { token: i2$1.MessageService }, { token: AvatarGenerator }], target: i0.ɵɵFactoryTarget.Component });
|
|
1529
|
+
RESTworldListViewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.5", type: RESTworldListViewComponent, selector: "rw-list", inputs: { editLink: "editLink", apiName: "apiName", rel: "rel", rowsPerPage: "rowsPerPage" }, ngImport: i0, template: "<p-table [value]=\"value\"\r\n [lazy]=\"true\"\r\n [lazyLoadOnInit]=\"false\"\r\n (onLazyLoad)=\"load($event)\"\r\n responsiveLayout=\"scroll\"\r\n [paginator]=\"true\"\r\n [rows]=\"rows\"\r\n [rowsPerPageOptions]=\"rowsPerPage\"\r\n [totalRecords]=\"totalRecords\"\r\n [loading]=\"isLoading\"\r\n [showInitialSortBadge]=\"true\"\r\n [columns]=\"columns\">\r\n\r\n <ng-template pTemplate=\"header\" let-columns>\r\n <tr>\r\n <th *ngFor=\"let col of columns\" [pSortableColumn]=\"col.field\">\r\n <div class=\"p-d-flex p-jc-between p-ai-center\">\r\n {{col.header}}\r\n <p-sortIcon [field]=\"col.field\"></p-sortIcon>\r\n <p-columnFilter [type]=\"col.type\" [field]=\"col.field\" display=\"menu\"></p-columnFilter>\r\n </div>\r\n </th>\r\n <th>\r\n <div class=\"flex justify-content-end\">\r\n <div class=\"mx-2\" pTooltip=\"Create new\" tooltipPosition=\"left\">\r\n <a class=\"p-button-success\" icon=\"fas fa-plus\" pButton [routerLink]=\"['/edit', apiName, newHref]\"></a>\r\n </div>\r\n </div>\r\n </th>\r\n </tr>\r\n </ng-template>\r\n\r\n <ng-template pTemplate=\"body\" let-entity let-columns=\"columns\">\r\n <tr>\r\n <td [ngSwitch]=\"col.type\" *ngFor=\"let col of columns\">\r\n <ng-container *ngSwitchCase=\"'text'\">\r\n <p-avatar *ngIf=\"col.field === 'createdBy' || col.field === 'lastChangedBy'\" [pTooltip]=\"entity[col.field]\" tooltipPosition=\"top\" [image]=\"avatarGenerator.getImage(entity[col.field])\" [label]=\"avatarGenerator.getLabel(entity[col.field])\" [style]=\"avatarGenerator.getStyle(entity[col.field])\" shape=\"circle\"></p-avatar>\r\n <span *ngIf=\"col.field !== 'createdBy' && col.field !== 'lastChangedBy'\">{{entity[col.field]}}</span>\r\n </ng-container>\r\n <span *ngSwitchCase=\"'numeric'\" class=\"flex justify-content-end\">{{entity[col.field]}}</span>\r\n <span *ngSwitchCase=\"'boolean'\" class=\"flex justify-content-center\"><p-triStateCheckbox [(ngModel)]=\"entity[col.field]\" [readonly]=\"true\"></p-triStateCheckbox></span>\r\n <span *ngSwitchCase=\"'date'\" [pTooltip]=\"entity[col.field]\">{{entity[col.field] | date:dateFormat}}</span>\r\n </td>\r\n <td>\r\n <div class=\"flex justify-content-end\">\r\n <a pButton pTooltip=\"View/Edit\" tooltipPosition=\"left\" [routerLink]=\"[editLink, apiName, entity._links?.self[0].href]\" icon=\"fas fa-edit\"></a>\r\n <button pTooltip=\"Delete\" tooltipPosition=\"left\" pButton *ngIf=\"entity._links.delete\" (click)=\"showDeleteConfirmatioModal(entity)\" icon=\"fas fa-trash-alt\" type=\"button\" class=\"mx-2 p-button-danger\"></button>\r\n </div>\r\n </td>\r\n </tr>\r\n </ng-template>\r\n\r\n <ng-template pTemplate=\"emptymessage\">\r\n <tr>\r\n <td colspan=\"8\">No entries found.</td>\r\n </tr>\r\n </ng-template>\r\n\r\n</p-table>\r\n\r\n<p-toast></p-toast>\r\n<p-confirmDialog></p-confirmDialog>\r\n", styles: [".p-tooltip{max-width:-moz-fit-content;max-width:fit-content}a.p-button{text-decoration:none}\n"], components: [{ type: i4$3.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollDelay", "virtualRowHeight", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "groupRowsByOrder", "minBufferPx", "maxBufferPx", "responsiveLayout", "breakpoint", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["selectAllChange", "selectionChange", "contextMenuSelectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { type: i4$3.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { type: i4$3.ColumnFilter, selector: "p-columnFilter", inputs: ["field", "type", "display", "showMenu", "matchMode", "operator", "showOperator", "showClearButton", "showApplyButton", "showMatchModes", "showAddButton", "hideOnClear", "placeholder", "matchModeOptions", "maxConstraints", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "locale", "localeMatcher", "currency", "currencyDisplay", "useGrouping"] }, { type: i5$2.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "style", "styleClass"] }, { type: i9$1.TriStateCheckbox, selector: "p-triStateCheckbox", inputs: ["disabled", "name", "ariaLabelledBy", "tabindex", "inputId", "style", "styleClass", "label", "readonly", "checkboxTrueIcon", "checkboxFalseIcon"], outputs: ["onChange"] }, { type: i11.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { type: i12$1.ConfirmDialog, selector: "p-confirmDialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "visible", "position"], outputs: ["onHide"] }], directives: [{ type: i2$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { type: i3$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4$3.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { type: i7.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { type: i4$2.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }, { type: i1$3.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading"] }, { type: i3$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i3$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i3$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i14.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i14.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], pipes: { "date": i3$1.DatePipe } });
|
|
1530
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RESTworldListViewComponent, decorators: [{
|
|
1531
|
+
type: Component,
|
|
1532
|
+
args: [{ selector: 'rw-list', template: "<p-table [value]=\"value\"\r\n [lazy]=\"true\"\r\n [lazyLoadOnInit]=\"false\"\r\n (onLazyLoad)=\"load($event)\"\r\n responsiveLayout=\"scroll\"\r\n [paginator]=\"true\"\r\n [rows]=\"rows\"\r\n [rowsPerPageOptions]=\"rowsPerPage\"\r\n [totalRecords]=\"totalRecords\"\r\n [loading]=\"isLoading\"\r\n [showInitialSortBadge]=\"true\"\r\n [columns]=\"columns\">\r\n\r\n <ng-template pTemplate=\"header\" let-columns>\r\n <tr>\r\n <th *ngFor=\"let col of columns\" [pSortableColumn]=\"col.field\">\r\n <div class=\"p-d-flex p-jc-between p-ai-center\">\r\n {{col.header}}\r\n <p-sortIcon [field]=\"col.field\"></p-sortIcon>\r\n <p-columnFilter [type]=\"col.type\" [field]=\"col.field\" display=\"menu\"></p-columnFilter>\r\n </div>\r\n </th>\r\n <th>\r\n <div class=\"flex justify-content-end\">\r\n <div class=\"mx-2\" pTooltip=\"Create new\" tooltipPosition=\"left\">\r\n <a class=\"p-button-success\" icon=\"fas fa-plus\" pButton [routerLink]=\"['/edit', apiName, newHref]\"></a>\r\n </div>\r\n </div>\r\n </th>\r\n </tr>\r\n </ng-template>\r\n\r\n <ng-template pTemplate=\"body\" let-entity let-columns=\"columns\">\r\n <tr>\r\n <td [ngSwitch]=\"col.type\" *ngFor=\"let col of columns\">\r\n <ng-container *ngSwitchCase=\"'text'\">\r\n <p-avatar *ngIf=\"col.field === 'createdBy' || col.field === 'lastChangedBy'\" [pTooltip]=\"entity[col.field]\" tooltipPosition=\"top\" [image]=\"avatarGenerator.getImage(entity[col.field])\" [label]=\"avatarGenerator.getLabel(entity[col.field])\" [style]=\"avatarGenerator.getStyle(entity[col.field])\" shape=\"circle\"></p-avatar>\r\n <span *ngIf=\"col.field !== 'createdBy' && col.field !== 'lastChangedBy'\">{{entity[col.field]}}</span>\r\n </ng-container>\r\n <span *ngSwitchCase=\"'numeric'\" class=\"flex justify-content-end\">{{entity[col.field]}}</span>\r\n <span *ngSwitchCase=\"'boolean'\" class=\"flex justify-content-center\"><p-triStateCheckbox [(ngModel)]=\"entity[col.field]\" [readonly]=\"true\"></p-triStateCheckbox></span>\r\n <span *ngSwitchCase=\"'date'\" [pTooltip]=\"entity[col.field]\">{{entity[col.field] | date:dateFormat}}</span>\r\n </td>\r\n <td>\r\n <div class=\"flex justify-content-end\">\r\n <a pButton pTooltip=\"View/Edit\" tooltipPosition=\"left\" [routerLink]=\"[editLink, apiName, entity._links?.self[0].href]\" icon=\"fas fa-edit\"></a>\r\n <button pTooltip=\"Delete\" tooltipPosition=\"left\" pButton *ngIf=\"entity._links.delete\" (click)=\"showDeleteConfirmatioModal(entity)\" icon=\"fas fa-trash-alt\" type=\"button\" class=\"mx-2 p-button-danger\"></button>\r\n </div>\r\n </td>\r\n </tr>\r\n </ng-template>\r\n\r\n <ng-template pTemplate=\"emptymessage\">\r\n <tr>\r\n <td colspan=\"8\">No entries found.</td>\r\n </tr>\r\n </ng-template>\r\n\r\n</p-table>\r\n\r\n<p-toast></p-toast>\r\n<p-confirmDialog></p-confirmDialog>\r\n", styles: [".p-tooltip{max-width:-moz-fit-content;max-width:fit-content}a.p-button{text-decoration:none}\n"] }]
|
|
1533
|
+
}], ctorParameters: function () { return [{ type: RESTworldClientCollection }, { type: i2$1.ConfirmationService }, { type: i2$1.MessageService }, { type: AvatarGenerator }]; }, propDecorators: { editLink: [{
|
|
1534
|
+
type: Input
|
|
1535
|
+
}], apiName: [{
|
|
1536
|
+
type: Input
|
|
1537
|
+
}], rel: [{
|
|
1538
|
+
type: Input
|
|
1539
|
+
}], rowsPerPage: [{
|
|
1540
|
+
type: Input
|
|
1541
|
+
}] } });
|
|
1542
|
+
|
|
1543
|
+
function initializeSettings(settingsService) {
|
|
1544
|
+
return () => __awaiter(this, void 0, void 0, function* () { return yield settingsService.initialize(); });
|
|
1545
|
+
}
|
|
1546
|
+
class RestworldClientModule {
|
|
1547
|
+
}
|
|
1548
|
+
RestworldClientModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RestworldClientModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1549
|
+
RestworldClientModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RestworldClientModule, declarations: [RESTworldListViewComponent,
|
|
1550
|
+
RESTworldEditViewComponent,
|
|
1551
|
+
RESTWorldImageViewComponent,
|
|
1552
|
+
RESTWorldFileViewComponent,
|
|
1553
|
+
SafeUrlPipe,
|
|
1554
|
+
AsPipe,
|
|
1555
|
+
RestworldEditFormComponent], imports: [CommonModule,
|
|
1556
|
+
RouterModule,
|
|
1557
|
+
FormsModule,
|
|
1558
|
+
ReactiveFormsModule,
|
|
1559
|
+
TableModule,
|
|
1560
|
+
TooltipModule,
|
|
1561
|
+
ScrollingModule,
|
|
1562
|
+
InputTextModule,
|
|
1563
|
+
InputNumberModule,
|
|
1564
|
+
CalendarModule,
|
|
1565
|
+
CheckboxModule,
|
|
1566
|
+
ConfirmDialogModule,
|
|
1567
|
+
ToastModule,
|
|
1568
|
+
MessagesModule,
|
|
1569
|
+
PanelModule,
|
|
1570
|
+
TabViewModule,
|
|
1571
|
+
SkeletonModule,
|
|
1572
|
+
ProgressSpinnerModule,
|
|
1573
|
+
RippleModule,
|
|
1574
|
+
TriStateCheckboxModule,
|
|
1575
|
+
AvatarModule,
|
|
1576
|
+
DropdownModule,
|
|
1577
|
+
MultiSelectModule,
|
|
1578
|
+
FileUploadModule,
|
|
1579
|
+
ValdemortModule,
|
|
1580
|
+
ImageCropperModule,
|
|
1581
|
+
DialogModule,
|
|
1582
|
+
ButtonModule,
|
|
1583
|
+
ColorPickerModule,
|
|
1584
|
+
DragDropModule], exports: [RESTworldListViewComponent,
|
|
1585
|
+
RESTworldEditViewComponent,
|
|
1586
|
+
RESTWorldImageViewComponent,
|
|
1587
|
+
RESTWorldFileViewComponent,
|
|
1588
|
+
SafeUrlPipe] });
|
|
1589
|
+
RestworldClientModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RestworldClientModule, providers: [
|
|
1590
|
+
RESTworldClientCollection,
|
|
1591
|
+
AvatarGenerator,
|
|
1592
|
+
ConfirmationService,
|
|
1593
|
+
FormService,
|
|
1594
|
+
MessageService,
|
|
1595
|
+
{
|
|
1596
|
+
provide: APP_INITIALIZER,
|
|
1597
|
+
useFactory: initializeSettings,
|
|
1598
|
+
deps: [SettingsService],
|
|
1599
|
+
multi: true,
|
|
1600
|
+
}
|
|
1601
|
+
], imports: [[
|
|
1602
|
+
CommonModule,
|
|
1603
|
+
RouterModule,
|
|
1604
|
+
FormsModule,
|
|
1605
|
+
ReactiveFormsModule,
|
|
1606
|
+
TableModule,
|
|
1607
|
+
TooltipModule,
|
|
1608
|
+
ScrollingModule,
|
|
1609
|
+
InputTextModule,
|
|
1610
|
+
InputNumberModule,
|
|
1611
|
+
CalendarModule,
|
|
1612
|
+
CheckboxModule,
|
|
1613
|
+
ConfirmDialogModule,
|
|
1614
|
+
ToastModule,
|
|
1615
|
+
MessagesModule,
|
|
1616
|
+
PanelModule,
|
|
1617
|
+
TabViewModule,
|
|
1618
|
+
SkeletonModule,
|
|
1619
|
+
ProgressSpinnerModule,
|
|
1620
|
+
RippleModule,
|
|
1621
|
+
TriStateCheckboxModule,
|
|
1622
|
+
AvatarModule,
|
|
1623
|
+
DropdownModule,
|
|
1624
|
+
MultiSelectModule,
|
|
1625
|
+
FileUploadModule,
|
|
1626
|
+
ValdemortModule,
|
|
1627
|
+
ImageCropperModule,
|
|
1628
|
+
DialogModule,
|
|
1629
|
+
ButtonModule,
|
|
1630
|
+
ColorPickerModule,
|
|
1631
|
+
DragDropModule
|
|
1632
|
+
]] });
|
|
1633
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RestworldClientModule, decorators: [{
|
|
1634
|
+
type: NgModule,
|
|
1635
|
+
args: [{
|
|
1636
|
+
declarations: [
|
|
1637
|
+
RESTworldListViewComponent,
|
|
1638
|
+
RESTworldEditViewComponent,
|
|
1639
|
+
RESTWorldImageViewComponent,
|
|
1640
|
+
RESTWorldFileViewComponent,
|
|
1641
|
+
SafeUrlPipe,
|
|
1642
|
+
AsPipe,
|
|
1643
|
+
RestworldEditFormComponent
|
|
1644
|
+
],
|
|
1645
|
+
imports: [
|
|
1646
|
+
CommonModule,
|
|
1647
|
+
RouterModule,
|
|
1648
|
+
FormsModule,
|
|
1649
|
+
ReactiveFormsModule,
|
|
1650
|
+
TableModule,
|
|
1651
|
+
TooltipModule,
|
|
1652
|
+
ScrollingModule,
|
|
1653
|
+
InputTextModule,
|
|
1654
|
+
InputNumberModule,
|
|
1655
|
+
CalendarModule,
|
|
1656
|
+
CheckboxModule,
|
|
1657
|
+
ConfirmDialogModule,
|
|
1658
|
+
ToastModule,
|
|
1659
|
+
MessagesModule,
|
|
1660
|
+
PanelModule,
|
|
1661
|
+
TabViewModule,
|
|
1662
|
+
SkeletonModule,
|
|
1663
|
+
ProgressSpinnerModule,
|
|
1664
|
+
RippleModule,
|
|
1665
|
+
TriStateCheckboxModule,
|
|
1666
|
+
AvatarModule,
|
|
1667
|
+
DropdownModule,
|
|
1668
|
+
MultiSelectModule,
|
|
1669
|
+
FileUploadModule,
|
|
1670
|
+
ValdemortModule,
|
|
1671
|
+
ImageCropperModule,
|
|
1672
|
+
DialogModule,
|
|
1673
|
+
ButtonModule,
|
|
1674
|
+
ColorPickerModule,
|
|
1675
|
+
DragDropModule
|
|
1676
|
+
],
|
|
1677
|
+
exports: [
|
|
1678
|
+
RESTworldListViewComponent,
|
|
1679
|
+
RESTworldEditViewComponent,
|
|
1680
|
+
RESTWorldImageViewComponent,
|
|
1681
|
+
RESTWorldFileViewComponent,
|
|
1682
|
+
SafeUrlPipe
|
|
1683
|
+
],
|
|
1684
|
+
providers: [
|
|
1685
|
+
RESTworldClientCollection,
|
|
1686
|
+
AvatarGenerator,
|
|
1687
|
+
ConfirmationService,
|
|
1688
|
+
FormService,
|
|
1689
|
+
MessageService,
|
|
1690
|
+
{
|
|
1691
|
+
provide: APP_INITIALIZER,
|
|
1692
|
+
useFactory: initializeSettings,
|
|
1693
|
+
deps: [SettingsService],
|
|
1694
|
+
multi: true,
|
|
1695
|
+
}
|
|
1696
|
+
]
|
|
1697
|
+
}]
|
|
1698
|
+
}] });
|
|
1699
|
+
|
|
1700
|
+
/*
|
|
1701
|
+
* Public API Surface of ngx-restworld-client
|
|
1702
|
+
*/
|
|
1703
|
+
|
|
1704
|
+
/**
|
|
1705
|
+
* Generated bundle index. Do not edit.
|
|
1706
|
+
*/
|
|
1707
|
+
|
|
1708
|
+
export { AsPipe, AvatarGenerator, ColumnType, FormService, LinkNames, ProblemDetails, RESTWorldFileViewComponent, RESTWorldImageViewComponent, RESTworldClient, RESTworldClientCollection, RESTworldEditViewComponent, RESTworldListViewComponent, RESTworldOptions, RestworldClientModule, RestworldEditFormComponent, SafeUrlPipe, SettingsService, initializeSettings };
|
|
1709
|
+
//# sourceMappingURL=wertzui-ngx-restworld-client.mjs.map
|