@eo4geo/ngx-bok-utils 1.1.1 → 1.2.1

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.
@@ -2,13 +2,13 @@ import * as i0 from '@angular/core';
2
2
  import { EventEmitter, Output, Component, inject, Injectable, Input, HostListener } from '@angular/core';
3
3
  import * as i1 from 'primeng/toolbar';
4
4
  import { ToolbarModule } from 'primeng/toolbar';
5
- import * as i4$1 from '@angular/common';
5
+ import * as i5$1 from '@angular/common';
6
6
  import { CommonModule } from '@angular/common';
7
7
  import * as i2 from 'primeng/button';
8
8
  import { ButtonModule } from 'primeng/button';
9
9
  import * as i3$1 from 'primeng/tieredmenu';
10
10
  import { TieredMenuModule } from 'primeng/tieredmenu';
11
- import * as i5$1 from 'primeng/avatar';
11
+ import * as i5$2 from 'primeng/avatar';
12
12
  import { AvatarModule } from 'primeng/avatar';
13
13
  import { AvatarGroupModule } from 'primeng/avatargroup';
14
14
  import * as i6 from 'primeng/inputtext';
@@ -25,13 +25,29 @@ import * as i5 from 'primeng/iconfield';
25
25
  import { IconFieldModule } from 'primeng/iconfield';
26
26
  import { Message } from 'primeng/message';
27
27
  import { Auth, authState, signInWithEmailAndPassword, createUserWithEmailAndPassword, signInWithPopup, GoogleAuthProvider, sendPasswordResetEmail, signOut, updateProfile } from '@angular/fire/auth';
28
- import { Firestore, collection, doc, getDoc, setDoc, updateDoc, docData } from '@angular/fire/firestore';
29
- import { BehaviorSubject, switchMap, of } from 'rxjs';
28
+ import { Firestore, collection, doc, getDoc, setDoc, updateDoc, docData, query, where, getDocs, collectionData, deleteDoc } from '@angular/fire/firestore';
29
+ import { BehaviorSubject, switchMap, of, Observable, from, take, Subject, forkJoin, first, map, concatMap, catchError, finalize } from 'rxjs';
30
30
  import * as i1$1 from '@angular/router';
31
31
  import * as i9 from 'primeng/toast';
32
32
  import { ToastModule } from 'primeng/toast';
33
33
  import * as i2$1 from 'primeng/api';
34
- import { MessageService } from 'primeng/api';
34
+ import { MessageService, ConfirmationService } from 'primeng/api';
35
+ import * as i6$2 from 'primeng/card';
36
+ import { CardModule } from 'primeng/card';
37
+ import * as i9$1 from 'primeng/accordion';
38
+ import { AccordionModule } from 'primeng/accordion';
39
+ import * as i8$2 from 'primeng/select';
40
+ import { SelectModule } from 'primeng/select';
41
+ import * as i14 from 'primeng/confirmdialog';
42
+ import { ConfirmDialogModule } from 'primeng/confirmdialog';
43
+ import * as i10 from 'primeng/tooltip';
44
+ import { TooltipModule } from 'primeng/tooltip';
45
+ import * as i6$1 from 'primeng/table';
46
+ import { TableModule } from 'primeng/table';
47
+ import * as i7$1 from 'primeng/toggleswitch';
48
+ import { ToggleSwitchModule } from 'primeng/toggleswitch';
49
+ import * as i8$1 from 'primeng/textarea';
50
+ import { TextareaModule } from 'primeng/textarea';
35
51
 
36
52
  class FooterComponent {
37
53
  openReleaseNotes = new EventEmitter();
@@ -177,6 +193,33 @@ class UserService {
177
193
  return of(null);
178
194
  }));
179
195
  }
196
+ isCurrentUser(userId) {
197
+ return this.auth.currentUser?.uid == userId;
198
+ }
199
+ getUidWithEmail(email) {
200
+ return new Observable((observer) => {
201
+ if (!this.isValidEmail(email)) {
202
+ observer.error(new Error('Invalid email.'));
203
+ return;
204
+ }
205
+ const userQuery = query(this.userCollection, where('email', '==', email));
206
+ from(getDocs(userQuery)).pipe(take(1)).subscribe({
207
+ next: snapshot => {
208
+ if (snapshot.empty) {
209
+ observer.error(new Error('No user found with this email.'));
210
+ }
211
+ else {
212
+ const userData = snapshot.docs[0].data();
213
+ observer.next({ uid: userData['_id'], name: userData['name'] });
214
+ observer.complete();
215
+ }
216
+ },
217
+ error: err => {
218
+ observer.error(err);
219
+ }
220
+ });
221
+ });
222
+ }
180
223
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: UserService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
181
224
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: UserService, providedIn: 'root' });
182
225
  }
@@ -275,7 +318,7 @@ class SessionModalComponent {
275
318
  }
276
319
  }
277
320
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SessionModalComponent, deps: [{ token: UserService }], target: i0.ɵɵFactoryTarget.Component });
278
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: SessionModalComponent, isStandalone: true, selector: "sessionModal", inputs: { visible: "visible" }, outputs: { visibleChange: "visibleChange" }, usesOnChanges: true, ngImport: i0, template: "<p-dialog [header]=\"getHeader()\" [modal]=\"true\" [visible]=\"visible\" resizable=\"false\" (visibleChange)=\"visibleChange.emit($event)\" [style]=\"{color: 'var(--primary-color)'}\">\r\n <p-message *ngIf=\"error\" severity=\"error\" variant=\"simple\" styleClass=\"mb-4 white-space-normal\" class=\"error-info\">{{error}}</p-message>\r\n <div class=\"flex items-center gap-4 mt-2 mb-1\">\r\n <p-floatlabel variant=\"on\" [class]=\"error ? 'custom-floatlabel error-floatlabel' : 'custom-floatlabel'\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-user\" />\r\n <input pInputText id=\"email\" autocomplete=\"off\" [class]=\"error ? 'custom-input error-input' : 'custom-input'\" [(ngModel)]=\"email\"/>\r\n </p-iconfield>\r\n <label for=\"email\">Email</label>\r\n </p-floatlabel>\r\n </div>\r\n <div *ngIf=\"!resetpassword\" class=\"flex items-center gap-4 mt-4 mb-1\">\r\n <p-floatlabel variant=\"on\" [class]=\"error ? 'custom-floatlabel error-floatlabel' : 'custom-floatlabel'\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-lock\" />\r\n <input pInputText id=\"password\" autocomplete=\"off\" [class]=\"error ? 'custom-input error-input' : 'custom-input'\" [(ngModel)]=\"password\"/>\r\n </p-iconfield>\r\n <label for=\"password\">Password</label>\r\n </p-floatlabel>\r\n </div>\r\n <div *ngIf=\"!login\" class=\"flex items-center gap-4 mt-4 mb-1\">\r\n <p-floatlabel variant=\"on\" [class]=\"error ? 'custom-floatlabel error-floatlabel' : 'custom-floatlabel'\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-lock\" />\r\n <input pInputText id=\"rPassword\" autocomplete=\"off\" [class]=\"error ? 'custom-input error-input' : 'custom-input'\" [(ngModel)]=\"repeatPassword\"/>\r\n </p-iconfield>\r\n <label for=\"rPassword\">Repeat Password</label>\r\n </p-floatlabel>\r\n </div>\r\n <a *ngIf=\"login && !resetpassword\" class=\"inline-flex ml-2 text-sm\" (click)=\"resetpassword = !resetpassword; error = null;\">Forgot Password?</a>\r\n <div class=\"flex align-items-center justify-content-between gap-2 mt-4\">\r\n <div class=\"flex justify-end gap-2\">\r\n <p-button class=\"custom-button\" [label]=\"getHeader()\" (click)=\"clickMainButton()\" />\r\n <p-button severity=\"secondary\" class=\"custom-secondary-button\" [label]=\"getSwitchLabel()\" (click)=\"clickSwitchButton()\" />\r\n </div>\r\n <p-button *ngIf=\"!resetpassword\" class=\"custom-button\" icon=\"pi pi-google\" label=\"Google\" (click)=\"loginWithGoogle()\" />\r\n </div>\r\n</p-dialog>", styles: [".custom-input{--p-inputtext-focus-border-color: var(--hover-color);--p-inputtext-hover-border-color: var(--hover-color)}.custom-floatlabel{--p-floatlabel-focus-color: var(--hover-color)}.custom-secondary-button{--p-button-secondary-hover-color: var(--primary-color);--p-button-secondary-active-color: var(--primary-color)}.custom-button{--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}a{cursor:pointer}a:hover{color:var(--hover-color)}.error-info{--p-message-error-simple-color: var(--danger-color)}.error-input{--p-inputtext-border-color: var(--danger-color)}.error-floatlabel{--p-floatlabel-color: var(--danger-color)}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i3.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: InputIconModule }, { kind: "component", type: i4.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["styleClass"] }, { kind: "ngmodule", type: IconFieldModule }, { kind: "component", type: i5.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["iconPosition", "styleClass"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i6.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: FloatLabelModule }, { kind: "component", type: i7.FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i8.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: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant"], outputs: ["onClose"] }] });
321
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: SessionModalComponent, isStandalone: true, selector: "sessionModal", inputs: { visible: "visible" }, outputs: { visibleChange: "visibleChange" }, usesOnChanges: true, ngImport: i0, template: "<p-dialog [header]=\"getHeader()\" [modal]=\"true\" [visible]=\"visible\" resizable=\"false\" (visibleChange)=\"visibleChange.emit($event)\" [style]=\"{color: 'var(--primary-color)'}\">\r\n <p-message *ngIf=\"error\" severity=\"error\" variant=\"simple\" styleClass=\"mb-4 white-space-normal\" class=\"error-info\">{{error}}</p-message>\r\n <div class=\"flex items-center gap-4 mt-2 mb-1\">\r\n <p-floatlabel variant=\"on\" [class]=\"error ? 'custom-floatlabel error-floatlabel' : 'custom-floatlabel'\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-user\" />\r\n <input pInputText id=\"email\" autocomplete=\"off\" [class]=\"error ? 'custom-input error-input' : 'custom-input'\" [(ngModel)]=\"email\"/>\r\n </p-iconfield>\r\n <label for=\"email\">Email</label>\r\n </p-floatlabel>\r\n </div>\r\n <div *ngIf=\"!resetpassword\" class=\"flex items-center gap-4 mt-4 mb-1\">\r\n <p-floatlabel variant=\"on\" [class]=\"error ? 'custom-floatlabel error-floatlabel' : 'custom-floatlabel'\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-lock\" />\r\n <input pInputText id=\"password\" autocomplete=\"off\" [class]=\"error ? 'custom-input error-input' : 'custom-input'\" [(ngModel)]=\"password\"/>\r\n </p-iconfield>\r\n <label for=\"password\">Password</label>\r\n </p-floatlabel>\r\n </div>\r\n <div *ngIf=\"!login\" class=\"flex items-center gap-4 mt-4 mb-1\">\r\n <p-floatlabel variant=\"on\" [class]=\"error ? 'custom-floatlabel error-floatlabel' : 'custom-floatlabel'\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-lock\" />\r\n <input pInputText id=\"rPassword\" autocomplete=\"off\" [class]=\"error ? 'custom-input error-input' : 'custom-input'\" [(ngModel)]=\"repeatPassword\"/>\r\n </p-iconfield>\r\n <label for=\"rPassword\">Repeat Password</label>\r\n </p-floatlabel>\r\n </div>\r\n <a *ngIf=\"login && !resetpassword\" class=\"inline-flex ml-2 text-sm\" (click)=\"resetpassword = !resetpassword; error = null;\">Forgot Password?</a>\r\n <div class=\"flex align-items-center justify-content-between gap-2 mt-4\">\r\n <div class=\"flex justify-end gap-2\">\r\n <p-button class=\"custom-button\" [label]=\"getHeader()\" (click)=\"clickMainButton()\" />\r\n <p-button severity=\"secondary\" class=\"custom-secondary-button\" [label]=\"getSwitchLabel()\" (click)=\"clickSwitchButton()\" />\r\n </div>\r\n <p-button *ngIf=\"!resetpassword\" class=\"custom-button\" icon=\"pi pi-google\" label=\"Google\" (click)=\"loginWithGoogle()\" />\r\n </div>\r\n</p-dialog>", styles: [".custom-input{--p-inputtext-focus-border-color: var(--hover-color);--p-inputtext-hover-border-color: var(--hover-color)}.custom-floatlabel{--p-floatlabel-focus-color: var(--hover-color)}.custom-secondary-button{--p-button-secondary-hover-color: var(--primary-color);--p-button-secondary-active-color: var(--primary-color)}.custom-button{--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}a{cursor:pointer}a:hover{color:var(--hover-color)}.error-info{--p-message-error-simple-color: var(--danger-color)}.error-input{--p-inputtext-border-color: var(--danger-color)}.error-floatlabel{--p-floatlabel-color: var(--danger-color)}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i3.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: InputIconModule }, { kind: "component", type: i4.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["styleClass"] }, { kind: "ngmodule", type: IconFieldModule }, { kind: "component", type: i5.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["iconPosition", "styleClass"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i6.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: FloatLabelModule }, { kind: "component", type: i7.FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i8.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: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant"], outputs: ["onClose"] }] });
279
322
  }
