ichec-angular-core 0.1.2 → 0.1.3

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.
@@ -53,31 +53,13 @@ class Paginated {
53
53
  results = [];
54
54
  }
55
55
  class Permission {
56
- id = 0;
57
- url = "";
58
- codename = "";
59
56
  static typename = "permission";
60
57
  static plural = "permissions";
61
- constructor(params = {}) {
62
- Object.assign(this, params);
63
- }
64
58
  }
59
+
65
60
  class PortalMember {
66
61
  static typename = "member";
67
62
  static plural = "members";
68
- id = 0;
69
- url = "";
70
- username = "";
71
- email = "";
72
- first_name = "";
73
- last_name = "";
74
- phone = "";
75
- organization = "";
76
- profile_url = "";
77
- all_permissions = [];
78
- constructor(params = {}) {
79
- Object.assign(this, params);
80
- }
81
63
  static getInitials(member) {
82
64
  let first_initial = "";
83
65
  let second_initial = "";
@@ -94,49 +76,20 @@ class PortalMember {
94
76
  return combined.toUpperCase();
95
77
  }
96
78
  }
79
+
97
80
  class Group {
98
81
  static typename = "group";
99
82
  static plural = "groups";
100
- name = "";
101
- url = "";
102
- id = 0;
103
- constructor(params = {}) {
104
- Object.assign(this, params);
105
- }
106
83
  }
107
84
 
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
85
  class Organization {
127
86
  static typename = "organization";
128
87
  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
- }
88
+ }
89
+
90
+ class Address {
91
+ static typename = "address";
92
+ static plural = "addresses";
140
93
  }
141
94
 
142
95
  class ItemQuery {
@@ -292,12 +245,6 @@ class ItemService extends RestService {
292
245
  typePlural() {
293
246
  return this.typenamePlural ? this.typenamePlural : this.typename + "s";
294
247
  }
295
- instantiateType(_) {
296
- throw new Error('Not Implemented');
297
- }
298
- getItem(id) {
299
- return super.getItem(id).pipe(map(x => this.instantiateType(x)));
300
- }
301
248
  }
302
249
 
303
250
  class ResolvedPermission {
@@ -314,9 +261,6 @@ class UserService extends ItemService {
314
261
  _url = PortalMember.plural;
315
262
  typename = PortalMember.typename;
316
263
  permissions = new Map();
317
- instantiateType(item) {
318
- return new PortalMember(item);
319
- }
320
264
  login(username, password) {
321
265
  console.log("Attempting login");
322
266
  const body = new URLSearchParams();
@@ -455,9 +399,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
455
399
  class AddressService extends ItemWithUserService {
456
400
  _url = Address.plural;
457
401
  typename = Address.typename;
458
- instantiateType(item) {
459
- return new Address(item);
460
- }
461
402
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
462
403
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressService, providedIn: 'root' });
463
404
  }
@@ -475,9 +416,6 @@ class GroupService extends ItemWithUserService {
475
416
  super();
476
417
  this.userService.loggedInUser.subscribe(user => this.refreshUserItems(user));
477
418
  }
478
- instantiateType(item) {
479
- return new Group(item);
480
- }
481
419
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: GroupService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
482
420
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: GroupService, providedIn: 'root' });
483
421
  }
@@ -491,9 +429,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
491
429
  class OrganizationService extends ItemWithUserService {
492
430
  _url = Organization.plural;
493
431
  typename = Organization.typename;
494
- instantiateType(item) {
495
- return new Organization(item);
496
- }
497
432
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
498
433
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationService, providedIn: 'root' });
499
434
  }
@@ -676,7 +611,10 @@ class DetailView {
676
611
  this.getItem();
677
612
  }
678
613
  title() {
679
- return this.itemService.typename.replace("_", " ");
614
+ if (this.itemService.typename) {
615
+ return this.itemService.typename.replace("_", " ");
616
+ }
617
+ return "";
680
618
  }
