ichec-angular-core 0.1.2 → 0.1.4
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/fesm2022/ichec-angular-core.mjs +739 -322
- package/fesm2022/ichec-angular-core.mjs.map +1 -1
- package/index.d.ts +295 -177
- package/package.json +1 -1
|
@@ -2,49 +2,50 @@ import { map, catchError, tap, mergeMap, throwError, BehaviorSubject, mergeAll,
|
|
|
2
2
|
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
4
|
import { InjectionToken, inject, Injectable, input, signal, Component, viewChild, computed, output } from '@angular/core';
|
|
5
|
+
import * as i1$3 from '@angular/forms';
|
|
6
|
+
import { FormControl, Validators, FormGroup, FormsModule, ReactiveFormsModule, FormBuilder } from '@angular/forms';
|
|
5
7
|
import * as i1 from '@angular/router';
|
|
6
8
|
import { RouterModule, RouterOutlet, Router, ActivatedRoute } from '@angular/router';
|
|
7
9
|
import * as i2 from '@angular/material/toolbar';
|
|
8
10
|
import { MatToolbarModule } from '@angular/material/toolbar';
|
|
9
|
-
import * as
|
|
11
|
+
import * as i1$1 from '@angular/material/icon';
|
|
10
12
|
import { MatIconModule } from '@angular/material/icon';
|
|
11
13
|
import * as i2$1 from '@angular/material/button';
|
|
12
14
|
import { MatButtonModule } from '@angular/material/button';
|
|
13
15
|
import * as i5 from '@angular/material/menu';
|
|
14
16
|
import { MatMenuModule } from '@angular/material/menu';
|
|
15
|
-
import * as i1$
|
|
17
|
+
import * as i1$2 from '@angular/material/sidenav';
|
|
16
18
|
import { MatSidenavContent, MatSidenavModule } from '@angular/material/sidenav';
|
|
17
19
|
import * as i2$2 from '@angular/material/list';
|
|
18
20
|
import { MatListModule } from '@angular/material/list';
|
|
19
21
|
import { NgIf, Location, NgTemplateOutlet, TitleCasePipe } from '@angular/common';
|
|
20
|
-
import * as
|
|
21
|
-
import { FormsModule, FormControl, ReactiveFormsModule, FormBuilder } from '@angular/forms';
|
|
22
|
-
import * as i3$2 from '@angular/material/input';
|
|
22
|
+
import * as i3 from '@angular/material/input';
|
|
23
23
|
import { MatInputModule } from '@angular/material/input';
|
|
24
|
-
import * as
|
|
24
|
+
import * as i2$3 from '@angular/material/form-field';
|
|
25
25
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
26
|
-
import * as i1$
|
|
26
|
+
import * as i1$4 from '@angular/material/card';
|
|
27
27
|
import { MatCardModule } from '@angular/material/card';
|
|
28
|
-
import * as
|
|
29
|
-
import {
|
|
28
|
+
import * as i4 from '@angular/material/checkbox';
|
|
29
|
+
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
30
|
+
import * as i1$5 from '@angular/material/table';
|
|
31
|
+
import { MatTableModule, MatTable } from '@angular/material/table';
|
|
30
32
|
import * as i6 from '@angular/material/select';
|
|
31
33
|
import { MatSelectModule } from '@angular/material/select';
|
|
34
|
+
import * as i4$1 from '@angular/material/tooltip';
|
|
35
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
32
36
|
import * as i6$1 from '@angular/material/autocomplete';
|
|
33
37
|
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
|
34
|
-
import * as i3$
|
|
38
|
+
import * as i3$1 from '@angular/material/sort';
|
|
35
39
|
import { MatSort, MatSortModule } from '@angular/material/sort';
|
|
36
|
-
import * as i1$
|
|
40
|
+
import * as i1$6 from '@angular/material/button-toggle';
|
|
37
41
|
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
|
38
|
-
import * as i2$
|
|
42
|
+
import * as i2$6 from '@angular/material/progress-spinner';
|
|
39
43
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
40
|
-
import * as
|
|
41
|
-
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
42
|
-
import * as i2$3 from '@angular/material/paginator';
|
|
44
|
+
import * as i2$4 from '@angular/material/paginator';
|
|
43
45
|
import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
|
|
44
|
-
import * as i2$
|
|
46
|
+
import * as i2$5 from '@angular/cdk/scrolling';
|
|
45
47
|
import { ScrollingModule } from '@angular/cdk/scrolling';
|
|
46
48
|
import { DataSource } from '@angular/cdk/collections';
|
|
47
|
-
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
48
49
|
|
|
49
50
|
class Paginated {
|
|
50
51
|
count = 0;
|
|
@@ -53,31 +54,13 @@ class Paginated {
|
|
|
53
54
|
results = [];
|
|
54
55
|
}
|
|
55
56
|
class Permission {
|
|
56
|
-
id = 0;
|
|
57
|
-
url = "";
|
|
58
|
-
codename = "";
|
|
59
57
|
static typename = "permission";
|
|
60
58
|
static plural = "permissions";
|
|
61
|
-
constructor(params = {}) {
|
|
62
|
-
Object.assign(this, params);
|
|
63
|
-
}
|
|
64
59
|
}
|
|
60
|
+
|
|
65
61
|
class PortalMember {
|
|
66
62
|
static typename = "member";
|
|
67
63
|
static plural = "members";
|
|
68
|
-
id = 0;
|
|
69
|
-
url = "";
|
|
70
|
-
username = "";
|
|
71
|
-
email = "";
|
|
72
|
-
first_name = "";
|
|
73
|
-
last_name = "";
|
|
74
|
-
phone = "";
|
|
75
|
-
organization = "";
|
|
76
|
-
profile_url = "";
|
|
77
|
-
all_permissions = [];
|
|
78
|
-
constructor(params = {}) {
|
|
79
|
-
Object.assign(this, params);
|
|
80
|
-
}
|
|
81
64
|
static getInitials(member) {
|
|
82
65
|
let first_initial = "";
|
|
83
66
|
let second_initial = "";
|
|
@@ -94,49 +77,20 @@ class PortalMember {
|
|
|
94
77
|
return combined.toUpperCase();
|
|
95
78
|
}
|
|
96
79
|
}
|
|
80
|
+
|
|
97
81
|
class Group {
|
|
98
82
|
static typename = "group";
|
|
99
83
|
static plural = "groups";
|
|
100
|
-
name = "";
|
|
101
|
-
url = "";
|
|
102
|
-
id = 0;
|
|
103
|
-
constructor(params = {}) {
|
|
104
|
-
Object.assign(this, params);
|
|
105
|
-
}
|
|
106
84
|
}
|
|
107
85
|
|
|
108
|
-
class Address {
|
|
109
|
-
static typename = "address";
|
|
110
|
-
static plural = "addresses";
|
|
111
|
-
id = 0;
|
|
112
|
-
url = "";
|
|
113
|
-
line1 = "";
|
|
114
|
-
line2 = null;
|
|
115
|
-
line3 = null;
|
|
116
|
-
city = null;
|
|
117
|
-
region = "";
|
|
118
|
-
postcode = null;
|
|
119
|
-
country = "";
|
|
120
|
-
country_name = "";
|
|
121
|
-
country_flag = "";
|
|
122
|
-
constructor(params = {}) {
|
|
123
|
-
Object.assign(this, params);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
86
|
class Organization {
|
|
127
87
|
static typename = "organization";
|
|
128
88
|
static plural = "organizations";
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
address = "";
|
|
135
|
-
website = "";
|
|
136
|
-
members = [];
|
|
137
|
-
constructor(params = {}) {
|
|
138
|
-
Object.assign(this, params);
|
|
139
|
-
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
class Address {
|
|
92
|
+
static typename = "address";
|
|
93
|
+
static plural = "addresses";
|
|
140
94
|
}
|
|
141
95
|
|
|
142
96
|
class ItemQuery {
|
|
@@ -160,6 +114,15 @@ class ApiError {
|
|
|
160
114
|
text = "";
|
|
161
115
|
}
|
|
162
116
|
|
|
117
|
+
const FORM_FIELD_CHOICES = [{ value: "BOOLEAN", display_name: "Boolean" },
|
|
118
|
+
{ value: "CHAR", display_name: "Short Text" },
|
|
119
|
+
{ value: "TEXT", display_name: "Long Text" },
|
|
120
|
+
{ value: "RICH_TEXT", display_name: "Rich Text" },
|
|
121
|
+
{ value: "SELECTION", display_name: "Selection" },
|
|
122
|
+
{ value: "INTEGER", display_name: "Integer" },
|
|
123
|
+
{ value: "FILE", display_name: "File" }
|
|
124
|
+
];
|
|
125
|
+
|
|
163
126
|
const ENDPOINT_URL = new InjectionToken("Default endpoint url");
|
|
164
127
|
class RestService {
|
|
165
128
|
_url = "";
|
|
@@ -292,12 +255,6 @@ class ItemService extends RestService {
|
|
|
292
255
|
typePlural() {
|
|
293
256
|
return this.typenamePlural ? this.typenamePlural : this.typename + "s";
|
|
294
257
|
}
|
|
295
|
-
instantiateType(_) {
|
|
296
|
-
throw new Error('Not Implemented');
|
|
297
|
-
}
|
|
298
|
-
getItem(id) {
|
|
299
|
-
return super.getItem(id).pipe(map(x => this.instantiateType(x)));
|
|
300
|
-
}
|
|
301
258
|
}
|
|
302
259
|
|
|
303
260
|
class ResolvedPermission {
|
|
@@ -314,9 +271,6 @@ class UserService extends ItemService {
|
|
|
314
271
|
_url = PortalMember.plural;
|
|
315
272
|
typename = PortalMember.typename;
|
|
316
273
|
permissions = new Map();
|
|
317
|
-
instantiateType(item) {
|
|
318
|
-
return new PortalMember(item);
|
|
319
|
-
}
|
|
320
274
|
login(username, password) {
|
|
321
275
|
console.log("Attempting login");
|
|
322
276
|
const body = new URLSearchParams();
|
|
@@ -382,8 +336,8 @@ class UserService extends ItemService {
|
|
|
382
336
|
if (!user) {
|
|
383
337
|
return;
|
|
384
338
|
}
|
|
385
|
-
user.
|
|
386
|
-
user.
|
|
339
|
+
user.permissions.forEach(p => this.permissions.set(this.parsePermission(p).feature, new ResolvedPermission()));
|
|
340
|
+
user.permissions.forEach(p => {
|
|
387
341
|
const permission = this.parsePermission(p);
|
|
388
342
|
if (permission.capability === "view") {
|
|
389
343
|
this.permissions.get(permission.feature).canView = true;
|
|
@@ -455,9 +409,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
455
409
|
class AddressService extends ItemWithUserService {
|
|
456
410
|
_url = Address.plural;
|
|
457
411
|
typename = Address.typename;
|
|
458
|
-
instantiateType(item) {
|
|
459
|
-
return new Address(item);
|
|
460
|
-
}
|
|
461
412
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
462
413
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressService, providedIn: 'root' });
|
|
463
414
|
}
|
|
@@ -475,9 +426,6 @@ class GroupService extends ItemWithUserService {
|
|
|
475
426
|
super();
|
|
476
427
|
this.userService.loggedInUser.subscribe(user => this.refreshUserItems(user));
|
|
477
428
|
}
|
|
478
|
-
instantiateType(item) {
|
|
479
|
-
return new Group(item);
|
|
480
|
-
}
|
|
481
429
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: GroupService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
482
430
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: GroupService, providedIn: 'root' });
|
|
483
431
|
}
|
|
@@ -491,9 +439,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
491
439
|
class OrganizationService extends ItemWithUserService {
|
|
492
440
|
_url = Organization.plural;
|
|
493
441
|
typename = Organization.typename;
|
|
494
|
-
instantiateType(item) {
|
|
495
|
-
return new Organization(item);
|
|
496
|
-
}
|
|
497
442
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
498
443
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationService, providedIn: 'root' });
|
|
499
444
|
}
|
|
@@ -504,6 +449,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
504
449
|
}]
|
|
505
450
|
}] });
|
|
506
451
|
|
|
452
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
453
|
+
class FormService {
|
|
454
|
+
toFormGroup(form) {
|
|
455
|
+
const controls = {};
|
|
456
|
+
form.groups.forEach(group => group.fields.forEach(field => {
|
|
457
|
+
controls[field.id.toString()] = field.required
|
|
458
|
+
? new FormControl(field.default || '', Validators.required)
|
|
459
|
+
: new FormControl(field.default || '');
|
|
460
|
+
}));
|
|
461
|
+
return new FormGroup(controls);
|
|
462
|
+
}
|
|
463
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FormService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
464
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FormService, providedIn: 'root' });
|
|
465
|
+
}
|
|
466
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FormService, decorators: [{
|
|
467
|
+
type: Injectable,
|
|
468
|
+
args: [{
|
|
469
|
+
providedIn: 'root',
|
|
470
|
+
}]
|
|
471
|
+
}] });
|
|
472
|
+
|
|
507
473
|
class LeftNavService {
|
|
508
474
|
activeOptions = new Set();
|
|
509
475
|
_groups = [];
|
|
@@ -577,7 +543,7 @@ class TopBarComponent {
|
|
|
577
543
|
return "";
|
|
578
544
|
}
|
|
579
545
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: TopBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
580
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: TopBarComponent, isStandalone: true, selector: "lib-top-bar", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "\n@if(user(); as user){\n<mat-toolbar style=\"height:60px\">\n <a mat-icon-button aria-label=\"Home\" [routerLink]=\"['home']\">\n <mat-icon>home</mat-icon>\n </a>\n <span>{{title()}}</span>\n <span class=\"topbar-spacer\"></span>\n <span>{{user.username}}</span>\n \n <button mat-icon-button style=\"margin: 5px\" aria-label=\"User Profile\" [matMenuTriggerFor]=\"profile_menu\">\n <mat-icon>person</mat-icon>\n </button>\n\n <mat-menu #profile_menu=\"matMenu\">\n <a mat-menu-item aria-label=\"My Profile\" [routerLink]=\"['/members/detail', user.id]\">\n <mat-icon>manage_accounts</mat-icon>\n <span>My Profile</span>\n </a> \n <a mat-menu-item aria-label=\"Get Support\" [routerLink]=\"['/feedback']\">\n <mat-icon>contact_support</mat-icon>\n <span>Get Support</span>\n </a> \n <button mat-menu-item (click)=\"onLogout()\">\n <mat-icon>logout</mat-icon>\n <span>Log Out</span>\n </button>\n\n </mat-menu>\n</mat-toolbar>\n}\n", styles: [".topbar-spacer{flex:1 1 auto}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "component", type: i2.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type:
|
|
546
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: TopBarComponent, isStandalone: true, selector: "lib-top-bar", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "\n@if(user(); as user){\n<mat-toolbar style=\"height:60px\">\n <a mat-icon-button aria-label=\"Home\" [routerLink]=\"['home']\">\n <mat-icon>home</mat-icon>\n </a>\n <span>{{title()}}</span>\n <span class=\"topbar-spacer\"></span>\n <span>{{user.username}}</span>\n \n <button mat-icon-button style=\"margin: 5px\" aria-label=\"User Profile\" [matMenuTriggerFor]=\"profile_menu\">\n <mat-icon>person</mat-icon>\n </button>\n\n <mat-menu #profile_menu=\"matMenu\">\n <a mat-menu-item aria-label=\"My Profile\" [routerLink]=\"['/members/detail', user.id]\">\n <mat-icon>manage_accounts</mat-icon>\n <span>My Profile</span>\n </a> \n <a mat-menu-item aria-label=\"Get Support\" [routerLink]=\"['/feedback']\">\n <mat-icon>contact_support</mat-icon>\n <span>Get Support</span>\n </a> \n <button mat-menu-item (click)=\"onLogout()\">\n <mat-icon>logout</mat-icon>\n <span>Log Out</span>\n </button>\n\n </mat-menu>\n</mat-toolbar>\n}\n", styles: [".topbar-spacer{flex:1 1 auto}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "component", type: i2.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i5.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i5.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i5.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }] });
|
|
581
547
|
}
|
|
582
548
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: TopBarComponent, decorators: [{
|
|
583
549
|
type: Component,
|
|
@@ -595,7 +561,7 @@ class LeftNavComponent {
|
|
|
595
561
|
return this._leftNavService.activeOptions;
|
|
596
562
|
}
|
|
597
563
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: LeftNavComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
598
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: LeftNavComponent, isStandalone: true, selector: "lib-left-nav", viewQueries: [{ propertyName: "sideNavContent", first: true, predicate: MatSidenavContent, descendants: true, isSignal: true }], ngImport: i0, template: "<mat-sidenav-container class=\"leftnav-container\">\n <mat-sidenav mode=\"side\" class=\"leftnav-side\" opened>\n <mat-nav-list>\n @for (option of getOptions(); track option) {\n <a mat-list-item [routerLink]=\"option.route\" [routerLinkActive]=\"['is-active']\">{{ option.name }}</a>\n }\n </mat-nav-list>\n </mat-sidenav>\n <mat-sidenav-content class=\"leftnav-content\"> \n <router-outlet />\n </mat-sidenav-content>\n</mat-sidenav-container>\n", styles: [":host{display:flex;flex-direction:column}.leftnav-container{flex-grow:1;display:flex}.leftnav-content{display:flex;flex-grow:1;height:90vh}.leftnav-side{padding:5px;width:160px}.is-active{background-color:#d3d3d3}\n"], dependencies: [{ kind: "ngmodule", type: MatSidenavModule }, { kind: "component", type: i1$
|
|
564
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: LeftNavComponent, isStandalone: true, selector: "lib-left-nav", viewQueries: [{ propertyName: "sideNavContent", first: true, predicate: MatSidenavContent, descendants: true, isSignal: true }], ngImport: i0, template: "<mat-sidenav-container class=\"leftnav-container\">\n <mat-sidenav mode=\"side\" class=\"leftnav-side\" opened>\n <mat-nav-list>\n @for (option of getOptions(); track option) {\n <a mat-list-item [routerLink]=\"option.route\" [routerLinkActive]=\"['is-active']\">{{ option.name }}</a>\n }\n </mat-nav-list>\n </mat-sidenav>\n <mat-sidenav-content class=\"leftnav-content\"> \n <router-outlet />\n </mat-sidenav-content>\n</mat-sidenav-container>\n", styles: [":host{display:flex;flex-direction:column}.leftnav-container{flex-grow:1;display:flex}.leftnav-content{display:flex;flex-grow:1;height:90vh}.leftnav-side{padding:5px;width:160px}.is-active{background-color:#d3d3d3}\n"], dependencies: [{ kind: "ngmodule", type: MatSidenavModule }, { kind: "component", type: i1$2.MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: i1$2.MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: i1$2.MatSidenavContent, selector: "mat-sidenav-content" }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i2$2.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "component", type: i2$2.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i1.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }] });
|
|
599
565
|
}
|
|
600
566
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: LeftNavComponent, decorators: [{
|
|
601
567
|
type: Component,
|
|
@@ -638,7 +604,7 @@ class LandingComponent {
|
|
|
638
604
|
this.router.navigateByUrl("/home");
|
|
639
605
|
}
|
|
640
606
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: LandingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
641
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: LandingComponent, isStandalone: true, selector: "lib-landing", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "\n @if(message(); as message){\n <p>{{message}}</p>\n }\n \n <mat-card style=\"text-align:center;\">\n <form class=\"base-form\" #loginForm=\"ngForm\" (ngSubmit)=\"login()\">\n <mat-card-content>\n <mat-form-field class=\"form-field\">\n <input matInput\n placeholder=\"Username\"\n type=\"text\"\n [(ngModel)]=\"loginUser.name\"\n name=\"username\"\n required>\n </mat-form-field>\n <mat-form-field class=\"form-field\">\n <input matInput\n placeholder=\"Password\"\n type=\"password\"\n [(ngModel)]=\"loginUser.password\"\n name=\"password\"\n required>\n </mat-form-field>\n </mat-card-content>\n <div *ngIf=\"loginError\" class=\"error\">\n <mat-icon>error</mat-icon><p>{{loginError()}}</p>\n </div>\n <button mat-flat-button\n type=\"submit\"\n [disabled]=\"!loginForm.form.valid\">Log In</button>\n </form>\n </mat-card>\n\n\n \n", styles: [":host{display:flex;align-items:center;flex-grow:1;background-color:#a5b3c9;flex-direction:column}.base-form{padding:10px}.form-field{display:flex}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$
|
|
607
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: LandingComponent, isStandalone: true, selector: "lib-landing", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "\n @if(message(); as message){\n <p>{{message}}</p>\n }\n \n <mat-card style=\"text-align:center;\">\n <form class=\"base-form\" #loginForm=\"ngForm\" (ngSubmit)=\"login()\">\n <mat-card-content>\n <mat-form-field class=\"form-field\">\n <input matInput\n placeholder=\"Username\"\n type=\"text\"\n [(ngModel)]=\"loginUser.name\"\n name=\"username\"\n required>\n </mat-form-field>\n <mat-form-field class=\"form-field\">\n <input matInput\n placeholder=\"Password\"\n type=\"password\"\n [(ngModel)]=\"loginUser.password\"\n name=\"password\"\n required>\n </mat-form-field>\n </mat-card-content>\n <div *ngIf=\"loginError\" class=\"error\">\n <mat-icon>error</mat-icon><p>{{loginError()}}</p>\n </div>\n <button mat-flat-button\n type=\"submit\"\n [disabled]=\"!loginForm.form.valid\">Log In</button>\n </form>\n </mat-card>\n\n\n \n", styles: [":host{display:flex;align-items:center;flex-grow:1;background-color:#a5b3c9;flex-direction:column}.base-form{padding:10px}.form-field{display:flex}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$3.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i1$4.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i1$4.MatCardContent, selector: "mat-card-content" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
642
608
|
}
|
|
643
609
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: LandingComponent, decorators: [{
|
|
644
610
|
type: Component,
|
|
@@ -676,7 +642,10 @@ class DetailView {
|
|
|
676
642
|
this.getItem();
|
|
677
643
|
}
|
|
678
644
|
title() {
|
|
679
|
-
|
|
645
|
+
if (this.itemService.typename) {
|
|
646
|
+
return this.itemService.typename.replace("_", " ");
|
|
647
|
+
}
|
|
648
|
+
return "";
|
|
680
649
|
}
|
|
681
650
|
onItemAvailable(item) {
|
|
682
651
|
this.item.set(item);
|
|
@@ -712,35 +681,39 @@ class EditView {
|
|
|
712
681
|
_route = inject(ActivatedRoute);
|
|
713
682
|
_location = inject(Location);
|
|
714
683
|
_userService = inject(UserService);
|
|
684
|
+
form;
|
|
715
685
|
itemService;
|
|
716
|
-
constructor(itemService) {
|
|
686
|
+
constructor(itemService, form) {
|
|
717
687
|
this.itemService = itemService;
|
|
688
|
+
this.form = form;
|
|
718
689
|
}
|
|
719
690
|
onInit() {
|
|
720
691
|
this.getItem();
|
|
721
692
|
}
|
|
722
|
-
onItemAvailable() {
|
|
693
|
+
onItemAvailable(item) {
|
|
723
694
|
this._userService.loggedInUser.subscribe(user => { if (user) {
|
|
724
|
-
this.onItemAndUserAvailable(user);
|
|
695
|
+
this.onItemAndUserAvailable(item, user);
|
|
725
696
|
} });
|
|
726
697
|
}
|
|
727
|
-
onItemAndUserAvailable(
|
|
698
|
+
onItemAndUserAvailable(_item, _user) {
|
|
728
699
|
}
|
|
729
700
|
goBack() {
|
|
730
701
|
this._location.back();
|
|
731
702
|
}
|
|
732
703
|
submit() {
|
|
733
|
-
|
|
734
|
-
if (this.item()) {
|
|
735
|
-
this.save();
|
|
736
|
-
}
|
|
704
|
+
this.save();
|
|
737
705
|
}
|
|
738
706
|
save() {
|
|
739
707
|
if (this.createMode()) {
|
|
740
|
-
this.
|
|
708
|
+
this.postItem();
|
|
741
709
|
}
|
|
742
710
|
else {
|
|
743
|
-
this.
|
|
711
|
+
const item = this.item();
|
|
712
|
+
{
|
|
713
|
+
if (item) {
|
|
714
|
+
this.putItem(item);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
744
717
|
}
|
|
745
718
|
}
|
|
746
719
|
cancel() {
|
|
@@ -760,16 +733,16 @@ class EditView {
|
|
|
760
733
|
onFileRead(_content) {
|
|
761
734
|
}
|
|
762
735
|
createItem() {
|
|
763
|
-
|
|
764
|
-
if (item) {
|
|
765
|
-
this.itemService.postItem(item).subscribe(item => this.saveFiles(item));
|
|
766
|
-
}
|
|
736
|
+
return this.form.createItem();
|
|
767
737
|
}
|
|
768
|
-
updateItem() {
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
738
|
+
updateItem(item) {
|
|
739
|
+
return this.form.updateItem(item);
|
|
740
|
+
}
|
|
741
|
+
postItem() {
|
|
742
|
+
this.itemService.postItem(this.createItem()).subscribe(item => this.saveFiles(item));
|
|
743
|
+
}
|
|
744
|
+
putItem(item) {
|
|
745
|
+
this.itemService.putItem(this.updateItem(item)).subscribe(item => this.saveFiles(item));
|
|
773
746
|
}
|
|
774
747
|
saveFiles(item) {
|
|
775
748
|
this.onItemUpdated(item);
|
|
@@ -788,16 +761,14 @@ class EditView {
|
|
|
788
761
|
}
|
|
789
762
|
getItem() {
|
|
790
763
|
if (this.isCreateRoute()) {
|
|
791
|
-
this.item.set(this.getTemplateItem());
|
|
792
764
|
this.createMode.set(true);
|
|
793
|
-
this.onItemAvailable();
|
|
794
765
|
}
|
|
795
766
|
else {
|
|
796
767
|
const id_str = this._route.snapshot.paramMap.get('id');
|
|
797
768
|
this.itemService.getItem(Number(id_str))
|
|
798
769
|
.subscribe(item => {
|
|
799
770
|
this.item.set(item);
|
|
800
|
-
this.onItemAvailable();
|
|
771
|
+
this.onItemAvailable(item);
|
|
801
772
|
});
|
|
802
773
|
}
|
|
803
774
|
}
|
|
@@ -817,6 +788,509 @@ class EditView {
|
|
|
817
788
|
}
|
|
818
789
|
}
|
|
819
790
|
|
|
791
|
+
class FormFieldDetailComponent {
|
|
792
|
+
field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
|
|
793
|
+
form = input.required(...(ngDevMode ? [{ debugName: "form" }] : []));
|
|
794
|
+
get isValid() {
|
|
795
|
+
return this.form().controls[this.key].valid;
|
|
796
|
+
}
|
|
797
|
+
get key() {
|
|
798
|
+
return this.field().id.toString();
|
|
799
|
+
}
|
|
800
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FormFieldDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
801
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: FormFieldDetailComponent, isStandalone: true, selector: "lib-form-field-detail", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div [formGroup]=\"form()\">\n <label [attr.for]=\"key\">{{ field().label }}</label>\n <div>\n @switch (field().field_type) {\n @case ('TEXT') {\n <mat-form-field class=\"form-field-wide\">\n <mat-label [attr.for]=\"key\">{{ field().label }}</mat-label>\n <textarea matInput\n [placeholder]=\"field().default\"\n type=\"text\"\n style=\"min-height:150px\"\n [formControlName]=\"key\"\n [name]=\"key\"></textarea>\n </mat-form-field>\n }\n @case('BOOLEAN')\n {\n <mat-checkbox\n class=\"form-field\"\n [name]=\"key\"\n [formControlName]=\"key\">\n {{ field().label }}\n </mat-checkbox>\n }\n @case ('INTEGER') {\n <mat-form-field class=\"form-field\">\n <mat-label>{{ field().label }}</mat-label>\n <input matInput\n [placeholder]=\"field().default\"\n type=\"number\"\n max=\"10\" min=\"1\"\n [formControlName]=\"key\"\n name=\"trl_stage\">\n </mat-form-field>\n }\n }\n </div>\n @if (!isValid) {\n <div class=\"errorMessage\">{{ field().label }} is required</div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$3.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i4.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }] });
|
|
802
|
+
}
|
|
803
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FormFieldDetailComponent, decorators: [{
|
|
804
|
+
type: Component,
|
|
805
|
+
args: [{ selector: 'lib-form-field-detail', imports: [ReactiveFormsModule,
|
|
806
|
+
MatFormFieldModule,
|
|
807
|
+
MatInputModule,
|
|
808
|
+
MatCheckboxModule], template: "<div [formGroup]=\"form()\">\n <label [attr.for]=\"key\">{{ field().label }}</label>\n <div>\n @switch (field().field_type) {\n @case ('TEXT') {\n <mat-form-field class=\"form-field-wide\">\n <mat-label [attr.for]=\"key\">{{ field().label }}</mat-label>\n <textarea matInput\n [placeholder]=\"field().default\"\n type=\"text\"\n style=\"min-height:150px\"\n [formControlName]=\"key\"\n [name]=\"key\"></textarea>\n </mat-form-field>\n }\n @case('BOOLEAN')\n {\n <mat-checkbox\n class=\"form-field\"\n [name]=\"key\"\n [formControlName]=\"key\">\n {{ field().label }}\n </mat-checkbox>\n }\n @case ('INTEGER') {\n <mat-form-field class=\"form-field\">\n <mat-label>{{ field().label }}</mat-label>\n <input matInput\n [placeholder]=\"field().default\"\n type=\"number\"\n max=\"10\" min=\"1\"\n [formControlName]=\"key\"\n name=\"trl_stage\">\n </mat-form-field>\n }\n }\n </div>\n @if (!isValid) {\n <div class=\"errorMessage\">{{ field().label }} is required</div>\n }\n</div>\n" }]
|
|
809
|
+
}] });
|
|
810
|
+
|
|
811
|
+
const FORM_FIELD_TABLE_FULL = [
|
|
812
|
+
{ name: 'label', title: 'Label', element_type: 'string' },
|
|
813
|
+
{ name: 'field_type', title: 'Type', element_type: 'string' }
|
|
814
|
+
];
|
|
815
|
+
const FORM_GROUP_TABLE_FULL = [
|
|
816
|
+
{ name: 'label', title: 'Label', element_type: 'string' }
|
|
817
|
+
];
|
|
818
|
+
|
|
819
|
+
class FormFieldListComponent {
|
|
820
|
+
form = input.required(...(ngDevMode ? [{ debugName: "form" }] : []));
|
|
821
|
+
edit = output();
|
|
822
|
+
columns = FORM_FIELD_TABLE_FULL;
|
|
823
|
+
columnNames = computed(() => { const names = this.columns.map(c => c.name); names.push("edit"); return names; }, ...(ngDevMode ? [{ debugName: "columnNames" }] : []));
|
|
824
|
+
onEdit(id) {
|
|
825
|
+
this.edit.emit(id);
|
|
826
|
+
}
|
|
827
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FormFieldListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
828
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: FormFieldListComponent, isStandalone: true, selector: "lib-form-field-list", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { edit: "edit" }, ngImport: i0, template: "<table mat-table [dataSource]=\"form().controls\" class=\"mat-elevation-z8\">\n @for (column of columns; track column.name) {\n <ng-container matColumnDef=\"{{ column.name }}\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>\n {{ column.title }}\n </th>\n <td mat-cell *matCellDef=\"let element\">{{ element.value[column.name] }}</td>\n </ng-container>\n }\n\n <ng-container matColumnDef=\"edit\">\n <th mat-header-cell *matHeaderCellDef>Edit\n </th>\n <td mat-cell *matCellDef=\"let idx = index\">\n <button mat-icon-button\n type=\"button\"\n color=\"primary\"\n aria-label=\"Edit an item\"\n (click)=\"onEdit(idx)\">\n <mat-icon>edit\n </mat-icon>\n </button>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"columnNames()\">\n </tr>\n <tr mat-row *matRowDef=\"let row; columns: columnNames();\">\n </tr>\n</table>\n\n\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$5.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$5.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$5.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$5.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$5.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$5.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$5.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$5.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$5.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$5.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
|
|
829
|
+
}
|
|
830
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FormFieldListComponent, decorators: [{
|
|
831
|
+
type: Component,
|
|
832
|
+
args: [{ selector: 'lib-form-field-list', imports: [MatTableModule, MatButtonModule, MatIconModule], template: "<table mat-table [dataSource]=\"form().controls\" class=\"mat-elevation-z8\">\n @for (column of columns; track column.name) {\n <ng-container matColumnDef=\"{{ column.name }}\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>\n {{ column.title }}\n </th>\n <td mat-cell *matCellDef=\"let element\">{{ element.value[column.name] }}</td>\n </ng-container>\n }\n\n <ng-container matColumnDef=\"edit\">\n <th mat-header-cell *matHeaderCellDef>Edit\n </th>\n <td mat-cell *matCellDef=\"let idx = index\">\n <button mat-icon-button\n type=\"button\"\n color=\"primary\"\n aria-label=\"Edit an item\"\n (click)=\"onEdit(idx)\">\n <mat-icon>edit\n </mat-icon>\n </button>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"columnNames()\">\n </tr>\n <tr mat-row *matRowDef=\"let row; columns: columnNames();\">\n </tr>\n</table>\n\n\n" }]
|
|
833
|
+
}] });
|
|
834
|
+
|
|
835
|
+
class FileUploadComponent {
|
|
836
|
+
files = input([], ...(ngDevMode ? [{ debugName: "files" }] : []));
|
|
837
|
+
previewLoaded = output();
|
|
838
|
+
fileUploaded = output();
|
|
839
|
+
clearLocal = output();
|
|
840
|
+
onPreviewRead(name, content) {
|
|
841
|
+
this.previewLoaded.emit({ name: name, content: content });
|
|
842
|
+
}
|
|
843
|
+
onFileUpload(name, event) {
|
|
844
|
+
if (!event.target) {
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
const input_element = event.target;
|
|
848
|
+
if (input_element.files && input_element.files.length > 0) {
|
|
849
|
+
const file = input_element.files[0];
|
|
850
|
+
this.fileUploaded.emit({ name: name, file: file });
|
|
851
|
+
const record = this.files().find(f => f.name == name);
|
|
852
|
+
if (record && record.file_type == "image") {
|
|
853
|
+
this.readFile(name, file);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
readFile(name, file) {
|
|
858
|
+
const reader = new FileReader();
|
|
859
|
+
reader.readAsDataURL(file);
|
|
860
|
+
reader.onload = () => {
|
|
861
|
+
if (reader.result) {
|
|
862
|
+
this.previewLoaded.emit({ name: name, content: reader.result });
|
|
863
|
+
}
|
|
864
|
+
;
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
onClearLocal() {
|
|
868
|
+
this.clearLocal.emit();
|
|
869
|
+
}
|
|
870
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FileUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
871
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: FileUploadComponent, isStandalone: true, selector: "lib-file-upload", inputs: { files: { classPropertyName: "files", publicName: "files", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { previewLoaded: "previewLoaded", fileUploaded: "fileUploaded", clearLocal: "clearLocal" }, ngImport: i0, template: "<div class=\"container\">\n @for( file of files(); track file.name)\n {\n @if (file.local)\n {\n <div class=\"image_holder\">\n <p>Update {{file.display_name}}</p>\n <img alt=\"{{file.display_name}}\" src=\"{{file.local}}\" style=\"height:120px;\">\n <button mat-mini-fab (click)=\"onClearLocal()\" type=\"button\">\n <mat-icon>clear</mat-icon>\n </button>\n </div> \n }\n @else\n {\n @if (file.remote){\n <div class=\"image_holder\">\n <p>Update {{file.display_name}}</p>\n <img alt=\"{{file.display_name}}\" src=\"{{file.remote}}\" style=\"height:120px;\">\n </div>\n }\n @else {\n <div>\n <span>Upload a {{file.display_name}}</span>\n </div> \n }\n \n }\n\n <div class=\"button-row\">\n <button mat-mini-fab (click)=\"fileInput.click()\" type=\"button\">\n <mat-icon>attachment</mat-icon>\n </button>\n <input hidden type=\"file\" #fileInput (change)=\"onFileUpload(file.name, $event)\"/>\n </div> \n } \n</div>\n", styles: [".container{padding:10px;display:flex;justify-content:center;text-align:center;flex-direction:column;max-width:300px}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }] });
|
|
872
|
+
}
|
|
873
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FileUploadComponent, decorators: [{
|
|
874
|
+
type: Component,
|
|
875
|
+
args: [{ selector: 'lib-file-upload', imports: [MatIconModule, MatButtonModule], template: "<div class=\"container\">\n @for( file of files(); track file.name)\n {\n @if (file.local)\n {\n <div class=\"image_holder\">\n <p>Update {{file.display_name}}</p>\n <img alt=\"{{file.display_name}}\" src=\"{{file.local}}\" style=\"height:120px;\">\n <button mat-mini-fab (click)=\"onClearLocal()\" type=\"button\">\n <mat-icon>clear</mat-icon>\n </button>\n </div> \n }\n @else\n {\n @if (file.remote){\n <div class=\"image_holder\">\n <p>Update {{file.display_name}}</p>\n <img alt=\"{{file.display_name}}\" src=\"{{file.remote}}\" style=\"height:120px;\">\n </div>\n }\n @else {\n <div>\n <span>Upload a {{file.display_name}}</span>\n </div> \n }\n \n }\n\n <div class=\"button-row\">\n <button mat-mini-fab (click)=\"fileInput.click()\" type=\"button\">\n <mat-icon>attachment</mat-icon>\n </button>\n <input hidden type=\"file\" #fileInput (change)=\"onFileUpload(file.name, $event)\"/>\n </div> \n } \n</div>\n", styles: [".container{padding:10px;display:flex;justify-content:center;text-align:center;flex-direction:column;max-width:300px}\n"] }]
|
|
876
|
+
}] });
|
|
877
|
+
|
|
878
|
+
class FormFieldEditComponent {
|
|
879
|
+
availableTypes = FORM_FIELD_CHOICES;
|
|
880
|
+
form = input.required(...(ngDevMode ? [{ debugName: "form" }] : []));
|
|
881
|
+
editMode = input(false, ...(ngDevMode ? [{ debugName: "editMode" }] : []));
|
|
882
|
+
submitted = output();
|
|
883
|
+
cancelled = output();
|
|
884
|
+
get isBoolean() {
|
|
885
|
+
return this.fieldType === "BOOLEAN";
|
|
886
|
+
}
|
|
887
|
+
get isShortText() {
|
|
888
|
+
return this.fieldType === "CHAR";
|
|
889
|
+
}
|
|
890
|
+
get isLongText() {
|
|
891
|
+
return this.fieldType === "TEXT";
|
|
892
|
+
}
|
|
893
|
+
get isRichText() {
|
|
894
|
+
return this.fieldType === "RICH_TEXT";
|
|
895
|
+
}
|
|
896
|
+
get isSelection() {
|
|
897
|
+
return this.fieldType === "SELECTION";
|
|
898
|
+
}
|
|
899
|
+
get isInteger() {
|
|
900
|
+
return this.fieldType === "INTEGER";
|
|
901
|
+
}
|
|
902
|
+
get isFile() {
|
|
903
|
+
return this.fieldType === "FILE";
|
|
904
|
+
}
|
|
905
|
+
get fieldType() {
|
|
906
|
+
return this.form().value.field_type;
|
|
907
|
+
}
|
|
908
|
+
submit() {
|
|
909
|
+
this.submitted.emit();
|
|
910
|
+
}
|
|
911
|
+
cancel() {
|
|
912
|
+
this.cancelled.emit();
|
|
913
|
+
}
|
|
914
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FormFieldEditComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
915
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: FormFieldEditComponent, isStandalone: true, selector: "lib-form-field-edit", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null }, editMode: { classPropertyName: "editMode", publicName: "editMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { submitted: "submitted", cancelled: "cancelled" }, ngImport: i0, template: "<form class=\"form-card\" id=\"app-field-form\" [formGroup]=\"form()\" (ngSubmit)=\"submit()\">\n <mat-form-field class=\"form-field\">\n <mat-label>Label</mat-label>\n <input matInput \n placeholder=\"Label\" \n type=\"text\" \n formControlName=\"label\" \n required \n name=\"label\">\n </mat-form-field>\n\n<mat-form-field class=\"form-field-wide\">\n<mat-label>Description</mat-label>\n<textarea matInput placeholder=\"Description\" style=\"min-height:150px\" type=\"text\" formControlName=\"description\"\n required name=\"description\"></textarea>\n</mat-form-field>\n\n <mat-checkbox class=\"example-margin\" formControlName=\"required\">Required?</mat-checkbox>\n\n<mat-form-field class=\"form-field\">\n <mat-label>Type</mat-label>\n <mat-select formControlName=\"field_type\" name=\"field_type\" required>\n @for(type of availableTypes; track type.value){\n <mat-option [value]=\"type.value\">{{type.display_name}}\n </mat-option>\n }\n </mat-select>\n</mat-form-field>\n \n @if(isBoolean)\n {\n <mat-form-field class=\"form-field\">\n <mat-label>Default</mat-label>\n <mat-select formControlName=\"default\" name=\"default\" required>\n <mat-option [value]=\"'true'\">True</mat-option>\n <mat-option [value]=\"'false'\">False</mat-option>\n </mat-select>\n </mat-form-field>\n }\n @else if(isShortText)\n {\n <mat-form-field class=\"form-field\">\n <mat-label>Default</mat-label>\n <input matInput \n placeholder=\"Default\" \n type=\"text\" \n formControlName=\"default\" \n name=\"default\">\n </mat-form-field>\n }\n @else if(isLongText || isRichText)\n {\n <mat-form-field class=\"form-field-wide\">\n <mat-label>Default</mat-label>\n <textarea matInput placeholder=\"Default\" style=\"min-height:150px\" type=\"text\" \n formControlName=\"default\"\n name=\"default\"></textarea>\n </mat-form-field>\n }\n @else if(isFile)\n {\n <lib-file-upload></lib-file-upload>\n }\n\n <div>\n\n @if(editMode())\n {\n <button mat-fab class=\"form_action_button\" \n type=\"submit\" form=\"app-field-form\" matTooltip=\"Save Field\"\n [disabled]=\"!form().valid\">\n <mat-icon>save</mat-icon>\n </button>\n\n <button mat-fab class=\"form_action_button\" \n matTooltip=\"Cancel Editing Field\" (click)=\"cancel()\">\n <mat-icon>cancel</mat-icon>\n </button> \n }\n @else {\n <button mat-fab class=\"form_action_button\" \n type=\"submit\" form=\"app-field-form\" matTooltip=\"Add Field\"\n [disabled]=\"!form().valid\">\n <mat-icon>add</mat-icon>\n </button>\n <button mat-fab class=\"form_action_button\" \n matTooltip=\"Cancel Adding Field\" (click)=\"cancel()\">\n <mat-icon>cancel</mat-icon>\n </button> \n }\n </div> \n</form>", styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "ngmodule", type: MatTableModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i2$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i4.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: FileUploadComponent, selector: "lib-file-upload", inputs: ["files"], outputs: ["previewLoaded", "fileUploaded", "clearLocal"] }] });
|
|
916
|
+
}
|
|
917
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FormFieldEditComponent, decorators: [{
|
|
918
|
+
type: Component,
|
|
919
|
+
args: [{ selector: 'lib-form-field-edit', imports: [ReactiveFormsModule,
|
|
920
|
+
RouterModule,
|
|
921
|
+
MatButtonModule,
|
|
922
|
+
MatCardModule,
|
|
923
|
+
MatTableModule,
|
|
924
|
+
MatInputModule,
|
|
925
|
+
MatFormFieldModule,
|
|
926
|
+
MatIconModule,
|
|
927
|
+
MatSelectModule,
|
|
928
|
+
MatTooltipModule,
|
|
929
|
+
MatCheckboxModule,
|
|
930
|
+
FileUploadComponent], template: "<form class=\"form-card\" id=\"app-field-form\" [formGroup]=\"form()\" (ngSubmit)=\"submit()\">\n <mat-form-field class=\"form-field\">\n <mat-label>Label</mat-label>\n <input matInput \n placeholder=\"Label\" \n type=\"text\" \n formControlName=\"label\" \n required \n name=\"label\">\n </mat-form-field>\n\n<mat-form-field class=\"form-field-wide\">\n<mat-label>Description</mat-label>\n<textarea matInput placeholder=\"Description\" style=\"min-height:150px\" type=\"text\" formControlName=\"description\"\n required name=\"description\"></textarea>\n</mat-form-field>\n\n <mat-checkbox class=\"example-margin\" formControlName=\"required\">Required?</mat-checkbox>\n\n<mat-form-field class=\"form-field\">\n <mat-label>Type</mat-label>\n <mat-select formControlName=\"field_type\" name=\"field_type\" required>\n @for(type of availableTypes; track type.value){\n <mat-option [value]=\"type.value\">{{type.display_name}}\n </mat-option>\n }\n </mat-select>\n</mat-form-field>\n \n @if(isBoolean)\n {\n <mat-form-field class=\"form-field\">\n <mat-label>Default</mat-label>\n <mat-select formControlName=\"default\" name=\"default\" required>\n <mat-option [value]=\"'true'\">True</mat-option>\n <mat-option [value]=\"'false'\">False</mat-option>\n </mat-select>\n </mat-form-field>\n }\n @else if(isShortText)\n {\n <mat-form-field class=\"form-field\">\n <mat-label>Default</mat-label>\n <input matInput \n placeholder=\"Default\" \n type=\"text\" \n formControlName=\"default\" \n name=\"default\">\n </mat-form-field>\n }\n @else if(isLongText || isRichText)\n {\n <mat-form-field class=\"form-field-wide\">\n <mat-label>Default</mat-label>\n <textarea matInput placeholder=\"Default\" style=\"min-height:150px\" type=\"text\" \n formControlName=\"default\"\n name=\"default\"></textarea>\n </mat-form-field>\n }\n @else if(isFile)\n {\n <lib-file-upload></lib-file-upload>\n }\n\n <div>\n\n @if(editMode())\n {\n <button mat-fab class=\"form_action_button\" \n type=\"submit\" form=\"app-field-form\" matTooltip=\"Save Field\"\n [disabled]=\"!form().valid\">\n <mat-icon>save</mat-icon>\n </button>\n\n <button mat-fab class=\"form_action_button\" \n matTooltip=\"Cancel Editing Field\" (click)=\"cancel()\">\n <mat-icon>cancel</mat-icon>\n </button> \n }\n @else {\n <button mat-fab class=\"form_action_button\" \n type=\"submit\" form=\"app-field-form\" matTooltip=\"Add Field\"\n [disabled]=\"!form().valid\">\n <mat-icon>add</mat-icon>\n </button>\n <button mat-fab class=\"form_action_button\" \n matTooltip=\"Cancel Adding Field\" (click)=\"cancel()\">\n <mat-icon>cancel</mat-icon>\n </button> \n }\n </div> \n</form>" }]
|
|
931
|
+
}] });
|
|
932
|
+
|
|
933
|
+
class DynamicFormComponent {
|
|
934
|
+
formService = inject(FormService);
|
|
935
|
+
inputForm = input.required(...(ngDevMode ? [{ debugName: "inputForm" }] : []));
|
|
936
|
+
form = computed(() => this.formService.toFormGroup(this.inputForm()), ...(ngDevMode ? [{ debugName: "form" }] : []));
|
|
937
|
+
payLoad = '';
|
|
938
|
+
onSubmit() {
|
|
939
|
+
this.payLoad = JSON.stringify(this.form().getRawValue());
|
|
940
|
+
}
|
|
941
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: DynamicFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
942
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: DynamicFormComponent, isStandalone: true, selector: "lib-dynamic-form", inputs: { inputForm: { classPropertyName: "inputForm", publicName: "inputForm", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div>\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"form()\">\n\n @for (group of inputForm().groups; track group.id) {\n @for (field of group.fields; track field.id) {\n <div class=\"form-row\">\n <lib-form-field-detail [field]=\"field\" [form]=\"form()\" />\n </div>\n }\n }\n </form>\n @if (payLoad) {\n <div class=\"form-row\"><strong>Saved the following values</strong><br />{{ payLoad }}</div>\n }\n</div>", styles: [""], dependencies: [{ kind: "component", type: FormFieldDetailComponent, selector: "lib-form-field-detail", inputs: ["field", "form"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }] });
|
|
943
|
+
}
|
|
944
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: DynamicFormComponent, decorators: [{
|
|
945
|
+
type: Component,
|
|
946
|
+
args: [{ selector: 'lib-dynamic-form', imports: [FormFieldDetailComponent, ReactiveFormsModule, FormFieldDetailComponent], template: "<div>\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"form()\">\n\n @for (group of inputForm().groups; track group.id) {\n @for (field of group.fields; track field.id) {\n <div class=\"form-row\">\n <lib-form-field-detail [field]=\"field\" [form]=\"form()\" />\n </div>\n }\n }\n </form>\n @if (payLoad) {\n <div class=\"form-row\"><strong>Saved the following values</strong><br />{{ payLoad }}</div>\n }\n</div>" }]
|
|
947
|
+
}] });
|
|
948
|
+
|
|
949
|
+
class FormFieldForm {
|
|
950
|
+
static createForm(fb) {
|
|
951
|
+
return fb.group({
|
|
952
|
+
label: fb.control('', Validators.required),
|
|
953
|
+
required: fb.control(false, Validators.required),
|
|
954
|
+
description: fb.control('', Validators.required),
|
|
955
|
+
template: fb.control(null),
|
|
956
|
+
options: fb.control(null),
|
|
957
|
+
default: fb.control(''),
|
|
958
|
+
field_type: fb.control("BOOLEAN", Validators.required),
|
|
959
|
+
order: fb.control(0),
|
|
960
|
+
id: fb.control(-1),
|
|
961
|
+
});
|
|
962
|
+
}
|
|
963
|
+
static fromItem(item, builder) {
|
|
964
|
+
const form = this.createForm(builder);
|
|
965
|
+
this.setValue(form, item);
|
|
966
|
+
return form;
|
|
967
|
+
}
|
|
968
|
+
static setValue(form, item) {
|
|
969
|
+
let id = -1;
|
|
970
|
+
if ('id' in item) {
|
|
971
|
+
id = item.id;
|
|
972
|
+
}
|
|
973
|
+
form.setValue({
|
|
974
|
+
label: item.label,
|
|
975
|
+
required: item.required,
|
|
976
|
+
description: item.description,
|
|
977
|
+
template: item.template,
|
|
978
|
+
options: "",
|
|
979
|
+
default: item.default,
|
|
980
|
+
field_type: item.field_type,
|
|
981
|
+
order: item.order,
|
|
982
|
+
id: id
|
|
983
|
+
});
|
|
984
|
+
}
|
|
985
|
+
static createItem(form) {
|
|
986
|
+
const value = form.value;
|
|
987
|
+
return {
|
|
988
|
+
label: value.label || "",
|
|
989
|
+
required: value.required || false,
|
|
990
|
+
description: value.description || "",
|
|
991
|
+
template: value.template || null,
|
|
992
|
+
options: null,
|
|
993
|
+
default: value.default || "",
|
|
994
|
+
field_type: value.field_type || "BOOLEAN",
|
|
995
|
+
order: value.order || 0
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
static updateItem(form, item) {
|
|
999
|
+
const value = form.value;
|
|
1000
|
+
item.label = value.label || "";
|
|
1001
|
+
item.required = value.required || false;
|
|
1002
|
+
item.description = value.description || "";
|
|
1003
|
+
item.template = value.template || null;
|
|
1004
|
+
item.options = null;
|
|
1005
|
+
item.default = value.default || "";
|
|
1006
|
+
item.field_type = value.field_type || "BOOLEAN";
|
|
1007
|
+
item.order = value.order || 0;
|
|
1008
|
+
return item;
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
class FormGroupForm {
|
|
1013
|
+
static createForm(fb) {
|
|
1014
|
+
return fb.group({
|
|
1015
|
+
label: fb.control(''),
|
|
1016
|
+
description: fb.control(''),
|
|
1017
|
+
order: fb.control(0),
|
|
1018
|
+
fields: fb.array([]),
|
|
1019
|
+
id: fb.control(-1)
|
|
1020
|
+
});
|
|
1021
|
+
}
|
|
1022
|
+
static createField(form, field) {
|
|
1023
|
+
const fields = this.getFields(form);
|
|
1024
|
+
field.patchValue({ order: fields.controls.length });
|
|
1025
|
+
fields.push(field);
|
|
1026
|
+
}
|
|
1027
|
+
static deleteField(form, id) {
|
|
1028
|
+
this.getFields(form).removeAt(id);
|
|
1029
|
+
}
|
|
1030
|
+
static fromItem(item, fb) {
|
|
1031
|
+
const form = this.createForm(fb);
|
|
1032
|
+
this.setValue(form, item, fb);
|
|
1033
|
+
return form;
|
|
1034
|
+
}
|
|
1035
|
+
static getLabel(form, id) {
|
|
1036
|
+
if (form.value) {
|
|
1037
|
+
if (form.value.label) {
|
|
1038
|
+
return form.value.label;
|
|
1039
|
+
}
|
|
1040
|
+
else if (form.value.order) {
|
|
1041
|
+
return "Group " + form.value.order.toString();
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
return "Group " + id.toString();
|
|
1045
|
+
}
|
|
1046
|
+
static setValue(form, item, fb) {
|
|
1047
|
+
let id = -1;
|
|
1048
|
+
if ('id' in item) {
|
|
1049
|
+
id = item.id;
|
|
1050
|
+
}
|
|
1051
|
+
form.patchValue({
|
|
1052
|
+
label: item.label,
|
|
1053
|
+
description: item.description,
|
|
1054
|
+
order: item.order,
|
|
1055
|
+
id: id
|
|
1056
|
+
});
|
|
1057
|
+
const fields = this.getFields(form);
|
|
1058
|
+
fields.clear();
|
|
1059
|
+
item.fields.map(f => fields.push(FormFieldForm.fromItem(f, fb)));
|
|
1060
|
+
}
|
|
1061
|
+
static getFields(form) {
|
|
1062
|
+
return form.get('fields');
|
|
1063
|
+
}
|
|
1064
|
+
static createItem(form) {
|
|
1065
|
+
const value = form.value;
|
|
1066
|
+
return {
|
|
1067
|
+
label: value.label || "",
|
|
1068
|
+
description: value.description || "",
|
|
1069
|
+
order: value.order || 0,
|
|
1070
|
+
fields: Array.from(this.getFields(form).controls.map(f => FormFieldForm.createItem(f)))
|
|
1071
|
+
};
|
|
1072
|
+
}
|
|
1073
|
+
static createOrUpdateField(form, items) {
|
|
1074
|
+
if (form.value.id && form.value.id >= 0) {
|
|
1075
|
+
const matching_item = items.find(item => "id" in item && item.id == form.value.id);
|
|
1076
|
+
return FormFieldForm.updateItem(form, matching_item);
|
|
1077
|
+
}
|
|
1078
|
+
return FormFieldForm.createItem(form);
|
|
1079
|
+
}
|
|
1080
|
+
static updateItem(form, item) {
|
|
1081
|
+
const value = form.value;
|
|
1082
|
+
item.label = value.label || "";
|
|
1083
|
+
item.description = value.description || "";
|
|
1084
|
+
item.order = value.order || 0;
|
|
1085
|
+
item.fields = Array.from(this.getFields(form).controls.map(f => this.createOrUpdateField(f, item.fields)));
|
|
1086
|
+
return item;
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
class FormGroupEditComponent {
|
|
1091
|
+
create = input(false, ...(ngDevMode ? [{ debugName: "create" }] : []));
|
|
1092
|
+
form = input.required(...(ngDevMode ? [{ debugName: "form" }] : []));
|
|
1093
|
+
cancelled = output();
|
|
1094
|
+
submitted = output();
|
|
1095
|
+
editingField = signal(-1, ...(ngDevMode ? [{ debugName: "editingField" }] : []));
|
|
1096
|
+
creatingField = signal(false, ...(ngDevMode ? [{ debugName: "creatingField" }] : []));
|
|
1097
|
+
fieldForm = null;
|
|
1098
|
+
builder = inject(FormBuilder);
|
|
1099
|
+
get fields() {
|
|
1100
|
+
return this.form().get('fields');
|
|
1101
|
+
}
|
|
1102
|
+
submit() {
|
|
1103
|
+
this.submitted.emit();
|
|
1104
|
+
}
|
|
1105
|
+
cancel() {
|
|
1106
|
+
this.cancelled.emit();
|
|
1107
|
+
}
|
|
1108
|
+
addField() {
|
|
1109
|
+
this.creatingField.set(true);
|
|
1110
|
+
this.fieldForm = FormFieldForm.createForm(this.builder);
|
|
1111
|
+
}
|
|
1112
|
+
editField(id) {
|
|
1113
|
+
this.editingField.set(id);
|
|
1114
|
+
this.fieldForm = this.fields.controls[this.editingField()];
|
|
1115
|
+
}
|
|
1116
|
+
cancelField() {
|
|
1117
|
+
this.resetField();
|
|
1118
|
+
}
|
|
1119
|
+
resetField() {
|
|
1120
|
+
this.creatingField.set(false);
|
|
1121
|
+
this.fieldForm = null;
|
|
1122
|
+
this.editingField.set(-1);
|
|
1123
|
+
}
|
|
1124
|
+
submitField() {
|
|
1125
|
+
if (this.creatingField() && this.fieldForm && this.form) {
|
|
1126
|
+
FormGroupForm.createField(this.form(), this.fieldForm);
|
|
1127
|
+
}
|
|
1128
|
+
this.resetField();
|
|
1129
|
+
}
|
|
1130
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FormGroupEditComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1131
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: FormGroupEditComponent, isStandalone: true, selector: "lib-form-group-edit", inputs: { create: { classPropertyName: "create", publicName: "create", isSignal: true, isRequired: false, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { cancelled: "cancelled", submitted: "submitted" }, ngImport: i0, template: "<div [formGroup]=\"form()\">\n\n @if(fieldForm && fields)\n {\n @if(creatingField())\n {\n <h3>Creating Field</h3>\n }\n @else {\n <h3>Editing Field</h3>\n }\n <lib-form-field-edit [form]=\"fieldForm\" (submitted)=\"submitField()\"\n (cancelled)=\"cancelField()\"></lib-form-field-edit>\n }\n @else{\n\n @if(create())\n {\n <h3>Creating Group</h3>\n }\n @else {\n <h3>Editing Group</h3>\n }\n\n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"description\">Description</mat-label>\n <textarea matInput placeholder=\"\" type=\"text\" style=\"min-height:150px\" formControlName=\"description\"\n name=\"description\"></textarea>\n </mat-form-field>\n\n <h3>Fields</h3>\n <div>\n <button mat-fab class=\"form_action_button\" (click)=\"addField()\" matTooltip=\"Add a Field\" type=\"button\">\n <mat-icon>add</mat-icon>\n </button>\n\n @if(fields && fields.length > 0){\n <lib-form-field-list [form]=\"fields\" (edit)=\"editField($event)\">\n </lib-form-field-list>\n }\n </div>\n\n <button mat-fab class=\"form-action-button\" (click)=\"submit()\" matTooltip=\"Save Group\" type=\"button\">\n <mat-icon>save</mat-icon>\n </button>\n\n <button mat-fab class=\"form-action-button\" (click)=\"cancel()\" matTooltip=\"Cancel adding Group\" type=\"button\">\n <mat-icon>cancel</mat-icon>\n </button>\n }\n\n\n</div>", styles: [""], dependencies: [{ kind: "component", type: FormFieldEditComponent, selector: "lib-form-field-edit", inputs: ["form", "editMode"], outputs: ["submitted", "cancelled"] }, { kind: "component", type: FormFieldListComponent, selector: "lib-form-field-list", inputs: ["form"], outputs: ["edit"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
1132
|
+
}
|
|
1133
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FormGroupEditComponent, decorators: [{
|
|
1134
|
+
type: Component,
|
|
1135
|
+
args: [{ selector: 'lib-form-group-edit', imports: [FormFieldEditComponent,
|
|
1136
|
+
FormFieldListComponent,
|
|
1137
|
+
MatIconModule,
|
|
1138
|
+
MatFormFieldModule,
|
|
1139
|
+
ReactiveFormsModule,
|
|
1140
|
+
MatButtonModule,
|
|
1141
|
+
MatInputModule, MatTooltipModule], template: "<div [formGroup]=\"form()\">\n\n @if(fieldForm && fields)\n {\n @if(creatingField())\n {\n <h3>Creating Field</h3>\n }\n @else {\n <h3>Editing Field</h3>\n }\n <lib-form-field-edit [form]=\"fieldForm\" (submitted)=\"submitField()\"\n (cancelled)=\"cancelField()\"></lib-form-field-edit>\n }\n @else{\n\n @if(create())\n {\n <h3>Creating Group</h3>\n }\n @else {\n <h3>Editing Group</h3>\n }\n\n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"description\">Description</mat-label>\n <textarea matInput placeholder=\"\" type=\"text\" style=\"min-height:150px\" formControlName=\"description\"\n name=\"description\"></textarea>\n </mat-form-field>\n\n <h3>Fields</h3>\n <div>\n <button mat-fab class=\"form_action_button\" (click)=\"addField()\" matTooltip=\"Add a Field\" type=\"button\">\n <mat-icon>add</mat-icon>\n </button>\n\n @if(fields && fields.length > 0){\n <lib-form-field-list [form]=\"fields\" (edit)=\"editField($event)\">\n </lib-form-field-list>\n }\n </div>\n\n <button mat-fab class=\"form-action-button\" (click)=\"submit()\" matTooltip=\"Save Group\" type=\"button\">\n <mat-icon>save</mat-icon>\n </button>\n\n <button mat-fab class=\"form-action-button\" (click)=\"cancel()\" matTooltip=\"Cancel adding Group\" type=\"button\">\n <mat-icon>cancel</mat-icon>\n </button>\n }\n\n\n</div>" }]
|
|
1142
|
+
}] });
|
|
1143
|
+
|
|
1144
|
+
class FormGroupListComponent {
|
|
1145
|
+
form = input(...(ngDevMode ? [undefined, { debugName: "form" }] : []));
|
|
1146
|
+
edit = output();
|
|
1147
|
+
delete = output();
|
|
1148
|
+
orderUp = output();
|
|
1149
|
+
orderDown = output();
|
|
1150
|
+
add = output();
|
|
1151
|
+
table = viewChild(MatTable, ...(ngDevMode ? [{ debugName: "table" }] : []));
|
|
1152
|
+
columns = FORM_GROUP_TABLE_FULL;
|
|
1153
|
+
columnNames = computed(() => {
|
|
1154
|
+
const names = this.columns.map(c => c.name);
|
|
1155
|
+
names.push("edit");
|
|
1156
|
+
return names;
|
|
1157
|
+
}, ...(ngDevMode ? [{ debugName: "columnNames" }] : []));
|
|
1158
|
+
onEdit(form) {
|
|
1159
|
+
this.edit.emit(form.value.order);
|
|
1160
|
+
}
|
|
1161
|
+
onDelete(form) {
|
|
1162
|
+
this.delete.emit(form.value.order);
|
|
1163
|
+
this.table()?.renderRows();
|
|
1164
|
+
}
|
|
1165
|
+
onOrderUp(form) {
|
|
1166
|
+
this.orderUp.emit(form.value.order);
|
|
1167
|
+
this.table()?.renderRows();
|
|
1168
|
+
}
|
|
1169
|
+
onOrderDown(form) {
|
|
1170
|
+
this.orderDown.emit(form.value.order);
|
|
1171
|
+
this.table()?.renderRows();
|
|
1172
|
+
}
|
|
1173
|
+
onAdd() {
|
|
1174
|
+
this.add.emit();
|
|
1175
|
+
}
|
|
1176
|
+
getLabel(form) {
|
|
1177
|
+
if (form.value.label) {
|
|
1178
|
+
return form.value.label;
|
|
1179
|
+
}
|
|
1180
|
+
else {
|
|
1181
|
+
return "Group " + form.value.order.toString();
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FormGroupListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1185
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: FormGroupListComponent, isStandalone: true, selector: "lib-form-group-list", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { edit: "edit", delete: "delete", orderUp: "orderUp", orderDown: "orderDown", add: "add" }, viewQueries: [{ propertyName: "table", first: true, predicate: MatTable, descendants: true, isSignal: true }], ngImport: i0, template: "@if(form(); as form){\n\n@if (form.controls.length > 0){\n<table mat-table [dataSource]=\"form.controls\" class=\"mat-elevation-z8\">\n @for (column of columns; track column.name) {\n <ng-container matColumnDef=\"{{ column.name }}\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>\n {{ column.title }}\n </th>\n <td mat-cell *matCellDef=\"let element;\">\n {{ getLabel(element) }}\n </td>\n </ng-container>\n }\n <ng-container matColumnDef=\"edit\">\n <th mat-header-cell *matHeaderCellDef>Edit\n </th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"control\">\n <button mat-icon-button\n type=\"button\"\n color=\"primary\"\n aria-label=\"Edit an item\"\n (click)=\"onEdit(element)\">\n <mat-icon>edit\n </mat-icon>\n </button>\n <button mat-icon-button\n type=\"button\"\n color=\"primary\"\n aria-label=\"Delete an item\"\n (click)=\"onDelete(element)\">\n <mat-icon>delete\n </mat-icon>\n </button>\n <button mat-icon-button\n type=\"button\"\n color=\"primary\"\n aria-label=\"Move Order Up\"\n (click)=\"onOrderUp(element)\">\n <mat-icon>arrow_upward\n </mat-icon>\n </button> \n <button mat-icon-button\n type=\"button\"\n color=\"primary\"\n aria-label=\"Move Order Down\"\n (click)=\"onOrderDown(element)\">\n <mat-icon>arrow_downward\n </mat-icon>\n </button>\n </div>\n </td>\n </ng-container>\n \n <tr mat-header-row *matHeaderRowDef=\"columnNames()\">\n </tr>\n <tr mat-row *matRowDef=\"let row; columns: columnNames();\">\n </tr>\n</table>\n}\n}\n\n<button mat-fab class=\"form-action-button\" \n (click)=\"onAdd()\" matTooltip=\"Add a Group\" type=\"button\">\n<mat-icon>add</mat-icon>\n</button>\n\n", styles: [".control,.mat-row:hover .control{display:block}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2$1.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$5.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$5.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$5.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$5.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$5.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$5.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$5.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$5.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$5.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$5.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
1186
|
+
}
|
|
1187
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FormGroupListComponent, decorators: [{
|
|
1188
|
+
type: Component,
|
|
1189
|
+
args: [{ selector: 'lib-form-group-list', imports: [MatIconModule, MatButtonModule, MatTableModule, MatTooltipModule], template: "@if(form(); as form){\n\n@if (form.controls.length > 0){\n<table mat-table [dataSource]=\"form.controls\" class=\"mat-elevation-z8\">\n @for (column of columns; track column.name) {\n <ng-container matColumnDef=\"{{ column.name }}\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>\n {{ column.title }}\n </th>\n <td mat-cell *matCellDef=\"let element;\">\n {{ getLabel(element) }}\n </td>\n </ng-container>\n }\n <ng-container matColumnDef=\"edit\">\n <th mat-header-cell *matHeaderCellDef>Edit\n </th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"control\">\n <button mat-icon-button\n type=\"button\"\n color=\"primary\"\n aria-label=\"Edit an item\"\n (click)=\"onEdit(element)\">\n <mat-icon>edit\n </mat-icon>\n </button>\n <button mat-icon-button\n type=\"button\"\n color=\"primary\"\n aria-label=\"Delete an item\"\n (click)=\"onDelete(element)\">\n <mat-icon>delete\n </mat-icon>\n </button>\n <button mat-icon-button\n type=\"button\"\n color=\"primary\"\n aria-label=\"Move Order Up\"\n (click)=\"onOrderUp(element)\">\n <mat-icon>arrow_upward\n </mat-icon>\n </button> \n <button mat-icon-button\n type=\"button\"\n color=\"primary\"\n aria-label=\"Move Order Down\"\n (click)=\"onOrderDown(element)\">\n <mat-icon>arrow_downward\n </mat-icon>\n </button>\n </div>\n </td>\n </ng-container>\n \n <tr mat-header-row *matHeaderRowDef=\"columnNames()\">\n </tr>\n <tr mat-row *matRowDef=\"let row; columns: columnNames();\">\n </tr>\n</table>\n}\n}\n\n<button mat-fab class=\"form-action-button\" \n (click)=\"onAdd()\" matTooltip=\"Add a Group\" type=\"button\">\n<mat-icon>add</mat-icon>\n</button>\n\n", styles: [".control,.mat-row:hover .control{display:block}\n"] }]
|
|
1190
|
+
}] });
|
|
1191
|
+
|
|
1192
|
+
class DynamicFormBuilderComponent {
|
|
1193
|
+
form = input.required(...(ngDevMode ? [{ debugName: "form" }] : []));
|
|
1194
|
+
handleSubmit = input(false, ...(ngDevMode ? [{ debugName: "handleSubmit" }] : []));
|
|
1195
|
+
submitted = output();
|
|
1196
|
+
editingField = signal(-1, ...(ngDevMode ? [{ debugName: "editingField" }] : []));
|
|
1197
|
+
creatingField = signal(false, ...(ngDevMode ? [{ debugName: "creatingField" }] : []));
|
|
1198
|
+
editingGroup = signal(-1, ...(ngDevMode ? [{ debugName: "editingGroup" }] : []));
|
|
1199
|
+
creatingGroup = signal(false, ...(ngDevMode ? [{ debugName: "creatingGroup" }] : []));
|
|
1200
|
+
dirty = signal(false, ...(ngDevMode ? [{ debugName: "dirty" }] : []));
|
|
1201
|
+
formBuilder = inject(FormBuilder);
|
|
1202
|
+
groupForm = null;
|
|
1203
|
+
addGroup() {
|
|
1204
|
+
this.creatingGroup.set(true);
|
|
1205
|
+
this.groupForm = FormGroupForm.createForm(this.formBuilder);
|
|
1206
|
+
}
|
|
1207
|
+
editGroup(id) {
|
|
1208
|
+
this.editingGroup.set(id);
|
|
1209
|
+
this.groupForm = this.form().groups.controls[id];
|
|
1210
|
+
}
|
|
1211
|
+
deleteGroup(id) {
|
|
1212
|
+
this.form().deleteGroup(id);
|
|
1213
|
+
this.dirty.set(true);
|
|
1214
|
+
this.reset();
|
|
1215
|
+
}
|
|
1216
|
+
submitGroup() {
|
|
1217
|
+
if (this.creatingGroup() && this.groupForm) {
|
|
1218
|
+
this.form().createGroup(this.groupForm);
|
|
1219
|
+
}
|
|
1220
|
+
this.dirty.set(true);
|
|
1221
|
+
this.reset();
|
|
1222
|
+
}
|
|
1223
|
+
cancel() {
|
|
1224
|
+
this.reset();
|
|
1225
|
+
}
|
|
1226
|
+
reset() {
|
|
1227
|
+
this.groupForm = null;
|
|
1228
|
+
this.creatingGroup.set(false);
|
|
1229
|
+
this.editingGroup.set(-1);
|
|
1230
|
+
}
|
|
1231
|
+
onSubmit() {
|
|
1232
|
+
this.submitted.emit();
|
|
1233
|
+
this.dirty.set(false);
|
|
1234
|
+
}
|
|
1235
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: DynamicFormBuilderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1236
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: DynamicFormBuilderComponent, isStandalone: true, selector: "lib-dynamic-form-builder", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null }, handleSubmit: { classPropertyName: "handleSubmit", publicName: "handleSubmit", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { submitted: "submitted" }, ngImport: i0, template: "<h2>Groups</h2>\n\n@if(groupForm)\n{\n<lib-form-group-edit [form]=\"groupForm\" [create]=\"creatingGroup()\" (cancelled)=\"cancel()\" (submitted)=\"submitGroup()\">\n</lib-form-group-edit>\n}\n@else {\n<lib-form-group-list [form]=\"form().groups\" (edit)=\"editGroup($event)\" (add)=\"addGroup()\"\n (delete)=\"deleteGroup($event)\"></lib-form-group-list>\n}\n\n@if(handleSubmit() && dirty())\n{\n <div>\n <button mat-fab class=\"form-action-button\" \n type=\"button\" matTooltip=\"Save Changes\" (click)=\"onSubmit()\">\n <mat-icon>save</mat-icon>\n </button>\n </div>\n}", styles: [""], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: FormGroupEditComponent, selector: "lib-form-group-edit", inputs: ["create", "form"], outputs: ["cancelled", "submitted"] }, { kind: "component", type: FormGroupListComponent, selector: "lib-form-group-list", inputs: ["form"], outputs: ["edit", "delete", "orderUp", "orderDown", "add"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
1237
|
+
}
|
|
1238
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: DynamicFormBuilderComponent, decorators: [{
|
|
1239
|
+
type: Component,
|
|
1240
|
+
args: [{ selector: 'lib-dynamic-form-builder', imports: [
|
|
1241
|
+
MatIconModule,
|
|
1242
|
+
MatFormFieldModule,
|
|
1243
|
+
ReactiveFormsModule,
|
|
1244
|
+
MatButtonModule, FormGroupEditComponent, FormGroupListComponent, MatTooltipModule
|
|
1245
|
+
], template: "<h2>Groups</h2>\n\n@if(groupForm)\n{\n<lib-form-group-edit [form]=\"groupForm\" [create]=\"creatingGroup()\" (cancelled)=\"cancel()\" (submitted)=\"submitGroup()\">\n</lib-form-group-edit>\n}\n@else {\n<lib-form-group-list [form]=\"form().groups\" (edit)=\"editGroup($event)\" (add)=\"addGroup()\"\n (delete)=\"deleteGroup($event)\"></lib-form-group-list>\n}\n\n@if(handleSubmit() && dirty())\n{\n <div>\n <button mat-fab class=\"form-action-button\" \n type=\"button\" matTooltip=\"Save Changes\" (click)=\"onSubmit()\">\n <mat-icon>save</mat-icon>\n </button>\n </div>\n}" }]
|
|
1246
|
+
}] });
|
|
1247
|
+
|
|
1248
|
+
class DynamicFormForm {
|
|
1249
|
+
fb = inject(FormBuilder);
|
|
1250
|
+
form;
|
|
1251
|
+
constructor() {
|
|
1252
|
+
this.form = this.fb.group({
|
|
1253
|
+
groups: this.fb.array([])
|
|
1254
|
+
});
|
|
1255
|
+
}
|
|
1256
|
+
get groups() {
|
|
1257
|
+
return this.form.get('groups');
|
|
1258
|
+
}
|
|
1259
|
+
createGroup(group) {
|
|
1260
|
+
group.patchValue({ order: this.groups.controls.length });
|
|
1261
|
+
this.groups.push(group);
|
|
1262
|
+
}
|
|
1263
|
+
deleteGroup(id) {
|
|
1264
|
+
this.groups.removeAt(id);
|
|
1265
|
+
}
|
|
1266
|
+
reset() {
|
|
1267
|
+
this.form = this.fb.group({
|
|
1268
|
+
groups: this.fb.array([])
|
|
1269
|
+
});
|
|
1270
|
+
}
|
|
1271
|
+
setValue(item) {
|
|
1272
|
+
this.groups.clear();
|
|
1273
|
+
item.groups.map(g => this.groups.push(FormGroupForm.fromItem(g, this.fb)));
|
|
1274
|
+
}
|
|
1275
|
+
createItem() {
|
|
1276
|
+
return {
|
|
1277
|
+
groups: Array.from(this.groups.controls.map(g => FormGroupForm.createItem(g)))
|
|
1278
|
+
};
|
|
1279
|
+
}
|
|
1280
|
+
createOrUpdateGroup(form, items) {
|
|
1281
|
+
if (form.value.id && form.value.id >= 0) {
|
|
1282
|
+
const matching_item = items.find(item => "id" in item && item.id == form.value.id);
|
|
1283
|
+
return FormGroupForm.updateItem(form, matching_item);
|
|
1284
|
+
}
|
|
1285
|
+
return FormGroupForm.createItem(form);
|
|
1286
|
+
}
|
|
1287
|
+
updateItem(item) {
|
|
1288
|
+
const item_update = item;
|
|
1289
|
+
item_update.groups = Array.from(this.groups.controls.map(f => this.createOrUpdateGroup(f, item.groups)));
|
|
1290
|
+
return item_update;
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
|
|
820
1294
|
class SelectTableComponent {
|
|
821
1295
|
itemType = input("", ...(ngDevMode ? [{ debugName: "itemType" }] : []));
|
|
822
1296
|
selected = input([], ...(ngDevMode ? [{ debugName: "selected" }] : []));
|
|
@@ -843,7 +1317,7 @@ class SelectTableComponent {
|
|
|
843
1317
|
this.table()?.renderRows();
|
|
844
1318
|
}
|
|
845
1319
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: SelectTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
846
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: SelectTableComponent, isStandalone: true, selector: "lib-select-table", inputs: { itemType: { classPropertyName: "itemType", publicName: "itemType", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemAdded: "itemAdded", itemRemoved: "itemRemoved", searchChanged: "searchChanged" }, viewQueries: [{ propertyName: "table", first: true, predicate: MatTable, descendants: true, isSignal: true }], ngImport: i0, template: "<div class='select-container'>\n <div>\n <mat-form-field>\n <mat-label>Add {{itemType()}}</mat-label>\n <input \n type=\"text\"\n aria-label=\"Selected item\"\n matInput\n [formControl]=\"searchControl\" \n [matAutocomplete]=\"auto\">\n\n <mat-autocomplete #auto=\"matAutocomplete\">\n @for(item of options(); track item.item.id){\n <mat-option [value]=\"item.title\">{{item.title}}\n </mat-option>\n }\n </mat-autocomplete>\n </mat-form-field>\n\n <button mat-mini-fab type=\"button\" class=\"form_action_button\" (click)=\"add()\">\n <mat-icon>add\n </mat-icon>\n </button>\n </div>\n\n @if(selected().length > 0){\n <table mat-table [dataSource]=\"selected()\" class=\"mat-elevation-z8\">\n @for (column of columns(); track column.name) {\n <ng-container matColumnDef=\"{{ column.name }}\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>\n {{ column.title }}\n </th>\n <td mat-cell *matCellDef=\"let element\">{{ element[column.name] }}</td>\n </ng-container>\n }\n\n <ng-container matColumnDef=\"remove\">\n <th mat-header-cell *matHeaderCellDef>Remove\n </th>\n <td mat-cell *matCellDef=\"let element\">\n <button mat-icon-button\n color=\"primary\"\n aria-label=\"Remove an item\"\n (click)=\"remove(element.id)\">\n <mat-icon>remove\n </mat-icon>\n </button>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"columnNames()\">\n </tr>\n <tr mat-row *matRowDef=\"let row; columns: columnNames();\">\n </tr>\n </table>\n }\n</div>", styles: [".select-container,.table_container{display:flex;text-align:center;justify-content:center;flex-direction:column}.form_action_button{padding:5px;margin:5px}\n"], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$
|
|
1320
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: SelectTableComponent, isStandalone: true, selector: "lib-select-table", inputs: { itemType: { classPropertyName: "itemType", publicName: "itemType", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemAdded: "itemAdded", itemRemoved: "itemRemoved", searchChanged: "searchChanged" }, viewQueries: [{ propertyName: "table", first: true, predicate: MatTable, descendants: true, isSignal: true }], ngImport: i0, template: "<div class='select-container'>\n <div>\n <mat-form-field>\n <mat-label>Add {{itemType()}}</mat-label>\n <input \n type=\"text\"\n aria-label=\"Selected item\"\n matInput\n [formControl]=\"searchControl\" \n [matAutocomplete]=\"auto\">\n\n <mat-autocomplete #auto=\"matAutocomplete\">\n @for(item of options(); track item.item.id){\n <mat-option [value]=\"item.title\">{{item.title}}\n </mat-option>\n }\n </mat-autocomplete>\n </mat-form-field>\n\n <button mat-mini-fab type=\"button\" class=\"form_action_button\" (click)=\"add()\">\n <mat-icon>add\n </mat-icon>\n </button>\n </div>\n\n @if(selected().length > 0){\n <table mat-table [dataSource]=\"selected()\" class=\"mat-elevation-z8\">\n @for (column of columns(); track column.name) {\n <ng-container matColumnDef=\"{{ column.name }}\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>\n {{ column.title }}\n </th>\n <td mat-cell *matCellDef=\"let element\">{{ element[column.name] }}</td>\n </ng-container>\n }\n\n <ng-container matColumnDef=\"remove\">\n <th mat-header-cell *matHeaderCellDef>Remove\n </th>\n <td mat-cell *matCellDef=\"let element\">\n <button mat-icon-button\n color=\"primary\"\n aria-label=\"Remove an item\"\n (click)=\"remove(element.id)\">\n <mat-icon>remove\n </mat-icon>\n </button>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"columnNames()\">\n </tr>\n <tr mat-row *matRowDef=\"let row; columns: columnNames();\">\n </tr>\n </table>\n }\n</div>", styles: [".select-container,.table_container{display:flex;text-align:center;justify-content:center;flex-direction:column}.form_action_button{padding:5px;margin:5px}\n"], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$5.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$5.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$5.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$5.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$5.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$5.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$5.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$5.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$5.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$5.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i6$1.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i6$1.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }] });
|
|
847
1321
|
}
|
|
848
1322
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: SelectTableComponent, decorators: [{
|
|
849
1323
|
type: Component,
|
|
@@ -857,6 +1331,50 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
857
1331
|
MatInputModule], template: "<div class='select-container'>\n <div>\n <mat-form-field>\n <mat-label>Add {{itemType()}}</mat-label>\n <input \n type=\"text\"\n aria-label=\"Selected item\"\n matInput\n [formControl]=\"searchControl\" \n [matAutocomplete]=\"auto\">\n\n <mat-autocomplete #auto=\"matAutocomplete\">\n @for(item of options(); track item.item.id){\n <mat-option [value]=\"item.title\">{{item.title}}\n </mat-option>\n }\n </mat-autocomplete>\n </mat-form-field>\n\n <button mat-mini-fab type=\"button\" class=\"form_action_button\" (click)=\"add()\">\n <mat-icon>add\n </mat-icon>\n </button>\n </div>\n\n @if(selected().length > 0){\n <table mat-table [dataSource]=\"selected()\" class=\"mat-elevation-z8\">\n @for (column of columns(); track column.name) {\n <ng-container matColumnDef=\"{{ column.name }}\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>\n {{ column.title }}\n </th>\n <td mat-cell *matCellDef=\"let element\">{{ element[column.name] }}</td>\n </ng-container>\n }\n\n <ng-container matColumnDef=\"remove\">\n <th mat-header-cell *matHeaderCellDef>Remove\n </th>\n <td mat-cell *matCellDef=\"let element\">\n <button mat-icon-button\n color=\"primary\"\n aria-label=\"Remove an item\"\n (click)=\"remove(element.id)\">\n <mat-icon>remove\n </mat-icon>\n </button>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"columnNames()\">\n </tr>\n <tr mat-row *matRowDef=\"let row; columns: columnNames();\">\n </tr>\n </table>\n }\n</div>", styles: [".select-container,.table_container{display:flex;text-align:center;justify-content:center;flex-direction:column}.form_action_button{padding:5px;margin:5px}\n"] }]
|
|
858
1332
|
}] });
|
|
859
1333
|
|
|
1334
|
+
const USER_TABLE_FULL = [
|
|
1335
|
+
{ name: 'first_name', title: 'First Name', element_type: 'string' },
|
|
1336
|
+
{ name: 'last_name', title: 'Surname', element_type: 'string' },
|
|
1337
|
+
{ name: 'username', title: 'Username', element_type: 'string' },
|
|
1338
|
+
{ name: 'email', title: 'Email', element_type: 'email' }
|
|
1339
|
+
];
|
|
1340
|
+
|
|
1341
|
+
class SelectionManager {
|
|
1342
|
+
candidates = signal([], ...(ngDevMode ? [{ debugName: "candidates" }] : []));
|
|
1343
|
+
selected = signal([], ...(ngDevMode ? [{ debugName: "selected" }] : []));
|
|
1344
|
+
columns = USER_TABLE_FULL;
|
|
1345
|
+
userService = inject(UserService);
|
|
1346
|
+
fetchCandidates(item, id) {
|
|
1347
|
+
const queries = new Map([[item, id.toString()]]);
|
|
1348
|
+
const query = new ItemQuery({ queries: queries });
|
|
1349
|
+
this.userService.get(query).subscribe(users => this.selected.set(users.results));
|
|
1350
|
+
this.userService.get().subscribe(users => this.updateCandidates(users));
|
|
1351
|
+
}
|
|
1352
|
+
updateCandidates(users) {
|
|
1353
|
+
this.candidates.set(users.results.map(user => { return { title: user.username, item: user }; }));
|
|
1354
|
+
}
|
|
1355
|
+
onRemoved(id) {
|
|
1356
|
+
const url = this.selected().find(m => m.id == id).url;
|
|
1357
|
+
this.selected.update(members => members.filter(m => m.id != id));
|
|
1358
|
+
return url;
|
|
1359
|
+
}
|
|
1360
|
+
onAdded(title) {
|
|
1361
|
+
const selected = this.candidates().find(m => m.title == title);
|
|
1362
|
+
if (selected) {
|
|
1363
|
+
this.selected.update(members => { members.push(selected.item); return members; });
|
|
1364
|
+
}
|
|
1365
|
+
this.candidates.update(members => members.filter(m => m.title != title));
|
|
1366
|
+
return this.selected().find(m => m.username == title).url;
|
|
1367
|
+
}
|
|
1368
|
+
onSearchChanged(searchTerm) {
|
|
1369
|
+
if (searchTerm) {
|
|
1370
|
+
this.userService.get(new ItemQuery({ filter: searchTerm })).subscribe(users => this.updateCandidates(users));
|
|
1371
|
+
}
|
|
1372
|
+
else {
|
|
1373
|
+
this.userService.get().subscribe(users => this.updateCandidates(users));
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
|
|
860
1378
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
861
1379
|
class ListTableViewComponent {
|
|
862
1380
|
itemType = input("", ...(ngDevMode ? [{ debugName: "itemType" }] : []));
|
|
@@ -902,7 +1420,7 @@ class ListTableViewComponent {
|
|
|
902
1420
|
}));
|
|
903
1421
|
}
|
|
904
1422
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ListTableViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
905
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: ListTableViewComponent, isStandalone: true, selector: "lib-list-table-view", inputs: { itemType: { classPropertyName: "itemType", publicName: "itemType", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: false, transformFunction: null }, searchFilter: { classPropertyName: "searchFilter", publicName: "searchFilter", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "sort", first: true, predicate: MatSort, descendants: true, isSignal: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true, isSignal: true }], ngImport: i0, template: "@if (dataSource(); as dataSource) {\n <table\n mat-table\n [dataSource]=\"dataSource\"\n matSort\n matSortActive=\"name\"\n matSortDisableClear\n matSortDirection=\"desc\"\n class=\"mat-elevation-z8\"\n >\n @for (column of columns(); track column.name) {\n <ng-container matColumnDef=\"{{ column.name }}\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>\n {{ column.title }}\n </th>\n <td mat-cell *matCellDef=\"let element\">{{ element[column.name] }}</td>\n </ng-container>\n }\n\n <tr mat-header-row *matHeaderRowDef=\"columnNames()\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: columnNames()\"\n [routerLink]=\"['/' + itemType() + '/detail/', row.id]\"\n [routerLinkActive]=\"['is-active']\"\n ></tr>\n </table>\n\n <mat-paginator\n [length]=\"dataSource.length()\"\n [pageSize]=\"20\"\n [pageSizeOptions]=\"pageSizeOptions\"\n aria-label=\"Select page\"\n >\n </mat-paginator>\n}\n", styles: [".mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.is-active{font-weight:700}\n"], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$
|
|
1423
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: ListTableViewComponent, isStandalone: true, selector: "lib-list-table-view", inputs: { itemType: { classPropertyName: "itemType", publicName: "itemType", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: false, transformFunction: null }, searchFilter: { classPropertyName: "searchFilter", publicName: "searchFilter", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "sort", first: true, predicate: MatSort, descendants: true, isSignal: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true, isSignal: true }], ngImport: i0, template: "@if (dataSource(); as dataSource) {\n <table\n mat-table\n [dataSource]=\"dataSource\"\n matSort\n matSortActive=\"name\"\n matSortDisableClear\n matSortDirection=\"desc\"\n class=\"mat-elevation-z8\"\n >\n @for (column of columns(); track column.name) {\n <ng-container matColumnDef=\"{{ column.name }}\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>\n {{ column.title }}\n </th>\n <td mat-cell *matCellDef=\"let element\">{{ element[column.name] }}</td>\n </ng-container>\n }\n\n <tr mat-header-row *matHeaderRowDef=\"columnNames()\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: columnNames()\"\n [routerLink]=\"['/' + itemType() + '/detail/', row.id]\"\n [routerLinkActive]=\"['is-active']\"\n ></tr>\n </table>\n\n <mat-paginator\n [length]=\"dataSource.length()\"\n [pageSize]=\"20\"\n [pageSizeOptions]=\"pageSizeOptions\"\n aria-label=\"Select page\"\n >\n </mat-paginator>\n}\n", styles: [".mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.is-active{font-weight:700}\n"], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$5.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$5.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$5.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$5.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$5.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$5.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$5.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$5.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$5.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$5.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i2$4.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "directive", type: i3$1.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i3$1.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i1.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }] });
|
|
906
1424
|
}
|
|
907
1425
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ListTableViewComponent, decorators: [{
|
|
908
1426
|
type: Component,
|
|
@@ -934,7 +1452,7 @@ class ListScrollViewComponent {
|
|
|
934
1452
|
data_source.reset(this.searchTerm(), this.pageSize());
|
|
935
1453
|
}
|
|
936
1454
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ListScrollViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
937
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.1.1", type: ListScrollViewComponent, isStandalone: true, selector: "lib-list-scroll-view", inputs: { searchTerm: { classPropertyName: "searchTerm", publicName: "searchTerm", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: false, transformFunction: null }, listItemTemplate: { classPropertyName: "listItemTemplate", publicName: "listItemTemplate", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mat-nav-list>\n <cdk-virtual-scroll-viewport\n itemSize=\"150\"\n class=\"scrollable-list\"\n style=\"height: 600px; width: 500px\"\n >\n <ng-container *cdkVirtualFor=\"let item of dataSource()\">\n <ng-container\n *ngTemplateOutlet=\"listItemTemplate(); context: { item: item }\"\n >\n </ng-container>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n</mat-nav-list>\n", styles: [":host{flex-grow:1}.mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.is-active{font-weight:700}\n"], dependencies: [{ kind: "ngmodule", type: MatListModule }, { kind: "component", type: i2$2.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i2$
|
|
1455
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.1.1", type: ListScrollViewComponent, isStandalone: true, selector: "lib-list-scroll-view", inputs: { searchTerm: { classPropertyName: "searchTerm", publicName: "searchTerm", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: false, transformFunction: null }, listItemTemplate: { classPropertyName: "listItemTemplate", publicName: "listItemTemplate", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mat-nav-list>\n <cdk-virtual-scroll-viewport\n itemSize=\"150\"\n class=\"scrollable-list\"\n style=\"height: 600px; width: 500px\"\n >\n <ng-container *cdkVirtualFor=\"let item of dataSource()\">\n <ng-container\n *ngTemplateOutlet=\"listItemTemplate(); context: { item: item }\"\n >\n </ng-container>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n</mat-nav-list>\n", styles: [":host{flex-grow:1}.mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.is-active{font-weight:700}\n"], dependencies: [{ kind: "ngmodule", type: MatListModule }, { kind: "component", type: i2$2.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i2$5.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i2$5.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i2$5.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }] });
|
|
938
1456
|
}
|
|
939
1457
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ListScrollViewComponent, decorators: [{
|
|
940
1458
|
type: Component,
|
|
@@ -949,7 +1467,7 @@ class BackButtonComponent {
|
|
|
949
1467
|
this.location.back();
|
|
950
1468
|
}
|
|
951
1469
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: BackButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
952
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.1", type: BackButtonComponent, isStandalone: true, selector: "lib-back-button", ngImport: i0, template: "<a mat-icon-button class=\"padded-button\"\n (click)=\"goBack()\"\n (keydown)=\"goBack()\"\n tabindex=\"0\"\n role=\"button\">\n<mat-icon>arrow_back</mat-icon>\n</a>\n\n", styles: [".padded-button{margin:5px}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type:
|
|
1470
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.1", type: BackButtonComponent, isStandalone: true, selector: "lib-back-button", ngImport: i0, template: "<a mat-icon-button class=\"padded-button\"\n (click)=\"goBack()\"\n (keydown)=\"goBack()\"\n tabindex=\"0\"\n role=\"button\">\n<mat-icon>arrow_back</mat-icon>\n</a>\n\n", styles: [".padded-button{margin:5px}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }] });
|
|
953
1471
|
}
|
|
954
1472
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: BackButtonComponent, decorators: [{
|
|
955
1473
|
type: Component,
|
|
@@ -974,7 +1492,7 @@ class SearchBarComponent {
|
|
|
974
1492
|
this.searchChanged.emit(this.searchFilter.value);
|
|
975
1493
|
}
|
|
976
1494
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: SearchBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
977
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: SearchBarComponent, isStandalone: true, selector: "lib-search-bar", inputs: { itemType: { classPropertyName: "itemType", publicName: "itemType", isSignal: true, isRequired: false, transformFunction: null }, sortFields: { classPropertyName: "sortFields", publicName: "sortFields", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchChanged: "searchChanged" }, ngImport: i0, template: "<div class=\"container\">\n <mat-form-field class=\"search\" style=\"margin: 10px;\">\n <mat-label>Search</mat-label>\n <input matInput [formControl]=\"searchFilter\" placeholder=\"Search {{ itemType() | titlecase }}\" />\n\n @if(searchFilter.value){\n <button matSuffix mat-icon-button aria-label=\"Cancel\" (click)=\"clearSearch()\">\n <mat-icon>cancel</mat-icon>\n </button>\n }\n @else(){\n <button matSuffix mat-icon-button aria-label=\"Search\">\n <mat-icon>search</mat-icon>\n </button>\n }\n </mat-form-field>\n\n @if(sortFields().length > 0){\n <mat-form-field style=\"margin: 10px\">\n <mat-label>Sort By</mat-label>\n <mat-select>\n @for(field of sortFields(); track field)\n {\n <mat-option>{{field}}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n <button mat-icon-button aria-label=\"Sort Order\" matTooltip=\"Toggle sort order\">\n <mat-icon>sort</mat-icon>\n </button>\n }\n</div>", styles: [".container{width:100%;display:flex;flex-wrap:wrap;flex-direction:row;align-items:center;justify-content:center}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$
|
|
1495
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: SearchBarComponent, isStandalone: true, selector: "lib-search-bar", inputs: { itemType: { classPropertyName: "itemType", publicName: "itemType", isSignal: true, isRequired: false, transformFunction: null }, sortFields: { classPropertyName: "sortFields", publicName: "sortFields", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchChanged: "searchChanged" }, ngImport: i0, template: "<div class=\"container\">\n <mat-form-field class=\"search\" style=\"margin: 10px;\">\n <mat-label>Search</mat-label>\n <input matInput [formControl]=\"searchFilter\" placeholder=\"Search {{ itemType() | titlecase }}\" />\n\n @if(searchFilter.value){\n <button matSuffix mat-icon-button aria-label=\"Cancel\" (click)=\"clearSearch()\">\n <mat-icon>cancel</mat-icon>\n </button>\n }\n @else(){\n <button matSuffix mat-icon-button aria-label=\"Search\">\n <mat-icon>search</mat-icon>\n </button>\n }\n </mat-form-field>\n\n @if(sortFields().length > 0){\n <mat-form-field style=\"margin: 10px\">\n <mat-label>Sort By</mat-label>\n <mat-select>\n @for(field of sortFields(); track field)\n {\n <mat-option>{{field}}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n <button mat-icon-button aria-label=\"Sort Order\" matTooltip=\"Toggle sort order\">\n <mat-icon>sort</mat-icon>\n </button>\n }\n</div>", styles: [".container{width:100%;display:flex;flex-wrap:wrap;flex-direction:row;align-items:center;justify-content:center}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i2$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }] });
|
|
978
1496
|
}
|
|
979
1497
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: SearchBarComponent, decorators: [{
|
|
980
1498
|
type: Component,
|
|
@@ -1001,7 +1519,6 @@ class ListDataSource extends DataSource {
|
|
|
1001
1519
|
fetchedPages = new Set();
|
|
1002
1520
|
constructor(itemService, consumerType = "table") {
|
|
1003
1521
|
super();
|
|
1004
|
-
console.log("created");
|
|
1005
1522
|
this.itemService = itemService;
|
|
1006
1523
|
this.consumerType = consumerType;
|
|
1007
1524
|
}
|
|
@@ -1134,7 +1651,7 @@ class ListViewComponent {
|
|
|
1134
1651
|
return (url_segments.length == 2) && (url_segments[1].path == "self");
|
|
1135
1652
|
}
|
|
1136
1653
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ListViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1137
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: ListViewComponent, isStandalone: true, selector: "lib-list-view", inputs: { viewType: { classPropertyName: "viewType", publicName: "viewType", isSignal: true, isRequired: false, transformFunction: null }, itemService: { classPropertyName: "itemService", publicName: "itemService", isSignal: true, isRequired: false, transformFunction: null }, itemDetailTemplate: { classPropertyName: "itemDetailTemplate", publicName: "itemDetailTemplate", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, sortFields: { classPropertyName: "sortFields", publicName: "sortFields", isSignal: true, isRequired: false, transformFunction: null }, noSelfItemsMessage: { classPropertyName: "noSelfItemsMessage", publicName: "noSelfItemsMessage", isSignal: true, isRequired: false, transformFunction: null }, noItemsCanCreateMessage: { classPropertyName: "noItemsCanCreateMessage", publicName: "noItemsCanCreateMessage", isSignal: true, isRequired: false, transformFunction: null }, noItemsMessage: { classPropertyName: "noItemsMessage", publicName: "noItemsMessage", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "sort", first: true, predicate: MatSort, descendants: true, isSignal: true }], ngImport: i0, template: "<lib-back-button></lib-back-button>\n\n<div class=\"container\">\n <div class=\"header\">\n <h1 class=\"title\">{{ title() | titlecase }}</h1>\n\n @if (canCreate()) {\n <div class=\"button-container\">\n <a mat-fab class=\"padded-button\" aria-label=\"Add new item\" matTooltip=\"Add new item\" [routerLink]=\"['create']\">\n <mat-icon>add</mat-icon></a>\n </div>\n }\n </div>\n\n @if(dataSource)\n {\n <div class=\"controls\" [hidden]=\"dataSource.sourceIsEmpty()\">\n <lib-search-bar [itemType]=\"title()\" [sortFields]=\"sortFields()\"\n (searchChanged)=\"onSearchChange($event)\"></lib-search-bar>\n\n @if(itemDetailTemplate()){\n <div style=\"margin: 10px\">\n <mat-button-toggle-group name=\"viewType\" aria-label=\"View Type\" [value]=\"selectedViewType()\"\n (change)=\"viewChanged($event)\">\n\n <mat-button-toggle value=\"table\" matTooltip=\"Show as table\">\n <mat-icon>table_view</mat-icon>\n </mat-button-toggle>\n\n <mat-button-toggle value=\"scroll\" matTooltip=\"Show as list\">\n <mat-icon>list</mat-icon>\n </mat-button-toggle>\n\n </mat-button-toggle-group>\n </div>\n }\n </div>\n\n @if (dataSource.loading()) {\n <div class=\"spinner-container\">\n <mat-spinner></mat-spinner>\n </div>\n }\n\n <div [hidden]=\"!dataSource.sourceIsEmpty()\">\n @if(isSelfList())\n {\n @if(noSelfItemsMessage())\n {\n <p>{{noSelfItemsMessage()}}</p>\n }\n @else {\n <p>You do not have any {{itemType()}}.</p> \n }\n }\n @else{\n @if(canCreate()){\n @if(noItemsCanCreateMessage())\n {\n <p>{{noItemsCanCreateMessage()}}</p>\n }\n @else{\n <p>There are currently no {{itemType()}}, click above to add one.</p>\n }\n }\n @else{\n @if(noItemsMessage())\n {\n <p>{{noItemsMessage()}}</p>\n }\n @else\n {\n <p>There are currently no {{itemType()}}.</p>\n }\n }\n }\n </div>\n\n <div [hidden]=\"dataSource.sourceIsEmpty()\">\n @if(isTableView()) {\n <lib-list-table-view [itemType]=\"itemType()\" [columns]=\"columns()\" [dataSource]=\"dataSource\">\n </lib-list-table-view>\n } \n @else {\n <lib-list-scroll-view [listItemTemplate]=\"itemDetailTemplate()\" [dataSource]=\"dataSource\"></lib-list-scroll-view>\n }\n\n </div>\n }\n</div>", styles: [":host{flex-grow:1}.container{display:flex;padding:10px;flex-direction:column;justify-content:center;text-align:center;align-items:center}.header{display:flex;flex-direction:row;align-items:center;justify-content:center}.title{text-align:center;padding:10px}.controls{display:flex;align-items:center;justify-content:center;flex-wrap:wrap}.hide-element{display:none}\n"], dependencies: [{ kind: "component", type: ListTableViewComponent, selector: "lib-list-table-view", inputs: ["itemType", "columns", "dataSource", "searchFilter"] }, { kind: "component", type: ListScrollViewComponent, selector: "lib-list-scroll-view", inputs: ["searchTerm", "pageSize", "dataSource", "listItemTemplate"] }, { kind: "component", type: BackButtonComponent, selector: "lib-back-button" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i1$
|
|
1654
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: ListViewComponent, isStandalone: true, selector: "lib-list-view", inputs: { viewType: { classPropertyName: "viewType", publicName: "viewType", isSignal: true, isRequired: false, transformFunction: null }, itemService: { classPropertyName: "itemService", publicName: "itemService", isSignal: true, isRequired: false, transformFunction: null }, itemDetailTemplate: { classPropertyName: "itemDetailTemplate", publicName: "itemDetailTemplate", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, sortFields: { classPropertyName: "sortFields", publicName: "sortFields", isSignal: true, isRequired: false, transformFunction: null }, noSelfItemsMessage: { classPropertyName: "noSelfItemsMessage", publicName: "noSelfItemsMessage", isSignal: true, isRequired: false, transformFunction: null }, noItemsCanCreateMessage: { classPropertyName: "noItemsCanCreateMessage", publicName: "noItemsCanCreateMessage", isSignal: true, isRequired: false, transformFunction: null }, noItemsMessage: { classPropertyName: "noItemsMessage", publicName: "noItemsMessage", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "sort", first: true, predicate: MatSort, descendants: true, isSignal: true }], ngImport: i0, template: "<lib-back-button></lib-back-button>\n\n<div class=\"container\">\n <div class=\"header\">\n <h1 class=\"title\">{{ title() | titlecase }}</h1>\n\n @if (canCreate()) {\n <div class=\"button-container\">\n <a mat-fab class=\"padded-button\" aria-label=\"Add new item\" matTooltip=\"Add new item\" [routerLink]=\"['create']\">\n <mat-icon>add</mat-icon></a>\n </div>\n }\n </div>\n\n @if(dataSource)\n {\n <div class=\"controls\" [hidden]=\"dataSource.sourceIsEmpty()\">\n <lib-search-bar [itemType]=\"title()\" [sortFields]=\"sortFields()\"\n (searchChanged)=\"onSearchChange($event)\"></lib-search-bar>\n\n @if(itemDetailTemplate()){\n <div style=\"margin: 10px\">\n <mat-button-toggle-group name=\"viewType\" aria-label=\"View Type\" [value]=\"selectedViewType()\"\n (change)=\"viewChanged($event)\">\n\n <mat-button-toggle value=\"table\" matTooltip=\"Show as table\">\n <mat-icon>table_view</mat-icon>\n </mat-button-toggle>\n\n <mat-button-toggle value=\"scroll\" matTooltip=\"Show as list\">\n <mat-icon>list</mat-icon>\n </mat-button-toggle>\n\n </mat-button-toggle-group>\n </div>\n }\n </div>\n\n @if (dataSource.loading()) {\n <div class=\"spinner-container\">\n <mat-spinner></mat-spinner>\n </div>\n }\n\n <div [hidden]=\"!dataSource.sourceIsEmpty()\">\n @if(isSelfList())\n {\n @if(noSelfItemsMessage())\n {\n <p>{{noSelfItemsMessage()}}</p>\n }\n @else {\n <p>You do not have any {{itemType()}}.</p> \n }\n }\n @else{\n @if(canCreate()){\n @if(noItemsCanCreateMessage())\n {\n <p>{{noItemsCanCreateMessage()}}</p>\n }\n @else{\n <p>There are currently no {{itemType()}}, click above to add one.</p>\n }\n }\n @else{\n @if(noItemsMessage())\n {\n <p>{{noItemsMessage()}}</p>\n }\n @else\n {\n <p>There are currently no {{itemType()}}.</p>\n }\n }\n }\n </div>\n\n <div [hidden]=\"dataSource.sourceIsEmpty()\">\n @if(isTableView()) {\n <lib-list-table-view [itemType]=\"itemType()\" [columns]=\"columns()\" [dataSource]=\"dataSource\">\n </lib-list-table-view>\n } \n @else {\n <lib-list-scroll-view [listItemTemplate]=\"itemDetailTemplate()\" [dataSource]=\"dataSource\"></lib-list-scroll-view>\n }\n\n </div>\n }\n</div>", styles: [":host{flex-grow:1}.container{display:flex;padding:10px;flex-direction:column;justify-content:center;text-align:center;align-items:center}.header{display:flex;flex-direction:row;align-items:center;justify-content:center}.title{text-align:center;padding:10px}.controls{display:flex;align-items:center;justify-content:center;flex-wrap:wrap}.hide-element{display:none}\n"], dependencies: [{ kind: "component", type: ListTableViewComponent, selector: "lib-list-table-view", inputs: ["itemType", "columns", "dataSource", "searchFilter"] }, { kind: "component", type: ListScrollViewComponent, selector: "lib-list-scroll-view", inputs: ["searchTerm", "pageSize", "dataSource", "listItemTemplate"] }, { kind: "component", type: BackButtonComponent, selector: "lib-back-button" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i1$6.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i1$6.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i2$6.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: SearchBarComponent, selector: "lib-search-bar", inputs: ["itemType", "sortFields"], outputs: ["searchChanged"] }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }] });
|
|
1138
1655
|
}
|
|
1139
1656
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ListViewComponent, decorators: [{
|
|
1140
1657
|
type: Component,
|
|
@@ -1166,7 +1683,7 @@ class DetailHeaderComponent {
|
|
|
1166
1683
|
this.deleteClicked.emit();
|
|
1167
1684
|
}
|
|
1168
1685
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: DetailHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1169
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: DetailHeaderComponent, isStandalone: true, selector: "lib-detail-header", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null }, route: { classPropertyName: "route", publicName: "route", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, canDelete: { classPropertyName: "canDelete", publicName: "canDelete", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { deleteClicked: "deleteClicked" }, ngImport: i0, template: "<div class=\"container\">\n\n <h1 class=\"header\">{{text()}}</h1>\n\n <div class=\"controls\">\n @if(canEdit()){\n <a mat-mini-fab class=\"control-button\" matTooltip=\"Edit the item\" title=\"Click to edit this item\" aria-label=\"Click to edit this item\"\n [routerLink]=\"[fullRoute(), id()]\">\n <mat-icon>edit</mat-icon>\n </a>\n }\n\n @if(canDelete()){\n <button mat-mini-fab class=\"control-button\" (click)=\"deleteClick()\" matTooltip=\"Delete the item\" title=\"Click to delete this item\"\n aria-label=\"Click to delete this item\">\n <mat-icon>delete</mat-icon></button>\n }\n </div>\n\n</div>", styles: [".container{width:100%;max-width:500px;padding:5px}.header{width:100%;padding:5px;margin:5px}.controls{display:flex;flex-direction:row;align-content:center;justify-content:center}.control-button{padding:5px;margin:5px}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type:
|
|
1686
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: DetailHeaderComponent, isStandalone: true, selector: "lib-detail-header", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null }, route: { classPropertyName: "route", publicName: "route", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, canDelete: { classPropertyName: "canDelete", publicName: "canDelete", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { deleteClicked: "deleteClicked" }, ngImport: i0, template: "<div class=\"container\">\n\n <h1 class=\"header\">{{text()}}</h1>\n\n <div class=\"controls\">\n @if(canEdit()){\n <a mat-mini-fab class=\"control-button\" matTooltip=\"Edit the item\" title=\"Click to edit this item\" aria-label=\"Click to edit this item\"\n [routerLink]=\"[fullRoute(), id()]\">\n <mat-icon>edit</mat-icon>\n </a>\n }\n\n @if(canDelete()){\n <button mat-mini-fab class=\"control-button\" (click)=\"deleteClick()\" matTooltip=\"Delete the item\" title=\"Click to delete this item\"\n aria-label=\"Click to delete this item\">\n <mat-icon>delete</mat-icon></button>\n }\n </div>\n\n</div>", styles: [".container{width:100%;max-width:500px;padding:5px}.header{width:100%;padding:5px;margin:5px}.controls{display:flex;flex-direction:row;align-content:center;justify-content:center}.control-button{padding:5px;margin:5px}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
1170
1687
|
}
|
|
1171
1688
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: DetailHeaderComponent, decorators: [{
|
|
1172
1689
|
type: Component,
|
|
@@ -1175,49 +1692,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
1175
1692
|
MatIconModule, MatTooltipModule], template: "<div class=\"container\">\n\n <h1 class=\"header\">{{text()}}</h1>\n\n <div class=\"controls\">\n @if(canEdit()){\n <a mat-mini-fab class=\"control-button\" matTooltip=\"Edit the item\" title=\"Click to edit this item\" aria-label=\"Click to edit this item\"\n [routerLink]=\"[fullRoute(), id()]\">\n <mat-icon>edit</mat-icon>\n </a>\n }\n\n @if(canDelete()){\n <button mat-mini-fab class=\"control-button\" (click)=\"deleteClick()\" matTooltip=\"Delete the item\" title=\"Click to delete this item\"\n aria-label=\"Click to delete this item\">\n <mat-icon>delete</mat-icon></button>\n }\n </div>\n\n</div>", styles: [".container{width:100%;max-width:500px;padding:5px}.header{width:100%;padding:5px;margin:5px}.controls{display:flex;flex-direction:row;align-content:center;justify-content:center}.control-button{padding:5px;margin:5px}\n"] }]
|
|
1176
1693
|
}] });
|
|
1177
1694
|
|
|
1178
|
-
class FileUploadComponent {
|
|
1179
|
-
files = input([], ...(ngDevMode ? [{ debugName: "files" }] : []));
|
|
1180
|
-
previewLoaded = output();
|
|
1181
|
-
fileUploaded = output();
|
|
1182
|
-
clearLocal = output();
|
|
1183
|
-
onPreviewRead(name, content) {
|
|
1184
|
-
this.previewLoaded.emit({ name: name, content: content });
|
|
1185
|
-
}
|
|
1186
|
-
onFileUpload(name, event) {
|
|
1187
|
-
if (!event.target) {
|
|
1188
|
-
return;
|
|
1189
|
-
}
|
|
1190
|
-
const input_element = event.target;
|
|
1191
|
-
if (input_element.files && input_element.files.length > 0) {
|
|
1192
|
-
const file = input_element.files[0];
|
|
1193
|
-
this.fileUploaded.emit({ name: name, file: file });
|
|
1194
|
-
const record = this.files().find(f => f.name == name);
|
|
1195
|
-
if (record && record.file_type == "image") {
|
|
1196
|
-
this.readFile(name, file);
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
}
|
|
1200
|
-
readFile(name, file) {
|
|
1201
|
-
const reader = new FileReader();
|
|
1202
|
-
reader.readAsDataURL(file);
|
|
1203
|
-
reader.onload = () => {
|
|
1204
|
-
if (reader.result) {
|
|
1205
|
-
this.previewLoaded.emit({ name: name, content: reader.result });
|
|
1206
|
-
}
|
|
1207
|
-
;
|
|
1208
|
-
};
|
|
1209
|
-
}
|
|
1210
|
-
onClearLocal() {
|
|
1211
|
-
this.clearLocal.emit();
|
|
1212
|
-
}
|
|
1213
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FileUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1214
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: FileUploadComponent, isStandalone: true, selector: "lib-file-upload", inputs: { files: { classPropertyName: "files", publicName: "files", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { previewLoaded: "previewLoaded", fileUploaded: "fileUploaded", clearLocal: "clearLocal" }, ngImport: i0, template: "<div class=\"container\">\n @for( file of files(); track file.name)\n {\n @if (file.local)\n {\n <div class=\"image_holder\">\n <p>Update {{file.display_name}}</p>\n <img alt=\"{{file.display_name}}\" src=\"{{file.local}}\" style=\"height:120px;\">\n <button mat-mini-fab (click)=\"onClearLocal()\">\n <mat-icon>clear</mat-icon>\n </button>\n </div> \n }\n @else\n {\n @if (file.remote){\n <div class=\"image_holder\">\n <p>Update {{file.display_name}}</p>\n <img alt=\"{{file.display_name}}\" src=\"{{file.remote}}\" style=\"height:120px;\">\n </div>\n }\n @else {\n <div>\n <span>Upload a {{file.display_name}}</span>\n </div> \n }\n \n }\n\n <div class=\"button-row\">\n <button mat-mini-fab (click)=\"fileInput.click()\">\n <mat-icon>attachment</mat-icon>\n </button>\n <input hidden type=\"file\" #fileInput (change)=\"onFileUpload(file.name, $event)\"/>\n </div> \n } \n</div>\n", styles: [".container{padding:10px;display:flex;justify-content:center;text-align:center;flex-direction:column;max-width:300px}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }] });
|
|
1215
|
-
}
|
|
1216
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FileUploadComponent, decorators: [{
|
|
1217
|
-
type: Component,
|
|
1218
|
-
args: [{ selector: 'lib-file-upload', imports: [MatIconModule, MatButtonModule], template: "<div class=\"container\">\n @for( file of files(); track file.name)\n {\n @if (file.local)\n {\n <div class=\"image_holder\">\n <p>Update {{file.display_name}}</p>\n <img alt=\"{{file.display_name}}\" src=\"{{file.local}}\" style=\"height:120px;\">\n <button mat-mini-fab (click)=\"onClearLocal()\">\n <mat-icon>clear</mat-icon>\n </button>\n </div> \n }\n @else\n {\n @if (file.remote){\n <div class=\"image_holder\">\n <p>Update {{file.display_name}}</p>\n <img alt=\"{{file.display_name}}\" src=\"{{file.remote}}\" style=\"height:120px;\">\n </div>\n }\n @else {\n <div>\n <span>Upload a {{file.display_name}}</span>\n </div> \n }\n \n }\n\n <div class=\"button-row\">\n <button mat-mini-fab (click)=\"fileInput.click()\">\n <mat-icon>attachment</mat-icon>\n </button>\n <input hidden type=\"file\" #fileInput (change)=\"onFileUpload(file.name, $event)\"/>\n </div> \n } \n</div>\n", styles: [".container{padding:10px;display:flex;justify-content:center;text-align:center;flex-direction:column;max-width:300px}\n"] }]
|
|
1219
|
-
}] });
|
|
1220
|
-
|
|
1221
1695
|
class FileRecord {
|
|
1222
1696
|
name = "";
|
|
1223
1697
|
display_name = "";
|
|
@@ -1237,6 +1711,15 @@ class UserDetailComponent extends DetailView {
|
|
|
1237
1711
|
ngOnInit() {
|
|
1238
1712
|
this.onInit();
|
|
1239
1713
|
}
|
|
1714
|
+
canEdit() {
|
|
1715
|
+
if (!this.userService.loggedInUser) {
|
|
1716
|
+
return false;
|
|
1717
|
+
}
|
|
1718
|
+
if (this.item()?.id == this.userService.loggedInUser.value?.id) {
|
|
1719
|
+
return true;
|
|
1720
|
+
}
|
|
1721
|
+
return super.canEdit();
|
|
1722
|
+
}
|
|
1240
1723
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1241
1724
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: UserDetailComponent, isStandalone: true, selector: "lib-user-detail", usesInheritance: true, ngImport: i0, template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n @if(item(); as item){\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.username\"\n [id]=\"item.id\"\n [route]=\"itemService.typePlural()\"\n [canEdit]=\"canEdit()\"\n [canDelete]=\"canDelete()\"\n (onDelete)=\"onDelete()\"></lib-detail-header>\n\n @if(item.profile_url){\n <div class=\"image-holder\">\n <img alt=\"User Profile Image\" src=\"{{item.url}}{{item.profile_url}}\" style=\"height:120px;\">\n </div> \n }\n \n <div class=\"item-field\">\n <span><b>Email: </b></span>\n {{item.email}}\n </div>\n \n <div class=\"item-field\">\n <span><b>First Name: </b></span>\n {{item.first_name}}\n </div>\n \n <div class=\"item-field\">\n <span><b>Last Name: </b></span>\n {{item.last_name}}\n </div>\n \n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}\n"], dependencies: [{ kind: "component", type: BackButtonComponent, selector: "lib-back-button" }, { kind: "component", type: DetailHeaderComponent, selector: "lib-detail-header", inputs: ["id", "text", "route", "canEdit", "canDelete"], outputs: ["deleteClicked"] }] });
|
|
1242
1725
|
}
|
|
@@ -1246,12 +1729,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
1246
1729
|
DetailHeaderComponent], template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n @if(item(); as item){\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.username\"\n [id]=\"item.id\"\n [route]=\"itemService.typePlural()\"\n [canEdit]=\"canEdit()\"\n [canDelete]=\"canDelete()\"\n (onDelete)=\"onDelete()\"></lib-detail-header>\n\n @if(item.profile_url){\n <div class=\"image-holder\">\n <img alt=\"User Profile Image\" src=\"{{item.url}}{{item.profile_url}}\" style=\"height:120px;\">\n </div> \n }\n \n <div class=\"item-field\">\n <span><b>Email: </b></span>\n {{item.email}}\n </div>\n \n <div class=\"item-field\">\n <span><b>First Name: </b></span>\n {{item.first_name}}\n </div>\n \n <div class=\"item-field\">\n <span><b>Last Name: </b></span>\n {{item.last_name}}\n </div>\n \n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}\n"] }]
|
|
1247
1730
|
}], ctorParameters: () => [] });
|
|
1248
1731
|
|
|
1249
|
-
class
|
|
1250
|
-
files = signal([new FileRecord({
|
|
1251
|
-
name: "image",
|
|
1252
|
-
display_name: "Profile Image",
|
|
1253
|
-
file_type: "image"
|
|
1254
|
-
})], ...(ngDevMode ? [{ debugName: "files" }] : []));
|
|
1732
|
+
class UserForm {
|
|
1255
1733
|
formBuilder = inject(FormBuilder);
|
|
1256
1734
|
form = this.formBuilder.group({
|
|
1257
1735
|
username: [''],
|
|
@@ -1260,17 +1738,7 @@ class UserEditComponent extends EditView {
|
|
|
1260
1738
|
last_name: [''],
|
|
1261
1739
|
phone: ['']
|
|
1262
1740
|
});
|
|
1263
|
-
|
|
1264
|
-
super(inject(UserService));
|
|
1265
|
-
}
|
|
1266
|
-
ngOnInit() {
|
|
1267
|
-
this.onInit();
|
|
1268
|
-
}
|
|
1269
|
-
onItemAvailable() {
|
|
1270
|
-
const item = this.item();
|
|
1271
|
-
if (!item) {
|
|
1272
|
-
return;
|
|
1273
|
-
}
|
|
1741
|
+
setValue(item) {
|
|
1274
1742
|
this.form.setValue({
|
|
1275
1743
|
username: item.username,
|
|
1276
1744
|
email: item.email,
|
|
@@ -1278,31 +1746,55 @@ class UserEditComponent extends EditView {
|
|
|
1278
1746
|
last_name: item.last_name,
|
|
1279
1747
|
phone: item.phone
|
|
1280
1748
|
});
|
|
1749
|
+
}
|
|
1750
|
+
createItem() {
|
|
1751
|
+
const value = this.form.value;
|
|
1752
|
+
return {
|
|
1753
|
+
username: value.username || "",
|
|
1754
|
+
email: value.email || "",
|
|
1755
|
+
first_name: value.first_name || "",
|
|
1756
|
+
last_name: value.last_name || "",
|
|
1757
|
+
phone: value.phone || ""
|
|
1758
|
+
};
|
|
1759
|
+
}
|
|
1760
|
+
updateItem(item) {
|
|
1761
|
+
const value = this.form.value;
|
|
1762
|
+
item.username = value.username || "";
|
|
1763
|
+
item.email = value.email || "";
|
|
1764
|
+
item.first_name = value.first_name || "";
|
|
1765
|
+
item.last_name = value.last_name || "";
|
|
1766
|
+
item.phone = value.phone || "";
|
|
1767
|
+
return item;
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1771
|
+
class UserEditComponent extends EditView {
|
|
1772
|
+
files = signal([new FileRecord({
|
|
1773
|
+
name: "image",
|
|
1774
|
+
display_name: "Profile Image",
|
|
1775
|
+
file_type: "image"
|
|
1776
|
+
})], ...(ngDevMode ? [{ debugName: "files" }] : []));
|
|
1777
|
+
constructor() {
|
|
1778
|
+
super(inject(UserService), new UserForm());
|
|
1779
|
+
}
|
|
1780
|
+
ngOnInit() {
|
|
1781
|
+
this.onInit();
|
|
1782
|
+
}
|
|
1783
|
+
onItemAvailable(item) {
|
|
1784
|
+
this.form.setValue(item);
|
|
1281
1785
|
if (item.profile_url) {
|
|
1282
1786
|
this.files.update(files => { const file = files.find(f => f.name === "image"); if (file) {
|
|
1283
1787
|
file.remote = item.url + item.profile_url;
|
|
1284
1788
|
} ; return files; });
|
|
1285
1789
|
}
|
|
1286
|
-
super.onItemAvailable();
|
|
1790
|
+
super.onItemAvailable(item);
|
|
1287
1791
|
}
|
|
1288
1792
|
submit() {
|
|
1289
1793
|
this.item.update((item) => { if (item) {
|
|
1290
|
-
item = this.
|
|
1794
|
+
item = this.form.updateItem(item);
|
|
1291
1795
|
} return item; });
|
|
1292
|
-
console.log(this.item());
|
|
1293
1796
|
super.submit();
|
|
1294
1797
|
}
|
|
1295
|
-
updateFromForm(item) {
|
|
1296
|
-
item.username = this.form.value.username || "";
|
|
1297
|
-
item.email = this.form.value.email || "";
|
|
1298
|
-
item.first_name = this.form.value.first_name || "";
|
|
1299
|
-
item.last_name = this.form.value.last_name || "";
|
|
1300
|
-
item.phone = this.form.value.phone || "";
|
|
1301
|
-
return item;
|
|
1302
|
-
}
|
|
1303
|
-
getTemplateItem() {
|
|
1304
|
-
return new PortalMember();
|
|
1305
|
-
}
|
|
1306
1798
|
onPreviewLoaded(preview) {
|
|
1307
1799
|
this.files.update(files => { const file = files.find(f => f.name === preview.name); if (file) {
|
|
1308
1800
|
file.local = preview.content;
|
|
@@ -1319,7 +1811,7 @@ class UserEditComponent extends EditView {
|
|
|
1319
1811
|
} ; });
|
|
1320
1812
|
}
|
|
1321
1813
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserEditComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1322
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
1814
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.1", type: UserEditComponent, isStandalone: true, selector: "lib-user-edit", usesInheritance: true, ngImport: i0, template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n <div class=\"item-edit-container\">\n\n <h1 class=\"item-edit-header\">{{heading() | titlecase}}</h1>\n\n <form class=\"form-card\" [formGroup]=\"form.form\" (ngSubmit)=\"submit()\">\n <mat-form-field class=\"form-field-wide\">\n <mat-label>Username</mat-label>\n <input matInput\n placeholder=\"Username\"\n type=\"text\"\n formControlName=\"username\"\n name=\"username\">\n </mat-form-field>\n \n <mat-form-field class=\"form-field-wide\">\n <mat-label>Email</mat-label>\n <input matInput\n placeholder=\"Email\"\n type=\"text\"\n formControlName=\"email\"\n name=\"email\">\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label>First Name</mat-label>\n <input matInput\n placeholder=\"First Name\"\n type=\"text\"\n formControlName=\"first_name\"\n name=\"first_name\">\n </mat-form-field>\n \n <mat-form-field class=\"form-field\">\n <mat-label>Last Name</mat-label>\n <input matInput\n placeholder=\"Last Name\"\n type=\"text\"\n formControlName=\"last_name\"\n name=\"last_name\">\n </mat-form-field>\n\n <lib-file-upload [files]=\"files()\"\n (previewLoaded)=\"onPreviewLoaded($event)\"\n (fileUploaded)=\"onFileUploaded($event)\"></lib-file-upload>\n\n <div class=\"button_group\">\n <button mat-fab\n class=\"form_action_button\"\n type=\"submit\"\n [disabled]=\"!form.form.valid\">\n <mat-icon>save</mat-icon></button>\n \n <button mat-fab\n class=\"form_action_button\"\n type=\"button\"\n (click)=\"cancel()\">\n <mat-icon>cancel</mat-icon></button>\n </div> \n </form>\n </div>\n</div>\n", styles: [":host{flex-grow:1}.item_view{display:flex;justify-content:left;align-items:left;flex-direction:column}.checkbox_group{justify-content:left;display:flex;flex-direction:column}.button_group{margin:10px;display:flex;flex-direction:row;justify-content:center}.btn-block{padding:5px}.form_action_button{padding:5px;margin:5px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: BackButtonComponent, selector: "lib-back-button" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i2$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: FileUploadComponent, selector: "lib-file-upload", inputs: ["files"], outputs: ["previewLoaded", "fileUploaded", "clearLocal"] }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }] });
|
|
1323
1815
|
}
|
|
1324
1816
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserEditComponent, decorators: [{
|
|
1325
1817
|
type: Component,
|
|
@@ -1332,13 +1824,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
1332
1824
|
MatIconModule,
|
|
1333
1825
|
FileUploadComponent,
|
|
1334
1826
|
TitleCasePipe
|
|
1335
|
-
], template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n
|
|
1827
|
+
], template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n <div class=\"item-edit-container\">\n\n <h1 class=\"item-edit-header\">{{heading() | titlecase}}</h1>\n\n <form class=\"form-card\" [formGroup]=\"form.form\" (ngSubmit)=\"submit()\">\n <mat-form-field class=\"form-field-wide\">\n <mat-label>Username</mat-label>\n <input matInput\n placeholder=\"Username\"\n type=\"text\"\n formControlName=\"username\"\n name=\"username\">\n </mat-form-field>\n \n <mat-form-field class=\"form-field-wide\">\n <mat-label>Email</mat-label>\n <input matInput\n placeholder=\"Email\"\n type=\"text\"\n formControlName=\"email\"\n name=\"email\">\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label>First Name</mat-label>\n <input matInput\n placeholder=\"First Name\"\n type=\"text\"\n formControlName=\"first_name\"\n name=\"first_name\">\n </mat-form-field>\n \n <mat-form-field class=\"form-field\">\n <mat-label>Last Name</mat-label>\n <input matInput\n placeholder=\"Last Name\"\n type=\"text\"\n formControlName=\"last_name\"\n name=\"last_name\">\n </mat-form-field>\n\n <lib-file-upload [files]=\"files()\"\n (previewLoaded)=\"onPreviewLoaded($event)\"\n (fileUploaded)=\"onFileUploaded($event)\"></lib-file-upload>\n\n <div class=\"button_group\">\n <button mat-fab\n class=\"form_action_button\"\n type=\"submit\"\n [disabled]=\"!form.form.valid\">\n <mat-icon>save</mat-icon></button>\n \n <button mat-fab\n class=\"form_action_button\"\n type=\"button\"\n (click)=\"cancel()\">\n <mat-icon>cancel</mat-icon></button>\n </div> \n </form>\n </div>\n</div>\n", styles: [":host{flex-grow:1}.item_view{display:flex;justify-content:left;align-items:left;flex-direction:column}.checkbox_group{justify-content:left;display:flex;flex-direction:column}.button_group{margin:10px;display:flex;flex-direction:row;justify-content:center}.btn-block{padding:5px}.form_action_button{padding:5px;margin:5px}\n"] }]
|
|
1336
1828
|
}], ctorParameters: () => [] });
|
|
1337
1829
|
|
|
1338
1830
|
class UserListDetailComponent {
|
|
1339
1831
|
item = input(...(ngDevMode ? [undefined, { debugName: "item" }] : []));
|
|
1340
1832
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserListDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1341
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: UserListDetailComponent, isStandalone: true, selector: "lib-user-list-detail", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mat-card mat-list-item class=\"item-card\">\n @if(item(); as item){\n <mat-card-header>\n <mat-card-title-group style=\"padding: 5px\">\n <mat-card-title\n >{{ item.first_name }} {{ item.last_name }}</mat-card-title\n >\n <mat-card-subtitle>{{ item.username }}</mat-card-subtitle>\n </mat-card-title-group>\n </mat-card-header>\n\n <mat-card-content>\n <p>Email: {{ item.email }}</p>\n </mat-card-content>\n }\n</mat-card>\n", styles: [":host{flex-grow:1}.mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.is-active{font-weight:700}\n"], dependencies: [{ kind: "ngmodule", type: MatListModule }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i1$
|
|
1833
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: UserListDetailComponent, isStandalone: true, selector: "lib-user-list-detail", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mat-card mat-list-item class=\"item-card\">\n @if(item(); as item){\n <mat-card-header>\n <mat-card-title-group style=\"padding: 5px\">\n <mat-card-title\n >{{ item.first_name }} {{ item.last_name }}</mat-card-title\n >\n <mat-card-subtitle>{{ item.username }}</mat-card-subtitle>\n </mat-card-title-group>\n </mat-card-header>\n\n <mat-card-content>\n <p>Email: {{ item.email }}</p>\n </mat-card-content>\n }\n</mat-card>\n", styles: [":host{flex-grow:1}.mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.is-active{font-weight:700}\n"], dependencies: [{ kind: "ngmodule", type: MatListModule }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i1$4.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i1$4.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i1$4.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i1$4.MatCardSubtitle, selector: "mat-card-subtitle, [mat-card-subtitle], [matCardSubtitle]" }, { kind: "directive", type: i1$4.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "component", type: i1$4.MatCardTitleGroup, selector: "mat-card-title-group" }] });
|
|
1342
1834
|
}
|
|
1343
1835
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserListDetailComponent, decorators: [{
|
|
1344
1836
|
type: Component,
|
|
@@ -1346,13 +1838,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
1346
1838
|
MatCardModule], template: "<mat-card mat-list-item class=\"item-card\">\n @if(item(); as item){\n <mat-card-header>\n <mat-card-title-group style=\"padding: 5px\">\n <mat-card-title\n >{{ item.first_name }} {{ item.last_name }}</mat-card-title\n >\n <mat-card-subtitle>{{ item.username }}</mat-card-subtitle>\n </mat-card-title-group>\n </mat-card-header>\n\n <mat-card-content>\n <p>Email: {{ item.email }}</p>\n </mat-card-content>\n }\n</mat-card>\n", styles: [":host{flex-grow:1}.mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.is-active{font-weight:700}\n"] }]
|
|
1347
1839
|
}] });
|
|
1348
1840
|
|
|
1349
|
-
const USER_TABLE_FULL = [
|
|
1350
|
-
{ name: 'first_name', title: 'First Name', element_type: 'string' },
|
|
1351
|
-
{ name: 'last_name', title: 'Surname', element_type: 'string' },
|
|
1352
|
-
{ name: 'username', title: 'Username', element_type: 'string' },
|
|
1353
|
-
{ name: 'email', title: 'Email', element_type: 'email' }
|
|
1354
|
-
];
|
|
1355
|
-
|
|
1356
1841
|
class UserComponent {
|
|
1357
1842
|
viewType = signal("list", ...(ngDevMode ? [{ debugName: "viewType" }] : []));
|
|
1358
1843
|
itemService = inject(UserService);
|
|
@@ -1396,7 +1881,7 @@ class AddressEditComponent {
|
|
|
1396
1881
|
countryOptions = input([], ...(ngDevMode ? [{ debugName: "countryOptions" }] : []));
|
|
1397
1882
|
form = input(...(ngDevMode ? [undefined, { debugName: "form" }] : []));
|
|
1398
1883
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressEditComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1399
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: AddressEditComponent, isStandalone: true, selector: "lib-address-edit", inputs: { countryOptions: { classPropertyName: "countryOptions", publicName: "countryOptions", isSignal: true, isRequired: false, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if(form(); as form){\n<div [formGroup]=\"form\" style=\"display: flex; flex-direction: column; width:100%\">\n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"line1\">Line 1</mat-label>\n <input matInput placeholder=\"Address Line 1\" type=\"text\" id=\"line1\" formControlName=\"line1\" name=\"line1\"\n required>\n </mat-form-field>\n\n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"line2\">Line 2</mat-label>\n <input matInput placeholder=\"Address Line 2\" type=\"text\" id=\"line2\" formControlName=\"line2\" name=\"line1\">\n </mat-form-field>\n\n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"line3\">Line 3</mat-label>\n <input matInput placeholder=\"Address Line 3\" type=\"text\" id=\"line3\" formControlName=\"line3\" name=\"line3\">\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label for=\"city\">City</mat-label>\n <input matInput placeholder=\"City\" type=\"text\" id=\"city\" formControlName=\"city\" name=\"city\">\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label for=\"region\">Region</mat-label>\n <input matInput placeholder=\"Region\" type=\"text\" id=\"region\" formControlName=\"region\" name=\"region\" required>\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label for=\"line1\">Post Code</mat-label>\n <input matInput placeholder=\"Post Code\" type=\"text\" id=\"postcode\" formControlName=\"postcode\" name=\"postcode\">\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label for=\"country\">Country</mat-label>\n <mat-select formControlName=\"country\" name=\"country\" id=\"country\" required>\n @for(country of countryOptions(); track $index){\n <mat-option [value]=\"country.code\">{{country.name}}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n</div>\n}", styles: [""], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type:
|
|
1884
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: AddressEditComponent, isStandalone: true, selector: "lib-address-edit", inputs: { countryOptions: { classPropertyName: "countryOptions", publicName: "countryOptions", isSignal: true, isRequired: false, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if(form(); as form){\n<div [formGroup]=\"form\" style=\"display: flex; flex-direction: column; width:100%\">\n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"line1\">Line 1</mat-label>\n <input matInput placeholder=\"Address Line 1\" type=\"text\" id=\"line1\" formControlName=\"line1\" name=\"line1\"\n required>\n </mat-form-field>\n\n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"line2\">Line 2</mat-label>\n <input matInput placeholder=\"Address Line 2\" type=\"text\" id=\"line2\" formControlName=\"line2\" name=\"line1\">\n </mat-form-field>\n\n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"line3\">Line 3</mat-label>\n <input matInput placeholder=\"Address Line 3\" type=\"text\" id=\"line3\" formControlName=\"line3\" name=\"line3\">\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label for=\"city\">City</mat-label>\n <input matInput placeholder=\"City\" type=\"text\" id=\"city\" formControlName=\"city\" name=\"city\">\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label for=\"region\">Region</mat-label>\n <input matInput placeholder=\"Region\" type=\"text\" id=\"region\" formControlName=\"region\" name=\"region\" required>\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label for=\"line1\">Post Code</mat-label>\n <input matInput placeholder=\"Post Code\" type=\"text\" id=\"postcode\" formControlName=\"postcode\" name=\"postcode\">\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label for=\"country\">Country</mat-label>\n <mat-select formControlName=\"country\" name=\"country\" id=\"country\" required>\n @for(country of countryOptions(); track $index){\n <mat-option [value]=\"country.code\">{{country.name}}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n</div>\n}", styles: [""], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
|
|
1400
1885
|
}
|
|
1401
1886
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressEditComponent, decorators: [{
|
|
1402
1887
|
type: Component,
|
|
@@ -1439,6 +1924,16 @@ class AddressForm {
|
|
|
1439
1924
|
country: item.country
|
|
1440
1925
|
});
|
|
1441
1926
|
}
|
|
1927
|
+
createItem() {
|
|
1928
|
+
const value = this.form.value;
|
|
1929
|
+
return { line1: value.line1 || "",
|
|
1930
|
+
line2: value.line2 || null,
|
|
1931
|
+
line3: value.line3 || null,
|
|
1932
|
+
city: value.city || null,
|
|
1933
|
+
region: value.region || "",
|
|
1934
|
+
postcode: value.postcode || null,
|
|
1935
|
+
country: value.country || "" };
|
|
1936
|
+
}
|
|
1442
1937
|
updateItem(item) {
|
|
1443
1938
|
const value = this.form.value;
|
|
1444
1939
|
item.line1 = value.line1 || "";
|
|
@@ -1468,63 +1963,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
1468
1963
|
}] });
|
|
1469
1964
|
|
|
1470
1965
|
class OrganizationDetailComponent extends DetailView {
|
|
1471
|
-
address = signal(null, ...(ngDevMode ? [{ debugName: "address" }] : []));
|
|
1472
|
-
addressService = inject(AddressService);
|
|
1473
1966
|
constructor() {
|
|
1474
1967
|
super(inject(OrganizationService));
|
|
1475
1968
|
}
|
|
1476
1969
|
ngOnInit() {
|
|
1477
1970
|
this.onInit();
|
|
1478
1971
|
}
|
|
1479
|
-
onItemAndUserAvailable(item, _user) {
|
|
1480
|
-
this.addressService.getUrl(item.address).subscribe(address => this.address.set(address));
|
|
1481
|
-
}
|
|
1482
1972
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1483
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: OrganizationDetailComponent, isStandalone: true, selector: "lib-organization-detail", usesInheritance: true, ngImport: i0, template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n @if(item(); as item){\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.name\"\n [id]=\"item.id\"\n [canEdit]=\"itemService.canEdit()\"\n [canDelete]=\"itemService.canDelete()\"\n [route]=\"itemService.typePlural()\"></lib-detail-header>\n\n <div class=\"item-field\">\n {{item.description}}\n </div>\n \n
|
|
1973
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: OrganizationDetailComponent, isStandalone: true, selector: "lib-organization-detail", usesInheritance: true, ngImport: i0, template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n @if(item(); as item){\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.name\"\n [id]=\"item.id\"\n [canEdit]=\"itemService.canEdit()\"\n [canDelete]=\"itemService.canDelete()\"\n [route]=\"itemService.typePlural()\"></lib-detail-header>\n\n <div class=\"item-field\">\n {{item.description}}\n </div>\n \n <h3>Address</h3>\n <lib-address-detail [address]=\"item.address\"></lib-address-detail>\n\n <div class=\"item-field\">\n <h3>Website</h3>{{item.website}}\n </div>\n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}.padded_button{padding:5px}\n"], dependencies: [{ kind: "component", type: BackButtonComponent, selector: "lib-back-button" }, { kind: "component", type: DetailHeaderComponent, selector: "lib-detail-header", inputs: ["id", "text", "route", "canEdit", "canDelete"], outputs: ["deleteClicked"] }, { kind: "component", type: AddressDetailComponent, selector: "lib-address-detail", inputs: ["address"] }] });
|
|
1484
1974
|
}
|
|
1485
1975
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationDetailComponent, decorators: [{
|
|
1486
1976
|
type: Component,
|
|
1487
1977
|
args: [{ selector: 'lib-organization-detail', imports: [BackButtonComponent,
|
|
1488
|
-
DetailHeaderComponent, AddressDetailComponent], template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n @if(item(); as item){\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.name\"\n [id]=\"item.id\"\n [canEdit]=\"itemService.canEdit()\"\n [canDelete]=\"itemService.canDelete()\"\n [route]=\"itemService.typePlural()\"></lib-detail-header>\n\n <div class=\"item-field\">\n {{item.description}}\n </div>\n \n
|
|
1978
|
+
DetailHeaderComponent, AddressDetailComponent], template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n @if(item(); as item){\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.name\"\n [id]=\"item.id\"\n [canEdit]=\"itemService.canEdit()\"\n [canDelete]=\"itemService.canDelete()\"\n [route]=\"itemService.typePlural()\"></lib-detail-header>\n\n <div class=\"item-field\">\n {{item.description}}\n </div>\n \n <h3>Address</h3>\n <lib-address-detail [address]=\"item.address\"></lib-address-detail>\n\n <div class=\"item-field\">\n <h3>Website</h3>{{item.website}}\n </div>\n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}.padded_button{padding:5px}\n"] }]
|
|
1489
1979
|
}], ctorParameters: () => [] });
|
|
1490
1980
|
|
|
1491
|
-
class SelectionManager {
|
|
1492
|
-
candidates = signal([], ...(ngDevMode ? [{ debugName: "candidates" }] : []));
|
|
1493
|
-
selected = signal([], ...(ngDevMode ? [{ debugName: "selected" }] : []));
|
|
1494
|
-
columns = USER_TABLE_FULL;
|
|
1495
|
-
userService = inject(UserService);
|
|
1496
|
-
fetchCandidates(item, id) {
|
|
1497
|
-
const queries = new Map([[item, id.toString()]]);
|
|
1498
|
-
const query = new ItemQuery({ queries: queries });
|
|
1499
|
-
this.userService.get(query).subscribe(users => this.selected.set(users.results));
|
|
1500
|
-
this.userService.get().subscribe(users => this.updateCandidates(users));
|
|
1501
|
-
}
|
|
1502
|
-
updateCandidates(users) {
|
|
1503
|
-
this.candidates.set(users.results.map(user => { return { title: user.username, item: user }; }));
|
|
1504
|
-
}
|
|
1505
|
-
onRemoved(id) {
|
|
1506
|
-
const url = this.selected().find(m => m.id == id).url;
|
|
1507
|
-
this.selected.update(members => members.filter(m => m.id != id));
|
|
1508
|
-
return url;
|
|
1509
|
-
}
|
|
1510
|
-
onAdded(title) {
|
|
1511
|
-
const selected = this.candidates().find(m => m.title == title);
|
|
1512
|
-
if (selected) {
|
|
1513
|
-
this.selected.update(members => { members.push(selected.item); return members; });
|
|
1514
|
-
}
|
|
1515
|
-
this.candidates.update(members => members.filter(m => m.title != title));
|
|
1516
|
-
return this.selected().find(m => m.username == title).url;
|
|
1517
|
-
}
|
|
1518
|
-
onSearchChanged(searchTerm) {
|
|
1519
|
-
if (searchTerm) {
|
|
1520
|
-
this.userService.get(new ItemQuery({ filter: searchTerm })).subscribe(users => this.updateCandidates(users));
|
|
1521
|
-
}
|
|
1522
|
-
else {
|
|
1523
|
-
this.userService.get().subscribe(users => this.updateCandidates(users));
|
|
1524
|
-
}
|
|
1525
|
-
}
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
1981
|
class OrganizationForm {
|
|
1529
1982
|
formBuilder = inject(FormBuilder);
|
|
1530
1983
|
form;
|
|
@@ -1538,7 +1991,8 @@ class OrganizationForm {
|
|
|
1538
1991
|
address: [this.address.form]
|
|
1539
1992
|
});
|
|
1540
1993
|
}
|
|
1541
|
-
|
|
1994
|
+
setValue(item) {
|
|
1995
|
+
this.address.setValue(item.address);
|
|
1542
1996
|
this.form.setValue({
|
|
1543
1997
|
name: item.name,
|
|
1544
1998
|
acronym: item.acronym,
|
|
@@ -1547,75 +2001,54 @@ class OrganizationForm {
|
|
|
1547
2001
|
address: this.address.form
|
|
1548
2002
|
});
|
|
1549
2003
|
}
|
|
2004
|
+
createItem() {
|
|
2005
|
+
const value = this.form.value;
|
|
2006
|
+
return {
|
|
2007
|
+
name: value.name || "",
|
|
2008
|
+
acronym: value.acronym || "",
|
|
2009
|
+
description: value.description || "",
|
|
2010
|
+
website: value.website || "",
|
|
2011
|
+
address: this.address.createItem(),
|
|
2012
|
+
members: []
|
|
2013
|
+
};
|
|
2014
|
+
}
|
|
1550
2015
|
updateItem(item) {
|
|
1551
2016
|
item.name = this.form.value.name || "";
|
|
1552
2017
|
item.acronym = this.form.value.acronym || "";
|
|
1553
2018
|
item.description = this.form.value.description || "";
|
|
1554
2019
|
item.website = this.form.value.website || "";
|
|
2020
|
+
item.address = this.address.updateItem(item.address);
|
|
1555
2021
|
return item;
|
|
1556
2022
|
}
|
|
1557
2023
|
}
|
|
1558
2024
|
|
|
1559
2025
|
class OrganizationEditComponent extends EditView {
|
|
1560
2026
|
countryOptions = signal([], ...(ngDevMode ? [{ debugName: "countryOptions" }] : []));
|
|
1561
|
-
selectionManager = new SelectionManager();
|
|
1562
|
-
form = new OrganizationForm();
|
|
1563
|
-
address = new Address();
|
|
1564
2027
|
addressService = inject(AddressService);
|
|
2028
|
+
selectionManager = new SelectionManager();
|
|
1565
2029
|
constructor() {
|
|
1566
|
-
super(inject(OrganizationService));
|
|
2030
|
+
super(inject(OrganizationService), new OrganizationForm());
|
|
1567
2031
|
}
|
|
1568
2032
|
ngOnInit() {
|
|
1569
2033
|
this.onInit();
|
|
1570
2034
|
this.addressService.getOptions().subscribe(options => this.onOptions(options));
|
|
1571
2035
|
}
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
if (item) {
|
|
1575
|
-
this.fetchAddress(item.address);
|
|
1576
|
-
this.form.updateFromItem(item);
|
|
1577
|
-
this.selectionManager.fetchCandidates(this.itemService.typename, item.id);
|
|
1578
|
-
}
|
|
1579
|
-
}
|
|
1580
|
-
submit() {
|
|
1581
|
-
this.syncFromForm();
|
|
1582
|
-
if (this.createMode()) {
|
|
1583
|
-
this.createAddress().subscribe(_ => super.submit());
|
|
1584
|
-
}
|
|
1585
|
-
else {
|
|
1586
|
-
this.updateAddress();
|
|
1587
|
-
super.submit();
|
|
1588
|
-
}
|
|
1589
|
-
}
|
|
1590
|
-
fetchAddress(url) {
|
|
1591
|
-
if (url) {
|
|
1592
|
-
this.addressService.getUrl(url).subscribe(address => this.onAddressUpdated(address));
|
|
1593
|
-
}
|
|
1594
|
-
}
|
|
1595
|
-
updateAddress() {
|
|
1596
|
-
this.addressService.putItem(this.address).subscribe(address => this.onAddressUpdated(address));
|
|
1597
|
-
}
|
|
1598
|
-
createAddress() {
|
|
1599
|
-
return this.addressService.postItem(this.address).pipe(tap(address => { this.onAddressCreated(address); }));
|
|
2036
|
+
addressForm() {
|
|
2037
|
+
return this.form.address.form;
|
|
1600
2038
|
}
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
this.
|
|
1604
|
-
|
|
1605
|
-
onAddressCreated(address) {
|
|
1606
|
-
this.onAddressUpdated(address);
|
|
1607
|
-
this.item.update(item => { if (item) {
|
|
1608
|
-
item.address = address.url;
|
|
1609
|
-
} return item; });
|
|
2039
|
+
createItem() {
|
|
2040
|
+
const item = this.form.createItem();
|
|
2041
|
+
item.members = this.selectionManager.selected().map(m => m.url);
|
|
2042
|
+
return item;
|
|
1610
2043
|
}
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
this.
|
|
1614
|
-
|
|
1615
|
-
} return item; });
|
|
2044
|
+
updateItem(item) {
|
|
2045
|
+
item = this.form.updateItem(item);
|
|
2046
|
+
item.members = this.selectionManager.selected().map(m => m.url);
|
|
2047
|
+
return item;
|
|
1616
2048
|
}
|
|
1617
|
-
|
|
1618
|
-
|
|
2049
|
+
onItemAndUserAvailable(item, _) {
|
|
2050
|
+
this.form.setValue(item);
|
|
2051
|
+
this.selectionManager.fetchCandidates(this.itemService.typename, item.id);
|
|
1619
2052
|
}
|
|
1620
2053
|
onPostActions(actions) {
|
|
1621
2054
|
if ('country' in actions && actions['country'].choices) {
|
|
@@ -1625,24 +2058,8 @@ class OrganizationEditComponent extends EditView {
|
|
|
1625
2058
|
onCountryChoices(choices) {
|
|
1626
2059
|
this.countryOptions.update(() => choices.map(c => { return { name: c.display_name, code: c.value, flag: "" }; }));
|
|
1627
2060
|
}
|
|
1628
|
-
addMember(url) {
|
|
1629
|
-
this.item.update(item => { if (item) {
|
|
1630
|
-
item.members.push(url);
|
|
1631
|
-
} return item; });
|
|
1632
|
-
}
|
|
1633
|
-
removeMember(url) {
|
|
1634
|
-
this.item.update(item => { if (item) {
|
|
1635
|
-
item.members.filter(m => m != url);
|
|
1636
|
-
} return item; });
|
|
1637
|
-
}
|
|
1638
|
-
onMemberRemoved(id) {
|
|
1639
|
-
this.removeMember(this.selectionManager.onRemoved(id));
|
|
1640
|
-
}
|
|
1641
|
-
onMemberAdded(title) {
|
|
1642
|
-
this.addMember(this.selectionManager.onAdded(title));
|
|
1643
|
-
}
|
|
1644
2061
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationEditComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1645
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2062
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.1", type: OrganizationEditComponent, isStandalone: true, selector: "lib-organization-edit", usesInheritance: true, ngImport: i0, template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n <div class=\"item-edit-container\">\n \n <h1 class=\"item-edit-header\">{{heading() | titlecase}}</h1>\n\n <form class=\"form-card\" [formGroup]=\"form.form\" (ngSubmit)=\"submit()\">\n\n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"name\">Name</mat-label>\n <input matInput placeholder=\"Name\"\n type=\"text\"\n id=\"name\"\n formControlName=\"name\"\n name=\"name\"\n required>\n </mat-form-field>\n \n <mat-form-field class=\"form-field\">\n <mat-label for=\"acronym\">Acronym</mat-label> \n <input matInput placeholder=\"Acronym\"\n type=\"text\"\n id=\"acronym\"\n formControlName=\"acronym\"\n name=\"acronym\">\n </mat-form-field>\n \n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"description\">Description</mat-label>\n <textarea matInput placeholder=\"Description\"\n type=\"text\"\n id=\"description\"\n formControlName=\"description\"\n name=\"description\"\n class=\"medium-textarea\"\n required></textarea>\n </mat-form-field>\n\n <h3>Address</h3>\n <lib-address-edit \n [countryOptions]=\"countryOptions()\"\n [form]=\"addressForm()\"\n ></lib-address-edit>\n\n <h3>Members</h3>\n <lib-select-table [selected]=\"selectionManager.selected()\"\n [itemType]=\"'Members'\"\n [columns]=\"selectionManager.columns\"\n [options]=\"selectionManager.candidates()\"\n (itemAdded)=\"selectionManager.onAdded($event)\"\n (itemRemoved)=\"selectionManager.onRemoved($event)\"\n (searchChanged)=\"selectionManager.onSearchChanged($event)\">\n </lib-select-table>\n\n <div class=\"button_group\">\n <button mat-fab\n class=\"form_action_button\"\n type=\"submit\"\n [disabled]=\"!form.form.valid\">\n <mat-icon>save</mat-icon>\n </button>\n \n <button mat-fab\n type=\"button\"\n class=\"form_action_button\"\n (click)=\"cancel()\">\n <mat-icon>cancel</mat-icon>\n </button>\n </div>\n </form>\n </div>\n</div>\n", styles: [":host{flex-grow:1}.medium-textarea{min-height:150px}.checkbox_group{justify-content:left;display:flex;flex-direction:column}.button_group{margin:10px;display:flex;flex-direction:row;justify-content:center}.btn-block{padding:5px}.form_action_button{padding:5px;margin:5px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i2$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatSelectModule }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: BackButtonComponent, selector: "lib-back-button" }, { kind: "component", type: AddressEditComponent, selector: "lib-address-edit", inputs: ["countryOptions", "form"] }, { kind: "component", type: SelectTableComponent, selector: "lib-select-table", inputs: ["itemType", "selected", "options", "columns"], outputs: ["itemAdded", "itemRemoved", "searchChanged"] }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }] });
|
|
1646
2063
|
}
|
|
1647
2064
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationEditComponent, decorators: [{
|
|
1648
2065
|
type: Component,
|
|
@@ -1658,7 +2075,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
1658
2075
|
AddressEditComponent,
|
|
1659
2076
|
SelectTableComponent,
|
|
1660
2077
|
TitleCasePipe
|
|
1661
|
-
], template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n
|
|
2078
|
+
], template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n <div class=\"item-edit-container\">\n \n <h1 class=\"item-edit-header\">{{heading() | titlecase}}</h1>\n\n <form class=\"form-card\" [formGroup]=\"form.form\" (ngSubmit)=\"submit()\">\n\n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"name\">Name</mat-label>\n <input matInput placeholder=\"Name\"\n type=\"text\"\n id=\"name\"\n formControlName=\"name\"\n name=\"name\"\n required>\n </mat-form-field>\n \n <mat-form-field class=\"form-field\">\n <mat-label for=\"acronym\">Acronym</mat-label> \n <input matInput placeholder=\"Acronym\"\n type=\"text\"\n id=\"acronym\"\n formControlName=\"acronym\"\n name=\"acronym\">\n </mat-form-field>\n \n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"description\">Description</mat-label>\n <textarea matInput placeholder=\"Description\"\n type=\"text\"\n id=\"description\"\n formControlName=\"description\"\n name=\"description\"\n class=\"medium-textarea\"\n required></textarea>\n </mat-form-field>\n\n <h3>Address</h3>\n <lib-address-edit \n [countryOptions]=\"countryOptions()\"\n [form]=\"addressForm()\"\n ></lib-address-edit>\n\n <h3>Members</h3>\n <lib-select-table [selected]=\"selectionManager.selected()\"\n [itemType]=\"'Members'\"\n [columns]=\"selectionManager.columns\"\n [options]=\"selectionManager.candidates()\"\n (itemAdded)=\"selectionManager.onAdded($event)\"\n (itemRemoved)=\"selectionManager.onRemoved($event)\"\n (searchChanged)=\"selectionManager.onSearchChanged($event)\">\n </lib-select-table>\n\n <div class=\"button_group\">\n <button mat-fab\n class=\"form_action_button\"\n type=\"submit\"\n [disabled]=\"!form.form.valid\">\n <mat-icon>save</mat-icon>\n </button>\n \n <button mat-fab\n type=\"button\"\n class=\"form_action_button\"\n (click)=\"cancel()\">\n <mat-icon>cancel</mat-icon>\n </button>\n </div>\n </form>\n </div>\n</div>\n", styles: [":host{flex-grow:1}.medium-textarea{min-height:150px}.checkbox_group{justify-content:left;display:flex;flex-direction:column}.button_group{margin:10px;display:flex;flex-direction:row;justify-content:center}.btn-block{padding:5px}.form_action_button{padding:5px;margin:5px}\n"] }]
|
|
1662
2079
|
}], ctorParameters: () => [] });
|
|
1663
2080
|
|
|
1664
2081
|
/*
|
|
@@ -1669,5 +2086,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
1669
2086
|
* Generated bundle index. Do not edit.
|
|
1670
2087
|
*/
|
|
1671
2088
|
|
|
1672
|
-
export { Address, AddressDetailComponent, AddressEditComponent, AddressForm, AddressService, ApiError, AvatarComponent, BackButtonComponent, DetailHeaderComponent, DetailView, ENDPOINT_URL, EditView, ErrorCode, FeedbackComponent, FileRecord, FileUploadComponent, Group, GroupComponent, GroupDetailComponent, GroupService, ItemQuery, ItemService, ItemWithUserService, LOGIN_USER, LandingComponent, LeftNavComponent, LeftNavService, ListTableViewComponent, ListViewComponent, MockItemService, Organization, OrganizationComponent, OrganizationDetailComponent, OrganizationEditComponent, OrganizationService, Paginated, Permission, PortalMember, ResolvedPermission, RestService, SearchBarComponent, SelectTableComponent, TopBarComponent, UserComponent, UserDetailComponent, UserEditComponent, UserService };
|
|
2089
|
+
export { Address, AddressDetailComponent, AddressEditComponent, AddressForm, AddressService, ApiError, AvatarComponent, BackButtonComponent, DetailHeaderComponent, DetailView, DynamicFormBuilderComponent, DynamicFormComponent, DynamicFormForm, ENDPOINT_URL, EditView, ErrorCode, FORM_FIELD_CHOICES, FeedbackComponent, FileRecord, FileUploadComponent, FormFieldDetailComponent, FormFieldEditComponent, FormFieldListComponent, FormService, Group, GroupComponent, GroupDetailComponent, GroupService, ItemQuery, ItemService, ItemWithUserService, LOGIN_USER, LandingComponent, LeftNavComponent, LeftNavService, ListTableViewComponent, ListViewComponent, MockItemService, Organization, OrganizationComponent, OrganizationDetailComponent, OrganizationEditComponent, OrganizationService, Paginated, Permission, PortalMember, ResolvedPermission, RestService, SearchBarComponent, SelectTableComponent, SelectionManager, TopBarComponent, UserComponent, UserDetailComponent, UserEditComponent, UserService };
|
|
1673
2090
|
//# sourceMappingURL=ichec-angular-core.mjs.map
|