280
323
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SessionModalComponent, decorators: [{
281
324
  type: Component,
@@ -356,11 +399,17 @@ class HeaderComponent {
356
399
  userItems = [
357
400
  {
358
401
  label: 'Profile',
359
- icon: 'pi pi-user'
402
+ icon: 'pi pi-user',
403
+ command: () => {
404
+ this.profileClick.emit();
405
+ }
360
406
  },
361
407
  {
362
408
  label: 'Organization',
363
- icon: 'pi pi-users'
409
+ icon: 'pi pi-users',
410
+ command: () => {
411
+ this.organizationClick.emit();
412
+ }
364
413
  },
365
414
  {
366
415
  label: 'Logout',
@@ -372,6 +421,8 @@ class HeaderComponent {
372
421
  ];
373
422
  toolName = "BoK Visualization & Search";
374
423
  login = false;
424
+ profileClick = new EventEmitter();
425
+ organizationClick = new EventEmitter();
375
426
  hideMenu = true;
376
427
  logged = false;
377
428
  nameInitial = 'A';
@@ -398,7 +449,7 @@ class HeaderComponent {
398
449
  }
399
450
  }
400
451
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: HeaderComponent, deps: [{ token: UserService }], target: i0.ɵɵFactoryTarget.Component });
401
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: HeaderComponent, isStandalone: true, selector: "header", inputs: { items: "items", toolName: "toolName", login: "login" }, host: { listeners: { "document:click": "clickout($event)" } }, ngImport: i0, template: "<div class=\"header\">\r\n <div class=\"flex align-content-center p-4 mx-4\">\r\n <a href=\"https://www.spacesuite-project.eu/\" target=\"_blank\" class=\"align-self-center\"><img class=\"logo flex align-items-center justify-content-center\" src=\"assets/images/SpaceSUITE_horizontal_color.png\" alt=\"LogoSpaceSUITE\"></a>\r\n <div class=\"hidden xl:flex align-self-center fixed-text\">\r\n <strong class=\"text-2xl overflow-hidden white-space-nowrap text-overflow-ellipsis\">\r\n {{toolName}}\r\n </strong>\r\n </div>\r\n <div class=\"flex gap-6 ml-auto\">\r\n <div class=\"justify-content-center hidden md:flex\" *ngFor=\"let item of items;\">\r\n <div class=\"flex align-items-center justify-content-center gap-2 text-xl font-bold header-option\" (click)=\"subMenu.toggle($event)\" *ngIf=\"item.label != 'Share'; else share\">\r\n <i [class]=\"item.icon\"></i>\r\n <div>{{item.label}}</div>\r\n <i *ngIf=\"item.items\" class=\"pi pi-angle-down\"></i>\r\n </div>\r\n <p-tieredmenu #subMenu [model]=\"item.items\" [breakpoint]=\"'767px'\" class=\"custom-p-tieredmenu\" [popup]=\"true\" />\r\n <ng-template #share>\r\n <div class=\"flex align-items-center justify-content-center gap-3\">\r\n <div *ngFor=\"let social of item.items;\">\r\n <a [href]=\"social.url\" target=\"_blank\" class=\"flex\">\r\n <i [class]=\"social.icon\" style=\"font-size: 1.25rem\"></i>\r\n </a>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div *ngIf=\"login\" class=\"hidden md:flex align-items-center justify-content-center\">\r\n <p-avatar *ngIf=\"logged; else loginButton\" [label]=\"nameInitial\" class=\"custom-p-avatar\" shape=\"circle\" (click)=\"userMenu.toggle($event)\"></p-avatar>\r\n </div>\r\n <p-tieredmenu #userMenu [model]=\"userItems\" [breakpoint]=\"'767px'\" class=\"custom-p-tieredmenu\" [popup]=\"true\" />\r\n <ng-template #loginButton>\r\n <p-button class=\"custom-header-button\" size=\"small\" label=\"Login\" aria-label=\"Login\" (onClick)=\"showLoginModal = !showLoginModal\"></p-button>\r\n </ng-template>\r\n </div>\r\n \r\n <p-button #menuButton (click)=\"hideMenu = !hideMenu\" class=\"md:hidden flex align-items-center custom-header-button ml-auto\" icon=\"pi pi-bars\" aria-label=\"Menu\"></p-button>\r\n </div>\r\n <p-tieredmenu #menu [hidden]=\"hideMenu\" [model]=\"items\" class=\"md:hidden custom-p-tieredmenu\"/>\r\n</div>\r\n\r\n<sessionModal [(visible)]=\"showLoginModal\"></sessionModal>\r\n", styles: [".header{background-color:#fff;color:var(--primary-color);position:relative;top:0;left:0;width:100%}.header:after{content:\"\";position:absolute;bottom:0;left:2rem;right:2rem;height:1px;background-color:#0000001a}.header a{color:var(--primary-color);cursor:pointer;text-decoration:none}.header a:hover{color:var(--hover-color)}.logo{width:auto;height:50px}.custom-header-button{--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}.header-option:hover{color:var(--hover-color);cursor:pointer}.custom-p-tieredmenu{--p-tieredmenu-item-icon-color: var(--primary-color);--p-tieredmenu-item-icon-active-color: var(--hover-color);--p-tieredmenu-item-icon-focus-color: var(--hover-color);--p-tieredmenu-item-color: var(--primary-color);--p-tieredmenu-item-active-color: var(--hover-color);--p-tieredmenu-item-focus-color: var(--hover-color)}.custom-p-avatar{color:var(--primary-color);cursor:pointer}.custom-p-avatar:hover{color:var(--hover-color)}.fixed-text{position:absolute;left:50%;transform:translate(-50%);z-index:10;max-width:20%}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TieredMenuModule }, { kind: "component", type: i3$1.TieredMenu, selector: "p-tieredMenu, p-tieredmenu, p-tiered-menu", inputs: ["model", "popup", "style", "styleClass", "appendTo", "breakpoint", "autoZIndex", "baseZIndex", "autoDisplay", "showTransitionOptions", "hideTransitionOptions", "id", "ariaLabel", "ariaLabelledBy", "disabled", "tabindex"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i5$1.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "style", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "ngmodule", type: AvatarGroupModule }, { kind: "component", type: SessionModalComponent, selector: "sessionModal", inputs: ["visible"], outputs: ["visibleChange"] }] });
452
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: HeaderComponent, isStandalone: true, selector: "header", inputs: { items: "items", toolName: "toolName", login: "login" }, outputs: { profileClick: "profileClick", organizationClick: "organizationClick" }, host: { listeners: { "document:click": "clickout($event)" } }, ngImport: i0, template: "<div class=\"header\">\r\n <div class=\"flex align-content-center p-4 mx-4\">\r\n <a href=\"https://www.spacesuite-project.eu/\" target=\"_blank\" class=\"align-self-center\"><img class=\"logo flex align-items-center justify-content-center\" src=\"assets/images/SpaceSUITE_horizontal_color.png\" alt=\"LogoSpaceSUITE\"></a>\r\n <div class=\"hidden xl:flex align-self-center fixed-text\">\r\n <strong class=\"text-2xl overflow-hidden white-space-nowrap text-overflow-ellipsis\">\r\n {{toolName}}\r\n </strong>\r\n </div>\r\n <div class=\"flex gap-6 ml-auto\">\r\n <div class=\"justify-content-center hidden md:flex\" *ngFor=\"let item of items;\">\r\n <div class=\"flex align-items-center justify-content-center gap-2 text-xl font-bold header-option\" (click)=\"subMenu.toggle($event)\" *ngIf=\"item.label != 'Share'; else share\">\r\n <i [class]=\"item.icon\"></i>\r\n <div>{{item.label}}</div>\r\n <i *ngIf=\"item.items\" class=\"pi pi-angle-down\"></i>\r\n </div>\r\n <p-tieredmenu #subMenu [model]=\"item.items\" [breakpoint]=\"'767px'\" class=\"custom-p-tieredmenu\" [popup]=\"true\" />\r\n <ng-template #share>\r\n <div class=\"flex align-items-center justify-content-center gap-3\">\r\n <div *ngFor=\"let social of item.items;\">\r\n <a [href]=\"social.url\" target=\"_blank\" class=\"flex\">\r\n <i [class]=\"social.icon\" style=\"font-size: 1.25rem\"></i>\r\n </a>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div *ngIf=\"login\" class=\"hidden md:flex align-items-center justify-content-center\">\r\n <p-avatar *ngIf=\"logged; else loginButton\" [label]=\"nameInitial\" class=\"custom-p-avatar\" shape=\"circle\" (click)=\"userMenu.toggle($event)\"></p-avatar>\r\n </div>\r\n <p-tieredmenu #userMenu [model]=\"userItems\" [breakpoint]=\"'767px'\" class=\"custom-p-tieredmenu\" [popup]=\"true\" />\r\n <ng-template #loginButton>\r\n <p-button class=\"custom-header-button\" size=\"small\" label=\"Login\" aria-label=\"Login\" (onClick)=\"showLoginModal = !showLoginModal\"></p-button>\r\n </ng-template>\r\n </div>\r\n \r\n <p-button #menuButton (click)=\"hideMenu = !hideMenu\" class=\"md:hidden flex align-items-center custom-header-button ml-auto\" icon=\"pi pi-bars\" aria-label=\"Menu\"></p-button>\r\n </div>\r\n <p-tieredmenu #menu [hidden]=\"hideMenu\" [model]=\"items\" class=\"md:hidden custom-p-tieredmenu\"/>\r\n</div>\r\n\r\n<sessionModal [(visible)]=\"showLoginModal\"></sessionModal>\r\n", styles: [".header{background-color:#fff;color:var(--primary-color);position:relative;top:0;left:0;width:100%}.header:after{content:\"\";position:absolute;bottom:0;left:2rem;right:2rem;height:1px;background-color:#0000001a}.header a{color:var(--primary-color);cursor:pointer;text-decoration:none}.header a:hover{color:var(--hover-color)}.logo{width:auto;height:50px}.custom-header-button{--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}.header-option:hover{color:var(--hover-color);cursor:pointer}.custom-p-tieredmenu{--p-tieredmenu-item-icon-color: var(--primary-color);--p-tieredmenu-item-icon-active-color: var(--hover-color);--p-tieredmenu-item-icon-focus-color: var(--hover-color);--p-tieredmenu-item-color: var(--primary-color);--p-tieredmenu-item-active-color: var(--hover-color);--p-tieredmenu-item-focus-color: var(--hover-color)}.custom-p-avatar{color:var(--primary-color);cursor:pointer}.custom-p-avatar:hover{color:var(--hover-color)}.fixed-text{position:absolute;left:50%;transform:translate(-50%);z-index:10;max-width:20%}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TieredMenuModule }, { kind: "component", type: i3$1.TieredMenu, selector: "p-tieredMenu, p-tieredmenu, p-tiered-menu", inputs: ["model", "popup", "style", "styleClass", "appendTo", "breakpoint", "autoZIndex", "baseZIndex", "autoDisplay", "showTransitionOptions", "hideTransitionOptions", "id", "ariaLabel", "ariaLabelledBy", "disabled", "tabindex"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i5$2.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "style", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "ngmodule", type: AvatarGroupModule }, { kind: "component", type: SessionModalComponent, selector: "sessionModal", inputs: ["visible"], outputs: ["visibleChange"] }] });
402
453
  }
403
454
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: HeaderComponent, decorators: [{
404
455
  type: Component,
@@ -409,6 +460,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
409
460
  type: Input
410
461
  }], login: [{
411
462
  type: Input
463
+ }], profileClick: [{
464
+ type: Output
465
+ }], organizationClick: [{
466
+ type: Output
412
467
  }], clickout: [{
413
468
  type: HostListener,
414
469
  args: ['document:click', ['$event']]
@@ -480,6 +535,799 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
480
535
  args: [{ standalone: true, selector: 'user-page', imports: [ButtonModule, InputIconModule, IconFieldModule, InputTextModule, FloatLabelModule, FormsModule, CommonModule, ToastModule], providers: [MessageService], template: "<p-toast class=\"custom-toast\" position=\"bottom-right\"/>\r\n<div class=\"flex flex-column align-items-center justify-content-center p-4\">\r\n <h2>User Profile</h2>\r\n <div class=\"flex gap-4\">\r\n <p-floatlabel variant=\"on\" class=\"custom-floatlabel\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-envelope\" />\r\n <input pInputText id=\"email\" [disabled]=\"true\" autocomplete=\"off\" class=\"w-full max-w-25rem custom-input\" [(ngModel)]=\"email\"/>\r\n </p-iconfield>\r\n <label for=\"email\">Email</label>\r\n </p-floatlabel>\r\n </div>\r\n <div class=\"flex gap-4 mt-4 mb-4\">\r\n <p-floatlabel variant=\"on\" class=\"custom-floatlabel\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-user\" />\r\n <input pInputText id=\"password\" [disabled]=\"email == ''\" autocomplete=\"off\" class=\"w-full max-w-25rem custom-input\" [(ngModel)]=\"newName\"/>\r\n </p-iconfield>\r\n <label for=\"password\">Name</label>\r\n </p-floatlabel>\r\n </div>\r\n <p-button class=\"custom-button\" label=\"Update Name\" [disabled]=\"(name == newName || email == '')\" (click)=\"updateName()\" />\r\n</div>", styles: [".custom-input{--p-inputtext-focus-border-color: var(--hover-color);--p-inputtext-hover-border-color: var(--hover-color)}.custom-floatlabel{--p-floatlabel-focus-color: var(--hover-color)}.custom-secondary-button{--p-button-secondary-hover-color: var(--primary-color);--p-button-secondary-active-color: var(--primary-color)}.custom-button{--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}a{cursor:pointer}a:hover{color:var(--hover-color)}.custom-toast{--p-toast-info-background: color-mix(in srgb, var(--secondary-color) 10%, rgba(255, 255, 255, .9) 90%);--p-toast-info-border-color: var(--secondary-color);--p-toast-info-color: var(--secondary-color);--p-toast-info-detail-color: var(--primary-color);--p-toast-error-background: color-mix(in srgb, var(--danger-color) 10%, rgba(255, 255, 255, .9) 90%);--p-toast-error-border-color: var(--danger-color);--p-toast-error-color: var(--danger-color);--p-toast-error-detail-color: var(--primary-color)}::ng-deep .p-toast-close-button .p-button-label{font-size:0}\n"] }]
481
536
  }], ctorParameters: () => [{ type: UserService }, { type: i2$1.MessageService }] });
482
537
 
538
+ class OrganizationFormComponent {
539
+ organization;
540
+ descriptionError = false;
541
+ buttonLabel = "Update Information";
542
+ validationFunction = (data) => {
543
+ for (let pair of data) {
544
+ if (pair[0] != pair[1])
545
+ return false;
546
+ }
547
+ return true;
548
+ };
549
+ formChange = new EventEmitter();
550
+ newName = "";
551
+ newDescription = "";
552
+ newContact = "";
553
+ emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
554
+ isValidEmail = (email) => this.emailRegex.test(email);
555
+ ngOnChanges(changes) {
556
+ if (changes['organization'] && this.organization) {
557
+ this.newName = changes['organization'].currentValue.name;
558
+ this.newDescription = changes['organization'].currentValue.description;
559
+ this.newContact = changes['organization'].currentValue.email;
560
+ }
561
+ }
562
+ descriptionFormModified() {
563
+ const pairs = [[this.newName, this.organization.name], [this.newDescription, this.organization.description], [this.newContact, this.organization.email]];
564
+ return this.validationFunction(pairs) || !this.isValidEmail(this.newContact);
565
+ }
566
+ updateDescription() {
567
+ const updateInfo = {
568
+ name: this.newName != this.organization.name ? this.newName : null,
569
+ description: this.newDescription != this.organization.description ? this.newDescription : null,
570
+ contact: this.newContact != this.organization.email ? this.newContact : null
571
+ };
572
+ this.formChange.emit(updateInfo);
573
+ }
574
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OrganizationFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
575
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: OrganizationFormComponent, isStandalone: true, selector: "organization-form", inputs: { organization: "organization", descriptionError: "descriptionError", buttonLabel: "buttonLabel", validationFunction: "validationFunction" }, outputs: { formChange: "formChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"flex flex-column gap-4 m-2 mb-4\">\r\n <p-floatlabel variant=\"on\" class=\"custom-floatlabel\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-pencil\" />\r\n <input pInputText id=\"name\" autocomplete=\"off\" class=\"w-full custom-input\" (ngModelChange)=\"descriptionError = false;\"\r\n [ngClass]=\"descriptionError ? 'error-input' : ''\" [(ngModel)]=\"newName\"/>\r\n </p-iconfield>\r\n <label for=\"name\">Name</label>\r\n </p-floatlabel>\r\n\r\n <p-floatlabel variant=\"on\" class=\"custom-floatlabel\">\r\n <p-iconfield class=\"textarea-iconfield\">\r\n <p-inputicon class=\"pi pi-align-justify\"></p-inputicon>\r\n <textarea id=\"description\" rows=\"5\" cols=\"30\" pTextarea [(ngModel)]=\"newDescription\" (ngModelChange)=\"descriptionError = false;\"\r\n style=\"resize: none;\" class=\"w-full custom-textarea\" [ngClass]=\"descriptionError ? 'error-textarea' : ''\"></textarea>\r\n </p-iconfield>\r\n <label for=\"description\">Description</label>\r\n </p-floatlabel>\r\n\r\n <p-floatlabel variant=\"on\" class=\"custom-floatlabel\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-envelope\" />\r\n <input pInputText id=\"contact\" autocomplete=\"off\" class=\"w-full custom-input\" (ngModelChange)=\"descriptionError = false;\"\r\n [ngClass]=\"descriptionError ? 'error-input' : ''\" [(ngModel)]=\"newContact\"/>\r\n </p-iconfield>\r\n <label for=\"contact\">Contact</label>\r\n </p-floatlabel>\r\n</div>\r\n<p-button class=\"custom-button ml-2\" [label]=\"buttonLabel\" size=\"small\" [disabled]=\"descriptionFormModified()\" (onClick)=\"updateDescription()\"/>", styles: [".custom-button{--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}.custom-input{--p-inputtext-focus-border-color: var(--hover-color);--p-inputtext-hover-border-color: var(--hover-color)}.custom-floatlabel{--p-floatlabel-focus-color: var(--hover-color)}.error-input{--p-inputtext-border-color: var(--danger-color)}.error-floatlabel{--p-floatlabel-color: var(--danger-color)}.textarea-iconfield{position:relative;display:flex;align-items:flex-start}.textarea-iconfield .p-inputicon{position:absolute;top:17px;left:11px;z-index:1}.custom-textarea{padding-left:2.5rem}.custom-textarea:hover,.custom-textarea:focus{border-color:var(--hover-color)!important}.error-textarea{border-color:var(--danger-color)!important}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i8.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: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InputIconModule }, { kind: "component", type: i4.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["styleClass"] }, { kind: "ngmodule", type: IconFieldModule }, { kind: "component", type: i5.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["iconPosition", "styleClass"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i6.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: FloatLabelModule }, { kind: "component", type: i7.FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i8$1.Textarea, selector: "[pTextarea]", inputs: ["autoResize", "variant", "fluid", "pSize"], outputs: ["onResize"] }] });
576
+ }
577
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OrganizationFormComponent, decorators: [{
578
+ type: Component,
579
+ args: [{ standalone: true, selector: 'organization-form', imports: [ButtonModule, CommonModule, FormsModule, InputIconModule, IconFieldModule, InputTextModule, FloatLabelModule, TextareaModule], template: "<div class=\"flex flex-column gap-4 m-2 mb-4\">\r\n <p-floatlabel variant=\"on\" class=\"custom-floatlabel\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-pencil\" />\r\n <input pInputText id=\"name\" autocomplete=\"off\" class=\"w-full custom-input\" (ngModelChange)=\"descriptionError = false;\"\r\n [ngClass]=\"descriptionError ? 'error-input' : ''\" [(ngModel)]=\"newName\"/>\r\n </p-iconfield>\r\n <label for=\"name\">Name</label>\r\n </p-floatlabel>\r\n\r\n <p-floatlabel variant=\"on\" class=\"custom-floatlabel\">\r\n <p-iconfield class=\"textarea-iconfield\">\r\n <p-inputicon class=\"pi pi-align-justify\"></p-inputicon>\r\n <textarea id=\"description\" rows=\"5\" cols=\"30\" pTextarea [(ngModel)]=\"newDescription\" (ngModelChange)=\"descriptionError = false;\"\r\n style=\"resize: none;\" class=\"w-full custom-textarea\" [ngClass]=\"descriptionError ? 'error-textarea' : ''\"></textarea>\r\n </p-iconfield>\r\n <label for=\"description\">Description</label>\r\n </p-floatlabel>\r\n\r\n <p-floatlabel variant=\"on\" class=\"custom-floatlabel\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-envelope\" />\r\n <input pInputText id=\"contact\" autocomplete=\"off\" class=\"w-full custom-input\" (ngModelChange)=\"descriptionError = false;\"\r\n [ngClass]=\"descriptionError ? 'error-input' : ''\" [(ngModel)]=\"newContact\"/>\r\n </p-iconfield>\r\n <label for=\"contact\">Contact</label>\r\n </p-floatlabel>\r\n</div>\r\n<p-button class=\"custom-button ml-2\" [label]=\"buttonLabel\" size=\"small\" [disabled]=\"descriptionFormModified()\" (onClick)=\"updateDescription()\"/>", styles: [".custom-button{--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}.custom-input{--p-inputtext-focus-border-color: var(--hover-color);--p-inputtext-hover-border-color: var(--hover-color)}.custom-floatlabel{--p-floatlabel-focus-color: var(--hover-color)}.error-input{--p-inputtext-border-color: var(--danger-color)}.error-floatlabel{--p-floatlabel-color: var(--danger-color)}.textarea-iconfield{position:relative;display:flex;align-items:flex-start}.textarea-iconfield .p-inputicon{position:absolute;top:17px;left:11px;z-index:1}.custom-textarea{padding-left:2.5rem}.custom-textarea:hover,.custom-textarea:focus{border-color:var(--hover-color)!important}.error-textarea{border-color:var(--danger-color)!important}\n"] }]
580
+ }], propDecorators: { organization: [{
581
+ type: Input
582
+ }], descriptionError: [{
583
+ type: Input
584
+ }], buttonLabel: [{
585
+ type: Input
586
+ }], validationFunction: [{
587
+ type: Input
588
+ }], formChange: [{
589
+ type: Output
590
+ }] } });
591
+
592
+ class OrganizationService {
593
+ auth = inject(Auth);
594
+ db = inject(Firestore);
595
+ userCollection;
596
+ orgCollection;
597
+ adminOrganizationMessagesSource = new Subject();
598
+ adminOrganizationMessages$ = this.adminOrganizationMessagesSource.asObservable();
599
+ constructor() {
600
+ this.userCollection = collection(this.db, 'Users');
601
+ this.orgCollection = collection(this.db, 'Organizations');
602
+ }
603
+ emitMessage(message) {
604
+ this.adminOrganizationMessagesSource.next(message);
605
+ }
606
+ getOrganizations() {
607
+ return collectionData(this.orgCollection);
608
+ }
609
+ getUserOrganizations() {
610
+ return authState(this.auth).pipe(switchMap(user => {
611
+ if (user) {
612
+ const userDocRef = doc(this.userCollection, user.uid);
613
+ return docData(userDocRef);
614
+ }
615
+ return of(null);
616
+ }), switchMap(userData => {
617
+ if (userData?.organizations && userData.organizations.length > 0) {
618
+ const orgRequests = userData.organizations.map(orgId => this.getOrganizationInfo(orgId));
619
+ return forkJoin(orgRequests);
620
+ }
621
+ return of([]);
622
+ }));
623
+ }
624
+ getOrganizationInfo(orgId) {
625
+ const orgDocRef = doc(this.orgCollection, orgId);
626
+ return docData(orgDocRef).pipe(first(), map(document => ({
627
+ _id: document?.['_id'],
628
+ name: document?.['name'],
629
+ description: document?.['description'],
630
+ email: document?.['contact'],
631
+ isAdmin: Array.isArray(document?.['admin']) && document['admin'].includes(this.auth.currentUser?.uid)
632
+ })));
633
+ }
634
+ getOrganizationUsers(orgId) {
635
+ const orgDocRef = doc(this.orgCollection, orgId);
636
+ const organizationUsersSnapshot = docData(orgDocRef);
637
+ return organizationUsersSnapshot.pipe(switchMap(users => {
638
+ const adminUsers$ = users.admin.map(uid => this.getUserInfo(uid).pipe(take(1), map(user => ({ ...user, isAdmin: true }))));
639
+ const regularUsers$ = users.regular.map(uid => this.getUserInfo(uid).pipe(take(1), map(user => ({ ...user, isAdmin: false }))));
640
+ return forkJoin([...adminUsers$, ...regularUsers$]);
641
+ }));
642
+ }
643
+ getUserInfo(uid) {
644
+ const orgDocRef = doc(this.userCollection, uid);
645
+ return docData(orgDocRef);
646
+ }
647
+ getOrganizationDivisions(orgId) {
648
+ const orgDocRef = doc(this.orgCollection, orgId);
649
+ const organizationUsersSnapshot = docData(orgDocRef);
650
+ return organizationUsersSnapshot.pipe(map(data => data.divisions));
651
+ }
652
+ leaveOrganization(orgId) {
653
+ return this.updateOrganizationUsers(orgId, this.removeItem).pipe(concatMap(() => this.updateUserOrganizations(orgId, this.removeItem)));
654
+ }
655
+ joinOrganization(orgId) {
656
+ return this.updateOrganizationUsers(orgId, this.addItem, undefined, this.nothing).pipe(concatMap(() => this.updateUserOrganizations(orgId, this.addItem)));
657
+ }
658
+ deleteUserFromOrganization(orgId, userId) {
659
+ return this.updateOrganizationUsers(orgId, this.removeItem, userId).pipe(concatMap(() => this.updateUserOrganizations(orgId, this.removeItem, userId)));
660
+ }
661
+ addUserToOrganization(orgId, userId) {
662
+ return this.updateOrganizationUsers(orgId, this.addItem, userId, this.nothing).pipe(concatMap(() => this.updateUserOrganizations(orgId, this.addItem, userId)));
663
+ }
664
+ changeAdminState(orgId, userId, newState) {
665
+ return newState
666
+ ? this.updateOrganizationUsers(orgId, this.removeItem, userId, this.addItem)
667
+ : this.updateOrganizationUsers(orgId, this.addItem, userId, this.removeItem);
668
+ }
669
+ updateUserOrganizations(orgId, updateFn, userId) {
670
+ const currentUserId = userId ?? this.auth.currentUser?.uid;
671
+ if (!currentUserId)
672
+ return of(void 0);
673
+ const userDocRef = doc(this.userCollection, currentUserId);
674
+ const userOrganizationsSnapshot = docData(userDocRef);
675
+ return new Observable((observer) => {
676
+ userOrganizationsSnapshot.pipe(take(1)).subscribe(async (userOrganizations) => {
677
+ if (!userOrganizations || !userOrganizations.organizations) {
678
+ observer.error(new Error('User organizations data is unavailable.'));
679
+ return;
680
+ }
681
+ const updatedOrganizations = updateFn(userOrganizations.organizations, orgId);
682
+ await updateDoc(userDocRef, { organizations: updatedOrganizations });
683
+ observer.next();
684
+ observer.complete();
685
+ });
686
+ });
687
+ }
688
+ updateOrganizationUsers(orgId, updateFn, userId, updateAdminFn) {
689
+ const orgDocRef = doc(this.orgCollection, orgId);
690
+ const organizationUsersSnapshot = docData(orgDocRef);
691
+ return new Observable((observer) => {
692
+ organizationUsersSnapshot.pipe(take(1)).subscribe(async (organizationUsers) => {
693
+ if (!organizationUsers) {
694
+ observer.error(new Error('Organization users data is unavailable.'));
695
+ return;
696
+ }
697
+ const currentUserId = userId ?? this.auth.currentUser?.uid;
698
+ if (!currentUserId) {
699
+ observer.error(new Error('Current user is not authenticated.'));
700
+ return;
701
+ }
702
+ if (organizationUsers.admin.length == 1 && organizationUsers.admin.includes(currentUserId)) {
703
+ observer.error(new Error('Cannot perform action: Current user is the only administrator.'));
704
+ return;
705
+ }
706
+ await updateDoc(orgDocRef, {
707
+ admin: updateAdminFn ? updateAdminFn(organizationUsers.admin, currentUserId) : updateFn(organizationUsers.admin, currentUserId),
708
+ regular: updateFn(organizationUsers.regular, currentUserId)
709
+ });
710
+ observer.next();
711
+ observer.complete();
712
+ });
713
+ });
714
+ }
715
+ addDivisions(orgId, newDivision) {
716
+ return this.updateOrganizationDivisions(orgId, newDivision, this.addItem);
717
+ }
718
+ deleteDivision(orgId, newDivision) {
719
+ return this.updateOrganizationDivisions(orgId, newDivision, this.removeItem);
720
+ }
721
+ updateOrganizationDivisions(orgId, newDivision, updateFn) {
722
+ const orgDocRef = doc(this.orgCollection, orgId);
723
+ const organizationDivisions = this.getOrganizationDivisions(orgId);
724
+ return new Observable((observer) => {
725
+ organizationDivisions.pipe(take(1)).subscribe(async (divisions) => {
726
+ if (!divisions) {
727
+ observer.error(new Error('Organization divisions data is unavailable.'));
728
+ return;
729
+ }
730
+ await updateDoc(orgDocRef, {
731
+ divisions: updateFn(divisions, newDivision)
732
+ });
733
+ observer.next();
734
+ observer.complete();
735
+ });
736
+ });
737
+ }
738
+ addItem(arr, item) {
739
+ return [...arr, item];
740
+ }
741
+ removeItem(arr, item) {
742
+ return arr.filter(i => i !== item);
743
+ }
744
+ nothing(arr, item) {
745
+ return arr;
746
+ }
747
+ updateOrganizationInformation(orgId, info) {
748
+ const orgDocRef = doc(this.orgCollection, orgId);
749
+ return new Observable((observer) => {
750
+ const updateData = {};
751
+ Object.entries(info).forEach(([key, value]) => {
752
+ if (value !== null) {
753
+ updateData[key] = value;
754
+ }
755
+ });
756
+ if (Object.keys(updateData).length > 0) {
757
+ updateDoc(orgDocRef, updateData)
758
+ .then(() => {
759
+ observer.next();
760
+ observer.complete();
761
+ })
762
+ .catch((error) => observer.error(error));
763
+ }
764
+ else {
765
+ observer.complete();
766
+ }
767
+ });
768
+ }
769
+ createOrganization(name, description, contact) {
770
+ const currentUserId = this.auth.currentUser?.uid;
771
+ if (!currentUserId) {
772
+ throw new Error('Current user is not authenticated.');
773
+ }
774
+ const orgRef = doc(this.orgCollection);
775
+ const org = {
776
+ _id: orgRef.id,
777
+ name,
778
+ description,
779
+ admin: [currentUserId],
780
+ regular: [],
781
+ pending: [],
782
+ adminUser: [],
783
+ regularUser: [],
784
+ pendingUser: [],
785
+ isPublic: false,
786
+ contact,
787
+ divisions: [],
788
+ };
789
+ return from(setDoc(orgRef, org)).pipe(concatMap(() => this.updateUserOrganizations(org._id, this.addItem, currentUserId)), take(1));
790
+ }
791
+ deleteOrganization(orgId, users) {
792
+ const userObservables = users.map(uid => this.updateUserOrganizations(orgId, this.removeItem, uid));
793
+ return forkJoin(userObservables).pipe(concatMap(() => {
794
+ const orgRef = doc(this.orgCollection, orgId);
795
+ return from(deleteDoc(orgRef)).pipe(catchError((error) => {
796
+ throw new Error('Error al eliminar la organización');
797
+ }), take(1));
798
+ }));
799
+ }
800
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OrganizationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
801
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OrganizationService, providedIn: 'root' });
802
+ }
803
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OrganizationService, decorators: [{
804
+ type: Injectable,
805
+ args: [{
806
+ providedIn: 'root',
807
+ }]
808
+ }], ctorParameters: () => [] });
809
+
810
+ class OrganizationAdminComponent {
811
+ orgService;
812
+ userService;
813
+ confirmationService;
814
+ organization;
815
+ users = [];
816
+ skelletonData = Array.from({ length: 5 }).map(() => { });
817
+ divisions = [];
818
+ newDivision = "";
819
+ divisionError = false;
820
+ descriptionError = false;
821
+ newUser = "";
822
+ userError = false;
823
+ usersSubscription;
824
+ divisionsSubscription;
825
+ inplaceIndicator = false;
826
+ constructor(orgService, userService, confirmationService) {
827
+ this.orgService = orgService;
828
+ this.userService = userService;
829
+ this.confirmationService = confirmationService;
830
+ }
831
+ ngOnInit() {
832
+ this.usersSubscription = this.orgService.getOrganizationUsers(this.organization._id).subscribe(newUsers => this.users = newUsers.sort((a, b) => b.email.localeCompare(a.email)));
833
+ this.divisionsSubscription = this.orgService.getOrganizationDivisions(this.organization._id).subscribe(newDivisions => this.divisions = newDivisions);
834
+ }
835
+ ngOnDestroy() {
836
+ this.unsubscribe();
837
+ }
838
+ unsubscribe() {
839
+ if (this.usersSubscription) {
840
+ this.usersSubscription.unsubscribe();
841
+ }
842
+ if (this.divisionsSubscription) {
843
+ this.divisionsSubscription.unsubscribe();
844
+ }
845
+ }
846
+ isCurrentUser(userId) {
847
+ return this.userService.isCurrentUser(userId);
848
+ }
849
+ deleteUser(userId, userName) {
850
+ let isSuccess = true;
851
+ this.orgService.deleteUserFromOrganization(this.organization._id, userId).pipe(catchError(error => {
852
+ isSuccess = false;
853
+ this.orgService.emitMessage({
854
+ severity: 'error',
855
+ summary: 'Error',
856
+ detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
857
+ life: 3000,
858
+ closable: true
859
+ });
860
+ return of(null);
861
+ }), finalize(() => {
862
+ if (isSuccess) {
863
+ this.orgService.emitMessage({
864
+ severity: 'info',
865
+ summary: 'Info',
866
+ detail: `You deleted ${userName ?? userId} from the organization without problems.`,
867
+ life: 3000,
868
+ closable: true
869
+ });
870
+ }
871
+ })).subscribe();
872
+ }
873
+ switchAdminState(userId, userName, newState) {
874
+ let isSuccess = true;
875
+ this.orgService.changeAdminState(this.organization._id, userId, newState).pipe(catchError(error => {
876
+ isSuccess = false;
877
+ const user = this.users.find(u => u._id === userId);
878
+ if (user)
879
+ user.isAdmin = true;
880
+ this.orgService.emitMessage({
881
+ severity: 'error',
882
+ summary: 'Error',
883
+ detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
884
+ life: 3000,
885
+ closable: true
886
+ });
887
+ return of(null);
888
+ }), finalize(() => {
889
+ if (isSuccess) {
890
+ const user = this.users.find(u => u._id === userId);
891
+ if (user)
892
+ user.isAdmin = newState;
893
+ if (this.isCurrentUser(userId))
894
+ this.organization.isAdmin = newState;
895
+ this.orgService.emitMessage({
896
+ severity: 'info',
897
+ summary: 'Info',
898
+ detail: newState ? `${userName ?? userId} is now an administrator of the organization.` : `${userName ?? userId} is no longer an administrator of the organization.`,
899
+ life: 3000,
900
+ closable: true
901
+ });
902
+ }
903
+ })).subscribe();
904
+ }
905
+ deleteDivision(division) {
906
+ let isSuccess = true;
907
+ this.orgService.deleteDivision(this.organization._id, division).pipe(catchError(error => {
908
+ isSuccess = false;
909
+ this.orgService.emitMessage({
910
+ severity: 'error',
911
+ summary: 'Error',
912
+ detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
913
+ life: 3000,
914
+ closable: true
915
+ });
916
+ return of(null);
917
+ }), finalize(() => {
918
+ if (isSuccess) {
919
+ this.orgService.emitMessage({
920
+ severity: 'info',
921
+ summary: 'Info',
922
+ detail: `You deleted ${division} from the organization without problems.`,
923
+ life: 3000,
924
+ closable: true
925
+ });
926
+ }
927
+ })).subscribe();
928
+ }
929
+ addDivision() {
930
+ if (this.divisions.includes(this.newDivision)) {
931
+ this.divisionError = true;
932
+ this.orgService.emitMessage({
933
+ severity: 'warn',
934
+ summary: 'Warn',
935
+ detail: 'You cannot add an existing division.',
936
+ life: 3000,
937
+ closable: true,
938
+ });
939
+ return;
940
+ }
941
+ let isSuccess = true;
942
+ this.orgService.addDivisions(this.organization._id, this.newDivision).pipe(catchError(error => {
943
+ isSuccess = false;
944
+ this.divisionError = true;
945
+ this.orgService.emitMessage({
946
+ severity: 'error',
947
+ summary: 'Error',
948
+ detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
949
+ life: 3000,
950
+ closable: true
951
+ });
952
+ return of(null);
953
+ }), finalize(() => {
954
+ if (isSuccess) {
955
+ this.divisionError = false;
956
+ this.orgService.emitMessage({
957
+ severity: 'info',
958
+ summary: 'Info',
959
+ detail: `You added ${this.newDivision} to the organization without problems.`,
960
+ life: 3000,
961
+ closable: true
962
+ });
963
+ this.newDivision = "";
964
+ }
965
+ })).subscribe();
966
+ }
967
+ updateDescription(updateInfo) {
968
+ let isSuccess = true;
969
+ this.orgService.updateOrganizationInformation(this.organization._id, updateInfo).pipe(catchError(error => {
970
+ isSuccess = false;
971
+ this.descriptionError = true;
972
+ this.orgService.emitMessage({
973
+ severity: 'error',
974
+ summary: 'Error',
975
+ detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
976
+ life: 3000,
977
+ closable: true
978
+ });
979
+ return of(null);
980
+ }), finalize(() => {
981
+ if (isSuccess) {
982
+ this.descriptionError = false;
983
+ this.organization.name = updateInfo.name ?? this.organization.name;
984
+ this.organization.description = updateInfo.description ?? this.organization.description;
985
+ this.organization.email = updateInfo.contact ?? this.organization.email;
986
+ this.orgService.emitMessage({
987
+ severity: 'info',
988
+ summary: 'Info',
989
+ detail: `You modified the organization description without problems.`,
990
+ life: 3000,
991
+ closable: true
992
+ });
993
+ }
994
+ })).subscribe();
995
+ }
996
+ addUserToOrganization() {
997
+ let isSuccess = true;
998
+ this.userService.getUidWithEmail(this.newUser).pipe(switchMap(data => {
999
+ if (this.users.some(user => user._id === data.uid)) {
1000
+ isSuccess = false;
1001
+ this.userError = true;
1002
+ this.orgService.emitMessage({
1003
+ severity: 'warn',
1004
+ summary: 'Warn',
1005
+ detail: `${this.newUser} already belong to this organization.`,
1006
+ life: 3000,
1007
+ closable: true
1008
+ });
1009
+ return of(null);
1010
+ }
1011
+ return this.orgService.addUserToOrganization(this.organization._id, data.uid);
1012
+ }), catchError(error => {
1013
+ isSuccess = false;
1014
+ this.userError = true;
1015
+ this.orgService.emitMessage({
1016
+ severity: 'error',
1017
+ summary: 'Error',
1018
+ detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
1019
+ life: 3000,
1020
+ closable: true
1021
+ });
1022
+ return of(null);
1023
+ }), finalize(() => {
1024
+ if (isSuccess) {
1025
+ this.userError = false;
1026
+ this.orgService.emitMessage({
1027
+ severity: 'info',
1028
+ summary: 'Info',
1029
+ detail: `You added ${this.newUser} to the organization without problems.`,
1030
+ life: 3000,
1031
+ closable: true
1032
+ });
1033
+ this.newUser = "";
1034
+ }
1035
+ })).subscribe();
1036
+ }
1037
+ deleteUserModal(event, userId, userName) {
1038
+ this.confirmationService.confirm({
1039
+ target: event.target,
1040
+ message: `Do you want to delete ${userName} from this organization?`,
1041
+ header: 'Delete User',
1042
+ icon: 'pi pi-info-circle',
1043
+ rejectLabel: 'Cancel',
1044
+ rejectButtonProps: {
1045
+ label: 'Cancel',
1046
+ severity: 'secondary',
1047
+ },
1048
+ acceptButtonProps: {
1049
+ label: 'Delete',
1050
+ severity: 'primary',
1051
+ },
1052
+ accept: () => {
1053
+ this.deleteUser(userId, userName);
1054
+ },
1055
+ reject: () => {
1056
+ },
1057
+ });
1058
+ }
1059
+ deleteDivisionModal(event, division) {
1060
+ this.confirmationService.confirm({
1061
+ target: event.target,
1062
+ message: `Do you want to delete ${division} from this organization?`,
1063
+ header: 'Delete Division',
1064
+ icon: 'pi pi-info-circle',
1065
+ rejectLabel: 'Cancel',
1066
+ rejectButtonProps: {
1067
+ label: 'Cancel',
1068
+ severity: 'secondary',
1069
+ },
1070
+ acceptButtonProps: {
1071
+ label: 'Delete',
1072
+ severity: 'primary',
1073
+ },
1074
+ accept: () => {
1075
+ this.deleteDivision(division);
1076
+ },
1077
+ reject: () => {
1078
+ },
1079
+ });
1080
+ }
1081
+ deleteOrganizationModal(event) {
1082
+ this.confirmationService.confirm({
1083
+ target: event.target,
1084
+ message: `Do you want to delete this organization?`,
1085
+ header: 'Delete Organization',
1086
+ icon: 'pi pi-info-circle',
1087
+ rejectLabel: 'Cancel',
1088
+ rejectButtonProps: {
1089
+ label: 'Cancel',
1090
+ severity: 'secondary',
1091
+ },
1092
+ acceptButtonProps: {
1093
+ label: 'Delete',
1094
+ severity: 'primary',
1095
+ },
1096
+ accept: () => {
1097
+ this.deleteOrganization();
1098
+ },
1099
+ reject: () => {
1100
+ },
1101
+ });
1102
+ }
1103
+ deleteOrganization() {
1104
+ let isSuccess = true;
1105
+ this.orgService.deleteOrganization(this.organization._id, this.users.map(user => user._id)).pipe(catchError(error => {
1106
+ isSuccess = false;
1107
+ this.orgService.emitMessage({
1108
+ severity: 'error',
1109
+ summary: 'Error',
1110
+ detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
1111
+ life: 3000,
1112
+ closable: true
1113
+ });
1114
+ return of(null);
1115
+ }), finalize(() => {
1116
+ if (isSuccess) {
1117
+ this.orgService.emitMessage({
1118
+ severity: 'info',
1119
+ summary: 'Info',
1120
+ detail: `You deleted ${this.organization.name} without problems.`,
1121
+ life: 3000,
1122
+ closable: true
1123
+ });
1124
+ }
1125
+ })).subscribe();
1126
+ }
1127
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OrganizationAdminComponent, deps: [{ token: OrganizationService }, { token: UserService }, { token: i2$1.ConfirmationService }], target: i0.ɵɵFactoryTarget.Component });
1128
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: OrganizationAdminComponent, isStandalone: true, selector: "organization-admin", inputs: { organization: "organization" }, providers: [ConfirmationService], ngImport: i0, template: "<p-confirmdialog />\r\n\r\n<div class=\"mt-4\" *ngIf=\"inplaceIndicator; else AdminContent\">\r\n <p-accordion [value]=\"[]\" [multiple]=\"true\" class=\"custom-acordion\">\r\n <p-accordion-panel value=\"0\">\r\n <p-accordion-header>Description</p-accordion-header>\r\n <p-accordion-content>\r\n <organization-form [organization]=\"organization\" [descriptionError]=\"descriptionError\" (formChange)=\"updateDescription($event)\"></organization-form>\r\n </p-accordion-content>\r\n </p-accordion-panel>\r\n \r\n <p-accordion-panel value=\"1\">\r\n <p-accordion-header>Users</p-accordion-header>\r\n <p-accordion-content>\r\n <div class=\"flex flex-wrap my-3 justify-content-center align-items-center gap-4\">\r\n <p-floatlabel variant=\"on\" [class]=\"userError ? 'custom-floatlabel error-floatlabel' : 'custom-floatlabel'\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-envelope\" />\r\n <input pInputText id=\"nDivision\" autocomplete=\"off\" class=\"w-full max-w-25rem\" [class]=\"userError ? 'custom-input error-input' : 'custom-input'\" \r\n [(ngModel)]=\"newUser\" (ngModelChange)=\"userError = false;\"/>\r\n </p-iconfield>\r\n <label for=\"nDivision\">User Email</label>\r\n </p-floatlabel>\r\n <p-button class=\"custom-button\" label=\"Add User\" size=\"small\" [disabled]=\"!newUser\" (onClick)=\"addUserToOrganization()\"/>\r\n </div>\r\n <p-table [value]=\"users\" [paginator]=\"true\" [rows]=\"5\" class=\"custom-table\">\r\n <ng-template #header>\r\n <tr>\r\n <th>Email</th>\r\n <th>Name</th>\r\n <th>Admin</th>\r\n <th style=\"width: 5rem\"></th>\r\n </tr>\r\n </ng-template>\r\n <ng-template #body let-user>\r\n <tr >\r\n <td>{{ user.email }}</td>\r\n <td>{{ user.name }}</td>\r\n <td>\r\n <p-toggleswitch class=\"custom-toogle\" [(ngModel)]=\"user.isAdmin\" (onChange)=\"switchAdminState(user._id, user.name, $event.checked)\"/>\r\n </td>\r\n <td>\r\n <p-button class=\"flex trash-button\" variant=\"text\" rounded=\"true\" size=\"large\" icon=\"pi pi-trash\" [disabled]=\"isCurrentUser(user._id)\" (onClick)=\"deleteUserModal($event, user._id, user.name)\"/>\r\n </td>\r\n </tr>\r\n </ng-template>\r\n </p-table>\r\n </p-accordion-content>\r\n </p-accordion-panel>\r\n \r\n <p-accordion-panel value=\"2\">\r\n <p-accordion-header>Divisions</p-accordion-header>\r\n <p-accordion-content>\r\n <div class=\"flex flex-wrap my-3 justify-content-center align-items-center gap-4\">\r\n <p-floatlabel variant=\"on\" [class]=\"divisionError ? 'custom-floatlabel error-floatlabel' : 'custom-floatlabel'\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-pencil\" />\r\n <input pInputText id=\"nDivision\" autocomplete=\"off\" class=\"w-full max-w-25rem\" [class]=\"divisionError ? 'custom-input error-input' : 'custom-input'\" \r\n [(ngModel)]=\"newDivision\" (ngModelChange)=\"divisionError = false;\"/>\r\n </p-iconfield>\r\n <label for=\"nDivision\">New Division</label>\r\n </p-floatlabel>\r\n <p-button class=\"custom-button\" label=\"Add Division\" size=\"small\" [disabled]=\"!newDivision\" (onClick)=\"addDivision()\"/>\r\n </div>\r\n <p-table [value]=\"divisions\" [paginator]=\"true\" [rows]=\"5\" class=\"custom-table\">\r\n <ng-template #header>\r\n <tr>\r\n <th>Name</th>\r\n <th style=\"width: 5rem\"></th>\r\n </tr>\r\n </ng-template>\r\n <ng-template #body let-division>\r\n <tr >\r\n <td>{{ division }}</td>\r\n <td>\r\n <p-button class=\"flex trash-button\" variant=\"text\" rounded=\"true\" size=\"large\" icon=\"pi pi-trash\" (onClick)=\"deleteDivisionModal($event, division)\"/>\r\n </td>\r\n </tr>\r\n </ng-template>\r\n </p-table>\r\n </p-accordion-content>\r\n </p-accordion-panel>\r\n </p-accordion>\r\n \r\n <div class=\"flex justify-content-between align-items-center mt-4 gap-4\">\r\n <div class=\"custom-inplace-display\" (click)=\"inplaceIndicator = false\">Collapse</div>\r\n <p-button class=\"delete-button\" label=\"Delete Organization\" size=\"small\" (onClick)=\"deleteOrganizationModal($event)\"/>\r\n </div>\r\n</div>\r\n\r\n<ng-template #AdminContent>\r\n <p class=\"mb-0 custom-inplace-display\" (click)=\"inplaceIndicator = true\">Admin Content</p>\r\n</ng-template>", styles: [".custom-button{--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}.delete-button{--p-button-primary-background: var(--danger-color);--p-button-primary-border-color: var(--danger-color);--p-button-primary-hover-background: color-mix(in srgb, var(--danger-color) 90%, black 10%);--p-button-primary-hover-border-color: color-mix(in srgb, var(--danger-color) 90%, black 10%);--p-button-primary-active-background: color-mix(in srgb, var(--danger-color) 70%, black 30%);--p-button-primary-active-border-color: color-mix(in srgb, var(--danger-color) 80%, black 20%)}.trash-button{--p-button-text-primary-color: var(--danger-color);--p-button-text-primary-hover-background: color-mix(in srgb, var(--danger-color) 10%, rgba(255, 255, 255, 0) 90%);--p-button-text-primary-active-background: color-mix(in srgb, var(--danger-color) 20%, rgba(255, 255, 255, 0) 80%)}.custom-toogle{--p-toggleswitch-checked-border-color: var(--secondary-color);--p-toggleswitch-checked-hover-border-color: var(--hover-color);--p-toggleswitch-checked-background: var(--secondary-color);--p-toggleswitch-checked-hover-background: var(--hover-color)}.custom-acordion{--p-accordion-header-color: color-mix(in srgb, var(--primary-color) 60%, rgba(255, 255, 255, 0) 40%);--p-accordion-header-hover-color: var(--hover-color);--p-accordion-header-active-color: var(--primary-color);--p-accordion-content-color: var(--primary-color)}.custom-table{--p-datatable-header-cell-color: var(--primary-color);--p-datatable-row-color: var(--primary-color);--p-paginator-nav-button-color: color-mix(in srgb, var(--primary-color) 60%, rgba(255, 255, 255, 0) 40%);--p-paginator-nav-button-selected-background: color-mix(in srgb, var(--hover-color) 10%, rgba(255, 255, 255, 0) 90%);--p-paginator-nav-button-hover-background: color-mix(in srgb, var(--secondary-color) 10%, rgba(255, 255, 255, 0) 90%)}.custom-input{--p-inputtext-focus-border-color: var(--hover-color);--p-inputtext-hover-border-color: var(--hover-color)}.custom-floatlabel{--p-floatlabel-focus-color: var(--hover-color)}.error-input{--p-inputtext-border-color: var(--danger-color)}.error-floatlabel{--p-floatlabel-color: var(--danger-color)}::ng-deep .p-confirmdialog{color:var(--primary-color)!important}::ng-deep .p-confirmdialog .p-confirmdialog-icon{color:var(--primary-color)!important}::ng-deep .p-confirmdialog .p-button{--p-button-primary-background: var(--danger-color);--p-button-primary-border-color: var(--danger-color);--p-button-primary-hover-background: color-mix(in srgb, var(--danger-color) 90%, black 10%);--p-button-primary-hover-border-color: color-mix(in srgb, var(--danger-color) 90%, black 10%);--p-button-primary-active-background: color-mix(in srgb, var(--danger-color) 70%, black 30%);--p-button-primary-active-border-color: color-mix(in srgb, var(--danger-color) 80%, black 20%)}.custom-inplace-display{display:block!important;max-width:fit-content;white-space:nowrap;cursor:pointer;color:var(--secondary-color);padding:0!important;border:none!important;border-radius:.1rem;outline:none}.custom-inplace-display:hover,.custom-inplace-display:focus{color:var(--hover-color)}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i6$1.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "virtualRowHeight", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i7$1.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["style", "styleClass", "tabindex", "inputId", "name", "disabled", "readonly", "trueValue", "falseValue", "ariaLabel", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i8.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: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AccordionModule }, { kind: "component", type: i9$1.Accordion, selector: "p-accordion", inputs: ["value", "multiple", "style", "styleClass", "expandIcon", "collapseIcon", "selectOnFocus", "transitionOptions", "activeIndex", "headerAriaLevel"], outputs: ["valueChange", "activeIndexChange", "onClose", "onOpen"] }, { kind: "component", type: i9$1.AccordionPanel, selector: "p-accordion-panel, p-accordionpanel", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: i9$1.AccordionHeader, selector: "p-accordion-header, p-accordionheader" }, { kind: "component", type: i9$1.AccordionContent, selector: "p-accordion-content, p-accordioncontent" }, { kind: "ngmodule", type: InputIconModule }, { kind: "component", type: i4.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["styleClass"] }, { kind: "ngmodule", type: IconFieldModule }, { kind: "component", type: i5.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["iconPosition", "styleClass"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i6.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: FloatLabelModule }, { kind: "component", type: i7.FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "ngmodule", type: ConfirmDialogModule }, { kind: "component", type: i14.ConfirmDialog, selector: "p-confirmDialog, p-confirmdialog, p-confirm-dialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "closeAriaLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "visible", "position"], outputs: ["onHide"] }, { kind: "component", type: OrganizationFormComponent, selector: "organization-form", inputs: ["organization", "descriptionError", "buttonLabel", "validationFunction"], outputs: ["formChange"] }] });
1129
+ }
1130
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OrganizationAdminComponent, decorators: [{
1131
+ type: Component,
1132
+ args: [{ standalone: true, selector: 'organization-admin', imports: [ButtonModule, CommonModule, TableModule, ToggleSwitchModule, FormsModule, AccordionModule, InputIconModule,
1133
+ IconFieldModule, InputTextModule, FloatLabelModule, ConfirmDialogModule, OrganizationFormComponent], providers: [ConfirmationService], template: "<p-confirmdialog />\r\n\r\n<div class=\"mt-4\" *ngIf=\"inplaceIndicator; else AdminContent\">\r\n <p-accordion [value]=\"[]\" [multiple]=\"true\" class=\"custom-acordion\">\r\n <p-accordion-panel value=\"0\">\r\n <p-accordion-header>Description</p-accordion-header>\r\n <p-accordion-content>\r\n <organization-form [organization]=\"organization\" [descriptionError]=\"descriptionError\" (formChange)=\"updateDescription($event)\"></organization-form>\r\n </p-accordion-content>\r\n </p-accordion-panel>\r\n \r\n <p-accordion-panel value=\"1\">\r\n <p-accordion-header>Users</p-accordion-header>\r\n <p-accordion-content>\r\n <div class=\"flex flex-wrap my-3 justify-content-center align-items-center gap-4\">\r\n <p-floatlabel variant=\"on\" [class]=\"userError ? 'custom-floatlabel error-floatlabel' : 'custom-floatlabel'\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-envelope\" />\r\n <input pInputText id=\"nDivision\" autocomplete=\"off\" class=\"w-full max-w-25rem\" [class]=\"userError ? 'custom-input error-input' : 'custom-input'\" \r\n [(ngModel)]=\"newUser\" (ngModelChange)=\"userError = false;\"/>\r\n </p-iconfield>\r\n <label for=\"nDivision\">User Email</label>\r\n </p-floatlabel>\r\n <p-button class=\"custom-button\" label=\"Add User\" size=\"small\" [disabled]=\"!newUser\" (onClick)=\"addUserToOrganization()\"/>\r\n </div>\r\n <p-table [value]=\"users\" [paginator]=\"true\" [rows]=\"5\" class=\"custom-table\">\r\n <ng-template #header>\r\n <tr>\r\n <th>Email</th>\r\n <th>Name</th>\r\n <th>Admin</th>\r\n <th style=\"width: 5rem\"></th>\r\n </tr>\r\n </ng-template>\r\n <ng-template #body let-user>\r\n <tr >\r\n <td>{{ user.email }}</td>\r\n <td>{{ user.name }}</td>\r\n <td>\r\n <p-toggleswitch class=\"custom-toogle\" [(ngModel)]=\"user.isAdmin\" (onChange)=\"switchAdminState(user._id, user.name, $event.checked)\"/>\r\n </td>\r\n <td>\r\n <p-button class=\"flex trash-button\" variant=\"text\" rounded=\"true\" size=\"large\" icon=\"pi pi-trash\" [disabled]=\"isCurrentUser(user._id)\" (onClick)=\"deleteUserModal($event, user._id, user.name)\"/>\r\n </td>\r\n </tr>\r\n </ng-template>\r\n </p-table>\r\n </p-accordion-content>\r\n </p-accordion-panel>\r\n \r\n <p-accordion-panel value=\"2\">\r\n <p-accordion-header>Divisions</p-accordion-header>\r\n <p-accordion-content>\r\n <div class=\"flex flex-wrap my-3 justify-content-center align-items-center gap-4\">\r\n <p-floatlabel variant=\"on\" [class]=\"divisionError ? 'custom-floatlabel error-floatlabel' : 'custom-floatlabel'\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-pencil\" />\r\n <input pInputText id=\"nDivision\" autocomplete=\"off\" class=\"w-full max-w-25rem\" [class]=\"divisionError ? 'custom-input error-input' : 'custom-input'\" \r\n [(ngModel)]=\"newDivision\" (ngModelChange)=\"divisionError = false;\"/>\r\n </p-iconfield>\r\n <label for=\"nDivision\">New Division</label>\r\n </p-floatlabel>\r\n <p-button class=\"custom-button\" label=\"Add Division\" size=\"small\" [disabled]=\"!newDivision\" (onClick)=\"addDivision()\"/>\r\n </div>\r\n <p-table [value]=\"divisions\" [paginator]=\"true\" [rows]=\"5\" class=\"custom-table\">\r\n <ng-template #header>\r\n <tr>\r\n <th>Name</th>\r\n <th style=\"width: 5rem\"></th>\r\n </tr>\r\n </ng-template>\r\n <ng-template #body let-division>\r\n <tr >\r\n <td>{{ division }}</td>\r\n <td>\r\n <p-button class=\"flex trash-button\" variant=\"text\" rounded=\"true\" size=\"large\" icon=\"pi pi-trash\" (onClick)=\"deleteDivisionModal($event, division)\"/>\r\n </td>\r\n </tr>\r\n </ng-template>\r\n </p-table>\r\n </p-accordion-content>\r\n </p-accordion-panel>\r\n </p-accordion>\r\n \r\n <div class=\"flex justify-content-between align-items-center mt-4 gap-4\">\r\n <div class=\"custom-inplace-display\" (click)=\"inplaceIndicator = false\">Collapse</div>\r\n <p-button class=\"delete-button\" label=\"Delete Organization\" size=\"small\" (onClick)=\"deleteOrganizationModal($event)\"/>\r\n </div>\r\n</div>\r\n\r\n<ng-template #AdminContent>\r\n <p class=\"mb-0 custom-inplace-display\" (click)=\"inplaceIndicator = true\">Admin Content</p>\r\n</ng-template>", styles: [".custom-button{--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}.delete-button{--p-button-primary-background: var(--danger-color);--p-button-primary-border-color: var(--danger-color);--p-button-primary-hover-background: color-mix(in srgb, var(--danger-color) 90%, black 10%);--p-button-primary-hover-border-color: color-mix(in srgb, var(--danger-color) 90%, black 10%);--p-button-primary-active-background: color-mix(in srgb, var(--danger-color) 70%, black 30%);--p-button-primary-active-border-color: color-mix(in srgb, var(--danger-color) 80%, black 20%)}.trash-button{--p-button-text-primary-color: var(--danger-color);--p-button-text-primary-hover-background: color-mix(in srgb, var(--danger-color) 10%, rgba(255, 255, 255, 0) 90%);--p-button-text-primary-active-background: color-mix(in srgb, var(--danger-color) 20%, rgba(255, 255, 255, 0) 80%)}.custom-toogle{--p-toggleswitch-checked-border-color: var(--secondary-color);--p-toggleswitch-checked-hover-border-color: var(--hover-color);--p-toggleswitch-checked-background: var(--secondary-color);--p-toggleswitch-checked-hover-background: var(--hover-color)}.custom-acordion{--p-accordion-header-color: color-mix(in srgb, var(--primary-color) 60%, rgba(255, 255, 255, 0) 40%);--p-accordion-header-hover-color: var(--hover-color);--p-accordion-header-active-color: var(--primary-color);--p-accordion-content-color: var(--primary-color)}.custom-table{--p-datatable-header-cell-color: var(--primary-color);--p-datatable-row-color: var(--primary-color);--p-paginator-nav-button-color: color-mix(in srgb, var(--primary-color) 60%, rgba(255, 255, 255, 0) 40%);--p-paginator-nav-button-selected-background: color-mix(in srgb, var(--hover-color) 10%, rgba(255, 255, 255, 0) 90%);--p-paginator-nav-button-hover-background: color-mix(in srgb, var(--secondary-color) 10%, rgba(255, 255, 255, 0) 90%)}.custom-input{--p-inputtext-focus-border-color: var(--hover-color);--p-inputtext-hover-border-color: var(--hover-color)}.custom-floatlabel{--p-floatlabel-focus-color: var(--hover-color)}.error-input{--p-inputtext-border-color: var(--danger-color)}.error-floatlabel{--p-floatlabel-color: var(--danger-color)}::ng-deep .p-confirmdialog{color:var(--primary-color)!important}::ng-deep .p-confirmdialog .p-confirmdialog-icon{color:var(--primary-color)!important}::ng-deep .p-confirmdialog .p-button{--p-button-primary-background: var(--danger-color);--p-button-primary-border-color: var(--danger-color);--p-button-primary-hover-background: color-mix(in srgb, var(--danger-color) 90%, black 10%);--p-button-primary-hover-border-color: color-mix(in srgb, var(--danger-color) 90%, black 10%);--p-button-primary-active-background: color-mix(in srgb, var(--danger-color) 70%, black 30%);--p-button-primary-active-border-color: color-mix(in srgb, var(--danger-color) 80%, black 20%)}.custom-inplace-display{display:block!important;max-width:fit-content;white-space:nowrap;cursor:pointer;color:var(--secondary-color);padding:0!important;border:none!important;border-radius:.1rem;outline:none}.custom-inplace-display:hover,.custom-inplace-display:focus{color:var(--hover-color)}\n"] }]
1134
+ }], ctorParameters: () => [{ type: OrganizationService }, { type: UserService }, { type: i2$1.ConfirmationService }], propDecorators: { organization: [{
1135
+ type: Input
1136
+ }] } });
1137
+
1138
+ class OrganizationPageComponent {
1139
+ orgService;
1140
+ messageService;
1141
+ userService;
1142
+ confirmationService;
1143
+ userOrganizations = [];
1144
+ orgSubscription;
1145
+ userStateSubscription;
1146
+ adminMessageSubscription;
1147
+ organizations = [];
1148
+ selectedOrganization;
1149
+ logged = false;
1150
+ duplicatedOrg = false;
1151
+ newOrganization = { _id: "", name: "", description: "", email: "", isAdmin: true };
1152
+ newOrganizationError = false;
1153
+ newOrganizationAcordion = [];
1154
+ constructor(orgService, messageService, userService, confirmationService) {
1155
+ this.orgService = orgService;
1156
+ this.messageService = messageService;
1157
+ this.userService = userService;
1158
+ this.confirmationService = confirmationService;
1159
+ }
1160
+ ngOnInit() {
1161
+ this.userStateSubscription = this.userService.getUserState().subscribe(({ logged }) => {
1162
+ this.logged = logged;
1163
+ });
1164
+ this.orgSubscription = this.orgService.getUserOrganizations().subscribe(orgs => {
1165
+ this.userOrganizations = orgs;
1166
+ });
1167
+ this.orgService.getOrganizations().pipe(take(1)).subscribe(orgs => {
1168
+ this.organizations = orgs.map(org => ({
1169
+ _id: org._id,
1170
+ name: org.name.trim().charAt(0).toUpperCase() + org.name.trim().slice(1)
1171
+ }));
1172
+ this.organizations.sort((a, b) => a.name.localeCompare(b.name));
1173
+ });
1174
+ this.adminMessageSubscription = this.orgService.adminOrganizationMessages$.subscribe(message => this.messageService.add(message));
1175
+ }
1176
+ ngOnDestroy() {
1177
+ this.orgSubscription?.unsubscribe();
1178
+ this.userStateSubscription?.unsubscribe();
1179
+ this.adminMessageSubscription?.unsubscribe();
1180
+ }
1181
+ leaveOrganization(orgId, orgName) {
1182
+ let isSuccess = true;
1183
+ this.orgService.leaveOrganization(orgId).pipe(catchError((error) => {
1184
+ isSuccess = false;
1185
+ this.messageService.add({
1186
+ severity: 'error',
1187
+ summary: 'Error',
1188
+ detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
1189
+ life: 3000,
1190
+ closable: true
1191
+ });
1192
+ return of(null);
1193
+ }), finalize(() => {
1194
+ if (isSuccess) {
1195
+ this.messageService.add({
1196
+ severity: 'info',
1197
+ summary: 'Info',
1198
+ detail: `You left ${orgName} without problems.`,
1199
+ life: 3000,
1200
+ closable: true
1201
+ });
1202
+ }
1203
+ })).subscribe();
1204
+ }
1205
+ joinOrganization() {
1206
+ if (!this.selectedOrganization) {
1207
+ return;
1208
+ }
1209
+ if (this.userOrganizations.some(userOrg => userOrg._id === this.selectedOrganization?._id)) {
1210
+ this.messageService.add({
1211
+ severity: 'warn',
1212
+ summary: 'Warn',
1213
+ detail: 'You cannot join an organization to which you already belong.',
1214
+ life: 3000,
1215
+ closable: true,
1216
+ });
1217
+ this.duplicatedOrg = true;
1218
+ return;
1219
+ }
1220
+ const orgId = this.selectedOrganization._id;
1221
+ const orgName = this.selectedOrganization.name;
1222
+ let isSuccess = true;
1223
+ this.orgService.joinOrganization(orgId).pipe(catchError((error) => {
1224
+ isSuccess = false;
1225
+ this.messageService.add({
1226
+ severity: 'error',
1227
+ summary: 'Error',
1228
+ detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
1229
+ life: 3000,
1230
+ closable: true
1231
+ });
1232
+ return of(null);
1233
+ }), finalize(() => {
1234
+ if (isSuccess) {
1235
+ this.messageService.add({
1236
+ severity: 'info',
1237
+ summary: 'Info',
1238
+ detail: `You joined ${orgName} without problems.`,
1239
+ life: 3000,
1240
+ closable: true
1241
+ });
1242
+ }
1243
+ })).subscribe();
1244
+ }
1245
+ updateDuplicatedOrg() {
1246
+ if (this.duplicatedOrg)
1247
+ this.duplicatedOrg = false;
1248
+ }
1249
+ copyEmail(email, name) {
1250
+ navigator.clipboard.writeText(email);
1251
+ this.messageService.add({
1252
+ severity: 'info',
1253
+ summary: 'Info',
1254
+ detail: `You copied ${name} contact email without problems.`,
1255
+ life: 3000,
1256
+ closable: true
1257
+ });
1258
+ }
1259
+ deleteModal(event, orgId, orgName) {
1260
+ this.confirmationService.confirm({
1261
+ target: event.target,
1262
+ message: 'Do you want to leave this organization?',
1263
+ header: 'Leave Organization',
1264
+ icon: 'pi pi-info-circle',
1265
+ rejectLabel: 'Cancel',
1266
+ rejectButtonProps: {
1267
+ label: 'Cancel',
1268
+ severity: 'secondary',
1269
+ },
1270
+ acceptButtonProps: {
1271
+ label: 'Delete',
1272
+ severity: 'primary',
1273
+ },
1274
+ accept: () => {
1275
+ this.leaveOrganization(orgId, orgName);
1276
+ },
1277
+ reject: () => {
1278
+ },
1279
+ });
1280
+ }
1281
+ createOrganization(createData) {
1282
+ if (!createData.name?.trim() || !createData.description?.trim() || !createData.contact?.trim()) {
1283
+ this.messageService.add({
1284
+ severity: 'warn',
1285
+ summary: 'Warn',
1286
+ detail: 'You cannot create an organization until you fill in all the fields.',
1287
+ life: 3000,
1288
+ closable: true,
1289
+ });
1290
+ this.newOrganizationError = true;
1291
+ return;
1292
+ }
1293
+ let isSuccess = true;
1294
+ this.orgService.createOrganization(createData.name, createData.description, createData.contact).pipe(catchError((error) => {
1295
+ isSuccess = false;
1296
+ this.messageService.add({
1297
+ severity: 'error',
1298
+ summary: 'Error',
1299
+ detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
1300
+ life: 3000,
1301
+ closable: true
1302
+ });
1303
+ this.newOrganizationError = true;
1304
+ return of(null);
1305
+ }), finalize(() => {
1306
+ if (isSuccess) {
1307
+ this.messageService.add({
1308
+ severity: 'info',
1309
+ summary: 'Info',
1310
+ detail: `You created ${createData.name} without problems.`,
1311
+ life: 3000,
1312
+ closable: true
1313
+ });
1314
+ this.newOrganizationError = false;
1315
+ this.newOrganization = { _id: "", name: "", description: "", email: "", isAdmin: true };
1316
+ this.newOrganizationAcordion = [];
1317
+ }
1318
+ })).subscribe();
1319
+ }
1320
+ newOrganizationValidation(data) {
1321
+ return data.some(([first, second]) => first === second || first === "");
1322
+ }
1323
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OrganizationPageComponent, deps: [{ token: OrganizationService }, { token: i2$1.MessageService }, { token: UserService }, { token: i2$1.ConfirmationService }], target: i0.ɵɵFactoryTarget.Component });
1324
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: OrganizationPageComponent, isStandalone: true, selector: "organization-page", providers: [MessageService, ConfirmationService], ngImport: i0, template: "<p-toast class=\"custom-toast\" position=\"bottom-right\"/>\r\n<p-confirmdialog />\r\n<div class=\"flex flex-column align-items-stretch p-4\">\r\n <h2 class=\"mx-auto\">Your Organization(s) Details</h2>\r\n <p class=\"mx-auto\">You are part of {{userOrganizations.length}} organization(s). You can also create your own organization.</p>\r\n <div class=\"flex flex-wrap mb-4 align-items-center gap-4 justify-content-center w-full\">\r\n <p-select [options]=\"organizations\" [showClear]=\"true\" [disabled]=\"!logged\" [(ngModel)]=\"selectedOrganization\" \r\n [optionLabel]=\"'name'\" placeholder=\"Select an Organization\" [ngClass]=\"duplicatedOrg ? 'invalid-select' : 'custom-select'\" \r\n (onChange)=\"updateDuplicatedOrg()\" class=\"w-full max-w-30rem\" [checkmark]=\"true\" panelStyleClass=\"max-w-30rem\" />\r\n <p-button class=\"custom-button\" label=\"Join Organization\" size=\"small\" (click)=\"joinOrganization()\" [disabled]=\"!logged || !selectedOrganization\"/>\r\n </div>\r\n <div class=\"flex flex-column gap-4\">\r\n <p-card class=\"custom-color-card flex justify-content-center\" styleClass=\"flex-auto\" [style]=\"{ 'max-width': '50rem', 'min-width': '20rem', height: 'auto'}\" *ngFor=\"let organization of userOrganizations; let i = index\">\r\n <ng-template #header>\r\n <div class=\"flex justify-content-between\" style=\"padding-left: 1.25rem; padding-right: 1.25rem; padding-top: 1.25rem;\">\r\n <div class=\"p-card-title\">{{organization.name}}</div>\r\n <div class=\"flex gap-1\">\r\n <p-button class=\"flex email-button\" variant=\"text\" rounded=\"true\" size=\"large\" icon=\"pi pi-envelope\" [disabled]=\"!organization.email\" \r\n (click)=\"copyEmail(organization.email, organization.name)\" pTooltip=\"{{organization.email}}\" tooltipPosition=\"top\"/>\r\n <p-button class=\"flex trash-button\" variant=\"text\" rounded=\"true\" size=\"large\" icon=\"pi pi-sign-out\" (click)=\"deleteModal($event, organization._id, organization.name)\"/>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <p class=\"m-0\">\r\n {{organization.description}}\r\n </p>\r\n <div *ngIf=\"organization.isAdmin\">\r\n <organization-admin [organization]=\"organization\"></organization-admin>\r\n </div>\r\n </p-card>\r\n <p-card class=\"custom-color-card flex justify-content-center\" styleClass=\"flex-auto plus-card\" [style]=\"{ 'max-width': '50rem', 'min-width': '20rem', height: 'auto'}\">\r\n <ng-template #content>\r\n <p-accordion [value]=\"newOrganizationAcordion\" [multiple]=\"true\" class=\"custom-acordion\" [expandIcon]=\"'pi pi-plus'\" [collapseIcon]=\"'pi pi-minus'\">\r\n <p-accordion-panel class=\"custom-accordionpanel\" value=\"0\">\r\n <p-accordion-header class=\"custom-accordionheader\">Create New Organization</p-accordion-header>\r\n <p-accordion-content>\r\n <div class=\"pt-4\">\r\n <organization-form [organization]=\"newOrganization\" [descriptionError]=\"newOrganizationError\" [buttonLabel]=\"'Create Organization'\" [validationFunction]=\"newOrganizationValidation\" (formChange)=\"createOrganization($event)\"></organization-form>\r\n </div>\r\n </p-accordion-content>\r\n </p-accordion-panel>\r\n </p-accordion>\r\n </ng-template>\r\n </p-card>\r\n </div>\r\n</div>", styles: [".custom-button{--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}.custom-color-card{--p-card-color: var(--primary-color);--p-card-subtitle-color: var(--secondary-color);--p-card-title-font-size: 1.25rem;--p-card-title-font-weight: 600}.custom-toast{--p-toast-info-background: color-mix(in srgb, var(--secondary-color) 10%, rgba(255, 255, 255, .9) 90%);--p-toast-info-border-color: var(--secondary-color);--p-toast-info-color: var(--secondary-color);--p-toast-info-detail-color: var(--primary-color);--p-toast-error-background: color-mix(in srgb, var(--danger-color) 10%, rgba(255, 255, 255, .9) 90%);--p-toast-error-border-color: var(--danger-color);--p-toast-error-color: var(--danger-color);--p-toast-error-detail-color: var(--primary-color);--p-toast-warn-background: color-mix(in srgb, var(--warning-color) 10%, rgba(255, 255, 255, .9) 90%);--p-toast-warn-border-color: var(--warning-color);--p-toast-warn-color: var(--warning-color);--p-toast-warn-detail-color: var(--primary-color)}::ng-deep .p-toast-close-button .p-button-label{font-size:0}.custom-select{--p-select-hover-border-color: var(--hover-color);--p-select-focus-border-color: var(--hover-color)}.invalid-select{--p-select-border-color: var(--danger-color);--p-select-color: var(--danger-color);--p-select-hover-border-color: var(--hover-color);--p-select-focus-border-color: var(--hover-color)}.trash-button{--p-button-text-primary-color: var(--danger-color);--p-button-text-primary-hover-background: color-mix(in srgb, var(--danger-color) 10%, rgba(255, 255, 255, 0) 90%);--p-button-text-primary-active-background: color-mix(in srgb, var(--danger-color) 20%, rgba(255, 255, 255, 0) 80%)}.email-button{--p-button-text-primary-color: var(--secondary-color);--p-button-text-primary-hover-background: color-mix(in srgb, var(--secondary-color) 10%, rgba(255, 255, 255, 0) 90%);--p-button-text-primary-active-background: color-mix(in srgb, var(--secondary-color) 20%, rgba(255, 255, 255, 0) 80%)}::ng-deep .p-tooltip{--p-tooltip-background: var(--primary-color);--p-tooltip-max-width: 20rem}::ng-deep .p-tooltip-text{white-space:nowrap!important;word-break:keep-all!important;overflow:hidden!important;text-overflow:ellipsis!important}::ng-deep .p-confirmdialog{color:var(--primary-color)!important}::ng-deep .p-confirmdialog .p-confirmdialog-icon{color:var(--primary-color)!important}::ng-deep .p-confirmdialog .p-button{--p-button-primary-background: var(--danger-color);--p-button-primary-border-color: var(--danger-color);--p-button-primary-hover-background: color-mix(in srgb, var(--danger-color) 90%, black 10%);--p-button-primary-hover-border-color: color-mix(in srgb, var(--danger-color) 90%, black 10%);--p-button-primary-active-background: color-mix(in srgb, var(--danger-color) 70%, black 30%);--p-button-primary-active-border-color: color-mix(in srgb, var(--danger-color) 80%, black 20%)}.custom-acordion{--p-accordion-header-color: color-mix(in srgb, var(--primary-color) 60%, rgba(255, 255, 255, 0) 40%);--p-accordion-header-hover-color: var(--hover-color);--p-accordion-header-active-color: var(--primary-color);--p-accordion-content-color: var(--primary-color)}.custom-accordionpanel{border-style:none!important}.custom-accordionheader{padding:0!important;padding-right:.75rem!important}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i6$2.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i9.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i8$2.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: OrganizationAdminComponent, selector: "organization-admin", inputs: ["organization"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i10.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: ConfirmDialogModule }, { kind: "component", type: i14.ConfirmDialog, selector: "p-confirmDialog, p-confirmdialog, p-confirm-dialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "closeAriaLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "visible", "position"], outputs: ["onHide"] }, { kind: "ngmodule", type: AccordionModule }, { kind: "component", type: i9$1.Accordion, selector: "p-accordion", inputs: ["value", "multiple", "style", "styleClass", "expandIcon", "collapseIcon", "selectOnFocus", "transitionOptions", "activeIndex", "headerAriaLevel"], outputs: ["valueChange", "activeIndexChange", "onClose", "onOpen"] }, { kind: "component", type: i9$1.AccordionPanel, selector: "p-accordion-panel, p-accordionpanel", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: i9$1.AccordionHeader, selector: "p-accordion-header, p-accordionheader" }, { kind: "component", type: i9$1.AccordionContent, selector: "p-accordion-content, p-accordioncontent" }, { kind: "component", type: OrganizationFormComponent, selector: "organization-form", inputs: ["organization", "descriptionError", "buttonLabel", "validationFunction"], outputs: ["formChange"] }] });
1325
+ }
1326
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OrganizationPageComponent, decorators: [{
1327
+ type: Component,
1328
+ args: [{ standalone: true, selector: 'organization-page', imports: [ButtonModule, CommonModule, CardModule, ToastModule, SelectModule, FormsModule, OrganizationAdminComponent, TooltipModule, ConfirmDialogModule, AccordionModule, OrganizationFormComponent], providers: [MessageService, ConfirmationService], template: "<p-toast class=\"custom-toast\" position=\"bottom-right\"/>\r\n<p-confirmdialog />\r\n<div class=\"flex flex-column align-items-stretch p-4\">\r\n <h2 class=\"mx-auto\">Your Organization(s) Details</h2>\r\n <p class=\"mx-auto\">You are part of {{userOrganizations.length}} organization(s). You can also create your own organization.</p>\r\n <div class=\"flex flex-wrap mb-4 align-items-center gap-4 justify-content-center w-full\">\r\n <p-select [options]=\"organizations\" [showClear]=\"true\" [disabled]=\"!logged\" [(ngModel)]=\"selectedOrganization\" \r\n [optionLabel]=\"'name'\" placeholder=\"Select an Organization\" [ngClass]=\"duplicatedOrg ? 'invalid-select' : 'custom-select'\" \r\n (onChange)=\"updateDuplicatedOrg()\" class=\"w-full max-w-30rem\" [checkmark]=\"true\" panelStyleClass=\"max-w-30rem\" />\r\n <p-button class=\"custom-button\" label=\"Join Organization\" size=\"small\" (click)=\"joinOrganization()\" [disabled]=\"!logged || !selectedOrganization\"/>\r\n </div>\r\n <div class=\"flex flex-column gap-4\">\r\n <p-card class=\"custom-color-card flex justify-content-center\" styleClass=\"flex-auto\" [style]=\"{ 'max-width': '50rem', 'min-width': '20rem', height: 'auto'}\" *ngFor=\"let organization of userOrganizations; let i = index\">\r\n <ng-template #header>\r\n <div class=\"flex justify-content-between\" style=\"padding-left: 1.25rem; padding-right: 1.25rem; padding-top: 1.25rem;\">\r\n <div class=\"p-card-title\">{{organization.name}}</div>\r\n <div class=\"flex gap-1\">\r\n <p-button class=\"flex email-button\" variant=\"text\" rounded=\"true\" size=\"large\" icon=\"pi pi-envelope\" [disabled]=\"!organization.email\" \r\n (click)=\"copyEmail(organization.email, organization.name)\" pTooltip=\"{{organization.email}}\" tooltipPosition=\"top\"/>\r\n <p-button class=\"flex trash-button\" variant=\"text\" rounded=\"true\" size=\"large\" icon=\"pi pi-sign-out\" (click)=\"deleteModal($event, organization._id, organization.name)\"/>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <p class=\"m-0\">\r\n {{organization.description}}\r\n </p>\r\n <div *ngIf=\"organization.isAdmin\">\r\n <organization-admin [organization]=\"organization\"></organization-admin>\r\n </div>\r\n </p-card>\r\n <p-card class=\"custom-color-card flex justify-content-center\" styleClass=\"flex-auto plus-card\" [style]=\"{ 'max-width': '50rem', 'min-width': '20rem', height: 'auto'}\">\r\n <ng-template #content>\r\n <p-accordion [value]=\"newOrganizationAcordion\" [multiple]=\"true\" class=\"custom-acordion\" [expandIcon]=\"'pi pi-plus'\" [collapseIcon]=\"'pi pi-minus'\">\r\n <p-accordion-panel class=\"custom-accordionpanel\" value=\"0\">\r\n <p-accordion-header class=\"custom-accordionheader\">Create New Organization</p-accordion-header>\r\n <p-accordion-content>\r\n <div class=\"pt-4\">\r\n <organization-form [organization]=\"newOrganization\" [descriptionError]=\"newOrganizationError\" [buttonLabel]=\"'Create Organization'\" [validationFunction]=\"newOrganizationValidation\" (formChange)=\"createOrganization($event)\"></organization-form>\r\n </div>\r\n </p-accordion-content>\r\n </p-accordion-panel>\r\n </p-accordion>\r\n </ng-template>\r\n </p-card>\r\n </div>\r\n</div>", styles: [".custom-button{--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}.custom-color-card{--p-card-color: var(--primary-color);--p-card-subtitle-color: var(--secondary-color);--p-card-title-font-size: 1.25rem;--p-card-title-font-weight: 600}.custom-toast{--p-toast-info-background: color-mix(in srgb, var(--secondary-color) 10%, rgba(255, 255, 255, .9) 90%);--p-toast-info-border-color: var(--secondary-color);--p-toast-info-color: var(--secondary-color);--p-toast-info-detail-color: var(--primary-color);--p-toast-error-background: color-mix(in srgb, var(--danger-color) 10%, rgba(255, 255, 255, .9) 90%);--p-toast-error-border-color: var(--danger-color);--p-toast-error-color: var(--danger-color);--p-toast-error-detail-color: var(--primary-color);--p-toast-warn-background: color-mix(in srgb, var(--warning-color) 10%, rgba(255, 255, 255, .9) 90%);--p-toast-warn-border-color: var(--warning-color);--p-toast-warn-color: var(--warning-color);--p-toast-warn-detail-color: var(--primary-color)}::ng-deep .p-toast-close-button .p-button-label{font-size:0}.custom-select{--p-select-hover-border-color: var(--hover-color);--p-select-focus-border-color: var(--hover-color)}.invalid-select{--p-select-border-color: var(--danger-color);--p-select-color: var(--danger-color);--p-select-hover-border-color: var(--hover-color);--p-select-focus-border-color: var(--hover-color)}.trash-button{--p-button-text-primary-color: var(--danger-color);--p-button-text-primary-hover-background: color-mix(in srgb, var(--danger-color) 10%, rgba(255, 255, 255, 0) 90%);--p-button-text-primary-active-background: color-mix(in srgb, var(--danger-color) 20%, rgba(255, 255, 255, 0) 80%)}.email-button{--p-button-text-primary-color: var(--secondary-color);--p-button-text-primary-hover-background: color-mix(in srgb, var(--secondary-color) 10%, rgba(255, 255, 255, 0) 90%);--p-button-text-primary-active-background: color-mix(in srgb, var(--secondary-color) 20%, rgba(255, 255, 255, 0) 80%)}::ng-deep .p-tooltip{--p-tooltip-background: var(--primary-color);--p-tooltip-max-width: 20rem}::ng-deep .p-tooltip-text{white-space:nowrap!important;word-break:keep-all!important;overflow:hidden!important;text-overflow:ellipsis!important}::ng-deep .p-confirmdialog{color:var(--primary-color)!important}::ng-deep .p-confirmdialog .p-confirmdialog-icon{color:var(--primary-color)!important}::ng-deep .p-confirmdialog .p-button{--p-button-primary-background: var(--danger-color);--p-button-primary-border-color: var(--danger-color);--p-button-primary-hover-background: color-mix(in srgb, var(--danger-color) 90%, black 10%);--p-button-primary-hover-border-color: color-mix(in srgb, var(--danger-color) 90%, black 10%);--p-button-primary-active-background: color-mix(in srgb, var(--danger-color) 70%, black 30%);--p-button-primary-active-border-color: color-mix(in srgb, var(--danger-color) 80%, black 20%)}.custom-acordion{--p-accordion-header-color: color-mix(in srgb, var(--primary-color) 60%, rgba(255, 255, 255, 0) 40%);--p-accordion-header-hover-color: var(--hover-color);--p-accordion-header-active-color: var(--primary-color);--p-accordion-content-color: var(--primary-color)}.custom-accordionpanel{border-style:none!important}.custom-accordionheader{padding:0!important;padding-right:.75rem!important}\n"] }]
1329
+ }], ctorParameters: () => [{ type: OrganizationService }, { type: i2$1.MessageService }, { type: UserService }, { type: i2$1.ConfirmationService }] });
1330
+
483
1331
  /*
484
1332
  * Public API Surface of ngx-bok-utils
485
1333
  */
@@ -488,5 +1336,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
488
1336
  * Generated bundle index. Do not edit.
489
1337
  */
490
1338
 
491
- export { FooterComponent, HeaderComponent, NotFoundPageComponent, UserPageComponent };
1339
+ export { FooterComponent, HeaderComponent, NotFoundPageComponent, OrganizationPageComponent, UserPageComponent };
492
1340
  //# sourceMappingURL=eo4geo-ngx-bok-utils.mjs.map