@myrmidon/auth-jwt-admin 2.0.0 → 4.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/esm2022/lib/auth-jwt-admin.module.mjs +6 -7
- package/esm2022/lib/components/auth-jwt-registration/auth-jwt-registration.component.mjs +6 -7
- package/esm2022/lib/components/confirm-dialog/confirm-dialog.component.mjs +7 -8
- package/esm2022/lib/components/password-strength-bar/password-strength-bar.component.mjs +6 -7
- package/esm2022/lib/components/state/user-list.repository.mjs +71 -90
- package/esm2022/lib/components/user-editor/user-editor.component.mjs +6 -7
- package/esm2022/lib/components/user-filter/user-filter.component.mjs +41 -33
- package/esm2022/lib/components/user-list/user-list.component.mjs +24 -28
- package/esm2022/lib/services/auth-jwt-account.service.mjs +6 -7
- package/esm2022/lib/services/dialog.service.mjs +6 -7
- package/fesm2022/myrmidon-auth-jwt-admin.mjs +181 -191
- package/fesm2022/myrmidon-auth-jwt-admin.mjs.map +1 -1
- package/lib/components/state/user-list.repository.d.ts +16 -23
- package/lib/components/user-filter/user-filter.component.d.ts +12 -10
- package/lib/components/user-list/user-list.component.d.ts +7 -6
- package/package.json +6 -6
|
@@ -11,7 +11,7 @@ import * as i2 from '@myrmidon/ng-tools';
|
|
|
11
11
|
import { NgToolsModule } from '@myrmidon/ng-tools';
|
|
12
12
|
import * as i4 from '@angular/common';
|
|
13
13
|
import { CommonModule } from '@angular/common';
|
|
14
|
-
import * as
|
|
14
|
+
import * as i2$2 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';
|
|
@@ -20,25 +20,22 @@ import { MatInputModule } from '@angular/material/input';
|
|
|
20
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 { select, createStore, withProps } from '@ngneat/elf';
|
|
25
|
-
import { selectActiveEntity, withEntities, withActiveId, upsertEntities, deleteAllEntities, setActiveId } from '@ngneat/elf-entities';
|
|
26
|
-
import { selectPaginationData, selectCurrentPageEntities, deleteAllPages, withPagination, updatePaginationData, setPage, hasPage, setCurrentPage } from '@ngneat/elf-pagination';
|
|
27
|
-
import { selectRequestStatus, withRequestsCache, withRequestsStatus, updateRequestStatus } from '@ngneat/elf-requests';
|
|
28
|
-
import * as i7$1 from '@angular/material/tooltip';
|
|
23
|
+
import * as i6$1 from '@angular/material/tooltip';
|
|
29
24
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
30
25
|
import '@angular/localize/init';
|
|
26
|
+
import { BehaviorSubject, tap } from 'rxjs';
|
|
27
|
+
import { PagedListStore } from '@myrmidon/paged-data-browsers';
|
|
31
28
|
import * as i1$2 from '@angular/material/dialog';
|
|
32
29
|
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
|
33
|
-
import * as i2$
|
|
30
|
+
import * as i2$3 from '@myrmidon/auth-jwt-login';
|
|
34
31
|
import { AuthJwtLoginModule } from '@myrmidon/auth-jwt-login';
|
|
35
|
-
import * as i6$
|
|
32
|
+
import * as i6$2 from '@angular/material/expansion';
|
|
36
33
|
import { MatExpansionModule } from '@angular/material/expansion';
|
|
37
34
|
import * as i8$1 from '@angular/material/paginator';
|
|
38
35
|
import { MatPaginatorModule } from '@angular/material/paginator';
|
|
39
36
|
import * as i9$1 from '@angular/material/progress-bar';
|
|
40
37
|
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
|
41
|
-
import * as i5
|
|
38
|
+
import * as i5 from '@angular/material/checkbox';
|
|
42
39
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
43
40
|
import { RouterModule } from '@angular/router';
|
|
44
41
|
import { MatCardModule } from '@angular/material/card';
|
|
@@ -257,15 +254,15 @@ class AuthJwtAccountService {
|
|
|
257
254
|
.delete(this._env.get('apiUrl') + 'accounts/' + name)
|
|
258
255
|
.pipe(catchError(this._error.handleError));
|
|
259
256
|
}
|
|
260
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
261
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
257
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: AuthJwtAccountService, deps: [{ token: i1.HttpClient }, { token: i2.ErrorService }, { token: i2.EnvService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
258
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: AuthJwtAccountService, providedIn: 'root' }); }
|
|
262
259
|
}
|
|
263
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
260
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: AuthJwtAccountService, decorators: [{
|
|
264
261
|
type: Injectable,
|
|
265
262
|
args: [{
|
|
266
263
|
providedIn: 'root',
|
|
267
264
|
}]
|
|
268
|
-
}], ctorParameters:
|
|
265
|
+
}], ctorParameters: () => [{ type: i1.HttpClient }, { type: i2.ErrorService }, { type: i2.EnvService }] });
|
|
269
266
|
|
|
270
267
|
class PasswordStrengthBarComponent {
|
|
271
268
|
constructor() {
|
|
@@ -333,13 +330,13 @@ class PasswordStrengthBarComponent {
|
|
|
333
330
|
this.bars[n] = col;
|
|
334
331
|
}
|
|
335
332
|
}
|
|
336
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
337
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
333
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: PasswordStrengthBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
334
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.1", 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"] }); }
|
|
338
335
|
}
|
|
339
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
336
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: PasswordStrengthBarComponent, decorators: [{
|
|
340
337
|
type: Component,
|
|
341
338
|
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"] }]
|
|
342
|
-
}], ctorParameters:
|
|
339
|
+
}], ctorParameters: () => [], propDecorators: { passwordToCheck: [{
|
|
343
340
|
type: Input
|
|
344
341
|
}], strengthChange: [{
|
|
345
342
|
type: Output
|
|
@@ -484,113 +481,152 @@ class AuthJwtRegistrationComponent {
|
|
|
484
481
|
},
|
|
485
482
|
});
|
|
486
483
|
}
|
|
487
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
488
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.1", type: AuthJwtRegistrationComponent, selector: "auth-jwt-registration", outputs: { registered: "registered" }, ngImport: i0, template: "<div>\r\n <form role=\"form\" [formGroup]=\"form\" (submit)=\"onSubmit()\">\r\n <fieldset>\r\n <legend i18n>registration</legend>\r\n <!-- email -->\r\n <div class=\"form-row\">\r\n <mat-form-field>\r\n <mat-label i18n>email</mat-label>\r\n <input\r\n matInput\r\n type=\"email\"\r\n id=\"email\"\r\n maxlength=\"256\"\r\n required\r\n autofocus\r\n spellcheck=\"false\"\r\n [formControl]=\"email\"\r\n />\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(email).errors?.required && (email.dirty || email.touched)\r\n \"\r\n >email required</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"$any(email).errors?.email && (email.dirty || email.touched)\"\r\n >invalid email</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(email).errors?.uniqueEmail && (email.dirty || email.touched)\r\n \"\r\n >email already registered</mat-error\r\n >\r\n </mat-form-field>\r\n <mat-icon *ngIf=\"email.pending\">hourglass</mat-icon>\r\n </div>\r\n\r\n <!-- name -->\r\n <div class=\"form-row\">\r\n <mat-form-field>\r\n <mat-label i18n>username</mat-label>\r\n <input\r\n matInput\r\n type=\"text\"\r\n id=\"name\"\r\n maxlength=\"50\"\r\n required\r\n pattern=\"^[a-zA-Z][a-zA-Z0-9]{2,49}$\"\r\n spellcheck=\"false\"\r\n [formControl]=\"name\"\r\n />\r\n <mat-error\r\n i18n\r\n *ngIf=\"$any(name).errors?.required && (name.dirty || name.touched)\"\r\n >username required</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"$any(name).errors?.pattern && (name.dirty || name.touched)\"\r\n >invalid username</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(name).errors?.uniqueName && (name.dirty || name.touched)\r\n \"\r\n >username already registered</mat-error\r\n >\r\n </mat-form-field>\r\n <mat-icon *ngIf=\"name.pending\">hourglass</mat-icon>\r\n </div>\r\n\r\n <!-- first name -->\r\n <div>\r\n <mat-form-field>\r\n <mat-label i18n>first name</mat-label>\r\n <input\r\n matInput\r\n type=\"text\"\r\n id=\"firstName\"\r\n maxlength=\"50\"\r\n required\r\n spellcheck=\"false\"\r\n [formControl]=\"firstName\"\r\n />\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n firstName.hasError('required') &&\r\n (firstName.dirty || firstName.touched)\r\n \"\r\n class=\"text-danger small\"\r\n >\r\n first name required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- last name -->\r\n <div>\r\n <mat-form-field>\r\n <mat-label i18n>last name</mat-label>\r\n <input\r\n matInput\r\n type=\"text\"\r\n id=\"lastName\"\r\n maxlength=\"50\"\r\n required\r\n spellcheck=\"false\"\r\n [formControl]=\"lastName\"\r\n />\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n lastName.hasError('required') &&\r\n (lastName.dirty || lastName.touched)\r\n \"\r\n class=\"text-danger small\"\r\n >\r\n last name required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- <div [formGroup]=\"passwords\"> -->\r\n <!-- password -->\r\n <div>\r\n <mat-form-field>\r\n <mat-label i18n>password</mat-label>\r\n <input\r\n matInput\r\n type=\"password\"\r\n name=\"password\"\r\n autocomplete=\"new-password\"\r\n maxlength=\"50\"\r\n required\r\n spellcheck=\"false\"\r\n [formControl]=\"password\"\r\n />\r\n <auth-jwt-password-strength-bar [passwordToCheck]=\"password.value\">\r\n </auth-jwt-password-strength-bar>\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(password).errors?.required &&\r\n (password.dirty || password.touched)\r\n \"\r\n >password required</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(password).errors?.passwordtooshort &&\r\n (password.dirty || password.touched)\r\n \"\r\n >at least 8 characters</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(password).errors?.noupperinpassword &&\r\n (password.dirty || password.touched)\r\n \"\r\n >at least 1 uppercase letter</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(password).errors?.nolowerinpassword &&\r\n (password.dirty || password.touched)\r\n \"\r\n >at least 1 lowercase letter</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(password).errors?.nosymbolinpassword &&\r\n (password.dirty || password.touched)\r\n \"\r\n >at least 1 punctuation/symbol</mat-error\r\n >\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- confirm password -->\r\n <div>\r\n <mat-form-field>\r\n <mat-label i18n>confirm password</mat-label>\r\n <input\r\n matInput\r\n type=\"password\"\r\n name=\"confirmPassword\"\r\n maxlength=\"50\"\r\n required\r\n spellcheck=\"false\"\r\n [formControl]=\"confirmPassword\"\r\n />\r\n </mat-form-field>\r\n </div>\r\n <div\r\n i18n\r\n *ngIf=\"form.errors?.areequal && confirmPassword.touched\"\r\n style=\"color: red\"\r\n >\r\n password differs from confirmation password\r\n </div>\r\n\r\n <button i18n\r\n mat-raised-button\r\n type=\"submit\"\r\n color=\"primary\"\r\n [disabled]=\"\r\n form.invalid || form.pristine || busy || name.pending || email.pending\r\n \"\r\n >\r\n register\r\n </button>\r\n <mat-progress-spinner diameter=\"20\" *ngIf=\"busy\"></mat-progress-spinner>\r\n </fieldset>\r\n </form>\r\n\r\n <details>\r\n <summary i18n>Hints</summary>\r\n <p i18n>\r\n To register a new user, you must provide his email address, choose a\r\n password, and choose a username, which must be unique (you will be\r\n notified if another user has already taken that name). The username must\r\n include only letters/digits, start with a letter, and be no shorter than 3\r\n characters, nor longer than 50.\r\n </p>\r\n <p i18n>\r\n To promote a decent security level, the password must include at least 8\r\n characters, uppercase and lowercase letters, digits, and punctuation (like\r\n dashes, stops, parentheses, etc.).\r\n </p>\r\n <p i18n>\r\n Once registered, if messaging is enabled on the server side the user will\r\n receive an email message to the email address you specified; he will have\r\n to click on the provided link to complete the registration process.\r\n Otherwise, you should edit the newly created user and confirm the email\r\n registration.\r\n </p>\r\n </details>\r\n</div>\r\n", styles: ["mat-form-field{width:400px}fieldset{border:1px solid silver;border-radius:8px;padding:16px}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}details{margin:8px}\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.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.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.MatLabel, selector: "mat-label" }, { 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"] }] }); }
|
|
484
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: AuthJwtRegistrationComponent, deps: [{ token: i1$1.FormBuilder }, { token: i2$1.MatSnackBar }, { token: AuthJwtAccountService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
485
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.1", type: AuthJwtRegistrationComponent, selector: "auth-jwt-registration", outputs: { registered: "registered" }, ngImport: i0, template: "<div>\r\n <form role=\"form\" [formGroup]=\"form\" (submit)=\"onSubmit()\">\r\n <fieldset>\r\n <legend i18n>registration</legend>\r\n <!-- email -->\r\n <div class=\"form-row\">\r\n <mat-form-field>\r\n <mat-label i18n>email</mat-label>\r\n <input\r\n matInput\r\n type=\"email\"\r\n id=\"email\"\r\n maxlength=\"256\"\r\n required\r\n autofocus\r\n spellcheck=\"false\"\r\n [formControl]=\"email\"\r\n />\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(email).errors?.required && (email.dirty || email.touched)\r\n \"\r\n >email required</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"$any(email).errors?.email && (email.dirty || email.touched)\"\r\n >invalid email</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(email).errors?.uniqueEmail && (email.dirty || email.touched)\r\n \"\r\n >email already registered</mat-error\r\n >\r\n </mat-form-field>\r\n <mat-icon *ngIf=\"email.pending\">hourglass</mat-icon>\r\n </div>\r\n\r\n <!-- name -->\r\n <div class=\"form-row\">\r\n <mat-form-field>\r\n <mat-label i18n>username</mat-label>\r\n <input\r\n matInput\r\n type=\"text\"\r\n id=\"name\"\r\n maxlength=\"50\"\r\n required\r\n pattern=\"^[a-zA-Z][a-zA-Z0-9]{2,49}$\"\r\n spellcheck=\"false\"\r\n [formControl]=\"name\"\r\n />\r\n <mat-error\r\n i18n\r\n *ngIf=\"$any(name).errors?.required && (name.dirty || name.touched)\"\r\n >username required</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"$any(name).errors?.pattern && (name.dirty || name.touched)\"\r\n >invalid username</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(name).errors?.uniqueName && (name.dirty || name.touched)\r\n \"\r\n >username already registered</mat-error\r\n >\r\n </mat-form-field>\r\n <mat-icon *ngIf=\"name.pending\">hourglass</mat-icon>\r\n </div>\r\n\r\n <!-- first name -->\r\n <div>\r\n <mat-form-field>\r\n <mat-label i18n>first name</mat-label>\r\n <input\r\n matInput\r\n type=\"text\"\r\n id=\"firstName\"\r\n maxlength=\"50\"\r\n required\r\n spellcheck=\"false\"\r\n [formControl]=\"firstName\"\r\n />\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n firstName.hasError('required') &&\r\n (firstName.dirty || firstName.touched)\r\n \"\r\n class=\"text-danger small\"\r\n >\r\n first name required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- last name -->\r\n <div>\r\n <mat-form-field>\r\n <mat-label i18n>last name</mat-label>\r\n <input\r\n matInput\r\n type=\"text\"\r\n id=\"lastName\"\r\n maxlength=\"50\"\r\n required\r\n spellcheck=\"false\"\r\n [formControl]=\"lastName\"\r\n />\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n lastName.hasError('required') &&\r\n (lastName.dirty || lastName.touched)\r\n \"\r\n class=\"text-danger small\"\r\n >\r\n last name required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- <div [formGroup]=\"passwords\"> -->\r\n <!-- password -->\r\n <div>\r\n <mat-form-field>\r\n <mat-label i18n>password</mat-label>\r\n <input\r\n matInput\r\n type=\"password\"\r\n name=\"password\"\r\n autocomplete=\"new-password\"\r\n maxlength=\"50\"\r\n required\r\n spellcheck=\"false\"\r\n [formControl]=\"password\"\r\n />\r\n <auth-jwt-password-strength-bar [passwordToCheck]=\"password.value\">\r\n </auth-jwt-password-strength-bar>\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(password).errors?.required &&\r\n (password.dirty || password.touched)\r\n \"\r\n >password required</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(password).errors?.passwordtooshort &&\r\n (password.dirty || password.touched)\r\n \"\r\n >at least 8 characters</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(password).errors?.noupperinpassword &&\r\n (password.dirty || password.touched)\r\n \"\r\n >at least 1 uppercase letter</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(password).errors?.nolowerinpassword &&\r\n (password.dirty || password.touched)\r\n \"\r\n >at least 1 lowercase letter</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(password).errors?.nosymbolinpassword &&\r\n (password.dirty || password.touched)\r\n \"\r\n >at least 1 punctuation/symbol</mat-error\r\n >\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- confirm password -->\r\n <div>\r\n <mat-form-field>\r\n <mat-label i18n>confirm password</mat-label>\r\n <input\r\n matInput\r\n type=\"password\"\r\n name=\"confirmPassword\"\r\n maxlength=\"50\"\r\n required\r\n spellcheck=\"false\"\r\n [formControl]=\"confirmPassword\"\r\n />\r\n </mat-form-field>\r\n </div>\r\n <div\r\n i18n\r\n *ngIf=\"form.errors?.areequal && confirmPassword.touched\"\r\n style=\"color: red\"\r\n >\r\n password differs from confirmation password\r\n </div>\r\n\r\n <button i18n\r\n mat-raised-button\r\n type=\"submit\"\r\n color=\"primary\"\r\n [disabled]=\"\r\n form.invalid || form.pristine || busy || name.pending || email.pending\r\n \"\r\n >\r\n register\r\n </button>\r\n <mat-progress-spinner diameter=\"20\" *ngIf=\"busy\"></mat-progress-spinner>\r\n </fieldset>\r\n </form>\r\n\r\n <details>\r\n <summary i18n>Hints</summary>\r\n <p i18n>\r\n To register a new user, you must provide his email address, choose a\r\n password, and choose a username, which must be unique (you will be\r\n notified if another user has already taken that name). The username must\r\n include only letters/digits, start with a letter, and be no shorter than 3\r\n characters, nor longer than 50.\r\n </p>\r\n <p i18n>\r\n To promote a decent security level, the password must include at least 8\r\n characters, uppercase and lowercase letters, digits, and punctuation (like\r\n dashes, stops, parentheses, etc.).\r\n </p>\r\n <p i18n>\r\n Once registered, if messaging is enabled on the server side the user will\r\n receive an email message to the email address you specified; he will have\r\n to click on the provided link to complete the registration process.\r\n Otherwise, you should edit the newly created user and confirm the email\r\n registration.\r\n </p>\r\n </details>\r\n</div>\r\n", styles: ["mat-form-field{width:400px}fieldset{border:1px solid silver;border-radius:8px;padding:16px}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}details{margin:8px}\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.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: i2$2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", 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.MatLabel, selector: "mat-label" }, { 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"] }] }); }
|
|
489
486
|
}
|
|
490
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
487
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: AuthJwtRegistrationComponent, decorators: [{
|
|
491
488
|
type: Component,
|
|
492
489
|
args: [{ selector: 'auth-jwt-registration', template: "<div>\r\n <form role=\"form\" [formGroup]=\"form\" (submit)=\"onSubmit()\">\r\n <fieldset>\r\n <legend i18n>registration</legend>\r\n <!-- email -->\r\n <div class=\"form-row\">\r\n <mat-form-field>\r\n <mat-label i18n>email</mat-label>\r\n <input\r\n matInput\r\n type=\"email\"\r\n id=\"email\"\r\n maxlength=\"256\"\r\n required\r\n autofocus\r\n spellcheck=\"false\"\r\n [formControl]=\"email\"\r\n />\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(email).errors?.required && (email.dirty || email.touched)\r\n \"\r\n >email required</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"$any(email).errors?.email && (email.dirty || email.touched)\"\r\n >invalid email</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(email).errors?.uniqueEmail && (email.dirty || email.touched)\r\n \"\r\n >email already registered</mat-error\r\n >\r\n </mat-form-field>\r\n <mat-icon *ngIf=\"email.pending\">hourglass</mat-icon>\r\n </div>\r\n\r\n <!-- name -->\r\n <div class=\"form-row\">\r\n <mat-form-field>\r\n <mat-label i18n>username</mat-label>\r\n <input\r\n matInput\r\n type=\"text\"\r\n id=\"name\"\r\n maxlength=\"50\"\r\n required\r\n pattern=\"^[a-zA-Z][a-zA-Z0-9]{2,49}$\"\r\n spellcheck=\"false\"\r\n [formControl]=\"name\"\r\n />\r\n <mat-error\r\n i18n\r\n *ngIf=\"$any(name).errors?.required && (name.dirty || name.touched)\"\r\n >username required</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"$any(name).errors?.pattern && (name.dirty || name.touched)\"\r\n >invalid username</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(name).errors?.uniqueName && (name.dirty || name.touched)\r\n \"\r\n >username already registered</mat-error\r\n >\r\n </mat-form-field>\r\n <mat-icon *ngIf=\"name.pending\">hourglass</mat-icon>\r\n </div>\r\n\r\n <!-- first name -->\r\n <div>\r\n <mat-form-field>\r\n <mat-label i18n>first name</mat-label>\r\n <input\r\n matInput\r\n type=\"text\"\r\n id=\"firstName\"\r\n maxlength=\"50\"\r\n required\r\n spellcheck=\"false\"\r\n [formControl]=\"firstName\"\r\n />\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n firstName.hasError('required') &&\r\n (firstName.dirty || firstName.touched)\r\n \"\r\n class=\"text-danger small\"\r\n >\r\n first name required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- last name -->\r\n <div>\r\n <mat-form-field>\r\n <mat-label i18n>last name</mat-label>\r\n <input\r\n matInput\r\n type=\"text\"\r\n id=\"lastName\"\r\n maxlength=\"50\"\r\n required\r\n spellcheck=\"false\"\r\n [formControl]=\"lastName\"\r\n />\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n lastName.hasError('required') &&\r\n (lastName.dirty || lastName.touched)\r\n \"\r\n class=\"text-danger small\"\r\n >\r\n last name required\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- <div [formGroup]=\"passwords\"> -->\r\n <!-- password -->\r\n <div>\r\n <mat-form-field>\r\n <mat-label i18n>password</mat-label>\r\n <input\r\n matInput\r\n type=\"password\"\r\n name=\"password\"\r\n autocomplete=\"new-password\"\r\n maxlength=\"50\"\r\n required\r\n spellcheck=\"false\"\r\n [formControl]=\"password\"\r\n />\r\n <auth-jwt-password-strength-bar [passwordToCheck]=\"password.value\">\r\n </auth-jwt-password-strength-bar>\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(password).errors?.required &&\r\n (password.dirty || password.touched)\r\n \"\r\n >password required</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(password).errors?.passwordtooshort &&\r\n (password.dirty || password.touched)\r\n \"\r\n >at least 8 characters</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(password).errors?.noupperinpassword &&\r\n (password.dirty || password.touched)\r\n \"\r\n >at least 1 uppercase letter</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(password).errors?.nolowerinpassword &&\r\n (password.dirty || password.touched)\r\n \"\r\n >at least 1 lowercase letter</mat-error\r\n >\r\n <mat-error\r\n i18n\r\n *ngIf=\"\r\n $any(password).errors?.nosymbolinpassword &&\r\n (password.dirty || password.touched)\r\n \"\r\n >at least 1 punctuation/symbol</mat-error\r\n >\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- confirm password -->\r\n <div>\r\n <mat-form-field>\r\n <mat-label i18n>confirm password</mat-label>\r\n <input\r\n matInput\r\n type=\"password\"\r\n name=\"confirmPassword\"\r\n maxlength=\"50\"\r\n required\r\n spellcheck=\"false\"\r\n [formControl]=\"confirmPassword\"\r\n />\r\n </mat-form-field>\r\n </div>\r\n <div\r\n i18n\r\n *ngIf=\"form.errors?.areequal && confirmPassword.touched\"\r\n style=\"color: red\"\r\n >\r\n password differs from confirmation password\r\n </div>\r\n\r\n <button i18n\r\n mat-raised-button\r\n type=\"submit\"\r\n color=\"primary\"\r\n [disabled]=\"\r\n form.invalid || form.pristine || busy || name.pending || email.pending\r\n \"\r\n >\r\n register\r\n </button>\r\n <mat-progress-spinner diameter=\"20\" *ngIf=\"busy\"></mat-progress-spinner>\r\n </fieldset>\r\n </form>\r\n\r\n <details>\r\n <summary i18n>Hints</summary>\r\n <p i18n>\r\n To register a new user, you must provide his email address, choose a\r\n password, and choose a username, which must be unique (you will be\r\n notified if another user has already taken that name). The username must\r\n include only letters/digits, start with a letter, and be no shorter than 3\r\n characters, nor longer than 50.\r\n </p>\r\n <p i18n>\r\n To promote a decent security level, the password must include at least 8\r\n characters, uppercase and lowercase letters, digits, and punctuation (like\r\n dashes, stops, parentheses, etc.).\r\n </p>\r\n <p i18n>\r\n Once registered, if messaging is enabled on the server side the user will\r\n receive an email message to the email address you specified; he will have\r\n to click on the provided link to complete the registration process.\r\n Otherwise, you should edit the newly created user and confirm the email\r\n registration.\r\n </p>\r\n </details>\r\n</div>\r\n", styles: ["mat-form-field{width:400px}fieldset{border:1px solid silver;border-radius:8px;padding:16px}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}details{margin:8px}\n"] }]
|
|
493
|
-
}], ctorParameters:
|
|
490
|
+
}], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: i2$1.MatSnackBar }, { type: AuthJwtAccountService }], propDecorators: { registered: [{
|
|
491
|
+
type: Output
|
|
492
|
+
}] } });
|
|
493
|
+
|
|
494
|
+
class UserFilterComponent {
|
|
495
|
+
get filter() {
|
|
496
|
+
return this._filter;
|
|
497
|
+
}
|
|
498
|
+
set filter(value) {
|
|
499
|
+
if (this._filter === value) {
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
this._filter = value || undefined;
|
|
503
|
+
this.updateForm(this._filter);
|
|
504
|
+
}
|
|
505
|
+
constructor(formBuilder) {
|
|
506
|
+
// form
|
|
507
|
+
this.name = formBuilder.control(null);
|
|
508
|
+
this.form = formBuilder.group({
|
|
509
|
+
name: this.name,
|
|
510
|
+
});
|
|
511
|
+
// event
|
|
512
|
+
this.filterChange = new EventEmitter();
|
|
513
|
+
}
|
|
514
|
+
updateForm(filter) {
|
|
515
|
+
if (!filter) {
|
|
516
|
+
this.form.reset();
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
this.name.setValue(filter.name || null);
|
|
520
|
+
this.form.markAsPristine();
|
|
521
|
+
}
|
|
522
|
+
getFilter() {
|
|
523
|
+
return {
|
|
524
|
+
name: this.name.value?.trim(),
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
reset() {
|
|
528
|
+
this.form.reset();
|
|
529
|
+
this._filter = {};
|
|
530
|
+
this.filterChange.emit(this._filter);
|
|
531
|
+
}
|
|
532
|
+
apply() {
|
|
533
|
+
this._filter = this.getFilter();
|
|
534
|
+
this.filterChange.emit(this._filter);
|
|
535
|
+
}
|
|
536
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: UserFilterComponent, deps: [{ token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
537
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.1", type: UserFilterComponent, selector: "auth-jwt-user-filter", inputs: { filter: "filter", disabled: "disabled" }, outputs: { filterChange: "filterChange" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"apply()\" ng-disabled=\"disabled\">\n <div class=\"form-row\">\n <mat-form-field>\n <mat-label i18n>name or ID</mat-label>\n <input matInput [formControl]=\"name\" />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n (click)=\"reset()\"\n color=\"warn\"\n i18n-matTooltip\n matTooltip=\"Reset filters\"\n [disabled]=\"disabled\"\n >\n <mat-icon>clear</mat-icon>\n </button>\n </mat-form-field>\n\n <button\n id=\"apply\"\n type=\"submit\"\n mat-icon-button\n color=\"primary\"\n [disabled]=\"disabled\"\n i18n-matTooltip\n matTooltip=\"Apply filters\"\n >\n <mat-icon>check_circle</mat-icon>\n </button>\n </div>\n</form>\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}#apply{margin-top:-20px}\n"], 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: i2$2.MatIconButton, selector: "button[mat-icon-button]", 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.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i6$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
|
|
538
|
+
}
|
|
539
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: UserFilterComponent, decorators: [{
|
|
540
|
+
type: Component,
|
|
541
|
+
args: [{ selector: 'auth-jwt-user-filter', template: "<form [formGroup]=\"form\" (submit)=\"apply()\" ng-disabled=\"disabled\">\n <div class=\"form-row\">\n <mat-form-field>\n <mat-label i18n>name or ID</mat-label>\n <input matInput [formControl]=\"name\" />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n (click)=\"reset()\"\n color=\"warn\"\n i18n-matTooltip\n matTooltip=\"Reset filters\"\n [disabled]=\"disabled\"\n >\n <mat-icon>clear</mat-icon>\n </button>\n </mat-form-field>\n\n <button\n id=\"apply\"\n type=\"submit\"\n mat-icon-button\n color=\"primary\"\n [disabled]=\"disabled\"\n i18n-matTooltip\n matTooltip=\"Apply filters\"\n >\n <mat-icon>check_circle</mat-icon>\n </button>\n </div>\n</form>\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}#apply{margin-top:-20px}\n"] }]
|
|
542
|
+
}], ctorParameters: () => [{ type: i1$1.FormBuilder }], propDecorators: { filter: [{
|
|
543
|
+
type: Input
|
|
544
|
+
}], disabled: [{
|
|
545
|
+
type: Input
|
|
546
|
+
}], filterChange: [{
|
|
494
547
|
type: Output
|
|
495
548
|
}] } });
|
|
496
549
|
|
|
497
|
-
const PAGE_SIZE = 20;
|
|
498
550
|
class UserListRepository {
|
|
551
|
+
get activeUser$() {
|
|
552
|
+
return this._activeUser$.asObservable();
|
|
553
|
+
}
|
|
554
|
+
get filter$() {
|
|
555
|
+
return this._store.filter$;
|
|
556
|
+
}
|
|
557
|
+
get page$() {
|
|
558
|
+
return this._store.page$;
|
|
559
|
+
}
|
|
560
|
+
get loading$() {
|
|
561
|
+
return this._loading$.asObservable();
|
|
562
|
+
}
|
|
563
|
+
get saving$() {
|
|
564
|
+
return this._saving$.asObservable();
|
|
565
|
+
}
|
|
499
566
|
constructor(_accService) {
|
|
500
567
|
this._accService = _accService;
|
|
501
|
-
|
|
502
|
-
this.
|
|
503
|
-
this._lastPageSize = PAGE_SIZE;
|
|
568
|
+
this._store = new PagedListStore(this);
|
|
569
|
+
this._activeUser$ = new BehaviorSubject(undefined);
|
|
504
570
|
this._loading$ = new BehaviorSubject(false);
|
|
505
571
|
this._saving$ = new BehaviorSubject(false);
|
|
506
|
-
this.
|
|
507
|
-
this.saving$ = this._saving$.asObservable();
|
|
508
|
-
// combine pagination parameters with page data for our consumers
|
|
509
|
-
this.pagination$ = combineLatest([
|
|
510
|
-
this._store.pipe(selectPaginationData()),
|
|
511
|
-
this._store.pipe(selectCurrentPageEntities()),
|
|
512
|
-
]).pipe(map(([pagination, data]) => ({ ...pagination, data })), debounceTime(0));
|
|
513
|
-
// the active user, if required
|
|
514
|
-
this.activeUser$ = this._store.pipe(selectActiveEntity());
|
|
515
|
-
// the filter, if required
|
|
516
|
-
this.filter$ = this._store.pipe(select((state) => state.filter));
|
|
517
|
-
this.filter$.subscribe((filter) => {
|
|
518
|
-
// when filter changed, reset any existing page and move to page 1
|
|
519
|
-
const paginationData = this._store.getValue().pagination;
|
|
520
|
-
this._store.update(deleteAllPages());
|
|
521
|
-
// load page 1
|
|
522
|
-
this.loadPage(1, paginationData.perPage);
|
|
523
|
-
});
|
|
524
|
-
// the request status
|
|
525
|
-
this.status$ = this._store.pipe(selectRequestStatus('user-list'));
|
|
526
|
-
// load page 1 and subscribe to pagination
|
|
527
|
-
this.loadPage(1, PAGE_SIZE);
|
|
528
|
-
this.pagination$.subscribe(console.log);
|
|
529
|
-
}
|
|
530
|
-
createStore() {
|
|
531
|
-
const store = createStore({ name: 'user-list' }, withProps({
|
|
532
|
-
filter: {},
|
|
533
|
-
}), withEntities({ idKey: 'userName' }), withActiveId(), withRequestsCache(), withRequestsStatus(), withPagination());
|
|
534
|
-
return store;
|
|
535
|
-
}
|
|
536
|
-
adaptPage(page) {
|
|
537
|
-
// adapt the server page DataPage<T> to Elf pagination
|
|
538
|
-
return {
|
|
539
|
-
currentPage: page.pageNumber,
|
|
540
|
-
perPage: page.pageSize,
|
|
541
|
-
lastPage: page.pageCount,
|
|
542
|
-
total: page.total,
|
|
543
|
-
data: page.items,
|
|
544
|
-
};
|
|
572
|
+
this._store.reset();
|
|
545
573
|
}
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
this.
|
|
574
|
+
loadPage(pageNumber, pageSize, filter) {
|
|
575
|
+
this._loading$.next(true);
|
|
576
|
+
return this._accService.getUsers(filter, pageNumber, pageSize).pipe(tap({
|
|
577
|
+
next: () => this._loading$.next(false),
|
|
578
|
+
error: () => this._loading$.next(false),
|
|
579
|
+
}));
|
|
549
580
|
}
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
581
|
+
async reset() {
|
|
582
|
+
this._loading$.next(true);
|
|
583
|
+
try {
|
|
584
|
+
await this._store.reset();
|
|
553
585
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
pageSize === this._lastPageSize) {
|
|
557
|
-
console.log('Page exists: ' + pageNumber);
|
|
558
|
-
this._store.update(setCurrentPage(pageNumber));
|
|
559
|
-
return;
|
|
586
|
+
catch (error) {
|
|
587
|
+
throw error;
|
|
560
588
|
}
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
this._store.update(deleteAllPages());
|
|
564
|
-
this._lastPageSize = pageSize;
|
|
589
|
+
finally {
|
|
590
|
+
this._loading$.next(false);
|
|
565
591
|
}
|
|
566
|
-
|
|
567
|
-
|
|
592
|
+
}
|
|
593
|
+
async setFilter(filter) {
|
|
568
594
|
this._loading$.next(true);
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
595
|
+
try {
|
|
596
|
+
await this._store.setFilter(filter);
|
|
597
|
+
}
|
|
598
|
+
catch (error) {
|
|
599
|
+
throw error;
|
|
600
|
+
}
|
|
601
|
+
finally {
|
|
573
602
|
this._loading$.next(false);
|
|
574
|
-
|
|
575
|
-
this._store.update(updateRequestStatus('user-list', 'success'));
|
|
576
|
-
});
|
|
603
|
+
}
|
|
577
604
|
}
|
|
578
|
-
|
|
579
|
-
this._store.
|
|
605
|
+
getFilter() {
|
|
606
|
+
return this._store.getFilter();
|
|
580
607
|
}
|
|
581
|
-
|
|
582
|
-
this.
|
|
608
|
+
async setPage(pageNumber, pageSize) {
|
|
609
|
+
this._loading$.next(true);
|
|
610
|
+
try {
|
|
611
|
+
await this._store.setPage(pageNumber, pageSize);
|
|
612
|
+
}
|
|
613
|
+
catch (error) {
|
|
614
|
+
throw error;
|
|
615
|
+
}
|
|
616
|
+
finally {
|
|
617
|
+
this._loading$.next(false);
|
|
618
|
+
}
|
|
583
619
|
}
|
|
584
|
-
|
|
585
|
-
this.
|
|
620
|
+
setActiveUser(user) {
|
|
621
|
+
this._activeUser$.next(user || undefined);
|
|
586
622
|
}
|
|
587
|
-
|
|
623
|
+
updateActiveUser(user) {
|
|
588
624
|
const promise = new Promise((resolve, reject) => {
|
|
589
625
|
this._saving$.next(true);
|
|
590
626
|
this._accService.updateUser(user).subscribe({
|
|
591
627
|
next: (_) => {
|
|
592
628
|
this._saving$.next(false);
|
|
593
|
-
this._store.
|
|
629
|
+
this._store.reset();
|
|
594
630
|
resolve(true);
|
|
595
631
|
},
|
|
596
632
|
error: (error) => {
|
|
@@ -605,12 +641,14 @@ class UserListRepository {
|
|
|
605
641
|
}
|
|
606
642
|
deleteUser(name) {
|
|
607
643
|
const promise = new Promise((resolve, reject) => {
|
|
644
|
+
if (this._activeUser$.value?.userName === name) {
|
|
645
|
+
this._activeUser$.next(undefined);
|
|
646
|
+
}
|
|
608
647
|
this._saving$.next(true);
|
|
609
648
|
this._accService.deleteUser(name).subscribe({
|
|
610
649
|
next: (_) => {
|
|
611
650
|
this._saving$.next(false);
|
|
612
|
-
this.
|
|
613
|
-
this.loadPage(1);
|
|
651
|
+
this._store.reset();
|
|
614
652
|
resolve(true);
|
|
615
653
|
},
|
|
616
654
|
error: (error) => {
|
|
@@ -622,59 +660,13 @@ class UserListRepository {
|
|
|
622
660
|
});
|
|
623
661
|
return promise;
|
|
624
662
|
}
|
|
625
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
626
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
663
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: UserListRepository, deps: [{ token: AuthJwtAccountService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
664
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: UserListRepository, providedIn: 'root' }); }
|
|
627
665
|
}
|
|
628
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
666
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: UserListRepository, decorators: [{
|
|
629
667
|
type: Injectable,
|
|
630
668
|
args: [{ providedIn: 'root' }]
|
|
631
|
-
}], ctorParameters:
|
|
632
|
-
|
|
633
|
-
class UserFilterComponent {
|
|
634
|
-
constructor(formBuilder, _repository) {
|
|
635
|
-
this._repository = _repository;
|
|
636
|
-
this.filter$ = _repository.filter$;
|
|
637
|
-
// form
|
|
638
|
-
this.name = formBuilder.control(null);
|
|
639
|
-
this.form = formBuilder.group({
|
|
640
|
-
name: this.name,
|
|
641
|
-
});
|
|
642
|
-
}
|
|
643
|
-
ngOnInit() {
|
|
644
|
-
this.filter$.subscribe((f) => {
|
|
645
|
-
this.updateForm(f);
|
|
646
|
-
});
|
|
647
|
-
}
|
|
648
|
-
updateForm(filter) {
|
|
649
|
-
this.name.setValue(filter.name || null);
|
|
650
|
-
this.form.markAsPristine();
|
|
651
|
-
}
|
|
652
|
-
reset() {
|
|
653
|
-
this.form.reset();
|
|
654
|
-
this.apply();
|
|
655
|
-
}
|
|
656
|
-
getFilter() {
|
|
657
|
-
return {
|
|
658
|
-
name: this.name.value?.trim(),
|
|
659
|
-
};
|
|
660
|
-
}
|
|
661
|
-
apply() {
|
|
662
|
-
if (this.form.invalid) {
|
|
663
|
-
return;
|
|
664
|
-
}
|
|
665
|
-
const filter = this.getFilter();
|
|
666
|
-
// update filter in state
|
|
667
|
-
this._repository.setFilter(filter);
|
|
668
|
-
}
|
|
669
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: UserFilterComponent, deps: [{ token: i1$1.FormBuilder }, { token: UserListRepository }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
670
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.1", type: UserFilterComponent, selector: "auth-jwt-user-filter", inputs: { disabled: "disabled" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"apply()\" ng-disabled=\"disabled\">\n <div class=\"form-row\">\n <mat-form-field>\n <mat-label i18n>name or ID</mat-label>\n <input matInput [formControl]=\"name\" />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n (click)=\"reset()\"\n color=\"warn\"\n i18n-matTooltip\n matTooltip=\"Reset filters\"\n [disabled]=\"disabled\"\n >\n <mat-icon>clear</mat-icon>\n </button>\n </mat-form-field>\n\n <button\n style=\"margin-top: -20px\"\n type=\"submit\"\n mat-icon-button\n color=\"primary\"\n [disabled]=\"disabled\"\n i18n-matTooltip\n matTooltip=\"Apply filters\"\n >\n <mat-icon>check_circle</mat-icon>\n </button>\n </div>\n</form>\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"], 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.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i7$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] }); }
|
|
671
|
-
}
|
|
672
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: UserFilterComponent, decorators: [{
|
|
673
|
-
type: Component,
|
|
674
|
-
args: [{ selector: 'auth-jwt-user-filter', template: "<form [formGroup]=\"form\" (submit)=\"apply()\" ng-disabled=\"disabled\">\n <div class=\"form-row\">\n <mat-form-field>\n <mat-label i18n>name or ID</mat-label>\n <input matInput [formControl]=\"name\" />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n (click)=\"reset()\"\n color=\"warn\"\n i18n-matTooltip\n matTooltip=\"Reset filters\"\n [disabled]=\"disabled\"\n >\n <mat-icon>clear</mat-icon>\n </button>\n </mat-form-field>\n\n <button\n style=\"margin-top: -20px\"\n type=\"submit\"\n mat-icon-button\n color=\"primary\"\n [disabled]=\"disabled\"\n i18n-matTooltip\n matTooltip=\"Apply filters\"\n >\n <mat-icon>check_circle</mat-icon>\n </button>\n </div>\n</form>\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"] }]
|
|
675
|
-
}], ctorParameters: function () { return [{ type: i1$1.FormBuilder }, { type: UserListRepository }]; }, propDecorators: { disabled: [{
|
|
676
|
-
type: Input
|
|
677
|
-
}] } });
|
|
669
|
+
}], ctorParameters: () => [{ type: AuthJwtAccountService }] });
|
|
678
670
|
|
|
679
671
|
// https://medium.com/@tarik.nzl/making-use-of-dialogs-in-material-2-mddialog-7533d27df41
|
|
680
672
|
class ConfirmDialogComponent {
|
|
@@ -687,18 +679,18 @@ class ConfirmDialogComponent {
|
|
|
687
679
|
this.cancel = $localize `no`;
|
|
688
680
|
}
|
|
689
681
|
ngOnInit() { }
|
|
690
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
691
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
682
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: ConfirmDialogComponent, deps: [{ token: i1$2.MatDialogRef }, { token: MAT_DIALOG_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
683
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.1", 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: i2$2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1$2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }] }); }
|
|
692
684
|
}
|
|
693
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
685
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: ConfirmDialogComponent, decorators: [{
|
|
694
686
|
type: Component,
|
|
695
687
|
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" }]
|
|
696
|
-
}], ctorParameters:
|
|
688
|
+
}], ctorParameters: () => [{ type: i1$2.MatDialogRef }, { type: undefined, decorators: [{
|
|
697
689
|
type: Optional
|
|
698
690
|
}, {
|
|
699
691
|
type: Inject,
|
|
700
692
|
args: [MAT_DIALOG_DATA]
|
|
701
|
-
}] }]
|
|
693
|
+
}] }] });
|
|
702
694
|
|
|
703
695
|
// https://medium.com/@tarik.nzl/making-use-of-dialogs-in-material-2-mddialog-7533d27df41
|
|
704
696
|
/**
|
|
@@ -723,15 +715,15 @@ class DialogService {
|
|
|
723
715
|
dialogRef.componentInstance.cancel = cancel;
|
|
724
716
|
return dialogRef.afterClosed();
|
|
725
717
|
}
|
|
726
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
727
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
718
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: DialogService, deps: [{ token: i1$2.MatDialog }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
719
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: DialogService, providedIn: 'root' }); }
|
|
728
720
|
}
|
|
729
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
721
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: DialogService, decorators: [{
|
|
730
722
|
type: Injectable,
|
|
731
723
|
args: [{
|
|
732
724
|
providedIn: 'root'
|
|
733
725
|
}]
|
|
734
|
-
}], ctorParameters:
|
|
726
|
+
}], ctorParameters: () => [{ type: i1$2.MatDialog }] });
|
|
735
727
|
|
|
736
728
|
class UserEditorComponent {
|
|
737
729
|
set user(value) {
|
|
@@ -819,13 +811,13 @@ class UserEditorComponent {
|
|
|
819
811
|
}
|
|
820
812
|
this.userChange.emit(this.getUserFromForm());
|
|
821
813
|
}
|
|
822
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
823
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
814
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: UserEditorComponent, deps: [{ token: i1$1.UntypedFormBuilder }, { token: i2$3.AuthJwtService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
815
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.1", type: UserEditorComponent, selector: "auth-jwt-user-editor", inputs: { user: "user" }, outputs: { userChange: "userChange", editorClose: "editorClose" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\n <div class=\"form-row\">\n <!-- email -->\n <mat-form-field>\n <mat-label i18n>email</mat-label>\n <input type=\"text\" matInput [formControl]=\"email\" />\n <mat-error\n i18n\n *ngIf=\"email.hasError('required') && (email.dirty || email.touched)\"\n >\n email address required\n </mat-error>\n <mat-error\n i18n\n *ngIf=\"email.hasError('pattern') && (email.dirty || email.touched)\"\n >\n invalid email address\n </mat-error>\n </mat-form-field>\n\n <!-- emailConfirmed -->\n <mat-checkbox [formControl]=\"emailConfirmed\" i18n\n >email address confirmed</mat-checkbox\n >\n </div>\n\n <!-- lockoutEnabled -->\n <div class=\"form-row\">\n <mat-checkbox [formControl]=\"lockoutEnabled\" i18n\n >lockout enabled</mat-checkbox\n >\n <button\n mat-icon-button\n color=\"primary\"\n (click)=\"endLockout()\"\n [disabled]=\"unlocked\"\n i18n-matTooltip\n matTooltip=\"Unlock this user if locked\"\n >\n <mat-icon>lock_open</mat-icon>\n </button>\n </div>\n\n <div class=\"form-row\">\n <!-- firstName -->\n <mat-form-field>\n <mat-label i18n>first name</mat-label>\n <input type=\"text\" matInput [formControl]=\"firstName\" />\n <mat-error\n i18n\n *ngIf=\"\n firstName.hasError('required') &&\n (firstName.dirty || firstName.touched)\n \"\n >\n first name required\n </mat-error>\n <mat-error\n i18n\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\n <!-- lastName -->\n <mat-form-field>\n <mat-label i18n>last name</mat-label>\n <input type=\"text\" matInput [formControl]=\"lastName\" />\n <mat-error\n i18n\n *ngIf=\"\n lastName.hasError('required') && (lastName.dirty || lastName.touched)\n \"\n >\n last name required\n </mat-error>\n <mat-error\n i18n\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 style=\"width: 16em\">\n <mat-label i18n>roles</mat-label>\n <input type=\"text\" matInput [formControl]=\"roles\" />\n <mat-error\n i18n\n *ngIf=\"roles.hasError('maxlength') && (roles.dirty || roles.touched)\"\n >\n too long\n </mat-error>\n <mat-hint i18n>roles (separated by space)</mat-hint>\n </mat-form-field>\n </div>\n\n <!-- buttons -->\n <br />\n <div>\n <button\n type=\"button\"\n mat-icon-button\n color=\"warn\"\n i18n-matTooltip\n matTooltip=\"Close\"\n (click)=\"close()\"\n >\n <mat-icon>cancel</mat-icon>\n </button>\n <button\n type=\"submit\"\n mat-icon-button\n color=\"primary\"\n [disabled]=\"form.invalid\"\n i18n-matTooltip\n matTooltip=\"Save user\"\n >\n <mat-icon>check_circle</mat-icon>\n </button>\n </div>\n</form>\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\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.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: i2$2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], 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: i6$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
|
|
824
816
|
}
|
|
825
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
817
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: UserEditorComponent, decorators: [{
|
|
826
818
|
type: Component,
|
|
827
819
|
args: [{ selector: 'auth-jwt-user-editor', template: "<form [formGroup]=\"form\" (submit)=\"save()\">\n <div class=\"form-row\">\n <!-- email -->\n <mat-form-field>\n <mat-label i18n>email</mat-label>\n <input type=\"text\" matInput [formControl]=\"email\" />\n <mat-error\n i18n\n *ngIf=\"email.hasError('required') && (email.dirty || email.touched)\"\n >\n email address required\n </mat-error>\n <mat-error\n i18n\n *ngIf=\"email.hasError('pattern') && (email.dirty || email.touched)\"\n >\n invalid email address\n </mat-error>\n </mat-form-field>\n\n <!-- emailConfirmed -->\n <mat-checkbox [formControl]=\"emailConfirmed\" i18n\n >email address confirmed</mat-checkbox\n >\n </div>\n\n <!-- lockoutEnabled -->\n <div class=\"form-row\">\n <mat-checkbox [formControl]=\"lockoutEnabled\" i18n\n >lockout enabled</mat-checkbox\n >\n <button\n mat-icon-button\n color=\"primary\"\n (click)=\"endLockout()\"\n [disabled]=\"unlocked\"\n i18n-matTooltip\n matTooltip=\"Unlock this user if locked\"\n >\n <mat-icon>lock_open</mat-icon>\n </button>\n </div>\n\n <div class=\"form-row\">\n <!-- firstName -->\n <mat-form-field>\n <mat-label i18n>first name</mat-label>\n <input type=\"text\" matInput [formControl]=\"firstName\" />\n <mat-error\n i18n\n *ngIf=\"\n firstName.hasError('required') &&\n (firstName.dirty || firstName.touched)\n \"\n >\n first name required\n </mat-error>\n <mat-error\n i18n\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\n <!-- lastName -->\n <mat-form-field>\n <mat-label i18n>last name</mat-label>\n <input type=\"text\" matInput [formControl]=\"lastName\" />\n <mat-error\n i18n\n *ngIf=\"\n lastName.hasError('required') && (lastName.dirty || lastName.touched)\n \"\n >\n last name required\n </mat-error>\n <mat-error\n i18n\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 style=\"width: 16em\">\n <mat-label i18n>roles</mat-label>\n <input type=\"text\" matInput [formControl]=\"roles\" />\n <mat-error\n i18n\n *ngIf=\"roles.hasError('maxlength') && (roles.dirty || roles.touched)\"\n >\n too long\n </mat-error>\n <mat-hint i18n>roles (separated by space)</mat-hint>\n </mat-form-field>\n </div>\n\n <!-- buttons -->\n <br />\n <div>\n <button\n type=\"button\"\n mat-icon-button\n color=\"warn\"\n i18n-matTooltip\n matTooltip=\"Close\"\n (click)=\"close()\"\n >\n <mat-icon>cancel</mat-icon>\n </button>\n <button\n type=\"submit\"\n mat-icon-button\n color=\"primary\"\n [disabled]=\"form.invalid\"\n i18n-matTooltip\n matTooltip=\"Save user\"\n >\n <mat-icon>check_circle</mat-icon>\n </button>\n </div>\n</form>\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"] }]
|
|
828
|
-
}], ctorParameters:
|
|
820
|
+
}], ctorParameters: () => [{ type: i1$1.UntypedFormBuilder }, { type: i2$3.AuthJwtService }], propDecorators: { user: [{
|
|
829
821
|
type: Input
|
|
830
822
|
}], userChange: [{
|
|
831
823
|
type: Output
|
|
@@ -838,58 +830,56 @@ class UserListComponent {
|
|
|
838
830
|
this._repository = _repository;
|
|
839
831
|
this._dialogService = _dialogService;
|
|
840
832
|
this._gravatarService = _gravatarService;
|
|
841
|
-
this.
|
|
833
|
+
this.filter$ = _repository.filter$;
|
|
834
|
+
this.page$ = _repository.page$;
|
|
842
835
|
this.active$ = _repository.activeUser$;
|
|
843
836
|
this.loading$ = _repository.loading$;
|
|
844
837
|
}
|
|
845
|
-
|
|
846
|
-
this._repository.
|
|
838
|
+
reset() {
|
|
839
|
+
this._repository.reset();
|
|
840
|
+
}
|
|
841
|
+
onFilterChange(filter) {
|
|
842
|
+
this._repository.setFilter(filter);
|
|
843
|
+
}
|
|
844
|
+
onPageChange(event) {
|
|
845
|
+
this._repository.setPage(event.pageIndex + 1, event.pageSize);
|
|
847
846
|
}
|
|
848
847
|
deleteUser(user) {
|
|
849
848
|
this._dialogService
|
|
850
849
|
.confirm($localize `Confirm`, $localize `Delete user ${user.userName}?`)
|
|
851
|
-
.pipe(take(1))
|
|
852
850
|
.subscribe((yes) => {
|
|
853
|
-
if (
|
|
854
|
-
|
|
851
|
+
if (yes) {
|
|
852
|
+
this._repository.deleteUser(user.userName);
|
|
855
853
|
}
|
|
856
|
-
this._repository.deleteUser(user.userName).finally(() => {
|
|
857
|
-
this._repository.clearCache();
|
|
858
|
-
this._repository.loadPage(1);
|
|
859
|
-
});
|
|
860
854
|
});
|
|
861
855
|
}
|
|
862
856
|
setActiveUser(user) {
|
|
863
|
-
this._repository.
|
|
857
|
+
this._repository.setActiveUser(user);
|
|
864
858
|
}
|
|
865
859
|
resetActiveUser() {
|
|
866
|
-
this._repository.
|
|
860
|
+
this._repository.setActiveUser(null);
|
|
867
861
|
}
|
|
868
862
|
saveActiveUser(user) {
|
|
869
|
-
this._repository.
|
|
870
|
-
this._repository.
|
|
863
|
+
this._repository.updateActiveUser(user);
|
|
864
|
+
this._repository.setActiveUser(null);
|
|
871
865
|
}
|
|
872
866
|
onUserEditorClose() {
|
|
873
|
-
this._repository.
|
|
867
|
+
this._repository.setActiveUser(null);
|
|
874
868
|
}
|
|
875
869
|
getGravatarUrl(email, size = 80) {
|
|
876
870
|
return this._gravatarService.buildGravatarUrl(email, size);
|
|
877
871
|
}
|
|
878
|
-
|
|
879
|
-
this.
|
|
880
|
-
this._repository.loadPage(1);
|
|
881
|
-
}
|
|
882
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: UserListComponent, deps: [{ token: UserListRepository }, { token: DialogService }, { token: i2$2.GravatarService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
883
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.1", type: UserListComponent, selector: "auth-jwt-user-list", ngImport: i0, template: "<div id=\"container\">\n <div>\n <!-- filters -->\n <div id=\"filters\">\n <auth-jwt-user-filter></auth-jwt-user-filter>\n </div>\n\n <!-- list -->\n <div id=\"list\" *ngIf=\"pagination$ | async as pagination\">\n <div *ngIf=\"loading$ | async\" gdArea=\"progress\">\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n <table>\n <thead>\n <td></td>\n <td></td>\n <th i18n>name</th>\n <th i18n class=\"noif-lt-md\">first</th>\n <th i18n class=\"noif-lt-md\">last</th>\n <th i18n class=\"noif-lt-md\">email</th>\n <th i18n>roles</th>\n <th i18n class=\"noif-lt-md\">lock end</th>\n </thead>\n <tbody>\n <tr *ngFor=\"let user of pagination.data\">\n <td>\n <button\n mat-icon-button\n type=\"button\"\n i18n-matTooltip\n matTooltip=\"Edit this user\"\n color=\"primary\"\n (click)=\"setActiveUser(user)\"\n >\n <mat-icon>mode_edit</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n i18n-matTooltip\n matTooltip=\"Delete this user\"\n color=\"warn\"\n (click)=\"deleteUser(user)\"\n >\n <mat-icon>remove_circle</mat-icon>\n </button>\n </td>\n <td>\n <img\n alt=\"avatar\"\n [src]=\"getGravatarUrl(user.email, 32)\"\n [alt]=\"user.userName\"\n />\n </td>\n <td>{{ user.userName }}</td>\n <td class=\"noif-lt-md\">{{ user.firstName }}</td>\n <td class=\"noif-lt-md\">{{ user.lastName }}</td>\n <td class=\"noif-lt-md\">\n <a [href]=\"'mailto:' + user.email\">{{ user.email }}</a>\n </td>\n <td>{{ user.roles.join(\" \") }}</td>\n <td class=\"noif-lt-md\">{{ user.lockoutEnd }}</td>\n </tr>\n </tbody>\n </table>\n\n <!-- paginator -->\n <div id=\"paginator\" class=\"form-row\">\n <button\n type=\"button\"\n mat-icon-button\n color=\"warn\"\n i18n-matmatTooltip\n matTooltip=\"Clear items cache\"\n (click)=\"clearCache()\"\n >\n <mat-icon>autorenew</mat-icon>\n </button>\n\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 </div>\n\n <!-- editor -->\n <mat-expansion-panel\n id=\"editor\"\n [expanded]=\"active$ | async\"\n [disabled]=\"!(active$ | async)\"\n >\n <div *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 </mat-expansion-panel>\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}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}div#filters{grid-area:filters}div#list{grid-area:list}div#paginator{grid-area:paginator;justify-content:end}div#editor{grid-area:editor}div#container{display:grid;grid-template-rows:auto 1fr auto auto;grid-template-columns:1fr;grid-template-areas:\"filters\" \"list\" \"paginator\" \"editor\";gap:8px}@media only screen and (max-width: 959px){.noif-lt-md{display:none}}@media only screen and (min-width: 1920px){div#container{grid-template-rows:auto 1fr auto;grid-template-columns:1fr auto;grid-template-areas:\"filters filters\" \"list editor\" \"paginator .\"}}\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$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["disabled", "expanded", "hideToggle", "togglePosition"], outputs: ["opened", "closed", "expandedChange", "afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i8$1.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }, { kind: "component", type: i9$1.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "directive", type: i7$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" }] }); }
|
|
872
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: UserListComponent, deps: [{ token: UserListRepository }, { token: DialogService }, { token: i2$3.GravatarService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
873
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.1", type: UserListComponent, selector: "auth-jwt-user-list", ngImport: i0, template: "<div id=\"container\">\n <div>\n <!-- filters -->\n <div id=\"filters\">\n <auth-jwt-user-filter\n [filter]=\"filter$ | async\"\n (filterChange)=\"onFilterChange($event)\"\n ></auth-jwt-user-filter>\n </div>\n\n <!-- list -->\n <div id=\"list\" *ngIf=\"page$ | async as page\">\n <div *ngIf=\"loading$ | async\">\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n <table>\n <thead>\n <td></td>\n <td></td>\n <th i18n>name</th>\n <th i18n class=\"noif-lt-md\">first</th>\n <th i18n class=\"noif-lt-md\">last</th>\n <th i18n class=\"noif-lt-md\">email</th>\n <th i18n>roles</th>\n <th i18n class=\"noif-lt-md\">lock end</th>\n </thead>\n <tbody>\n <tr *ngFor=\"let user of page.items\">\n <td class=\"fit-width\">\n <button\n mat-icon-button\n type=\"button\"\n i18n-matTooltip\n matTooltip=\"Edit this user\"\n color=\"primary\"\n (click)=\"setActiveUser(user)\"\n >\n <mat-icon>mode_edit</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n i18n-matTooltip\n matTooltip=\"Delete this user\"\n color=\"warn\"\n (click)=\"deleteUser(user)\"\n >\n <mat-icon>remove_circle</mat-icon>\n </button>\n </td>\n <td class=\"fit-width\">\n <img\n alt=\"avatar\"\n [src]=\"getGravatarUrl(user.email, 32)\"\n [alt]=\"user.userName\"\n />\n </td>\n <td>{{ user.userName }}</td>\n <td class=\"noif-lt-md\">{{ user.firstName }}</td>\n <td class=\"noif-lt-md\">{{ user.lastName }}</td>\n <td class=\"noif-lt-md\">\n <a [href]=\"'mailto:' + user.email\">{{ user.email }}</a>\n </td>\n <td>{{ user.roles.join(\" \") }}</td>\n <td class=\"noif-lt-md\">{{ user.lockoutEnd }}</td>\n </tr>\n </tbody>\n </table>\n\n <!-- paginator -->\n <div class=\"form-row\">\n <button\n type=\"button\"\n mat-icon-button\n color=\"warn\"\n i18n-matmatTooltip\n matTooltip=\"Refresh list\"\n (click)=\"reset()\"\n >\n <mat-icon>autorenew</mat-icon>\n </button>\n\n <mat-paginator\n [length]=\"page.total\"\n [pageIndex]=\"page.pageNumber - 1\"\n [pageSize]=\"page.pageSize\"\n [pageSizeOptions]=\"[5, 10, 20, 50, 100]\"\n (page)=\"onPageChange($event)\"\n [showFirstLastButtons]=\"true\"\n ></mat-paginator>\n </div>\n </div>\n </div>\n\n <!-- editor -->\n <mat-expansion-panel\n id=\"editor\"\n [expanded]=\"active$ | async\"\n [disabled]=\"!(active$ | async)\"\n >\n <div *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 </mat-expansion-panel>\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.fit-width{width:1px;white-space:nowrap}table{width:100%;border-collapse:collapse}fieldset{border:1px solid silver;border-radius:8px;padding:16px}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}div#filters{grid-area:filters}div#list{grid-area:list}div#editor{grid-area:editor}div#container{display:grid;grid-template-rows:auto 1fr auto;grid-template-columns:1fr;grid-template-areas:\"filters\" \"list\" \"editor\";gap:8px}@media only screen and (max-width: 959px){.noif-lt-md{display:none}}@media only screen and (min-width: 1920px){div#container{grid-template-rows:auto 1fr;grid-template-columns:1fr auto;grid-template-areas:\"filters filters\" \"list editor\"}}\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: i2$2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i6$2.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["disabled", "expanded", "hideToggle", "togglePosition"], outputs: ["opened", "closed", "expandedChange", "afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i8$1.MatPaginator, selector: "mat-paginator", inputs: ["disabled", "color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "component", type: i9$1.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "directive", type: i6$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: UserFilterComponent, selector: "auth-jwt-user-filter", inputs: ["filter", "disabled"], outputs: ["filterChange"] }, { kind: "component", type: UserEditorComponent, selector: "auth-jwt-user-editor", inputs: ["user"], outputs: ["userChange", "editorClose"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }] }); }
|
|
884
874
|
}
|
|
885
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
875
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: UserListComponent, decorators: [{
|
|
886
876
|
type: Component,
|
|
887
|
-
args: [{ selector: 'auth-jwt-user-list', template: "<div id=\"container\">\n <div>\n <!-- filters -->\n <div id=\"filters\">\n <auth-jwt-user-filter></auth-jwt-user-filter>\n </div>\n\n <!-- list -->\n <div id=\"list\" *ngIf=\"
|
|
888
|
-
}], ctorParameters:
|
|
877
|
+
args: [{ selector: 'auth-jwt-user-list', template: "<div id=\"container\">\n <div>\n <!-- filters -->\n <div id=\"filters\">\n <auth-jwt-user-filter\n [filter]=\"filter$ | async\"\n (filterChange)=\"onFilterChange($event)\"\n ></auth-jwt-user-filter>\n </div>\n\n <!-- list -->\n <div id=\"list\" *ngIf=\"page$ | async as page\">\n <div *ngIf=\"loading$ | async\">\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n <table>\n <thead>\n <td></td>\n <td></td>\n <th i18n>name</th>\n <th i18n class=\"noif-lt-md\">first</th>\n <th i18n class=\"noif-lt-md\">last</th>\n <th i18n class=\"noif-lt-md\">email</th>\n <th i18n>roles</th>\n <th i18n class=\"noif-lt-md\">lock end</th>\n </thead>\n <tbody>\n <tr *ngFor=\"let user of page.items\">\n <td class=\"fit-width\">\n <button\n mat-icon-button\n type=\"button\"\n i18n-matTooltip\n matTooltip=\"Edit this user\"\n color=\"primary\"\n (click)=\"setActiveUser(user)\"\n >\n <mat-icon>mode_edit</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n i18n-matTooltip\n matTooltip=\"Delete this user\"\n color=\"warn\"\n (click)=\"deleteUser(user)\"\n >\n <mat-icon>remove_circle</mat-icon>\n </button>\n </td>\n <td class=\"fit-width\">\n <img\n alt=\"avatar\"\n [src]=\"getGravatarUrl(user.email, 32)\"\n [alt]=\"user.userName\"\n />\n </td>\n <td>{{ user.userName }}</td>\n <td class=\"noif-lt-md\">{{ user.firstName }}</td>\n <td class=\"noif-lt-md\">{{ user.lastName }}</td>\n <td class=\"noif-lt-md\">\n <a [href]=\"'mailto:' + user.email\">{{ user.email }}</a>\n </td>\n <td>{{ user.roles.join(\" \") }}</td>\n <td class=\"noif-lt-md\">{{ user.lockoutEnd }}</td>\n </tr>\n </tbody>\n </table>\n\n <!-- paginator -->\n <div class=\"form-row\">\n <button\n type=\"button\"\n mat-icon-button\n color=\"warn\"\n i18n-matmatTooltip\n matTooltip=\"Refresh list\"\n (click)=\"reset()\"\n >\n <mat-icon>autorenew</mat-icon>\n </button>\n\n <mat-paginator\n [length]=\"page.total\"\n [pageIndex]=\"page.pageNumber - 1\"\n [pageSize]=\"page.pageSize\"\n [pageSizeOptions]=\"[5, 10, 20, 50, 100]\"\n (page)=\"onPageChange($event)\"\n [showFirstLastButtons]=\"true\"\n ></mat-paginator>\n </div>\n </div>\n </div>\n\n <!-- editor -->\n <mat-expansion-panel\n id=\"editor\"\n [expanded]=\"active$ | async\"\n [disabled]=\"!(active$ | async)\"\n >\n <div *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 </mat-expansion-panel>\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.fit-width{width:1px;white-space:nowrap}table{width:100%;border-collapse:collapse}fieldset{border:1px solid silver;border-radius:8px;padding:16px}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}div#filters{grid-area:filters}div#list{grid-area:list}div#editor{grid-area:editor}div#container{display:grid;grid-template-rows:auto 1fr auto;grid-template-columns:1fr;grid-template-areas:\"filters\" \"list\" \"editor\";gap:8px}@media only screen and (max-width: 959px){.noif-lt-md{display:none}}@media only screen and (min-width: 1920px){div#container{grid-template-rows:auto 1fr;grid-template-columns:1fr auto;grid-template-areas:\"filters filters\" \"list editor\"}}\n"] }]
|
|
878
|
+
}], ctorParameters: () => [{ type: UserListRepository }, { type: DialogService }, { type: i2$3.GravatarService }] });
|
|
889
879
|
|
|
890
880
|
class AuthJwtAdminModule {
|
|
891
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
892
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
|
|
881
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: AuthJwtAdminModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
882
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.1", ngImport: i0, type: AuthJwtAdminModule, declarations: [AuthJwtRegistrationComponent,
|
|
893
883
|
PasswordStrengthBarComponent,
|
|
894
884
|
UserFilterComponent,
|
|
895
885
|
UserListComponent,
|
|
@@ -917,7 +907,7 @@ class AuthJwtAdminModule {
|
|
|
917
907
|
PasswordStrengthBarComponent,
|
|
918
908
|
UserFilterComponent,
|
|
919
909
|
UserListComponent] }); }
|
|
920
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
910
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: AuthJwtAdminModule, imports: [CommonModule,
|
|
921
911
|
HttpClientModule,
|
|
922
912
|
FormsModule,
|
|
923
913
|
RouterModule,
|
|
@@ -938,7 +928,7 @@ class AuthJwtAdminModule {
|
|
|
938
928
|
AuthJwtLoginModule,
|
|
939
929
|
NgToolsModule] }); }
|
|
940
930
|
}
|
|
941
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
931
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: AuthJwtAdminModule, decorators: [{
|
|
942
932
|
type: NgModule,
|
|
943
933
|
args: [{
|
|
944
934
|
declarations: [
|