@myrmidon/auth-jwt-admin 0.1.1 → 1.0.0
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/esm2020/lib/auth-jwt-admin.module.mjs +5 -5
- package/esm2020/lib/components/auth-jwt-registration/auth-jwt-registration.component.mjs +6 -6
- package/esm2020/lib/components/confirm-dialog/confirm-dialog.component.mjs +3 -3
- package/esm2020/lib/components/password-strength-bar/password-strength-bar.component.mjs +3 -3
- package/esm2020/lib/components/state/user-list.repository.mjs +147 -0
- package/esm2020/lib/components/user-editor/user-editor.component.mjs +7 -7
- package/esm2020/lib/components/user-filter/user-filter.component.mjs +15 -18
- package/esm2020/lib/components/user-list/user-list.component.mjs +34 -102
- package/esm2020/lib/services/auth-jwt-account.service.mjs +7 -7
- package/esm2020/lib/services/dialog.service.mjs +3 -3
- package/fesm2015/myrmidon-auth-jwt-admin.mjs +188 -221
- package/fesm2015/myrmidon-auth-jwt-admin.mjs.map +1 -1
- package/fesm2020/myrmidon-auth-jwt-admin.mjs +187 -219
- package/fesm2020/myrmidon-auth-jwt-admin.mjs.map +1 -1
- package/lib/components/auth-jwt-registration/auth-jwt-registration.component.d.ts +1 -1
- package/lib/components/confirm-dialog/confirm-dialog.component.d.ts +1 -1
- package/lib/components/password-strength-bar/password-strength-bar.component.d.ts +1 -1
- package/lib/components/state/user-list.repository.d.ts +36 -0
- package/lib/components/user-editor/user-editor.component.d.ts +1 -1
- package/lib/components/user-filter/user-filter.component.d.ts +7 -8
- package/lib/components/user-list/user-list.component.d.ts +11 -20
- package/lib/services/auth-jwt-account.service.d.ts +1 -3
- package/package.json +6 -6
- package/esm2020/lib/components/state/users.paginator.mjs +0 -12
- package/esm2020/lib/components/state/users.query.mjs +0 -20
- package/esm2020/lib/components/state/users.service.mjs +0 -65
- package/esm2020/lib/components/state/users.store.mjs +0 -27
- package/lib/components/state/users.paginator.d.ts +0 -3
- package/lib/components/state/users.query.d.ts +0 -12
- package/lib/components/state/users.service.d.ts +0 -19
- package/lib/components/state/users.store.d.ts +0 -13
|
@@ -1,40 +1,42 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, EventEmitter, Component, Input, Output,
|
|
2
|
+
import { Injectable, EventEmitter, Component, Input, Output, Optional, Inject, NgModule } from '@angular/core';
|
|
3
3
|
import * as i1$1 from '@angular/forms';
|
|
4
4
|
import { Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
5
|
-
import { retry, catchError, take
|
|
5
|
+
import { retry, catchError, take } from 'rxjs/operators';
|
|
6
6
|
import * as i2$1 from '@angular/material/snack-bar';
|
|
7
7
|
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
|
8
8
|
import * as i1 from '@angular/common/http';
|
|
9
9
|
import { HttpParams, HttpClientModule } from '@angular/common/http';
|
|
10
10
|
import * as i2 from '@myrmidon/ng-tools';
|
|
11
11
|
import { NgToolsModule } from '@myrmidon/ng-tools';
|
|
12
|
-
import * as
|
|
12
|
+
import * as i4 from '@angular/common';
|
|
13
13
|
import { CommonModule } from '@angular/common';
|
|
14
|
-
import * as
|
|
14
|
+
import * as i5 from '@angular/material/button';
|
|
15
15
|
import { MatButtonModule } from '@angular/material/button';
|
|
16
16
|
import * as i6 from '@angular/material/icon';
|
|
17
17
|
import { MatIconModule } from '@angular/material/icon';
|
|
18
|
-
import * as i7
|
|
19
|
-
import * as i8 from '@angular/material/input';
|
|
18
|
+
import * as i7 from '@angular/material/input';
|
|
20
19
|
import { MatInputModule } from '@angular/material/input';
|
|
20
|
+
import * as i8 from '@angular/material/form-field';
|
|
21
21
|
import * as i9 from '@angular/material/progress-spinner';
|
|
22
22
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
23
|
-
import
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import
|
|
23
|
+
import { __rest } from 'tslib';
|
|
24
|
+
import { BehaviorSubject, combineLatest, map, debounceTime, take as take$1 } from 'rxjs';
|
|
25
|
+
import { select, createStore, withProps } from '@ngneat/elf';
|
|
26
|
+
import { selectActiveEntity, withEntities, withActiveId, upsertEntities, deleteAllEntities, setActiveId, updateEntities } from '@ngneat/elf-entities';
|
|
27
|
+
import { selectPaginationData, selectCurrentPageEntities, deleteAllPages, withPagination, updatePaginationData, setPage, hasPage, setCurrentPage } from '@ngneat/elf-pagination';
|
|
28
|
+
import { selectRequestStatus, withRequestsCache, withRequestsStatus, updateRequestStatus } from '@ngneat/elf-requests';
|
|
29
|
+
import * as i9$1 from '@angular/material/tooltip';
|
|
27
30
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
28
|
-
import { BehaviorSubject, combineLatest } from 'rxjs';
|
|
29
31
|
import * as i1$2 from '@angular/material/dialog';
|
|
30
32
|
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
|
31
33
|
import * as i2$2 from '@myrmidon/auth-jwt-login';
|
|
32
34
|
import { AuthJwtLoginModule } from '@myrmidon/auth-jwt-login';
|
|
33
|
-
import * as
|
|
35
|
+
import * as i7$1 from '@angular/material/paginator';
|
|
34
36
|
import { MatPaginatorModule } from '@angular/material/paginator';
|
|
35
|
-
import * as
|
|
37
|
+
import * as i8$1 from '@angular/material/progress-bar';
|
|
36
38
|
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
|
37
|
-
import * as i5 from '@angular/material/checkbox';
|
|
39
|
+
import * as i5$1 from '@angular/material/checkbox';
|
|
38
40
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
39
41
|
import { MatCardModule } from '@angular/material/card';
|
|
40
42
|
import { RouterModule } from '@angular/router';
|
|
@@ -148,10 +150,10 @@ class AuthJwtAccountService {
|
|
|
148
150
|
})
|
|
149
151
|
.pipe(retry(3), catchError(this._error.handleError));
|
|
150
152
|
}
|
|
151
|
-
getUsers(filter) {
|
|
153
|
+
getUsers(filter, pageNumber = 1, pageSize = 20) {
|
|
152
154
|
let httpParams = new HttpParams();
|
|
153
|
-
httpParams = httpParams.set('pageNumber',
|
|
154
|
-
httpParams = httpParams.set('pageSize',
|
|
155
|
+
httpParams = httpParams.set('pageNumber', pageNumber.toString());
|
|
156
|
+
httpParams = httpParams.set('pageSize', pageSize.toString());
|
|
155
157
|
if (filter.name) {
|
|
156
158
|
httpParams = httpParams.set('name', filter.name);
|
|
157
159
|
}
|
|
@@ -248,9 +250,9 @@ class AuthJwtAccountService {
|
|
|
248
250
|
.pipe(catchError(this._error.handleError));
|
|
249
251
|
}
|
|
250
252
|
}
|
|
251
|
-
AuthJwtAccountService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
252
|
-
AuthJwtAccountService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
253
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
253
|
+
AuthJwtAccountService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: AuthJwtAccountService, deps: [{ token: i1.HttpClient }, { token: i2.ErrorService }, { token: i2.EnvService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
254
|
+
AuthJwtAccountService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: AuthJwtAccountService, providedIn: 'root' });
|
|
255
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: AuthJwtAccountService, decorators: [{
|
|
254
256
|
type: Injectable,
|
|
255
257
|
args: [{
|
|
256
258
|
providedIn: 'root',
|
|
@@ -324,9 +326,9 @@ class PasswordStrengthBarComponent {
|
|
|
324
326
|
}
|
|
325
327
|
}
|
|
326
328
|
}
|
|
327
|
-
PasswordStrengthBarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
328
|
-
PasswordStrengthBarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
329
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
329
|
+
PasswordStrengthBarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: PasswordStrengthBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
330
|
+
PasswordStrengthBarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.0", type: PasswordStrengthBarComponent, selector: "auth-jwt-password-strength-bar", inputs: { passwordToCheck: "passwordToCheck" }, outputs: { strengthChange: "strengthChange" }, usesOnChanges: true, ngImport: i0, template: "<div id=\"strength\">\n <small>strength:</small>\n <ul id=\"strengthBar\">\n <li class=\"point\" [style.background-color]=\"bars[0]\"></li>\n <li class=\"point\" [style.background-color]=\"bars[1]\"></li>\n <li class=\"point\" [style.background-color]=\"bars[2]\"></li>\n <li class=\"point\" [style.background-color]=\"bars[3]\"></li>\n <li class=\"point\" [style.background-color]=\"bars[4]\"></li>\n </ul>\n</div>\n", styles: ["ul#strengthBar{display:inline;list-style:none;margin:0 0 0 15px;padding:0;vertical-align:2px}li.point:last{margin:0!important}li.point{background:#ddd;border-radius:2px;display:inline-block;height:5px;margin-right:1px;width:20px}\n"] });
|
|
331
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: PasswordStrengthBarComponent, decorators: [{
|
|
330
332
|
type: Component,
|
|
331
333
|
args: [{ selector: 'auth-jwt-password-strength-bar', template: "<div id=\"strength\">\n <small>strength:</small>\n <ul id=\"strengthBar\">\n <li class=\"point\" [style.background-color]=\"bars[0]\"></li>\n <li class=\"point\" [style.background-color]=\"bars[1]\"></li>\n <li class=\"point\" [style.background-color]=\"bars[2]\"></li>\n <li class=\"point\" [style.background-color]=\"bars[3]\"></li>\n <li class=\"point\" [style.background-color]=\"bars[4]\"></li>\n </ul>\n</div>\n", styles: ["ul#strengthBar{display:inline;list-style:none;margin:0 0 0 15px;padding:0;vertical-align:2px}li.point:last{margin:0!important}li.point{background:#ddd;border-radius:2px;display:inline-block;height:5px;margin-right:1px;width:20px}\n"] }]
|
|
332
334
|
}], ctorParameters: function () { return []; }, propDecorators: { passwordToCheck: [{
|
|
@@ -514,118 +516,158 @@ class AuthJwtRegistrationComponent {
|
|
|
514
516
|
});
|
|
515
517
|
}
|
|
516
518
|
}
|
|
517
|
-
AuthJwtRegistrationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
518
|
-
AuthJwtRegistrationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
519
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
519
|
+
AuthJwtRegistrationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: AuthJwtRegistrationComponent, deps: [{ token: i1$1.UntypedFormBuilder }, { token: i2$1.MatSnackBar }, { token: AuthJwtAccountService }], target: i0.ɵɵFactoryTarget.Component });
|
|
520
|
+
AuthJwtRegistrationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.0", type: AuthJwtRegistrationComponent, selector: "auth-jwt-registration", outputs: { registered: "registered" }, ngImport: i0, template: "<div>\n <div>\n <p>\n To register a new user, you must provide his email address, choose a\n password, and choose a username, which must be unique (you will be\n notified if another user has already taken that name). The username must\n include only letters/digits, start with a letter, and be no shorter than 3\n characters, nor longer than 50.\n </p>\n <p>\n To promote a decent security level, the password must include at least 8\n characters, uppercase and lowercase letters, digits, and punctuation (like\n dashes, stops, parentheses, etc.).\n </p>\n <p>\n Once registered, the user will receive an email message to the email\n address you specified; he will have to click on the provided link to\n complete the registration process.\n </p>\n </div>\n\n <form role=\"form\" [formGroup]=\"registration\" (submit)=\"onSubmit()\">\n <fieldset>\n <label>register user</label>\n <!-- email -->\n <div>\n <mat-form-field>\n <input\n matInput\n type=\"email\"\n id=\"email\"\n maxlength=\"256\"\n required\n autofocus\n spellcheck=\"false\"\n placeholder=\"email\"\n formControlName=\"email\"\n />\n <mat-error>{{ getEmailErrorLabel() }}</mat-error>\n <mat-icon *ngIf=\"email.pending\">hourglass</mat-icon>\n </mat-form-field>\n </div>\n\n <!-- name -->\n <div>\n <mat-form-field>\n <input\n matInput\n type=\"text\"\n id=\"name\"\n maxlength=\"50\"\n required\n pattern=\"^[a-zA-Z][a-zA-Z0-9]{2,49}$\"\n spellcheck=\"false\"\n placeholder=\"username\"\n formControlName=\"name\"\n />\n <mat-error>{{ getNameErrorLabel() }}</mat-error>\n <mat-icon *ngIf=\"name.pending\">hourglass</mat-icon>\n </mat-form-field>\n </div>\n\n <!-- first name -->\n <div>\n <mat-form-field>\n <input\n matInput\n type=\"text\"\n id=\"firstName\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n placeholder=\"first name\"\n formControlName=\"firstName\"\n />\n <mat-error\n *ngIf=\"\n firstName.hasError('required') &&\n (firstName.dirty || firstName.touched)\n \"\n class=\"text-danger small\"\n >\n first name required\n </mat-error>\n </mat-form-field>\n </div>\n\n <!-- last name -->\n <div>\n <mat-form-field>\n <input\n matInput\n type=\"text\"\n id=\"lastName\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n placeholder=\"last name\"\n formControlName=\"lastName\"\n />\n <mat-error\n *ngIf=\"\n lastName.hasError('required') &&\n (lastName.dirty || lastName.touched)\n \"\n class=\"text-danger small\"\n >\n last name required\n </mat-error>\n </mat-form-field>\n </div>\n\n <div [formGroup]=\"passwords\">\n <!-- password -->\n <div>\n <mat-form-field>\n <input\n matInput\n type=\"password\"\n name=\"password\"\n autocomplete=\"new-password\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n placeholder=\"password\"\n formControlName=\"password\"\n />\n <auth-jwt-password-strength-bar [passwordToCheck]=\"password.value\">\n </auth-jwt-password-strength-bar>\n <mat-error>{{ getPasswordErrorLabel() }}</mat-error>\n </mat-form-field>\n </div>\n\n <!-- confirm password -->\n <div>\n <mat-form-field>\n <input\n matInput\n type=\"password\"\n name=\"confirmPassword\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n placeholder=\"confirm password\"\n formControlName=\"confirmPassword\"\n />\n <mat-error\n *ngIf=\"\n passwords.hasError('areEqual') &&\n (confirmPassword.dirty || confirmPassword.touched)\n \"\n >\n password differs from confirmation password\n </mat-error>\n </mat-form-field>\n </div>\n </div>\n\n <button\n mat-raised-button\n type=\"submit\"\n color=\"primary\"\n [disabled]=\"\n !registration.valid || busy || name.pending || email.pending\n \"\n >\n register\n </button>\n <mat-progress-spinner\n diameter=\"20\"\n *ngIf=\"busy\"\n aria-label=\"Busy\"\n ></mat-progress-spinner>\n </fieldset>\n </form>\n</div>\n", styles: ["mat-form-field{width:400px}fieldset{border:1px solid silver;border-radius:8px;padding:16px}\n"], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i5.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i8.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: i9.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: PasswordStrengthBarComponent, selector: "auth-jwt-password-strength-bar", inputs: ["passwordToCheck"], outputs: ["strengthChange"] }] });
|
|
521
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: AuthJwtRegistrationComponent, decorators: [{
|
|
520
522
|
type: Component,
|
|
521
523
|
args: [{ selector: 'auth-jwt-registration', template: "<div>\n <div>\n <p>\n To register a new user, you must provide his email address, choose a\n password, and choose a username, which must be unique (you will be\n notified if another user has already taken that name). The username must\n include only letters/digits, start with a letter, and be no shorter than 3\n characters, nor longer than 50.\n </p>\n <p>\n To promote a decent security level, the password must include at least 8\n characters, uppercase and lowercase letters, digits, and punctuation (like\n dashes, stops, parentheses, etc.).\n </p>\n <p>\n Once registered, the user will receive an email message to the email\n address you specified; he will have to click on the provided link to\n complete the registration process.\n </p>\n </div>\n\n <form role=\"form\" [formGroup]=\"registration\" (submit)=\"onSubmit()\">\n <fieldset>\n <label>register user</label>\n <!-- email -->\n <div>\n <mat-form-field>\n <input\n matInput\n type=\"email\"\n id=\"email\"\n maxlength=\"256\"\n required\n autofocus\n spellcheck=\"false\"\n placeholder=\"email\"\n formControlName=\"email\"\n />\n <mat-error>{{ getEmailErrorLabel() }}</mat-error>\n <mat-icon *ngIf=\"email.pending\">hourglass</mat-icon>\n </mat-form-field>\n </div>\n\n <!-- name -->\n <div>\n <mat-form-field>\n <input\n matInput\n type=\"text\"\n id=\"name\"\n maxlength=\"50\"\n required\n pattern=\"^[a-zA-Z][a-zA-Z0-9]{2,49}$\"\n spellcheck=\"false\"\n placeholder=\"username\"\n formControlName=\"name\"\n />\n <mat-error>{{ getNameErrorLabel() }}</mat-error>\n <mat-icon *ngIf=\"name.pending\">hourglass</mat-icon>\n </mat-form-field>\n </div>\n\n <!-- first name -->\n <div>\n <mat-form-field>\n <input\n matInput\n type=\"text\"\n id=\"firstName\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n placeholder=\"first name\"\n formControlName=\"firstName\"\n />\n <mat-error\n *ngIf=\"\n firstName.hasError('required') &&\n (firstName.dirty || firstName.touched)\n \"\n class=\"text-danger small\"\n >\n first name required\n </mat-error>\n </mat-form-field>\n </div>\n\n <!-- last name -->\n <div>\n <mat-form-field>\n <input\n matInput\n type=\"text\"\n id=\"lastName\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n placeholder=\"last name\"\n formControlName=\"lastName\"\n />\n <mat-error\n *ngIf=\"\n lastName.hasError('required') &&\n (lastName.dirty || lastName.touched)\n \"\n class=\"text-danger small\"\n >\n last name required\n </mat-error>\n </mat-form-field>\n </div>\n\n <div [formGroup]=\"passwords\">\n <!-- password -->\n <div>\n <mat-form-field>\n <input\n matInput\n type=\"password\"\n name=\"password\"\n autocomplete=\"new-password\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n placeholder=\"password\"\n formControlName=\"password\"\n />\n <auth-jwt-password-strength-bar [passwordToCheck]=\"password.value\">\n </auth-jwt-password-strength-bar>\n <mat-error>{{ getPasswordErrorLabel() }}</mat-error>\n </mat-form-field>\n </div>\n\n <!-- confirm password -->\n <div>\n <mat-form-field>\n <input\n matInput\n type=\"password\"\n name=\"confirmPassword\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n placeholder=\"confirm password\"\n formControlName=\"confirmPassword\"\n />\n <mat-error\n *ngIf=\"\n passwords.hasError('areEqual') &&\n (confirmPassword.dirty || confirmPassword.touched)\n \"\n >\n password differs from confirmation password\n </mat-error>\n </mat-form-field>\n </div>\n </div>\n\n <button\n mat-raised-button\n type=\"submit\"\n color=\"primary\"\n [disabled]=\"\n !registration.valid || busy || name.pending || email.pending\n \"\n >\n register\n </button>\n <mat-progress-spinner\n diameter=\"20\"\n *ngIf=\"busy\"\n aria-label=\"Busy\"\n ></mat-progress-spinner>\n </fieldset>\n </form>\n</div>\n", styles: ["mat-form-field{width:400px}fieldset{border:1px solid silver;border-radius:8px;padding:16px}\n"] }]
|
|
522
524
|
}], ctorParameters: function () { return [{ type: i1$1.UntypedFormBuilder }, { type: i2$1.MatSnackBar }, { type: AuthJwtAccountService }]; }, propDecorators: { registered: [{
|
|
523
525
|
type: Output
|
|
524
526
|
}] } });
|
|
525
527
|
|
|
526
|
-
const
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
528
|
+
const PAGE_SIZE = 20;
|
|
529
|
+
class UserListRepository {
|
|
530
|
+
constructor(_accService) {
|
|
531
|
+
this._accService = _accService;
|
|
532
|
+
// create store
|
|
533
|
+
this._store = this.createStore();
|
|
534
|
+
this._lastPageSize = PAGE_SIZE;
|
|
535
|
+
this._loading$ = new BehaviorSubject(false);
|
|
536
|
+
this._saving$ = new BehaviorSubject(false);
|
|
537
|
+
this.loading$ = this._loading$.asObservable();
|
|
538
|
+
this.saving$ = this._saving$.asObservable();
|
|
539
|
+
// combine pagination parameters with page data for our consumers
|
|
540
|
+
this.pagination$ = combineLatest([
|
|
541
|
+
this._store.pipe(selectPaginationData()),
|
|
542
|
+
this._store.pipe(selectCurrentPageEntities()),
|
|
543
|
+
]).pipe(map(([pagination, data]) => (Object.assign(Object.assign({}, pagination), { data }))), debounceTime(0));
|
|
544
|
+
// the active document, if required
|
|
545
|
+
this.activeUser$ = this._store.pipe(selectActiveEntity());
|
|
546
|
+
// the filter, if required
|
|
547
|
+
this.filter$ = this._store.pipe(select((state) => state.filter));
|
|
548
|
+
this.filter$.subscribe((filter) => {
|
|
549
|
+
// when filter changed, reset any existing page and move to page 1
|
|
550
|
+
const paginationData = this._store.getValue().pagination;
|
|
551
|
+
console.log('Deleting all pages');
|
|
552
|
+
this._store.update(deleteAllPages());
|
|
553
|
+
// load page 1
|
|
554
|
+
this.loadPage(1, paginationData.perPage);
|
|
555
|
+
});
|
|
556
|
+
// the request status
|
|
557
|
+
this.status$ = this._store.pipe(selectRequestStatus('document'));
|
|
558
|
+
// load page 1 and subscribe to pagination
|
|
559
|
+
this.loadPage(1, PAGE_SIZE);
|
|
560
|
+
this.pagination$.subscribe(console.log);
|
|
561
|
+
}
|
|
562
|
+
createStore() {
|
|
563
|
+
const store = createStore({ name: 'user-list' }, withProps({
|
|
564
|
+
filter: {},
|
|
565
|
+
}), withEntities({ idKey: 'userName' }), withActiveId(), withRequestsCache(), withRequestsStatus(), withPagination());
|
|
566
|
+
return store;
|
|
567
|
+
}
|
|
568
|
+
adaptPage(page) {
|
|
569
|
+
// adapt the server page DataPage<T> to Elf pagination
|
|
570
|
+
return {
|
|
571
|
+
currentPage: page.pageNumber,
|
|
572
|
+
perPage: page.pageSize,
|
|
573
|
+
lastPage: page.pageCount,
|
|
574
|
+
total: page.total,
|
|
575
|
+
data: page.items,
|
|
576
|
+
};
|
|
555
577
|
}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
args: [{ providedIn: 'root' }]
|
|
562
|
-
}], ctorParameters: function () { return [{ type: UsersStore }]; } });
|
|
563
|
-
|
|
564
|
-
class UsersService {
|
|
565
|
-
constructor(_store, _accountService) {
|
|
566
|
-
this._store = _store;
|
|
567
|
-
this._accountService = _accountService;
|
|
578
|
+
addPage(response) {
|
|
579
|
+
const { data } = response, paginationData = __rest(response, ["data"]);
|
|
580
|
+
this._store.update(upsertEntities(data),
|
|
581
|
+
// addEntities(data),
|
|
582
|
+
updatePaginationData(paginationData), setPage(paginationData.currentPage, data.map((c) => c.userName)));
|
|
568
583
|
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
this._store.
|
|
575
|
-
|
|
584
|
+
loadPage(pageNumber, pageSize) {
|
|
585
|
+
if (!pageSize) {
|
|
586
|
+
pageSize = PAGE_SIZE;
|
|
587
|
+
}
|
|
588
|
+
// if the page exists and page size is the same, just move to it
|
|
589
|
+
if (this._store.query(hasPage(pageNumber)) &&
|
|
590
|
+
pageSize === this._lastPageSize) {
|
|
591
|
+
console.log('Page exists: ' + pageNumber);
|
|
592
|
+
this._store.update(setCurrentPage(pageNumber));
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
// reset cached pages if page size changed
|
|
596
|
+
if (this._lastPageSize !== pageSize) {
|
|
597
|
+
this._store.update(deleteAllPages());
|
|
598
|
+
this._lastPageSize = pageSize;
|
|
599
|
+
}
|
|
600
|
+
// load page from server
|
|
601
|
+
this._store.update(updateRequestStatus('document', 'pending'));
|
|
602
|
+
this._loading$.next(true);
|
|
603
|
+
this._accService
|
|
604
|
+
.getUsers(this._store.getValue().filter, pageNumber, pageSize)
|
|
605
|
+
.pipe(take$1(1))
|
|
606
|
+
.subscribe((page) => {
|
|
607
|
+
this._loading$.next(false);
|
|
608
|
+
this.addPage(Object.assign(Object.assign({}, this.adaptPage(page)), { data: page.items }));
|
|
609
|
+
this._store.update(updateRequestStatus('document', 'success'));
|
|
576
610
|
});
|
|
577
611
|
}
|
|
612
|
+
setFilter(filter) {
|
|
613
|
+
this._store.update((state) => (Object.assign(Object.assign({}, state), { filter: filter })));
|
|
614
|
+
}
|
|
615
|
+
clearCache() {
|
|
616
|
+
this._store.update(deleteAllEntities(), deleteAllPages());
|
|
617
|
+
}
|
|
578
618
|
setActive(name) {
|
|
579
|
-
this._store.
|
|
619
|
+
this._store.update(setActiveId(name));
|
|
580
620
|
}
|
|
581
621
|
updateActive(user) {
|
|
582
622
|
const promise = new Promise((resolve, reject) => {
|
|
583
|
-
this.
|
|
584
|
-
this.
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
623
|
+
this._saving$.next(true);
|
|
624
|
+
this._accService.updateUser(user).subscribe({
|
|
625
|
+
next: (_) => {
|
|
626
|
+
this._saving$.next(false);
|
|
627
|
+
this._store.update(updateEntities(user.userName, user));
|
|
628
|
+
resolve(true);
|
|
629
|
+
},
|
|
630
|
+
error: (error) => {
|
|
631
|
+
this._saving$.next(false);
|
|
632
|
+
console.error(`Error updating user ${user.userName}: ` +
|
|
633
|
+
JSON.stringify(error || {}));
|
|
634
|
+
resolve(false);
|
|
635
|
+
},
|
|
596
636
|
});
|
|
597
637
|
});
|
|
598
638
|
return promise;
|
|
599
639
|
}
|
|
600
640
|
deleteUser(name) {
|
|
601
641
|
const promise = new Promise((resolve, reject) => {
|
|
602
|
-
this.
|
|
603
|
-
this.
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
642
|
+
this._saving$.next(true);
|
|
643
|
+
this._accService.deleteUser(name).subscribe({
|
|
644
|
+
next: (_) => {
|
|
645
|
+
this._saving$.next(false);
|
|
646
|
+
this.clearCache();
|
|
647
|
+
this.loadPage(1);
|
|
648
|
+
resolve(true);
|
|
649
|
+
},
|
|
650
|
+
error: (error) => {
|
|
651
|
+
this._saving$.next(false);
|
|
652
|
+
console.error(`Error deleting user ${name}: ` + JSON.stringify(error || {}));
|
|
653
|
+
reject(error);
|
|
654
|
+
},
|
|
613
655
|
});
|
|
614
656
|
});
|
|
615
657
|
return promise;
|
|
616
658
|
}
|
|
617
659
|
}
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
660
|
+
UserListRepository.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: UserListRepository, deps: [{ token: AuthJwtAccountService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
661
|
+
UserListRepository.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: UserListRepository, providedIn: 'root' });
|
|
662
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: UserListRepository, decorators: [{
|
|
621
663
|
type: Injectable,
|
|
622
664
|
args: [{ providedIn: 'root' }]
|
|
623
|
-
}], ctorParameters: function () { return [{ type:
|
|
665
|
+
}], ctorParameters: function () { return [{ type: AuthJwtAccountService }]; } });
|
|
624
666
|
|
|
625
667
|
class UserFilterComponent {
|
|
626
|
-
constructor(formBuilder,
|
|
627
|
-
this.
|
|
628
|
-
this.filter$ =
|
|
668
|
+
constructor(formBuilder, _repository) {
|
|
669
|
+
this._repository = _repository;
|
|
670
|
+
this.filter$ = _repository.filter$;
|
|
629
671
|
// form
|
|
630
672
|
this.name = formBuilder.control(null);
|
|
631
673
|
this.form = formBuilder.group({
|
|
@@ -638,7 +680,7 @@ class UserFilterComponent {
|
|
|
638
680
|
});
|
|
639
681
|
}
|
|
640
682
|
updateForm(filter) {
|
|
641
|
-
this.name.setValue(filter.name);
|
|
683
|
+
this.name.setValue(filter.name || null);
|
|
642
684
|
this.form.markAsPristine();
|
|
643
685
|
}
|
|
644
686
|
reset() {
|
|
@@ -648,8 +690,6 @@ class UserFilterComponent {
|
|
|
648
690
|
getFilter() {
|
|
649
691
|
var _a;
|
|
650
692
|
return {
|
|
651
|
-
pageNumber: 1,
|
|
652
|
-
pageSize: 20,
|
|
653
693
|
name: (_a = this.name.value) === null || _a === void 0 ? void 0 : _a.trim(),
|
|
654
694
|
};
|
|
655
695
|
}
|
|
@@ -659,27 +699,18 @@ class UserFilterComponent {
|
|
|
659
699
|
}
|
|
660
700
|
const filter = this.getFilter();
|
|
661
701
|
// update filter in state
|
|
662
|
-
this.
|
|
702
|
+
this._repository.setFilter(filter);
|
|
663
703
|
}
|
|
664
704
|
}
|
|
665
|
-
UserFilterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
666
|
-
UserFilterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
667
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
705
|
+
UserFilterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: UserFilterComponent, deps: [{ token: i1$1.FormBuilder }, { token: UserListRepository }], target: i0.ɵɵFactoryTarget.Component });
|
|
706
|
+
UserFilterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.0", type: UserFilterComponent, selector: "auth-jwt-user-filter", inputs: { disabled: "disabled" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"apply()\" ng-disabled=\"disabled\">\n <mat-form-field>\n <input matInput [formControl]=\"name\" placeholder=\"name or ID\" />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n (click)=\"reset()\"\n color=\"warn\"\n matTooltip=\"Reset filters\"\n [disabled]=\"disabled\"\n >\n <mat-icon>clear</mat-icon>\n </button>\n </mat-form-field>\n\n <button\n type=\"submit\"\n mat-icon-button\n color=\"primary\"\n [disabled]=\"disabled\"\n matTooltip=\"Apply filters\"\n >\n <mat-icon>check_circle</mat-icon>\n </button>\n</form>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i5.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i8.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]" }, { kind: "directive", type: i9$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
|
|
707
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: UserFilterComponent, decorators: [{
|
|
668
708
|
type: Component,
|
|
669
709
|
args: [{ selector: 'auth-jwt-user-filter', template: "<form [formGroup]=\"form\" (submit)=\"apply()\" ng-disabled=\"disabled\">\n <mat-form-field>\n <input matInput [formControl]=\"name\" placeholder=\"name or ID\" />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n (click)=\"reset()\"\n color=\"warn\"\n matTooltip=\"Reset filters\"\n [disabled]=\"disabled\"\n >\n <mat-icon>clear</mat-icon>\n </button>\n </mat-form-field>\n\n <button\n type=\"submit\"\n mat-icon-button\n color=\"primary\"\n [disabled]=\"disabled\"\n matTooltip=\"Apply filters\"\n >\n <mat-icon>check_circle</mat-icon>\n </button>\n</form>\n" }]
|
|
670
|
-
}], ctorParameters: function () { return [{ type: i1$1.
|
|
710
|
+
}], ctorParameters: function () { return [{ type: i1$1.FormBuilder }, { type: UserListRepository }]; }, propDecorators: { disabled: [{
|
|
671
711
|
type: Input
|
|
672
712
|
}] } });
|
|
673
713
|
|
|
674
|
-
// create a factory provider for the paginator
|
|
675
|
-
const USERS_PAGINATOR = new InjectionToken('USERS_PAGINATOR', {
|
|
676
|
-
providedIn: 'root',
|
|
677
|
-
factory: () => {
|
|
678
|
-
const query = inject(UsersQuery);
|
|
679
|
-
return new PaginatorPlugin(query).withControls().withRange();
|
|
680
|
-
},
|
|
681
|
-
});
|
|
682
|
-
|
|
683
714
|
// https://medium.com/@tarik.nzl/making-use-of-dialogs-in-material-2-mddialog-7533d27df41
|
|
684
715
|
class ConfirmDialogComponent {
|
|
685
716
|
constructor(dialogRef, data) {
|
|
@@ -692,9 +723,9 @@ class ConfirmDialogComponent {
|
|
|
692
723
|
}
|
|
693
724
|
ngOnInit() { }
|
|
694
725
|
}
|
|
695
|
-
ConfirmDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
696
|
-
ConfirmDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
697
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
726
|
+
ConfirmDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ConfirmDialogComponent, deps: [{ token: i1$2.MatDialogRef }, { token: MAT_DIALOG_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
727
|
+
ConfirmDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.0", type: ConfirmDialogComponent, selector: "ng-component", ngImport: i0, template: "<h1 mat-dialog-title>{{ title }}</h1>\r\n<mat-dialog-content>\r\n {{ prompt }}\r\n</mat-dialog-content>\r\n<mat-dialog-actions>\r\n <button\r\n type=\"button\"\r\n mat-raised-button\r\n color=\"warn\"\r\n (click)=\"dialogRef.close(true)\"\r\n >\r\n {{ ok }}\r\n </button>\r\n <button type=\"button\" mat-button (click)=\"dialogRef.close()\">\r\n {{ cancel }}\r\n </button>\r\n</mat-dialog-actions>\r\n", styles: [""], dependencies: [{ kind: "component", type: i5.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i1$2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i1$2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }] });
|
|
728
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ConfirmDialogComponent, decorators: [{
|
|
698
729
|
type: Component,
|
|
699
730
|
args: [{ template: "<h1 mat-dialog-title>{{ title }}</h1>\r\n<mat-dialog-content>\r\n {{ prompt }}\r\n</mat-dialog-content>\r\n<mat-dialog-actions>\r\n <button\r\n type=\"button\"\r\n mat-raised-button\r\n color=\"warn\"\r\n (click)=\"dialogRef.close(true)\"\r\n >\r\n {{ ok }}\r\n </button>\r\n <button type=\"button\" mat-button (click)=\"dialogRef.close()\">\r\n {{ cancel }}\r\n </button>\r\n</mat-dialog-actions>\r\n" }]
|
|
700
731
|
}], ctorParameters: function () {
|
|
@@ -730,9 +761,9 @@ class DialogService {
|
|
|
730
761
|
return dialogRef.afterClosed();
|
|
731
762
|
}
|
|
732
763
|
}
|
|
733
|
-
DialogService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
734
|
-
DialogService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
735
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
764
|
+
DialogService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: DialogService, deps: [{ token: i1$2.MatDialog }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
765
|
+
DialogService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: DialogService, providedIn: 'root' });
|
|
766
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: DialogService, decorators: [{
|
|
736
767
|
type: Injectable,
|
|
737
768
|
args: [{
|
|
738
769
|
providedIn: 'root'
|
|
@@ -828,11 +859,11 @@ class UserEditorComponent {
|
|
|
828
859
|
this.userChange.emit(this.getUserFromForm());
|
|
829
860
|
}
|
|
830
861
|
}
|
|
831
|
-
UserEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
832
|
-
UserEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
833
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
862
|
+
UserEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: UserEditorComponent, deps: [{ token: i1$1.UntypedFormBuilder }, { token: i2$2.AuthJwtService }], target: i0.ɵɵFactoryTarget.Component });
|
|
863
|
+
UserEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.0", type: UserEditorComponent, selector: "auth-jwt-user-editor", inputs: { user: "user" }, outputs: { userChange: "userChange", editorClose: "editorClose" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\n <!-- email -->\n <div>\n <mat-form-field>\n <mat-label>email</mat-label>\n <input type=\"text\" matInput [formControl]=\"email\" />\n <mat-error\n *ngIf=\"email.hasError('required') && (email.dirty || email.touched)\"\n >\n email address required\n </mat-error>\n <mat-error\n *ngIf=\"email.hasError('pattern') && (email.dirty || email.touched)\"\n >\n invalid email address\n </mat-error>\n </mat-form-field>\n </div>\n\n <!-- emailConfirmed -->\n <div>\n <mat-checkbox [formControl]=\"emailConfirmed\"\n >email address confirmed</mat-checkbox\n >\n </div>\n\n <!-- lockoutEnabled -->\n <div>\n <mat-checkbox [formControl]=\"lockoutEnabled\">lockout enabled</mat-checkbox>\n \n <button\n mat-icon-button\n color=\"primary\"\n (click)=\"endLockout()\"\n [disabled]=\"unlocked\"\n matTooltip=\"Unlock this user if locked\"\n >\n <mat-icon>lock_open</mat-icon>\n </button>\n </div>\n\n <!-- firstName -->\n <div>\n <mat-form-field>\n <mat-label>first name</mat-label>\n <input type=\"text\" matInput [formControl]=\"firstName\" />\n <mat-error\n *ngIf=\"\n firstName.hasError('required') &&\n (firstName.dirty || firstName.touched)\n \"\n >\n first name required\n </mat-error>\n <mat-error\n *ngIf=\"\n firstName.hasError('maxlength') &&\n (firstName.dirty || firstName.touched)\n \"\n >\n first name too long\n </mat-error>\n </mat-form-field>\n </div>\n\n <!-- lastName -->\n <div>\n <mat-form-field>\n <mat-label>last name</mat-label>\n <input type=\"text\" matInput [formControl]=\"lastName\" />\n <mat-error\n *ngIf=\"\n lastName.hasError('required') && (lastName.dirty || lastName.touched)\n \"\n >\n last name required\n </mat-error>\n <mat-error\n *ngIf=\"\n lastName.hasError('maxlength') && (lastName.dirty || lastName.touched)\n \"\n >\n last name too long\n </mat-error>\n </mat-form-field>\n </div>\n\n <!-- roles -->\n <div>\n <mat-form-field>\n <mat-label>roles</mat-label>\n <input type=\"text\" matInput [formControl]=\"roles\" />\n <mat-error\n *ngIf=\"roles.hasError('maxlength') && (roles.dirty || roles.touched)\"\n >\n too long\n </mat-error>\n <mat-hint>roles (separated by space)</mat-hint>\n </mat-form-field>\n </div>\n\n <!-- buttons -->\n <br />\n <div>\n <button mat-icon-button color=\"warn\" matTooltip=\"Close\" (click)=\"close()\">\n <mat-icon>cancel</mat-icon>\n </button>\n \n <button\n type=\"submit\"\n mat-icon-button\n color=\"primary\"\n [disabled]=\"form.invalid\"\n matTooltip=\"Save user data\"\n >\n <mat-icon>check_circle</mat-icon>\n </button>\n </div>\n</form>\n", styles: [""], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i5.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i5$1.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i8.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i8.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i9$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
|
|
864
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: UserEditorComponent, decorators: [{
|
|
834
865
|
type: Component,
|
|
835
|
-
args: [{ selector: 'auth-jwt-user-editor', template: "<form [formGroup]=\"form\" (submit)=\"save()\">\n <!-- email -->\n <div>\n <mat-form-field>\n <input type=\"text\" matInput [formControl]=\"email\"
|
|
866
|
+
args: [{ selector: 'auth-jwt-user-editor', template: "<form [formGroup]=\"form\" (submit)=\"save()\">\n <!-- email -->\n <div>\n <mat-form-field>\n <mat-label>email</mat-label>\n <input type=\"text\" matInput [formControl]=\"email\" />\n <mat-error\n *ngIf=\"email.hasError('required') && (email.dirty || email.touched)\"\n >\n email address required\n </mat-error>\n <mat-error\n *ngIf=\"email.hasError('pattern') && (email.dirty || email.touched)\"\n >\n invalid email address\n </mat-error>\n </mat-form-field>\n </div>\n\n <!-- emailConfirmed -->\n <div>\n <mat-checkbox [formControl]=\"emailConfirmed\"\n >email address confirmed</mat-checkbox\n >\n </div>\n\n <!-- lockoutEnabled -->\n <div>\n <mat-checkbox [formControl]=\"lockoutEnabled\">lockout enabled</mat-checkbox>\n \n <button\n mat-icon-button\n color=\"primary\"\n (click)=\"endLockout()\"\n [disabled]=\"unlocked\"\n matTooltip=\"Unlock this user if locked\"\n >\n <mat-icon>lock_open</mat-icon>\n </button>\n </div>\n\n <!-- firstName -->\n <div>\n <mat-form-field>\n <mat-label>first name</mat-label>\n <input type=\"text\" matInput [formControl]=\"firstName\" />\n <mat-error\n *ngIf=\"\n firstName.hasError('required') &&\n (firstName.dirty || firstName.touched)\n \"\n >\n first name required\n </mat-error>\n <mat-error\n *ngIf=\"\n firstName.hasError('maxlength') &&\n (firstName.dirty || firstName.touched)\n \"\n >\n first name too long\n </mat-error>\n </mat-form-field>\n </div>\n\n <!-- lastName -->\n <div>\n <mat-form-field>\n <mat-label>last name</mat-label>\n <input type=\"text\" matInput [formControl]=\"lastName\" />\n <mat-error\n *ngIf=\"\n lastName.hasError('required') && (lastName.dirty || lastName.touched)\n \"\n >\n last name required\n </mat-error>\n <mat-error\n *ngIf=\"\n lastName.hasError('maxlength') && (lastName.dirty || lastName.touched)\n \"\n >\n last name too long\n </mat-error>\n </mat-form-field>\n </div>\n\n <!-- roles -->\n <div>\n <mat-form-field>\n <mat-label>roles</mat-label>\n <input type=\"text\" matInput [formControl]=\"roles\" />\n <mat-error\n *ngIf=\"roles.hasError('maxlength') && (roles.dirty || roles.touched)\"\n >\n too long\n </mat-error>\n <mat-hint>roles (separated by space)</mat-hint>\n </mat-form-field>\n </div>\n\n <!-- buttons -->\n <br />\n <div>\n <button mat-icon-button color=\"warn\" matTooltip=\"Close\" (click)=\"close()\">\n <mat-icon>cancel</mat-icon>\n </button>\n \n <button\n type=\"submit\"\n mat-icon-button\n color=\"primary\"\n [disabled]=\"form.invalid\"\n matTooltip=\"Save user data\"\n >\n <mat-icon>check_circle</mat-icon>\n </button>\n </div>\n</form>\n" }]
|
|
836
867
|
}], ctorParameters: function () { return [{ type: i1$1.UntypedFormBuilder }, { type: i2$2.AuthJwtService }]; }, propDecorators: { user: [{
|
|
837
868
|
type: Input
|
|
838
869
|
}], userChange: [{
|
|
@@ -842,77 +873,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.2", ngImpor
|
|
|
842
873
|
}] } });
|
|
843
874
|
|
|
844
875
|
class UserListComponent {
|
|
845
|
-
constructor(
|
|
846
|
-
this.
|
|
847
|
-
this._accountService = _accountService;
|
|
848
|
-
this._usersService = _usersService;
|
|
876
|
+
constructor(_repository, _dialogService, _gravatarService) {
|
|
877
|
+
this._repository = _repository;
|
|
849
878
|
this._dialogService = _dialogService;
|
|
850
879
|
this._gravatarService = _gravatarService;
|
|
851
|
-
this.
|
|
852
|
-
this.
|
|
853
|
-
this.
|
|
854
|
-
// https://netbasal.com/manage-your-entities-with-akita-like-a-boss-768732f8d4d1
|
|
855
|
-
this.active$ = userQuery.selectActive();
|
|
856
|
-
this.pagination$ = combineLatest([
|
|
857
|
-
this.paginator.pageChanges,
|
|
858
|
-
this.pageSize.valueChanges.pipe(
|
|
859
|
-
// we are required to emit at least the initial value
|
|
860
|
-
// as combineLatest emits only if ALL observables have emitted
|
|
861
|
-
startWith(20),
|
|
862
|
-
// clear the cache when page size changes
|
|
863
|
-
tap((_) => {
|
|
864
|
-
this.paginator.clearCache();
|
|
865
|
-
})),
|
|
866
|
-
this._filter$.pipe(
|
|
867
|
-
// clear the cache when filters changed
|
|
868
|
-
tap((_) => {
|
|
869
|
-
this.paginator.clearCache();
|
|
870
|
-
})),
|
|
871
|
-
this._refresh$.pipe(
|
|
872
|
-
// clear the cache when forcing refresh
|
|
873
|
-
tap((_) => {
|
|
874
|
-
this.paginator.clearCache();
|
|
875
|
-
})),
|
|
876
|
-
]).pipe(
|
|
877
|
-
// for each emitted value, combine into a filter and use it
|
|
878
|
-
// to request the page from server
|
|
879
|
-
switchMap(([pageNumber, pageSize, filter, refresh]) => {
|
|
880
|
-
// const filter = { ...this._docsQuery.getValue().filter };
|
|
881
|
-
const f = Object.assign({}, filter);
|
|
882
|
-
f.pageNumber = pageNumber;
|
|
883
|
-
f.pageSize = pageSize;
|
|
884
|
-
const request = this.getRequest(f);
|
|
885
|
-
// update saved filters
|
|
886
|
-
this.paginator.metadata.set('filter', f);
|
|
887
|
-
return this.paginator.getPage(request);
|
|
888
|
-
}));
|
|
889
|
-
}
|
|
890
|
-
ngOnDestroy() {
|
|
891
|
-
this.paginator.destroy();
|
|
892
|
-
}
|
|
893
|
-
getRequest(filter) {
|
|
894
|
-
return () => this._accountService.getUsers(filter).pipe(
|
|
895
|
-
// adapt server results to the paginator plugin
|
|
896
|
-
map((p) => {
|
|
897
|
-
return {
|
|
898
|
-
currentPage: p.pageNumber,
|
|
899
|
-
perPage: p.pageSize,
|
|
900
|
-
lastPage: p.pageCount,
|
|
901
|
-
data: p.items,
|
|
902
|
-
total: p.total,
|
|
903
|
-
};
|
|
904
|
-
}));
|
|
880
|
+
this.pagination$ = _repository.pagination$;
|
|
881
|
+
this.active$ = _repository.activeUser$;
|
|
882
|
+
this.loading$ = _repository.loading$;
|
|
905
883
|
}
|
|
906
884
|
pageChange(event) {
|
|
907
|
-
|
|
908
|
-
this.paginator.setPage(event.pageIndex + 1);
|
|
909
|
-
if (event.pageSize !== this.pageSize.value) {
|
|
910
|
-
this.pageSize.setValue(event.pageSize);
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
refresh() {
|
|
914
|
-
this.paginator.clearCache();
|
|
915
|
-
this._refresh$.next(this._refresh$.value + 1);
|
|
885
|
+
this._repository.loadPage(event.pageIndex + 1, event.pageSize);
|
|
916
886
|
}
|
|
917
887
|
deleteUser(user) {
|
|
918
888
|
this._dialogService
|
|
@@ -922,21 +892,20 @@ class UserListComponent {
|
|
|
922
892
|
if (!yes) {
|
|
923
893
|
return;
|
|
924
894
|
}
|
|
925
|
-
this.
|
|
926
|
-
this.
|
|
895
|
+
this._repository.deleteUser(user.userName).finally(() => {
|
|
896
|
+
this._repository.clearCache();
|
|
897
|
+
this._repository.loadPage(1);
|
|
927
898
|
});
|
|
928
899
|
});
|
|
929
900
|
}
|
|
930
901
|
setActiveUser(user) {
|
|
931
|
-
this.
|
|
902
|
+
this._repository.setActive((user === null || user === void 0 ? void 0 : user.userName) || null);
|
|
932
903
|
}
|
|
933
904
|
resetActiveUser() {
|
|
934
|
-
this.
|
|
905
|
+
this._repository.setActive(null);
|
|
935
906
|
}
|
|
936
907
|
saveActiveUser(user) {
|
|
937
|
-
this.
|
|
938
|
-
this.refresh();
|
|
939
|
-
});
|
|
908
|
+
this._repository.updateActive(user);
|
|
940
909
|
}
|
|
941
910
|
onUserEditorClose() {
|
|
942
911
|
this.setActiveUser(null);
|
|
@@ -944,23 +913,21 @@ class UserListComponent {
|
|
|
944
913
|
getGravatarUrl(email, size = 80) {
|
|
945
914
|
return this._gravatarService.buildGravatarUrl(email, size);
|
|
946
915
|
}
|
|
916
|
+
clearCache() {
|
|
917
|
+
this._repository.clearCache();
|
|
918
|
+
}
|
|
947
919
|
}
|
|
948
|
-
UserListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
949
|
-
UserListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
950
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
920
|
+
UserListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: UserListComponent, deps: [{ token: UserListRepository }, { token: DialogService }, { token: i2$2.GravatarService }], target: i0.ɵɵFactoryTarget.Component });
|
|
921
|
+
UserListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.0", type: UserListComponent, selector: "auth-jwt-user-list", ngImport: i0, template: "<div\n gdAreas=\"filters | progress | list | pager | editor\"\n gdRows=\"80px 64px 2fr 40px 1fr\"\n gdColumns=\"1fr\"\n gdGap=\"8px\"\n>\n <div>\n <!-- filters -->\n <div gdArea=\"filters\">\n <auth-jwt-user-filter></auth-jwt-user-filter>\n </div>\n\n <!-- progress -->\n <div *ngIf=\"loading$ | async\" gdArea=\"progress\">\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n\n <!-- list -->\n <div gdArea=\"list\" *ngIf=\"pagination$ | async as pagination\">\n <table>\n <thead>\n <td></td>\n <td></td>\n <td></td>\n <th>name</th>\n <th>first</th>\n <th>last</th>\n <th>email</th>\n <th>roles</th>\n <th>lock end</th>\n </thead>\n <tbody>\n <tr *ngFor=\"let user of pagination.data\">\n <td class=\"command\">\n <button\n mat-icon-button\n type=\"button\"\n matTooltip=\"Edit {{ user.userName }}\"\n color=\"primary\"\n (click)=\"setActiveUser(user)\"\n >\n <mat-icon>mode_edit</mat-icon>\n </button>\n </td>\n <td class=\"command\">\n <button\n mat-icon-button\n type=\"button\"\n matTooltip=\"Delete {{ user.userName }}\"\n color=\"warn\"\n (click)=\"deleteUser(user)\"\n >\n <mat-icon>remove_circle</mat-icon>\n </button>\n </td>\n <td>\n <img\n [src]=\"getGravatarUrl(user.email, 32)\"\n [alt]=\"user.userName\"\n />\n </td>\n <td>{{ user.userName }}</td>\n <td>{{ user.firstName }}</td>\n <td>{{ user.lastName }}</td>\n <td>\n <a [href]=\"'mailto:' + user.email\">{{ user.email }}</a>\n </td>\n <td>{{ user.roles.join(\" \") }}</td>\n <td>{{ user.lockoutEnd }}</td>\n </tr>\n </tbody>\n </table>\n <!-- pagination -->\n <mat-paginator\n gdArea=\"pager\"\n gdAlignColumns=\"center\"\n gdAlignRows=\"start\"\n [length]=\"pagination.total\"\n [pageSize]=\"pagination.perPage\"\n [pageSizeOptions]=\"[20, 50, 75, 100]\"\n [pageIndex]=\"pagination.currentPage - 1\"\n [showFirstLastButtons]=\"true\"\n (page)=\"pageChange($event)\"\n ></mat-paginator>\n </div>\n </div>\n\n <!-- editor -->\n <div gdArea=\"editor\" *ngIf=\"active$ | async as active\">\n <fieldset>\n <legend>{{ active.userName }}</legend>\n <auth-jwt-user-editor\n [user]=\"active\"\n (userChange)=\"saveActiveUser($event)\"\n (editorClose)=\"resetActiveUser()\"\n ></auth-jwt-user-editor>\n </fieldset>\n </div>\n</div>\n", styles: ["tr:nth-child(odd){background-color:#f8f8f8}th{padding:0 8px;text-align:left;color:silver;font-weight:400}td{padding:0 8px}td.command{width:24px}table{width:100%;border-collapse:collapse}fieldset{border:1px solid silver;border-radius:8px;padding:16px}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i5.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i7$1.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }, { kind: "component", type: i8$1.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "directive", type: i9$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: UserFilterComponent, selector: "auth-jwt-user-filter", inputs: ["disabled"] }, { kind: "component", type: UserEditorComponent, selector: "auth-jwt-user-editor", inputs: ["user"], outputs: ["userChange", "editorClose"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }] });
|
|
922
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: UserListComponent, decorators: [{
|
|
951
923
|
type: Component,
|
|
952
|
-
args: [{ selector: 'auth-jwt-user-list', template: "<div\n gdAreas=\"filters | progress | list | pager | editor\"\n gdRows=\"80px 64px 2fr 40px 1fr\"\n gdColumns=\"1fr\"\n gdGap=\"8px\"\n>\n <div>\n <!-- filters -->\n <div gdArea=\"filters\">\n <auth-jwt-user-filter></auth-jwt-user-filter>\n </div>\n\n <!-- progress -->\n <div *ngIf=\"
|
|
953
|
-
}], ctorParameters: function () {
|
|
954
|
-
return [{ type: i15.PaginatorPlugin, decorators: [{
|
|
955
|
-
type: Inject,
|
|
956
|
-
args: [USERS_PAGINATOR]
|
|
957
|
-
}] }, { type: UsersQuery }, { type: AuthJwtAccountService }, { type: UsersService }, { type: DialogService }, { type: i2$2.GravatarService }, { type: i1$1.UntypedFormBuilder }];
|
|
958
|
-
} });
|
|
924
|
+
args: [{ selector: 'auth-jwt-user-list', template: "<div\n gdAreas=\"filters | progress | list | pager | editor\"\n gdRows=\"80px 64px 2fr 40px 1fr\"\n gdColumns=\"1fr\"\n gdGap=\"8px\"\n>\n <div>\n <!-- filters -->\n <div gdArea=\"filters\">\n <auth-jwt-user-filter></auth-jwt-user-filter>\n </div>\n\n <!-- progress -->\n <div *ngIf=\"loading$ | async\" gdArea=\"progress\">\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n\n <!-- list -->\n <div gdArea=\"list\" *ngIf=\"pagination$ | async as pagination\">\n <table>\n <thead>\n <td></td>\n <td></td>\n <td></td>\n <th>name</th>\n <th>first</th>\n <th>last</th>\n <th>email</th>\n <th>roles</th>\n <th>lock end</th>\n </thead>\n <tbody>\n <tr *ngFor=\"let user of pagination.data\">\n <td class=\"command\">\n <button\n mat-icon-button\n type=\"button\"\n matTooltip=\"Edit {{ user.userName }}\"\n color=\"primary\"\n (click)=\"setActiveUser(user)\"\n >\n <mat-icon>mode_edit</mat-icon>\n </button>\n </td>\n <td class=\"command\">\n <button\n mat-icon-button\n type=\"button\"\n matTooltip=\"Delete {{ user.userName }}\"\n color=\"warn\"\n (click)=\"deleteUser(user)\"\n >\n <mat-icon>remove_circle</mat-icon>\n </button>\n </td>\n <td>\n <img\n [src]=\"getGravatarUrl(user.email, 32)\"\n [alt]=\"user.userName\"\n />\n </td>\n <td>{{ user.userName }}</td>\n <td>{{ user.firstName }}</td>\n <td>{{ user.lastName }}</td>\n <td>\n <a [href]=\"'mailto:' + user.email\">{{ user.email }}</a>\n </td>\n <td>{{ user.roles.join(\" \") }}</td>\n <td>{{ user.lockoutEnd }}</td>\n </tr>\n </tbody>\n </table>\n <!-- pagination -->\n <mat-paginator\n gdArea=\"pager\"\n gdAlignColumns=\"center\"\n gdAlignRows=\"start\"\n [length]=\"pagination.total\"\n [pageSize]=\"pagination.perPage\"\n [pageSizeOptions]=\"[20, 50, 75, 100]\"\n [pageIndex]=\"pagination.currentPage - 1\"\n [showFirstLastButtons]=\"true\"\n (page)=\"pageChange($event)\"\n ></mat-paginator>\n </div>\n </div>\n\n <!-- editor -->\n <div gdArea=\"editor\" *ngIf=\"active$ | async as active\">\n <fieldset>\n <legend>{{ active.userName }}</legend>\n <auth-jwt-user-editor\n [user]=\"active\"\n (userChange)=\"saveActiveUser($event)\"\n (editorClose)=\"resetActiveUser()\"\n ></auth-jwt-user-editor>\n </fieldset>\n </div>\n</div>\n", styles: ["tr:nth-child(odd){background-color:#f8f8f8}th{padding:0 8px;text-align:left;color:silver;font-weight:400}td{padding:0 8px}td.command{width:24px}table{width:100%;border-collapse:collapse}fieldset{border:1px solid silver;border-radius:8px;padding:16px}\n"] }]
|
|
925
|
+
}], ctorParameters: function () { return [{ type: UserListRepository }, { type: DialogService }, { type: i2$2.GravatarService }]; } });
|
|
959
926
|
|
|
960
927
|
class AuthJwtAdminModule {
|
|
961
928
|
}
|
|
962
|
-
AuthJwtAdminModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
963
|
-
AuthJwtAdminModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
|
|
929
|
+
AuthJwtAdminModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: AuthJwtAdminModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
930
|
+
AuthJwtAdminModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.0.0", ngImport: i0, type: AuthJwtAdminModule, declarations: [AuthJwtRegistrationComponent,
|
|
964
931
|
PasswordStrengthBarComponent,
|
|
965
932
|
UserFilterComponent,
|
|
966
933
|
UserListComponent,
|
|
@@ -987,7 +954,7 @@ AuthJwtAdminModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", vers
|
|
|
987
954
|
PasswordStrengthBarComponent,
|
|
988
955
|
UserFilterComponent,
|
|
989
956
|
UserListComponent] });
|
|
990
|
-
AuthJwtAdminModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
957
|
+
AuthJwtAdminModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: AuthJwtAdminModule, imports: [CommonModule,
|
|
991
958
|
HttpClientModule,
|
|
992
959
|
FormsModule,
|
|
993
960
|
RouterModule,
|
|
@@ -1006,7 +973,7 @@ AuthJwtAdminModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", vers
|
|
|
1006
973
|
MatTooltipModule,
|
|
1007
974
|
AuthJwtLoginModule,
|
|
1008
975
|
NgToolsModule] });
|
|
1009
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
976
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: AuthJwtAdminModule, decorators: [{
|
|
1010
977
|
type: NgModule,
|
|
1011
978
|
args: [{
|
|
1012
979
|
declarations: [
|