UNPKG

@tangential/admin-console

Version:
575 lines (568 loc) 92.1 kB
import * as i1$1 from '@angular/common'; import { CommonModule } from '@angular/common'; import * as i0 from '@angular/core'; import { Component, ViewEncapsulation, ChangeDetectionStrategy, ViewChild, NgModule, EventEmitter, Input, Output } from '@angular/core'; import * as i2$2 from '@angular/forms'; import { FormsModule } from '@angular/forms'; import * as i3$1 from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button'; import * as i1$2 from '@angular/material/button-toggle'; import { MatButtonToggleModule } from '@angular/material/button-toggle'; import * as i4 from '@angular/material/checkbox'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatGridListModule } from '@angular/material/grid-list'; import * as i4$2 from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon'; import * as i6$1 from '@angular/material/input'; import { MatInputModule } from '@angular/material/input'; import { MatListModule } from '@angular/material/list'; import { MatMenuModule } from '@angular/material/menu'; import * as i7 from '@angular/material/sort'; import { MatSort, MatSortModule } from '@angular/material/sort'; import * as i6 from '@angular/material/table'; import { MatTableDataSource, MatTableModule } from '@angular/material/table'; import { MatToolbarModule } from '@angular/material/toolbar'; import * as i5 from '@tangential/components'; import { TanjComponentsModule } from '@tangential/components'; import * as i2 from '@tangential/authorization-service'; import { AuthPermission, AuthRole, AuthUser, VisitorResolver, HasRoleGuard, AdminService, FirebaseAdminService } from '@tangential/authorization-service'; import * as i1 from '@tangential/core'; import { NameGenerator, generatePushID, Page, DefaultPageAnalytics } from '@tangential/core'; import { tap, debounceTime, distinctUntilChanged, filter, map } from 'rxjs/operators'; import * as i2$1 from '@angular/router'; import { RouterModule } from '@angular/router'; import * as i3 from '@angular/cdk/a11y'; import { SelectionModel } from '@angular/cdk/collections'; import * as i4$1 from '@tangential/plugin'; import 'rxjs'; import * as i5$1 from '@angular/material/form-field'; class AdminConsoleParentPage { constructor(bus, adminService, changeDetectorRef) { this.bus = bus; this.adminService = adminService; this.changeDetectorRef = changeDetectorRef; this.auth$ = this.adminService.auth$().pipe(tap((v) => { this.auth = v; this.changeDetectorRef.markForCheck(); })); } } AdminConsoleParentPage.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: AdminConsoleParentPage, deps: [{ token: i1.MessageBus }, { token: i2.AdminService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); AdminConsoleParentPage.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.10", type: AdminConsoleParentPage, selector: "tanj-admin-console-parent-page", ngImport: i0, template: '<router-outlet></router-outlet>', isInline: true, dependencies: [{ kind: "directive", type: i2$1.RouterOutlet, selector: "router-outlet", outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }], changeDetection: i0.ChangeDetectionStrategy.Default, encapsulation: i0.ViewEncapsulation.None }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: AdminConsoleParentPage, decorators: [{ type: Component, args: [{ selector: 'tanj-admin-console-parent-page', template: '<router-outlet></router-outlet>', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.Default }] }], ctorParameters: function () { return [{ type: i1.MessageBus }, { type: i2.AdminService }, { type: i0.ChangeDetectorRef }]; } }); class PermissionManagerPage { constructor(adminService, parent, _liveAnnouncer, changeDetectorRef) { this.adminService = adminService; this.parent = parent; this._liveAnnouncer = _liveAnnouncer; this.changeDetectorRef = changeDetectorRef; this.displayedColumns = ['select', '$key', 'description', 'createdMils', 'editedMils']; this.dataSource = new MatTableDataSource(); this.selection = new SelectionModel(true, []); this.rows = []; this.selected = []; } ngOnInit() { this.parent.auth$.subscribe({ next: (v) => { this.rows = v.settings.permissions; this.dataSource = new MatTableDataSource(v.settings.permissions); this.dataSource.sort = this.sort; this.changeDetectorRef.markForCheck(); } }); } get nextItemIndex() { let idx = 1; if (this.rows && this.rows.length) { idx = (this.rows[this.rows.length - 1].orderIndex + 1); } return idx; } onAddItemAction() { const permission = AuthPermission.from({ $key: NameGenerator.generate(), orderIndex: this.nextItemIndex }); this.adminService.addPermission(permission).catch((reason) => { console.error('PermissionManagerPage', 'error adding permission', reason); throw new Error(reason); }); } onRemove(key) { this.adminService.removePermission(key).catch((reason) => { console.error('PermissionManagerPage', 'error removing permission', reason); throw new Error(reason); }); } onRemoveSelectedAction(keys) { keys.forEach((key) => { this.adminService.removePermission(key).catch((reason) => { console.error('PermissionManagerPage', 'error removing permission', reason); throw new Error(reason); }); }); } onItemChange(permission) { this.adminService.updatePermission(permission).catch((reason) => { console.error('PermissionManagerPage', 'error updating permission', reason); throw new Error(reason); }); } /** * Borrowed directly from Angular Material examples: https://material.angular.io/components/table/overview */ /** Whether the number of selected elements matches the total number of rows. */ isAllSelected() { const numSelected = this.selection.selected.length; const numRows = this.dataSource.data.length; return numSelected === numRows; } /** Selects all rows if they are not all selected; otherwise clear selection. */ toggleAllRows() { if (this.isAllSelected()) { this.selection.clear(); return; } this.selection.select(...this.dataSource.data); } /** The label for the checkbox on the passed row */ checkboxLabel(row) { if (!row) { return `${this.isAllSelected() ? 'deselect' : 'select'} all`; } return `${this.selection.isSelected(row) ? 'deselect' : 'select'} ${row.description}`; } /** Announce the change in sort state for assistive technology. */ announceSortChange(sortState) { // This example uses English messages. If your application supports // multiple language, you would internationalize these strings. // Furthermore, you can customize the message to add additional // details about the values being sorted. if (sortState.direction) { this._liveAnnouncer.announce(`Sorted ${sortState.direction}ending`); } else { this._liveAnnouncer.announce('Sorting cleared'); } } } PermissionManagerPage.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: PermissionManagerPage, deps: [{ token: i2.AdminService }, { token: AdminConsoleParentPage }, { token: i3.LiveAnnouncer }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); PermissionManagerPage.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.10", type: PermissionManagerPage, selector: "tanj-permission-manager", viewQueries: [{ propertyName: "sort", first: true, predicate: MatSort, descendants: true }], ngImport: i0, template: "<tanj-page-body>\n <table mat-table matSort (matSortChange)=\"announceSortChange($event)\" [dataSource]=\"dataSource\" class=\"mat-elevation-z8 tng-user-mgr-table\">\n\n <!-- Checkbox Column -->\n <ng-container matColumnDef=\"select\">\n <th mat-header-cell *matHeaderCellDef>\n <mat-checkbox (change)=\"$event ? toggleAllRows() : null\"\n [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\"\n [aria-label]=\"checkboxLabel()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\" >\n <mat-checkbox (click)=\"$event.stopPropagation()\"\n (change)=\"$event ? selection.toggle(row) : null\"\n [checked]=\"selection.isSelected(row)\"\n [aria-label]=\"checkboxLabel(row)\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- UID Column -->\n <ng-container matColumnDef=\"$key\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Permission ID\"> Permission ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.$key}} </td>\n </ng-container>\n\n <!-- User name Column -->\n <ng-container matColumnDef=\"description\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Description\"> Description </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.description}} </td>\n </ng-container>\n\n <!-- User Email Column -->\n <ng-container matColumnDef=\"createdMils\" >\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Created Date\"> Created </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.createdMils | date:'yyyy-MM~dd, HH:mm:ss'}} </td>\n </ng-container>\n\n <!-- Last Sign in Column -->\n <ng-container matColumnDef=\"editedMils\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Last Modified\"> Last Modified </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.editedMils | date:'yyyy-MM~dd, HH:mm:ss' }} </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\" (click)=\"selection.toggle(row)\"></tr>\n </table>\n\n</tanj-page-body>\n", dependencies: [{ kind: "component", type: i4.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i5.PageBodyComponent, selector: "tanj-page-body", inputs: ["suppressHeaderShim", "flex", "layout", "layoutAlign"] }, { kind: "component", type: i6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i7.MatSort, selector: "[matSort]", inputs: ["matSortDisabled", "matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i7.MatSortHeader, selector: "[mat-sort-header]", inputs: ["disabled", "mat-sort-header", "arrowPosition", "start", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "pipe", type: i1$1.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: PermissionManagerPage, decorators: [{ type: Component, args: [{ selector: 'tanj-permission-manager', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<tanj-page-body>\n <table mat-table matSort (matSortChange)=\"announceSortChange($event)\" [dataSource]=\"dataSource\" class=\"mat-elevation-z8 tng-user-mgr-table\">\n\n <!-- Checkbox Column -->\n <ng-container matColumnDef=\"select\">\n <th mat-header-cell *matHeaderCellDef>\n <mat-checkbox (change)=\"$event ? toggleAllRows() : null\"\n [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\"\n [aria-label]=\"checkboxLabel()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\" >\n <mat-checkbox (click)=\"$event.stopPropagation()\"\n (change)=\"$event ? selection.toggle(row) : null\"\n [checked]=\"selection.isSelected(row)\"\n [aria-label]=\"checkboxLabel(row)\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- UID Column -->\n <ng-container matColumnDef=\"$key\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Permission ID\"> Permission ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.$key}} </td>\n </ng-container>\n\n <!-- User name Column -->\n <ng-container matColumnDef=\"description\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Description\"> Description </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.description}} </td>\n </ng-container>\n\n <!-- User Email Column -->\n <ng-container matColumnDef=\"createdMils\" >\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Created Date\"> Created </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.createdMils | date:'yyyy-MM~dd, HH:mm:ss'}} </td>\n </ng-container>\n\n <!-- Last Sign in Column -->\n <ng-container matColumnDef=\"editedMils\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Last Modified\"> Last Modified </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.editedMils | date:'yyyy-MM~dd, HH:mm:ss' }} </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\" (click)=\"selection.toggle(row)\"></tr>\n </table>\n\n</tanj-page-body>\n" }] }], ctorParameters: function () { return [{ type: i2.AdminService }, { type: AdminConsoleParentPage }, { type: i3.LiveAnnouncer }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { sort: [{ type: ViewChild, args: [MatSort] }] } }); class RoleManagerPage { constructor(parent, adminService, _liveAnnouncer, changeDetectorRef) { this.parent = parent; this.adminService = adminService; this._liveAnnouncer = _liveAnnouncer; this.changeDetectorRef = changeDetectorRef; this.displayedColumns = ['select', '$key', 'description', 'createdMils', 'editedMils']; this.dataSource = new MatTableDataSource(); this.selection = new SelectionModel(true, []); this.rows = []; this.selected = []; } ngOnInit() { this.parent.auth$.subscribe({ next: (v) => { this.rows = v.settings.roles; this.dataSource = new MatTableDataSource(v.settings.roles); this.dataSource.sort = this.sort; this.changeDetectorRef.markForCheck(); } }); } get nextItemIndex() { let idx = 1; if (this.rows && this.rows.length) { idx = (this.rows[this.rows.length - 1].orderIndex + 1); } return idx; } grantPermission(role, permission) { this.adminService.grantPermissionOnRole(role.$key, permission.$key).catch((reason) => { console.error('RoleManagerComponent', 'could not grant permission', reason); }); } revokePermission(role, permission) { this.adminService.revokePermissionOnRole(role.$key, permission.$key).catch((reason) => { console.error('RoleManagerComponent', 'could not revoke permission', reason); }); } onAddItemAction() { const role = AuthRole.from({ $key: NameGenerator.generate(), orderIndex: this.nextItemIndex }); this.adminService.addRole(role).catch((reason) => { console.error('RoleManagerComponent', 'error adding role', reason); throw new Error(reason); }); } onRemove(key) { this.adminService.removeRole(key).catch((reason) => { console.error('RoleManagerComponent', 'error removing role', reason); throw new Error(reason); }); } onRemoveSelectedAction(keys) { keys.forEach((key) => { this.adminService.removeRole(key).catch((reason) => { console.error('RoleManagerComponent', 'error removing role', reason); throw new Error(reason); }); }); } onItemChange(role) { this.adminService.updateRole(role).catch((reason) => { console.log('RoleManagerComponent', 'error updating role', reason); throw new Error(reason); }); } /** * Borrowed directly from Angular Material examples: https://material.angular.io/components/table/overview */ /** Whether the number of selected elements matches the total number of rows. */ isAllSelected() { const numSelected = this.selection.selected.length; const numRows = this.dataSource.data.length; return numSelected === numRows; } /** Selects all rows if they are not all selected; otherwise clear selection. */ toggleAllRows() { if (this.isAllSelected()) { this.selection.clear(); return; } this.selection.select(...this.dataSource.data); } /** The label for the checkbox on the passed row */ checkboxLabel(row) { if (!row) { return `${this.isAllSelected() ? 'deselect' : 'select'} all`; } return `${this.selection.isSelected(row) ? 'deselect' : 'select'} ${row.description}`; } /** Announce the change in sort state for assistive technology. */ announceSortChange(sortState) { // This example uses English messages. If your application supports // multiple language, you would internationalize these strings. // Furthermore, you can customize the message to add additional // details about the values being sorted. if (sortState.direction) { this._liveAnnouncer.announce(`Sorted ${sortState.direction}ending`); } else { this._liveAnnouncer.announce('Sorting cleared'); } } } RoleManagerPage.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: RoleManagerPage, deps: [{ token: AdminConsoleParentPage }, { token: i2.AdminService }, { token: i3.LiveAnnouncer }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); RoleManagerPage.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.10", type: RoleManagerPage, selector: "tanj-role-manager-page", viewQueries: [{ propertyName: "sort", first: true, predicate: MatSort, descendants: true }], ngImport: i0, template: "<tanj-page-body>\n <table mat-table matSort (matSortChange)=\"announceSortChange($event)\" [dataSource]=\"dataSource\" class=\"mat-elevation-z8 tng-user-mgr-table\">\n\n <!-- Checkbox Column -->\n <ng-container matColumnDef=\"select\">\n <th mat-header-cell *matHeaderCellDef>\n <mat-checkbox (change)=\"$event ? toggleAllRows() : null\"\n [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\"\n [aria-label]=\"checkboxLabel()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\" >\n <mat-checkbox (click)=\"$event.stopPropagation()\"\n (change)=\"$event ? selection.toggle(row) : null\"\n [checked]=\"selection.isSelected(row)\"\n [aria-label]=\"checkboxLabel(row)\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- UID Column -->\n <ng-container matColumnDef=\"$key\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Permission ID\"> Permission ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.$key}} </td>\n </ng-container>\n\n <!-- User name Column -->\n <ng-container matColumnDef=\"description\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Description\"> Description </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.description}} </td>\n </ng-container>\n\n <!-- User Email Column -->\n <ng-container matColumnDef=\"createdMils\" >\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Created Date\"> Created </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.createdMils | date:'yyyy-MM~dd, HH:mm:ss'}} </td>\n </ng-container>\n\n <!-- Last Sign in Column -->\n <ng-container matColumnDef=\"editedMils\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Last Modified\"> Last Modified </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.editedMils | date:'yyyy-MM~dd, HH:mm:ss' }} </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\" (click)=\"selection.toggle(row)\"></tr>\n </table>\n\n</tanj-page-body>\n", dependencies: [{ kind: "component", type: i4.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i5.PageBodyComponent, selector: "tanj-page-body", inputs: ["suppressHeaderShim", "flex", "layout", "layoutAlign"] }, { kind: "component", type: i6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i7.MatSort, selector: "[matSort]", inputs: ["matSortDisabled", "matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i7.MatSortHeader, selector: "[mat-sort-header]", inputs: ["disabled", "mat-sort-header", "arrowPosition", "start", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "pipe", type: i1$1.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: RoleManagerPage, decorators: [{ type: Component, args: [{ selector: 'tanj-role-manager-page', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<tanj-page-body>\n <table mat-table matSort (matSortChange)=\"announceSortChange($event)\" [dataSource]=\"dataSource\" class=\"mat-elevation-z8 tng-user-mgr-table\">\n\n <!-- Checkbox Column -->\n <ng-container matColumnDef=\"select\">\n <th mat-header-cell *matHeaderCellDef>\n <mat-checkbox (change)=\"$event ? toggleAllRows() : null\"\n [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\"\n [aria-label]=\"checkboxLabel()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\" >\n <mat-checkbox (click)=\"$event.stopPropagation()\"\n (change)=\"$event ? selection.toggle(row) : null\"\n [checked]=\"selection.isSelected(row)\"\n [aria-label]=\"checkboxLabel(row)\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- UID Column -->\n <ng-container matColumnDef=\"$key\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Permission ID\"> Permission ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.$key}} </td>\n </ng-container>\n\n <!-- User name Column -->\n <ng-container matColumnDef=\"description\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Description\"> Description </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.description}} </td>\n </ng-container>\n\n <!-- User Email Column -->\n <ng-container matColumnDef=\"createdMils\" >\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Created Date\"> Created </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.createdMils | date:'yyyy-MM~dd, HH:mm:ss'}} </td>\n </ng-container>\n\n <!-- Last Sign in Column -->\n <ng-container matColumnDef=\"editedMils\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Last Modified\"> Last Modified </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.editedMils | date:'yyyy-MM~dd, HH:mm:ss' }} </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\" (click)=\"selection.toggle(row)\"></tr>\n </table>\n\n</tanj-page-body>\n" }] }], ctorParameters: function () { return [{ type: AdminConsoleParentPage }, { type: i2.AdminService }, { type: i3.LiveAnnouncer }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { sort: [{ type: ViewChild, args: [MatSort] }] } }); class UserManagerPage { constructor(adminService, parent, _liveAnnouncer, changeDetectorRef) { this.adminService = adminService; this.parent = parent; this._liveAnnouncer = _liveAnnouncer; this.changeDetectorRef = changeDetectorRef; this.displayedColumns = ['select', '$key', 'displayName', 'email', 'lastSignInMils']; this.dataSource = new MatTableDataSource(); this.selection = new SelectionModel(true, []); this.rows = []; this.selected = []; this.columns = [ { prop: '$key', name: 'Key', flexGrow: 1 }, { prop: 'displayName', name: 'Display Name', flexGrow: 2 }, { prop: 'email', name: 'Created', flexGrow: 2 }, { prop: 'lastSignInMils', name: 'Last Sign In', flexGrow: 1 } ]; } ngOnInit() { this.parent.auth$.subscribe({ next: (v) => { this.rows = v.users; this.dataSource = new MatTableDataSource(v.users); this.dataSource.sort = this.sort; this.changeDetectorRef.markForCheck(); } }); } grantPermission(user, permission) { this.adminService.grantPermissionOnUser(user, permission).catch((reason) => { console.error('UserManagerComponent', 'could not grant permission', reason); }); } revokePermission(user, permission) { console.log('UserManagerComponent', 'revokePermission'); this.adminService.revokePermissionOnUser(user, permission).catch((reason) => { console.error('UserManagerComponent', 'could not revoke permission', reason); }); } grantRole(user, role) { this.adminService.grantRoleOnUser(user, role).catch((reason) => { console.error('UserManagerComponent', 'could not grant role', reason); }); } revokeRole(user, role) { this.adminService.revokeRoleOnUser(user.$key, role.$key).catch((reason) => { console.error('UserManagerComponent', 'could not revoke role', reason); }); } onAddItemAction() { const user = new AuthUser(generatePushID()); user.displayName = 'New User '; this.adminService.addUser(user).catch((reason) => { console.error('UserManagerComponent', 'error adding user', reason); throw new Error(reason); }); } onRemove(key) { this.adminService.removeUser(key).catch((reason) => { console.error('UserManagerComponent', 'error removing user', reason); throw new Error(reason); }); } onRemoveSelectedAction(keys) { keys.forEach((key) => { this.adminService.removeUser(key).catch((reason) => { console.error('UserManagerComponent', 'error removing user', reason); throw new Error(reason); }); }); } onItemChange(user) { this.adminService.updateUser(user).catch((reason) => { console.error('UserManagerComponent', 'error updating user', reason); throw new Error(reason); }); } /** * Borrowed directly from Angular Material examples: https://material.angular.io/components/table/overview */ /** Whether the number of selected elements matches the total number of rows. */ isAllSelected() { const numSelected = this.selection.selected.length; const numRows = this.dataSource.data.length; return numSelected === numRows; } /** Selects all rows if they are not all selected; otherwise clear selection. */ toggleAllRows() { if (this.isAllSelected()) { this.selection.clear(); return; } this.selection.select(...this.dataSource.data); } /** The label for the checkbox on the passed row */ checkboxLabel(row) { if (!row) { return `${this.isAllSelected() ? 'deselect' : 'select'} all`; } return `${this.selection.isSelected(row) ? 'deselect' : 'select'} ${row.displayName}`; } /** Announce the change in sort state for assistive technology. */ announceSortChange(sortState) { // This example uses English messages. If your application supports // multiple language, you would internationalize these strings. // Furthermore, you can customize the message to add additional // details about the values being sorted. if (sortState.direction) { this._liveAnnouncer.announce(`Sorted ${sortState.direction}ending`); } else { this._liveAnnouncer.announce('Sorting cleared'); } } } UserManagerPage.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: UserManagerPage, deps: [{ token: i2.AdminService }, { token: AdminConsoleParentPage }, { token: i3.LiveAnnouncer }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); UserManagerPage.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.10", type: UserManagerPage, selector: "tanj-user-manager-page", viewQueries: [{ propertyName: "sort", first: true, predicate: MatSort, descendants: true }], ngImport: i0, template: "<tanj-page-body>\n <table mat-table matSort (matSortChange)=\"announceSortChange($event)\" [dataSource]=\"dataSource\" class=\"mat-elevation-z8 tng-user-mgr-table\">\n\n <!-- Checkbox Column -->\n <ng-container matColumnDef=\"select\">\n <th mat-header-cell *matHeaderCellDef>\n <mat-checkbox (change)=\"$event ? toggleAllRows() : null\"\n [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\"\n [aria-label]=\"checkboxLabel()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\" >\n <mat-checkbox (click)=\"$event.stopPropagation()\"\n (change)=\"$event ? selection.toggle(row) : null\"\n [checked]=\"selection.isSelected(row)\"\n [aria-label]=\"checkboxLabel(row)\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- UID Column -->\n <ng-container matColumnDef=\"$key\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by UID\"> User ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.$key}} </td>\n </ng-container>\n\n <!-- User name Column -->\n <ng-container matColumnDef=\"displayName\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by name\"> User Name </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.displayName}} </td>\n </ng-container>\n\n <!-- User Email Column -->\n <ng-container matColumnDef=\"email\" >\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by email\"> Email </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.email}} </td>\n </ng-container>\n\n <!-- Last Sign in Column -->\n <ng-container matColumnDef=\"lastSignInMils\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Last Sign In\"> Last Sign In </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.lastSignInMils | date:'yyyy-MM~dd, HH:mm:ss' }} </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\" (click)=\"selection.toggle(row)\"></tr>\n </table>\n</tanj-page-body>\n", dependencies: [{ kind: "component", type: i4.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i5.PageBodyComponent, selector: "tanj-page-body", inputs: ["suppressHeaderShim", "flex", "layout", "layoutAlign"] }, { kind: "component", type: i6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i7.MatSort, selector: "[matSort]", inputs: ["matSortDisabled", "matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i7.MatSortHeader, selector: "[mat-sort-header]", inputs: ["disabled", "mat-sort-header", "arrowPosition", "start", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "pipe", type: i1$1.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: UserManagerPage, decorators: [{ type: Component, args: [{ selector: 'tanj-user-manager-page', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<tanj-page-body>\n <table mat-table matSort (matSortChange)=\"announceSortChange($event)\" [dataSource]=\"dataSource\" class=\"mat-elevation-z8 tng-user-mgr-table\">\n\n <!-- Checkbox Column -->\n <ng-container matColumnDef=\"select\">\n <th mat-header-cell *matHeaderCellDef>\n <mat-checkbox (change)=\"$event ? toggleAllRows() : null\"\n [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\"\n [aria-label]=\"checkboxLabel()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\" >\n <mat-checkbox (click)=\"$event.stopPropagation()\"\n (change)=\"$event ? selection.toggle(row) : null\"\n [checked]=\"selection.isSelected(row)\"\n [aria-label]=\"checkboxLabel(row)\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- UID Column -->\n <ng-container matColumnDef=\"$key\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by UID\"> User ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.$key}} </td>\n </ng-container>\n\n <!-- User name Column -->\n <ng-container matColumnDef=\"displayName\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by name\"> User Name </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.displayName}} </td>\n </ng-container>\n\n <!-- User Email Column -->\n <ng-container matColumnDef=\"email\" >\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by email\"> Email </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.email}} </td>\n </ng-container>\n\n <!-- Last Sign in Column -->\n <ng-container matColumnDef=\"lastSignInMils\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Last Sign In\"> Last Sign In </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.lastSignInMils | date:'yyyy-MM~dd, HH:mm:ss' }} </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\" (click)=\"selection.toggle(row)\"></tr>\n </table>\n</tanj-page-body>\n" }] }], ctorParameters: function () { return [{ type: i2.AdminService }, { type: AdminConsoleParentPage }, { type: i3.LiveAnnouncer }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { sort: [{ type: ViewChild, args: [MatSort] }] } }); class PluginsPage extends Page { constructor(bus, router, route, parent, pluginManager, changeDetectorRef) { super(bus); this.router = router; this.route = route; this.parent = parent; this.pluginManager = pluginManager; this.changeDetectorRef = changeDetectorRef; this.routeInfo = { page: { title: 'Admin Console' }, analytics: DefaultPageAnalytics(), showAds: false }; this.visitor = null; } ngOnInit() { this.pluginManager.scan(); } } PluginsPage.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: PluginsPage, deps: [{ token: i1.MessageBus }, { token: i2$1.Router }, { token: i2$1.ActivatedRoute }, { token: AdminConsoleParentPage }, { token: i4$1.PluginManager }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); PluginsPage.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.10", type: PluginsPage, selector: "tanj-plugins-page", usesInheritance: true, ngImport: i0, template: "<div class=\"tanj-header-shim\"></div>\n<div flex layout=\"column\" layout-align=\"start\">\n <div *ngFor=\"let entry of pluginManager.pluginPaths\" flex layout=\"row\" layout-align=\"start\" class=\"tanj-plugin-entry\">\n <div class=\"tanj-entry-name\">{{entry.name}}</div>\n <a class=\"tanj-entry-path\" [routerLink]=\"['/', entry.path, 'plugin']\">{{entry.path}}</a>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.Default, encapsulation: i0.ViewEncapsulation.None }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: PluginsPage, decorators: [{ type: Component, args: [{ selector: 'tanj-plugins-page', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.Default, template: "<div class=\"tanj-header-shim\"></div>\n<div flex layout=\"column\" layout-align=\"start\">\n <div *ngFor=\"let entry of pluginManager.pluginPaths\" flex layout=\"row\" layout-align=\"start\" class=\"tanj-plugin-entry\">\n <div class=\"tanj-entry-name\">{{entry.name}}</div>\n <a class=\"tanj-entry-path\" [routerLink]=\"['/', entry.path, 'plugin']\">{{entry.path}}</a>\n </div>\n</div>\n" }] }], ctorParameters: function () { return [{ type: i1.MessageBus }, { type: i2$1.Router }, { type: i2$1.ActivatedRoute }, { type: AdminConsoleParentPage }, { type: i4$1.PluginManager }, { type: i0.ChangeDetectorRef }]; } }); const AdminRoutes = { parent: { path: '', component: AdminConsoleParentPage, resolve: { visitor: VisitorResolver }, canActivate: [HasRoleGuard], data: { roles: ['Administrator'] }, navTargets: { absSelf: ['/', 'admin'], up() { return ['/']; }, } }, children: { plugins: { path: 'plugins', component: PluginsPage, navTargets: { absSelf: ['/', 'admin', 'plugins'] }, }, permissions: { path: 'permissions', component: PermissionManagerPage, navTargets: { absSelf: ['/', 'admin', 'permissions'] }, }, roles: { path: 'roles', component: RoleManagerPage, navTargets: { absSelf: ['/', 'admin', 'roles'] }, }, users: { path: 'users', component: UserManagerPage, navTargets: { absSelf: ['/', 'admin', 'users'] }, } } }; const routes = [ { path: AdminRoutes.parent.path, component: AdminRoutes.parent.component, canActivate: AdminRoutes.parent.canActivate, data: AdminRoutes.parent.data, resolve: AdminRoutes.parent.resolve, children: [ { path: '', children: [ AdminRoutes.children.plugins, AdminRoutes.children.permissions, AdminRoutes.children.roles, AdminRoutes.children.users, ] }, ] } ]; class AdminConsoleRoutingModule { } AdminConsoleRoutingModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: AdminConsoleRoutingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); AdminConsoleRoutingModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.2.10", ngImport: i0, type: AdminConsoleRoutingModule, imports: [i2$1.RouterModule], exports: [RouterModule] }); AdminConsoleRoutingModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: AdminConsoleRoutingModule, providers: [ VisitorResolver, ], imports: [RouterModule.forChild(routes), RouterModule] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: AdminConsoleRoutingModule, decorators: [{ type: NgModule, args: [{ imports: [ RouterModule.forChild(routes) ], exports: [ RouterModule ], providers: [ VisitorResolver, ] }] }] }); class PermissionComponent { constructor() { this.remove = new EventEmitter(false); this._focusDebouncer = new EventEmitter(false); this.submitted = false; this._changed = false; let distinct = this._focusDebouncer.asObservable(); distinct = distinct.pipe(debounceTime(10), distinctUntilChanged()); this.focus = distinct.pipe(filter((v) => v === true), map(() => new Event('focus'))); this.change = distinct.pipe(filter((focused) => focused === false && this._changed), map(() => { const change = { previous: this._previous, current: this.permission }; if (!this.permission) { throw "Missing Permission"; } this._previous = AuthPermission.from(this.permission); this._changed = false; return change; })); this.blur = distinct.pipe(filter((v) => v === false), map(() => new Event('blur'))); } ngOnChanges(changes) { if (changes.permission) { this._previous = AuthPermission.from(this.permission); this._changed = false; } } fireRemove() { this.remove.emit(this.permission); } onChange(event) { event.stopPropagation(); this._changed = true; } onBlur(event) { event.stopPropagation(); this._focusDebouncer.emit(false); } onFocus(event) { event.stopPropagation(); this._focusDebouncer.emit(true); } onSubmit() { this.submitted = true; } } PermissionComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: PermissionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); PermissionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.10", type: PermissionComponent, selector: "tanj-permission", inputs: { permission: "permission" }, outputs: { change: "change", remove: "remove", focus: "focus", blur: "blur" }, usesOnChanges: true, ngImport: i0, template: "<div flex layout=\"column\" layout-align=\"start\">\n\n <div class=\"tanj-permission-form-wrapper\" flex layout=\"column\" layout-align=\"start\">\n\n\n <form *ngIf=\"permission != null\"\n (ngSubmit)=\"onSubmit($event)\"\n #permissionForm=\"ngForm\"\n flex\n layout=\"row\"\n layout-align=\"space-between\">\n\n <div class=\"tanj-permission-inputs-wrapper\" layout=\"row\" flex=\"80\" layout-align=\"space-between start\">\n <mat-form-field flex=\"40\">\n <input matInput [(ngModel)]=\"permission.$key\" name=\"name\" #fName=\"ngModel\"\n class=\"tanj-input\"\n dividerColor=\"accent\"\n [type]=\"'text'\"\n required minlength=\"2\"\n value=\"{{permission.$key}}\"\n placeholder=\"Name\"\n (change)=\"onChange($event)\"\n (focus)=\"onFocus($event)\"\n (blur)=\"onBlur($event)\"\n />\n </mat-form-field>\n <mat-form-field flex=\"60\">\n <input matInput [(ngModel)]=\"permission.description\" name=\"description\" #fDescription=\"ngModel\"\n class=\"tanj-description tanj-input\"\n dividerColor=\"accent\"\n\n [type]=\"'text'\"\n value=\"{{permission.description}