681
619
  onItemAvailable(item) {
682
620
  this.item.set(item);
@@ -712,35 +650,39 @@ class EditView {
712
650
  _route = inject(ActivatedRoute);
713
651
  _location = inject(Location);
714
652
  _userService = inject(UserService);
653
+ form;
715
654
  itemService;
716
- constructor(itemService) {
655
+ constructor(itemService, form) {
717
656
  this.itemService = itemService;
657
+ this.form = form;
718
658
  }
719
659
  onInit() {
720
660
  this.getItem();
721
661
  }
722
- onItemAvailable() {
662
+ onItemAvailable(item) {
723
663
  this._userService.loggedInUser.subscribe(user => { if (user) {
724
- this.onItemAndUserAvailable(user);
664
+ this.onItemAndUserAvailable(item, user);
725
665
  } });
726
666
  }
727
- onItemAndUserAvailable(_) {
667
+ onItemAndUserAvailable(_item, _user) {
728
668
  }
729
669
  goBack() {
730
670
  this._location.back();
731
671
  }
732
672
  submit() {
733
- console.log("submit called");
734
- if (this.item()) {
735
- this.save();
736
- }
673
+ this.save();
737
674
  }
738
675
  save() {
739
676
  if (this.createMode()) {
740
- this.createItem();
677
+ this.postItem();
741
678
  }
742
679
  else {
743
- this.updateItem();
680
+ const item = this.item();
681
+ {
682
+ if (item) {
683
+ this.putItem(item);
684
+ }
685
+ }
744
686
  }
745
687
  }
746
688
  cancel() {
@@ -760,16 +702,16 @@ class EditView {
760
702
  onFileRead(_content) {
761
703
  }
762
704
  createItem() {
763
- const item = this.item();
764
- if (item) {
765
- this.itemService.postItem(item).subscribe(item => this.saveFiles(item));
766
- }
705
+ return this.form.createItem();
767
706
  }
768
- updateItem() {
769
- const item = this.item();
770
- if (item) {
771
- this.itemService.putItem(item).subscribe(item => this.saveFiles(item));
772
- }
707
+ updateItem(item) {
708
+ return this.form.updateItem(item);
709
+ }
710
+ postItem() {
711
+ this.itemService.postItem(this.createItem()).subscribe(item => this.saveFiles(item));
712
+ }
713
+ putItem(item) {
714
+ this.itemService.putItem(this.updateItem(item)).subscribe(item => this.saveFiles(item));
773
715
  }
774
716
  saveFiles(item) {
775
717
  this.onItemUpdated(item);
@@ -788,16 +730,14 @@ class EditView {
788
730
  }
789
731
  getItem() {
790
732
  if (this.isCreateRoute()) {
791
- this.item.set(this.getTemplateItem());
792
733
  this.createMode.set(true);
793
- this.onItemAvailable();
794
734
  }
795
735
  else {
796
736
  const id_str = this._route.snapshot.paramMap.get('id');
797
737
  this.itemService.getItem(Number(id_str))
798
738
  .subscribe(item => {
799
739
  this.item.set(item);
800
- this.onItemAvailable();
740
+ this.onItemAvailable(item);
801
741
  });
802
742
  }
803
743
  }
@@ -857,6 +797,50 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
857
797
  MatInputModule], template: "<div class='select-container'>\n <div>\n <mat-form-field>\n <mat-label>Add {{itemType()}}</mat-label>\n <input \n type=\"text\"\n aria-label=\"Selected item\"\n matInput\n [formControl]=\"searchControl\" \n [matAutocomplete]=\"auto\">\n\n <mat-autocomplete #auto=\"matAutocomplete\">\n @for(item of options(); track item.item.id){\n <mat-option [value]=\"item.title\">{{item.title}}\n </mat-option>\n }\n </mat-autocomplete>\n </mat-form-field>\n\n <button mat-mini-fab type=\"button\" class=\"form_action_button\" (click)=\"add()\">\n <mat-icon>add\n </mat-icon>\n </button>\n </div>\n\n @if(selected().length > 0){\n <table mat-table [dataSource]=\"selected()\" class=\"mat-elevation-z8\">\n @for (column of columns(); track column.name) {\n <ng-container matColumnDef=\"{{ column.name }}\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>\n {{ column.title }}\n </th>\n <td mat-cell *matCellDef=\"let element\">{{ element[column.name] }}</td>\n </ng-container>\n }\n\n <ng-container matColumnDef=\"remove\">\n <th mat-header-cell *matHeaderCellDef>Remove\n </th>\n <td mat-cell *matCellDef=\"let element\">\n <button mat-icon-button\n color=\"primary\"\n aria-label=\"Remove an item\"\n (click)=\"remove(element.id)\">\n <mat-icon>remove\n </mat-icon>\n </button>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"columnNames()\">\n </tr>\n <tr mat-row *matRowDef=\"let row; columns: columnNames();\">\n </tr>\n </table>\n }\n</div>", styles: [".select-container,.table_container{display:flex;text-align:center;justify-content:center;flex-direction:column}.form_action_button{padding:5px;margin:5px}\n"] }]
858
798
  }] });
859
799
 
800
+ const USER_TABLE_FULL = [
801
+ { name: 'first_name', title: 'First Name', element_type: 'string' },
802
+ { name: 'last_name', title: 'Surname', element_type: 'string' },
803
+ { name: 'username', title: 'Username', element_type: 'string' },
804
+ { name: 'email', title: 'Email', element_type: 'email' }
805
+ ];
806
+
807
+ class SelectionManager {
808
+ candidates = signal([], ...(ngDevMode ? [{ debugName: "candidates" }] : []));
809
+ selected = signal([], ...(ngDevMode ? [{ debugName: "selected" }] : []));
810
+ columns = USER_TABLE_FULL;
811
+ userService = inject(UserService);
812
+ fetchCandidates(item, id) {
813
+ const queries = new Map([[item, id.toString()]]);
814
+ const query = new ItemQuery({ queries: queries });
815
+ this.userService.get(query).subscribe(users => this.selected.set(users.results));
816
+ this.userService.get().subscribe(users => this.updateCandidates(users));
817
+ }
818
+ updateCandidates(users) {
819
+ this.candidates.set(users.results.map(user => { return { title: user.username, item: user }; }));
820
+ }
821
+ onRemoved(id) {
822
+ const url = this.selected().find(m => m.id == id).url;
823
+ this.selected.update(members => members.filter(m => m.id != id));
824
+ return url;
825
+ }
826
+ onAdded(title) {
827
+ const selected = this.candidates().find(m => m.title == title);
828
+ if (selected) {
829
+ this.selected.update(members => { members.push(selected.item); return members; });
830
+ }
831
+ this.candidates.update(members => members.filter(m => m.title != title));
832
+ return this.selected().find(m => m.username == title).url;
833
+ }
834
+ onSearchChanged(searchTerm) {
835
+ if (searchTerm) {
836
+ this.userService.get(new ItemQuery({ filter: searchTerm })).subscribe(users => this.updateCandidates(users));
837
+ }
838
+ else {
839
+ this.userService.get().subscribe(users => this.updateCandidates(users));
840
+ }
841
+ }
842
+ }
843
+
860
844
  /* eslint-disable @typescript-eslint/no-explicit-any */
861
845
  class ListTableViewComponent {
862
846
  itemType = input("", ...(ngDevMode ? [{ debugName: "itemType" }] : []));
@@ -1001,7 +985,6 @@ class ListDataSource extends DataSource {
1001
985
  fetchedPages = new Set();
1002
986
  constructor(itemService, consumerType = "table") {
1003
987
  super();
1004
- console.log("created");
1005
988
  this.itemService = itemService;
1006
989
  this.consumerType = consumerType;
1007
990
  }
@@ -1246,12 +1229,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
1246
1229
  DetailHeaderComponent], template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n @if(item(); as item){\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.username\"\n [id]=\"item.id\"\n [route]=\"itemService.typePlural()\"\n [canEdit]=\"canEdit()\"\n [canDelete]=\"canDelete()\"\n (onDelete)=\"onDelete()\"></lib-detail-header>\n\n @if(item.profile_url){\n <div class=\"image-holder\">\n <img alt=\"User Profile Image\" src=\"{{item.url}}{{item.profile_url}}\" style=\"height:120px;\">\n </div> \n }\n \n <div class=\"item-field\">\n <span><b>Email: </b></span>\n {{item.email}}\n </div>\n \n <div class=\"item-field\">\n <span><b>First Name: </b></span>\n {{item.first_name}}\n </div>\n \n <div class=\"item-field\">\n <span><b>Last Name: </b></span>\n {{item.last_name}}\n </div>\n \n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}\n"] }]
1247
1230
  }], ctorParameters: () => [] });
