ichec-angular-core 0.1.0 → 0.1.2
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 +577 -496
- package/fesm2022/ichec-angular-core.mjs.map +1 -1
- package/index.d.ts +303 -153
- package/package.json +1 -1
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { map, catchError, tap, mergeMap, throwError, BehaviorSubject, mergeAll, merge, debounceTime, distinctUntilChanged, Subscription,
|
|
1
|
+
import { map, catchError, tap, mergeMap, throwError, BehaviorSubject, mergeAll, of, merge, debounceTime, distinctUntilChanged, Subscription, finalize } from 'rxjs';
|
|
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 { NgIf, Location, NgTemplateOutlet, TitleCasePipe } from '@angular/common';
|
|
6
5
|
import * as i1 from '@angular/router';
|
|
7
6
|
import { RouterModule, RouterOutlet, Router, ActivatedRoute } from '@angular/router';
|
|
8
7
|
import * as i2 from '@angular/material/toolbar';
|
|
@@ -17,6 +16,7 @@ import * as i1$1 from '@angular/material/sidenav';
|
|
|
17
16
|
import { MatSidenavContent, MatSidenavModule } from '@angular/material/sidenav';
|
|
18
17
|
import * as i2$2 from '@angular/material/list';
|
|
19
18
|
import { MatListModule } from '@angular/material/list';
|
|
19
|
+
import { NgIf, Location, NgTemplateOutlet, TitleCasePipe } from '@angular/common';
|
|
20
20
|
import * as i1$2 from '@angular/forms';
|
|
21
21
|
import { FormsModule, FormControl, ReactiveFormsModule, FormBuilder } from '@angular/forms';
|
|
22
22
|
import * as i3$2 from '@angular/material/input';
|
|
@@ -31,14 +31,14 @@ import * as i6 from '@angular/material/select';
|
|
|
31
31
|
import { MatSelectModule } from '@angular/material/select';
|
|
32
32
|
import * as i6$1 from '@angular/material/autocomplete';
|
|
33
33
|
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
|
34
|
-
import * as i4 from '@angular/material/tooltip';
|
|
35
|
-
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
36
34
|
import * as i3$3 from '@angular/material/sort';
|
|
37
35
|
import { MatSort, MatSortModule } from '@angular/material/sort';
|
|
38
36
|
import * as i1$5 from '@angular/material/button-toggle';
|
|
39
37
|
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
|
40
38
|
import * as i2$5 from '@angular/material/progress-spinner';
|
|
41
39
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
40
|
+
import * as i4 from '@angular/material/tooltip';
|
|
41
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
42
42
|
import * as i2$3 from '@angular/material/paginator';
|
|
43
43
|
import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
|
|
44
44
|
import * as i2$4 from '@angular/cdk/scrolling';
|
|
@@ -78,6 +78,21 @@ class PortalMember {
|
|
|
78
78
|
constructor(params = {}) {
|
|
79
79
|
Object.assign(this, params);
|
|
80
80
|
}
|
|
81
|
+
static getInitials(member) {
|
|
82
|
+
let first_initial = "";
|
|
83
|
+
let second_initial = "";
|
|
84
|
+
if (member.first_name) {
|
|
85
|
+
first_initial = member.first_name[0];
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
first_initial = member.username[0];
|
|
89
|
+
}
|
|
90
|
+
if (member.first_name) {
|
|
91
|
+
second_initial = member.last_name[0];
|
|
92
|
+
}
|
|
93
|
+
const combined = first_initial + second_initial;
|
|
94
|
+
return combined.toUpperCase();
|
|
95
|
+
}
|
|
81
96
|
}
|
|
82
97
|
class Group {
|
|
83
98
|
static typename = "group";
|
|
@@ -90,6 +105,40 @@ class Group {
|
|
|
90
105
|
}
|
|
91
106
|
}
|
|
92
107
|
|
|
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
|
+
class Organization {
|
|
127
|
+
static typename = "organization";
|
|
128
|
+
static plural = "organizations";
|
|
129
|
+
id = 0;
|
|
130
|
+
url = "";
|
|
131
|
+
name = "";
|
|
132
|
+
acronym = "";
|
|
133
|
+
description = "";
|
|
134
|
+
address = "";
|
|
135
|
+
website = "";
|
|
136
|
+
members = [];
|
|
137
|
+
constructor(params = {}) {
|
|
138
|
+
Object.assign(this, params);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
93
142
|
class ItemQuery {
|
|
94
143
|
queries = new Map();
|
|
95
144
|
page = 0;
|
|
@@ -226,7 +275,8 @@ class RestService {
|
|
|
226
275
|
}
|
|
227
276
|
|
|
228
277
|
class ItemService extends RestService {
|
|
229
|
-
|
|
278
|
+
typenamePlural = "";
|
|
279
|
+
typename = "";
|
|
230
280
|
canEdit() {
|
|
231
281
|
return false;
|
|
232
282
|
}
|
|
@@ -239,6 +289,9 @@ class ItemService extends RestService {
|
|
|
239
289
|
canView() {
|
|
240
290
|
return false;
|
|
241
291
|
}
|
|
292
|
+
typePlural() {
|
|
293
|
+
return this.typenamePlural ? this.typenamePlural : this.typename + "s";
|
|
294
|
+
}
|
|
242
295
|
instantiateType(_) {
|
|
243
296
|
throw new Error('Not Implemented');
|
|
244
297
|
}
|
|
@@ -259,7 +312,7 @@ class UserService extends ItemService {
|
|
|
259
312
|
*/
|
|
260
313
|
loggedInUser = new BehaviorSubject(null);
|
|
261
314
|
_url = PortalMember.plural;
|
|
262
|
-
|
|
315
|
+
typename = PortalMember.typename;
|
|
263
316
|
permissions = new Map();
|
|
264
317
|
instantiateType(item) {
|
|
265
318
|
return new PortalMember(item);
|
|
@@ -357,23 +410,71 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
357
410
|
}]
|
|
358
411
|
}] });
|
|
359
412
|
|
|
360
|
-
class
|
|
413
|
+
class ItemWithUserService extends ItemService {
|
|
361
414
|
userService = inject(UserService);
|
|
362
415
|
userItems = new BehaviorSubject([]);
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
this.userService.
|
|
416
|
+
canCreate() {
|
|
417
|
+
return this.userService.hasAddPermission(this.permissionName());
|
|
418
|
+
}
|
|
419
|
+
canView() {
|
|
420
|
+
return this.userService.hasViewPermission(this.permissionName());
|
|
421
|
+
}
|
|
422
|
+
canEdit() {
|
|
423
|
+
return this.userService.hasEditPermission(this.permissionName());
|
|
424
|
+
}
|
|
425
|
+
canDelete() {
|
|
426
|
+
return this.userService.hasDeletePermission(this.permissionName());
|
|
427
|
+
}
|
|
428
|
+
permissionName() {
|
|
429
|
+
return this.typename.replace("_", "");
|
|
430
|
+
}
|
|
431
|
+
getUserItems() {
|
|
432
|
+
if (this.userService.loggedInUser.value) {
|
|
433
|
+
return this.getForUser(this.userService.loggedInUser.value);
|
|
434
|
+
}
|
|
435
|
+
return of(new Paginated());
|
|
368
436
|
}
|
|
369
437
|
refreshUserItems(user) {
|
|
370
438
|
if (user) {
|
|
371
|
-
this.
|
|
439
|
+
this.getUserItems().subscribe(items => this.userItems.next(items.results));
|
|
372
440
|
}
|
|
373
441
|
else {
|
|
374
442
|
this.userItems.next([]);
|
|
375
443
|
}
|
|
376
444
|
}
|
|
445
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ItemWithUserService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
446
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ItemWithUserService, providedIn: 'root' });
|
|
447
|
+
}
|
|
448
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ItemWithUserService, decorators: [{
|
|
449
|
+
type: Injectable,
|
|
450
|
+
args: [{
|
|
451
|
+
providedIn: 'root'
|
|
452
|
+
}]
|
|
453
|
+
}] });
|
|
454
|
+
|
|
455
|
+
class AddressService extends ItemWithUserService {
|
|
456
|
+
_url = Address.plural;
|
|
457
|
+
typename = Address.typename;
|
|
458
|
+
instantiateType(item) {
|
|
459
|
+
return new Address(item);
|
|
460
|
+
}
|
|
461
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
462
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressService, providedIn: 'root' });
|
|
463
|
+
}
|
|
464
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressService, decorators: [{
|
|
465
|
+
type: Injectable,
|
|
466
|
+
args: [{
|
|
467
|
+
providedIn: 'root'
|
|
468
|
+
}]
|
|
469
|
+
}] });
|
|
470
|
+
|
|
471
|
+
class GroupService extends ItemWithUserService {
|
|
472
|
+
_url = Group.plural;
|
|
473
|
+
typename = Group.typename;
|
|
474
|
+
constructor() {
|
|
475
|
+
super();
|
|
476
|
+
this.userService.loggedInUser.subscribe(user => this.refreshUserItems(user));
|
|
477
|
+
}
|
|
377
478
|
instantiateType(item) {
|
|
378
479
|
return new Group(item);
|
|
379
480
|
}
|
|
@@ -387,60 +488,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
387
488
|
}]
|
|
388
489
|
}], ctorParameters: () => [] });
|
|
389
490
|
|
|
390
|
-
class
|
|
391
|
-
static typename = "address";
|
|
392
|
-
static plural = "addresses";
|
|
393
|
-
id = 0;
|
|
394
|
-
url = "";
|
|
395
|
-
line1 = "";
|
|
396
|
-
line2 = "";
|
|
397
|
-
line3 = "";
|
|
398
|
-
city = "";
|
|
399
|
-
region = "";
|
|
400
|
-
postcode = "";
|
|
401
|
-
country = "";
|
|
402
|
-
country_name = "";
|
|
403
|
-
country_flag = "";
|
|
404
|
-
members = [];
|
|
405
|
-
constructor(params = {}) {
|
|
406
|
-
Object.assign(this, params);
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
class Organization {
|
|
410
|
-
static typename = "organization";
|
|
411
|
-
static plural = "organizations";
|
|
412
|
-
id = 0;
|
|
413
|
-
url = "";
|
|
414
|
-
name = "";
|
|
415
|
-
acronym = "";
|
|
416
|
-
description = "";
|
|
417
|
-
address = "";
|
|
418
|
-
website = "";
|
|
419
|
-
members = [];
|
|
420
|
-
constructor(params = {}) {
|
|
421
|
-
Object.assign(this, params);
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
class OrganizationService extends ItemService {
|
|
491
|
+
class OrganizationService extends ItemWithUserService {
|
|
426
492
|
_url = Organization.plural;
|
|
427
|
-
|
|
428
|
-
userService = inject(UserService);
|
|
493
|
+
typename = Organization.typename;
|
|
429
494
|
instantiateType(item) {
|
|
430
495
|
return new Organization(item);
|
|
431
496
|
}
|
|
432
|
-
canCreate() {
|
|
433
|
-
return this.userService.hasAddPermission(Organization.typename);
|
|
434
|
-
}
|
|
435
|
-
canView() {
|
|
436
|
-
return this.userService.hasViewPermission(Organization.typename);
|
|
437
|
-
}
|
|
438
|
-
canEdit() {
|
|
439
|
-
return this.userService.hasEditPermission(Organization.typename);
|
|
440
|
-
}
|
|
441
|
-
canDelete() {
|
|
442
|
-
return this.userService.hasDeletePermission(Organization.typename);
|
|
443
|
-
}
|
|
444
497
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
445
498
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationService, providedIn: 'root' });
|
|
446
499
|
}
|
|
@@ -488,6 +541,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
488
541
|
}]
|
|
489
542
|
}], ctorParameters: () => [] });
|
|
490
543
|
|
|
544
|
+
class MockItemService {
|
|
545
|
+
canEdit() {
|
|
546
|
+
return false;
|
|
547
|
+
}
|
|
548
|
+
canDelete() {
|
|
549
|
+
return false;
|
|
550
|
+
}
|
|
551
|
+
canCreate() {
|
|
552
|
+
return false;
|
|
553
|
+
}
|
|
554
|
+
typePlural() {
|
|
555
|
+
return "mock_plurals";
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
491
559
|
class TopBarComponent {
|
|
492
560
|
title = input(...(ngDevMode ? [undefined, { debugName: "title" }] : []));
|
|
493
561
|
user = signal(null, ...(ngDevMode ? [{ debugName: "user" }] : []));
|
|
@@ -501,12 +569,23 @@ class TopBarComponent {
|
|
|
501
569
|
onLogout() {
|
|
502
570
|
this.userService.logout();
|
|
503
571
|
}
|
|
572
|
+
getInitials() {
|
|
573
|
+
const user = this.user();
|
|
574
|
+
if (user) {
|
|
575
|
+
return PortalMember.getInitials(user);
|
|
576
|
+
}
|
|
577
|
+
return "";
|
|
578
|
+
}
|
|
504
579
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: TopBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
505
|
-
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 aria-label=\"User Profile\" [matMenuTriggerFor]=\"profile_menu\">\n <mat-icon>person</mat-icon>\n </button>\n\n <mat-menu #profile_menu=\"matMenu\">\n <button mat-menu-item (click)=\"onLogout()\">Log Out</button>\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: i3.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"] }] });
|
|
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: i3.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"] }] });
|
|
506
581
|
}
|
|
507
582
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: TopBarComponent, decorators: [{
|
|
508
583
|
type: Component,
|
|
509
|
-
args: [{ selector: 'lib-top-bar', imports: [
|
|
584
|
+
args: [{ selector: 'lib-top-bar', imports: [RouterModule,
|
|
585
|
+
MatToolbarModule,
|
|
586
|
+
MatIconModule,
|
|
587
|
+
MatButtonModule,
|
|
588
|
+
MatMenuModule], 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"] }]
|
|
510
589
|
}] });
|
|
511
590
|
|
|
512
591
|
class LeftNavComponent {
|
|
@@ -566,6 +645,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
566
645
|
args: [{ selector: 'lib-landing', imports: [FormsModule, MatCardModule, MatFormFieldModule, MatInputModule, MatButtonModule, MatIconModule, NgIf], 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"] }]
|
|
567
646
|
}] });
|
|
568
647
|
|
|
648
|
+
class FeedbackComponent {
|
|
649
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FeedbackComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
650
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.1", type: FeedbackComponent, isStandalone: true, selector: "lib-feedback", ngImport: i0, template: "<p>feedback works!</p>\n", styles: [""] });
|
|
651
|
+
}
|
|
652
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FeedbackComponent, decorators: [{
|
|
653
|
+
type: Component,
|
|
654
|
+
args: [{ selector: 'lib-feedback', imports: [], template: "<p>feedback works!</p>\n" }]
|
|
655
|
+
}] });
|
|
656
|
+
|
|
657
|
+
class AvatarComponent {
|
|
658
|
+
text = input("", ...(ngDevMode ? [{ debugName: "text" }] : []));
|
|
659
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
660
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.1.1", type: AvatarComponent, isStandalone: true, selector: "lib-avatar", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"container\"> <span>{{text()}}</span> </div>", styles: [".container{width:36px;height:36px;border-radius:100%;text-align:center;justify-content:center;align-content:center;background-color:#d3d3d3}.container span{line-height:8px;color:#000}\n"] });
|
|
661
|
+
}
|
|
662
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AvatarComponent, decorators: [{
|
|
663
|
+
type: Component,
|
|
664
|
+
args: [{ selector: 'lib-avatar', imports: [], template: "<div class=\"container\"> <span>{{text()}}</span> </div>", styles: [".container{width:36px;height:36px;border-radius:100%;text-align:center;justify-content:center;align-content:center;background-color:#d3d3d3}.container span{line-height:8px;color:#000}\n"] }]
|
|
665
|
+
}] });
|
|
666
|
+
|
|
569
667
|
class DetailView {
|
|
570
668
|
item = signal(null, ...(ngDevMode ? [{ debugName: "item" }] : []));
|
|
571
669
|
route = inject(ActivatedRoute);
|
|
@@ -577,6 +675,9 @@ class DetailView {
|
|
|
577
675
|
onInit() {
|
|
578
676
|
this.getItem();
|
|
579
677
|
}
|
|
678
|
+
title() {
|
|
679
|
+
return this.itemService.typename.replace("_", " ");
|
|
680
|
+
}
|
|
580
681
|
onItemAvailable(item) {
|
|
581
682
|
this.item.set(item);
|
|
582
683
|
this.userService.loggedInUser.subscribe(user => { if (user) {
|
|
@@ -605,16 +706,15 @@ class DetailView {
|
|
|
605
706
|
}
|
|
606
707
|
|
|
607
708
|
class EditView {
|
|
608
|
-
typename = "";
|
|
609
709
|
createMode = signal(false, ...(ngDevMode ? [{ debugName: "createMode" }] : []));
|
|
610
|
-
heading = computed(() => { const prefix = this.createMode() ? "New " : "Edit "; return prefix + this.
|
|
710
|
+
heading = computed(() => { const prefix = this.createMode() ? "New " : "Edit "; return prefix + this.getTitle(); }, ...(ngDevMode ? [{ debugName: "heading" }] : []));
|
|
611
711
|
item = signal(null, ...(ngDevMode ? [{ debugName: "item" }] : []));
|
|
612
712
|
_route = inject(ActivatedRoute);
|
|
613
713
|
_location = inject(Location);
|
|
614
714
|
_userService = inject(UserService);
|
|
615
|
-
|
|
616
|
-
constructor(
|
|
617
|
-
this.
|
|
715
|
+
itemService;
|
|
716
|
+
constructor(itemService) {
|
|
717
|
+
this.itemService = itemService;
|
|
618
718
|
}
|
|
619
719
|
onInit() {
|
|
620
720
|
this.getItem();
|
|
@@ -630,6 +730,7 @@ class EditView {
|
|
|
630
730
|
this._location.back();
|
|
631
731
|
}
|
|
632
732
|
submit() {
|
|
733
|
+
console.log("submit called");
|
|
633
734
|
if (this.item()) {
|
|
634
735
|
this.save();
|
|
635
736
|
}
|
|
@@ -645,8 +746,14 @@ class EditView {
|
|
|
645
746
|
cancel() {
|
|
646
747
|
this.goBack();
|
|
647
748
|
}
|
|
749
|
+
getTitle() {
|
|
750
|
+
if (this.itemService && this.itemService.typename) {
|
|
751
|
+
return this.itemService.typename.replace("_", " ");
|
|
752
|
+
}
|
|
753
|
+
return "";
|
|
754
|
+
}
|
|
648
755
|
fetchRestOptions() {
|
|
649
|
-
this.
|
|
756
|
+
this.itemService.getOptions().subscribe(options => this.onOptions(options));
|
|
650
757
|
}
|
|
651
758
|
onUploadedFileReady(_file) {
|
|
652
759
|
}
|
|
@@ -655,13 +762,13 @@ class EditView {
|
|
|
655
762
|
createItem() {
|
|
656
763
|
const item = this.item();
|
|
657
764
|
if (item) {
|
|
658
|
-
this.
|
|
765
|
+
this.itemService.postItem(item).subscribe(item => this.saveFiles(item));
|
|
659
766
|
}
|
|
660
767
|
}
|
|
661
768
|
updateItem() {
|
|
662
769
|
const item = this.item();
|
|
663
770
|
if (item) {
|
|
664
|
-
this.
|
|
771
|
+
this.itemService.putItem(item).subscribe(item => this.saveFiles(item));
|
|
665
772
|
}
|
|
666
773
|
}
|
|
667
774
|
saveFiles(item) {
|
|
@@ -687,7 +794,7 @@ class EditView {
|
|
|
687
794
|
}
|
|
688
795
|
else {
|
|
689
796
|
const id_str = this._route.snapshot.paramMap.get('id');
|
|
690
|
-
this.
|
|
797
|
+
this.itemService.getItem(Number(id_str))
|
|
691
798
|
.subscribe(item => {
|
|
692
799
|
this.item.set(item);
|
|
693
800
|
this.onItemAvailable();
|
|
@@ -710,46 +817,6 @@ class EditView {
|
|
|
710
817
|
}
|
|
711
818
|
}
|
|
712
819
|
|
|
713
|
-
class ListView {
|
|
714
|
-
count = signal(0, ...(ngDevMode ? [{ debugName: "count" }] : []));
|
|
715
|
-
items = signal([], ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
716
|
-
next_url = null;
|
|
717
|
-
_route = inject(ActivatedRoute);
|
|
718
|
-
_location = inject(Location);
|
|
719
|
-
_userService = inject(UserService);
|
|
720
|
-
_itemService;
|
|
721
|
-
constructor(_itemService) {
|
|
722
|
-
this._itemService = _itemService;
|
|
723
|
-
}
|
|
724
|
-
getItems(query = new ItemQuery()) {
|
|
725
|
-
if (this.isSelfList()) {
|
|
726
|
-
this._userService.loggedInUser.subscribe(user => {
|
|
727
|
-
if (user) {
|
|
728
|
-
this.onUserAvailable(user, query);
|
|
729
|
-
}
|
|
730
|
-
});
|
|
731
|
-
}
|
|
732
|
-
else {
|
|
733
|
-
this._itemService.get(query).subscribe(items => this.onItems(items));
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
onItems(paginated) {
|
|
737
|
-
this.count.set(paginated.count);
|
|
738
|
-
this.items.set(paginated.results);
|
|
739
|
-
this.next_url = paginated.next;
|
|
740
|
-
}
|
|
741
|
-
onUserAvailable(user, query) {
|
|
742
|
-
this._itemService.getForUser(user, query).subscribe(items => this.onItems(items));
|
|
743
|
-
}
|
|
744
|
-
isSelfList() {
|
|
745
|
-
const url_segments = this._route.snapshot.url;
|
|
746
|
-
return (url_segments.length == 2) && (url_segments[1].path == "self");
|
|
747
|
-
}
|
|
748
|
-
goBack() {
|
|
749
|
-
this._location.back();
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
|
|
753
820
|
class SelectTableComponent {
|
|
754
821
|
itemType = input("", ...(ngDevMode ? [{ debugName: "itemType" }] : []));
|
|
755
822
|
selected = input([], ...(ngDevMode ? [{ debugName: "selected" }] : []));
|
|
@@ -758,7 +825,7 @@ class SelectTableComponent {
|
|
|
758
825
|
itemAdded = output();
|
|
759
826
|
itemRemoved = output();
|
|
760
827
|
searchChanged = output();
|
|
761
|
-
columnNames = computed(() => this.columns().map(c => c.name), ...(ngDevMode ? [{ debugName: "columnNames" }] : []));
|
|
828
|
+
columnNames = computed(() => { const names = this.columns().map(c => c.name); names.push("remove"); return names; }, ...(ngDevMode ? [{ debugName: "columnNames" }] : []));
|
|
762
829
|
searchControl = new FormControl('');
|
|
763
830
|
table = viewChild(MatTable, ...(ngDevMode ? [{ debugName: "table" }] : []));
|
|
764
831
|
ngOnInit() {
|
|
@@ -772,6 +839,7 @@ class SelectTableComponent {
|
|
|
772
839
|
if (this.searchControl.value) {
|
|
773
840
|
this.itemAdded.emit(this.searchControl.value);
|
|
774
841
|
}
|
|
842
|
+
this.searchControl.reset();
|
|
775
843
|
this.table()?.renderRows();
|
|
776
844
|
}
|
|
777
845
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: SelectTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
@@ -789,260 +857,64 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
789
857
|
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"] }]
|
|
790
858
|
}] });
|
|
791
859
|
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
860
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
861
|
+
class ListTableViewComponent {
|
|
862
|
+
itemType = input("", ...(ngDevMode ? [{ debugName: "itemType" }] : []));
|
|
863
|
+
columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
|
|
864
|
+
dataSource = input(...(ngDevMode ? [undefined, { debugName: "dataSource" }] : []));
|
|
865
|
+
searchFilter = input("", ...(ngDevMode ? [{ debugName: "searchFilter" }] : []));
|
|
866
|
+
pageSizeOptions = [20, 50, 100];
|
|
867
|
+
initialPageSize = 20;
|
|
868
|
+
columnNames = computed(() => this.columns().map(c => c.name), ...(ngDevMode ? [{ debugName: "columnNames" }] : []));
|
|
869
|
+
sort = viewChild(MatSort, ...(ngDevMode ? [{ debugName: "sort" }] : []));
|
|
870
|
+
paginator = viewChild(MatPaginator, ...(ngDevMode ? [{ debugName: "paginator" }] : []));
|
|
871
|
+
ngAfterViewInit() {
|
|
872
|
+
const paginator = this.paginator();
|
|
873
|
+
const sort = this.sort();
|
|
874
|
+
if (!paginator || !sort) {
|
|
875
|
+
return;
|
|
876
|
+
}
|
|
877
|
+
sort.sortChange.subscribe(() => this.reset());
|
|
878
|
+
merge(sort.sortChange, paginator.page)
|
|
879
|
+
.pipe(tap(() => this.fetch()))
|
|
880
|
+
.subscribe();
|
|
796
881
|
}
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
}] });
|
|
804
|
-
|
|
805
|
-
class DetailHeaderComponent {
|
|
806
|
-
id = input(0, ...(ngDevMode ? [{ debugName: "id" }] : []));
|
|
807
|
-
text = input("", ...(ngDevMode ? [{ debugName: "text" }] : []));
|
|
808
|
-
route = input("", ...(ngDevMode ? [{ debugName: "route" }] : []));
|
|
809
|
-
canEdit = input(false, ...(ngDevMode ? [{ debugName: "canEdit" }] : []));
|
|
810
|
-
canDelete = input(false, ...(ngDevMode ? [{ debugName: "canDelete" }] : []));
|
|
811
|
-
deleteClicked = output();
|
|
812
|
-
fullRoute = computed(() => "/" + this.route() + "s/edit/", ...(ngDevMode ? [{ debugName: "fullRoute" }] : []));
|
|
813
|
-
deleteClick() {
|
|
814
|
-
this.deleteClicked.emit();
|
|
882
|
+
reset() {
|
|
883
|
+
const paginator = this.paginator();
|
|
884
|
+
if (!paginator) {
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
887
|
+
paginator.pageIndex = 0;
|
|
815
888
|
}
|
|
816
|
-
|
|
817
|
-
|
|
889
|
+
fetch() {
|
|
890
|
+
const paginator = this.paginator();
|
|
891
|
+
const sort = this.sort();
|
|
892
|
+
const data_source = this.dataSource();
|
|
893
|
+
if (!paginator || !sort || !data_source) {
|
|
894
|
+
return;
|
|
895
|
+
}
|
|
896
|
+
data_source.fetch(new ItemQuery({
|
|
897
|
+
page: paginator.pageIndex + 1,
|
|
898
|
+
page_size: paginator.pageSize,
|
|
899
|
+
sort_order: sort.direction,
|
|
900
|
+
sort_field: sort.active,
|
|
901
|
+
filter: this.searchFilter()
|
|
902
|
+
}));
|
|
903
|
+
}
|
|
904
|
+
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$4.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$4.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$4.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$4.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$4.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$4.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$4.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$4.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$4.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$4.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$3.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$3.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i3$3.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"] }] });
|
|
818
906
|
}
|
|
819
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type:
|
|
907
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ListTableViewComponent, decorators: [{
|
|
820
908
|
type: Component,
|
|
821
|
-
args: [{ selector: 'lib-
|
|
909
|
+
args: [{ selector: 'lib-list-table-view', imports: [MatTableModule,
|
|
910
|
+
ReactiveFormsModule,
|
|
822
911
|
MatButtonModule,
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
fileUploaded = output();
|
|
830
|
-
onPreviewRead(name, content) {
|
|
831
|
-
this.previewLoaded.emit({ name: name, content: content });
|
|
832
|
-
}
|
|
833
|
-
onFileUpload(name, event) {
|
|
834
|
-
if (!event.target) {
|
|
835
|
-
return;
|
|
836
|
-
}
|
|
837
|
-
const input_element = event.target;
|
|
838
|
-
if (input_element.files && input_element.files.length > 0) {
|
|
839
|
-
const file = input_element.files[0];
|
|
840
|
-
this.fileUploaded.emit({ name: name, file: file });
|
|
841
|
-
const record = this.files().find(f => f.name == name);
|
|
842
|
-
if (record && record.file_type == "image") {
|
|
843
|
-
this.readFile(name, file);
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
readFile(name, file) {
|
|
848
|
-
const reader = new FileReader();
|
|
849
|
-
reader.readAsDataURL(file);
|
|
850
|
-
reader.onload = () => {
|
|
851
|
-
if (reader.result) {
|
|
852
|
-
this.previewLoaded.emit({ name: name, content: reader.result });
|
|
853
|
-
}
|
|
854
|
-
;
|
|
855
|
-
};
|
|
856
|
-
}
|
|
857
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FileUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
858
|
-
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" }, 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 </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"] }] });
|
|
859
|
-
}
|
|
860
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FileUploadComponent, decorators: [{
|
|
861
|
-
type: Component,
|
|
862
|
-
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 </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"] }]
|
|
863
|
-
}] });
|
|
864
|
-
|
|
865
|
-
class FileRecord {
|
|
866
|
-
name = "";
|
|
867
|
-
display_name = "";
|
|
868
|
-
file_type = "standard";
|
|
869
|
-
file = null;
|
|
870
|
-
remote = "";
|
|
871
|
-
local = "";
|
|
872
|
-
constructor(params = {}) {
|
|
873
|
-
Object.assign(this, params);
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
class UserDetailComponent extends DetailView {
|
|
878
|
-
typename = "user";
|
|
879
|
-
constructor() {
|
|
880
|
-
super(inject(UserService));
|
|
881
|
-
}
|
|
882
|
-
ngOnInit() {
|
|
883
|
-
this.onInit();
|
|
884
|
-
}
|
|
885
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
886
|
-
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]=\"typename\"\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"] }] });
|
|
887
|
-
}
|
|
888
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserDetailComponent, decorators: [{
|
|
889
|
-
type: Component,
|
|
890
|
-
args: [{ selector: 'lib-user-detail', imports: [NgIf,
|
|
891
|
-
BackButtonComponent,
|
|
892
|
-
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]=\"typename\"\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"] }]
|
|
893
|
-
}], ctorParameters: () => [] });
|
|
894
|
-
|
|
895
|
-
class UserEditComponent extends EditView {
|
|
896
|
-
typename = "User";
|
|
897
|
-
files = signal([new FileRecord({ name: "image",
|
|
898
|
-
display_name: "Profile Image",
|
|
899
|
-
file_type: "image" })], ...(ngDevMode ? [{ debugName: "files" }] : []));
|
|
900
|
-
formBuilder = inject(FormBuilder);
|
|
901
|
-
form = this.formBuilder.group({
|
|
902
|
-
username: [''],
|
|
903
|
-
email: [''],
|
|
904
|
-
first_name: [''],
|
|
905
|
-
last_name: [''],
|
|
906
|
-
phone: ['']
|
|
907
|
-
});
|
|
908
|
-
constructor() {
|
|
909
|
-
super(inject(UserService));
|
|
910
|
-
}
|
|
911
|
-
ngOnInit() {
|
|
912
|
-
this.onInit();
|
|
913
|
-
}
|
|
914
|
-
onItemAvailable() {
|
|
915
|
-
const item = this.item();
|
|
916
|
-
if (!item) {
|
|
917
|
-
return;
|
|
918
|
-
}
|
|
919
|
-
this.form.setValue({
|
|
920
|
-
username: item.username,
|
|
921
|
-
email: item.email,
|
|
922
|
-
first_name: item.first_name,
|
|
923
|
-
last_name: item.last_name,
|
|
924
|
-
phone: item.phone
|
|
925
|
-
});
|
|
926
|
-
if (item.profile_url) {
|
|
927
|
-
this.files.update(files => { const file = files.find(f => f.name === "image"); if (file) {
|
|
928
|
-
file.remote = item.url + item.profile_url;
|
|
929
|
-
} ; return files; });
|
|
930
|
-
}
|
|
931
|
-
super.onItemAvailable();
|
|
932
|
-
}
|
|
933
|
-
submit() {
|
|
934
|
-
this.item.update((item) => { if (item) {
|
|
935
|
-
item = this.updateFromForm(item);
|
|
936
|
-
} return item; });
|
|
937
|
-
console.log(this.item());
|
|
938
|
-
super.submit();
|
|
939
|
-
}
|
|
940
|
-
updateFromForm(item) {
|
|
941
|
-
item.username = this.form.value.username || "";
|
|
942
|
-
item.email = this.form.value.email || "";
|
|
943
|
-
item.first_name = this.form.value.first_name || "";
|
|
944
|
-
item.last_name = this.form.value.last_name || "";
|
|
945
|
-
item.phone = this.form.value.phone || "";
|
|
946
|
-
return item;
|
|
947
|
-
}
|
|
948
|
-
getTemplateItem() {
|
|
949
|
-
return new PortalMember();
|
|
950
|
-
}
|
|
951
|
-
onPreviewLoaded(preview) {
|
|
952
|
-
this.files.update(files => { const file = files.find(f => f.name === preview.name); if (file) {
|
|
953
|
-
file.local = preview.content;
|
|
954
|
-
} ; return files; });
|
|
955
|
-
}
|
|
956
|
-
onFileUploaded(upload) {
|
|
957
|
-
this.files.update(files => { const file = files.find(f => f.name === upload.name); if (file) {
|
|
958
|
-
file.file = upload.file;
|
|
959
|
-
} ; return files; });
|
|
960
|
-
}
|
|
961
|
-
saveFiles(item) {
|
|
962
|
-
this.files().forEach(record => { if (record.file) {
|
|
963
|
-
this._restService.postFile(item.id, record.name, record.file).subscribe(item => this.onItemUpdated(item));
|
|
964
|
-
} ; });
|
|
965
|
-
}
|
|
966
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserEditComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
967
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.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 @if(item(); as item){\n <div class=\"item-edit-container\">\n\n <h1 class=\"item-edit-header\">{{heading()}}</h1>\n\n <form class=\"form-card\" [formGroup]=\"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.valid\">\n <mat-icon>save</mat-icon></button>\n \n <button mat-fab\n class=\"form_action_button\"\n (click)=\"cancel()\">\n <mat-icon>cancel</mat-icon></button>\n </div>\n \n </form>\n </div>\n }\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$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.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$2.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: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.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"] }] });
|
|
968
|
-
}
|
|
969
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserEditComponent, decorators: [{
|
|
970
|
-
type: Component,
|
|
971
|
-
args: [{ selector: 'lib-user-edit', imports: [NgIf,
|
|
972
|
-
ReactiveFormsModule,
|
|
973
|
-
MatButtonModule,
|
|
974
|
-
BackButtonComponent,
|
|
975
|
-
MatInputModule,
|
|
976
|
-
MatFormFieldModule,
|
|
977
|
-
MatIconModule,
|
|
978
|
-
FileUploadComponent
|
|
979
|
-
], template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n @if(item(); as item){\n <div class=\"item-edit-container\">\n\n <h1 class=\"item-edit-header\">{{heading()}}</h1>\n\n <form class=\"form-card\" [formGroup]=\"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.valid\">\n <mat-icon>save</mat-icon></button>\n \n <button mat-fab\n class=\"form_action_button\"\n (click)=\"cancel()\">\n <mat-icon>cancel</mat-icon></button>\n </div>\n \n </form>\n </div>\n }\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"] }]
|
|
980
|
-
}], ctorParameters: () => [] });
|
|
981
|
-
|
|
982
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
983
|
-
class ListTableViewComponent {
|
|
984
|
-
itemType = input("", ...(ngDevMode ? [{ debugName: "itemType" }] : []));
|
|
985
|
-
columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
|
|
986
|
-
dataSource = input(...(ngDevMode ? [undefined, { debugName: "dataSource" }] : []));
|
|
987
|
-
searchFilter = input("", ...(ngDevMode ? [{ debugName: "searchFilter" }] : []));
|
|
988
|
-
pageSizeOptions = [20, 50, 100];
|
|
989
|
-
initialPageSize = 20;
|
|
990
|
-
columnNames = computed(() => this.columns().map(c => c.name), ...(ngDevMode ? [{ debugName: "columnNames" }] : []));
|
|
991
|
-
sort = viewChild(MatSort, ...(ngDevMode ? [{ debugName: "sort" }] : []));
|
|
992
|
-
paginator = viewChild(MatPaginator, ...(ngDevMode ? [{ debugName: "paginator" }] : []));
|
|
993
|
-
ngOnInit() {
|
|
994
|
-
const data_source = this.dataSource();
|
|
995
|
-
if (data_source) {
|
|
996
|
-
data_source.fetch(new ItemQuery({ page_size: this.initialPageSize }));
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
ngAfterViewInit() {
|
|
1000
|
-
const paginator = this.paginator();
|
|
1001
|
-
const sort = this.sort();
|
|
1002
|
-
if (!paginator || !sort) {
|
|
1003
|
-
return;
|
|
1004
|
-
}
|
|
1005
|
-
sort.sortChange.subscribe(() => this.reset());
|
|
1006
|
-
merge(sort.sortChange, paginator.page)
|
|
1007
|
-
.pipe(tap(() => this.fetch()))
|
|
1008
|
-
.subscribe();
|
|
1009
|
-
}
|
|
1010
|
-
reset() {
|
|
1011
|
-
const paginator = this.paginator();
|
|
1012
|
-
if (!paginator) {
|
|
1013
|
-
return;
|
|
1014
|
-
}
|
|
1015
|
-
paginator.pageIndex = 0;
|
|
1016
|
-
}
|
|
1017
|
-
fetch() {
|
|
1018
|
-
const paginator = this.paginator();
|
|
1019
|
-
const sort = this.sort();
|
|
1020
|
-
const data_source = this.dataSource();
|
|
1021
|
-
if (!paginator || !sort || !data_source) {
|
|
1022
|
-
return;
|
|
1023
|
-
}
|
|
1024
|
-
data_source.fetch(new ItemQuery({
|
|
1025
|
-
page: paginator.pageIndex + 1,
|
|
1026
|
-
page_size: paginator.pageSize,
|
|
1027
|
-
sort_order: sort.direction,
|
|
1028
|
-
sort_field: sort.active,
|
|
1029
|
-
filter: this.searchFilter()
|
|
1030
|
-
}));
|
|
1031
|
-
}
|
|
1032
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ListTableViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1033
|
-
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$4.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$4.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$4.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$4.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$4.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$4.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$4.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$4.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$4.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$4.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$3.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$3.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i3$3.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"] }] });
|
|
1034
|
-
}
|
|
1035
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ListTableViewComponent, decorators: [{
|
|
1036
|
-
type: Component,
|
|
1037
|
-
args: [{ selector: 'lib-list-table-view', imports: [MatTableModule,
|
|
1038
|
-
ReactiveFormsModule,
|
|
1039
|
-
MatButtonModule,
|
|
1040
|
-
MatInputModule,
|
|
1041
|
-
MatIconModule,
|
|
1042
|
-
MatPaginatorModule,
|
|
1043
|
-
MatSortModule,
|
|
1044
|
-
RouterModule
|
|
1045
|
-
], 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"] }]
|
|
912
|
+
MatInputModule,
|
|
913
|
+
MatIconModule,
|
|
914
|
+
MatPaginatorModule,
|
|
915
|
+
MatSortModule,
|
|
916
|
+
RouterModule
|
|
917
|
+
], 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"] }]
|
|
1046
918
|
}] });
|
|
1047
919
|
|
|
1048
920
|
// Datasource needs any
|
|
@@ -1052,9 +924,6 @@ class ListScrollViewComponent {
|
|
|
1052
924
|
pageSize = input(20, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
|
|
1053
925
|
dataSource = input(...(ngDevMode ? [undefined, { debugName: "dataSource" }] : []));
|
|
1054
926
|
listItemTemplate = input(null, ...(ngDevMode ? [{ debugName: "listItemTemplate" }] : []));
|
|
1055
|
-
ngOnInit() {
|
|
1056
|
-
this.reset();
|
|
1057
|
-
}
|
|
1058
927
|
reset() {
|
|
1059
928
|
const data_source = this.dataSource();
|
|
1060
929
|
if (!data_source) {
|
|
@@ -1074,6 +943,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
1074
943
|
ScrollingModule], 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"] }]
|
|
1075
944
|
}] });
|
|
1076
945
|
|
|
946
|
+
class BackButtonComponent {
|
|
947
|
+
location = inject(Location);
|
|
948
|
+
goBack() {
|
|
949
|
+
this.location.back();
|
|
950
|
+
}
|
|
951
|
+
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: i3.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
|
+
}
|
|
954
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: BackButtonComponent, decorators: [{
|
|
955
|
+
type: Component,
|
|
956
|
+
args: [{ selector: 'lib-back-button', imports: [MatIconModule, MatButtonModule], 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"] }]
|
|
957
|
+
}] });
|
|
958
|
+
|
|
1077
959
|
class SearchBarComponent {
|
|
1078
960
|
itemType = input("", ...(ngDevMode ? [{ debugName: "itemType" }] : []));
|
|
1079
961
|
sortFields = input([], ...(ngDevMode ? [{ debugName: "sortFields" }] : []));
|
|
@@ -1110,6 +992,8 @@ class ListDataSource extends DataSource {
|
|
|
1110
992
|
loading = signal(true, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
1111
993
|
searchTerm = signal("", ...(ngDevMode ? [{ debugName: "searchTerm" }] : []));
|
|
1112
994
|
pageSize = signal(20, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
|
|
995
|
+
hasFetched = signal(false, ...(ngDevMode ? [{ debugName: "hasFetched" }] : []));
|
|
996
|
+
sourceIsEmpty = computed(() => this.length() == 0 && this.hasFetched() && !this.searchTerm(), ...(ngDevMode ? [{ debugName: "sourceIsEmpty" }] : []));
|
|
1113
997
|
consumerType;
|
|
1114
998
|
items = new BehaviorSubject([]);
|
|
1115
999
|
itemService;
|
|
@@ -1117,6 +1001,7 @@ class ListDataSource extends DataSource {
|
|
|
1117
1001
|
fetchedPages = new Set();
|
|
1118
1002
|
constructor(itemService, consumerType = "table") {
|
|
1119
1003
|
super();
|
|
1004
|
+
console.log("created");
|
|
1120
1005
|
this.itemService = itemService;
|
|
1121
1006
|
this.consumerType = consumerType;
|
|
1122
1007
|
}
|
|
@@ -1160,6 +1045,7 @@ class ListDataSource extends DataSource {
|
|
|
1160
1045
|
}
|
|
1161
1046
|
onResponse(response) {
|
|
1162
1047
|
this.length.set(response.count);
|
|
1048
|
+
this.hasFetched.set(true);
|
|
1163
1049
|
if (this.hasTableConsumer()) {
|
|
1164
1050
|
this.items.next(response.results);
|
|
1165
1051
|
}
|
|
@@ -1181,9 +1067,13 @@ class ListViewComponent {
|
|
|
1181
1067
|
itemDetailTemplate = input(null, ...(ngDevMode ? [{ debugName: "itemDetailTemplate" }] : []));
|
|
1182
1068
|
columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
|
|
1183
1069
|
sortFields = input([], ...(ngDevMode ? [{ debugName: "sortFields" }] : []));
|
|
1070
|
+
noSelfItemsMessage = input(...(ngDevMode ? [undefined, { debugName: "noSelfItemsMessage" }] : []));
|
|
1071
|
+
noItemsCanCreateMessage = input(...(ngDevMode ? [undefined, { debugName: "noItemsCanCreateMessage" }] : []));
|
|
1072
|
+
noItemsMessage = input(...(ngDevMode ? [undefined, { debugName: "noItemsMessage" }] : []));
|
|
1184
1073
|
selectedViewType = signal("table", ...(ngDevMode ? [{ debugName: "selectedViewType" }] : []));
|
|
1185
1074
|
pageSize = 20;
|
|
1186
1075
|
pageSizeOptions = [20, 50, 100];
|
|
1076
|
+
route = inject(ActivatedRoute);
|
|
1187
1077
|
dataSource = undefined;
|
|
1188
1078
|
sort = viewChild(MatSort, ...(ngDevMode ? [{ debugName: "sort" }] : []));
|
|
1189
1079
|
columnNames = computed(() => this.columns().map(c => c.name), ...(ngDevMode ? [{ debugName: "columnNames" }] : []));
|
|
@@ -1212,10 +1102,13 @@ class ListViewComponent {
|
|
|
1212
1102
|
itemType() {
|
|
1213
1103
|
const item_service = this.itemService();
|
|
1214
1104
|
if (item_service) {
|
|
1215
|
-
return item_service.
|
|
1105
|
+
return item_service.typePlural();
|
|
1216
1106
|
}
|
|
1217
1107
|
return "";
|
|
1218
1108
|
}
|
|
1109
|
+
title() {
|
|
1110
|
+
return this.itemType().replace("_", " ");
|
|
1111
|
+
}
|
|
1219
1112
|
isTableView() {
|
|
1220
1113
|
return this.selectedViewType() === "table";
|
|
1221
1114
|
}
|
|
@@ -1236,8 +1129,12 @@ class ListViewComponent {
|
|
|
1236
1129
|
console.log(this.selectedViewType());
|
|
1237
1130
|
this.resetDataSource();
|
|
1238
1131
|
}
|
|
1132
|
+
isSelfList() {
|
|
1133
|
+
const url_segments = this.route.snapshot.url;
|
|
1134
|
+
return (url_segments.length == 2) && (url_segments[1].path == "self");
|
|
1135
|
+
}
|
|
1239
1136
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ListViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1240
|
-
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 } }, 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\">{{
|
|
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$5.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$5.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$5.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.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.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" }] });
|
|
1241
1138
|
}
|
|
1242
1139
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ListViewComponent, decorators: [{
|
|
1243
1140
|
type: Component,
|
|
@@ -1254,129 +1151,252 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
1254
1151
|
MatInputModule,
|
|
1255
1152
|
MatTooltipModule,
|
|
1256
1153
|
MatButtonModule,
|
|
1257
|
-
SearchBarComponent], template: "<lib-back-button></lib-back-button>\n\n<div class=\"container\">\n <div class=\"header\">\n <h1 class=\"title\">{{
|
|
1154
|
+
SearchBarComponent], 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"] }]
|
|
1258
1155
|
}] });
|
|
1259
1156
|
|
|
1260
|
-
class
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1157
|
+
class DetailHeaderComponent {
|
|
1158
|
+
id = input(0, ...(ngDevMode ? [{ debugName: "id" }] : []));
|
|
1159
|
+
text = input("", ...(ngDevMode ? [{ debugName: "text" }] : []));
|
|
1160
|
+
route = input("", ...(ngDevMode ? [{ debugName: "route" }] : []));
|
|
1161
|
+
canEdit = input(false, ...(ngDevMode ? [{ debugName: "canEdit" }] : []));
|
|
1162
|
+
canDelete = input(false, ...(ngDevMode ? [{ debugName: "canDelete" }] : []));
|
|
1163
|
+
deleteClicked = output();
|
|
1164
|
+
fullRoute = computed(() => "/" + this.route() + "/edit/", ...(ngDevMode ? [{ debugName: "fullRoute" }] : []));
|
|
1165
|
+
deleteClick() {
|
|
1166
|
+
this.deleteClicked.emit();
|
|
1167
|
+
}
|
|
1168
|
+
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: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
1264
1170
|
}
|
|
1265
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type:
|
|
1171
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: DetailHeaderComponent, decorators: [{
|
|
1266
1172
|
type: Component,
|
|
1267
|
-
args: [{ selector: 'lib-
|
|
1268
|
-
|
|
1173
|
+
args: [{ selector: 'lib-detail-header', imports: [RouterModule,
|
|
1174
|
+
MatButtonModule,
|
|
1175
|
+
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"] }]
|
|
1269
1176
|
}] });
|
|
1270
1177
|
|
|
1271
|
-
class
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
}
|
|
1278
|
-
|
|
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: [{
|
|
1279
1217
|
type: Component,
|
|
1280
|
-
args: [{ selector: 'lib-
|
|
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"] }]
|
|
1281
1219
|
}] });
|
|
1282
1220
|
|
|
1283
|
-
class
|
|
1284
|
-
|
|
1221
|
+
class FileRecord {
|
|
1222
|
+
name = "";
|
|
1223
|
+
display_name = "";
|
|
1224
|
+
file_type = "standard";
|
|
1225
|
+
file = null;
|
|
1226
|
+
remote = "";
|
|
1227
|
+
local = "";
|
|
1228
|
+
constructor(params = {}) {
|
|
1229
|
+
Object.assign(this, params);
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
class UserDetailComponent extends DetailView {
|
|
1285
1234
|
constructor() {
|
|
1286
|
-
super(inject(
|
|
1235
|
+
super(inject(UserService));
|
|
1287
1236
|
}
|
|
1288
1237
|
ngOnInit() {
|
|
1289
1238
|
this.onInit();
|
|
1290
1239
|
}
|
|
1291
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type:
|
|
1292
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type:
|
|
1240
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1241
|
+
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"] }] });
|
|
1293
1242
|
}
|
|
1294
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type:
|
|
1243
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserDetailComponent, decorators: [{
|
|
1295
1244
|
type: Component,
|
|
1296
|
-
args: [{ selector: 'lib-
|
|
1297
|
-
|
|
1298
|
-
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.name\"\n [id]=\"item.id\"\n [route]=\"typename\"></lib-detail-header>\n \n <div class=\"item-field\">{{item.name}}</div>\n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}\n"] }]
|
|
1245
|
+
args: [{ selector: 'lib-user-detail', imports: [BackButtonComponent,
|
|
1246
|
+
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"] }]
|
|
1299
1247
|
}], ctorParameters: () => [] });
|
|
1300
1248
|
|
|
1301
|
-
class
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1249
|
+
class UserEditComponent extends EditView {
|
|
1250
|
+
files = signal([new FileRecord({
|
|
1251
|
+
name: "image",
|
|
1252
|
+
display_name: "Profile Image",
|
|
1253
|
+
file_type: "image"
|
|
1254
|
+
})], ...(ngDevMode ? [{ debugName: "files" }] : []));
|
|
1255
|
+
formBuilder = inject(FormBuilder);
|
|
1256
|
+
form = this.formBuilder.group({
|
|
1257
|
+
username: [''],
|
|
1258
|
+
email: [''],
|
|
1259
|
+
first_name: [''],
|
|
1260
|
+
last_name: [''],
|
|
1261
|
+
phone: ['']
|
|
1262
|
+
});
|
|
1263
|
+
constructor() {
|
|
1264
|
+
super(inject(UserService));
|
|
1265
|
+
}
|
|
1266
|
+
ngOnInit() {
|
|
1267
|
+
this.onInit();
|
|
1268
|
+
}
|
|
1269
|
+
onItemAvailable() {
|
|
1270
|
+
const item = this.item();
|
|
1271
|
+
if (!item) {
|
|
1272
|
+
return;
|
|
1273
|
+
}
|
|
1274
|
+
this.form.setValue({
|
|
1275
|
+
username: item.username,
|
|
1276
|
+
email: item.email,
|
|
1277
|
+
first_name: item.first_name,
|
|
1278
|
+
last_name: item.last_name,
|
|
1279
|
+
phone: item.phone
|
|
1280
|
+
});
|
|
1281
|
+
if (item.profile_url) {
|
|
1282
|
+
this.files.update(files => { const file = files.find(f => f.name === "image"); if (file) {
|
|
1283
|
+
file.remote = item.url + item.profile_url;
|
|
1284
|
+
} ; return files; });
|
|
1285
|
+
}
|
|
1286
|
+
super.onItemAvailable();
|
|
1287
|
+
}
|
|
1288
|
+
submit() {
|
|
1289
|
+
this.item.update((item) => { if (item) {
|
|
1290
|
+
item = this.updateFromForm(item);
|
|
1291
|
+
} return item; });
|
|
1292
|
+
console.log(this.item());
|
|
1293
|
+
super.submit();
|
|
1294
|
+
}
|
|
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
|
+
onPreviewLoaded(preview) {
|
|
1307
|
+
this.files.update(files => { const file = files.find(f => f.name === preview.name); if (file) {
|
|
1308
|
+
file.local = preview.content;
|
|
1309
|
+
} ; return files; });
|
|
1310
|
+
}
|
|
1311
|
+
onFileUploaded(upload) {
|
|
1312
|
+
this.files.update(files => { const file = files.find(f => f.name === upload.name); if (file) {
|
|
1313
|
+
file.file = upload.file;
|
|
1314
|
+
} ; return files; });
|
|
1315
|
+
}
|
|
1316
|
+
saveFiles(item) {
|
|
1317
|
+
this.files().forEach(record => { if (record.file) {
|
|
1318
|
+
this.itemService.postFile(item.id, record.name, record.file).subscribe(item => this.onItemUpdated(item));
|
|
1319
|
+
} ; });
|
|
1320
|
+
}
|
|
1321
|
+
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: "17.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 @if(item(); as item){\n <div class=\"item-edit-container\">\n\n <h1 class=\"item-edit-header\">{{heading() | titlecase}}</h1>\n\n <form class=\"form-card\" [formGroup]=\"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 </form>\n\n <div class=\"button_group\">\n <button mat-fab\n class=\"form_action_button\"\n type=\"submit\"\n [disabled]=\"!form.valid\">\n <mat-icon>save</mat-icon></button>\n \n <button mat-fab\n class=\"form_action_button\"\n (click)=\"cancel()\">\n <mat-icon>cancel</mat-icon></button>\n </div>\n </div>\n }\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$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.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$2.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: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.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" }] });
|
|
1306
1323
|
}
|
|
1307
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type:
|
|
1324
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserEditComponent, decorators: [{
|
|
1308
1325
|
type: Component,
|
|
1309
|
-
args: [{ selector: 'lib-
|
|
1310
|
-
|
|
1326
|
+
args: [{ selector: 'lib-user-edit', imports: [
|
|
1327
|
+
ReactiveFormsModule,
|
|
1328
|
+
MatButtonModule,
|
|
1329
|
+
BackButtonComponent,
|
|
1330
|
+
MatInputModule,
|
|
1331
|
+
MatFormFieldModule,
|
|
1332
|
+
MatIconModule,
|
|
1333
|
+
FileUploadComponent,
|
|
1334
|
+
TitleCasePipe
|
|
1335
|
+
], template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n @if(item(); as item){\n <div class=\"item-edit-container\">\n\n <h1 class=\"item-edit-header\">{{heading() | titlecase}}</h1>\n\n <form class=\"form-card\" [formGroup]=\"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 </form>\n\n <div class=\"button_group\">\n <button mat-fab\n class=\"form_action_button\"\n type=\"submit\"\n [disabled]=\"!form.valid\">\n <mat-icon>save</mat-icon></button>\n \n <button mat-fab\n class=\"form_action_button\"\n (click)=\"cancel()\">\n <mat-icon>cancel</mat-icon></button>\n </div>\n </div>\n }\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
|
+
}], ctorParameters: () => [] });
|
|
1311
1337
|
|
|
1312
|
-
class
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
{
|
|
1316
|
-
{ name: 'is_partner', title: 'Is Partner', element_type: 'boolean' }];
|
|
1317
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1318
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.1", type: OrganizationComponent, isStandalone: true, selector: "lib-organization", ngImport: i0, template: "<lib-list-view\n [itemService]=\"itemService\"\n [columns]=\"columns\"\n >\n</lib-list-view>\n\n\n\n", styles: [":host{flex-grow:1}\n"], dependencies: [{ kind: "component", type: ListViewComponent, selector: "lib-list-view", inputs: ["viewType", "itemService", "itemDetailTemplate", "columns", "sortFields"] }] });
|
|
1338
|
+
class UserListDetailComponent {
|
|
1339
|
+
item = input(...(ngDevMode ? [undefined, { debugName: "item" }] : []));
|
|
1340
|
+
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$3.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i1$3.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i1$3.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i1$3.MatCardSubtitle, selector: "mat-card-subtitle, [mat-card-subtitle], [matCardSubtitle]" }, { kind: "directive", type: i1$3.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "component", type: i1$3.MatCardTitleGroup, selector: "mat-card-title-group" }] });
|
|
1319
1342
|
}
|
|
1320
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type:
|
|
1343
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserListDetailComponent, decorators: [{
|
|
1321
1344
|
type: Component,
|
|
1322
|
-
args: [{ selector: 'lib-
|
|
1323
|
-
|
|
1324
|
-
], template: "<lib-list-view\n [itemService]=\"itemService\"\n [columns]=\"columns\"\n >\n</lib-list-view>\n\n\n\n", styles: [":host{flex-grow:1}\n"] }]
|
|
1345
|
+
args: [{ selector: 'lib-user-list-detail', imports: [MatListModule,
|
|
1346
|
+
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"] }]
|
|
1325
1347
|
}] });
|
|
1326
1348
|
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
1334
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressService, providedIn: 'root' });
|
|
1335
|
-
}
|
|
1336
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressService, decorators: [{
|
|
1337
|
-
type: Injectable,
|
|
1338
|
-
args: [{
|
|
1339
|
-
providedIn: 'root'
|
|
1340
|
-
}]
|
|
1341
|
-
}] });
|
|
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
|
+
];
|
|
1342
1355
|
|
|
1343
|
-
class
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1356
|
+
class UserComponent {
|
|
1357
|
+
viewType = signal("list", ...(ngDevMode ? [{ debugName: "viewType" }] : []));
|
|
1358
|
+
itemService = inject(UserService);
|
|
1359
|
+
columns = USER_TABLE_FULL;
|
|
1360
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1361
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.1", type: UserComponent, isStandalone: true, selector: "lib-user", ngImport: i0, template: "<lib-list-view\n [itemService]=\"itemService\"\n [itemDetailTemplate]=\"listItemTemplate\"\n [columns]=\"columns\"\n [viewType]=\"viewType()\"\n >\n <ng-template #listItemTemplate let-item=\"item\">\n <lib-user-list-detail [item]=\"item\"\n [routerLink]=\"['/' + itemService.typePlural() + '/detail/', item.id]\"\n [routerLinkActive]=\"['is-active']\">\n </lib-user-list-detail>\n </ng-template>\n</lib-list-view>\n", styles: [":host{flex-grow:1}\n"], dependencies: [{ kind: "component", type: ListViewComponent, selector: "lib-list-view", inputs: ["viewType", "itemService", "itemDetailTemplate", "columns", "sortFields", "noSelfItemsMessage", "noItemsCanCreateMessage", "noItemsMessage"] }, { kind: "component", type: UserListDetailComponent, selector: "lib-user-list-detail", inputs: ["item"] }, { 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"] }] });
|
|
1347
1362
|
}
|
|
1348
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type:
|
|
1363
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserComponent, decorators: [{
|
|
1349
1364
|
type: Component,
|
|
1350
|
-
args: [{ selector: 'lib-
|
|
1365
|
+
args: [{ selector: 'lib-user', imports: [ListViewComponent, UserListDetailComponent, RouterModule], template: "<lib-list-view\n [itemService]=\"itemService\"\n [itemDetailTemplate]=\"listItemTemplate\"\n [columns]=\"columns\"\n [viewType]=\"viewType()\"\n >\n <ng-template #listItemTemplate let-item=\"item\">\n <lib-user-list-detail [item]=\"item\"\n [routerLink]=\"['/' + itemService.typePlural() + '/detail/', item.id]\"\n [routerLinkActive]=\"['is-active']\">\n </lib-user-list-detail>\n </ng-template>\n</lib-list-view>\n", styles: [":host{flex-grow:1}\n"] }]
|
|
1351
1366
|
}] });
|
|
1352
1367
|
|
|
1353
|
-
class
|
|
1354
|
-
typename = "organization";
|
|
1355
|
-
address = signal(null, ...(ngDevMode ? [{ debugName: "address" }] : []));
|
|
1356
|
-
addressService = inject(AddressService);
|
|
1368
|
+
class GroupDetailComponent extends DetailView {
|
|
1357
1369
|
constructor() {
|
|
1358
|
-
super(inject(
|
|
1370
|
+
super(inject(GroupService));
|
|
1359
1371
|
}
|
|
1360
1372
|
ngOnInit() {
|
|
1361
1373
|
this.onInit();
|
|
1362
1374
|
}
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
}
|
|
1366
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1367
|
-
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]=\"typename\"></lib-detail-header>\n\n <div class=\"item-field\">\n {{item.description}}\n </div>\n \n @if(address(); as address)\n {\n <h3>Address</h3>\n <lib-address-detail [address]=\"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"] }] });
|
|
1375
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: GroupDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1376
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: GroupDetailComponent, isStandalone: true, selector: "lib-group-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.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\">{{item.name}}</div>\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"] }] });
|
|
1368
1377
|
}
|
|
1369
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type:
|
|
1378
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: GroupDetailComponent, decorators: [{
|
|
1370
1379
|
type: Component,
|
|
1371
|
-
args: [{ selector: 'lib-
|
|
1372
|
-
DetailHeaderComponent
|
|
1380
|
+
args: [{ selector: 'lib-group-detail', imports: [BackButtonComponent,
|
|
1381
|
+
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.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\">{{item.name}}</div>\n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}\n"] }]
|
|
1373
1382
|
}], ctorParameters: () => [] });
|
|
1374
1383
|
|
|
1384
|
+
class GroupComponent {
|
|
1385
|
+
itemService = inject(GroupService);
|
|
1386
|
+
columns = [{ name: 'name', title: 'Name', element_type: 'string' }];
|
|
1387
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: GroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1388
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.1", type: GroupComponent, isStandalone: true, selector: "lib-group", ngImport: i0, template: "<lib-list-view\n [itemService]=\"itemService\"\n [columns]=\"columns\"\n >\n</lib-list-view>\n\n", styles: [":host{flex-grow:1}\n"], dependencies: [{ kind: "component", type: ListViewComponent, selector: "lib-list-view", inputs: ["viewType", "itemService", "itemDetailTemplate", "columns", "sortFields", "noSelfItemsMessage", "noItemsCanCreateMessage", "noItemsMessage"] }] });
|
|
1389
|
+
}
|
|
1390
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: GroupComponent, decorators: [{
|
|
1391
|
+
type: Component,
|
|
1392
|
+
args: [{ selector: 'lib-group', imports: [ListViewComponent], template: "<lib-list-view\n [itemService]=\"itemService\"\n [columns]=\"columns\"\n >\n</lib-list-view>\n\n", styles: [":host{flex-grow:1}\n"] }]
|
|
1393
|
+
}] });
|
|
1394
|
+
|
|
1375
1395
|
class AddressEditComponent {
|
|
1376
1396
|
countryOptions = input([], ...(ngDevMode ? [{ debugName: "countryOptions" }] : []));
|
|
1377
1397
|
form = input(...(ngDevMode ? [undefined, { debugName: "form" }] : []));
|
|
1378
1398
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressEditComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1379
|
-
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\"
|
|
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: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.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$2.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$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
|
|
1380
1400
|
}
|
|
1381
1401
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressEditComponent, decorators: [{
|
|
1382
1402
|
type: Component,
|
|
@@ -1384,7 +1404,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
1384
1404
|
MatSelectModule,
|
|
1385
1405
|
MatInputModule,
|
|
1386
1406
|
ReactiveFormsModule
|
|
1387
|
-
], 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\"
|
|
1407
|
+
], 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}" }]
|
|
1408
|
+
}] });
|
|
1409
|
+
|
|
1410
|
+
class AddressDetailComponent {
|
|
1411
|
+
address = input(...(ngDevMode ? [undefined, { debugName: "address" }] : []));
|
|
1412
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1413
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: AddressDetailComponent, isStandalone: true, selector: "lib-address-detail", inputs: { address: { classPropertyName: "address", publicName: "address", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if(address(); as address){\n<div class=\"item-field\" style=\"display:flex;flex-wrap: wrap;justify-content: center;align-content: center;\">\n <span style=\"margin-left: 3px;\">{{address.line1}}, </span>\n <span style=\"margin-left: 3px;\">{{address.line2}},</span>\n @if(address.line3){\n <span style=\"margin-left: 3px;\">{{address.line3}},</span>\n }\n @if(address.city){\n <span style=\"margin-left: 3px;\">{{address.city}},</span>\n }\n <span style=\"margin-left: 3px;\">{{address.region}},</span>\n @if(address.postcode){ \n <span style=\"margin-left: 3px;\">{{address.postcode}},</span>\n }\n <span style=\"margin-left: 3px;\">{{address.country_name}}</span>\n</div>\n}", styles: [""] });
|
|
1414
|
+
}
|
|
1415
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressDetailComponent, decorators: [{
|
|
1416
|
+
type: Component,
|
|
1417
|
+
args: [{ selector: 'lib-address-detail', imports: [], template: "@if(address(); as address){\n<div class=\"item-field\" style=\"display:flex;flex-wrap: wrap;justify-content: center;align-content: center;\">\n <span style=\"margin-left: 3px;\">{{address.line1}}, </span>\n <span style=\"margin-left: 3px;\">{{address.line2}},</span>\n @if(address.line3){\n <span style=\"margin-left: 3px;\">{{address.line3}},</span>\n }\n @if(address.city){\n <span style=\"margin-left: 3px;\">{{address.city}},</span>\n }\n <span style=\"margin-left: 3px;\">{{address.region}},</span>\n @if(address.postcode){ \n <span style=\"margin-left: 3px;\">{{address.postcode}},</span>\n }\n <span style=\"margin-left: 3px;\">{{address.country_name}}</span>\n</div>\n}" }]
|
|
1388
1418
|
}] });
|
|
1389
1419
|
|
|
1390
1420
|
class AddressForm {
|
|
@@ -1401,27 +1431,100 @@ class AddressForm {
|
|
|
1401
1431
|
setValue(item) {
|
|
1402
1432
|
this.form.setValue({
|
|
1403
1433
|
line1: item.line1,
|
|
1404
|
-
line2: item.line2,
|
|
1405
|
-
line3: item.line3,
|
|
1406
|
-
city: item.city,
|
|
1434
|
+
line2: item.line2 || "",
|
|
1435
|
+
line3: item.line3 || "",
|
|
1436
|
+
city: item.city || "",
|
|
1407
1437
|
region: item.region,
|
|
1408
|
-
postcode: item.postcode,
|
|
1438
|
+
postcode: item.postcode || "",
|
|
1409
1439
|
country: item.country
|
|
1410
1440
|
});
|
|
1411
1441
|
}
|
|
1412
1442
|
updateItem(item) {
|
|
1413
1443
|
const value = this.form.value;
|
|
1414
1444
|
item.line1 = value.line1 || "";
|
|
1415
|
-
item.line2 = value.line2 ||
|
|
1416
|
-
item.line3 = value.line3 ||
|
|
1417
|
-
item.city = value.city ||
|
|
1445
|
+
item.line2 = value.line2 || null;
|
|
1446
|
+
item.line3 = value.line3 || null;
|
|
1447
|
+
item.city = value.city || null;
|
|
1418
1448
|
item.region = value.region || "";
|
|
1419
|
-
item.postcode = value.postcode ||
|
|
1449
|
+
item.postcode = value.postcode || null;
|
|
1420
1450
|
item.country = value.country || "";
|
|
1421
1451
|
return item;
|
|
1422
1452
|
}
|
|
1423
1453
|
}
|
|
1424
1454
|
|
|
1455
|
+
class OrganizationComponent {
|
|
1456
|
+
itemService = inject(OrganizationService);
|
|
1457
|
+
columns = [{ name: 'name', title: 'Name', element_type: 'string' },
|
|
1458
|
+
{ name: 'website', title: 'Website', element_type: 'url' },
|
|
1459
|
+
{ name: 'is_partner', title: 'Is Partner', element_type: 'boolean' }];
|
|
1460
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1461
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.1", type: OrganizationComponent, isStandalone: true, selector: "lib-organization", ngImport: i0, template: "<lib-list-view\n [itemService]=\"itemService\"\n [columns]=\"columns\"\n >\n</lib-list-view>\n\n\n\n", styles: [":host{flex-grow:1}\n"], dependencies: [{ kind: "component", type: ListViewComponent, selector: "lib-list-view", inputs: ["viewType", "itemService", "itemDetailTemplate", "columns", "sortFields", "noSelfItemsMessage", "noItemsCanCreateMessage", "noItemsMessage"] }] });
|
|
1462
|
+
}
|
|
1463
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationComponent, decorators: [{
|
|
1464
|
+
type: Component,
|
|
1465
|
+
args: [{ selector: 'lib-organization', imports: [
|
|
1466
|
+
ListViewComponent
|
|
1467
|
+
], template: "<lib-list-view\n [itemService]=\"itemService\"\n [columns]=\"columns\"\n >\n</lib-list-view>\n\n\n\n", styles: [":host{flex-grow:1}\n"] }]
|
|
1468
|
+
}] });
|
|
1469
|
+
|
|
1470
|
+
class OrganizationDetailComponent extends DetailView {
|
|
1471
|
+
address = signal(null, ...(ngDevMode ? [{ debugName: "address" }] : []));
|
|
1472
|
+
addressService = inject(AddressService);
|
|
1473
|
+
constructor() {
|
|
1474
|
+
super(inject(OrganizationService));
|
|
1475
|
+
}
|
|
1476
|
+
ngOnInit() {
|
|
1477
|
+
this.onInit();
|
|
1478
|
+
}
|
|
1479
|
+
onItemAndUserAvailable(item, _user) {
|
|
1480
|
+
this.addressService.getUrl(item.address).subscribe(address => this.address.set(address));
|
|
1481
|
+
}
|
|
1482
|
+
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 @if(address(); as address)\n {\n <h3>Address</h3>\n <lib-address-detail [address]=\"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
|
+
}
|
|
1485
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationDetailComponent, decorators: [{
|
|
1486
|
+
type: Component,
|
|
1487
|
+
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 @if(address(); as address)\n {\n <h3>Address</h3>\n <lib-address-detail [address]=\"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
|
+
}], ctorParameters: () => [] });
|
|
1490
|
+
|
|
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
|
+
|
|
1425
1528
|
class OrganizationForm {
|
|
1426
1529
|
formBuilder = inject(FormBuilder);
|
|
1427
1530
|
form;
|
|
@@ -1454,14 +1557,8 @@ class OrganizationForm {
|
|
|
1454
1557
|
}
|
|
1455
1558
|
|
|
1456
1559
|
class OrganizationEditComponent extends EditView {
|
|
1457
|
-
typename = "Organization";
|
|
1458
1560
|
countryOptions = signal([], ...(ngDevMode ? [{ debugName: "countryOptions" }] : []));
|
|
1459
|
-
|
|
1460
|
-
selectedMembers = signal([], ...(ngDevMode ? [{ debugName: "selectedMembers" }] : []));
|
|
1461
|
-
columns = [{ name: 'first_name', title: 'First Name', element_type: 'string' },
|
|
1462
|
-
{ name: 'last_name', title: 'Surname', element_type: 'string' },
|
|
1463
|
-
{ name: 'username', title: 'Username', element_type: 'string' },
|
|
1464
|
-
{ name: 'email', title: 'Email', element_type: 'string' }];
|
|
1561
|
+
selectionManager = new SelectionManager();
|
|
1465
1562
|
form = new OrganizationForm();
|
|
1466
1563
|
address = new Address();
|
|
1467
1564
|
addressService = inject(AddressService);
|
|
@@ -1477,15 +1574,9 @@ class OrganizationEditComponent extends EditView {
|
|
|
1477
1574
|
if (item) {
|
|
1478
1575
|
this.fetchAddress(item.address);
|
|
1479
1576
|
this.form.updateFromItem(item);
|
|
1480
|
-
|
|
1481
|
-
const query = new ItemQuery({ queries: queries });
|
|
1482
|
-
this._userService.get(query).subscribe(users => this.selectedMembers.set(users.results));
|
|
1483
|
-
this._userService.get().subscribe(users => this.updateCandidates(users));
|
|
1577
|
+
this.selectionManager.fetchCandidates(this.itemService.typename, item.id);
|
|
1484
1578
|
}
|
|
1485
1579
|
}
|
|
1486
|
-
updateCandidates(users) {
|
|
1487
|
-
this.candidateMembers.set(users.results.map(user => { return { title: user.username, item: user }; }));
|
|
1488
|
-
}
|
|
1489
1580
|
submit() {
|
|
1490
1581
|
this.syncFromForm();
|
|
1491
1582
|
if (this.createMode()) {
|
|
@@ -1534,35 +1625,24 @@ class OrganizationEditComponent extends EditView {
|
|
|
1534
1625
|
onCountryChoices(choices) {
|
|
1535
1626
|
this.countryOptions.update(() => choices.map(c => { return { name: c.display_name, code: c.value, flag: "" }; }));
|
|
1536
1627
|
}
|
|
1537
|
-
|
|
1538
|
-
const url = this.selectedMembers().find(m => m.id == id).url;
|
|
1539
|
-
this.selectedMembers.update(members => members.filter(m => m.id != id));
|
|
1628
|
+
addMember(url) {
|
|
1540
1629
|
this.item.update(item => { if (item) {
|
|
1541
|
-
item.members.
|
|
1630
|
+
item.members.push(url);
|
|
1542
1631
|
} return item; });
|
|
1543
1632
|
}
|
|
1544
|
-
|
|
1545
|
-
const selected = this.candidateMembers().find(m => m.title == title);
|
|
1546
|
-
if (selected) {
|
|
1547
|
-
this.selectedMembers.update(members => { members.push(selected.item); return members; });
|
|
1548
|
-
}
|
|
1549
|
-
this.candidateMembers.update(members => members.filter(m => m.title != title));
|
|
1550
|
-
const url = this.selectedMembers().find(m => m.username == title).url;
|
|
1633
|
+
removeMember(url) {
|
|
1551
1634
|
this.item.update(item => { if (item) {
|
|
1552
|
-
item.members.
|
|
1635
|
+
item.members.filter(m => m != url);
|
|
1553
1636
|
} return item; });
|
|
1554
1637
|
}
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
else {
|
|
1561
|
-
this._userService.get().subscribe(users => this.updateCandidates(users));
|
|
1562
|
-
}
|
|
1638
|
+
onMemberRemoved(id) {
|
|
1639
|
+
this.removeMember(this.selectionManager.onRemoved(id));
|
|
1640
|
+
}
|
|
1641
|
+
onMemberAdded(title) {
|
|
1642
|
+
this.addMember(this.selectionManager.onAdded(title));
|
|
1563
1643
|
}
|
|
1564
1644
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationEditComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1565
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.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 @if(item(); as item){\n <div class=\"item-edit-container\">\n \n <h1 class=\"item-edit-header\">{{heading()}}</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]=\"form.address.form\"\n ></lib-address-edit>\n\n <h3>Members</h3>\n <lib-select-table [selected]=\"
|
|
1645
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.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 @if(item(); as item){\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]=\"form.address.form\"\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)=\"onMemberAdded($event)\"\n (itemRemoved)=\"onMemberRemoved($event)\"\n (searchChanged)=\"selectionManager.onSearchChanged($event)\">\n </lib-select-table>\n\n </form>\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 class=\"form_action_button\"\n (click)=\"cancel()\">\n <mat-icon>cancel</mat-icon>\n </button>\n </div>\n\n </div>\n }\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$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.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$2.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: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatSelectModule }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.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" }] });
|
|
1566
1646
|
}
|
|
1567
1647
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationEditComponent, decorators: [{
|
|
1568
1648
|
type: Component,
|
|
@@ -1576,8 +1656,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
1576
1656
|
MatCheckboxModule,
|
|
1577
1657
|
BackButtonComponent,
|
|
1578
1658
|
AddressEditComponent,
|
|
1579
|
-
SelectTableComponent
|
|
1580
|
-
|
|
1659
|
+
SelectTableComponent,
|
|
1660
|
+
TitleCasePipe
|
|
1661
|
+
], template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n @if(item(); as item){\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]=\"form.address.form\"\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)=\"onMemberAdded($event)\"\n (itemRemoved)=\"onMemberRemoved($event)\"\n (searchChanged)=\"selectionManager.onSearchChanged($event)\">\n </lib-select-table>\n\n </form>\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 class=\"form_action_button\"\n (click)=\"cancel()\">\n <mat-icon>cancel</mat-icon>\n </button>\n </div>\n\n </div>\n }\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"] }]
|
|
1581
1662
|
}], ctorParameters: () => [] });
|
|
1582
1663
|
|
|
1583
1664
|
/*
|
|
@@ -1588,5 +1669,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
1588
1669
|
* Generated bundle index. Do not edit.
|
|
1589
1670
|
*/
|
|
1590
1671
|
|
|
1591
|
-
export { ApiError, BackButtonComponent, DetailHeaderComponent, DetailView, ENDPOINT_URL, EditView, ErrorCode, FileRecord, FileUploadComponent, Group, GroupComponent, GroupDetailComponent, GroupService, ItemQuery, LOGIN_USER, LandingComponent, LeftNavComponent, LeftNavService,
|
|
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 };
|
|
1592
1673
|
//# sourceMappingURL=ichec-angular-core.mjs.map
|