@myrmidon/auth-jwt-admin 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/lib/auth-jwt-admin.module.mjs +15 -11
- package/esm2020/lib/components/auth-jwt-registration/auth-jwt-registration.component.mjs +3 -3
- 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 +11 -14
- package/esm2020/lib/components/user-editor/user-editor.component.mjs +5 -5
- package/esm2020/lib/components/user-filter/user-filter.component.mjs +5 -5
- package/esm2020/lib/components/user-list/user-list.component.mjs +15 -12
- package/esm2020/lib/services/auth-jwt-account.service.mjs +13 -19
- package/esm2020/lib/services/dialog.service.mjs +3 -3
- package/fesm2015/myrmidon-auth-jwt-admin.mjs +62 -64
- package/fesm2015/myrmidon-auth-jwt-admin.mjs.map +1 -1
- package/fesm2020/myrmidon-auth-jwt-admin.mjs +62 -64
- package/fesm2020/myrmidon-auth-jwt-admin.mjs.map +1 -1
- package/lib/auth-jwt-admin.module.d.ts +11 -10
- package/lib/components/state/user-list.repository.d.ts +1 -1
- package/lib/services/auth-jwt-account.service.d.ts +3 -1
- package/package.json +2 -2
|
@@ -22,23 +22,25 @@ import * as i9 from '@angular/material/progress-spinner';
|
|
|
22
22
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
23
23
|
import { BehaviorSubject, combineLatest, map, debounceTime, take as take$1 } from 'rxjs';
|
|
24
24
|
import { select, createStore, withProps } from '@ngneat/elf';
|
|
25
|
-
import { selectActiveEntity, withEntities, withActiveId, upsertEntities, deleteAllEntities, setActiveId
|
|
25
|
+
import { selectActiveEntity, withEntities, withActiveId, upsertEntities, deleteAllEntities, setActiveId } from '@ngneat/elf-entities';
|
|
26
26
|
import { selectPaginationData, selectCurrentPageEntities, deleteAllPages, withPagination, updatePaginationData, setPage, hasPage, setCurrentPage } from '@ngneat/elf-pagination';
|
|
27
27
|
import { selectRequestStatus, withRequestsCache, withRequestsStatus, updateRequestStatus } from '@ngneat/elf-requests';
|
|
28
|
-
import * as
|
|
28
|
+
import * as i7$1 from '@angular/material/tooltip';
|
|
29
29
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
30
30
|
import * as i1$2 from '@angular/material/dialog';
|
|
31
31
|
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
|
32
32
|
import * as i2$2 from '@myrmidon/auth-jwt-login';
|
|
33
33
|
import { AuthJwtLoginModule } from '@myrmidon/auth-jwt-login';
|
|
34
|
-
import * as
|
|
34
|
+
import * as i6$1 from '@angular/material/expansion';
|
|
35
|
+
import { MatExpansionModule } from '@angular/material/expansion';
|
|
36
|
+
import * as i8$1 from '@angular/material/paginator';
|
|
35
37
|
import { MatPaginatorModule } from '@angular/material/paginator';
|
|
36
|
-
import * as
|
|
38
|
+
import * as i9$1 from '@angular/material/progress-bar';
|
|
37
39
|
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
|
38
40
|
import * as i5$1 from '@angular/material/checkbox';
|
|
39
41
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
40
|
-
import { MatCardModule } from '@angular/material/card';
|
|
41
42
|
import { RouterModule } from '@angular/router';
|
|
43
|
+
import { MatCardModule } from '@angular/material/card';
|
|
42
44
|
|
|
43
45
|
class PasswordValidators {
|
|
44
46
|
/** "Standard" password validator for my API services. */
|
|
@@ -108,27 +110,19 @@ class AuthJwtAccountService {
|
|
|
108
110
|
/**
|
|
109
111
|
* Register the user with the specified registration data.
|
|
110
112
|
* @param registration The registration data.
|
|
113
|
+
* @param confirmed True to automatically confirm the user's email address
|
|
114
|
+
* without sending the confirmation email message.
|
|
111
115
|
*/
|
|
112
|
-
register(registration) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
// }),
|
|
117
|
-
// };
|
|
118
|
-
return this._http.post(this._env.get('apiUrl') + 'accounts/register', registration
|
|
119
|
-
// options
|
|
120
|
-
);
|
|
116
|
+
register(registration, confirmed = false) {
|
|
117
|
+
return this._http.post(this._env.get('apiUrl') +
|
|
118
|
+
'accounts/register' +
|
|
119
|
+
(confirmed ? '?confirmed=true' : ''), registration);
|
|
121
120
|
}
|
|
122
121
|
/**
|
|
123
122
|
* Resend the confirmation email to the specified address.
|
|
124
123
|
* @param email address.
|
|
125
124
|
*/
|
|
126
125
|
resendConfirmEmail(email) {
|
|
127
|
-
// const options = {
|
|
128
|
-
// headers: this.createAuthHeaders({
|
|
129
|
-
// 'Content-Type': 'application/json',
|
|
130
|
-
// }),
|
|
131
|
-
// };
|
|
132
126
|
return this._http.get(this._env.get('apiUrl') +
|
|
133
127
|
'accounts/resendconfirm/' +
|
|
134
128
|
encodeURIComponent(email)
|
|
@@ -216,7 +210,9 @@ class AuthJwtAccountService {
|
|
|
216
210
|
*/
|
|
217
211
|
updateUser(user) {
|
|
218
212
|
return this._http
|
|
219
|
-
.put(this._env.get('apiUrl') +
|
|
213
|
+
.put(this._env.get('apiUrl') +
|
|
214
|
+
'users' +
|
|
215
|
+
(user.emailConfirmed ? '?confirmed=true' : ''), user)
|
|
220
216
|
.pipe(catchError(this._error.handleError));
|
|
221
217
|
}
|
|
222
218
|
/**
|
|
@@ -249,9 +245,9 @@ class AuthJwtAccountService {
|
|
|
249
245
|
.pipe(catchError(this._error.handleError));
|
|
250
246
|
}
|
|
251
247
|
}
|
|
252
|
-
AuthJwtAccountService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
253
|
-
AuthJwtAccountService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.
|
|
254
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
248
|
+
AuthJwtAccountService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: AuthJwtAccountService, deps: [{ token: i1.HttpClient }, { token: i2.ErrorService }, { token: i2.EnvService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
249
|
+
AuthJwtAccountService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: AuthJwtAccountService, providedIn: 'root' });
|
|
250
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: AuthJwtAccountService, decorators: [{
|
|
255
251
|
type: Injectable,
|
|
256
252
|
args: [{
|
|
257
253
|
providedIn: 'root',
|
|
@@ -325,9 +321,9 @@ class PasswordStrengthBarComponent {
|
|
|
325
321
|
}
|
|
326
322
|
}
|
|
327
323
|
}
|
|
328
|
-
PasswordStrengthBarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
329
|
-
PasswordStrengthBarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.
|
|
330
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
324
|
+
PasswordStrengthBarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: PasswordStrengthBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
325
|
+
PasswordStrengthBarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.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"] });
|
|
326
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: PasswordStrengthBarComponent, decorators: [{
|
|
331
327
|
type: Component,
|
|
332
328
|
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"] }]
|
|
333
329
|
}], ctorParameters: function () { return []; }, propDecorators: { passwordToCheck: [{
|
|
@@ -515,9 +511,9 @@ class AuthJwtRegistrationComponent {
|
|
|
515
511
|
});
|
|
516
512
|
}
|
|
517
513
|
}
|
|
518
|
-
AuthJwtRegistrationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
519
|
-
AuthJwtRegistrationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.
|
|
520
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
514
|
+
AuthJwtRegistrationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: AuthJwtRegistrationComponent, deps: [{ token: i1$1.UntypedFormBuilder }, { token: i2$1.MatSnackBar }, { token: AuthJwtAccountService }], target: i0.ɵɵFactoryTarget.Component });
|
|
515
|
+
AuthJwtRegistrationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.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"] }] });
|
|
516
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: AuthJwtRegistrationComponent, decorators: [{
|
|
521
517
|
type: Component,
|
|
522
518
|
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"] }]
|
|
523
519
|
}], ctorParameters: function () { return [{ type: i1$1.UntypedFormBuilder }, { type: i2$1.MatSnackBar }, { type: AuthJwtAccountService }]; }, propDecorators: { registered: [{
|
|
@@ -540,20 +536,19 @@ class UserListRepository {
|
|
|
540
536
|
this._store.pipe(selectPaginationData()),
|
|
541
537
|
this._store.pipe(selectCurrentPageEntities()),
|
|
542
538
|
]).pipe(map(([pagination, data]) => ({ ...pagination, data })), debounceTime(0));
|
|
543
|
-
// the active
|
|
539
|
+
// the active user, if required
|
|
544
540
|
this.activeUser$ = this._store.pipe(selectActiveEntity());
|
|
545
541
|
// the filter, if required
|
|
546
542
|
this.filter$ = this._store.pipe(select((state) => state.filter));
|
|
547
543
|
this.filter$.subscribe((filter) => {
|
|
548
544
|
// when filter changed, reset any existing page and move to page 1
|
|
549
545
|
const paginationData = this._store.getValue().pagination;
|
|
550
|
-
console.log('Deleting all pages');
|
|
551
546
|
this._store.update(deleteAllPages());
|
|
552
547
|
// load page 1
|
|
553
548
|
this.loadPage(1, paginationData.perPage);
|
|
554
549
|
});
|
|
555
550
|
// the request status
|
|
556
|
-
this.status$ = this._store.pipe(selectRequestStatus('
|
|
551
|
+
this.status$ = this._store.pipe(selectRequestStatus('user-list'));
|
|
557
552
|
// load page 1 and subscribe to pagination
|
|
558
553
|
this.loadPage(1, PAGE_SIZE);
|
|
559
554
|
this.pagination$.subscribe(console.log);
|
|
@@ -576,9 +571,7 @@ class UserListRepository {
|
|
|
576
571
|
}
|
|
577
572
|
addPage(response) {
|
|
578
573
|
const { data, ...paginationData } = response;
|
|
579
|
-
this._store.update(upsertEntities(data),
|
|
580
|
-
// addEntities(data),
|
|
581
|
-
updatePaginationData(paginationData), setPage(paginationData.currentPage, data.map((c) => c.userName)));
|
|
574
|
+
this._store.update(upsertEntities(data), updatePaginationData(paginationData), setPage(paginationData.currentPage, data.map((c) => c.userName)));
|
|
582
575
|
}
|
|
583
576
|
loadPage(pageNumber, pageSize) {
|
|
584
577
|
if (!pageSize) {
|
|
@@ -597,7 +590,7 @@ class UserListRepository {
|
|
|
597
590
|
this._lastPageSize = pageSize;
|
|
598
591
|
}
|
|
599
592
|
// load page from server
|
|
600
|
-
this._store.update(updateRequestStatus('
|
|
593
|
+
this._store.update(updateRequestStatus('user-list', 'pending'));
|
|
601
594
|
this._loading$.next(true);
|
|
602
595
|
this._accService
|
|
603
596
|
.getUsers(this._store.getValue().filter, pageNumber, pageSize)
|
|
@@ -605,7 +598,7 @@ class UserListRepository {
|
|
|
605
598
|
.subscribe((page) => {
|
|
606
599
|
this._loading$.next(false);
|
|
607
600
|
this.addPage({ ...this.adaptPage(page), data: page.items });
|
|
608
|
-
this._store.update(updateRequestStatus('
|
|
601
|
+
this._store.update(updateRequestStatus('user-list', 'success'));
|
|
609
602
|
});
|
|
610
603
|
}
|
|
611
604
|
setFilter(filter) {
|
|
@@ -623,7 +616,7 @@ class UserListRepository {
|
|
|
623
616
|
this._accService.updateUser(user).subscribe({
|
|
624
617
|
next: (_) => {
|
|
625
618
|
this._saving$.next(false);
|
|
626
|
-
this._store.update(
|
|
619
|
+
this._store.update(upsertEntities(user));
|
|
627
620
|
resolve(true);
|
|
628
621
|
},
|
|
629
622
|
error: (error) => {
|
|
@@ -656,9 +649,9 @@ class UserListRepository {
|
|
|
656
649
|
return promise;
|
|
657
650
|
}
|
|
658
651
|
}
|
|
659
|
-
UserListRepository.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
660
|
-
UserListRepository.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.
|
|
661
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
652
|
+
UserListRepository.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: UserListRepository, deps: [{ token: AuthJwtAccountService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
653
|
+
UserListRepository.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: UserListRepository, providedIn: 'root' });
|
|
654
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: UserListRepository, decorators: [{
|
|
662
655
|
type: Injectable,
|
|
663
656
|
args: [{ providedIn: 'root' }]
|
|
664
657
|
}], ctorParameters: function () { return [{ type: AuthJwtAccountService }]; } });
|
|
@@ -700,11 +693,11 @@ class UserFilterComponent {
|
|
|
700
693
|
this._repository.setFilter(filter);
|
|
701
694
|
}
|
|
702
695
|
}
|
|
703
|
-
UserFilterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
704
|
-
UserFilterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.
|
|
705
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
696
|
+
UserFilterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: UserFilterComponent, deps: [{ token: i1$1.FormBuilder }, { token: UserListRepository }], target: i0.ɵɵFactoryTarget.Component });
|
|
697
|
+
UserFilterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.0", 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 <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 style=\"margin-top: -20px\"\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 </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.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i7$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
|
|
698
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: UserFilterComponent, decorators: [{
|
|
706
699
|
type: Component,
|
|
707
|
-
args: [{ selector: 'auth-jwt-user-filter', template: "<form [formGroup]=\"form\" (submit)=\"apply()\" ng-disabled=\"disabled\">\n <mat-form-field>\n
|
|
700
|
+
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 <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 style=\"margin-top: -20px\"\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 </div>\n</form>\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"] }]
|
|
708
701
|
}], ctorParameters: function () { return [{ type: i1$1.FormBuilder }, { type: UserListRepository }]; }, propDecorators: { disabled: [{
|
|
709
702
|
type: Input
|
|
710
703
|
}] } });
|
|
@@ -721,9 +714,9 @@ class ConfirmDialogComponent {
|
|
|
721
714
|
}
|
|
722
715
|
ngOnInit() { }
|
|
723
716
|
}
|
|
724
|
-
ConfirmDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
725
|
-
ConfirmDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.
|
|
726
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
717
|
+
ConfirmDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: ConfirmDialogComponent, deps: [{ token: i1$2.MatDialogRef }, { token: MAT_DIALOG_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
718
|
+
ConfirmDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.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"] }] });
|
|
719
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: ConfirmDialogComponent, decorators: [{
|
|
727
720
|
type: Component,
|
|
728
721
|
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" }]
|
|
729
722
|
}], ctorParameters: function () { return [{ type: i1$2.MatDialogRef }, { type: undefined, decorators: [{
|
|
@@ -757,9 +750,9 @@ class DialogService {
|
|
|
757
750
|
return dialogRef.afterClosed();
|
|
758
751
|
}
|
|
759
752
|
}
|
|
760
|
-
DialogService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
761
|
-
DialogService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.
|
|
762
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
753
|
+
DialogService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: DialogService, deps: [{ token: i1$2.MatDialog }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
754
|
+
DialogService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: DialogService, providedIn: 'root' });
|
|
755
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: DialogService, decorators: [{
|
|
763
756
|
type: Injectable,
|
|
764
757
|
args: [{
|
|
765
758
|
providedIn: 'root'
|
|
@@ -853,11 +846,11 @@ class UserEditorComponent {
|
|
|
853
846
|
this.userChange.emit(this.getUserFromForm());
|
|
854
847
|
}
|
|
855
848
|
}
|
|
856
|
-
UserEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
857
|
-
UserEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.
|
|
858
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
849
|
+
UserEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: UserEditorComponent, deps: [{ token: i1$1.UntypedFormBuilder }, { token: i2$2.AuthJwtService }], target: i0.ɵɵFactoryTarget.Component });
|
|
850
|
+
UserEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.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 <div class=\"form-row\">\n <!-- email -->\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\n <!-- emailConfirmed -->\n <mat-checkbox [formControl]=\"emailConfirmed\"\n >email address confirmed</mat-checkbox\n >\n </div>\n\n <!-- lockoutEnabled -->\n <div class=\"form-row\">\n <mat-checkbox [formControl]=\"lockoutEnabled\">lockout enabled</mat-checkbox>\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 <div class=\"form-row\">\n <!-- firstName -->\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\n <!-- lastName -->\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 style=\"width: 16em\">\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 <button\n type=\"submit\"\n mat-icon-button\n color=\"primary\"\n [disabled]=\"form.invalid\"\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: 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: i7$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
|
|
851
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: UserEditorComponent, decorators: [{
|
|
859
852
|
type: Component,
|
|
860
|
-
args: [{ selector: 'auth-jwt-user-editor', template: "<form [formGroup]=\"form\" (submit)=\"save()\">\n <!-- email -->\n
|
|
853
|
+
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>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\n <!-- emailConfirmed -->\n <mat-checkbox [formControl]=\"emailConfirmed\"\n >email address confirmed</mat-checkbox\n >\n </div>\n\n <!-- lockoutEnabled -->\n <div class=\"form-row\">\n <mat-checkbox [formControl]=\"lockoutEnabled\">lockout enabled</mat-checkbox>\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 <div class=\"form-row\">\n <!-- firstName -->\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\n <!-- lastName -->\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 style=\"width: 16em\">\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 <button\n type=\"submit\"\n mat-icon-button\n color=\"primary\"\n [disabled]=\"form.invalid\"\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"] }]
|
|
861
854
|
}], ctorParameters: function () { return [{ type: i1$1.UntypedFormBuilder }, { type: i2$2.AuthJwtService }]; }, propDecorators: { user: [{
|
|
862
855
|
type: Input
|
|
863
856
|
}], userChange: [{
|
|
@@ -900,28 +893,30 @@ class UserListComponent {
|
|
|
900
893
|
}
|
|
901
894
|
saveActiveUser(user) {
|
|
902
895
|
this._repository.updateActive(user);
|
|
896
|
+
this._repository.setActive(null);
|
|
903
897
|
}
|
|
904
898
|
onUserEditorClose() {
|
|
905
|
-
this.
|
|
899
|
+
this._repository.setActive(null);
|
|
906
900
|
}
|
|
907
901
|
getGravatarUrl(email, size = 80) {
|
|
908
902
|
return this._gravatarService.buildGravatarUrl(email, size);
|
|
909
903
|
}
|
|
910
904
|
clearCache() {
|
|
911
905
|
this._repository.clearCache();
|
|
906
|
+
this._repository.loadPage(1);
|
|
912
907
|
}
|
|
913
908
|
}
|
|
914
|
-
UserListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
915
|
-
UserListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.
|
|
916
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
909
|
+
UserListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: UserListComponent, deps: [{ token: UserListRepository }, { token: DialogService }, { token: i2$2.GravatarService }], target: i0.ɵɵFactoryTarget.Component });
|
|
910
|
+
UserListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.0", type: UserListComponent, selector: "auth-jwt-user-list", ngImport: i0, template: "<div id=\"container\">\n <div>\n <!-- filters -->\n <div style=\"grid-area: filters\">\n <auth-jwt-user-filter></auth-jwt-user-filter>\n </div>\n\n <!-- list -->\n <div style=\"grid-area: 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>name</th>\n <th class=\"noif-lt-md\">first</th>\n <th class=\"noif-lt-md\">last</th>\n <th class=\"noif-lt-md\">email</th>\n <th>roles</th>\n <th 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 matTooltip=\"Edit {{ user.userName }}\"\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 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 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 style=\"grid-area: paginator; justify-content: end\" class=\"form-row\">\n <button\n type=\"button\"\n mat-icon-button\n color=\"warn\"\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 style=\"grid-area: 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#container{display:grid;grid-template-rows:auto 1fr auto auto;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));grid-template-areas:\"filters\" \"list\" \"paginator\" \"editor\";gap:8px}@media only screen and (max-width: 959px){.noif-lt-md{display:none}}\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" }] });
|
|
911
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: UserListComponent, decorators: [{
|
|
917
912
|
type: Component,
|
|
918
|
-
args: [{ selector: 'auth-jwt-user-list', template: "<div
|
|
913
|
+
args: [{ selector: 'auth-jwt-user-list', template: "<div id=\"container\">\n <div>\n <!-- filters -->\n <div style=\"grid-area: filters\">\n <auth-jwt-user-filter></auth-jwt-user-filter>\n </div>\n\n <!-- list -->\n <div style=\"grid-area: 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>name</th>\n <th class=\"noif-lt-md\">first</th>\n <th class=\"noif-lt-md\">last</th>\n <th class=\"noif-lt-md\">email</th>\n <th>roles</th>\n <th 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 matTooltip=\"Edit {{ user.userName }}\"\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 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 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 style=\"grid-area: paginator; justify-content: end\" class=\"form-row\">\n <button\n type=\"button\"\n mat-icon-button\n color=\"warn\"\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 style=\"grid-area: 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#container{display:grid;grid-template-rows:auto 1fr auto auto;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));grid-template-areas:\"filters\" \"list\" \"paginator\" \"editor\";gap:8px}@media only screen and (max-width: 959px){.noif-lt-md{display:none}}\n"] }]
|
|
919
914
|
}], ctorParameters: function () { return [{ type: UserListRepository }, { type: DialogService }, { type: i2$2.GravatarService }]; } });
|
|
920
915
|
|
|
921
916
|
class AuthJwtAdminModule {
|
|
922
917
|
}
|
|
923
|
-
AuthJwtAdminModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
924
|
-
AuthJwtAdminModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.
|
|
918
|
+
AuthJwtAdminModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: AuthJwtAdminModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
919
|
+
AuthJwtAdminModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.1.0", ngImport: i0, type: AuthJwtAdminModule, declarations: [AuthJwtRegistrationComponent,
|
|
925
920
|
PasswordStrengthBarComponent,
|
|
926
921
|
UserFilterComponent,
|
|
927
922
|
UserListComponent,
|
|
@@ -936,6 +931,7 @@ AuthJwtAdminModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", vers
|
|
|
936
931
|
MatCardModule,
|
|
937
932
|
MatCheckboxModule,
|
|
938
933
|
MatDialogModule,
|
|
934
|
+
MatExpansionModule,
|
|
939
935
|
MatIconModule,
|
|
940
936
|
MatInputModule,
|
|
941
937
|
MatPaginatorModule,
|
|
@@ -948,7 +944,7 @@ AuthJwtAdminModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", vers
|
|
|
948
944
|
PasswordStrengthBarComponent,
|
|
949
945
|
UserFilterComponent,
|
|
950
946
|
UserListComponent] });
|
|
951
|
-
AuthJwtAdminModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.
|
|
947
|
+
AuthJwtAdminModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: AuthJwtAdminModule, imports: [CommonModule,
|
|
952
948
|
HttpClientModule,
|
|
953
949
|
FormsModule,
|
|
954
950
|
RouterModule,
|
|
@@ -958,6 +954,7 @@ AuthJwtAdminModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", vers
|
|
|
958
954
|
MatCardModule,
|
|
959
955
|
MatCheckboxModule,
|
|
960
956
|
MatDialogModule,
|
|
957
|
+
MatExpansionModule,
|
|
961
958
|
MatIconModule,
|
|
962
959
|
MatInputModule,
|
|
963
960
|
MatPaginatorModule,
|
|
@@ -967,7 +964,7 @@ AuthJwtAdminModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", vers
|
|
|
967
964
|
MatTooltipModule,
|
|
968
965
|
AuthJwtLoginModule,
|
|
969
966
|
NgToolsModule] });
|
|
970
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
967
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: AuthJwtAdminModule, decorators: [{
|
|
971
968
|
type: NgModule,
|
|
972
969
|
args: [{
|
|
973
970
|
declarations: [
|
|
@@ -989,6 +986,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImpor
|
|
|
989
986
|
MatCardModule,
|
|
990
987
|
MatCheckboxModule,
|
|
991
988
|
MatDialogModule,
|
|
989
|
+
MatExpansionModule,
|
|
992
990
|
MatIconModule,
|
|
993
991
|
MatInputModule,
|
|
994
992
|
MatPaginatorModule,
|