1248
1231
 
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" }] : []));
1232
+ class UserForm {
1255
1233
  formBuilder = inject(FormBuilder);
1256
1234
  form = this.formBuilder.group({
1257
1235
  username: [''],
@@ -1260,17 +1238,7 @@ class UserEditComponent extends EditView {
1260
1238
  last_name: [''],
1261
1239
  phone: ['']
1262
1240
  });
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
- }
1241
+ setValue(item) {
1274
1242
  this.form.setValue({
1275
1243
  username: item.username,
1276
1244
  email: item.email,
@@ -1278,31 +1246,55 @@ class UserEditComponent extends EditView {
1278
1246
  last_name: item.last_name,
1279
1247
  phone: item.phone
1280
1248
  });
1249
+ }
1250
+ createItem() {
1251
+ const value = this.form.value;
1252
+ return {
1253
+ username: value.username || "",
1254
+ email: value.email || "",
1255
+ first_name: value.first_name || "",
1256
+ last_name: value.last_name || "",
1257
+ phone: value.phone || ""
1258
+ };
1259
+ }
1260
+ updateItem(item) {
1261
+ const value = this.form.value;
1262
+ item.username = value.username || "";
1263
+ item.email = value.email || "";
1264
+ item.first_name = value.first_name || "";
1265
+ item.last_name = value.last_name || "";
1266
+ item.phone = value.phone || "";
1267
+ return item;
1268
+ }
1269
+ }
1270
+
1271
+ class UserEditComponent extends EditView {
1272
+ files = signal([new FileRecord({
1273
+ name: "image",
1274
+ display_name: "Profile Image",
1275
+ file_type: "image"
1276
+ })], ...(ngDevMode ? [{ debugName: "files" }] : []));
1277
+ constructor() {
1278
+ super(inject(UserService), new UserForm());
1279
+ }
1280
+ ngOnInit() {
1281
+ this.onInit();
1282
+ }
1283
+ onItemAvailable(item) {
1284
+ this.form.setValue(item);
1281
1285
  if (item.profile_url) {
1282
1286
  this.files.update(files => { const file = files.find(f => f.name === "image"); if (file) {
1283
1287
  file.remote = item.url + item.profile_url;
1284
1288
  } ; return files; });
1285
1289
  }
1286
- super.onItemAvailable();
1290
+ super.onItemAvailable(item);
1287
1291
  }
1288
1292
  submit() {
1289
1293
  this.item.update((item) => { if (item) {
1290
- item = this.updateFromForm(item);
1294
+ item = this.form.updateItem(item);
1291
1295
  } return item; });
1292
- console.log(this.item());
1293
1296
  super.submit();
1294
1297
  }
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
1298
  onPreviewLoaded(preview) {
1307
1299
  this.files.update(files => { const file = files.find(f => f.name === preview.name); if (file) {
1308
1300
  file.local = preview.content;
@@ -1319,7 +1311,7 @@ class UserEditComponent extends EditView {
1319
1311
  } ; });
1320
1312
  }
1321
1313
  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" }] });
1314
+ 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.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.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" }] });
1323
1315
  }
1324
1316
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserEditComponent, decorators: [{
1325
1317
  type: Component,
@@ -1332,7 +1324,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
1332
1324
  MatIconModule,
1333
1325
  FileUploadComponent,
1334
1326
  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"] }]
1327
+ ], 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 <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.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
1328
  }], ctorParameters: () => [] });
