@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.
Files changed (39) hide show
  1. package/{esm2015/lib/constants/link-names.js → esm2020/lib/constants/link-names.mjs} +0 -0
  2. package/{esm2015/lib/models/api-url.js → esm2020/lib/models/api-url.mjs} +0 -0
  3. package/{esm2015/lib/models/client-settings.js → esm2020/lib/models/client-settings.mjs} +1 -1
  4. package/{esm2015/lib/models/problem-details.js → esm2020/lib/models/problem-details.mjs} +0 -0
  5. package/{esm2015/lib/models/restworld-options.js → esm2020/lib/models/restworld-options.mjs} +0 -0
  6. package/{esm2015/lib/pipes/as.pipe.js → esm2020/lib/pipes/as.pipe.mjs} +4 -4
  7. package/{esm2015/lib/pipes/safe-url.pipe.js → esm2020/lib/pipes/safe-url.pipe.mjs} +4 -4
  8. package/esm2020/lib/restworld-client.module.mjs +200 -0
  9. package/{esm2015/lib/services/avatar-generator.js → esm2020/lib/services/avatar-generator.mjs} +4 -4
  10. package/{esm2015/lib/services/form.service.js → esm2020/lib/services/form.service.mjs} +4 -4
  11. package/esm2020/lib/services/restworld-client-collection.mjs +39 -0
  12. package/esm2020/lib/services/restworld-client.mjs +165 -0
  13. package/esm2020/lib/services/settings.service.mjs +39 -0
  14. package/esm2020/lib/views/restworld-edit-form/restworld-edit-form.component.mjs +230 -0
  15. package/esm2020/lib/views/restworld-edit-view/restworld-edit-view.component.mjs +313 -0
  16. package/esm2020/lib/views/restworld-file-view/restworld-file-view.component.mjs +57 -0
  17. package/esm2020/lib/views/restworld-image-view/restworld-image-view.component.mjs +100 -0
  18. package/esm2020/lib/views/restworld-list-view/restworld-list-view.component.mjs +341 -0
  19. package/{esm2015/public-api.js → esm2020/public-api.mjs} +0 -0
  20. package/{esm2015/wertzui-ngx-restworld-client.js → esm2020/wertzui-ngx-restworld-client.mjs} +0 -0
  21. package/fesm2015/wertzui-ngx-restworld-client.mjs +1709 -0
  22. package/fesm2015/wertzui-ngx-restworld-client.mjs.map +1 -0
  23. package/fesm2020/wertzui-ngx-restworld-client.mjs +1649 -0
  24. package/fesm2020/wertzui-ngx-restworld-client.mjs.map +1 -0
  25. package/lib/models/client-settings.d.ts +4 -1
  26. package/package.json +42 -31
  27. package/bundles/wertzui-ngx-restworld-client.umd.js +0 -2477
  28. package/bundles/wertzui-ngx-restworld-client.umd.js.map +0 -1
  29. package/esm2015/lib/restworld-client.module.js +0 -201
  30. package/esm2015/lib/services/restworld-client-collection.js +0 -42
  31. package/esm2015/lib/services/restworld-client.js +0 -183
  32. package/esm2015/lib/services/settings.service.js +0 -47
  33. package/esm2015/lib/views/restworld-edit-form/restworld-edit-form.component.js +0 -238
  34. package/esm2015/lib/views/restworld-edit-view/restworld-edit-view.component.js +0 -335
  35. package/esm2015/lib/views/restworld-file-view/restworld-file-view.component.js +0 -63
  36. package/esm2015/lib/views/restworld-image-view/restworld-image-view.component.js +0 -107
  37. package/esm2015/lib/views/restworld-list-view/restworld-list-view.component.js +0 -353
  38. package/fesm2015/wertzui-ngx-restworld-client.js +0 -1728
  39. 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:&nbsp;</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:&nbsp;</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