@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
|
@@ -23,23 +23,25 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
|
23
23
|
import { __rest } from 'tslib';
|
|
24
24
|
import { BehaviorSubject, combineLatest, map, debounceTime, take as take$1 } from 'rxjs';
|
|
25
25
|
import { select, createStore, withProps } from '@ngneat/elf';
|
|
26
|
-
import { selectActiveEntity, withEntities, withActiveId, upsertEntities, deleteAllEntities, setActiveId
|
|
26
|
+
import { selectActiveEntity, withEntities, withActiveId, upsertEntities, deleteAllEntities, setActiveId } from '@ngneat/elf-entities';
|
|
27
27
|
import { selectPaginationData, selectCurrentPageEntities, deleteAllPages, withPagination, updatePaginationData, setPage, hasPage, setCurrentPage } from '@ngneat/elf-pagination';
|
|
28
28
|
import { selectRequestStatus, withRequestsCache, withRequestsStatus, updateRequestStatus } from '@ngneat/elf-requests';
|
|
29
|
-
import * as
|
|
29
|
+
import * as i7$1 from '@angular/material/tooltip';
|
|
30
30
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
31
31
|
import * as i1$2 from '@angular/material/dialog';
|
|
32
32
|
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
|
33
33
|
import * as i2$2 from '@myrmidon/auth-jwt-login';
|
|
34
34
|
import { AuthJwtLoginModule } from '@myrmidon/auth-jwt-login';
|
|
35
|
-
import * as
|
|
35
|
+
import * as i6$1 from '@angular/material/expansion';
|
|
36
|
+
import { MatExpansionModule } from '@angular/material/expansion';
|
|
37
|
+
import * as i8$1 from '@angular/material/paginator';
|
|
36
38
|
import { MatPaginatorModule } from '@angular/material/paginator';
|
|
37
|
-
import * as
|
|
39
|
+
import * as i9$1 from '@angular/material/progress-bar';
|
|
38
40
|
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
|
39
41
|
import * as i5$1 from '@angular/material/checkbox';
|
|
40
42
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
41
|
-
import { MatCardModule } from '@angular/material/card';
|
|
42
43
|
import { RouterModule } from '@angular/router';
|
|
44
|
+
import { MatCardModule } from '@angular/material/card';
|
|
43
45
|
|
|
44
46
|
class PasswordValidators {
|
|
45
47
|
/** "Standard" password validator for my API services. */
|
|
@@ -109,27 +111,19 @@ class AuthJwtAccountService {
|
|
|
109
111
|
/**
|
|
110
112
|
* Register the user with the specified registration data.
|
|
111
113
|
* @param registration The registration data.
|
|
114
|
+
* @param confirmed True to automatically confirm the user's email address
|
|
115
|
+
* without sending the confirmation email message.
|
|
112
116
|
*/
|
|
113
|
-
register(registration) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
// }),
|
|
118
|
-
// };
|
|
119
|
-
return this._http.post(this._env.get('apiUrl') + 'accounts/register', registration
|
|
120
|
-
// options
|
|
121
|
-
);
|
|
117
|
+
register(registration, confirmed = false) {
|
|
118
|
+
return this._http.post(this._env.get('apiUrl') +
|
|
119
|
+
'accounts/register' +
|
|
120
|
+
(confirmed ? '?confirmed=true' : ''), registration);
|
|
122
121
|
}
|
|
123
122
|
/**
|
|
124
123
|
* Resend the confirmation email to the specified address.
|
|
125
124
|
* @param email address.
|
|
126
125
|
*/
|
|
127
126
|
resendConfirmEmail(email) {
|
|
128
|
-
// const options = {
|
|
129
|
-
// headers: this.createAuthHeaders({
|
|
130
|
-
// 'Content-Type': 'application/json',
|
|
131
|
-
// }),
|
|
132
|
-
// };
|
|
133
127
|
return this._http.get(this._env.get('apiUrl') +
|
|
134
128
|
'accounts/resendconfirm/' +
|
|
135
129
|
encodeURIComponent(email)
|
|
@@ -217,7 +211,9 @@ class AuthJwtAccountService {
|
|
|
217
211
|
*/
|
|
218
212
|
updateUser(user) {
|
|
219
213
|
return this._http
|
|
220
|
-
.put(this._env.get('apiUrl') +
|
|
214
|
+
.put(this._env.get('apiUrl') +
|
|
215
|
+
'users' +
|
|
216
|
+
(user.emailConfirmed ? '?confirmed=true' : ''), user)
|
|
221
217
|
.pipe(catchError(this._error.handleError));
|
|
222
218
|
}
|
|
223
219
|
/**
|
|
@@ -250,9 +246,9 @@ class AuthJwtAccountService {
|
|
|
250
246
|
.pipe(catchError(this._error.handleError));
|
|
251
247
|
}
|
|
252
248
|
}
|
|
253
|
-
AuthJwtAccountService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
254
|
-
AuthJwtAccountService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.
|
|
255
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
249
|
+
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 });
|
|
250
|
+
AuthJwtAccountService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: AuthJwtAccountService, providedIn: 'root' });
|
|
251
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: AuthJwtAccountService, decorators: [{
|
|
256
252
|
type: Injectable,
|
|
257
253
|
args: [{
|
|
258
254
|
providedIn: 'root',
|
|
@@ -326,9 +322,9 @@ class PasswordStrengthBarComponent {
|
|
|
326
322
|
}
|
|
327
323
|
}
|
|
328
324
|
}
|
|
329
|
-
PasswordStrengthBarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
330
|
-
PasswordStrengthBarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.
|
|
331
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
325
|
+
PasswordStrengthBarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: PasswordStrengthBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
326
|
+
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"] });
|
|
327
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: PasswordStrengthBarComponent, decorators: [{
|
|
332
328
|
type: Component,
|
|
333
329
|
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"] }]
|
|
334
330
|
}], ctorParameters: function () { return []; }, propDecorators: { passwordToCheck: [{
|
|
@@ -516,9 +512,9 @@ class AuthJwtRegistrationComponent {
|
|
|
516
512
|
});
|
|
517
513
|
}
|
|
518
514
|
}
|
|
519
|
-
AuthJwtRegistrationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
520
|
-
AuthJwtRegistrationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.
|
|
521
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
515
|
+
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 });
|
|
516
|
+
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"] }] });
|
|
517
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: AuthJwtRegistrationComponent, decorators: [{
|
|
522
518
|
type: Component,
|
|
523
519
|
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"] }]
|
|
524
520
|
}], ctorParameters: function () { return [{ type: i1$1.UntypedFormBuilder }, { type: i2$1.MatSnackBar }, { type: AuthJwtAccountService }]; }, propDecorators: { registered: [{
|
|
@@ -541,20 +537,19 @@ class UserListRepository {
|
|
|
541
537
|
this._store.pipe(selectPaginationData()),
|
|
542
538
|
this._store.pipe(selectCurrentPageEntities()),
|
|
543
539
|
]).pipe(map(([pagination, data]) => (Object.assign(Object.assign({}, pagination), { data }))), debounceTime(0));
|
|
544
|
-
// the active
|
|
540
|
+
// the active user, if required
|
|
545
541
|
this.activeUser$ = this._store.pipe(selectActiveEntity());
|
|
546
542
|
// the filter, if required
|
|
547
543
|
this.filter$ = this._store.pipe(select((state) => state.filter));
|
|
548
544
|
this.filter$.subscribe((filter) => {
|
|
549
545
|
// when filter changed, reset any existing page and move to page 1
|
|
550
546
|
const paginationData = this._store.getValue().pagination;
|
|
551
|
-
console.log('Deleting all pages');
|
|
552
547
|
this._store.update(deleteAllPages());
|
|
553
548
|
// load page 1
|
|
554
549
|
this.loadPage(1, paginationData.perPage);
|
|
555
550
|
});
|
|
556
551
|
// the request status
|
|
557
|
-
this.status$ = this._store.pipe(selectRequestStatus('
|
|
552
|
+
this.status$ = this._store.pipe(selectRequestStatus('user-list'));
|
|
558
553
|
// load page 1 and subscribe to pagination
|
|
559
554
|
this.loadPage(1, PAGE_SIZE);
|
|
560
555
|
this.pagination$.subscribe(console.log);
|
|
@@ -577,9 +572,7 @@ class UserListRepository {
|
|
|
577
572
|
}
|
|
578
573
|
addPage(response) {
|
|
579
574
|
const { data } = response, paginationData = __rest(response, ["data"]);
|
|
580
|
-
this._store.update(upsertEntities(data),
|
|
581
|
-
// addEntities(data),
|
|
582
|
-
updatePaginationData(paginationData), setPage(paginationData.currentPage, data.map((c) => c.userName)));
|
|
575
|
+
this._store.update(upsertEntities(data), updatePaginationData(paginationData), setPage(paginationData.currentPage, data.map((c) => c.userName)));
|
|
583
576
|
}
|
|
584
577
|
loadPage(pageNumber, pageSize) {
|
|
585
578
|
if (!pageSize) {
|
|
@@ -598,7 +591,7 @@ class UserListRepository {
|
|
|
598
591
|
this._lastPageSize = pageSize;
|
|
599
592
|
}
|
|
600
593
|
// load page from server
|
|
601
|
-
this._store.update(updateRequestStatus('
|
|
594
|
+
this._store.update(updateRequestStatus('user-list', 'pending'));
|
|
602
595
|
this._loading$.next(true);
|
|
603
596
|
this._accService
|
|
604
597
|
.getUsers(this._store.getValue().filter, pageNumber, pageSize)
|
|
@@ -606,7 +599,7 @@ class UserListRepository {
|
|
|
606
599
|
.subscribe((page) => {
|
|
607
600
|
this._loading$.next(false);
|
|
608
601
|
this.addPage(Object.assign(Object.assign({}, this.adaptPage(page)), { data: page.items }));
|
|
609
|
-
this._store.update(updateRequestStatus('
|
|
602
|
+
this._store.update(updateRequestStatus('user-list', 'success'));
|
|
610
603
|
});
|
|
611
604
|
}
|
|
612
605
|
setFilter(filter) {
|
|
@@ -624,7 +617,7 @@ class UserListRepository {
|
|
|
624
617
|
this._accService.updateUser(user).subscribe({
|
|
625
618
|
next: (_) => {
|
|
626
619
|
this._saving$.next(false);
|
|
627
|
-
this._store.update(
|
|
620
|
+
this._store.update(upsertEntities(user));
|
|
628
621
|
resolve(true);
|
|
629
622
|
},
|
|
630
623
|
error: (error) => {
|
|
@@ -657,9 +650,9 @@ class UserListRepository {
|
|
|
657
650
|
return promise;
|
|
658
651
|
}
|
|
659
652
|
}
|
|
660
|
-
UserListRepository.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
661
|
-
UserListRepository.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.
|
|
662
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
653
|
+
UserListRepository.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: UserListRepository, deps: [{ token: AuthJwtAccountService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
654
|
+
UserListRepository.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: UserListRepository, providedIn: 'root' });
|
|
655
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: UserListRepository, decorators: [{
|
|
663
656
|
type: Injectable,
|
|
664
657
|
args: [{ providedIn: 'root' }]
|
|
665
658
|
}], ctorParameters: function () { return [{ type: AuthJwtAccountService }]; } });
|
|
@@ -702,11 +695,11 @@ class UserFilterComponent {
|
|
|
702
695
|
this._repository.setFilter(filter);
|
|
703
696
|
}
|
|
704
697
|
}
|
|
705
|
-
UserFilterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
706
|
-
UserFilterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.
|
|
707
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
698
|
+
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 });
|
|
699
|
+
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"] }] });
|
|
700
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: UserFilterComponent, decorators: [{
|
|
708
701
|
type: Component,
|
|
709
|
-
args: [{ selector: 'auth-jwt-user-filter', template: "<form [formGroup]=\"form\" (submit)=\"apply()\" ng-disabled=\"disabled\">\n <mat-form-field>\n
|
|
702
|
+
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"] }]
|
|
710
703
|
}], ctorParameters: function () { return [{ type: i1$1.FormBuilder }, { type: UserListRepository }]; }, propDecorators: { disabled: [{
|
|
711
704
|
type: Input
|
|
712
705
|
}] } });
|
|
@@ -723,9 +716,9 @@ class ConfirmDialogComponent {
|
|
|
723
716
|
}
|
|
724
717
|
ngOnInit() { }
|
|
725
718
|
}
|
|
726
|
-
ConfirmDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
727
|
-
ConfirmDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.
|
|
728
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
719
|
+
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 });
|
|
720
|
+
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"] }] });
|
|
721
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: ConfirmDialogComponent, decorators: [{
|
|
729
722
|
type: Component,
|
|
730
723
|
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" }]
|
|
731
724
|
}], ctorParameters: function () {
|
|
@@ -761,9 +754,9 @@ class DialogService {
|
|
|
761
754
|
return dialogRef.afterClosed();
|
|
762
755
|
}
|
|
763
756
|
}
|
|
764
|
-
DialogService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
765
|
-
DialogService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.
|
|
766
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
757
|
+
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 });
|
|
758
|
+
DialogService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: DialogService, providedIn: 'root' });
|
|
759
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: DialogService, decorators: [{
|
|
767
760
|
type: Injectable,
|
|
768
761
|
args: [{
|
|
769
762
|
providedIn: 'root'
|
|
@@ -859,11 +852,11 @@ class UserEditorComponent {
|
|
|
859
852
|
this.userChange.emit(this.getUserFromForm());
|
|
860
853
|
}
|
|
861
854
|
}
|
|
862
|
-
UserEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
863
|
-
UserEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.
|
|
864
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
855
|
+
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 });
|
|
856
|
+
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"] }] });
|
|
857
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: UserEditorComponent, decorators: [{
|
|
865
858
|
type: Component,
|
|
866
|
-
args: [{ selector: 'auth-jwt-user-editor', template: "<form [formGroup]=\"form\" (submit)=\"save()\">\n <!-- email -->\n
|
|
859
|
+
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"] }]
|
|
867
860
|
}], ctorParameters: function () { return [{ type: i1$1.UntypedFormBuilder }, { type: i2$2.AuthJwtService }]; }, propDecorators: { user: [{
|
|
868
861
|
type: Input
|
|
869
862
|
}], userChange: [{
|
|
@@ -906,28 +899,30 @@ class UserListComponent {
|
|
|
906
899
|
}
|
|
907
900
|
saveActiveUser(user) {
|
|
908
901
|
this._repository.updateActive(user);
|
|
902
|
+
this._repository.setActive(null);
|
|
909
903
|
}
|
|
910
904
|
onUserEditorClose() {
|
|
911
|
-
this.
|
|
905
|
+
this._repository.setActive(null);
|
|
912
906
|
}
|
|
913
907
|
getGravatarUrl(email, size = 80) {
|
|
914
908
|
return this._gravatarService.buildGravatarUrl(email, size);
|
|
915
909
|
}
|
|
916
910
|
clearCache() {
|
|
917
911
|
this._repository.clearCache();
|
|
912
|
+
this._repository.loadPage(1);
|
|
918
913
|
}
|
|
919
914
|
}
|
|
920
|
-
UserListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
921
|
-
UserListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.
|
|
922
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
915
|
+
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 });
|
|
916
|
+
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" }] });
|
|
917
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: UserListComponent, decorators: [{
|
|
923
918
|
type: Component,
|
|
924
|
-
args: [{ selector: 'auth-jwt-user-list', template: "<div
|
|
919
|
+
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"] }]
|
|
925
920
|
}], ctorParameters: function () { return [{ type: UserListRepository }, { type: DialogService }, { type: i2$2.GravatarService }]; } });
|
|
926
921
|
|
|
927
922
|
class AuthJwtAdminModule {
|
|
928
923
|
}
|
|
929
|
-
AuthJwtAdminModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
930
|
-
AuthJwtAdminModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.
|
|
924
|
+
AuthJwtAdminModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: AuthJwtAdminModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
925
|
+
AuthJwtAdminModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.1.0", ngImport: i0, type: AuthJwtAdminModule, declarations: [AuthJwtRegistrationComponent,
|
|
931
926
|
PasswordStrengthBarComponent,
|
|
932
927
|
UserFilterComponent,
|
|
933
928
|
UserListComponent,
|
|
@@ -942,6 +937,7 @@ AuthJwtAdminModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", vers
|
|
|
942
937
|
MatCardModule,
|
|
943
938
|
MatCheckboxModule,
|
|
944
939
|
MatDialogModule,
|
|
940
|
+
MatExpansionModule,
|
|
945
941
|
MatIconModule,
|
|
946
942
|
MatInputModule,
|
|
947
943
|
MatPaginatorModule,
|
|
@@ -954,7 +950,7 @@ AuthJwtAdminModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", vers
|
|
|
954
950
|
PasswordStrengthBarComponent,
|
|
955
951
|
UserFilterComponent,
|
|
956
952
|
UserListComponent] });
|
|
957
|
-
AuthJwtAdminModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.
|
|
953
|
+
AuthJwtAdminModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: AuthJwtAdminModule, imports: [CommonModule,
|
|
958
954
|
HttpClientModule,
|
|
959
955
|
FormsModule,
|
|
960
956
|
RouterModule,
|
|
@@ -964,6 +960,7 @@ AuthJwtAdminModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", vers
|
|
|
964
960
|
MatCardModule,
|
|
965
961
|
MatCheckboxModule,
|
|
966
962
|
MatDialogModule,
|
|
963
|
+
MatExpansionModule,
|
|
967
964
|
MatIconModule,
|
|
968
965
|
MatInputModule,
|
|
969
966
|
MatPaginatorModule,
|
|
@@ -973,7 +970,7 @@ AuthJwtAdminModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", vers
|
|
|
973
970
|
MatTooltipModule,
|
|
974
971
|
AuthJwtLoginModule,
|
|
975
972
|
NgToolsModule] });
|
|
976
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
973
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: AuthJwtAdminModule, decorators: [{
|
|
977
974
|
type: NgModule,
|
|
978
975
|
args: [{
|
|
979
976
|
declarations: [
|
|
@@ -995,6 +992,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImpor
|
|
|
995
992
|
MatCardModule,
|
|
996
993
|
MatCheckboxModule,
|
|
997
994
|
MatDialogModule,
|
|
995
|
+
MatExpansionModule,
|
|
998
996
|
MatIconModule,
|
|
999
997
|
MatInputModule,
|
|
1000
998
|
MatPaginatorModule,
|