@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,1649 @@
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 * as i1$2 from '@angular/common/http';
10
+ import { HttpHeaders, HttpClient } from '@angular/common/http';
11
+ import * as i2$1 from 'primeng/api';
12
+ import { FilterMatchMode, ConfirmationService, MessageService } from 'primeng/api';
13
+ import * as i4$1 from 'primeng/dropdown';
14
+ import { DropdownModule } from 'primeng/dropdown';
15
+ import * as i5$1 from 'primeng/multiselect';
16
+ import { MultiSelectModule } from 'primeng/multiselect';
17
+ import * as i6 from 'primeng/calendar';
18
+ import { CalendarModule } from 'primeng/calendar';
19
+ import * as i7$1 from 'primeng/inputnumber';
20
+ import { InputNumberModule } from 'primeng/inputnumber';
21
+ import * as i8 from 'primeng/checkbox';
22
+ import { CheckboxModule } from 'primeng/checkbox';
23
+ import * as i9$1 from 'primeng/tristatecheckbox';
24
+ import { TriStateCheckboxModule } from 'primeng/tristatecheckbox';
25
+ import * as i2 from 'primeng/fileupload';
26
+ import { FileUpload, FileUploadModule } from 'primeng/fileupload';
27
+ import * as i1$3 from 'primeng/button';
28
+ import { ButtonModule } from 'primeng/button';
29
+ import * as i3 from 'primeng/dialog';
30
+ import { DialogModule } from 'primeng/dialog';
31
+ import * as i4 from 'ngx-image-cropper';
32
+ import { ImageCropperModule } from 'ngx-image-cropper';
33
+ import * as i5 from 'primeng/colorpicker';
34
+ import { ColorPickerModule } from 'primeng/colorpicker';
35
+ import * as i3$1 from '@angular/common';
36
+ import { CommonModule } from '@angular/common';
37
+ import * as i7 from 'primeng/tooltip';
38
+ import { TooltipModule } from 'primeng/tooltip';
39
+ import * as i9 from 'primeng/inputtext';
40
+ import { InputTextModule } from 'primeng/inputtext';
41
+ import * as i10 from 'primeng/ripple';
42
+ import { RippleModule } from 'primeng/ripple';
43
+ import * as i12 from 'ngx-valdemort';
44
+ import { ValdemortModule } from 'ngx-valdemort';
45
+ import * as i17 from '@angular/cdk/drag-drop';
46
+ import { DragDropModule } from '@angular/cdk/drag-drop';
47
+ import * as i4$2 from '@angular/router';
48
+ import { RouterModule } from '@angular/router';
49
+ import * as i7$2 from 'primeng/tabview';
50
+ import { TabViewModule } from 'primeng/tabview';
51
+ import * as i8$1 from 'primeng/skeleton';
52
+ import { SkeletonModule } from 'primeng/skeleton';
53
+ import * as i10$1 from 'primeng/progressspinner';
54
+ import { ProgressSpinnerModule } from 'primeng/progressspinner';
55
+ import * as i11 from 'primeng/toast';
56
+ import { ToastModule } from 'primeng/toast';
57
+ import * as i12$1 from 'primeng/confirmdialog';
58
+ import { ConfirmDialogModule } from 'primeng/confirmdialog';
59
+ import * as i4$3 from 'primeng/table';
60
+ import { TableModule } from 'primeng/table';
61
+ import * as i5$2 from 'primeng/avatar';
62
+ import { AvatarModule } from 'primeng/avatar';
63
+ import { ScrollingModule } from '@angular/cdk/scrolling';
64
+ import { MessagesModule } from 'primeng/messages';
65
+ import { PanelModule } from 'primeng/panel';
66
+
67
+ var LinkNames;
68
+ (function (LinkNames) {
69
+ LinkNames["get"] = "Get";
70
+ LinkNames["getList"] = "GetList";
71
+ LinkNames["post"] = "Post";
72
+ LinkNames["put"] = "Put";
73
+ LinkNames["delete"] = "Delete";
74
+ LinkNames["new"] = "New";
75
+ })(LinkNames || (LinkNames = {}));
76
+
77
+ class ProblemDetails extends Resource {
78
+ static isProblemDetails(resource) {
79
+ return resource instanceof ProblemDetails;
80
+ }
81
+ static containsProblemDetailsInformation(resource) {
82
+ return resource && (resource instanceof ProblemDetails || (resource instanceof Resource && 'status' in resource && _.isNumber(resource['status']) && resource['status'] >= 100 && resource['status'] < 600));
83
+ }
84
+ static fromResource(resource) {
85
+ if (!ProblemDetails.containsProblemDetailsInformation(resource))
86
+ throw new Error(`The resource ${resource} does not have problem details.`);
87
+ return Object.assign(new ProblemDetails(), resource);
88
+ }
89
+ }
90
+
91
+ class RESTworldOptions {
92
+ constructor(BaseUrl, Version) {
93
+ this.BaseUrl = BaseUrl;
94
+ this.Version = Version;
95
+ if (!BaseUrl.endsWith('/'))
96
+ throw new Error(`The provided BaseUrl '${BaseUrl}' does not end with a slash '/'.`);
97
+ }
98
+ }
99
+
100
+ class SafeUrlPipe {
101
+ constructor(_domSanitizer) {
102
+ this._domSanitizer = _domSanitizer;
103
+ }
104
+ transform(url) {
105
+ if (_.isString(url))
106
+ throw new Error(`The given url '${url}' is not a string.`);
107
+ return this._domSanitizer.bypassSecurityTrustResourceUrl(url);
108
+ }
109
+ }
110
+ SafeUrlPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: SafeUrlPipe, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
111
+ SafeUrlPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: SafeUrlPipe, name: "safeUrl" });
112
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: SafeUrlPipe, decorators: [{
113
+ type: Pipe,
114
+ args: [{
115
+ name: 'safeUrl'
116
+ }]
117
+ }], ctorParameters: function () { return [{ type: i1.DomSanitizer }]; } });
118
+
119
+ /**
120
+ * Cast super type into type using generics
121
+ * Return Type obtained by optional @param type OR assignment type.
122
+ */
123
+ class AsPipe {
124
+ /**
125
+ * Cast (S: SuperType) into (T: Type) using @Generics.
126
+ * @param value (S: SuperType) obtained from input type.
127
+ * @optional @param type (T CastingType)
128
+ * type?: { new (): T }
129
+ * type?: new () => T
130
+ */
131
+ transform(value, type) {
132
+ return value;
133
+ }
134
+ }
135
+ AsPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: AsPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
136
+ AsPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: AsPipe, name: "as" });
137
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: AsPipe, decorators: [{
138
+ type: Pipe,
139
+ args: [{ name: 'as' }]
140
+ }] });
141
+
142
+ class AvatarGenerator {
143
+ constructor() {
144
+ this.getImageOverride = () => '';
145
+ }
146
+ getImage(nameOrEmail) {
147
+ let uri = AvatarGenerator._imageCache.get(nameOrEmail);
148
+ if (!uri) {
149
+ uri = this.getImageOverride(nameOrEmail);
150
+ AvatarGenerator._imageCache.set(nameOrEmail, uri);
151
+ }
152
+ return uri;
153
+ }
154
+ getLabel(nameOrEmail) {
155
+ if (!nameOrEmail)
156
+ return '';
157
+ if (this.getImage(nameOrEmail))
158
+ return '';
159
+ const name = AvatarGenerator.getLocalPartOfEmailAddress(nameOrEmail);
160
+ const initials = AvatarGenerator.getTwoUppercaseLettersFromName(name);
161
+ return initials;
162
+ }
163
+ getStyle(nameOrEmail) {
164
+ if (this.getImage(nameOrEmail))
165
+ return '';
166
+ const foregroundColor = '#ffffff';
167
+ const backgroundColor = AvatarGenerator.getBackgroundColor(nameOrEmail);
168
+ const style = {
169
+ 'background-color': backgroundColor,
170
+ color: foregroundColor,
171
+ };
172
+ return style;
173
+ }
174
+ static getLocalPartOfEmailAddress(email) {
175
+ const indexOfAt = email.indexOf('@');
176
+ if (indexOfAt < 2) {
177
+ if (indexOfAt >= 0) {
178
+ if (indexOfAt === email.length - 1)
179
+ return email.substring(0, indexOfAt);
180
+ return email.substring(indexOfAt + 1);
181
+ }
182
+ }
183
+ else {
184
+ return email.substring(0, indexOfAt);
185
+ }
186
+ return email;
187
+ }
188
+ static getTwoUppercaseLettersFromName(name) {
189
+ // Too short to do anything besides just returning the name
190
+ if (name.length <= 2) {
191
+ return name.toUpperCase();
192
+ }
193
+ // Try to split by non word characters
194
+ const splittedByNonWord = name.split(AvatarGenerator._nonWordRegex);
195
+ if (splittedByNonWord.length > 1) {
196
+ return (splittedByNonWord[0][0] + splittedByNonWord[1][0]).toUpperCase();
197
+ }
198
+ // Try to split by upper case letters
199
+ const upperCaseLetters = [...name]
200
+ .filter((c) => c.toUpperCase() === c && !AvatarGenerator._nonWordRegex.test(c))
201
+ .join();
202
+ if (upperCaseLetters.length > 1) {
203
+ return upperCaseLetters.substring(0, 2);
204
+ }
205
+ // Just return the first 2 letters
206
+ return name.substring(0, 2).toUpperCase();
207
+ }
208
+ // from https://stackoverflow.com/a/66494926/1378307
209
+ static getBackgroundColor(text, minLightness = 40, maxLightness = 80, minSaturation = 30, maxSaturation = 100) {
210
+ if (!text)
211
+ return '#aaa';
212
+ const hash = [...text].reduce((acc, char) => {
213
+ return char.charCodeAt(0) + ((acc << 5) - acc);
214
+ }, 0);
215
+ return ('hsl(' +
216
+ (hash % 360) +
217
+ ', ' +
218
+ ((hash % (maxSaturation - minSaturation)) + minSaturation) +
219
+ '%, ' +
220
+ ((hash % (maxLightness - minLightness)) + minLightness) +
221
+ '%)');
222
+ }
223
+ }
224
+ AvatarGenerator._nonWordRegex = new RegExp('\\W');
225
+ AvatarGenerator._imageCache = new Map();
226
+ AvatarGenerator.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: AvatarGenerator, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
227
+ AvatarGenerator.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: AvatarGenerator, providedIn: 'root' });
228
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: AvatarGenerator, decorators: [{
229
+ type: Injectable,
230
+ args: [{
231
+ providedIn: 'root',
232
+ }]
233
+ }], propDecorators: { getImageOverride: [{
234
+ type: Input
235
+ }] } });
236
+
237
+ class FormService {
238
+ createFormGroupsFromTemplates(templates) {
239
+ const tabs = Object.fromEntries(Object.entries(templates).map(([name, template]) => [
240
+ name,
241
+ this.createFormGroupFromTemplate(template)
242
+ ]));
243
+ return tabs;
244
+ }
245
+ createFormGroupFromTemplates(templates, ignoredProperties) {
246
+ const controls = Object.fromEntries(Object.entries(templates)
247
+ .filter(([key,]) => !ignoredProperties.some(p => key === p))
248
+ .map(([name, template]) => [
249
+ name,
250
+ this.createFormGroupFromTemplate(template)
251
+ ]));
252
+ const formGroup = new FormGroup(controls);
253
+ return formGroup;
254
+ }
255
+ createFormArrayFromTemplates(templates, ignoredProperties) {
256
+ const controls = Object.entries(templates)
257
+ .filter(([key,]) => !ignoredProperties.some(p => key === p))
258
+ .map(([, template]) => this.createFormGroupFromTemplate(template));
259
+ const formArray = new FormArray(controls);
260
+ return formArray;
261
+ }
262
+ createFormGroupFromTemplate(template) {
263
+ const controls = Object.fromEntries(template.properties.map(p => [
264
+ p.name,
265
+ this.createFormControl(p)
266
+ ]));
267
+ const formGroup = new FormGroup(controls);
268
+ return formGroup;
269
+ }
270
+ createFormControl(property) {
271
+ if (property.type === PropertyType.Object)
272
+ return this.createFormGroupFromTemplate(property._templates['default']);
273
+ if (property.type === PropertyType.Collection)
274
+ return this.createFormArrayFromTemplates(property._templates, ['default']);
275
+ const control = new FormControl(property.value);
276
+ if (property.max)
277
+ control.addValidators(Validators.max(property.max));
278
+ if (property.maxLength)
279
+ control.addValidators(Validators.maxLength(property.maxLength));
280
+ if (property.min)
281
+ control.addValidators(Validators.min(property.min));
282
+ if (property.minLength)
283
+ control.addValidators(Validators.minLength(property.minLength));
284
+ if (property.regex)
285
+ control.addValidators(Validators.pattern(property.regex));
286
+ if (property.required)
287
+ control.addValidators(Validators.required);
288
+ if (property.type === PropertyType.Email)
289
+ control.addValidators(Validators.email);
290
+ return control;
291
+ }
292
+ }
293
+ FormService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: FormService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
294
+ FormService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: FormService, providedIn: 'root' });
295
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: FormService, decorators: [{
296
+ type: Injectable,
297
+ args: [{
298
+ providedIn: 'root'
299
+ }]
300
+ }] });
301
+
302
+ class RESTworldClient {
303
+ constructor(_halClient, _options) {
304
+ this._halClient = _halClient;
305
+ this._options = _options;
306
+ }
307
+ get halClient() {
308
+ return this._halClient;
309
+ }
310
+ async ensureHomeResourceIsSet() {
311
+ if (!this._homeResource) {
312
+ const response = await this.getHomeForced();
313
+ if (ProblemDetails.isProblemDetails(response.body)) {
314
+ throw new Error(`Cannot get the home resource from ${this._options.BaseUrl} with Version ${this._options.Version}. Response was: ${response}`);
315
+ }
316
+ if (!response.body)
317
+ throw new Error(`Cannot get the home resource from ${this._options.BaseUrl} with Version ${this._options.Version}. Response was empty.`);
318
+ this._homeResource = response.body;
319
+ this.setDefaultCurie();
320
+ }
321
+ }
322
+ async getHomeForced() {
323
+ const header = RESTworldClient.createHeaders('application/hal+json', this._options.Version);
324
+ const response = await this.halClient.get(this._options.BaseUrl, Resource, ProblemDetails, header);
325
+ return response;
326
+ }
327
+ setDefaultCurie() {
328
+ const curies = this._homeResource?._links?.curies;
329
+ if (!curies || curies.length === 0 || !curies[0])
330
+ this._defaultCurie = undefined;
331
+ else
332
+ this._defaultCurie = curies[0].name;
333
+ }
334
+ async getList(rel, parameters, headers, curie) {
335
+ const link = this.getLinkFromHome(rel, LinkNames.getList, curie);
336
+ const uri = link.fillTemplate(parameters);
337
+ const response = await this.halClient.get(uri, PagedListResource, ProblemDetails, headers);
338
+ return response;
339
+ }
340
+ async getListByUri(uri, parameters, headers) {
341
+ const link = new Link();
342
+ link.href = uri;
343
+ const filledUri = link.fillTemplate(parameters);
344
+ const response = await this.halClient.get(filledUri, PagedListResource, ProblemDetails, headers);
345
+ return response;
346
+ }
347
+ async getSingle(relOrUri, id, headers, curie) {
348
+ let uri;
349
+ if (relOrUri.startsWith('http')) {
350
+ if (id !== undefined)
351
+ throw new Error('When supplying a URI, an ID cannot be supplied too.');
352
+ if (curie)
353
+ throw new Error('When supplying a URI, a curie cannot be supplied too.');
354
+ uri = relOrUri;
355
+ }
356
+ else {
357
+ if (!_.isNumber(id))
358
+ throw new Error('When supplying a rel, an ID must be supplied too.');
359
+ const link = this.getLinkFromHome(relOrUri, LinkNames.get, curie);
360
+ uri = link.fillTemplate({ id: id.toString() });
361
+ }
362
+ const response = await this.halClient.get(uri, Resource, ProblemDetails, headers);
363
+ return response;
364
+ }
365
+ async save(resource) {
366
+ const saveLink = resource.findLink('save');
367
+ if (!saveLink)
368
+ throw new Error(`The resource ${resource} does not have a save link.`);
369
+ if (!saveLink.name)
370
+ throw new Error(`The save link ${saveLink} does not have a save name.`);
371
+ const uri = saveLink.href;
372
+ const method = saveLink.name.toLowerCase();
373
+ const header = RESTworldClient.createHeaders('application/hal+json', this._options.Version);
374
+ let response;
375
+ switch (method) {
376
+ case 'put':
377
+ response = await this.halClient.put(uri, resource, Resource, ProblemDetails, header);
378
+ break;
379
+ case 'post':
380
+ response = await this.halClient.post(uri, resource, Resource, ProblemDetails, header);
381
+ break;
382
+ default:
383
+ throw new Error(`'${method}' is not allowed as link name for the save link. Only 'POST' and 'PUT' are allowed.`);
384
+ }
385
+ return response;
386
+ }
387
+ async getAllForms(resource) {
388
+ const urls = resource.getFormLinkHrefs();
389
+ const header = RESTworldClient.createHeaders('application/prs.hal-forms+json', this._options.Version);
390
+ const formsPromises = urls.map(url => this._halClient.get(url, FormsResource, ProblemDetails, header));
391
+ const formsAndProblems = await Promise.all(formsPromises);
392
+ return formsAndProblems;
393
+ }
394
+ async submit(template, formValues) {
395
+ const uri = template.target || '';
396
+ const method = template.method?.toLowerCase();
397
+ const header = RESTworldClient.createHeaders('application/prs.hal-forms+json', this._options.Version);
398
+ let response;
399
+ switch (method) {
400
+ case 'put':
401
+ response = await this.halClient.put(uri, formValues, FormsResource, ProblemDetails, header);
402
+ break;
403
+ case 'post':
404
+ response = await this.halClient.post(uri, formValues, FormsResource, ProblemDetails, header);
405
+ break;
406
+ default:
407
+ response = await this.halClient.get(uri, FormsResource, ProblemDetails, header);
408
+ }
409
+ return response;
410
+ }
411
+ async delete(resource) {
412
+ const deleteLink = resource.findLink('delete');
413
+ if (!deleteLink)
414
+ throw new Error(`The resource ${resource} does not have a delete link.`);
415
+ const uri = deleteLink.href;
416
+ const header = RESTworldClient.createHeaders('application/hal+json', this._options.Version);
417
+ const response = await this.halClient.delete(uri, ProblemDetails, header);
418
+ return response;
419
+ }
420
+ getAllLinksFromHome() {
421
+ if (!this._homeResource)
422
+ throw new Error('Home resource is not set. Call ensureHomeResourceIsSet() first.');
423
+ return this._homeResource._links;
424
+ }
425
+ getLinkFromHome(rel, name, curie) {
426
+ const links = this.getLinksFromHome(rel, curie);
427
+ const link = name ? links.find(l => l.name === name) : links[0];
428
+ if (!link)
429
+ throw new Error(`The home resource does not have a link with the rel '${this.getFullRel(rel, curie)}' and the name '${name}'.`);
430
+ return link;
431
+ }
432
+ getLinksFromHome(rel, curie) {
433
+ if (!this._homeResource)
434
+ throw new Error('Home resource is not set. Call ensureHomeResourceIsSet() first.');
435
+ const fullRel = this.getFullRel(rel, curie);
436
+ const links = this._homeResource._links[fullRel];
437
+ if (!links || links.length === 0)
438
+ throw Error(`The home resource does not have a link with the rel '${fullRel}'.`);
439
+ return links;
440
+ }
441
+ getFullRel(rel, curie) {
442
+ // rel already includes a curie => just return it
443
+ if (rel.includes(':'))
444
+ return rel;
445
+ // No curie given => use default curie.
446
+ if (!curie)
447
+ curie = this._defaultCurie;
448
+ // Combine curie and rel
449
+ const fullRel = `${curie}:${rel}`;
450
+ return fullRel;
451
+ }
452
+ static createHeaders(mediaType, version) {
453
+ if (version)
454
+ return new HttpHeaders({
455
+ 'Accept': `${mediaType || 'application/hal+json'}; v=${version}`,
456
+ 'Content-Type': `${mediaType || 'application/hal+json'}; v=${version}`
457
+ });
458
+ return new HttpHeaders();
459
+ }
460
+ }
461
+
462
+ class RESTworldClientCollection {
463
+ constructor(_halClient) {
464
+ this._halClient = _halClient;
465
+ this._clients = {};
466
+ }
467
+ containsClient(name) {
468
+ return Object.keys(this._clients).includes(name);
469
+ }
470
+ async addOrGetExistingClient(name, options) {
471
+ if (Object.keys(this._clients).includes(name))
472
+ return this.getClient(name);
473
+ const client = new RESTworldClient(this._halClient, options);
474
+ await client.ensureHomeResourceIsSet();
475
+ this._clients[name] = client;
476
+ return client;
477
+ }
478
+ getClient(name) {
479
+ const client = this._clients[name];
480
+ if (!client)
481
+ throw new Error(`No client with the name '${name}' exists.`);
482
+ return client;
483
+ }
484
+ get all() {
485
+ return this._clients;
486
+ }
487
+ }
488
+ 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 });
489
+ RESTworldClientCollection.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RESTworldClientCollection, providedIn: 'root' });
490
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RESTworldClientCollection, decorators: [{
491
+ type: Injectable,
492
+ args: [{
493
+ providedIn: 'root'
494
+ }]
495
+ }], ctorParameters: function () { return [{ type: i1$1.HalClient }]; } });
496
+
497
+ class SettingsService {
498
+ constructor(backend, _clients) {
499
+ this._clients = _clients;
500
+ this._client = new HttpClient(backend);
501
+ }
502
+ get settings() {
503
+ return this._settings;
504
+ }
505
+ async initialize() {
506
+ await this.ensureSettingsAreLoaded();
507
+ await this.populateRESTworldClientCollectionFromSettings();
508
+ }
509
+ async ensureSettingsAreLoaded() {
510
+ this._settings = await this._client
511
+ .get('/settings')
512
+ .toPromise();
513
+ }
514
+ async populateRESTworldClientCollectionFromSettings() {
515
+ if (!this._settings?.apiUrls)
516
+ return;
517
+ await Promise.all(this._settings.apiUrls
518
+ .map(api => this._clients.addOrGetExistingClient(api.name, new RESTworldOptions(api.url, api.version))));
519
+ }
520
+ }
521
+ 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 });
522
+ SettingsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: SettingsService, providedIn: 'root' });
523
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: SettingsService, decorators: [{
524
+ type: Injectable,
525
+ args: [{
526
+ providedIn: 'root'
527
+ }]
528
+ }], ctorParameters: function () { return [{ type: i1$2.HttpBackend }, { type: RESTworldClientCollection }]; } });
529
+
530
+ class RESTWorldImageViewComponent {
531
+ constructor() {
532
+ this.maintainAspectRatio = true;
533
+ this.aspectRatio = 1;
534
+ this.resizeToWidth = 0;
535
+ this.resizeToHeight = 0;
536
+ this.onlyScaleDown = false;
537
+ this.containWithinAspectRatio = false;
538
+ this.backgroundColor = "#ffffff";
539
+ this.format = 'png';
540
+ this.disabled = false;
541
+ this.displayCropDialog = false;
542
+ }
543
+ writeValue(obj) {
544
+ this.uri = obj;
545
+ }
546
+ registerOnChange(fn) {
547
+ this.onChange = fn;
548
+ }
549
+ registerOnTouched() {
550
+ // not needed for this component, but needed to implement the interface
551
+ }
552
+ setDisabledState(isDisabled) {
553
+ this.disabled = isDisabled;
554
+ }
555
+ showCropDialog() {
556
+ this.displayCropDialog = true;
557
+ }
558
+ imageChanged(event) {
559
+ this.tempImageFile = event.files[0];
560
+ this.showCropDialog();
561
+ }
562
+ croppedImageChanged(event) {
563
+ this.tempCroppedUri = event.base64;
564
+ }
565
+ acceptCroppedImage() {
566
+ this.uri = this.tempCroppedUri;
567
+ this.onChange?.(this.uri);
568
+ this.closeCropDialog();
569
+ }
570
+ closeCropDialog() {
571
+ this.fileUploads?.forEach(f => f.clear());
572
+ this.displayCropDialog = false;
573
+ }
574
+ }
575
+ RESTWorldImageViewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RESTWorldImageViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
576
+ 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: [{
577
+ provide: NG_VALUE_ACCESSOR,
578
+ useExisting: forwardRef(() => RESTWorldImageViewComponent),
579
+ multi: true
580
+ }], 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 } });
581
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RESTWorldImageViewComponent, decorators: [{
582
+ type: Component,
583
+ args: [{ selector: 'rw-image', providers: [{
584
+ provide: NG_VALUE_ACCESSOR,
585
+ useExisting: forwardRef(() => RESTWorldImageViewComponent),
586
+ multi: true
587
+ }], 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"] }]
588
+ }], propDecorators: { alt: [{
589
+ type: Input
590
+ }], accept: [{
591
+ type: Input
592
+ }], fileName: [{
593
+ type: Input
594
+ }], maintainAspectRatio: [{
595
+ type: Input
596
+ }], aspectRatio: [{
597
+ type: Input
598
+ }], resizeToWidth: [{
599
+ type: Input
600
+ }], resizeToHeight: [{
601
+ type: Input
602
+ }], onlyScaleDown: [{
603
+ type: Input
604
+ }], containWithinAspectRatio: [{
605
+ type: Input
606
+ }], backgroundColor: [{
607
+ type: Input
608
+ }], format: [{
609
+ type: Input
610
+ }], fileUploads: [{
611
+ type: ViewChildren,
612
+ args: [FileUpload]
613
+ }] } });
614
+
615
+ class RESTWorldFileViewComponent {
616
+ constructor() {
617
+ this.disabled = false;
618
+ }
619
+ writeValue(obj) {
620
+ this.uri = obj;
621
+ }
622
+ registerOnChange(fn) {
623
+ this.onChange = fn;
624
+ }
625
+ registerOnTouched() {
626
+ // not needed for this component, but needed to implement the interface
627
+ }
628
+ setDisabledState(isDisabled) {
629
+ this.disabled = isDisabled;
630
+ }
631
+ fileChanged(event) {
632
+ const file = event.files[0];
633
+ const reader = new FileReader();
634
+ reader.onload = () => {
635
+ this.uri = reader.result;
636
+ this.onChange?.(this.uri);
637
+ };
638
+ reader.readAsDataURL(file);
639
+ }
640
+ }
641
+ RESTWorldFileViewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RESTWorldFileViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
642
+ RESTWorldFileViewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.5", type: RESTWorldFileViewComponent, selector: "rw-file", inputs: { accept: "accept", fileName: "fileName" }, providers: [{
643
+ provide: NG_VALUE_ACCESSOR,
644
+ useExisting: forwardRef(() => RESTWorldFileViewComponent),
645
+ multi: true
646
+ }], 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 } });
647
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RESTWorldFileViewComponent, decorators: [{
648
+ type: Component,
649
+ args: [{ selector: 'rw-file', providers: [{
650
+ provide: NG_VALUE_ACCESSOR,
651
+ useExisting: forwardRef(() => RESTWorldFileViewComponent),
652
+ multi: true
653
+ }], 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"] }]
654
+ }], propDecorators: { accept: [{
655
+ type: Input
656
+ }], fileName: [{
657
+ type: Input
658
+ }], fileUploads: [{
659
+ type: ViewChildren,
660
+ args: [FileUpload]
661
+ }] } });
662
+
663
+ class RestworldEditFormComponent {
664
+ constructor(_formService, _changeDetectorRef, _messageService, _clients) {
665
+ this._formService = _formService;
666
+ this._changeDetectorRef = _changeDetectorRef;
667
+ this._messageService = _messageService;
668
+ this._clients = _clients;
669
+ this.FormGroup = FormGroup;
670
+ this.FormArray = FormArray;
671
+ this.Number = Number;
672
+ }
673
+ get PropertyType() {
674
+ return PropertyType;
675
+ }
676
+ get dateFormat() {
677
+ return new Date(3333, 10, 22)
678
+ .toLocaleDateString()
679
+ .replace("22", "dd")
680
+ .replace("11", "mm")
681
+ .replace("3333", "yy")
682
+ .replace("33", "y");
683
+ }
684
+ ngOnInit() {
685
+ if (!this.formGroup)
686
+ throw new Error("[formGroup] is required on <rw-form>");
687
+ if (!this.template)
688
+ throw new Error("[template] is required on <rw-form>");
689
+ if (!this.apiName)
690
+ throw new Error("[apiName] is required on <rw-form>");
691
+ }
692
+ getTooltip(resource, keysToExclude) {
693
+ const tooltip = Object.entries(resource)
694
+ .filter(([key]) => !(key.startsWith('_') || ['createdAt', 'createdBy', 'lastChangedAt', 'lastChangedBy', 'timestamp'].includes(key) || keysToExclude?.includes(key)))
695
+ .reduce((prev, [key, value], index) => `${prev}${index === 0 ? '' : '\n'}${key}: ${RestworldEditFormComponent.jsonStringifyWithElipsis(value)}`, '');
696
+ return tooltip;
697
+ }
698
+ static jsonStringifyWithElipsis(value) {
699
+ const maxLength = 200;
700
+ const end = 10;
701
+ const start = maxLength - end - 2;
702
+ const json = JSON.stringify(value);
703
+ const shortened = json.length > maxLength ? json.substring(0, start) + '…' + json.substring(json.length - end) : json;
704
+ return shortened;
705
+ }
706
+ getCollectionEntryTemplates(property) {
707
+ if (!property)
708
+ return [];
709
+ return Object.entries(property._templates)
710
+ .filter(([key,]) => Number.isInteger(Number.parseInt(key)))
711
+ .map(([, value]) => value);
712
+ }
713
+ addNewItemToCollection(property, formArray) {
714
+ if (!(formArray instanceof FormArray))
715
+ throw new Error('formArray is not an instance of FormArray.');
716
+ const maxIndex = Math.max(...Object.keys(property._templates)
717
+ .map(key => Number.parseInt(key))
718
+ .filter(key => Number.isSafeInteger(key)));
719
+ const nextIndex = maxIndex + 1;
720
+ const defaultTemplate = property._templates['default'];
721
+ const copiedTemplateDto = JSON.parse(JSON.stringify(defaultTemplate));
722
+ const copiedTemplate = new Template(copiedTemplateDto);
723
+ copiedTemplate.title = nextIndex.toString();
724
+ property._templates[copiedTemplate.title] = copiedTemplate;
725
+ formArray.push(this._formService.createFormGroupFromTemplate(defaultTemplate));
726
+ }
727
+ deleteItemFromCollection(property, formArray, template) {
728
+ if (!template.title)
729
+ throw new Error(`Cannot delete the item, because the template '${template}' does not have a title.`);
730
+ if (!(formArray instanceof FormArray))
731
+ throw new Error('formArray is not an instance of FormArray.');
732
+ const templates = property._templates;
733
+ delete templates[template.title];
734
+ formArray.removeAt(Number.parseInt(template.title));
735
+ }
736
+ collectionItemDropped($event) {
737
+ const formArray = $event.container.data.formArray;
738
+ const previousIndex = $event.previousIndex;
739
+ const currentIndex = $event.currentIndex;
740
+ const movementDirection = currentIndex > previousIndex ? 1 : -1;
741
+ // Move in FormArray
742
+ // We do not need to move the item in the _templates object
743
+ const movedControl = formArray.at(previousIndex);
744
+ for (let i = previousIndex; i * movementDirection < currentIndex * movementDirection; i = i + movementDirection) {
745
+ formArray.setControl(i, formArray.at(i + movementDirection));
746
+ }
747
+ formArray.setControl(currentIndex, movedControl);
748
+ this._changeDetectorRef.markForCheck();
749
+ console.log($event);
750
+ }
751
+ async onOptionsFiltered(property, event) {
752
+ const options = property?.options;
753
+ if (!options?.link?.href || !event.filter || event.filter === '')
754
+ return;
755
+ const templatedUri = options.link.href;
756
+ let filter = `contains(${options.promptField}, '${event.filter}')`;
757
+ if (options.valueField?.toLowerCase() === 'id' && !Number.isNaN(Number.parseInt(event.filter)))
758
+ filter = `(${options.valueField} eq ${event.filter}) or (${filter})`;
759
+ const response = await this.getClient().getListByUri(templatedUri, { $filter: filter, $top: 10 });
760
+ if (!response.ok || ProblemDetails.isProblemDetails(response.body) || !response.body) {
761
+ const message = `An error occurred while getting the filtered items.`;
762
+ this._messageService.add({ severity: 'error', summary: 'Error', detail: message, data: response });
763
+ return;
764
+ }
765
+ const items = response.body._embedded.items;
766
+ options.inline = items;
767
+ }
768
+ getClient() {
769
+ if (!this.apiName)
770
+ throw new Error('Cannot get a client, because the apiName is not set.');
771
+ return this._clients.getClient(this.apiName);
772
+ }
773
+ }
774
+ 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 });
775
+ 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 } });
776
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RestworldEditFormComponent, decorators: [{
777
+ type: Component,
778
+ 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"] }]
779
+ }], ctorParameters: function () { return [{ type: FormService }, { type: i0.ChangeDetectorRef }, { type: i2$1.MessageService }, { type: RESTworldClientCollection }]; }, propDecorators: { formGroup: [{
780
+ type: Input
781
+ }], template: [{
782
+ type: Input
783
+ }], apiName: [{
784
+ type: Input
785
+ }], inputOptionsSingleRef: [{
786
+ type: ContentChild,
787
+ args: ['inputOptionsSingle', { static: false }]
788
+ }], inputOptionsMultipleRef: [{
789
+ type: ContentChild,
790
+ args: ['inputOptionsMultiple', { static: false }]
791
+ }], inputOptionsRef: [{
792
+ type: ContentChild,
793
+ args: ['inputOptions', { static: false }]
794
+ }], inputHiddenRef: [{
795
+ type: ContentChild,
796
+ args: ['inputHidden', { static: false }]
797
+ }], inputTextRef: [{
798
+ type: ContentChild,
799
+ args: ['inputText', { static: false }]
800
+ }], inputTextareaRef: [{
801
+ type: ContentChild,
802
+ args: ['inputTextarea', { static: false }]
803
+ }], inputSearchRef: [{
804
+ type: ContentChild,
805
+ args: ['inputSearch', { static: false }]
806
+ }], inputTelRef: [{
807
+ type: ContentChild,
808
+ args: ['inputTel', { static: false }]
809
+ }], inputUrlRef: [{
810
+ type: ContentChild,
811
+ args: ['inputUrl', { static: false }]
812
+ }], inputEmailRef: [{
813
+ type: ContentChild,
814
+ args: ['inputEmail', { static: false }]
815
+ }], inputPasswordRef: [{
816
+ type: ContentChild,
817
+ args: ['inputPassword', { static: false }]
818
+ }], inputDateRef: [{
819
+ type: ContentChild,
820
+ args: ['inputDate', { static: false }]
821
+ }], inputMonthRef: [{
822
+ type: ContentChild,
823
+ args: ['inputMonth', { static: false }]
824
+ }], inputWeekRef: [{
825
+ type: ContentChild,
826
+ args: ['inputWeek', { static: false }]
827
+ }], inputTimeRef: [{
828
+ type: ContentChild,
829
+ args: ['inputTime', { static: false }]
830
+ }], inputDatetimeLocalRef: [{
831
+ type: ContentChild,
832
+ args: ['inputDatetimeLocal', { static: false }]
833
+ }], inputNumberRef: [{
834
+ type: ContentChild,
835
+ args: ['inputNumber', { static: false }]
836
+ }], inputRangeRef: [{
837
+ type: ContentChild,
838
+ args: ['inputRange', { static: false }]
839
+ }], inputColorRef: [{
840
+ type: ContentChild,
841
+ args: ['inputColor', { static: false }]
842
+ }], inputBoolRef: [{
843
+ type: ContentChild,
844
+ args: ['inputBool', { static: false }]
845
+ }], inputDatetimeOffsetRef: [{
846
+ type: ContentChild,
847
+ args: ['inputDatetimeOffset', { static: false }]
848
+ }], inputDurationRef: [{
849
+ type: ContentChild,
850
+ args: ['inputDuration', { static: false }]
851
+ }], inputImageRef: [{
852
+ type: ContentChild,
853
+ args: ['inputImage', { static: false }]
854
+ }], inputFileRef: [{
855
+ type: ContentChild,
856
+ args: ['inputFile', { static: false }]
857
+ }], inputObjectRef: [{
858
+ type: ContentChild,
859
+ args: ['inputObject', { static: false }]
860
+ }], inputCollectionRef: [{
861
+ type: ContentChild,
862
+ args: ['inputCollection', { static: false }]
863
+ }], inputDefaultRef: [{
864
+ type: ContentChild,
865
+ args: ['inputDefault', { static: false }]
866
+ }] } });
867
+
868
+ class RESTworldEditViewComponent {
869
+ constructor(_clients, _confirmationService, _messageService, _location, _router, _formService, valdemortConfig) {
870
+ this._clients = _clients;
871
+ this._confirmationService = _confirmationService;
872
+ this._messageService = _messageService;
873
+ this._location = _location;
874
+ this._router = _router;
875
+ this._formService = _formService;
876
+ this._templates = {};
877
+ this._formTabs = {};
878
+ this.isLoading = false;
879
+ valdemortConfig.errorClasses = 'p-error text-sm';
880
+ }
881
+ get PropertyType() {
882
+ return PropertyType;
883
+ }
884
+ get templates() {
885
+ return this._templates;
886
+ }
887
+ get isLoadingForTheFirstTime() {
888
+ return Object.keys(this.templates).length === 0 && this.isLoading;
889
+ }
890
+ get formTabs() {
891
+ return this._formTabs;
892
+ }
893
+ set apiName(value) {
894
+ this._apiName = value;
895
+ this.load();
896
+ }
897
+ get apiName() {
898
+ return this._apiName;
899
+ }
900
+ //@Input()
901
+ //public set rel(value: string | undefined) {
902
+ // this._rel = value;
903
+ //}
904
+ //public get rel(): string | undefined {
905
+ // return this._rel;
906
+ //}
907
+ //private _rel?: string;
908
+ set uri(value) {
909
+ this._uri = value;
910
+ this.load();
911
+ }
912
+ get uri() {
913
+ return this._uri;
914
+ }
915
+ get resource() {
916
+ return this._resource;
917
+ }
918
+ get canSave() {
919
+ const length = this.resource?._links["save"]?.length;
920
+ return length !== undefined && length > 0;
921
+ }
922
+ get canDelete() {
923
+ const length = this.resource?._links["delete"]?.length;
924
+ return length !== undefined && length > 0;
925
+ }
926
+ canSubmit(templateName) {
927
+ const form = this.formTabs[templateName];
928
+ return form && form.valid;
929
+ }
930
+ getTooltip(resource, keysToExclude) {
931
+ const tooltip = Object.entries(resource)
932
+ .filter(([key]) => !(key.startsWith('_') || ['createdAt', 'createdBy', 'lastChangedAt', 'lastChangedBy', 'timestamp'].includes(key) || keysToExclude?.includes(key)))
933
+ .reduce((prev, [key, value], index) => `${prev}${index === 0 ? '' : '\n'}${key}: ${RESTworldEditViewComponent.jsonStringifyWithElipsis(value)}`, '');
934
+ return tooltip;
935
+ }
936
+ static jsonStringifyWithElipsis(value) {
937
+ const maxLength = 200;
938
+ const end = 10;
939
+ const start = maxLength - end - 2;
940
+ const json = JSON.stringify(value);
941
+ const shortened = json.length > maxLength ? json.substring(0, start) + '…' + json.substring(json.length - end) : json;
942
+ return shortened;
943
+ }
944
+ getClient() {
945
+ if (!this.apiName)
946
+ throw new Error('Cannot get a client, because the apiName is not set.');
947
+ return this._clients.getClient(this.apiName);
948
+ }
949
+ async submit(templateName, template, formValue) {
950
+ this.isLoading = true;
951
+ try {
952
+ const targetBeforeSave = template.target;
953
+ const response = await this.getClient().submit(template, formValue);
954
+ if (!response.ok) {
955
+ let summary = 'Error';
956
+ let detail = 'Error while saving the resource.';
957
+ if (ProblemDetails.isProblemDetails(response.body)) {
958
+ const problemDetails = response.body;
959
+ summary = problemDetails.title || summary;
960
+ detail = problemDetails.detail || detail;
961
+ // display validation errors
962
+ if (problemDetails['errors']) {
963
+ const form = this.formTabs[templateName];
964
+ for (const [key, errorsForKey] of Object.entries(problemDetails['errors'])) {
965
+ const path = key.split(/\.|\[/).map(e => e.replace("]", ""));
966
+ const formControl = path.reduce((control, pathElement) => (control instanceof FormGroup ? control.controls[pathElement] : control) || control, form);
967
+ formControl.setErrors({ remote: errorsForKey });
968
+ }
969
+ }
970
+ }
971
+ this._messageService.add({ severity: 'error', summary: summary, detail: detail, data: response, life: 10000 });
972
+ }
973
+ else {
974
+ const responseResource = response.body;
975
+ const targetAfterSave = responseResource._templates[templateName].target;
976
+ setTimeout(() => this._messageService.add({ severity: 'success', summary: 'Saved', detail: 'The resource has been saved.' }), 100);
977
+ if (targetBeforeSave !== targetAfterSave) {
978
+ this._router.navigate(['/edit', this.apiName, responseResource._links.self[0].href]);
979
+ }
980
+ }
981
+ }
982
+ catch (e) {
983
+ this._messageService.add({ severity: 'error', summary: 'Error', detail: `An unknown error occurred. ${JSON.stringify(e)}`, life: 10000 });
984
+ console.log(e);
985
+ }
986
+ this.isLoading = false;
987
+ }
988
+ showDeleteConfirmatioModal() {
989
+ this._confirmationService.confirm({
990
+ message: 'Do you really want to delete this resource?',
991
+ header: 'Confirm delete',
992
+ icon: 'far fa-trash-alt',
993
+ accept: () => this.delete()
994
+ });
995
+ }
996
+ async delete() {
997
+ if (!this.apiName || !this.uri || !this.resource)
998
+ return;
999
+ Object.assign(this.resource, this.formTabs.value);
1000
+ await this.getClient().delete(this.resource);
1001
+ setTimeout(() => this._messageService.add({ severity: 'success', summary: 'Deleted', detail: 'The resource has been deleted.' }), 100);
1002
+ this._location.back();
1003
+ }
1004
+ async load() {
1005
+ if (!this.apiName || !this.uri)
1006
+ return;
1007
+ this.isLoading = true;
1008
+ const response = await this.getClient().getSingle(this.uri);
1009
+ if (!response.ok || ProblemDetails.isProblemDetails(response.body) || !response.body) {
1010
+ this._messageService.add({ severity: 'error', summary: 'Error', detail: 'Error while loading the resource from the API.', data: response });
1011
+ }
1012
+ else {
1013
+ this._resource = response.body;
1014
+ this._templates = await this.getAllTemplates(this._resource);
1015
+ this._formTabs = this._formService.createFormGroupsFromTemplates(this._templates);
1016
+ }
1017
+ this.isLoading = false;
1018
+ }
1019
+ async setInitialSelectedOptionsElementsForTemplates(templates) {
1020
+ return Promise.all(Object.values(templates)
1021
+ .map(template => this.setInitialSelectedOptionsElementsForTemplate(template)));
1022
+ }
1023
+ imageChanged(formControl, event) {
1024
+ const file = event.files[0];
1025
+ console.log(file);
1026
+ const reader = new FileReader();
1027
+ reader.onload = () => {
1028
+ const uri = reader.result;
1029
+ console.log(uri);
1030
+ formControl.setValue(uri);
1031
+ };
1032
+ reader.readAsDataURL(file);
1033
+ }
1034
+ async setInitialSelectedOptionsElementsForTemplate(template) {
1035
+ return Promise.all(template.properties
1036
+ .filter(property => property?.options?.link?.href)
1037
+ .map(property => this.setInitialSelectedOptionsElementForProperty(property)));
1038
+ }
1039
+ async setInitialSelectedOptionsElementForProperty(property) {
1040
+ const options = property?.options;
1041
+ if (!options?.link?.href)
1042
+ return;
1043
+ const templatedUri = options.link.href;
1044
+ const filter = `${options.valueField} eq ${property.value}`;
1045
+ const response = await this.getClient().getListByUri(templatedUri, { $filter: filter, $top: 10 });
1046
+ if (!response.ok || ProblemDetails.isProblemDetails(response.body) || !response.body) {
1047
+ const message = `An error occurred while getting the filtered items.`;
1048
+ this._messageService.add({ severity: 'error', summary: 'Error', detail: message, data: response });
1049
+ return;
1050
+ }
1051
+ const items = response.body._embedded.items;
1052
+ options.inline = items;
1053
+ }
1054
+ async getAllTemplates(resource) {
1055
+ const formResponses = await this.getClient().getAllForms(resource);
1056
+ const failedResponses = formResponses.filter(response => !response.ok || ProblemDetails.isProblemDetails(response.body) || !response.body);
1057
+ if (failedResponses.length !== 0) {
1058
+ for (const response of failedResponses) {
1059
+ this._messageService.add({ severity: 'error', summary: 'Error', detail: 'Error while loading the resource from the API.', data: response });
1060
+ }
1061
+ return Promise.resolve({});
1062
+ }
1063
+ const formTemplates = Object.assign({}, ...formResponses.map(response => response.body._templates));
1064
+ await this.setInitialSelectedOptionsElementsForTemplates(formTemplates);
1065
+ return formTemplates;
1066
+ }
1067
+ }
1068
+ 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 });
1069
+ 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 } });
1070
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RESTworldEditViewComponent, decorators: [{
1071
+ type: Component,
1072
+ 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"] }]
1073
+ }], 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: [{
1074
+ type: Input
1075
+ }], uri: [{
1076
+ type: Input
1077
+ }], extraTabsRef: [{
1078
+ type: ContentChild,
1079
+ args: ['extraTabs', { static: false }]
1080
+ }], buttonsRef: [{
1081
+ type: ContentChild,
1082
+ args: ['buttons', { static: false }]
1083
+ }], inputOptionsSingleRef: [{
1084
+ type: ContentChild,
1085
+ args: ['inputOptionsSingle', { static: false }]
1086
+ }], inputOptionsMultipleRef: [{
1087
+ type: ContentChild,
1088
+ args: ['inputOptionsMultiple', { static: false }]
1089
+ }], inputOptionsRef: [{
1090
+ type: ContentChild,
1091
+ args: ['inputOptions', { static: false }]
1092
+ }], inputHiddenRef: [{
1093
+ type: ContentChild,
1094
+ args: ['inputHidden', { static: false }]
1095
+ }], inputTextRef: [{
1096
+ type: ContentChild,
1097
+ args: ['inputText', { static: false }]
1098
+ }], inputTextareaRef: [{
1099
+ type: ContentChild,
1100
+ args: ['inputTextarea', { static: false }]
1101
+ }], inputSearchRef: [{
1102
+ type: ContentChild,
1103
+ args: ['inputSearch', { static: false }]
1104
+ }], inputTelRef: [{
1105
+ type: ContentChild,
1106
+ args: ['inputTel', { static: false }]
1107
+ }], inputUrlRef: [{
1108
+ type: ContentChild,
1109
+ args: ['inputUrl', { static: false }]
1110
+ }], inputEmailRef: [{
1111
+ type: ContentChild,
1112
+ args: ['inputEmail', { static: false }]
1113
+ }], inputPasswordRef: [{
1114
+ type: ContentChild,
1115
+ args: ['inputPassword', { static: false }]
1116
+ }], inputDateRef: [{
1117
+ type: ContentChild,
1118
+ args: ['inputDate', { static: false }]
1119
+ }], inputMonthRef: [{
1120
+ type: ContentChild,
1121
+ args: ['inputMonth', { static: false }]
1122
+ }], inputWeekRef: [{
1123
+ type: ContentChild,
1124
+ args: ['inputWeek', { static: false }]
1125
+ }], inputTimeRef: [{
1126
+ type: ContentChild,
1127
+ args: ['inputTime', { static: false }]
1128
+ }], inputDatetimeLocalRef: [{
1129
+ type: ContentChild,
1130
+ args: ['inputDatetimeLocal', { static: false }]
1131
+ }], inputNumberRef: [{
1132
+ type: ContentChild,
1133
+ args: ['inputNumber', { static: false }]
1134
+ }], inputRangeRef: [{
1135
+ type: ContentChild,
1136
+ args: ['inputRange', { static: false }]
1137
+ }], inputColorRef: [{
1138
+ type: ContentChild,
1139
+ args: ['inputColor', { static: false }]
1140
+ }], inputBoolRef: [{
1141
+ type: ContentChild,
1142
+ args: ['inputBool', { static: false }]
1143
+ }], inputDatetimeOffsetRef: [{
1144
+ type: ContentChild,
1145
+ args: ['inputDatetimeOffset', { static: false }]
1146
+ }], inputDurationRef: [{
1147
+ type: ContentChild,
1148
+ args: ['inputDuration', { static: false }]
1149
+ }], inputImageRef: [{
1150
+ type: ContentChild,
1151
+ args: ['inputImage', { static: false }]
1152
+ }], inputFileRef: [{
1153
+ type: ContentChild,
1154
+ args: ['inputFile', { static: false }]
1155
+ }], inputDefaultRef: [{
1156
+ type: ContentChild,
1157
+ args: ['inputDefault', { static: false }]
1158
+ }] } });
1159
+
1160
+ var ColumnType;
1161
+ (function (ColumnType) {
1162
+ ColumnType["text"] = "text";
1163
+ ColumnType["numeric"] = "numeric";
1164
+ ColumnType["boolean"] = "boolean";
1165
+ ColumnType["date"] = "date";
1166
+ })(ColumnType || (ColumnType = {}));
1167
+ class RESTworldListViewComponent {
1168
+ constructor(_clients, _confirmationService, _messageService, avatarGenerator) {
1169
+ this._clients = _clients;
1170
+ this._confirmationService = _confirmationService;
1171
+ this._messageService = _messageService;
1172
+ this.avatarGenerator = avatarGenerator;
1173
+ this._columns = [];
1174
+ this._editLink = '/edit';
1175
+ this.isLoading = false;
1176
+ this._totalRecords = 0;
1177
+ this.rowsPerPage = [10, 25, 50];
1178
+ this._lastEvent = {
1179
+ rows: this.rowsPerPage[0]
1180
+ };
1181
+ }
1182
+ get columns() {
1183
+ return this._columns;
1184
+ }
1185
+ set editLink(value) {
1186
+ if (value)
1187
+ this._editLink = value;
1188
+ }
1189
+ get editLink() {
1190
+ return this._editLink;
1191
+ }
1192
+ set apiName(value) {
1193
+ this._apiName = value;
1194
+ if (this.apiName && this.rel && this._lastEvent)
1195
+ this.load(this._lastEvent);
1196
+ }
1197
+ get apiName() {
1198
+ return this._apiName;
1199
+ }
1200
+ set rel(value) {
1201
+ this._rel = value;
1202
+ if (this.apiName && this.rel && this._lastEvent)
1203
+ this.load(this._lastEvent);
1204
+ }
1205
+ get rel() {
1206
+ return this._rel;
1207
+ }
1208
+ get value() {
1209
+ return this.resource?._embedded?.items || [];
1210
+ }
1211
+ get rows() {
1212
+ return this._lastEvent?.rows || 0;
1213
+ }
1214
+ get totalRecords() {
1215
+ return this._totalRecords;
1216
+ }
1217
+ set totalRecords(value) {
1218
+ this._totalRecords = value || 0;
1219
+ }
1220
+ get sortOrder() {
1221
+ return this._lastEvent.sortOrder || 0;
1222
+ }
1223
+ get newHref() {
1224
+ return this.resource?.findLink('new')?.href;
1225
+ }
1226
+ get dateFormat() {
1227
+ return RESTworldListViewComponent._dateFormat;
1228
+ }
1229
+ getClient() {
1230
+ if (!this.apiName)
1231
+ throw new Error('Cannot get a client, because the apiName is not set.');
1232
+ return this._clients.getClient(this.apiName);
1233
+ }
1234
+ async load(event) {
1235
+ if (!this.apiName || !this.rel)
1236
+ return;
1237
+ this.isLoading = true;
1238
+ this._lastEvent = event;
1239
+ const parameters = this.createParametersFromEvent(event);
1240
+ const response = await this.getClient().getList(this.rel, parameters);
1241
+ if (!response.ok || ProblemDetails.isProblemDetails(response.body) || !response.body) {
1242
+ this._messageService.add({ severity: 'error', summary: 'Error', detail: 'Error while loading the resources from the API.', data: response });
1243
+ }
1244
+ else if (response.body) {
1245
+ this.resource = response.body;
1246
+ this.totalRecords = this.resource.totalPages && parameters.$top ? this.resource.totalPages * parameters.$top : undefined;
1247
+ this._columns = this.createColumns();
1248
+ }
1249
+ this.isLoading = false;
1250
+ }
1251
+ showDeleteConfirmatioModal(resource) {
1252
+ this._confirmationService.confirm({
1253
+ message: 'Do you really want to delete this resource?',
1254
+ header: 'Confirm delete',
1255
+ icon: 'far fa-trash-alt',
1256
+ accept: () => this.delete(resource)
1257
+ });
1258
+ }
1259
+ async delete(resource) {
1260
+ if (!this.apiName || !this.rel)
1261
+ return;
1262
+ await this.getClient().delete(resource);
1263
+ this._messageService.add({ severity: 'success', summary: 'Deleted', detail: 'The resource has been deleted.' });
1264
+ this.load(this._lastEvent);
1265
+ }
1266
+ createColumns() {
1267
+ if (this.value.length === 0)
1268
+ return this.columns;
1269
+ // Get all distinct properties from all rows
1270
+ // We look at all rows to eliminate possible undefined values
1271
+ const rowsWithProperties = this.value
1272
+ .map(resource => Object.entries(resource)
1273
+ .filter(p => p[0] !== '_links' &&
1274
+ p[0] !== '_embedded' &&
1275
+ p[0] !== 'id' &&
1276
+ p[0] !== 'timestamp'));
1277
+ const distinctProperties = rowsWithProperties[0];
1278
+ for (const propertiesOfRow of rowsWithProperties) {
1279
+ for (const property of propertiesOfRow) {
1280
+ const propertyName = property[0];
1281
+ const propertyValue = property[1];
1282
+ const alreadyFoundPropertyWithSameName = distinctProperties.find(p => p[0] === propertyName);
1283
+ if (!alreadyFoundPropertyWithSameName) // Add new property
1284
+ distinctProperties.push(property);
1285
+ else if (!alreadyFoundPropertyWithSameName[1] && propertyValue) // Use defined value instead of existing undefined value
1286
+ alreadyFoundPropertyWithSameName[1] = propertyValue;
1287
+ }
1288
+ }
1289
+ // Check if the rows are entities with change tracking
1290
+ const withoutChangeTrackingProperties = distinctProperties.filter(p => p[0] !== 'createdAt' &&
1291
+ p[0] !== 'createdBy' &&
1292
+ p[0] !== 'lastChangedAt' &&
1293
+ p[0] !== 'lastChangedBy');
1294
+ const hasChangeTrackingProperties = withoutChangeTrackingProperties.length < distinctProperties.length;
1295
+ // First the id, then all other properties
1296
+ const sortedProperties = [
1297
+ ['id', 0],
1298
+ ...withoutChangeTrackingProperties
1299
+ ];
1300
+ // And change tracking properties at the end
1301
+ if (hasChangeTrackingProperties) {
1302
+ sortedProperties.push(['createdAt', new Date()]);
1303
+ sortedProperties.push(['createdBy', '']);
1304
+ sortedProperties.push(['lastChangedAt', new Date()]);
1305
+ sortedProperties.push(['lastChangedBy', '']);
1306
+ }
1307
+ const columns = sortedProperties
1308
+ .map(p => ({
1309
+ header: RESTworldListViewComponent.toTitleCase(p[0]),
1310
+ field: p[0],
1311
+ type: RESTworldListViewComponent.getColumnType(p[1]),
1312
+ }));
1313
+ return columns;
1314
+ }
1315
+ static getColumnType(value) {
1316
+ if (value === null || value === undefined)
1317
+ return ColumnType.text;
1318
+ if (_.isNumber(value))
1319
+ return ColumnType.numeric;
1320
+ if (_.isDate(value))
1321
+ return ColumnType.date;
1322
+ if (_.isString(value))
1323
+ return ColumnType.text;
1324
+ if (_.isBoolean(value))
1325
+ return ColumnType.boolean;
1326
+ return ColumnType.text;
1327
+ }
1328
+ static toTitleCase(anyCase) {
1329
+ return anyCase
1330
+ .replace(/(_)+/g, ' ') // underscore to whitespace
1331
+ .replace(/([a-z])([A-Z][a-z])/g, "$1 $2") // insert space before each new word if there is none
1332
+ .replace(/([A-Z][a-z])([A-Z])/g, "$1 $2") // insert space after each word if there is none
1333
+ .replace(/([a-z])([A-Z]+[a-z])/g, "$1 $2") // insert space after single letter word if there is none
1334
+ .replace(/([A-Z]+)([A-Z][a-z][a-z])/g, "$1 $2") // insert space before single letter word if there is none
1335
+ .replace(/([a-z]+)([A-Z0-9]+)/g, "$1 $2") // insert space after numbers
1336
+ .replace(/^./, (match) => match.toUpperCase()); // change first letter to be upper case
1337
+ }
1338
+ createParametersFromEvent(event) {
1339
+ const oDataParameters = {
1340
+ $filter: this.createFilterFromEvent(event),
1341
+ $orderby: RESTworldListViewComponent.createOrderByFromEvent(event),
1342
+ $top: RESTworldListViewComponent.createTopFromEvent(event),
1343
+ $skip: RESTworldListViewComponent.createSkipFromEvent(event)
1344
+ };
1345
+ return oDataParameters;
1346
+ }
1347
+ static createSkipFromEvent(event) {
1348
+ return event.first;
1349
+ }
1350
+ static createTopFromEvent(event) {
1351
+ return event.rows;
1352
+ }
1353
+ static createOrderByFromEvent(event) {
1354
+ if (event.sortField) {
1355
+ const order = !event.sortOrder || event.sortOrder > 0 ? 'asc' : 'desc';
1356
+ return `${event.sortField} ${order}`;
1357
+ }
1358
+ return undefined;
1359
+ }
1360
+ createFilterFromEvent(event) {
1361
+ if (!event.filters)
1362
+ return undefined;
1363
+ const filter = Object.entries(event.filters)
1364
+ // The type definition is wrong, event.filters has values of type FilterMetadata[] and not FilterMetadata.
1365
+ .map(([property, filter]) => ({ property: property, filters: filter }))
1366
+ .map(f => this.createFilterForPropertyArray(f.property, f.filters))
1367
+ .filter(f => !!f)
1368
+ .join(' and ');
1369
+ if (filter === '')
1370
+ return undefined;
1371
+ return `(${filter})`;
1372
+ }
1373
+ createFilterForPropertyArray(property, filters) {
1374
+ const filter = filters
1375
+ .map(f => this.createFilterForProperty(property, f))
1376
+ .filter(f => !!f)
1377
+ .join(` ${filters[0].operator} `);
1378
+ if (filter === '')
1379
+ return undefined;
1380
+ return `(${filter})`;
1381
+ }
1382
+ createFilterForProperty(property, filter) {
1383
+ if (!filter.value)
1384
+ return undefined;
1385
+ const oDataOperator = RESTworldListViewComponent.createODataOperator(filter.matchMode);
1386
+ const comparisonValue = this.createComparisonValue(property, filter.value);
1387
+ switch (oDataOperator) {
1388
+ case 'contains':
1389
+ case 'not contains':
1390
+ case 'startswith':
1391
+ case 'endswith':
1392
+ return `${oDataOperator}(${property}, ${comparisonValue})`;
1393
+ default:
1394
+ return `${property} ${oDataOperator} ${comparisonValue}`;
1395
+ }
1396
+ }
1397
+ static createODataOperator(matchMode) {
1398
+ switch (matchMode) {
1399
+ case FilterMatchMode.STARTS_WITH:
1400
+ return 'startswith';
1401
+ case FilterMatchMode.CONTAINS:
1402
+ return 'contains';
1403
+ case FilterMatchMode.NOT_CONTAINS:
1404
+ return 'not contains';
1405
+ case FilterMatchMode.ENDS_WITH:
1406
+ return 'endswith';
1407
+ case FilterMatchMode.EQUALS:
1408
+ return 'eq';
1409
+ case FilterMatchMode.NOT_EQUALS:
1410
+ return 'ne';
1411
+ case FilterMatchMode.IN:
1412
+ return 'in';
1413
+ case FilterMatchMode.LESS_THAN:
1414
+ return 'lt';
1415
+ case FilterMatchMode.LESS_THAN_OR_EQUAL_TO:
1416
+ return 'le';
1417
+ case FilterMatchMode.GREATER_THAN:
1418
+ return 'gt';
1419
+ case FilterMatchMode.GREATER_THAN_OR_EQUAL_TO:
1420
+ return 'ge';
1421
+ case FilterMatchMode.IS:
1422
+ return 'eq';
1423
+ case FilterMatchMode.IS_NOT:
1424
+ return 'ne';
1425
+ case FilterMatchMode.BEFORE:
1426
+ return 'lt';
1427
+ case FilterMatchMode.AFTER:
1428
+ return 'gt';
1429
+ case FilterMatchMode.DATE_AFTER:
1430
+ return 'ge';
1431
+ case FilterMatchMode.DATE_BEFORE:
1432
+ return 'lt';
1433
+ case FilterMatchMode.DATE_IS:
1434
+ return 'eq';
1435
+ case FilterMatchMode.DATE_IS_NOT:
1436
+ return 'ne';
1437
+ default:
1438
+ throw Error(`Unknown matchMode ${matchMode}`);
1439
+ }
1440
+ }
1441
+ createComparisonValue(property, value) {
1442
+ if (value === null || value === undefined)
1443
+ return 'null';
1444
+ const columns = this.columns.filter(c => c.field === property);
1445
+ if (columns.length !== 1)
1446
+ throw new Error(`Cannot find the column for the property ${property} which is specified in the filter.`);
1447
+ const type = columns[0].type;
1448
+ switch (type) {
1449
+ case ColumnType.boolean:
1450
+ return `${value}`;
1451
+ case ColumnType.date:
1452
+ return `cast(${value.toISOString()}, Edm.DateTimeOffset)`;
1453
+ case ColumnType.numeric:
1454
+ return `${value}`;
1455
+ case ColumnType.text:
1456
+ return `'${value}'`;
1457
+ default:
1458
+ throw new Error(`Unknown column type '${type}'`);
1459
+ }
1460
+ }
1461
+ }
1462
+ RESTworldListViewComponent._dateFormat = new Date(3333, 10, 22)
1463
+ .toLocaleDateString()
1464
+ .replace("22", "dd")
1465
+ .replace("11", "MM")
1466
+ .replace("3333", "y")
1467
+ .replace("33", "yy");
1468
+ 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 });
1469
+ 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 } });
1470
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RESTworldListViewComponent, decorators: [{
1471
+ type: Component,
1472
+ 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"] }]
1473
+ }], ctorParameters: function () { return [{ type: RESTworldClientCollection }, { type: i2$1.ConfirmationService }, { type: i2$1.MessageService }, { type: AvatarGenerator }]; }, propDecorators: { editLink: [{
1474
+ type: Input
1475
+ }], apiName: [{
1476
+ type: Input
1477
+ }], rel: [{
1478
+ type: Input
1479
+ }], rowsPerPage: [{
1480
+ type: Input
1481
+ }] } });
1482
+
1483
+ function initializeSettings(settingsService) {
1484
+ return async () => await settingsService.initialize();
1485
+ }
1486
+ class RestworldClientModule {
1487
+ }
1488
+ RestworldClientModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RestworldClientModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1489
+ RestworldClientModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RestworldClientModule, declarations: [RESTworldListViewComponent,
1490
+ RESTworldEditViewComponent,
1491
+ RESTWorldImageViewComponent,
1492
+ RESTWorldFileViewComponent,
1493
+ SafeUrlPipe,
1494
+ AsPipe,
1495
+ RestworldEditFormComponent], imports: [CommonModule,
1496
+ RouterModule,
1497
+ FormsModule,
1498
+ ReactiveFormsModule,
1499
+ TableModule,
1500
+ TooltipModule,
1501
+ ScrollingModule,
1502
+ InputTextModule,
1503
+ InputNumberModule,
1504
+ CalendarModule,
1505
+ CheckboxModule,
1506
+ ConfirmDialogModule,
1507
+ ToastModule,
1508
+ MessagesModule,
1509
+ PanelModule,
1510
+ TabViewModule,
1511
+ SkeletonModule,
1512
+ ProgressSpinnerModule,
1513
+ RippleModule,
1514
+ TriStateCheckboxModule,
1515
+ AvatarModule,
1516
+ DropdownModule,
1517
+ MultiSelectModule,
1518
+ FileUploadModule,
1519
+ ValdemortModule,
1520
+ ImageCropperModule,
1521
+ DialogModule,
1522
+ ButtonModule,
1523
+ ColorPickerModule,
1524
+ DragDropModule], exports: [RESTworldListViewComponent,
1525
+ RESTworldEditViewComponent,
1526
+ RESTWorldImageViewComponent,
1527
+ RESTWorldFileViewComponent,
1528
+ SafeUrlPipe] });
1529
+ RestworldClientModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RestworldClientModule, providers: [
1530
+ RESTworldClientCollection,
1531
+ AvatarGenerator,
1532
+ ConfirmationService,
1533
+ FormService,
1534
+ MessageService,
1535
+ {
1536
+ provide: APP_INITIALIZER,
1537
+ useFactory: initializeSettings,
1538
+ deps: [SettingsService],
1539
+ multi: true,
1540
+ }
1541
+ ], imports: [[
1542
+ CommonModule,
1543
+ RouterModule,
1544
+ FormsModule,
1545
+ ReactiveFormsModule,
1546
+ TableModule,
1547
+ TooltipModule,
1548
+ ScrollingModule,
1549
+ InputTextModule,
1550
+ InputNumberModule,
1551
+ CalendarModule,
1552
+ CheckboxModule,
1553
+ ConfirmDialogModule,
1554
+ ToastModule,
1555
+ MessagesModule,
1556
+ PanelModule,
1557
+ TabViewModule,
1558
+ SkeletonModule,
1559
+ ProgressSpinnerModule,
1560
+ RippleModule,
1561
+ TriStateCheckboxModule,
1562
+ AvatarModule,
1563
+ DropdownModule,
1564
+ MultiSelectModule,
1565
+ FileUploadModule,
1566
+ ValdemortModule,
1567
+ ImageCropperModule,
1568
+ DialogModule,
1569
+ ButtonModule,
1570
+ ColorPickerModule,
1571
+ DragDropModule
1572
+ ]] });
1573
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: RestworldClientModule, decorators: [{
1574
+ type: NgModule,
1575
+ args: [{
1576
+ declarations: [
1577
+ RESTworldListViewComponent,
1578
+ RESTworldEditViewComponent,
1579
+ RESTWorldImageViewComponent,
1580
+ RESTWorldFileViewComponent,
1581
+ SafeUrlPipe,
1582
+ AsPipe,
1583
+ RestworldEditFormComponent
1584
+ ],
1585
+ imports: [
1586
+ CommonModule,
1587
+ RouterModule,
1588
+ FormsModule,
1589
+ ReactiveFormsModule,
1590
+ TableModule,
1591
+ TooltipModule,
1592
+ ScrollingModule,
1593
+ InputTextModule,
1594
+ InputNumberModule,
1595
+ CalendarModule,
1596
+ CheckboxModule,
1597
+ ConfirmDialogModule,
1598
+ ToastModule,
1599
+ MessagesModule,
1600
+ PanelModule,
1601
+ TabViewModule,
1602
+ SkeletonModule,
1603
+ ProgressSpinnerModule,
1604
+ RippleModule,
1605
+ TriStateCheckboxModule,
1606
+ AvatarModule,
1607
+ DropdownModule,
1608
+ MultiSelectModule,
1609
+ FileUploadModule,
1610
+ ValdemortModule,
1611
+ ImageCropperModule,
1612
+ DialogModule,
1613
+ ButtonModule,
1614
+ ColorPickerModule,
1615
+ DragDropModule
1616
+ ],
1617
+ exports: [
1618
+ RESTworldListViewComponent,
1619
+ RESTworldEditViewComponent,
1620
+ RESTWorldImageViewComponent,
1621
+ RESTWorldFileViewComponent,
1622
+ SafeUrlPipe
1623
+ ],
1624
+ providers: [
1625
+ RESTworldClientCollection,
1626
+ AvatarGenerator,
1627
+ ConfirmationService,
1628
+ FormService,
1629
+ MessageService,
1630
+ {
1631
+ provide: APP_INITIALIZER,
1632
+ useFactory: initializeSettings,
1633
+ deps: [SettingsService],
1634
+ multi: true,
1635
+ }
1636
+ ]
1637
+ }]
1638
+ }] });
1639
+
1640
+ /*
1641
+ * Public API Surface of ngx-restworld-client
1642
+ */
1643
+
1644
+ /**
1645
+ * Generated bundle index. Do not edit.
1646
+ */
1647
+
1648
+ export { AsPipe, AvatarGenerator, ColumnType, FormService, LinkNames, ProblemDetails, RESTWorldFileViewComponent, RESTWorldImageViewComponent, RESTworldClient, RESTworldClientCollection, RESTworldEditViewComponent, RESTworldListViewComponent, RESTworldOptions, RestworldClientModule, RestworldEditFormComponent, SafeUrlPipe, SettingsService, initializeSettings };
1649
+ //# sourceMappingURL=wertzui-ngx-restworld-client.mjs.map