1337
1329
 
1338
1330
  class UserListDetailComponent {
@@ -1346,13 +1338,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
1346
1338
  MatCardModule], template: "<mat-card mat-list-item class=\"item-card\">\n @if(item(); as item){\n <mat-card-header>\n <mat-card-title-group style=\"padding: 5px\">\n <mat-card-title\n >{{ item.first_name }} {{ item.last_name }}</mat-card-title\n >\n <mat-card-subtitle>{{ item.username }}</mat-card-subtitle>\n </mat-card-title-group>\n </mat-card-header>\n\n <mat-card-content>\n <p>Email: {{ item.email }}</p>\n </mat-card-content>\n }\n</mat-card>\n", styles: [":host{flex-grow:1}.mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.is-active{font-weight:700}\n"] }]
1347
1339
  }] });
1348
1340
 
1349
- const USER_TABLE_FULL = [
1350
- { name: 'first_name', title: 'First Name', element_type: 'string' },
1351
- { name: 'last_name', title: 'Surname', element_type: 'string' },
1352
- { name: 'username', title: 'Username', element_type: 'string' },
1353
- { name: 'email', title: 'Email', element_type: 'email' }
1354
- ];
1355
-
1356
1341
  class UserComponent {
1357
1342
  viewType = signal("list", ...(ngDevMode ? [{ debugName: "viewType" }] : []));
1358
1343
  itemService = inject(UserService);
@@ -1439,6 +1424,16 @@ class AddressForm {
1439
1424
  country: item.country
1440
1425
  });
