@eo4geo/ngx-bok-utils 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/eo4geo-ngx-bok-utils.mjs +847 -19
- package/fesm2022/eo4geo-ngx-bok-utils.mjs.map +1 -1
- package/lib/components/header/header.component.d.ts +6 -1
- package/lib/components/organizationAdmin/organizationAdmin.component.d.ts +53 -0
- package/lib/components/organizationForm/organizationForm.component.d.ts +29 -0
- package/lib/components/organizationPage/organizationPage.component.d.ts +56 -0
- package/lib/services/organization.service.d.ts +55 -0
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
|
@@ -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
|
|
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
|
-
import * as
|
|
9
|
+
import * as i4$1 from 'primeng/tieredmenu';
|
|
10
10
|
import { TieredMenuModule } from 'primeng/tieredmenu';
|
|
11
|
-
import * as
|
|
11
|
+
import * as i6$1 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, query, where, getDocs } from '@angular/fire/firestore';
|
|
29
|
-
import { BehaviorSubject, switchMap, of, Observable, from, take } from 'rxjs';
|
|
30
|
-
import * as
|
|
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
|
+
import * as i2$1 from '@angular/router';
|
|
31
31
|
import * as i9 from 'primeng/toast';
|
|
32
32
|
import { ToastModule } from 'primeng/toast';
|
|
33
|
-
import * as i2$
|
|
34
|
-
import { MessageService } from 'primeng/api';
|
|
33
|
+
import * as i2$2 from 'primeng/api';
|
|
34
|
+
import { MessageService, ConfirmationService } from 'primeng/api';
|
|
35
|
+
import * as i6$3 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$2 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();
|
|
@@ -302,7 +318,7 @@ class SessionModalComponent {
|
|
|
302
318
|
}
|
|
303
319
|
}
|
|
304
320
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SessionModalComponent, deps: [{ token: UserService }], target: i0.ɵɵFactoryTarget.Component });
|
|
305
|
-
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:
|
|
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"] }] });
|
|
306
322
|
}
|
|
307
323
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SessionModalComponent, decorators: [{
|
|
308
324
|
type: Component,
|
|
@@ -315,6 +331,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
|
|
|
315
331
|
|
|
316
332
|
class HeaderComponent {
|
|
317
333
|
userService;
|
|
334
|
+
router;
|
|
318
335
|
items = [
|
|
319
336
|
{
|
|
320
337
|
label: 'Tools',
|
|
@@ -403,6 +420,16 @@ class HeaderComponent {
|
|
|
403
420
|
}
|
|
404
421
|
}
|
|
405
422
|
];
|
|
423
|
+
unregisteredUserItems = [
|
|
424
|
+
{
|
|
425
|
+
label: 'Login',
|
|
426
|
+
icon: 'pi pi-sign-in',
|
|
427
|
+
command: () => {
|
|
428
|
+
this.showLoginModal = !this.showLoginModal;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
];
|
|
432
|
+
buttonItems = this.items.concat(this.unregisteredUserItems);
|
|
406
433
|
toolName = "BoK Visualization & Search";
|
|
407
434
|
login = false;
|
|
408
435
|
profileClick = new EventEmitter();
|
|
@@ -412,13 +439,18 @@ class HeaderComponent {
|
|
|
412
439
|
nameInitial = 'A';
|
|
413
440
|
showLoginModal = false;
|
|
414
441
|
userStateSubscription;
|
|
415
|
-
constructor(userService) {
|
|
442
|
+
constructor(userService, router) {
|
|
416
443
|
this.userService = userService;
|
|
444
|
+
this.router = router;
|
|
417
445
|
}
|
|
418
446
|
ngOnInit() {
|
|
419
447
|
this.userStateSubscription = this.userService.getUserState().subscribe(({ logged, nameInitial }) => {
|
|
420
448
|
this.logged = logged;
|
|
421
449
|
this.nameInitial = nameInitial;
|
|
450
|
+
if (this.logged)
|
|
451
|
+
this.buttonItems = this.items.concat(this.userItems);
|
|
452
|
+
else
|
|
453
|
+
this.buttonItems = this.items.concat(this.unregisteredUserItems);
|
|
422
454
|
});
|
|
423
455
|
}
|
|
424
456
|
ngOnDestroy() {
|
|
@@ -432,13 +464,16 @@ class HeaderComponent {
|
|
|
432
464
|
this.hideMenu = true;
|
|
433
465
|
}
|
|
434
466
|
}
|
|
435
|
-
|
|
436
|
-
|
|
467
|
+
navigateToMainPage() {
|
|
468
|
+
this.router.navigate([''], { replaceUrl: true });
|
|
469
|
+
}
|
|
470
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: HeaderComponent, deps: [{ token: UserService }, { token: i2$1.Router }], target: i0.ɵɵFactoryTarget.Component });
|
|
471
|
+
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\" style=\"cursor: pointer;\" (click)=\"navigateToMainPage()\">\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]=\"buttonItems\" 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: i4$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: i6$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"] }] });
|
|
437
472
|
}
|
|
438
473
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: HeaderComponent, decorators: [{
|
|
439
474
|
type: Component,
|
|
440
|
-
args: [{ standalone: true, selector: 'header', imports: [ButtonModule, TieredMenuModule, CommonModule, AvatarModule, AvatarGroupModule, SessionModalComponent], 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]=\"
|
|
441
|
-
}], ctorParameters: () => [{ type: UserService }], propDecorators: { items: [{
|
|
475
|
+
args: [{ standalone: true, selector: 'header', imports: [ButtonModule, TieredMenuModule, CommonModule, AvatarModule, AvatarGroupModule, SessionModalComponent], 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\" style=\"cursor: pointer;\" (click)=\"navigateToMainPage()\">\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]=\"buttonItems\" 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"] }]
|
|
476
|
+
}], ctorParameters: () => [{ type: UserService }, { type: i2$1.Router }], propDecorators: { items: [{
|
|
442
477
|
type: Input
|
|
443
478
|
}], toolName: [{
|
|
444
479
|
type: Input
|
|
@@ -461,13 +496,13 @@ class NotFoundPageComponent {
|
|
|
461
496
|
goToHomepage() {
|
|
462
497
|
this.router.navigate([''], { replaceUrl: true });
|
|
463
498
|
}
|
|
464
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: NotFoundPageComponent, deps: [{ token:
|
|
499
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: NotFoundPageComponent, deps: [{ token: i2$1.Router }], target: i0.ɵɵFactoryTarget.Component });
|
|
465
500
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: NotFoundPageComponent, isStandalone: true, selector: "not-found-page", ngImport: i0, template: "<div class=\"flex flex-column justify-content-center align-items-center m-8\">\r\n <img src=\"assets/images/hosting-404-error-1.png\" alt=\"not Found\" class=\"w-4 m-4\">\r\n <h1>page not found</h1>\r\n <p-button label=\"Go To Homepage\" size=\"large\" class=\"custom-button\" (onClick)=\"goToHomepage()\"></p-button>\r\n</div>", styles: [".custom-button{--p-button-primary-color: white;--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%)}\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"] }] });
|
|
466
501
|
}
|
|
467
502
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: NotFoundPageComponent, decorators: [{
|
|
468
503
|
type: Component,
|
|
469
504
|
args: [{ standalone: true, selector: 'not-found-page', imports: [ButtonModule], template: "<div class=\"flex flex-column justify-content-center align-items-center m-8\">\r\n <img src=\"assets/images/hosting-404-error-1.png\" alt=\"not Found\" class=\"w-4 m-4\">\r\n <h1>page not found</h1>\r\n <p-button label=\"Go To Homepage\" size=\"large\" class=\"custom-button\" (onClick)=\"goToHomepage()\"></p-button>\r\n</div>", styles: [".custom-button{--p-button-primary-color: white;--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%)}\n"] }]
|
|
470
|
-
}], ctorParameters: () => [{ type:
|
|
505
|
+
}], ctorParameters: () => [{ type: i2$1.Router }] });
|
|
471
506
|
|
|
472
507
|
class UserPageComponent {
|
|
473
508
|
userService;
|
|
@@ -511,13 +546,806 @@ class UserPageComponent {
|
|
|
511
546
|
});
|
|
512
547
|
}
|
|
513
548
|
}
|
|
514
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: UserPageComponent, deps: [{ token: UserService }, { token: i2$
|
|
549
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: UserPageComponent, deps: [{ token: UserService }, { token: i2$2.MessageService }], target: i0.ɵɵFactoryTarget.Component });
|
|
515
550
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: UserPageComponent, isStandalone: true, selector: "user-page", providers: [MessageService], ngImport: i0, 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"], 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: 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: "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"] }] });
|
|
516
551
|
}
|
|
517
552
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: UserPageComponent, decorators: [{
|
|
518
553
|
type: Component,
|
|
519
554
|
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"] }]
|
|
520
|
-
}], ctorParameters: () => [{ type: UserService }, { type: i2$
|
|
555
|
+
}], ctorParameters: () => [{ type: UserService }, { type: i2$2.MessageService }] });
|
|
556
|
+
|
|
557
|
+
class OrganizationFormComponent {
|
|
558
|
+
organization;
|
|
559
|
+
descriptionError = false;
|
|
560
|
+
buttonLabel = "Update Information";
|
|
561
|
+
validationFunction = (data) => {
|
|
562
|
+
for (let pair of data) {
|
|
563
|
+
if (pair[0] != pair[1])
|
|
564
|
+
return false;
|
|
565
|
+
}
|
|
566
|
+
return true;
|
|
567
|
+
};
|
|
568
|
+
formChange = new EventEmitter();
|
|
569
|
+
newName = "";
|
|
570
|
+
newDescription = "";
|
|
571
|
+
newContact = "";
|
|
572
|
+
emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
|
573
|
+
isValidEmail = (email) => this.emailRegex.test(email);
|
|
574
|
+
ngOnChanges(changes) {
|
|
575
|
+
if (changes['organization'] && this.organization) {
|
|
576
|
+
this.newName = changes['organization'].currentValue.name;
|
|
577
|
+
this.newDescription = changes['organization'].currentValue.description;
|
|
578
|
+
this.newContact = changes['organization'].currentValue.email;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
descriptionFormModified() {
|
|
582
|
+
const pairs = [[this.newName, this.organization.name], [this.newDescription, this.organization.description], [this.newContact, this.organization.email]];
|
|
583
|
+
return this.validationFunction(pairs) || !this.isValidEmail(this.newContact);
|
|
584
|
+
}
|
|
585
|
+
updateDescription() {
|
|
586
|
+
const updateInfo = {
|
|
587
|
+
name: this.newName != this.organization.name ? this.newName : null,
|
|
588
|
+
description: this.newDescription != this.organization.description ? this.newDescription : null,
|
|
589
|
+
contact: this.newContact != this.organization.email ? this.newContact : null
|
|
590
|
+
};
|
|
591
|
+
this.formChange.emit(updateInfo);
|
|
592
|
+
}
|
|
593
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OrganizationFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
594
|
+
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"] }] });
|
|
595
|
+
}
|
|
596
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OrganizationFormComponent, decorators: [{
|
|
597
|
+
type: Component,
|
|
598
|
+
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"] }]
|
|
599
|
+
}], propDecorators: { organization: [{
|
|
600
|
+
type: Input
|
|
601
|
+
}], descriptionError: [{
|
|
602
|
+
type: Input
|
|
603
|
+
}], buttonLabel: [{
|
|
604
|
+
type: Input
|
|
605
|
+
}], validationFunction: [{
|
|
606
|
+
type: Input
|
|
607
|
+
}], formChange: [{
|
|
608
|
+
type: Output
|
|
609
|
+
}] } });
|
|
610
|
+
|
|
611
|
+
class OrganizationService {
|
|
612
|
+
auth = inject(Auth);
|
|
613
|
+
db = inject(Firestore);
|
|
614
|
+
userCollection;
|
|
615
|
+
orgCollection;
|
|
616
|
+
adminOrganizationMessagesSource = new Subject();
|
|
617
|
+
adminOrganizationMessages$ = this.adminOrganizationMessagesSource.asObservable();
|
|
618
|
+
constructor() {
|
|
619
|
+
this.userCollection = collection(this.db, 'Users');
|
|
620
|
+
this.orgCollection = collection(this.db, 'Organizations');
|
|
621
|
+
}
|
|
622
|
+
emitMessage(message) {
|
|
623
|
+
this.adminOrganizationMessagesSource.next(message);
|
|
624
|
+
}
|
|
625
|
+
getOrganizations() {
|
|
626
|
+
return collectionData(this.orgCollection);
|
|
627
|
+
}
|
|
628
|
+
getUserOrganizations() {
|
|
629
|
+
return authState(this.auth).pipe(switchMap(user => {
|
|
630
|
+
if (user) {
|
|
631
|
+
const userDocRef = doc(this.userCollection, user.uid);
|
|
632
|
+
return docData(userDocRef);
|
|
633
|
+
}
|
|
634
|
+
return of(null);
|
|
635
|
+
}), switchMap(userData => {
|
|
636
|
+
if (userData?.organizations && userData.organizations.length > 0) {
|
|
637
|
+
const orgRequests = userData.organizations.map(orgId => this.getOrganizationInfo(orgId));
|
|
638
|
+
return forkJoin(orgRequests);
|
|
639
|
+
}
|
|
640
|
+
return of([]);
|
|
641
|
+
}));
|
|
642
|
+
}
|
|
643
|
+
getOrganizationInfo(orgId) {
|
|
644
|
+
const orgDocRef = doc(this.orgCollection, orgId);
|
|
645
|
+
return docData(orgDocRef).pipe(first(), map(document => ({
|
|
646
|
+
_id: document?.['_id'],
|
|
647
|
+
name: document?.['name'],
|
|
648
|
+
description: document?.['description'],
|
|
649
|
+
email: document?.['contact'],
|
|
650
|
+
isAdmin: Array.isArray(document?.['admin']) && document['admin'].includes(this.auth.currentUser?.uid)
|
|
651
|
+
})));
|
|
652
|
+
}
|
|
653
|
+
getOrganizationUsers(orgId) {
|
|
654
|
+
const orgDocRef = doc(this.orgCollection, orgId);
|
|
655
|
+
const organizationUsersSnapshot = docData(orgDocRef);
|
|
656
|
+
return organizationUsersSnapshot.pipe(switchMap(users => {
|
|
657
|
+
const adminUsers$ = users.admin.map(uid => this.getUserInfo(uid).pipe(take(1), map(user => ({ ...user, isAdmin: true }))));
|
|
658
|
+
const regularUsers$ = users.regular.map(uid => this.getUserInfo(uid).pipe(take(1), map(user => ({ ...user, isAdmin: false }))));
|
|
659
|
+
return forkJoin([...adminUsers$, ...regularUsers$]);
|
|
660
|
+
}));
|
|
661
|
+
}
|
|
662
|
+
getUserInfo(uid) {
|
|
663
|
+
const orgDocRef = doc(this.userCollection, uid);
|
|
664
|
+
return docData(orgDocRef);
|
|
665
|
+
}
|
|
666
|
+
getOrganizationDivisions(orgId) {
|
|
667
|
+
const orgDocRef = doc(this.orgCollection, orgId);
|
|
668
|
+
const organizationUsersSnapshot = docData(orgDocRef);
|
|
669
|
+
return organizationUsersSnapshot.pipe(map(data => data.divisions));
|
|
670
|
+
}
|
|
671
|
+
leaveOrganization(orgId) {
|
|
672
|
+
return this.updateOrganizationUsers(orgId, this.removeItem).pipe(concatMap(() => this.updateUserOrganizations(orgId, this.removeItem)));
|
|
673
|
+
}
|
|
674
|
+
joinOrganization(orgId) {
|
|
675
|
+
return this.updateOrganizationUsers(orgId, this.addItem, undefined, this.nothing).pipe(concatMap(() => this.updateUserOrganizations(orgId, this.addItem)));
|
|
676
|
+
}
|
|
677
|
+
deleteUserFromOrganization(orgId, userId) {
|
|
678
|
+
return this.updateOrganizationUsers(orgId, this.removeItem, userId).pipe(concatMap(() => this.updateUserOrganizations(orgId, this.removeItem, userId)));
|
|
679
|
+
}
|
|
680
|
+
addUserToOrganization(orgId, userId) {
|
|
681
|
+
return this.updateOrganizationUsers(orgId, this.addItem, userId, this.nothing).pipe(concatMap(() => this.updateUserOrganizations(orgId, this.addItem, userId)));
|
|
682
|
+
}
|
|
683
|
+
changeAdminState(orgId, userId, newState) {
|
|
684
|
+
return newState
|
|
685
|
+
? this.updateOrganizationUsers(orgId, this.removeItem, userId, this.addItem)
|
|
686
|
+
: this.updateOrganizationUsers(orgId, this.addItem, userId, this.removeItem);
|
|
687
|
+
}
|
|
688
|
+
updateUserOrganizations(orgId, updateFn, userId) {
|
|
689
|
+
const currentUserId = userId ?? this.auth.currentUser?.uid;
|
|
690
|
+
if (!currentUserId)
|
|
691
|
+
return of(void 0);
|
|
692
|
+
const userDocRef = doc(this.userCollection, currentUserId);
|
|
693
|
+
const userOrganizationsSnapshot = docData(userDocRef);
|
|
694
|
+
return new Observable((observer) => {
|
|
695
|
+
userOrganizationsSnapshot.pipe(take(1)).subscribe(async (userOrganizations) => {
|
|
696
|
+
if (!userOrganizations || !userOrganizations.organizations) {
|
|
697
|
+
observer.error(new Error('User organizations data is unavailable.'));
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
const updatedOrganizations = updateFn(userOrganizations.organizations, orgId);
|
|
701
|
+
await updateDoc(userDocRef, { organizations: updatedOrganizations });
|
|
702
|
+
observer.next();
|
|
703
|
+
observer.complete();
|
|
704
|
+
});
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
updateOrganizationUsers(orgId, updateFn, userId, updateAdminFn) {
|
|
708
|
+
const orgDocRef = doc(this.orgCollection, orgId);
|
|
709
|
+
const organizationUsersSnapshot = docData(orgDocRef);
|
|
710
|
+
return new Observable((observer) => {
|
|
711
|
+
organizationUsersSnapshot.pipe(take(1)).subscribe(async (organizationUsers) => {
|
|
712
|
+
if (!organizationUsers) {
|
|
713
|
+
observer.error(new Error('Organization users data is unavailable.'));
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
const currentUserId = userId ?? this.auth.currentUser?.uid;
|
|
717
|
+
if (!currentUserId) {
|
|
718
|
+
observer.error(new Error('Current user is not authenticated.'));
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
if (organizationUsers.admin.length == 1 && organizationUsers.admin.includes(currentUserId)) {
|
|
722
|
+
observer.error(new Error('Cannot perform action: Current user is the only administrator.'));
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
725
|
+
await updateDoc(orgDocRef, {
|
|
726
|
+
admin: updateAdminFn ? updateAdminFn(organizationUsers.admin, currentUserId) : updateFn(organizationUsers.admin, currentUserId),
|
|
727
|
+
regular: updateFn(organizationUsers.regular, currentUserId)
|
|
728
|
+
});
|
|
729
|
+
observer.next();
|
|
730
|
+
observer.complete();
|
|
731
|
+
});
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
addDivisions(orgId, newDivision) {
|
|
735
|
+
return this.updateOrganizationDivisions(orgId, newDivision, this.addItem);
|
|
736
|
+
}
|
|
737
|
+
deleteDivision(orgId, newDivision) {
|
|
738
|
+
return this.updateOrganizationDivisions(orgId, newDivision, this.removeItem);
|
|
739
|
+
}
|
|
740
|
+
updateOrganizationDivisions(orgId, newDivision, updateFn) {
|
|
741
|
+
const orgDocRef = doc(this.orgCollection, orgId);
|
|
742
|
+
const organizationDivisions = this.getOrganizationDivisions(orgId);
|
|
743
|
+
return new Observable((observer) => {
|
|
744
|
+
organizationDivisions.pipe(take(1)).subscribe(async (divisions) => {
|
|
745
|
+
if (!divisions) {
|
|
746
|
+
observer.error(new Error('Organization divisions data is unavailable.'));
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
await updateDoc(orgDocRef, {
|
|
750
|
+
divisions: updateFn(divisions, newDivision)
|
|
751
|
+
});
|
|
752
|
+
observer.next();
|
|
753
|
+
observer.complete();
|
|
754
|
+
});
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
addItem(arr, item) {
|
|
758
|
+
return [...arr, item];
|
|
759
|
+
}
|
|
760
|
+
removeItem(arr, item) {
|
|
761
|
+
return arr.filter(i => i !== item);
|
|
762
|
+
}
|
|
763
|
+
nothing(arr, item) {
|
|
764
|
+
return arr;
|
|
765
|
+
}
|
|
766
|
+
updateOrganizationInformation(orgId, info) {
|
|
767
|
+
const orgDocRef = doc(this.orgCollection, orgId);
|
|
768
|
+
return new Observable((observer) => {
|
|
769
|
+
const updateData = {};
|
|
770
|
+
Object.entries(info).forEach(([key, value]) => {
|
|
771
|
+
if (value !== null) {
|
|
772
|
+
updateData[key] = value;
|
|
773
|
+
}
|
|
774
|
+
});
|
|
775
|
+
if (Object.keys(updateData).length > 0) {
|
|
776
|
+
updateDoc(orgDocRef, updateData)
|
|
777
|
+
.then(() => {
|
|
778
|
+
observer.next();
|
|
779
|
+
observer.complete();
|
|
780
|
+
})
|
|
781
|
+
.catch((error) => observer.error(error));
|
|
782
|
+
}
|
|
783
|
+
else {
|
|
784
|
+
observer.complete();
|
|
785
|
+
}
|
|
786
|
+
});
|
|
787
|
+
}
|
|
788
|
+
createOrganization(name, description, contact) {
|
|
789
|
+
const currentUserId = this.auth.currentUser?.uid;
|
|
790
|
+
if (!currentUserId) {
|
|
791
|
+
throw new Error('Current user is not authenticated.');
|
|
792
|
+
}
|
|
793
|
+
const orgRef = doc(this.orgCollection);
|
|
794
|
+
const org = {
|
|
795
|
+
_id: orgRef.id,
|
|
796
|
+
name,
|
|
797
|
+
description,
|
|
798
|
+
admin: [currentUserId],
|
|
799
|
+
regular: [],
|
|
800
|
+
pending: [],
|
|
801
|
+
adminUser: [],
|
|
802
|
+
regularUser: [],
|
|
803
|
+
pendingUser: [],
|
|
804
|
+
isPublic: false,
|
|
805
|
+
contact,
|
|
806
|
+
divisions: [],
|
|
807
|
+
};
|
|
808
|
+
return from(setDoc(orgRef, org)).pipe(concatMap(() => this.updateUserOrganizations(org._id, this.addItem, currentUserId)), take(1));
|
|
809
|
+
}
|
|
810
|
+
deleteOrganization(orgId, users) {
|
|
811
|
+
const userObservables = users.map(uid => this.updateUserOrganizations(orgId, this.removeItem, uid));
|
|
812
|
+
return forkJoin(userObservables).pipe(concatMap(() => {
|
|
813
|
+
const orgRef = doc(this.orgCollection, orgId);
|
|
814
|
+
return from(deleteDoc(orgRef)).pipe(catchError((error) => {
|
|
815
|
+
throw new Error('Error al eliminar la organización');
|
|
816
|
+
}), take(1));
|
|
817
|
+
}));
|
|
818
|
+
}
|
|
819
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OrganizationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
820
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OrganizationService, providedIn: 'root' });
|
|
821
|
+
}
|
|
822
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OrganizationService, decorators: [{
|
|
823
|
+
type: Injectable,
|
|
824
|
+
args: [{
|
|
825
|
+
providedIn: 'root',
|
|
826
|
+
}]
|
|
827
|
+
}], ctorParameters: () => [] });
|
|
828
|
+
|
|
829
|
+
class OrganizationAdminComponent {
|
|
830
|
+
orgService;
|
|
831
|
+
userService;
|
|
832
|
+
confirmationService;
|
|
833
|
+
organization;
|
|
834
|
+
users = [];
|
|
835
|
+
skelletonData = Array.from({ length: 5 }).map(() => { });
|
|
836
|
+
divisions = [];
|
|
837
|
+
newDivision = "";
|
|
838
|
+
divisionError = false;
|
|
839
|
+
descriptionError = false;
|
|
840
|
+
newUser = "";
|
|
841
|
+
userError = false;
|
|
842
|
+
usersSubscription;
|
|
843
|
+
divisionsSubscription;
|
|
844
|
+
inplaceIndicator = false;
|
|
845
|
+
constructor(orgService, userService, confirmationService) {
|
|
846
|
+
this.orgService = orgService;
|
|
847
|
+
this.userService = userService;
|
|
848
|
+
this.confirmationService = confirmationService;
|
|
849
|
+
}
|
|
850
|
+
ngOnInit() {
|
|
851
|
+
this.usersSubscription = this.orgService.getOrganizationUsers(this.organization._id).subscribe(newUsers => this.users = newUsers.sort((a, b) => b.email.localeCompare(a.email)));
|
|
852
|
+
this.divisionsSubscription = this.orgService.getOrganizationDivisions(this.organization._id).subscribe(newDivisions => this.divisions = newDivisions);
|
|
853
|
+
}
|
|
854
|
+
ngOnDestroy() {
|
|
855
|
+
this.unsubscribe();
|
|
856
|
+
}
|
|
857
|
+
unsubscribe() {
|
|
858
|
+
if (this.usersSubscription) {
|
|
859
|
+
this.usersSubscription.unsubscribe();
|
|
860
|
+
}
|
|
861
|
+
if (this.divisionsSubscription) {
|
|
862
|
+
this.divisionsSubscription.unsubscribe();
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
isCurrentUser(userId) {
|
|
866
|
+
return this.userService.isCurrentUser(userId);
|
|
867
|
+
}
|
|
868
|
+
deleteUser(userId, userName) {
|
|
869
|
+
let isSuccess = true;
|
|
870
|
+
this.orgService.deleteUserFromOrganization(this.organization._id, userId).pipe(catchError(error => {
|
|
871
|
+
isSuccess = false;
|
|
872
|
+
this.orgService.emitMessage({
|
|
873
|
+
severity: 'error',
|
|
874
|
+
summary: 'Error',
|
|
875
|
+
detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
|
|
876
|
+
life: 3000,
|
|
877
|
+
closable: true
|
|
878
|
+
});
|
|
879
|
+
return of(null);
|
|
880
|
+
}), finalize(() => {
|
|
881
|
+
if (isSuccess) {
|
|
882
|
+
this.orgService.emitMessage({
|
|
883
|
+
severity: 'info',
|
|
884
|
+
summary: 'Info',
|
|
885
|
+
detail: `You deleted ${userName ?? userId} from the organization without problems.`,
|
|
886
|
+
life: 3000,
|
|
887
|
+
closable: true
|
|
888
|
+
});
|
|
889
|
+
}
|
|
890
|
+
})).subscribe();
|
|
891
|
+
}
|
|
892
|
+
switchAdminState(userId, userName, newState) {
|
|
893
|
+
let isSuccess = true;
|
|
894
|
+
this.orgService.changeAdminState(this.organization._id, userId, newState).pipe(catchError(error => {
|
|
895
|
+
isSuccess = false;
|
|
896
|
+
const user = this.users.find(u => u._id === userId);
|
|
897
|
+
if (user)
|
|
898
|
+
user.isAdmin = true;
|
|
899
|
+
this.orgService.emitMessage({
|
|
900
|
+
severity: 'error',
|
|
901
|
+
summary: 'Error',
|
|
902
|
+
detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
|
|
903
|
+
life: 3000,
|
|
904
|
+
closable: true
|
|
905
|
+
});
|
|
906
|
+
return of(null);
|
|
907
|
+
}), finalize(() => {
|
|
908
|
+
if (isSuccess) {
|
|
909
|
+
const user = this.users.find(u => u._id === userId);
|
|
910
|
+
if (user)
|
|
911
|
+
user.isAdmin = newState;
|
|
912
|
+
if (this.isCurrentUser(userId))
|
|
913
|
+
this.organization.isAdmin = newState;
|
|
914
|
+
this.orgService.emitMessage({
|
|
915
|
+
severity: 'info',
|
|
916
|
+
summary: 'Info',
|
|
917
|
+
detail: newState ? `${userName ?? userId} is now an administrator of the organization.` : `${userName ?? userId} is no longer an administrator of the organization.`,
|
|
918
|
+
life: 3000,
|
|
919
|
+
closable: true
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
})).subscribe();
|
|
923
|
+
}
|
|
924
|
+
deleteDivision(division) {
|
|
925
|
+
let isSuccess = true;
|
|
926
|
+
this.orgService.deleteDivision(this.organization._id, division).pipe(catchError(error => {
|
|
927
|
+
isSuccess = false;
|
|
928
|
+
this.orgService.emitMessage({
|
|
929
|
+
severity: 'error',
|
|
930
|
+
summary: 'Error',
|
|
931
|
+
detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
|
|
932
|
+
life: 3000,
|
|
933
|
+
closable: true
|
|
934
|
+
});
|
|
935
|
+
return of(null);
|
|
936
|
+
}), finalize(() => {
|
|
937
|
+
if (isSuccess) {
|
|
938
|
+
this.orgService.emitMessage({
|
|
939
|
+
severity: 'info',
|
|
940
|
+
summary: 'Info',
|
|
941
|
+
detail: `You deleted ${division} from the organization without problems.`,
|
|
942
|
+
life: 3000,
|
|
943
|
+
closable: true
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
})).subscribe();
|
|
947
|
+
}
|
|
948
|
+
addDivision() {
|
|
949
|
+
if (this.divisions.includes(this.newDivision)) {
|
|
950
|
+
this.divisionError = true;
|
|
951
|
+
this.orgService.emitMessage({
|
|
952
|
+
severity: 'warn',
|
|
953
|
+
summary: 'Warn',
|
|
954
|
+
detail: 'You cannot add an existing division.',
|
|
955
|
+
life: 3000,
|
|
956
|
+
closable: true,
|
|
957
|
+
});
|
|
958
|
+
return;
|
|
959
|
+
}
|
|
960
|
+
let isSuccess = true;
|
|
961
|
+
this.orgService.addDivisions(this.organization._id, this.newDivision).pipe(catchError(error => {
|
|
962
|
+
isSuccess = false;
|
|
963
|
+
this.divisionError = true;
|
|
964
|
+
this.orgService.emitMessage({
|
|
965
|
+
severity: 'error',
|
|
966
|
+
summary: 'Error',
|
|
967
|
+
detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
|
|
968
|
+
life: 3000,
|
|
969
|
+
closable: true
|
|
970
|
+
});
|
|
971
|
+
return of(null);
|
|
972
|
+
}), finalize(() => {
|
|
973
|
+
if (isSuccess) {
|
|
974
|
+
this.divisionError = false;
|
|
975
|
+
this.orgService.emitMessage({
|
|
976
|
+
severity: 'info',
|
|
977
|
+
summary: 'Info',
|
|
978
|
+
detail: `You added ${this.newDivision} to the organization without problems.`,
|
|
979
|
+
life: 3000,
|
|
980
|
+
closable: true
|
|
981
|
+
});
|
|
982
|
+
this.newDivision = "";
|
|
983
|
+
}
|
|
984
|
+
})).subscribe();
|
|
985
|
+
}
|
|
986
|
+
updateDescription(updateInfo) {
|
|
987
|
+
let isSuccess = true;
|
|
988
|
+
this.orgService.updateOrganizationInformation(this.organization._id, updateInfo).pipe(catchError(error => {
|
|
989
|
+
isSuccess = false;
|
|
990
|
+
this.descriptionError = true;
|
|
991
|
+
this.orgService.emitMessage({
|
|
992
|
+
severity: 'error',
|
|
993
|
+
summary: 'Error',
|
|
994
|
+
detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
|
|
995
|
+
life: 3000,
|
|
996
|
+
closable: true
|
|
997
|
+
});
|
|
998
|
+
return of(null);
|
|
999
|
+
}), finalize(() => {
|
|
1000
|
+
if (isSuccess) {
|
|
1001
|
+
this.descriptionError = false;
|
|
1002
|
+
this.organization.name = updateInfo.name ?? this.organization.name;
|
|
1003
|
+
this.organization.description = updateInfo.description ?? this.organization.description;
|
|
1004
|
+
this.organization.email = updateInfo.contact ?? this.organization.email;
|
|
1005
|
+
this.orgService.emitMessage({
|
|
1006
|
+
severity: 'info',
|
|
1007
|
+
summary: 'Info',
|
|
1008
|
+
detail: `You modified the organization description without problems.`,
|
|
1009
|
+
life: 3000,
|
|
1010
|
+
closable: true
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
1013
|
+
})).subscribe();
|
|
1014
|
+
}
|
|
1015
|
+
addUserToOrganization() {
|
|
1016
|
+
let isSuccess = true;
|
|
1017
|
+
this.userService.getUidWithEmail(this.newUser).pipe(switchMap(data => {
|
|
1018
|
+
if (this.users.some(user => user._id === data.uid)) {
|
|
1019
|
+
isSuccess = false;
|
|
1020
|
+
this.userError = true;
|
|
1021
|
+
this.orgService.emitMessage({
|
|
1022
|
+
severity: 'warn',
|
|
1023
|
+
summary: 'Warn',
|
|
1024
|
+
detail: `${this.newUser} already belong to this organization.`,
|
|
1025
|
+
life: 3000,
|
|
1026
|
+
closable: true
|
|
1027
|
+
});
|
|
1028
|
+
return of(null);
|
|
1029
|
+
}
|
|
1030
|
+
return this.orgService.addUserToOrganization(this.organization._id, data.uid);
|
|
1031
|
+
}), catchError(error => {
|
|
1032
|
+
isSuccess = false;
|
|
1033
|
+
this.userError = true;
|
|
1034
|
+
this.orgService.emitMessage({
|
|
1035
|
+
severity: 'error',
|
|
1036
|
+
summary: 'Error',
|
|
1037
|
+
detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
|
|
1038
|
+
life: 3000,
|
|
1039
|
+
closable: true
|
|
1040
|
+
});
|
|
1041
|
+
return of(null);
|
|
1042
|
+
}), finalize(() => {
|
|
1043
|
+
if (isSuccess) {
|
|
1044
|
+
this.userError = false;
|
|
1045
|
+
this.orgService.emitMessage({
|
|
1046
|
+
severity: 'info',
|
|
1047
|
+
summary: 'Info',
|
|
1048
|
+
detail: `You added ${this.newUser} to the organization without problems.`,
|
|
1049
|
+
life: 3000,
|
|
1050
|
+
closable: true
|
|
1051
|
+
});
|
|
1052
|
+
this.newUser = "";
|
|
1053
|
+
}
|
|
1054
|
+
})).subscribe();
|
|
1055
|
+
}
|
|
1056
|
+
deleteUserModal(event, userId, userName) {
|
|
1057
|
+
this.confirmationService.confirm({
|
|
1058
|
+
target: event.target,
|
|
1059
|
+
message: `Do you want to delete ${userName} from this organization?`,
|
|
1060
|
+
header: 'Delete User',
|
|
1061
|
+
icon: 'pi pi-info-circle',
|
|
1062
|
+
rejectLabel: 'Cancel',
|
|
1063
|
+
rejectButtonProps: {
|
|
1064
|
+
label: 'Cancel',
|
|
1065
|
+
severity: 'secondary',
|
|
1066
|
+
},
|
|
1067
|
+
acceptButtonProps: {
|
|
1068
|
+
label: 'Delete',
|
|
1069
|
+
severity: 'primary',
|
|
1070
|
+
},
|
|
1071
|
+
accept: () => {
|
|
1072
|
+
this.deleteUser(userId, userName);
|
|
1073
|
+
},
|
|
1074
|
+
reject: () => {
|
|
1075
|
+
},
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1078
|
+
deleteDivisionModal(event, division) {
|
|
1079
|
+
this.confirmationService.confirm({
|
|
1080
|
+
target: event.target,
|
|
1081
|
+
message: `Do you want to delete ${division} from this organization?`,
|
|
1082
|
+
header: 'Delete Division',
|
|
1083
|
+
icon: 'pi pi-info-circle',
|
|
1084
|
+
rejectLabel: 'Cancel',
|
|
1085
|
+
rejectButtonProps: {
|
|
1086
|
+
label: 'Cancel',
|
|
1087
|
+
severity: 'secondary',
|
|
1088
|
+
},
|
|
1089
|
+
acceptButtonProps: {
|
|
1090
|
+
label: 'Delete',
|
|
1091
|
+
severity: 'primary',
|
|
1092
|
+
},
|
|
1093
|
+
accept: () => {
|
|
1094
|
+
this.deleteDivision(division);
|
|
1095
|
+
},
|
|
1096
|
+
reject: () => {
|
|
1097
|
+
},
|
|
1098
|
+
});
|
|
1099
|
+
}
|
|
1100
|
+
deleteOrganizationModal(event) {
|
|
1101
|
+
this.confirmationService.confirm({
|
|
1102
|
+
target: event.target,
|
|
1103
|
+
message: `Do you want to delete this organization?`,
|
|
1104
|
+
header: 'Delete Organization',
|
|
1105
|
+
icon: 'pi pi-info-circle',
|
|
1106
|
+
rejectLabel: 'Cancel',
|
|
1107
|
+
rejectButtonProps: {
|
|
1108
|
+
label: 'Cancel',
|
|
1109
|
+
severity: 'secondary',
|
|
1110
|
+
},
|
|
1111
|
+
acceptButtonProps: {
|
|
1112
|
+
label: 'Delete',
|
|
1113
|
+
severity: 'primary',
|
|
1114
|
+
},
|
|
1115
|
+
accept: () => {
|
|
1116
|
+
this.deleteOrganization();
|
|
1117
|
+
},
|
|
1118
|
+
reject: () => {
|
|
1119
|
+
},
|
|
1120
|
+
});
|
|
1121
|
+
}
|
|
1122
|
+
deleteOrganization() {
|
|
1123
|
+
let isSuccess = true;
|
|
1124
|
+
this.orgService.deleteOrganization(this.organization._id, this.users.map(user => user._id)).pipe(catchError(error => {
|
|
1125
|
+
isSuccess = false;
|
|
1126
|
+
this.orgService.emitMessage({
|
|
1127
|
+
severity: 'error',
|
|
1128
|
+
summary: 'Error',
|
|
1129
|
+
detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
|
|
1130
|
+
life: 3000,
|
|
1131
|
+
closable: true
|
|
1132
|
+
});
|
|
1133
|
+
return of(null);
|
|
1134
|
+
}), finalize(() => {
|
|
1135
|
+
if (isSuccess) {
|
|
1136
|
+
this.orgService.emitMessage({
|
|
1137
|
+
severity: 'info',
|
|
1138
|
+
summary: 'Info',
|
|
1139
|
+
detail: `You deleted ${this.organization.name} without problems.`,
|
|
1140
|
+
life: 3000,
|
|
1141
|
+
closable: true
|
|
1142
|
+
});
|
|
1143
|
+
}
|
|
1144
|
+
})).subscribe();
|
|
1145
|
+
}
|
|
1146
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OrganizationAdminComponent, deps: [{ token: OrganizationService }, { token: UserService }, { token: i2$2.ConfirmationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1147
|
+
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$2.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"] }] });
|
|
1148
|
+
}
|
|
1149
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OrganizationAdminComponent, decorators: [{
|
|
1150
|
+
type: Component,
|
|
1151
|
+
args: [{ standalone: true, selector: 'organization-admin', imports: [ButtonModule, CommonModule, TableModule, ToggleSwitchModule, FormsModule, AccordionModule, InputIconModule,
|
|
1152
|
+
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"] }]
|
|
1153
|
+
}], ctorParameters: () => [{ type: OrganizationService }, { type: UserService }, { type: i2$2.ConfirmationService }], propDecorators: { organization: [{
|
|
1154
|
+
type: Input
|
|
1155
|
+
}] } });
|
|
1156
|
+
|
|
1157
|
+
class OrganizationPageComponent {
|
|
1158
|
+
orgService;
|
|
1159
|
+
messageService;
|
|
1160
|
+
userService;
|
|
1161
|
+
confirmationService;
|
|
1162
|
+
userOrganizations = [];
|
|
1163
|
+
orgSubscription;
|
|
1164
|
+
userStateSubscription;
|
|
1165
|
+
adminMessageSubscription;
|
|
1166
|
+
organizations = [];
|
|
1167
|
+
selectedOrganization;
|
|
1168
|
+
logged = false;
|
|
1169
|
+
duplicatedOrg = false;
|
|
1170
|
+
newOrganization = { _id: "", name: "", description: "", email: "", isAdmin: true };
|
|
1171
|
+
newOrganizationError = false;
|
|
1172
|
+
newOrganizationAcordion = [];
|
|
1173
|
+
constructor(orgService, messageService, userService, confirmationService) {
|
|
1174
|
+
this.orgService = orgService;
|
|
1175
|
+
this.messageService = messageService;
|
|
1176
|
+
this.userService = userService;
|
|
1177
|
+
this.confirmationService = confirmationService;
|
|
1178
|
+
}
|
|
1179
|
+
ngOnInit() {
|
|
1180
|
+
this.userStateSubscription = this.userService.getUserState().subscribe(({ logged }) => {
|
|
1181
|
+
this.logged = logged;
|
|
1182
|
+
});
|
|
1183
|
+
this.orgSubscription = this.orgService.getUserOrganizations().subscribe(orgs => {
|
|
1184
|
+
this.userOrganizations = orgs;
|
|
1185
|
+
});
|
|
1186
|
+
this.orgService.getOrganizations().pipe(take(1)).subscribe(orgs => {
|
|
1187
|
+
this.organizations = orgs.map(org => ({
|
|
1188
|
+
_id: org._id,
|
|
1189
|
+
name: org.name.trim().charAt(0).toUpperCase() + org.name.trim().slice(1)
|
|
1190
|
+
}));
|
|
1191
|
+
this.organizations.sort((a, b) => a.name.localeCompare(b.name));
|
|
1192
|
+
});
|
|
1193
|
+
this.adminMessageSubscription = this.orgService.adminOrganizationMessages$.subscribe(message => this.messageService.add(message));
|
|
1194
|
+
}
|
|
1195
|
+
ngOnDestroy() {
|
|
1196
|
+
this.orgSubscription?.unsubscribe();
|
|
1197
|
+
this.userStateSubscription?.unsubscribe();
|
|
1198
|
+
this.adminMessageSubscription?.unsubscribe();
|
|
1199
|
+
}
|
|
1200
|
+
leaveOrganization(orgId, orgName) {
|
|
1201
|
+
let isSuccess = true;
|
|
1202
|
+
this.orgService.leaveOrganization(orgId).pipe(catchError((error) => {
|
|
1203
|
+
isSuccess = false;
|
|
1204
|
+
this.messageService.add({
|
|
1205
|
+
severity: 'error',
|
|
1206
|
+
summary: 'Error',
|
|
1207
|
+
detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
|
|
1208
|
+
life: 3000,
|
|
1209
|
+
closable: true
|
|
1210
|
+
});
|
|
1211
|
+
return of(null);
|
|
1212
|
+
}), finalize(() => {
|
|
1213
|
+
if (isSuccess) {
|
|
1214
|
+
this.messageService.add({
|
|
1215
|
+
severity: 'info',
|
|
1216
|
+
summary: 'Info',
|
|
1217
|
+
detail: `You left ${orgName} without problems.`,
|
|
1218
|
+
life: 3000,
|
|
1219
|
+
closable: true
|
|
1220
|
+
});
|
|
1221
|
+
}
|
|
1222
|
+
})).subscribe();
|
|
1223
|
+
}
|
|
1224
|
+
joinOrganization() {
|
|
1225
|
+
if (!this.selectedOrganization) {
|
|
1226
|
+
return;
|
|
1227
|
+
}
|
|
1228
|
+
if (this.userOrganizations.some(userOrg => userOrg._id === this.selectedOrganization?._id)) {
|
|
1229
|
+
this.messageService.add({
|
|
1230
|
+
severity: 'warn',
|
|
1231
|
+
summary: 'Warn',
|
|
1232
|
+
detail: 'You cannot join an organization to which you already belong.',
|
|
1233
|
+
life: 3000,
|
|
1234
|
+
closable: true,
|
|
1235
|
+
});
|
|
1236
|
+
this.duplicatedOrg = true;
|
|
1237
|
+
return;
|
|
1238
|
+
}
|
|
1239
|
+
const orgId = this.selectedOrganization._id;
|
|
1240
|
+
const orgName = this.selectedOrganization.name;
|
|
1241
|
+
let isSuccess = true;
|
|
1242
|
+
this.orgService.joinOrganization(orgId).pipe(catchError((error) => {
|
|
1243
|
+
isSuccess = false;
|
|
1244
|
+
this.messageService.add({
|
|
1245
|
+
severity: 'error',
|
|
1246
|
+
summary: 'Error',
|
|
1247
|
+
detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
|
|
1248
|
+
life: 3000,
|
|
1249
|
+
closable: true
|
|
1250
|
+
});
|
|
1251
|
+
return of(null);
|
|
1252
|
+
}), finalize(() => {
|
|
1253
|
+
if (isSuccess) {
|
|
1254
|
+
this.messageService.add({
|
|
1255
|
+
severity: 'info',
|
|
1256
|
+
summary: 'Info',
|
|
1257
|
+
detail: `You joined ${orgName} without problems.`,
|
|
1258
|
+
life: 3000,
|
|
1259
|
+
closable: true
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1262
|
+
})).subscribe();
|
|
1263
|
+
}
|
|
1264
|
+
updateDuplicatedOrg() {
|
|
1265
|
+
if (this.duplicatedOrg)
|
|
1266
|
+
this.duplicatedOrg = false;
|
|
1267
|
+
}
|
|
1268
|
+
copyEmail(email, name) {
|
|
1269
|
+
navigator.clipboard.writeText(email);
|
|
1270
|
+
this.messageService.add({
|
|
1271
|
+
severity: 'info',
|
|
1272
|
+
summary: 'Info',
|
|
1273
|
+
detail: `You copied ${name} contact email without problems.`,
|
|
1274
|
+
life: 3000,
|
|
1275
|
+
closable: true
|
|
1276
|
+
});
|
|
1277
|
+
}
|
|
1278
|
+
deleteModal(event, orgId, orgName) {
|
|
1279
|
+
this.confirmationService.confirm({
|
|
1280
|
+
target: event.target,
|
|
1281
|
+
message: 'Do you want to leave this organization?',
|
|
1282
|
+
header: 'Leave Organization',
|
|
1283
|
+
icon: 'pi pi-info-circle',
|
|
1284
|
+
rejectLabel: 'Cancel',
|
|
1285
|
+
rejectButtonProps: {
|
|
1286
|
+
label: 'Cancel',
|
|
1287
|
+
severity: 'secondary',
|
|
1288
|
+
},
|
|
1289
|
+
acceptButtonProps: {
|
|
1290
|
+
label: 'Delete',
|
|
1291
|
+
severity: 'primary',
|
|
1292
|
+
},
|
|
1293
|
+
accept: () => {
|
|
1294
|
+
this.leaveOrganization(orgId, orgName);
|
|
1295
|
+
},
|
|
1296
|
+
reject: () => {
|
|
1297
|
+
},
|
|
1298
|
+
});
|
|
1299
|
+
}
|
|
1300
|
+
createOrganization(createData) {
|
|
1301
|
+
if (!createData.name?.trim() || !createData.description?.trim() || !createData.contact?.trim()) {
|
|
1302
|
+
this.messageService.add({
|
|
1303
|
+
severity: 'warn',
|
|
1304
|
+
summary: 'Warn',
|
|
1305
|
+
detail: 'You cannot create an organization until you fill in all the fields.',
|
|
1306
|
+
life: 3000,
|
|
1307
|
+
closable: true,
|
|
1308
|
+
});
|
|
1309
|
+
this.newOrganizationError = true;
|
|
1310
|
+
return;
|
|
1311
|
+
}
|
|
1312
|
+
let isSuccess = true;
|
|
1313
|
+
this.orgService.createOrganization(createData.name, createData.description, createData.contact).pipe(catchError((error) => {
|
|
1314
|
+
isSuccess = false;
|
|
1315
|
+
this.messageService.add({
|
|
1316
|
+
severity: 'error',
|
|
1317
|
+
summary: 'Error',
|
|
1318
|
+
detail: error.message ?? 'Something went wrong. Try again later or contact the administrator.',
|
|
1319
|
+
life: 3000,
|
|
1320
|
+
closable: true
|
|
1321
|
+
});
|
|
1322
|
+
this.newOrganizationError = true;
|
|
1323
|
+
return of(null);
|
|
1324
|
+
}), finalize(() => {
|
|
1325
|
+
if (isSuccess) {
|
|
1326
|
+
this.messageService.add({
|
|
1327
|
+
severity: 'info',
|
|
1328
|
+
summary: 'Info',
|
|
1329
|
+
detail: `You created ${createData.name} without problems.`,
|
|
1330
|
+
life: 3000,
|
|
1331
|
+
closable: true
|
|
1332
|
+
});
|
|
1333
|
+
this.newOrganizationError = false;
|
|
1334
|
+
this.newOrganization = { _id: "", name: "", description: "", email: "", isAdmin: true };
|
|
1335
|
+
this.newOrganizationAcordion = [];
|
|
1336
|
+
}
|
|
1337
|
+
})).subscribe();
|
|
1338
|
+
}
|
|
1339
|
+
newOrganizationValidation(data) {
|
|
1340
|
+
return data.some(([first, second]) => first === second || first === "");
|
|
1341
|
+
}
|
|
1342
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OrganizationPageComponent, deps: [{ token: OrganizationService }, { token: i2$2.MessageService }, { token: UserService }, { token: i2$2.ConfirmationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1343
|
+
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$3.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"] }] });
|
|
1344
|
+
}
|
|
1345
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OrganizationPageComponent, decorators: [{
|
|
1346
|
+
type: Component,
|
|
1347
|
+
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"] }]
|
|
1348
|
+
}], ctorParameters: () => [{ type: OrganizationService }, { type: i2$2.MessageService }, { type: UserService }, { type: i2$2.ConfirmationService }] });
|
|
521
1349
|
|
|
522
1350
|
/*
|
|
523
1351
|
* Public API Surface of ngx-bok-utils
|
|
@@ -527,5 +1355,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
|
|
|
527
1355
|
* Generated bundle index. Do not edit.
|
|
528
1356
|
*/
|
|
529
1357
|
|
|
530
|
-
export { FooterComponent, HeaderComponent, NotFoundPageComponent, UserPageComponent };
|
|
1358
|
+
export { FooterComponent, HeaderComponent, NotFoundPageComponent, OrganizationPageComponent, UserPageComponent };
|
|
531
1359
|
//# sourceMappingURL=eo4geo-ngx-bok-utils.mjs.map
|