@wertzui/ngx-restworld-client 1.0.2 → 2.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.
- package/bundles/wertzui-ngx-restworld-client.umd.js +1101 -301
- package/bundles/wertzui-ngx-restworld-client.umd.js.map +1 -1
- package/esm2015/lib/models/problem-details.js +2 -2
- package/esm2015/lib/pipes/as.pipe.js +25 -0
- package/esm2015/lib/pipes/safe-url.pipe.js +23 -0
- package/esm2015/lib/restworld-client.module.js +68 -8
- package/esm2015/lib/services/avatar-generator.js +2 -2
- package/esm2015/lib/services/form.service.js +69 -0
- package/esm2015/lib/services/restworld-client-collection.js +1 -1
- package/esm2015/lib/services/restworld-client.js +46 -8
- package/esm2015/lib/views/restworld-edit-form/restworld-edit-form.component.js +238 -0
- package/esm2015/lib/views/restworld-edit-view/restworld-edit-view.component.js +209 -143
- package/esm2015/lib/views/restworld-file-view/restworld-file-view.component.js +63 -0
- package/esm2015/lib/views/restworld-image-view/restworld-image-view.component.js +107 -0
- package/esm2015/lib/views/restworld-list-view/restworld-list-view.component.js +64 -37
- package/esm2015/public-api.js +7 -1
- package/fesm2015/wertzui-ngx-restworld-client.js +880 -220
- package/fesm2015/wertzui-ngx-restworld-client.js.map +1 -1
- package/lib/models/problem-details.d.ts +4 -8
- package/lib/pipes/as.pipe.d.ts +18 -0
- package/lib/pipes/safe-url.pipe.d.ts +10 -0
- package/lib/restworld-client.module.d.ts +35 -21
- package/lib/services/form.service.d.ts +14 -0
- package/lib/services/restworld-client.d.ts +4 -1
- package/lib/views/restworld-edit-form/restworld-edit-form.component.d.ts +69 -0
- package/lib/views/restworld-edit-view/restworld-edit-view.component.d.ts +53 -32
- package/lib/views/restworld-file-view/restworld-file-view.component.d.ts +21 -0
- package/lib/views/restworld-image-view/restworld-image-view.component.d.ts +38 -0
- package/lib/views/restworld-list-view/restworld-list-view.component.d.ts +20 -8
- package/package.json +29 -8
- package/public-api.d.ts +6 -0
|
@@ -1,48 +1,66 @@
|
|
|
1
1
|
import * as _ from 'lodash';
|
|
2
|
-
import * as i1 from '@wertzui/ngx-hal-client';
|
|
3
|
-
import { Resource, PagedListResource } from '@wertzui/ngx-hal-client';
|
|
2
|
+
import * as i1$1 from '@wertzui/ngx-hal-client';
|
|
3
|
+
import { Resource, PropertyType, PagedListResource, Link, FormsResource, Template } from '@wertzui/ngx-hal-client';
|
|
4
4
|
import * as i0 from '@angular/core';
|
|
5
|
-
import { Injectable, Input, Component, ContentChild, APP_INITIALIZER, NgModule } 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';
|
|
6
9
|
import { __awaiter } from 'tslib';
|
|
7
|
-
import * as i1$
|
|
10
|
+
import * as i1$2 from '@angular/common/http';
|
|
8
11
|
import { HttpHeaders, HttpClient } from '@angular/common/http';
|
|
9
|
-
import * as
|
|
10
|
-
import { FormGroup, FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
11
|
-
import * as i2 from 'primeng/api';
|
|
12
|
+
import * as i2$1 from 'primeng/api';
|
|
12
13
|
import { FilterMatchMode, ConfirmationService, MessageService } from 'primeng/api';
|
|
13
|
-
import * as
|
|
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';
|
|
14
37
|
import { CommonModule } from '@angular/common';
|
|
15
|
-
import * as
|
|
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';
|
|
16
49
|
import { RouterModule } from '@angular/router';
|
|
17
|
-
import * as
|
|
50
|
+
import * as i7$2 from 'primeng/tabview';
|
|
18
51
|
import { TabViewModule } from 'primeng/tabview';
|
|
19
|
-
import * as
|
|
52
|
+
import * as i8$1 from 'primeng/skeleton';
|
|
20
53
|
import { SkeletonModule } from 'primeng/skeleton';
|
|
21
|
-
import * as
|
|
22
|
-
import { CalendarModule } from 'primeng/calendar';
|
|
23
|
-
import * as i8 from 'primeng/inputnumber';
|
|
24
|
-
import { InputNumberModule } from 'primeng/inputnumber';
|
|
25
|
-
import * as i9 from 'primeng/checkbox';
|
|
26
|
-
import { CheckboxModule } from 'primeng/checkbox';
|
|
27
|
-
import * as i10 from 'primeng/progressspinner';
|
|
54
|
+
import * as i10$1 from 'primeng/progressspinner';
|
|
28
55
|
import { ProgressSpinnerModule } from 'primeng/progressspinner';
|
|
29
56
|
import * as i11 from 'primeng/toast';
|
|
30
57
|
import { ToastModule } from 'primeng/toast';
|
|
31
|
-
import * as i12 from 'primeng/confirmdialog';
|
|
58
|
+
import * as i12$1 from 'primeng/confirmdialog';
|
|
32
59
|
import { ConfirmDialogModule } from 'primeng/confirmdialog';
|
|
33
|
-
import * as
|
|
34
|
-
import { InputTextModule } from 'primeng/inputtext';
|
|
35
|
-
import * as i15 from 'primeng/button';
|
|
36
|
-
import * as i16 from 'primeng/ripple';
|
|
37
|
-
import { RippleModule } from 'primeng/ripple';
|
|
38
|
-
import * as i4$1 from 'primeng/table';
|
|
60
|
+
import * as i4$3 from 'primeng/table';
|
|
39
61
|
import { TableModule } from 'primeng/table';
|
|
40
|
-
import * as i5$
|
|
62
|
+
import * as i5$2 from 'primeng/avatar';
|
|
41
63
|
import { AvatarModule } from 'primeng/avatar';
|
|
42
|
-
import * as i6$1 from 'primeng/tristatecheckbox';
|
|
43
|
-
import { TriStateCheckboxModule } from 'primeng/tristatecheckbox';
|
|
44
|
-
import * as i10$1 from 'primeng/tooltip';
|
|
45
|
-
import { TooltipModule } from 'primeng/tooltip';
|
|
46
64
|
import { ScrollingModule } from '@angular/cdk/scrolling';
|
|
47
65
|
import { MessagesModule } from 'primeng/messages';
|
|
48
66
|
import { PanelModule } from 'primeng/panel';
|
|
@@ -62,7 +80,7 @@ class ProblemDetails extends Resource {
|
|
|
62
80
|
return resource instanceof ProblemDetails;
|
|
63
81
|
}
|
|
64
82
|
static containsProblemDetailsInformation(resource) {
|
|
65
|
-
return resource && (resource instanceof ProblemDetails || (resource instanceof Resource &&
|
|
83
|
+
return resource && (resource instanceof ProblemDetails || (resource instanceof Resource && 'status' in resource && _.isNumber(resource['status']) && resource['status'] >= 100 && resource['status'] < 600));
|
|
66
84
|
}
|
|
67
85
|
static fromResource(resource) {
|
|
68
86
|
if (!ProblemDetails.containsProblemDetailsInformation(resource))
|
|
@@ -80,9 +98,51 @@ class RESTworldOptions {
|
|
|
80
98
|
}
|
|
81
99
|
}
|
|
82
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
|
+
|
|
83
143
|
class AvatarGenerator {
|
|
84
144
|
constructor() {
|
|
85
|
-
this.getImageOverride = (
|
|
145
|
+
this.getImageOverride = () => '';
|
|
86
146
|
}
|
|
87
147
|
getImage(nameOrEmail) {
|
|
88
148
|
let uri = AvatarGenerator._imageCache.get(nameOrEmail);
|
|
@@ -175,6 +235,71 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.11", ngImpo
|
|
|
175
235
|
type: Input
|
|
176
236
|
}] } });
|
|
177
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
|
+
|
|
178
303
|
class RESTworldClient {
|
|
179
304
|
constructor(_halClient, _options) {
|
|
180
305
|
this._halClient = _halClient;
|
|
@@ -199,7 +324,7 @@ class RESTworldClient {
|
|
|
199
324
|
}
|
|
200
325
|
getHomeForced() {
|
|
201
326
|
return __awaiter(this, void 0, void 0, function* () {
|
|
202
|
-
const header = RESTworldClient.createHeaders(this._options.Version);
|
|
327
|
+
const header = RESTworldClient.createHeaders('application/hal+json', this._options.Version);
|
|
203
328
|
const response = yield this.halClient.get(this._options.BaseUrl, Resource, ProblemDetails, header);
|
|
204
329
|
return response;
|
|
205
330
|
});
|
|
@@ -220,6 +345,15 @@ class RESTworldClient {
|
|
|
220
345
|
return response;
|
|
221
346
|
});
|
|
222
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
|
+
}
|
|
223
357
|
getSingle(relOrUri, id, headers, curie) {
|
|
224
358
|
return __awaiter(this, void 0, void 0, function* () {
|
|
225
359
|
let uri;
|
|
@@ -249,7 +383,7 @@ class RESTworldClient {
|
|
|
249
383
|
throw new Error(`The save link ${saveLink} does not have a save name.`);
|
|
250
384
|
const uri = saveLink.href;
|
|
251
385
|
const method = saveLink.name.toLowerCase();
|
|
252
|
-
const header = RESTworldClient.createHeaders(this._options.Version);
|
|
386
|
+
const header = RESTworldClient.createHeaders('application/hal+json', this._options.Version);
|
|
253
387
|
let response;
|
|
254
388
|
switch (method) {
|
|
255
389
|
case 'put':
|
|
@@ -264,13 +398,42 @@ class RESTworldClient {
|
|
|
264
398
|
return response;
|
|
265
399
|
});
|
|
266
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
|
+
}
|
|
267
430
|
delete(resource) {
|
|
268
431
|
return __awaiter(this, void 0, void 0, function* () {
|
|
269
432
|
const deleteLink = resource.findLink('delete');
|
|
270
433
|
if (!deleteLink)
|
|
271
434
|
throw new Error(`The resource ${resource} does not have a delete link.`);
|
|
272
435
|
const uri = deleteLink.href;
|
|
273
|
-
const header = RESTworldClient.createHeaders(this._options.Version);
|
|
436
|
+
const header = RESTworldClient.createHeaders('application/hal+json', this._options.Version);
|
|
274
437
|
const response = yield this.halClient.delete(uri, ProblemDetails, header);
|
|
275
438
|
return response;
|
|
276
439
|
});
|
|
@@ -282,7 +445,7 @@ class RESTworldClient {
|
|
|
282
445
|
}
|
|
283
446
|
getLinkFromHome(rel, name, curie) {
|
|
284
447
|
const links = this.getLinksFromHome(rel, curie);
|
|
285
|
-
const link =
|
|
448
|
+
const link = name ? links.find(l => l.name === name) : links[0];
|
|
286
449
|
if (!link)
|
|
287
450
|
throw new Error(`The home resource does not have a link with the rel '${this.getFullRel(rel, curie)}' and the name '${name}'.`);
|
|
288
451
|
return link;
|
|
@@ -307,9 +470,9 @@ class RESTworldClient {
|
|
|
307
470
|
const fullRel = `${curie}:${rel}`;
|
|
308
471
|
return fullRel;
|
|
309
472
|
}
|
|
310
|
-
static createHeaders(version) {
|
|
473
|
+
static createHeaders(mediaType, version) {
|
|
311
474
|
if (version)
|
|
312
|
-
return new HttpHeaders({ 'Accept':
|
|
475
|
+
return new HttpHeaders({ 'Accept': `${mediaType || 'application/hal+json'}; v=${version}` });
|
|
313
476
|
return new HttpHeaders();
|
|
314
477
|
}
|
|
315
478
|
}
|
|
@@ -342,14 +505,14 @@ class RESTworldClientCollection {
|
|
|
342
505
|
return this._clients;
|
|
343
506
|
}
|
|
344
507
|
}
|
|
345
|
-
RESTworldClientCollection.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.11", ngImport: i0, type: RESTworldClientCollection, deps: [{ token: i1.HalClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
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 });
|
|
346
509
|
RESTworldClientCollection.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.11", ngImport: i0, type: RESTworldClientCollection, providedIn: 'root' });
|
|
347
510
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.11", ngImport: i0, type: RESTworldClientCollection, decorators: [{
|
|
348
511
|
type: Injectable,
|
|
349
512
|
args: [{
|
|
350
513
|
providedIn: 'root'
|
|
351
514
|
}]
|
|
352
|
-
}], ctorParameters: function () { return [{ type: i1.HalClient }]; } });
|
|
515
|
+
}], ctorParameters: function () { return [{ type: i1$1.HalClient }]; } });
|
|
353
516
|
|
|
354
517
|
class SettingsService {
|
|
355
518
|
constructor(backend, _clients) {
|
|
@@ -382,31 +545,397 @@ class SettingsService {
|
|
|
382
545
|
});
|
|
383
546
|
}
|
|
384
547
|
}
|
|
385
|
-
SettingsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.11", ngImport: i0, type: SettingsService, deps: [{ token: i1$
|
|
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 });
|
|
386
549
|
SettingsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.11", ngImport: i0, type: SettingsService, providedIn: 'root' });
|
|
387
550
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.11", ngImport: i0, type: SettingsService, decorators: [{
|
|
388
551
|
type: Injectable,
|
|
389
552
|
args: [{
|
|
390
553
|
providedIn: 'root'
|
|
391
554
|
}]
|
|
392
|
-
}], ctorParameters: function () { return [{ type: i1$
|
|
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: </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
|
+
}] } });
|
|
393
914
|
|
|
394
915
|
class RESTworldEditViewComponent {
|
|
395
|
-
constructor(_clients, _confirmationService, _messageService, _location, _router) {
|
|
916
|
+
constructor(_clients, _confirmationService, _messageService, _location, _router, _formService, valdemortConfig) {
|
|
396
917
|
this._clients = _clients;
|
|
397
918
|
this._confirmationService = _confirmationService;
|
|
398
919
|
this._messageService = _messageService;
|
|
399
920
|
this._location = _location;
|
|
400
921
|
this._router = _router;
|
|
401
|
-
this.
|
|
402
|
-
this.
|
|
922
|
+
this._formService = _formService;
|
|
923
|
+
this._templates = {};
|
|
924
|
+
this._formTabs = {};
|
|
403
925
|
this.isLoading = false;
|
|
926
|
+
valdemortConfig.errorClasses = 'p-error text-sm';
|
|
927
|
+
}
|
|
928
|
+
get PropertyType() {
|
|
929
|
+
return PropertyType;
|
|
404
930
|
}
|
|
405
|
-
get
|
|
406
|
-
return this.
|
|
931
|
+
get templates() {
|
|
932
|
+
return this._templates;
|
|
407
933
|
}
|
|
408
|
-
get
|
|
409
|
-
return this.
|
|
934
|
+
get isLoadingForTheFirstTime() {
|
|
935
|
+
return Object.keys(this.templates).length === 0 && this.isLoading;
|
|
936
|
+
}
|
|
937
|
+
get formTabs() {
|
|
938
|
+
return this._formTabs;
|
|
410
939
|
}
|
|
411
940
|
set apiName(value) {
|
|
412
941
|
this._apiName = value;
|
|
@@ -443,39 +972,68 @@ class RESTworldEditViewComponent {
|
|
|
443
972
|
const length = (_b = (_a = this.resource) === null || _a === void 0 ? void 0 : _a._links["delete"]) === null || _b === void 0 ? void 0 : _b.length;
|
|
444
973
|
return length !== undefined && length > 0;
|
|
445
974
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
.
|
|
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;
|
|
453
992
|
}
|
|
454
993
|
getClient() {
|
|
455
994
|
if (!this.apiName)
|
|
456
995
|
throw new Error('Cannot get a client, because the apiName is not set.');
|
|
457
996
|
return this._clients.getClient(this.apiName);
|
|
458
997
|
}
|
|
459
|
-
|
|
998
|
+
submit(templateName, template, formValue) {
|
|
460
999
|
return __awaiter(this, void 0, void 0, function* () {
|
|
461
|
-
if (!this.apiName || !this.uri || !this.resource)
|
|
462
|
-
return;
|
|
463
|
-
Object.assign(this.resource, this.formGroup.value);
|
|
464
|
-
const selfHrefBeforeSave = this.resource._links.self[0].href;
|
|
465
1000
|
this.isLoading = true;
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
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
|
+
}
|
|
477
1030
|
}
|
|
478
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;
|
|
479
1037
|
});
|
|
480
1038
|
}
|
|
481
1039
|
showDeleteConfirmatioModal() {
|
|
@@ -490,7 +1048,7 @@ class RESTworldEditViewComponent {
|
|
|
490
1048
|
return __awaiter(this, void 0, void 0, function* () {
|
|
491
1049
|
if (!this.apiName || !this.uri || !this.resource)
|
|
492
1050
|
return;
|
|
493
|
-
Object.assign(this.resource, this.
|
|
1051
|
+
Object.assign(this.resource, this.formTabs.value);
|
|
494
1052
|
yield this.getClient().delete(this.resource);
|
|
495
1053
|
setTimeout(() => this._messageService.add({ severity: 'success', summary: 'Deleted', detail: 'The resource has been deleted.' }), 100);
|
|
496
1054
|
this._location.back();
|
|
@@ -507,136 +1065,173 @@ class RESTworldEditViewComponent {
|
|
|
507
1065
|
}
|
|
508
1066
|
else {
|
|
509
1067
|
this._resource = response.body;
|
|
510
|
-
this.
|
|
511
|
-
this.
|
|
1068
|
+
this._templates = yield this.getAllTemplates(this._resource);
|
|
1069
|
+
this._formTabs = this._formService.createFormGroupsFromTemplates(this._templates);
|
|
512
1070
|
}
|
|
513
1071
|
this.isLoading = false;
|
|
514
1072
|
});
|
|
515
1073
|
}
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
const formGroup = new FormGroup(controls);
|
|
522
|
-
return formGroup;
|
|
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
|
+
});
|
|
523
1079
|
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
.
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
// Check if the rows are entities with change tracking
|
|
535
|
-
const withoutChangeTrackingProperties = properties.filter(p => p[0] !== 'createdAt' &&
|
|
536
|
-
p[0] !== 'createdBy' &&
|
|
537
|
-
p[0] !== 'lastChangedAt' &&
|
|
538
|
-
p[0] !== 'lastChangedBy');
|
|
539
|
-
const hasChangeTrackingProperties = withoutChangeTrackingProperties.length < properties.length;
|
|
540
|
-
// First the id, then all other properties
|
|
541
|
-
const sortedProperties = [];
|
|
542
|
-
if (Object.hasOwnProperty('id'))
|
|
543
|
-
sortedProperties.push(['id', resource['id']]);
|
|
544
|
-
sortedProperties.push(...withoutChangeTrackingProperties);
|
|
545
|
-
// And change tracking properties at the end
|
|
546
|
-
if (hasChangeTrackingProperties) {
|
|
547
|
-
sortedProperties.push(['createdAt', resource['createdAt']]);
|
|
548
|
-
sortedProperties.push(['createdBy', resource['createdBy']]);
|
|
549
|
-
sortedProperties.push(['lastChangedAt', resource['lastChangedAt']]);
|
|
550
|
-
sortedProperties.push(['lastChangedBy', resource['lastChangedBy']]);
|
|
551
|
-
}
|
|
552
|
-
const propertyDescriptions = sortedProperties
|
|
553
|
-
.map(p => ({
|
|
554
|
-
field: p[0],
|
|
555
|
-
value: p[1],
|
|
556
|
-
label: RESTworldEditViewComponent.toTitleCase(p[0]),
|
|
557
|
-
type: RESTworldEditViewComponent.getColumnType(p[0], p[1]),
|
|
558
|
-
isReadOnly: RESTworldEditViewComponent.getIsReadOnly(p[0])
|
|
559
|
-
}));
|
|
560
|
-
for (var description of propertyDescriptions) {
|
|
561
|
-
if (description.type === 'object') {
|
|
562
|
-
const children = RESTworldEditViewComponent.createProperyInfos(description.value);
|
|
563
|
-
children.forEach(d => description.field + '.' + d.field);
|
|
564
|
-
description.children = children;
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
return propertyDescriptions;
|
|
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);
|
|
568
1090
|
}
|
|
569
|
-
|
|
570
|
-
return
|
|
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
|
+
});
|
|
571
1097
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
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
|
+
});
|
|
589
1115
|
}
|
|
590
|
-
|
|
591
|
-
return
|
|
592
|
-
.
|
|
593
|
-
|
|
594
|
-
.
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
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
|
+
});
|
|
599
1130
|
}
|
|
600
1131
|
}
|
|
601
|
-
RESTworldEditViewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.11", ngImport: i0, type: RESTworldEditViewComponent, deps: [{ token: RESTworldClientCollection }, { token: i2.ConfirmationService }, { token: i2.MessageService }, { token: i3.Location }, { token: i4.Router }], target: i0.ɵɵFactoryTarget.Component });
|
|
602
|
-
RESTworldEditViewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.11", type: RESTworldEditViewComponent, selector: "restworld-edit-view", inputs: { apiName: "apiName", uri: "uri" }, queries: [{ propertyName: "visualTabRef", first: true, predicate: ["visualTab"], descendants: true }, { propertyName: "formRef", first: true, predicate: ["form"], descendants: true }, { propertyName: "formRowRef", first: true, predicate: ["formRow"], descendants: true }, { propertyName: "formLabelRef", first: true, predicate: ["formLabel"], descendants: true }, { propertyName: "formInputRef", first: true, predicate: ["formInput"], descendants: true }, { propertyName: "visualTabAdditionalRef", first: true, predicate: ["visualTabAdditional"], descendants: true }, { propertyName: "rawTabRef", first: true, predicate: ["rawTab"], descendants: true }, { propertyName: "buttonsRef", first: true, predicate: ["buttonsRef"], 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<form [formGroup]=\"formGroup\" (ngSubmit)=\"save()\">\r\n <p-tabView>\r\n <p-tabPanel header=\"Visual\" [disabled]=\"!resource || isLoading\">\r\n <ng-template #defaultVisualTab>\r\n <ng-container *ngIf=\"!resource && isLoading\">\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 </ng-container>\r\n\r\n <div *ngIf=\"resource\" class=\"blockable-container\">\r\n <div class=\"blockable-element\">\r\n <ng-template #defaultForm let-properties=\"properties\" let-formGroup=\"formGroup\">\r\n <div [formGroup]=\"formGroup\">\r\n <div *ngFor=\"let property of properties\" class=\"grid field\">\r\n <ng-template #defaultFormRow>\r\n <ng-template #defaultFormLabel>\r\n <label [attr.for]=\"property.field\" class=\"col-12 mb-2 md:col-2 md:mb-0\" [class.p-disabled]=\"property.isReadOnly\" [class.hasChildren]=\"property.children?.length > 0\">{{property.label}}</label>\r\n </ng-template>\r\n <ng-container *ngTemplateOutlet=\"formLabelRef || defaultFormLabel; context:{ $implicit: property }\"></ng-container>\r\n <ng-template #defaultFormInput let-property let-formGroup=\"formGroup\">\r\n <div [ngSwitch]=\"property.type\" class=\"col-12 md:col-10\">\r\n <input *ngSwitchCase=\"'text'\" [formControlName]=\"property.field\" [id]=\"property.field\" type=\"text\" pInputText class=\"w-full\" [class.p-disabled]=\"property.isReadOnly\">\r\n <p-calendar *ngSwitchCase=\"'date'\" [formControlName]=\"property.field\" [id]=\"property.field\" [dateFormat]=\"dateFormat\" [showTime]=\"true\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.isReadOnly\"></p-calendar>\r\n <p-inputNumber *ngSwitchCase=\"'numeric'\" [formControlName]=\"property.field\" [id]=\"property.field\" mode=\"decimal\" [showButtons]=\"!property.isReadOnly\" class=\"w-full\" styleClass=\"w-full\" [class.p-disabled]=\"property.isReadOnly\"></p-inputNumber>\r\n <p-checkbox *ngSwitchCase=\"'boolean'\" [formControl]=\"formGroup.controls[property.field]\" [id]=\"property.field\" [readonly]=\"property.isReadOnly\"></p-checkbox>\r\n <div *ngSwitchCase=\"'object'\">\r\n <ng-container *ngTemplateOutlet=\"formRef || defaultForm; context:{ properties: property.children, formGroup: formGroup.controls[property.field] }\"></ng-container>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-container *ngTemplateOutlet=\"formInputRef || defaultFormInput; context:{ $implicit: property, formGroup: formGroup }\"></ng-container>\r\n </ng-template>\r\n <ng-container *ngTemplateOutlet=\"formRowRef || defaultFormRow; context:{ $implicit: property }\"></ng-container>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-container *ngTemplateOutlet=\"formRef || defaultForm; context: { properties: properties, formGroup: formGroup }\"></ng-container>\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 </ng-template>\r\n <ng-container *ngTemplateOutlet=\"visualTabRef || defaultVisualTab\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"visualTabAdditionalRef || null; context:{ $implicit: resource, properties: properties, isLoading: isLoading }\"></ng-container>\r\n </p-tabPanel>\r\n\r\n <p-tabPanel header=\"Raw\" [disabled]=\"!resource || isLoading\">\r\n <ng-template #defaultRawTab>\r\n <pre>{{resource | json}}</pre>\r\n </ng-template>\r\n <ng-container *ngTemplateOutlet=\"rawTabRef || defaultRawTab\"></ng-container>\r\n </p-tabPanel>\r\n </p-tabView>\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]=\"!resource || isLoading || !canSave\"></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=\"mx-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\r\n</form>\r\n\r\n<p-toast></p-toast>\r\n<p-confirmDialog></p-confirmDialog>\r\n", styles: [".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: i5.TabView, selector: "p-tabView", inputs: ["orientation", "style", "styleClass", "controlClose", "scrollable", "activeIndex"], outputs: ["onChange", "onClose", "activeIndexChange"] }, { type: i5.TabPanel, selector: "p-tabPanel", inputs: ["closable", "headerStyle", "headerStyleClass", "cache", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "selected", "disabled", "header", "leftIcon", "rightIcon"] }, { type: i6.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "style", "shape", "animation", "borderRadius", "size", "width", "height"] }, { type: i7.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: i8.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: i9.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: i10.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.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: i13.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i13.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i13.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i13.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: i14.InputText, selector: "[pInputText]" }, { type: i13.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i13.FormControlName, selector: "[formControlName]", inputs: ["disabled", "formControlName", "ngModel"], outputs: ["ngModelChange"] }, { type: i13.FormControlDirective, selector: "[formControl]", inputs: ["disabled", "formControl", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { type: i15.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading"] }, { type: i16.Ripple, selector: "[pRipple]" }], pipes: { "json": i3.JsonPipe } });
|
|
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 } });
|
|
603
1134
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.11", ngImport: i0, type: RESTworldEditViewComponent, decorators: [{
|
|
604
1135
|
type: Component,
|
|
605
1136
|
args: [{
|
|
606
|
-
selector: '
|
|
1137
|
+
selector: 'rw-edit',
|
|
607
1138
|
templateUrl: './restworld-edit-view.component.html',
|
|
608
1139
|
styleUrls: ['./restworld-edit-view.component.css']
|
|
609
1140
|
}]
|
|
610
|
-
}], ctorParameters: function () { return [{ type: RESTworldClientCollection }, { type: i2.ConfirmationService }, { type: i2.MessageService }, { type: i3.Location }, { type: i4.Router }]; }, propDecorators: { apiName: [{
|
|
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: [{
|
|
611
1142
|
type: Input
|
|
612
1143
|
}], uri: [{
|
|
613
1144
|
type: Input
|
|
614
|
-
}],
|
|
1145
|
+
}], extraTabsRef: [{
|
|
615
1146
|
type: ContentChild,
|
|
616
|
-
args: ['
|
|
617
|
-
}],
|
|
1147
|
+
args: ['extraTabs', { static: false }]
|
|
1148
|
+
}], buttonsRef: [{
|
|
618
1149
|
type: ContentChild,
|
|
619
|
-
args: ['
|
|
620
|
-
}],
|
|
1150
|
+
args: ['buttons', { static: false }]
|
|
1151
|
+
}], inputOptionsSingleRef: [{
|
|
621
1152
|
type: ContentChild,
|
|
622
|
-
args: ['
|
|
623
|
-
}],
|
|
1153
|
+
args: ['inputOptionsSingle', { static: false }]
|
|
1154
|
+
}], inputOptionsMultipleRef: [{
|
|
624
1155
|
type: ContentChild,
|
|
625
|
-
args: ['
|
|
626
|
-
}],
|
|
1156
|
+
args: ['inputOptionsMultiple', { static: false }]
|
|
1157
|
+
}], inputOptionsRef: [{
|
|
627
1158
|
type: ContentChild,
|
|
628
|
-
args: ['
|
|
629
|
-
}],
|
|
1159
|
+
args: ['inputOptions', { static: false }]
|
|
1160
|
+
}], inputHiddenRef: [{
|
|
630
1161
|
type: ContentChild,
|
|
631
|
-
args: ['
|
|
632
|
-
}],
|
|
1162
|
+
args: ['inputHidden', { static: false }]
|
|
1163
|
+
}], inputTextRef: [{
|
|
633
1164
|
type: ContentChild,
|
|
634
|
-
args: ['
|
|
635
|
-
}],
|
|
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: [{
|
|
636
1212
|
type: ContentChild,
|
|
637
|
-
args: ['
|
|
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 }]
|
|
638
1226
|
}] } });
|
|
639
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 = {}));
|
|
640
1235
|
class RESTworldListViewComponent {
|
|
641
1236
|
constructor(_clients, _confirmationService, _messageService, avatarGenerator) {
|
|
642
1237
|
this._clients = _clients;
|
|
@@ -713,12 +1308,12 @@ class RESTworldListViewComponent {
|
|
|
713
1308
|
return;
|
|
714
1309
|
this.isLoading = true;
|
|
715
1310
|
this._lastEvent = event;
|
|
716
|
-
const parameters =
|
|
1311
|
+
const parameters = this.createParametersFromEvent(event);
|
|
717
1312
|
const response = yield this.getClient().getList(this.rel, parameters);
|
|
718
1313
|
if (!response.ok || ProblemDetails.isProblemDetails(response.body) || !response.body) {
|
|
719
1314
|
this._messageService.add({ severity: 'error', summary: 'Error', detail: 'Error while loading the resources from the API.', data: response });
|
|
720
1315
|
}
|
|
721
|
-
else {
|
|
1316
|
+
else if (response.body) {
|
|
722
1317
|
this.resource = response.body;
|
|
723
1318
|
this.totalRecords = this.resource.totalPages && parameters.$top ? this.resource.totalPages * parameters.$top : undefined;
|
|
724
1319
|
this._columns = this.createColumns();
|
|
@@ -745,7 +1340,7 @@ class RESTworldListViewComponent {
|
|
|
745
1340
|
}
|
|
746
1341
|
createColumns() {
|
|
747
1342
|
if (this.value.length === 0)
|
|
748
|
-
return
|
|
1343
|
+
return this.columns;
|
|
749
1344
|
// Get all distinct properties from all rows
|
|
750
1345
|
// We look at all rows to eliminate possible undefined values
|
|
751
1346
|
const rowsWithProperties = this.value
|
|
@@ -754,9 +1349,9 @@ class RESTworldListViewComponent {
|
|
|
754
1349
|
p[0] !== '_embedded' &&
|
|
755
1350
|
p[0] !== 'id' &&
|
|
756
1351
|
p[0] !== 'timestamp'));
|
|
757
|
-
|
|
758
|
-
for (
|
|
759
|
-
for (
|
|
1352
|
+
const distinctProperties = rowsWithProperties[0];
|
|
1353
|
+
for (const propertiesOfRow of rowsWithProperties) {
|
|
1354
|
+
for (const property of propertiesOfRow) {
|
|
760
1355
|
const propertyName = property[0];
|
|
761
1356
|
const propertyValue = property[1];
|
|
762
1357
|
const alreadyFoundPropertyWithSameName = distinctProperties.find(p => p[0] === propertyName);
|
|
@@ -794,16 +1389,16 @@ class RESTworldListViewComponent {
|
|
|
794
1389
|
}
|
|
795
1390
|
static getColumnType(value) {
|
|
796
1391
|
if (value === null || value === undefined)
|
|
797
|
-
return
|
|
1392
|
+
return ColumnType.text;
|
|
798
1393
|
if (_.isNumber(value))
|
|
799
|
-
return
|
|
1394
|
+
return ColumnType.numeric;
|
|
800
1395
|
if (_.isDate(value))
|
|
801
|
-
return
|
|
1396
|
+
return ColumnType.date;
|
|
802
1397
|
if (_.isString(value))
|
|
803
|
-
return
|
|
1398
|
+
return ColumnType.text;
|
|
804
1399
|
if (_.isBoolean(value))
|
|
805
|
-
return
|
|
806
|
-
return
|
|
1400
|
+
return ColumnType.boolean;
|
|
1401
|
+
return ColumnType.text;
|
|
807
1402
|
}
|
|
808
1403
|
static toTitleCase(anyCase) {
|
|
809
1404
|
return anyCase
|
|
@@ -815,9 +1410,9 @@ class RESTworldListViewComponent {
|
|
|
815
1410
|
.replace(/([a-z]+)([A-Z0-9]+)/g, "$1 $2") // insert space after numbers
|
|
816
1411
|
.replace(/^./, (match) => match.toUpperCase()); // change first letter to be upper case
|
|
817
1412
|
}
|
|
818
|
-
|
|
1413
|
+
createParametersFromEvent(event) {
|
|
819
1414
|
const oDataParameters = {
|
|
820
|
-
$filter:
|
|
1415
|
+
$filter: this.createFilterFromEvent(event),
|
|
821
1416
|
$orderby: RESTworldListViewComponent.createOrderByFromEvent(event),
|
|
822
1417
|
$top: RESTworldListViewComponent.createTopFromEvent(event),
|
|
823
1418
|
$skip: RESTworldListViewComponent.createSkipFromEvent(event)
|
|
@@ -837,22 +1432,33 @@ class RESTworldListViewComponent {
|
|
|
837
1432
|
}
|
|
838
1433
|
return undefined;
|
|
839
1434
|
}
|
|
840
|
-
|
|
1435
|
+
createFilterFromEvent(event) {
|
|
841
1436
|
if (!event.filters)
|
|
842
1437
|
return undefined;
|
|
843
1438
|
const filter = Object.entries(event.filters)
|
|
844
|
-
.
|
|
845
|
-
.
|
|
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)
|
|
846
1443
|
.join(' and ');
|
|
847
1444
|
if (filter === '')
|
|
848
1445
|
return undefined;
|
|
849
1446
|
return `(${filter})`;
|
|
850
1447
|
}
|
|
851
|
-
|
|
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) {
|
|
852
1458
|
if (!filter.value)
|
|
853
1459
|
return undefined;
|
|
854
1460
|
const oDataOperator = RESTworldListViewComponent.createODataOperator(filter.matchMode);
|
|
855
|
-
const comparisonValue =
|
|
1461
|
+
const comparisonValue = this.createComparisonValue(property, filter.value);
|
|
856
1462
|
switch (oDataOperator) {
|
|
857
1463
|
case 'contains':
|
|
858
1464
|
case 'not contains':
|
|
@@ -895,28 +1501,37 @@ class RESTworldListViewComponent {
|
|
|
895
1501
|
return 'lt';
|
|
896
1502
|
case FilterMatchMode.AFTER:
|
|
897
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';
|
|
898
1512
|
default:
|
|
899
1513
|
throw Error(`Unknown matchMode ${matchMode}`);
|
|
900
1514
|
}
|
|
901
1515
|
}
|
|
902
|
-
|
|
1516
|
+
createComparisonValue(property, value) {
|
|
903
1517
|
if (value === null || value === undefined)
|
|
904
1518
|
return 'null';
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
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}'`);
|
|
914
1534
|
}
|
|
915
|
-
if (_.isArray(value))
|
|
916
|
-
return `(${value
|
|
917
|
-
.map((v) => this.createComparisonValue(v))
|
|
918
|
-
.join(',')})`;
|
|
919
|
-
throw new Error(`Unknown type of value: ${value}.`);
|
|
920
1535
|
}
|
|
921
1536
|
}
|
|
922
1537
|
RESTworldListViewComponent._dateFormat = new Date(3333, 10, 22)
|
|
@@ -925,16 +1540,16 @@ RESTworldListViewComponent._dateFormat = new Date(3333, 10, 22)
|
|
|
925
1540
|
.replace("11", "MM")
|
|
926
1541
|
.replace("3333", "y")
|
|
927
1542
|
.replace("33", "yy");
|
|
928
|
-
RESTworldListViewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.11", ngImport: i0, type: RESTworldListViewComponent, deps: [{ token: RESTworldClientCollection }, { token: i2.ConfirmationService }, { token: i2.MessageService }, { token: AvatarGenerator }], target: i0.ɵɵFactoryTarget.Component });
|
|
929
|
-
RESTworldListViewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.11", type: RESTworldListViewComponent, selector: "
|
|
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 } });
|
|
930
1545
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.11", ngImport: i0, type: RESTworldListViewComponent, decorators: [{
|
|
931
1546
|
type: Component,
|
|
932
1547
|
args: [{
|
|
933
|
-
selector: '
|
|
1548
|
+
selector: 'rw-list',
|
|
934
1549
|
templateUrl: './restworld-list-view.component.html',
|
|
935
1550
|
styleUrls: ['./restworld-list-view.component.css']
|
|
936
1551
|
}]
|
|
937
|
-
}], ctorParameters: function () { return [{ type: RESTworldClientCollection }, { type: i2.ConfirmationService }, { type: i2.MessageService }, { type: AvatarGenerator }]; }, propDecorators: { editLink: [{
|
|
1552
|
+
}], ctorParameters: function () { return [{ type: RESTworldClientCollection }, { type: i2$1.ConfirmationService }, { type: i2$1.MessageService }, { type: AvatarGenerator }]; }, propDecorators: { editLink: [{
|
|
938
1553
|
type: Input
|
|
939
1554
|
}], apiName: [{
|
|
940
1555
|
type: Input
|
|
@@ -951,7 +1566,12 @@ class RestworldClientModule {
|
|
|
951
1566
|
}
|
|
952
1567
|
RestworldClientModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.11", ngImport: i0, type: RestworldClientModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
953
1568
|
RestworldClientModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.11", ngImport: i0, type: RestworldClientModule, declarations: [RESTworldListViewComponent,
|
|
954
|
-
RESTworldEditViewComponent
|
|
1569
|
+
RESTworldEditViewComponent,
|
|
1570
|
+
RESTWorldImageViewComponent,
|
|
1571
|
+
RESTWorldFileViewComponent,
|
|
1572
|
+
SafeUrlPipe,
|
|
1573
|
+
AsPipe,
|
|
1574
|
+
RestworldEditFormComponent], imports: [CommonModule,
|
|
955
1575
|
RouterModule,
|
|
956
1576
|
FormsModule,
|
|
957
1577
|
ReactiveFormsModule,
|
|
@@ -971,12 +1591,25 @@ RestworldClientModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", v
|
|
|
971
1591
|
ProgressSpinnerModule,
|
|
972
1592
|
RippleModule,
|
|
973
1593
|
TriStateCheckboxModule,
|
|
974
|
-
AvatarModule
|
|
975
|
-
|
|
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] });
|
|
976
1608
|
RestworldClientModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.11", ngImport: i0, type: RestworldClientModule, providers: [
|
|
977
1609
|
RESTworldClientCollection,
|
|
978
1610
|
AvatarGenerator,
|
|
979
1611
|
ConfirmationService,
|
|
1612
|
+
FormService,
|
|
980
1613
|
MessageService,
|
|
981
1614
|
{
|
|
982
1615
|
provide: APP_INITIALIZER,
|
|
@@ -1005,14 +1638,28 @@ RestworldClientModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", v
|
|
|
1005
1638
|
ProgressSpinnerModule,
|
|
1006
1639
|
RippleModule,
|
|
1007
1640
|
TriStateCheckboxModule,
|
|
1008
|
-
AvatarModule
|
|
1641
|
+
AvatarModule,
|
|
1642
|
+
DropdownModule,
|
|
1643
|
+
MultiSelectModule,
|
|
1644
|
+
FileUploadModule,
|
|
1645
|
+
ValdemortModule,
|
|
1646
|
+
ImageCropperModule,
|
|
1647
|
+
DialogModule,
|
|
1648
|
+
ButtonModule,
|
|
1649
|
+
ColorPickerModule,
|
|
1650
|
+
DragDropModule
|
|
1009
1651
|
]] });
|
|
1010
1652
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.11", ngImport: i0, type: RestworldClientModule, decorators: [{
|
|
1011
1653
|
type: NgModule,
|
|
1012
1654
|
args: [{
|
|
1013
1655
|
declarations: [
|
|
1014
1656
|
RESTworldListViewComponent,
|
|
1015
|
-
RESTworldEditViewComponent
|
|
1657
|
+
RESTworldEditViewComponent,
|
|
1658
|
+
RESTWorldImageViewComponent,
|
|
1659
|
+
RESTWorldFileViewComponent,
|
|
1660
|
+
SafeUrlPipe,
|
|
1661
|
+
AsPipe,
|
|
1662
|
+
RestworldEditFormComponent
|
|
1016
1663
|
],
|
|
1017
1664
|
imports: [
|
|
1018
1665
|
CommonModule,
|
|
@@ -1035,16 +1682,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.11", ngImpo
|
|
|
1035
1682
|
ProgressSpinnerModule,
|
|
1036
1683
|
RippleModule,
|
|
1037
1684
|
TriStateCheckboxModule,
|
|
1038
|
-
AvatarModule
|
|
1685
|
+
AvatarModule,
|
|
1686
|
+
DropdownModule,
|
|
1687
|
+
MultiSelectModule,
|
|
1688
|
+
FileUploadModule,
|
|
1689
|
+
ValdemortModule,
|
|
1690
|
+
ImageCropperModule,
|
|
1691
|
+
DialogModule,
|
|
1692
|
+
ButtonModule,
|
|
1693
|
+
ColorPickerModule,
|
|
1694
|
+
DragDropModule
|
|
1039
1695
|
],
|
|
1040
1696
|
exports: [
|
|
1041
1697
|
RESTworldListViewComponent,
|
|
1042
|
-
RESTworldEditViewComponent
|
|
1698
|
+
RESTworldEditViewComponent,
|
|
1699
|
+
RESTWorldImageViewComponent,
|
|
1700
|
+
RESTWorldFileViewComponent,
|
|
1701
|
+
SafeUrlPipe
|
|
1043
1702
|
],
|
|
1044
1703
|
providers: [
|
|
1045
1704
|
RESTworldClientCollection,
|
|
1046
1705
|
AvatarGenerator,
|
|
1047
1706
|
ConfirmationService,
|
|
1707
|
+
FormService,
|
|
1048
1708
|
MessageService,
|
|
1049
1709
|
{
|
|
1050
1710
|
provide: APP_INITIALIZER,
|
|
@@ -1064,5 +1724,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.11", ngImpo
|
|
|
1064
1724
|
* Generated bundle index. Do not edit.
|
|
1065
1725
|
*/
|
|
1066
1726
|
|
|
1067
|
-
export { AvatarGenerator, LinkNames, ProblemDetails, RESTworldClient, RESTworldClientCollection, RESTworldEditViewComponent, RESTworldListViewComponent, RESTworldOptions, RestworldClientModule, SettingsService, initializeSettings };
|
|
1727
|
+
export { AsPipe, AvatarGenerator, ColumnType, FormService, LinkNames, ProblemDetails, RESTWorldFileViewComponent, RESTWorldImageViewComponent, RESTworldClient, RESTworldClientCollection, RESTworldEditViewComponent, RESTworldListViewComponent, RESTworldOptions, RestworldClientModule, RestworldEditFormComponent, SafeUrlPipe, SettingsService, initializeSettings };
|
|
1068
1728
|
//# sourceMappingURL=wertzui-ngx-restworld-client.js.map
|