1441
1426
  }
1427
+ createItem() {
1428
+ const value = this.form.value;
1429
+ return { line1: value.line1 || "",
1430
+ line2: value.line2 || null,
1431
+ line3: value.line3 || null,
1432
+ city: value.city || null,
1433
+ region: value.region || "",
1434
+ postcode: value.postcode || null,
1435
+ country: value.country || "" };
1436
+ }
1442
1437
  updateItem(item) {
1443
1438
  const value = this.form.value;
1444
1439
  item.line1 = value.line1 || "";
@@ -1468,63 +1463,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
1468
1463
  }] });
1469
1464
 
1470
1465
  class OrganizationDetailComponent extends DetailView {
1471
- address = signal(null, ...(ngDevMode ? [{ debugName: "address" }] : []));
1472
- addressService = inject(AddressService);
1473
1466
  constructor() {
1474
1467
  super(inject(OrganizationService));
1475
1468
  }
1476
1469
  ngOnInit() {
1477
1470
  this.onInit();
1478
1471
  }
1479
- onItemAndUserAvailable(item, _user) {
1480
- this.addressService.getUrl(item.address).subscribe(address => this.address.set(address));
1481
- }
1482
1472
  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"] }] });
1473
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: OrganizationDetailComponent, isStandalone: true, selector: "lib-organization-detail", usesInheritance: true, ngImport: i0, template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n @if(item(); as item){\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.name\"\n [id]=\"item.id\"\n [canEdit]=\"itemService.canEdit()\"\n [canDelete]=\"itemService.canDelete()\"\n [route]=\"itemService.typePlural()\"></lib-detail-header>\n\n <div class=\"item-field\">\n {{item.description}}\n </div>\n \n <h3>Address</h3>\n <lib-address-detail [address]=\"item.address\"></lib-address-detail>\n\n <div class=\"item-field\">\n <h3>Website</h3>{{item.website}}\n </div>\n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}.padded_button{padding:5px}\n"], dependencies: [{ kind: "component", type: BackButtonComponent, selector: "lib-back-button" }, { kind: "component", type: DetailHeaderComponent, selector: "lib-detail-header", inputs: ["id", "text", "route", "canEdit", "canDelete"], outputs: ["deleteClicked"] }, { kind: "component", type: AddressDetailComponent, selector: "lib-address-detail", inputs: ["address"] }] });
1484
1474
  }
1485
1475
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationDetailComponent, decorators: [{
1486
1476
  type: Component,
1487
1477
  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"] }]
1478
+ DetailHeaderComponent, AddressDetailComponent], template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n @if(item(); as item){\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.name\"\n [id]=\"item.id\"\n [canEdit]=\"itemService.canEdit()\"\n [canDelete]=\"itemService.canDelete()\"\n [route]=\"itemService.typePlural()\"></lib-detail-header>\n\n <div class=\"item-field\">\n {{item.description}}\n </div>\n \n <h3>Address</h3>\n <lib-address-detail [address]=\"item.address\"></lib-address-detail>\n\n <div class=\"item-field\">\n <h3>Website</h3>{{item.website}}\n </div>\n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}.padded_button{padding:5px}\n"] }]
1489
1479
  }], ctorParameters: () => [] });
1490
1480
 
