@wertzui/ngx-restworld-client 2.0.0 → 3.0.0

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