1491
- class SelectionManager {
1492
- candidates = signal([], ...(ngDevMode ? [{ debugName: "candidates" }] : []));
1493
- selected = signal([], ...(ngDevMode ? [{ debugName: "selected" }] : []));
1494
- columns = USER_TABLE_FULL;
1495
- userService = inject(UserService);
1496
- fetchCandidates(item, id) {
1497
- const queries = new Map([[item, id.toString()]]);
1498
- const query = new ItemQuery({ queries: queries });
1499
- this.userService.get(query).subscribe(users => this.selected.set(users.results));
1500
- this.userService.get().subscribe(users => this.updateCandidates(users));
1501
- }
1502
- updateCandidates(users) {
1503
- this.candidates.set(users.results.map(user => { return { title: user.username, item: user }; }));
1504
- }
1505
- onRemoved(id) {
1506
- const url = this.selected().find(m => m.id == id).url;
1507
- this.selected.update(members => members.filter(m => m.id != id));
1508
- return url;
1509
- }
1510
- onAdded(title) {
1511
- const selected = this.candidates().find(m => m.title == title);
1512
- if (selected) {
1513
- this.selected.update(members => { members.push(selected.item); return members; });
1514
- }
1515
- this.candidates.update(members => members.filter(m => m.title != title));
1516
- return this.selected().find(m => m.username == title).url;
1517
- }
1518
- onSearchChanged(searchTerm) {
1519
- if (searchTerm) {
1520
- this.userService.get(new ItemQuery({ filter: searchTerm })).subscribe(users => this.updateCandidates(users));
1521
- }
1522
- else {
1523
- this.userService.get().subscribe(users => this.updateCandidates(users));
1524
- }
1525
- }
1526
- }
1527
-
1528
1481
  class OrganizationForm {
1529
1482
  formBuilder = inject(FormBuilder);
1530
1483
  form;
@@ -1538,7 +1491,8 @@ class OrganizationForm {
1538
1491
  address: [this.address.form]
1539
1492
  });
1540
1493
  }
1541
- updateFromItem(item) {
1494
+ setValue(item) {
1495
+ this.address.setValue(item.address);
1542
1496
  this.form.setValue({
1543
1497
  name: item.name,
1544
1498
  acronym: item.acronym,
@@ -1547,11 +1501,23 @@ class OrganizationForm {
1547
1501
  address: this.address.form
1548
1502
  });
1549
1503
  }
1504
+ createItem() {
1505
+ const value = this.form.value;
1506
+ return {
1507
+ name: value.name || "",
1508
+ acronym: value.acronym || "",
1509
+ description: value.description || "",
1510
+ website: value.website || "",
1511
+ address: this.address.createItem(),
1512
+ members: []
1513
+ };
1514
+ }
1550
1515
  updateItem(item) {
1551
1516
  item.name = this.form.value.name || "";
1552
1517
  item.acronym = this.form.value.acronym || "";
1553
1518
  item.description = this.form.value.description || "";
1554
1519
  item.website = this.form.value.website || "";
1520
+ item.address = this.address.updateItem(item.address);
1555
1521
  return item;
1556
1522
  }
1557
1523
  }
@@ -1559,63 +1525,27 @@ class OrganizationForm {
1559
1525
  class OrganizationEditComponent extends EditView {
1560
1526
  countryOptions = signal([], ...(ngDevMode ? [{ debugName: "countryOptions" }] : []));
1561
1527
  selectionManager = new SelectionManager();
1562
- form = new OrganizationForm();
1563
- address = new Address();
1564
- addressService = inject(AddressService);
1565
1528
  constructor() {
1566
- super(inject(OrganizationService));
1529
+ super(inject(OrganizationService), new OrganizationForm());
1567
1530
  }
1568
1531
  ngOnInit() {
1569
1532
  this.onInit();
1570
- this.addressService.getOptions().subscribe(options => this.onOptions(options));
1571
1533
  }
1572
- onItemAndUserAvailable(_) {
1573
- const item = this.item();
1574
- if (item) {
1575
- this.fetchAddress(item.address);
1576
- this.form.updateFromItem(item);
1577
- this.selectionManager.fetchCandidates(this.itemService.typename, item.id);
1578
- }
1579
- }
1580
- submit() {
1581
- this.syncFromForm();
1582
- if (this.createMode()) {
1583
- this.createAddress().subscribe(_ => super.submit());
1584
- }
1585
- else {
1586
- this.updateAddress();
1587
- super.submit();
1588
- }
1589
- }
1590
- fetchAddress(url) {
1591
- if (url) {
1592
- this.addressService.getUrl(url).subscribe(address => this.onAddressUpdated(address));
1593
- }
1594
- }
1595
- updateAddress() {
1596
- this.addressService.putItem(this.address).subscribe(address => this.onAddressUpdated(address));
1534
+ addressForm() {
1535
+ return this.form.address.form;
1597
1536
  }
1598
- createAddress() {
1599
- return this.addressService.postItem(this.address).pipe(tap(address => { this.onAddressCreated(address); }));
1600
- }
1601
- onAddressUpdated(address) {
1602
- this.address = address;
1603
- this.form.address.setValue(this.address);
1604
- }
1605
- onAddressCreated(address) {
1606
- this.onAddressUpdated(address);
1607
- this.item.update(item => { if (item) {
1608
- item.address = address.url;
1609
- } return item; });
1537
+ createItem() {
1538
+ const item = this.form.createItem();
1539
+ item.members = this.selectionManager.selected().map(m => m.url);
1540
+ return item;
1610
1541
  }
1611
- syncFromForm() {
1612
- this.address = this.form.address.updateItem(this.address);
1613
- this.item.update((item) => { if (item) {
1614
- item = this.form.updateItem(item);
1615
- } return item; });
1542
+ updateItem(item) {
1543
+ item = this.form.updateItem(item);
1544
+ item.members = this.selectionManager.selected().map(m => m.url);
1545
+ return item;
1616
1546
  }
1617
- getTemplateItem() {
1618
- return new Organization();
1547
+ onItemAndUserAvailable(item, _) {
1548
+ this.selectionManager.fetchCandidates(this.itemService.typename, item.id);
1619
1549
  }
1620
1550
  onPostActions(actions) {
1621
1551
  if ('country' in actions && actions['country'].choices) {
@@ -1625,24 +1555,8 @@ class OrganizationEditComponent extends EditView {
1625
1555
  onCountryChoices(choices) {
1626
1556
  this.countryOptions.update(() => choices.map(c => { return { name: c.display_name, code: c.value, flag: "" }; }));
1627
1557
  }
1628
- addMember(url) {
1629
- this.item.update(item => { if (item) {
1630
- item.members.push(url);
1631
- } return item; });
1632
- }
1633
- removeMember(url) {
1634
- this.item.update(item => { if (item) {
1635
- item.members.filter(m => m != url);
1636
- } return item; });
1637
- }
1638
- onMemberRemoved(id) {
1639
- this.removeMember(this.selectionManager.onRemoved(id));
1640
- }
1641
- onMemberAdded(title) {
1642
- this.addMember(this.selectionManager.onAdded(title));
1643
- }
1644
1558
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationEditComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1645
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "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" }] });
1559
+ 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]=\"addressForm()\"\n ></lib-address-edit>\n\n <h3>Members</h3>\n <lib-select-table [selected]=\"selectionManager.selected()\"\n [itemType]=\"'Members'\"\n [columns]=\"selectionManager.columns\"\n [options]=\"selectionManager.candidates()\"\n (itemAdded)=\"selectionManager.onAdded($event)\"\n (itemRemoved)=\"selectionManager.onRemoved($event)\"\n (searchChanged)=\"selectionManager.onSearchChanged($event)\">\n </lib-select-table>\n\n </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" }] });
1646
1560
  }
1647
1561
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationEditComponent, decorators: [{
1648
1562
  type: Component,
@@ -1658,7 +1572,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
1658
1572
  AddressEditComponent,
1659
1573
  SelectTableComponent,
1660
1574
  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"] }]
1575
+ ], 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]=\"addressForm()\"\n ></lib-address-edit>\n\n <h3>Members</h3>\n <lib-select-table [selected]=\"selectionManager.selected()\"\n [itemType]=\"'Members'\"\n [columns]=\"selectionManager.columns\"\n [options]=\"selectionManager.candidates()\"\n (itemAdded)=\"selectionManager.onAdded($event)\"\n (itemRemoved)=\"selectionManager.onRemoved($event)\"\n (searchChanged)=\"selectionManager.onSearchChanged($event)\">\n </lib-select-table>\n\n </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"] }]
1662
1576
  }], ctorParameters: () => [] });
1663
1577
 
1664
1578
  /*
@@ -1669,5 +1583,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
1669
1583
  * Generated bundle index. Do not edit.
1670
1584
  */
1671
1585
 
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 };
1586
+ 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, SelectionManager, TopBarComponent, UserComponent, UserDetailComponent, UserEditComponent, UserService };
1673
1587
  //# sourceMappingURL=ichec-angular-core.mjs.map