@myrmidon/auth-jwt-admin 1.0.5 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/esm2022/lib/auth-jwt-admin.module.mjs +120 -0
  2. package/esm2022/lib/components/auth-jwt-registration/auth-jwt-registration.component.mjs +165 -0
  3. package/esm2022/lib/components/confirm-dialog/confirm-dialog.component.mjs +30 -0
  4. package/esm2022/lib/components/password-strength-bar/password-strength-bar.component.mjs +81 -0
  5. package/esm2022/lib/components/state/user-list.repository.mjs +145 -0
  6. package/esm2022/lib/components/user-editor/user-editor.component.mjs +113 -0
  7. package/esm2022/lib/components/user-filter/user-filter.component.mjs +56 -0
  8. package/esm2022/lib/components/user-list/user-list.component.mjs +71 -0
  9. package/esm2022/lib/services/auth-jwt-account.service.mjs +182 -0
  10. package/esm2022/lib/services/dialog.service.mjs +38 -0
  11. package/{esm2020 → esm2022}/lib/validators/password.validators.mjs +48 -48
  12. package/{esm2020 → esm2022}/myrmidon-auth-jwt-admin.mjs +4 -4
  13. package/{esm2020 → esm2022}/public-api.mjs +12 -12
  14. package/fesm2022/myrmidon-auth-jwt-admin.mjs +992 -0
  15. package/fesm2022/myrmidon-auth-jwt-admin.mjs.map +1 -0
  16. package/index.d.ts +5 -5
  17. package/lib/auth-jwt-admin.module.d.ts +30 -30
  18. package/lib/components/auth-jwt-registration/auth-jwt-registration.component.d.ts +37 -37
  19. package/lib/components/confirm-dialog/confirm-dialog.component.d.ts +15 -15
  20. package/lib/components/password-strength-bar/password-strength-bar.component.d.ts +17 -17
  21. package/lib/components/state/user-list.repository.d.ts +36 -36
  22. package/lib/components/user-editor/user-editor.component.d.ts +29 -29
  23. package/lib/components/user-filter/user-filter.component.d.ts +21 -21
  24. package/lib/components/user-list/user-list.component.d.ts +29 -28
  25. package/lib/services/auth-jwt-account.service.d.ts +114 -114
  26. package/lib/services/dialog.service.d.ts +19 -19
  27. package/lib/validators/password.validators.d.ts +6 -6
  28. package/package.json +24 -17
  29. package/public-api.d.ts +8 -8
  30. package/esm2020/lib/auth-jwt-admin.module.mjs +0 -119
  31. package/esm2020/lib/components/auth-jwt-registration/auth-jwt-registration.component.mjs +0 -164
  32. package/esm2020/lib/components/confirm-dialog/confirm-dialog.component.mjs +0 -29
  33. package/esm2020/lib/components/password-strength-bar/password-strength-bar.component.mjs +0 -80
  34. package/esm2020/lib/components/state/user-list.repository.mjs +0 -144
  35. package/esm2020/lib/components/user-editor/user-editor.component.mjs +0 -112
  36. package/esm2020/lib/components/user-filter/user-filter.component.mjs +0 -55
  37. package/esm2020/lib/components/user-list/user-list.component.mjs +0 -69
  38. package/esm2020/lib/services/auth-jwt-account.service.mjs +0 -181
  39. package/esm2020/lib/services/dialog.service.mjs +0 -37
  40. package/fesm2015/myrmidon-auth-jwt-admin.mjs +0 -997
  41. package/fesm2015/myrmidon-auth-jwt-admin.mjs.map +0 -1
  42. package/fesm2020/myrmidon-auth-jwt-admin.mjs +0 -991
  43. package/fesm2020/myrmidon-auth-jwt-admin.mjs.map +0 -1
@@ -0,0 +1,145 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { BehaviorSubject, combineLatest, debounceTime, map, take, } from 'rxjs';
3
+ import { createStore, select, withProps } from '@ngneat/elf';
4
+ import { deleteAllEntities, selectActiveEntity, setActiveId, upsertEntities, withActiveId, withEntities, } from '@ngneat/elf-entities';
5
+ import { deleteAllPages, hasPage, selectCurrentPageEntities, selectPaginationData, setCurrentPage, setPage, updatePaginationData, withPagination, } from '@ngneat/elf-pagination';
6
+ import { selectRequestStatus, updateRequestStatus, withRequestsCache, withRequestsStatus, } from '@ngneat/elf-requests';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "../../services/auth-jwt-account.service";
9
+ const PAGE_SIZE = 20;
10
+ class UserListRepository {
11
+ constructor(_accService) {
12
+ this._accService = _accService;
13
+ // create store
14
+ this._store = this.createStore();
15
+ this._lastPageSize = PAGE_SIZE;
16
+ this._loading$ = new BehaviorSubject(false);
17
+ this._saving$ = new BehaviorSubject(false);
18
+ this.loading$ = this._loading$.asObservable();
19
+ this.saving$ = this._saving$.asObservable();
20
+ // combine pagination parameters with page data for our consumers
21
+ this.pagination$ = combineLatest([
22
+ this._store.pipe(selectPaginationData()),
23
+ this._store.pipe(selectCurrentPageEntities()),
24
+ ]).pipe(map(([pagination, data]) => ({ ...pagination, data })), debounceTime(0));
25
+ // the active user, if required
26
+ this.activeUser$ = this._store.pipe(selectActiveEntity());
27
+ // the filter, if required
28
+ this.filter$ = this._store.pipe(select((state) => state.filter));
29
+ this.filter$.subscribe((filter) => {
30
+ // when filter changed, reset any existing page and move to page 1
31
+ const paginationData = this._store.getValue().pagination;
32
+ this._store.update(deleteAllPages());
33
+ // load page 1
34
+ this.loadPage(1, paginationData.perPage);
35
+ });
36
+ // the request status
37
+ this.status$ = this._store.pipe(selectRequestStatus('user-list'));
38
+ // load page 1 and subscribe to pagination
39
+ this.loadPage(1, PAGE_SIZE);
40
+ this.pagination$.subscribe(console.log);
41
+ }
42
+ createStore() {
43
+ const store = createStore({ name: 'user-list' }, withProps({
44
+ filter: {},
45
+ }), withEntities({ idKey: 'userName' }), withActiveId(), withRequestsCache(), withRequestsStatus(), withPagination());
46
+ return store;
47
+ }
48
+ adaptPage(page) {
49
+ // adapt the server page DataPage<T> to Elf pagination
50
+ return {
51
+ currentPage: page.pageNumber,
52
+ perPage: page.pageSize,
53
+ lastPage: page.pageCount,
54
+ total: page.total,
55
+ data: page.items,
56
+ };
57
+ }
58
+ addPage(response) {
59
+ const { data, ...paginationData } = response;
60
+ this._store.update(upsertEntities(data), updatePaginationData(paginationData), setPage(paginationData.currentPage, data.map((c) => c.userName)));
61
+ }
62
+ loadPage(pageNumber, pageSize) {
63
+ if (!pageSize) {
64
+ pageSize = PAGE_SIZE;
65
+ }
66
+ // if the page exists and page size is the same, just move to it
67
+ if (this._store.query(hasPage(pageNumber)) &&
68
+ pageSize === this._lastPageSize) {
69
+ console.log('Page exists: ' + pageNumber);
70
+ this._store.update(setCurrentPage(pageNumber));
71
+ return;
72
+ }
73
+ // reset cached pages if page size changed
74
+ if (this._lastPageSize !== pageSize) {
75
+ this._store.update(deleteAllPages());
76
+ this._lastPageSize = pageSize;
77
+ }
78
+ // load page from server
79
+ this._store.update(updateRequestStatus('user-list', 'pending'));
80
+ this._loading$.next(true);
81
+ this._accService
82
+ .getUsers(this._store.getValue().filter, pageNumber, pageSize)
83
+ .pipe(take(1))
84
+ .subscribe((page) => {
85
+ this._loading$.next(false);
86
+ this.addPage({ ...this.adaptPage(page), data: page.items });
87
+ this._store.update(updateRequestStatus('user-list', 'success'));
88
+ });
89
+ }
90
+ setFilter(filter) {
91
+ this._store.update((state) => ({ ...state, filter: filter }));
92
+ }
93
+ clearCache() {
94
+ this._store.update(deleteAllEntities(), deleteAllPages());
95
+ }
96
+ setActive(name) {
97
+ this._store.update(setActiveId(name));
98
+ }
99
+ updateActive(user) {
100
+ const promise = new Promise((resolve, reject) => {
101
+ this._saving$.next(true);
102
+ this._accService.updateUser(user).subscribe({
103
+ next: (_) => {
104
+ this._saving$.next(false);
105
+ this._store.update(upsertEntities(user));
106
+ resolve(true);
107
+ },
108
+ error: (error) => {
109
+ this._saving$.next(false);
110
+ console.error(`Error updating user ${user.userName}: ` +
111
+ JSON.stringify(error || {}));
112
+ resolve(false);
113
+ },
114
+ });
115
+ });
116
+ return promise;
117
+ }
118
+ deleteUser(name) {
119
+ const promise = new Promise((resolve, reject) => {
120
+ this._saving$.next(true);
121
+ this._accService.deleteUser(name).subscribe({
122
+ next: (_) => {
123
+ this._saving$.next(false);
124
+ this.clearCache();
125
+ this.loadPage(1);
126
+ resolve(true);
127
+ },
128
+ error: (error) => {
129
+ this._saving$.next(false);
130
+ console.error(`Error deleting user ${name}: ` + JSON.stringify(error || {}));
131
+ reject(error);
132
+ },
133
+ });
134
+ });
135
+ return promise;
136
+ }
137
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: UserListRepository, deps: [{ token: i1.AuthJwtAccountService }], target: i0.ɵɵFactoryTarget.Injectable }); }
138
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: UserListRepository, providedIn: 'root' }); }
139
+ }
140
+ export { UserListRepository };
141
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: UserListRepository, decorators: [{
142
+ type: Injectable,
143
+ args: [{ providedIn: 'root' }]
144
+ }], ctorParameters: function () { return [{ type: i1.AuthJwtAccountService }]; } });
145
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1saXN0LnJlcG9zaXRvcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9teXJtaWRvbi9hdXRoLWp3dC1hZG1pbi9zcmMvbGliL2NvbXBvbmVudHMvc3RhdGUvdXNlci1saXN0LnJlcG9zaXRvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQ0wsZUFBZSxFQUNmLGFBQWEsRUFDYixZQUFZLEVBQ1osR0FBRyxFQUVILElBQUksR0FDTCxNQUFNLE1BQU0sQ0FBQztBQUVkLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM3RCxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLGtCQUFrQixFQUNsQixXQUFXLEVBRVgsY0FBYyxFQUNkLFlBQVksRUFDWixZQUFZLEdBQ2IsTUFBTSxzQkFBc0IsQ0FBQztBQUM5QixPQUFPLEVBQ0wsY0FBYyxFQUNkLE9BQU8sRUFFUCx5QkFBeUIsRUFDekIsb0JBQW9CLEVBQ3BCLGNBQWMsRUFDZCxPQUFPLEVBQ1Asb0JBQW9CLEVBQ3BCLGNBQWMsR0FDZixNQUFNLHdCQUF3QixDQUFDO0FBQ2hDLE9BQU8sRUFDTCxtQkFBbUIsRUFFbkIsbUJBQW1CLEVBQ25CLGlCQUFpQixFQUNqQixrQkFBa0IsR0FDbkIsTUFBTSxzQkFBc0IsQ0FBQzs7O0FBVTlCLE1BQU0sU0FBUyxHQUFHLEVBQUUsQ0FBQztBQU1yQixNQUNhLGtCQUFrQjtJQWE3QixZQUFvQixXQUFrQztRQUFsQyxnQkFBVyxHQUFYLFdBQVcsQ0FBdUI7UUFDcEQsZUFBZTtRQUNmLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxhQUFhLEdBQUcsU0FBUyxDQUFDO1FBQy9CLElBQUksQ0FBQyxT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QztvQkFDbEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDakIsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNoQixDQUFDO2dCQUNELEtBQUssRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFO29CQUNmLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUMxQixPQUFPLENBQUMsS0FBSyxDQUNYLHVCQUF1QixJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsQ0FDOUQsQ0FBQztvQkFDRixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ2hCLENBQUM7YUFDRixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7OEdBakxVLGtCQUFrQjtrSEFBbEIsa0JBQWtCLGNBREwsTUFBTTs7U0FDbkIsa0JBQWtCOzJGQUFsQixrQkFBa0I7a0JBRDlCLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge1xyXG4gIEJlaGF2aW9yU3ViamVjdCxcclxuICBjb21iaW5lTGF0ZXN0LFxyXG4gIGRlYm91bmNlVGltZSxcclxuICBtYXAsXHJcbiAgT2JzZXJ2YWJsZSxcclxuICB0YWtlLFxyXG59IGZyb20gJ3J4anMnO1xyXG5cclxuaW1wb3J0IHsgY3JlYXRlU3RvcmUsIHNlbGVjdCwgd2l0aFByb3BzIH0gZnJvbSAnQG5nbmVhdC9lbGYnO1xyXG5pbXBvcnQge1xyXG4gIGRlbGV0ZUFsbEVudGl0aWVzLFxyXG4gIHNlbGVjdEFjdGl2ZUVudGl0eSxcclxuICBzZXRBY3RpdmVJZCxcclxuICB1cGRhdGVFbnRpdGllcyxcclxuICB1cHNlcnRFbnRpdGllcyxcclxuICB3aXRoQWN0aXZlSWQsXHJcbiAgd2l0aEVudGl0aWVzLFxyXG59IGZyb20gJ0BuZ25lYXQvZWxmLWVudGl0aWVzJztcclxuaW1wb3J0IHtcclxuICBkZWxldGVBbGxQYWdlcyxcclxuICBoYXNQYWdlLFxyXG4gIFBhZ2luYXRpb25EYXRhLFxyXG4gIHNlbGVjdEN1cnJlbnRQYWdlRW50aXRpZXMsXHJcbiAgc2VsZWN0UGFnaW5hdGlvbkRhdGEsXHJcbiAgc2V0Q3VycmVudFBhZ2UsXHJcbiAgc2V0UGFnZSxcclxuICB1cGRhdGVQYWdpbmF0aW9uRGF0YSxcclxuICB3aXRoUGFnaW5hdGlvbixcclxufSBmcm9tICdAbmduZWF0L2VsZi1wYWdpbmF0aW9uJztcclxuaW1wb3J0IHtcclxuICBzZWxlY3RSZXF1ZXN0U3RhdHVzLFxyXG4gIFN0YXR1c1N0YXRlLFxyXG4gIHVwZGF0ZVJlcXVlc3RTdGF0dXMsXHJcbiAgd2l0aFJlcXVlc3RzQ2FjaGUsXHJcbiAgd2l0aFJlcXVlc3RzU3RhdHVzLFxyXG59IGZyb20gJ0BuZ25lYXQvZWxmLXJlcXVlc3RzJztcclxuXHJcbmltcG9ydCB7IFVzZXIgfSBmcm9tICdAbXlybWlkb24vYXV0aC1qd3QtbG9naW4nO1xyXG5pbXBvcnQgeyBEYXRhUGFnZSB9IGZyb20gJ0BteXJtaWRvbi9uZy10b29scyc7XHJcblxyXG5pbXBvcnQge1xyXG4gIEF1dGhKd3RBY2NvdW50U2VydmljZSxcclxuICBVc2VyRmlsdGVyLFxyXG59IGZyb20gJy4uLy4uL3NlcnZpY2VzL2F1dGgtand0LWFjY291bnQuc2VydmljZSc7XHJcblxyXG5jb25zdCBQQUdFX1NJWkUgPSAyMDtcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgVXNlckxpc3RQcm9wcyB7XHJcbiAgZmlsdGVyOiBVc2VyRmlsdGVyO1xyXG59XHJcblxyXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxyXG5leHBvcnQgY2xhc3MgVXNlckxpc3RSZXBvc2l0b3J5IHtcclxuICBwcml2YXRlIF9zdG9yZTtcclxuICBwcml2YXRlIF9sYXN0UGFnZVNpemU6IG51bWJlcjtcclxuICBwcml2YXRlIF9sb2FkaW5nJDogQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+O1xyXG4gIHByaXZhdGUgX3NhdmluZyQ6IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPjtcclxuXHJcbiAgcHVibGljIGFjdGl2ZVVzZXIkOiBPYnNlcnZhYmxlPFVzZXIgfCB1bmRlZmluZWQ+O1xyXG4gIHB1YmxpYyBmaWx0ZXIkOiBPYnNlcnZhYmxlPFVzZXJGaWx0ZXI+O1xyXG4gIHB1YmxpYyBwYWdpbmF0aW9uJDogT2JzZXJ2YWJsZTxQYWdpbmF0aW9uRGF0YSAmIHsgZGF0YTogVXNlcltdIH0+O1xyXG4gIHB1YmxpYyBzdGF0dXMkOiBPYnNlcnZhYmxlPFN0YXR1c1N0YXRlPjtcclxuICBwdWJsaWMgbG9hZGluZyQ6IE9ic2VydmFibGU8Ym9vbGVhbj47XHJcbiAgcHVibGljIHNhdmluZyQ6IE9ic2VydmFibGU8Ym9vbGVhbj47XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX2FjY1NlcnZpY2U6IEF1dGhKd3RBY2NvdW50U2VydmljZSkge1xyXG4gICAgLy8gY3JlYXRlIHN0b3JlXHJcbiAgICB0aGlzLl9zdG9yZSA9IHRoaXMuY3JlYXRlU3RvcmUoKTtcclxuICAgIHRoaXMuX2xhc3RQYWdlU2l6ZSA9IFBBR0VfU0laRTtcclxuICAgIHRoaXMuX2xvYWRpbmckID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XHJcbiAgICB0aGlzLl9zYXZpbmckID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XHJcbiAgICB0aGlzLmxvYWRpbmckID0gdGhpcy5fbG9hZGluZyQuYXNPYnNlcnZhYmxlKCk7XHJcbiAgICB0aGlzLnNhdmluZyQgPSB0aGlzLl9zYXZpbmckLmFzT2JzZXJ2YWJsZSgpO1xyXG4gICAgLy8gY29tYmluZSBwYWdpbmF0aW9uIHBhcmFtZXRlcnMgd2l0aCBwYWdlIGRhdGEgZm9yIG91ciBjb25zdW1lcnNcclxuICAgIHRoaXMucGFnaW5hdGlvbiQgPSBjb21iaW5lTGF0ZXN0KFtcclxuICAgICAgdGhpcy5fc3RvcmUucGlwZShzZWxlY3RQYWdpbmF0aW9uRGF0YSgpKSxcclxuICAgICAgdGhpcy5fc3RvcmUucGlwZShzZWxlY3RDdXJyZW50UGFnZUVudGl0aWVzKCkpLFxyXG4gICAgXSkucGlwZShcclxuICAgICAgbWFwKChbcGFnaW5hdGlvbiwgZGF0YV0pID0+ICh7IC4uLnBhZ2luYXRpb24sIGRhdGEgfSkpLFxyXG4gICAgICBkZWJvdW5jZVRpbWUoMClcclxuICAgICk7XHJcbiAgICAvLyB0aGUgYWN0aXZlIHVzZXIsIGlmIHJlcXVpcmVkXHJcbiAgICB0aGlzLmFjdGl2ZVVzZXIkID0gdGhpcy5fc3RvcmUucGlwZShzZWxlY3RBY3RpdmVFbnRpdHkoKSk7XHJcbiAgICAvLyB0aGUgZmlsdGVyLCBpZiByZXF1aXJlZFxyXG4gICAgdGhpcy5maWx0ZXIkID0gdGhpcy5fc3RvcmUucGlwZShzZWxlY3QoKHN0YXRlKSA9PiBzdGF0ZS5maWx0ZXIpKTtcclxuICAgIHRoaXMuZmlsdGVyJC5zdWJzY3JpYmUoKGZpbHRlcikgPT4ge1xyXG4gICAgICAvLyB3aGVuIGZpbHRlciBjaGFuZ2VkLCByZXNldCBhbnkgZXhpc3RpbmcgcGFnZSBhbmQgbW92ZSB0byBwYWdlIDFcclxuICAgICAgY29uc3QgcGFnaW5hdGlvbkRhdGEgPSB0aGlzLl9zdG9yZS5nZXRWYWx1ZSgpLnBhZ2luYXRpb247XHJcbiAgICAgIHRoaXMuX3N0b3JlLnVwZGF0ZShkZWxldGVBbGxQYWdlcygpKTtcclxuICAgICAgLy8gbG9hZCBwYWdlIDFcclxuICAgICAgdGhpcy5sb2FkUGFnZSgxLCBwYWdpbmF0aW9uRGF0YS5wZXJQYWdlKTtcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIHRoZSByZXF1ZXN0IHN0YXR1c1xyXG4gICAgdGhpcy5zdGF0dXMkID0gdGhpcy5fc3RvcmUucGlwZShzZWxlY3RSZXF1ZXN0U3RhdHVzKCd1c2VyLWxpc3QnKSk7XHJcblxyXG4gICAgLy8gbG9hZCBwYWdlIDEgYW5kIHN1YnNjcmliZSB0byBwYWdpbmF0aW9uXHJcbiAgICB0aGlzLmxvYWRQYWdlKDEsIFBBR0VfU0laRSk7XHJcbiAgICB0aGlzLnBhZ2luYXRpb24kLnN1YnNjcmliZShjb25zb2xlLmxvZyk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNyZWF0ZVN0b3JlKCk6IHR5cGVvZiBzdG9yZSB7XHJcbiAgICBjb25zdCBzdG9yZSA9IGNyZWF0ZVN0b3JlKFxyXG4gICAgICB7IG5hbWU6ICd1c2VyLWxpc3QnIH0sXHJcbiAgICAgIHdpdGhQcm9wczxVc2VyTGlzdFByb3BzPih7XHJcbiAgICAgICAgZmlsdGVyOiB7fSxcclxuICAgICAgfSksXHJcbiAgICAgIHdpdGhFbnRpdGllczxVc2VyLCAndXNlck5hbWUnPih7IGlkS2V5OiAndXNlck5hbWUnIH0pLFxyXG4gICAgICB3aXRoQWN0aXZlSWQoKSxcclxuICAgICAgd2l0aFJlcXVlc3RzQ2FjaGU8J3VzZXItbGlzdCc+KCksXHJcbiAgICAgIHdpdGhSZXF1ZXN0c1N0YXR1cygpLFxyXG4gICAgICB3aXRoUGFnaW5hdGlvbigpXHJcbiAgICApO1xyXG5cclxuICAgIHJldHVybiBzdG9yZTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYWRhcHRQYWdlKHBhZ2U6IERhdGFQYWdlPFVzZXI+KTogUGFnaW5hdGlvbkRhdGEgJiB7IGRhdGE6IFVzZXJbXSB9IHtcclxuICAgIC8vIGFkYXB0IHRoZSBzZXJ2ZXIgcGFnZSBEYXRhUGFnZTxUPiB0byBFbGYgcGFnaW5hdGlvblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgY3VycmVudFBhZ2U6IHBhZ2UucGFnZU51bWJlcixcclxuICAgICAgcGVyUGFnZTogcGFnZS5wYWdlU2l6ZSxcclxuICAgICAgbGFzdFBhZ2U6IHBhZ2UucGFnZUNvdW50LFxyXG4gICAgICB0b3RhbDogcGFnZS50b3RhbCxcclxuICAgICAgZGF0YTogcGFnZS5pdGVtcyxcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFkZFBhZ2UocmVzcG9uc2U6IFBhZ2luYXRpb25EYXRhICYgeyBkYXRhOiBVc2VyW10gfSk6IHZvaWQge1xyXG4gICAgY29uc3QgeyBkYXRhLCAuLi5wYWdpbmF0aW9uRGF0YSB9ID0gcmVzcG9uc2U7XHJcbiAgICB0aGlzLl9zdG9yZS51cGRhdGUoXHJcbiAgICAgIHVwc2VydEVudGl0aWVzKGRhdGEpLFxyXG4gICAgICB1cGRhdGVQYWdpbmF0aW9uRGF0YShwYWdpbmF0aW9uRGF0YSksXHJcbiAgICAgIHNldFBhZ2UoXHJcbiAgICAgICAgcGFnaW5hdGlvbkRhdGEuY3VycmVudFBhZ2UsXHJcbiAgICAgICAgZGF0YS5tYXAoKGMpID0+IGMudXNlck5hbWUpXHJcbiAgICAgIClcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbG9hZFBhZ2UocGFnZU51bWJlcjogbnVtYmVyLCBwYWdlU2l6ZT86IG51bWJlcik6IHZvaWQge1xyXG4gICAgaWYgKCFwYWdlU2l6ZSkge1xyXG4gICAgICBwYWdlU2l6ZSA9IFBBR0VfU0laRTtcclxuICAgIH1cclxuICAgIC8vIGlmIHRoZSBwYWdlIGV4aXN0cyBhbmQgcGFnZSBzaXplIGlzIHRoZSBzYW1lLCBqdXN0IG1vdmUgdG8gaXRcclxuICAgIGlmIChcclxuICAgICAgdGhpcy5fc3RvcmUucXVlcnkoaGFzUGFnZShwYWdlTnVtYmVyKSkgJiZcclxuICAgICAgcGFnZVNpemUgPT09IHRoaXMuX2xhc3RQYWdlU2l6ZVxyXG4gICAgKSB7XHJcbiAgICAgIGNvbnNvbGUubG9nKCdQYWdlIGV4aXN0czogJyArIHBhZ2VOdW1iZXIpO1xyXG4gICAgICB0aGlzLl9zdG9yZS51cGRhdGUoc2V0Q3VycmVudFBhZ2UocGFnZU51bWJlcikpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gcmVzZXQgY2FjaGVkIHBhZ2VzIGlmIHBhZ2Ugc2l6ZSBjaGFuZ2VkXHJcbiAgICBpZiAodGhpcy5fbGFzdFBhZ2VTaXplICE9PSBwYWdlU2l6ZSkge1xyXG4gICAgICB0aGlzLl9zdG9yZS51cGRhdGUoZGVsZXRlQWxsUGFnZXMoKSk7XHJcbiAgICAgIHRoaXMuX2xhc3RQYWdlU2l6ZSA9IHBhZ2VTaXplO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGxvYWQgcGFnZSBmcm9tIHNlcnZlclxyXG4gICAgdGhpcy5fc3RvcmUudXBkYXRlKHVwZGF0ZVJlcXVlc3RTdGF0dXMoJ3VzZXItbGlzdCcsICdwZW5kaW5nJykpO1xyXG4gICAgdGhpcy5fbG9hZGluZyQubmV4dCh0cnVlKTtcclxuICAgIHRoaXMuX2FjY1NlcnZpY2VcclxuICAgICAgLmdldFVzZXJzKHRoaXMuX3N0b3JlLmdldFZhbHVlKCkuZmlsdGVyLCBwYWdlTnVtYmVyLCBwYWdlU2l6ZSlcclxuICAgICAgLnBpcGUodGFrZSgxKSlcclxuICAgICAgLnN1YnNjcmliZSgocGFnZSkgPT4ge1xyXG4gICAgICAgIHRoaXMuX2xvYWRpbmckLm5leHQoZmFsc2UpO1xyXG4gICAgICAgIHRoaXMuYWRkUGFnZSh7IC4uLnRoaXMuYWRhcHRQYWdlKHBhZ2UpLCBkYXRhOiBwYWdlLml0ZW1zIH0pO1xyXG4gICAgICAgIHRoaXMuX3N0b3JlLnVwZGF0ZSh1cGRhdGVSZXF1ZXN0U3RhdHVzKCd1c2VyLWxpc3QnLCAnc3VjY2VzcycpKTtcclxuICAgICAgfSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2V0RmlsdGVyKGZpbHRlcjogVXNlckZpbHRlcik6IHZvaWQge1xyXG4gICAgdGhpcy5fc3RvcmUudXBkYXRlKChzdGF0ZSkgPT4gKHsgLi4uc3RhdGUsIGZpbHRlcjogZmlsdGVyIH0pKTtcclxuICB9XHJcblxyXG4gIGNsZWFyQ2FjaGUoKSB7XHJcbiAgICB0aGlzLl9zdG9yZS51cGRhdGUoZGVsZXRlQWxsRW50aXRpZXMoKSwgZGVsZXRlQWxsUGFnZXMoKSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2V0QWN0aXZlKG5hbWU6IHN0cmluZyB8IG51bGwpOiB2b2lkIHtcclxuICAgIHRoaXMuX3N0b3JlLnVwZGF0ZShzZXRBY3RpdmVJZChuYW1lKSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgdXBkYXRlQWN0aXZlKHVzZXI6IFVzZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuICAgIGNvbnN0IHByb21pc2U6IFByb21pc2U8Ym9vbGVhbj4gPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgIHRoaXMuX3NhdmluZyQubmV4dCh0cnVlKTtcclxuXHJcbiAgICAgIHRoaXMuX2FjY1NlcnZpY2UudXBkYXRlVXNlcih1c2VyKS5zdWJzY3JpYmUoe1xyXG4gICAgICAgIG5leHQ6IChfKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLl9zYXZpbmckLm5leHQoZmFsc2UpO1xyXG4gICAgICAgICAgdGhpcy5fc3RvcmUudXBkYXRlKHVwc2VydEVudGl0aWVzKHVzZXIpKTtcclxuICAgICAgICAgIHJlc29sdmUodHJ1ZSk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlcnJvcjogKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLl9zYXZpbmckLm5leHQoZmFsc2UpO1xyXG4gICAgICAgICAgY29uc29sZS5lcnJvcihcclxuICAgICAgICAgICAgYEVycm9yIHVwZGF0aW5nIHVzZXIgJHt1c2VyLnVzZXJOYW1lfTogYCArXHJcbiAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkoZXJyb3IgfHwge30pXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgcmVzb2x2ZShmYWxzZSk7XHJcbiAgICAgICAgfSxcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICAgIHJldHVybiBwcm9taXNlO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGRlbGV0ZVVzZXIobmFtZTogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XHJcbiAgICBjb25zdCBwcm9taXNlOiBQcm9taXNlPGJvb2xlYW4+ID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICB0aGlzLl9zYXZpbmckLm5leHQodHJ1ZSk7XHJcblxyXG4gICAgICB0aGlzLl9hY2NTZXJ2aWNlLmRlbGV0ZVVzZXIobmFtZSkuc3Vic2NyaWJlKHtcclxuICAgICAgICBuZXh0OiAoXykgPT4ge1xyXG4gICAgICAgICAgdGhpcy5fc2F2aW5nJC5uZXh0KGZhbHNlKTtcclxuICAgICAgICAgIHRoaXMuY2xlYXJDYWNoZSgpO1xyXG4gICAgICAgICAgdGhpcy5sb2FkUGFnZSgxKTtcclxuICAgICAgICAgIHJlc29sdmUodHJ1ZSk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlcnJvcjogKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLl9zYXZpbmckLm5leHQoZmFsc2UpO1xyXG4gICAgICAgICAgY29uc29sZS5lcnJvcihcclxuICAgICAgICAgICAgYEVycm9yIGRlbGV0aW5nIHVzZXIgJHtuYW1lfTogYCArIEpTT04uc3RyaW5naWZ5KGVycm9yIHx8IHt9KVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHJlamVjdChlcnJvcik7XHJcbiAgICAgICAgfSxcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICAgIHJldHVybiBwcm9taXNlO1xyXG4gIH1cclxufVxyXG4iXX0=
@@ -0,0 +1,113 @@
1
+ import { Component, Input, Output, EventEmitter } from '@angular/core';
2
+ import { Validators, } from '@angular/forms';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@angular/forms";
5
+ import * as i2 from "@myrmidon/auth-jwt-login";
6
+ import * as i3 from "@angular/common";
7
+ import * as i4 from "@angular/material/button";
8
+ import * as i5 from "@angular/material/checkbox";
9
+ import * as i6 from "@angular/material/icon";
10
+ import * as i7 from "@angular/material/input";
11
+ import * as i8 from "@angular/material/form-field";
12
+ import * as i9 from "@angular/material/tooltip";
13
+ class UserEditorComponent {
14
+ set user(value) {
15
+ this._user = value;
16
+ this.updateForm(value);
17
+ }
18
+ get user() {
19
+ return this._user;
20
+ }
21
+ constructor(formBuilder, _authService) {
22
+ this._authService = _authService;
23
+ // events
24
+ this.userChange = new EventEmitter();
25
+ this.editorClose = new EventEmitter();
26
+ // form
27
+ this.email = formBuilder.control(null, [
28
+ Validators.required,
29
+ Validators.email,
30
+ ]);
31
+ this.emailConfirmed = formBuilder.control(false);
32
+ this.lockoutEnabled = formBuilder.control(false);
33
+ this.firstName = formBuilder.control(null, [
34
+ Validators.required,
35
+ Validators.maxLength(50),
36
+ ]);
37
+ this.lastName = formBuilder.control(null, [
38
+ Validators.required,
39
+ Validators.maxLength(50),
40
+ ]);
41
+ this.roles = formBuilder.control(null, Validators.maxLength(200));
42
+ this.form = formBuilder.group({
43
+ email: this.email,
44
+ emailConfirmed: this.emailConfirmed,
45
+ lockoutEnabled: this.lockoutEnabled,
46
+ firstName: this.firstName,
47
+ lastName: this.lastName,
48
+ roles: this.roles,
49
+ });
50
+ }
51
+ ngOnInit() { }
52
+ updateForm(user) {
53
+ if (!user) {
54
+ this.form.reset();
55
+ }
56
+ else {
57
+ this.email.setValue(user.email);
58
+ this.emailConfirmed.setValue(user.emailConfirmed);
59
+ this.lockoutEnabled.setValue(user.lockoutEnabled);
60
+ this.firstName.setValue(user.firstName);
61
+ this.lastName.setValue(user.lastName);
62
+ if (user.roles?.length > 0) {
63
+ this.roles.setValue(user.roles.join(' '));
64
+ }
65
+ else {
66
+ this.roles.setValue(null);
67
+ }
68
+ }
69
+ }
70
+ getUserFromForm() {
71
+ return {
72
+ userName: this._user?.userName || '',
73
+ email: this.email.value,
74
+ emailConfirmed: this.emailConfirmed.value,
75
+ lockoutEnabled: this.lockoutEnabled.value,
76
+ firstName: this.firstName.value,
77
+ lastName: this.lastName.value,
78
+ roles: this.roles.value
79
+ ? this.roles.value.split(' ').filter((s) => s)
80
+ : [],
81
+ };
82
+ }
83
+ endLockout() {
84
+ if (this.unlocked) {
85
+ return;
86
+ }
87
+ this._user.lockoutEnd = this._authService.getUTCDate();
88
+ this.unlocked = true;
89
+ }
90
+ close() {
91
+ this.editorClose.emit();
92
+ }
93
+ save() {
94
+ if (this.form.invalid) {
95
+ return;
96
+ }
97
+ this.userChange.emit(this.getUserFromForm());
98
+ }
99
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: UserEditorComponent, deps: [{ token: i1.UntypedFormBuilder }, { token: i2.AuthJwtService }], target: i0.ɵɵFactoryTarget.Component }); }
100
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.1", type: UserEditorComponent, selector: "auth-jwt-user-editor", inputs: { user: "user" }, outputs: { userChange: "userChange", editorClose: "editorClose" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\n <div class=\"form-row\">\n <!-- email -->\n <mat-form-field>\n <mat-label i18n>email</mat-label>\n <input type=\"text\" matInput [formControl]=\"email\" />\n <mat-error\n i18n\n *ngIf=\"email.hasError('required') && (email.dirty || email.touched)\"\n >\n email address required\n </mat-error>\n <mat-error\n i18n\n *ngIf=\"email.hasError('pattern') && (email.dirty || email.touched)\"\n >\n invalid email address\n </mat-error>\n </mat-form-field>\n\n <!-- emailConfirmed -->\n <mat-checkbox [formControl]=\"emailConfirmed\" i18n\n >email address confirmed</mat-checkbox\n >\n </div>\n\n <!-- lockoutEnabled -->\n <div class=\"form-row\">\n <mat-checkbox [formControl]=\"lockoutEnabled\" i18n\n >lockout enabled</mat-checkbox\n >\n <button\n mat-icon-button\n color=\"primary\"\n (click)=\"endLockout()\"\n [disabled]=\"unlocked\"\n i18n-matTooltip\n matTooltip=\"Unlock this user if locked\"\n >\n <mat-icon>lock_open</mat-icon>\n </button>\n </div>\n\n <div class=\"form-row\">\n <!-- firstName -->\n <mat-form-field>\n <mat-label i18n>first name</mat-label>\n <input type=\"text\" matInput [formControl]=\"firstName\" />\n <mat-error\n i18n\n *ngIf=\"\n firstName.hasError('required') &&\n (firstName.dirty || firstName.touched)\n \"\n >\n first name required\n </mat-error>\n <mat-error\n i18n\n *ngIf=\"\n firstName.hasError('maxlength') &&\n (firstName.dirty || firstName.touched)\n \"\n >\n first name too long\n </mat-error>\n </mat-form-field>\n\n <!-- lastName -->\n <mat-form-field>\n <mat-label i18n>last name</mat-label>\n <input type=\"text\" matInput [formControl]=\"lastName\" />\n <mat-error\n i18n\n *ngIf=\"\n lastName.hasError('required') && (lastName.dirty || lastName.touched)\n \"\n >\n last name required\n </mat-error>\n <mat-error\n i18n\n *ngIf=\"\n lastName.hasError('maxlength') && (lastName.dirty || lastName.touched)\n \"\n >\n last name too long\n </mat-error>\n </mat-form-field>\n </div>\n\n <!-- roles -->\n <div>\n <mat-form-field style=\"width: 16em\">\n <mat-label i18n>roles</mat-label>\n <input type=\"text\" matInput [formControl]=\"roles\" />\n <mat-error\n i18n\n *ngIf=\"roles.hasError('maxlength') && (roles.dirty || roles.touched)\"\n >\n too long\n </mat-error>\n <mat-hint i18n>roles (separated by space)</mat-hint>\n </mat-form-field>\n </div>\n\n <!-- buttons -->\n <br />\n <div>\n <button\n type=\"button\"\n mat-icon-button\n color=\"warn\"\n i18n-matTooltip\n matTooltip=\"Close\"\n (click)=\"close()\"\n >\n <mat-icon>cancel</mat-icon>\n </button>\n <button\n type=\"submit\"\n mat-icon-button\n color=\"primary\"\n [disabled]=\"form.invalid\"\n i18n-matTooltip\n matTooltip=\"Save user\"\n >\n <mat-icon>check_circle</mat-icon>\n </button>\n </div>\n</form>\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i8.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i8.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] }); }
101
+ }
102
+ export { UserEditorComponent };
103
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: UserEditorComponent, decorators: [{
104
+ type: Component,
105
+ args: [{ selector: 'auth-jwt-user-editor', template: "<form [formGroup]=\"form\" (submit)=\"save()\">\n <div class=\"form-row\">\n <!-- email -->\n <mat-form-field>\n <mat-label i18n>email</mat-label>\n <input type=\"text\" matInput [formControl]=\"email\" />\n <mat-error\n i18n\n *ngIf=\"email.hasError('required') && (email.dirty || email.touched)\"\n >\n email address required\n </mat-error>\n <mat-error\n i18n\n *ngIf=\"email.hasError('pattern') && (email.dirty || email.touched)\"\n >\n invalid email address\n </mat-error>\n </mat-form-field>\n\n <!-- emailConfirmed -->\n <mat-checkbox [formControl]=\"emailConfirmed\" i18n\n >email address confirmed</mat-checkbox\n >\n </div>\n\n <!-- lockoutEnabled -->\n <div class=\"form-row\">\n <mat-checkbox [formControl]=\"lockoutEnabled\" i18n\n >lockout enabled</mat-checkbox\n >\n <button\n mat-icon-button\n color=\"primary\"\n (click)=\"endLockout()\"\n [disabled]=\"unlocked\"\n i18n-matTooltip\n matTooltip=\"Unlock this user if locked\"\n >\n <mat-icon>lock_open</mat-icon>\n </button>\n </div>\n\n <div class=\"form-row\">\n <!-- firstName -->\n <mat-form-field>\n <mat-label i18n>first name</mat-label>\n <input type=\"text\" matInput [formControl]=\"firstName\" />\n <mat-error\n i18n\n *ngIf=\"\n firstName.hasError('required') &&\n (firstName.dirty || firstName.touched)\n \"\n >\n first name required\n </mat-error>\n <mat-error\n i18n\n *ngIf=\"\n firstName.hasError('maxlength') &&\n (firstName.dirty || firstName.touched)\n \"\n >\n first name too long\n </mat-error>\n </mat-form-field>\n\n <!-- lastName -->\n <mat-form-field>\n <mat-label i18n>last name</mat-label>\n <input type=\"text\" matInput [formControl]=\"lastName\" />\n <mat-error\n i18n\n *ngIf=\"\n lastName.hasError('required') && (lastName.dirty || lastName.touched)\n \"\n >\n last name required\n </mat-error>\n <mat-error\n i18n\n *ngIf=\"\n lastName.hasError('maxlength') && (lastName.dirty || lastName.touched)\n \"\n >\n last name too long\n </mat-error>\n </mat-form-field>\n </div>\n\n <!-- roles -->\n <div>\n <mat-form-field style=\"width: 16em\">\n <mat-label i18n>roles</mat-label>\n <input type=\"text\" matInput [formControl]=\"roles\" />\n <mat-error\n i18n\n *ngIf=\"roles.hasError('maxlength') && (roles.dirty || roles.touched)\"\n >\n too long\n </mat-error>\n <mat-hint i18n>roles (separated by space)</mat-hint>\n </mat-form-field>\n </div>\n\n <!-- buttons -->\n <br />\n <div>\n <button\n type=\"button\"\n mat-icon-button\n color=\"warn\"\n i18n-matTooltip\n matTooltip=\"Close\"\n (click)=\"close()\"\n >\n <mat-icon>cancel</mat-icon>\n </button>\n <button\n type=\"submit\"\n mat-icon-button\n color=\"primary\"\n [disabled]=\"form.invalid\"\n i18n-matTooltip\n matTooltip=\"Save user\"\n >\n <mat-icon>check_circle</mat-icon>\n </button>\n </div>\n</form>\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"] }]
106
+ }], ctorParameters: function () { return [{ type: i1.UntypedFormBuilder }, { type: i2.AuthJwtService }]; }, propDecorators: { user: [{
107
+ type: Input
108
+ }], userChange: [{
109
+ type: Output
110
+ }], editorClose: [{
111
+ type: Output
112
+ }] } });
113
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1lZGl0b3IuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbXlybWlkb24vYXV0aC1qd3QtYWRtaW4vc3JjL2xpYi9jb21wb25lbnRzL3VzZXItZWRpdG9yL3VzZXItZWRpdG9yLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL215cm1pZG9uL2F1dGgtand0LWFkbWluL3NyYy9saWIvY29tcG9uZW50cy91c2VyLWVkaXRvci91c2VyLWVkaXRvci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQy9FLE9BQU8sRUFJTCxVQUFVLEdBQ1gsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7Ozs7Ozs7QUFHeEIsTUFLYSxtQkFBbUI7SUFhOUIsSUFBb0IsSUFBSSxDQUFDLEtBQXVCO1FBQzlDLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDekIsQ0FBQztJQUNELElBQVcsSUFBSTtRQUNiLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztJQUNwQixDQUFDO0lBS0QsWUFBWSxXQUErQixFQUFVLFlBQTRCO1FBQTVCLGlCQUFZLEdBQVosWUFBWSxDQUFnQjtRQUMvRSxTQUFTO1FBQ1QsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQzNDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUMzQyxPQUFPO1FBQ1AsSUFBSSxDQUFDLEtBQUssR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRTtZQUNyQyxVQUFVLENBQUMsUUFBUTtZQUNuQixVQUFVLENBQUMsS0FB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UyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RELENBQUMsQ0FBQyxFQUFFO1NBQ1AsQ0FBQztJQUNKLENBQUM7SUFFTSxVQUFVO1FBQ2YsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ2pCLE9BQU87U0FDUjtRQUNELElBQUksQ0FBQyxLQUFNLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDeEQsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7SUFDdkIsQ0FBQztJQUVNLEtBQUs7UUFDVixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFFTSxJQUFJO1FBQ1QsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNyQixPQUFPO1NBQ1I7UUFDRCxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQztJQUMvQyxDQUFDOzhHQXpHVSxtQkFBbUI7a0dBQW5CLG1CQUFtQix5SkNkaEMsc3hHQW1JQTs7U0RySGEsbUJBQW1COzJGQUFuQixtQkFBbUI7a0JBTC9CLFNBQVM7K0JBQ0Usc0JBQXNCO3NJQWlCWixJQUFJO3NCQUF2QixLQUFLO2dCQVFJLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csV0FBVztzQkFBcEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIFVudHlwZWRGb3JtR3JvdXAsXG4gIFVudHlwZWRGb3JtQ29udHJvbCxcbiAgVW50eXBlZEZvcm1CdWlsZGVyLFxuICBWYWxpZGF0b3JzLFxufSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBBdXRoSnd0U2VydmljZSwgVXNlciB9IGZyb20gJ0BteXJtaWRvbi9hdXRoLWp3dC1sb2dpbic7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2F1dGgtand0LXVzZXItZWRpdG9yJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3VzZXItZWRpdG9yLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vdXNlci1lZGl0b3IuY29tcG9uZW50LmNzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBVc2VyRWRpdG9yQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgcHJpdmF0ZSBfdXNlcjogVXNlciB8IHVuZGVmaW5lZDtcblxuICBwdWJsaWMgZW1haWw6IFVudHlwZWRGb3JtQ29udHJvbDtcbiAgcHVibGljIGVtYWlsQ29uZmlybWVkOiBVbnR5cGVkRm9ybUNvbnRyb2w7XG4gIHB1YmxpYyBsb2Nrb3V0RW5hYmxlZDogVW50eXBlZEZvcm1Db250cm9sO1xuICBwdWJsaWMgZmlyc3ROYW1lOiBVbnR5cGVkRm9ybUNvbnRyb2w7XG4gIHB1YmxpYyBsYXN0TmFtZTogVW50eXBlZEZvcm1Db250cm9sO1xuICBwdWJsaWMgcm9sZXM6IFVudHlwZWRGb3JtQ29udHJvbDtcbiAgcHVibGljIGZvcm06IFVudHlwZWRGb3JtR3JvdXA7XG5cbiAgcHVibGljIHVubG9ja2VkOiBib29sZWFuIHwgdW5kZWZpbmVkO1xuXG4gIEBJbnB1dCgpIHB1YmxpYyBzZXQgdXNlcih2YWx1ZTogVXNlciB8IHVuZGVmaW5lZCkge1xuICAgIHRoaXMuX3VzZXIgPSB2YWx1ZTtcbiAgICB0aGlzLnVwZGF0ZUZvcm0odmFsdWUpO1xuICB9XG4gIHB1YmxpYyBnZXQgdXNlcigpOiBVc2VyIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5fdXNlcjtcbiAgfVxuXG4gIEBPdXRwdXQoKSB1c2VyQ2hhbmdlOiBFdmVudEVtaXR0ZXI8VXNlcj47XG4gIEBPdXRwdXQoKSBlZGl0b3JDbG9zZTogRXZlbnRFbWl0dGVyPGFueT47XG5cbiAgY29uc3RydWN0b3IoZm9ybUJ1aWxkZXI6IFVudHlwZWRGb3JtQnVpbGRlciwgcHJpdmF0ZSBfYXV0aFNlcnZpY2U6IEF1dGhKd3RTZXJ2aWNlKSB7XG4gICAgLy8gZXZlbnRzXG4gICAgdGhpcy51c2VyQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxVc2VyPigpO1xuICAgIHRoaXMuZWRpdG9yQ2xvc2UgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgICAvLyBmb3JtXG4gICAgdGhpcy5lbWFpbCA9IGZvcm1CdWlsZGVyLmNvbnRyb2wobnVsbCwgW1xuICAgICAgVmFsaWRhdG9ycy5yZXF1aXJlZCxcbiAgICAgIFZhbGlkYXRvcnMuZW1haWwsXG4gICAgXSk7XG4gICAgdGhpcy5lbWFpbENvbmZpcm1lZCA9IGZvcm1CdWlsZGVyLmNvbnRyb2woZmFsc2UpO1xuICAgIHRoaXMubG9ja291dEVuYWJsZWQgPSBmb3JtQnVpbGRlci5jb250cm9sKGZhbHNlKTtcbiAgICB0aGlzLmZpcnN0TmFtZSA9IGZvcm1CdWlsZGVyLmNvbnRyb2wobnVsbCwgW1xuICAgICAgVmFsaWRhdG9ycy5yZXF1aXJlZCxcbiAgICAgIFZhbGlkYXRvcnMubWF4TGVuZ3RoKDUwKSxcbiAgICBdKTtcbiAgICB0aGlzLmxhc3ROYW1lID0gZm9ybUJ1aWxkZXIuY29udHJvbChudWxsLCBbXG4gICAgICBWYWxpZGF0b3JzLnJlcXVpcmVkLFxuICAgICAgVmFsaWRhdG9ycy5tYXhMZW5ndGgoNTApLFxuICAgIF0pO1xuICAgIHRoaXMucm9sZXMgPSBmb3JtQnVpbGRlci5jb250cm9sKG51bGwsIFZhbGlkYXRvcnMubWF4TGVuZ3RoKDIwMCkpO1xuXG4gICAgdGhpcy5mb3JtID0gZm9ybUJ1aWxkZXIuZ3JvdXAoe1xuICAgICAgZW1haWw6IHRoaXMuZW1haWwsXG4gICAgICBlbWFpbENvbmZpcm1lZDogdGhpcy5lbWFpbENvbmZpcm1lZCxcbiAgICAgIGxvY2tvdXRFbmFibGVkOiB0aGlzLmxvY2tvdXRFbmFibGVkLFxuICAgICAgZmlyc3ROYW1lOiB0aGlzLmZpcnN0TmFtZSxcbiAgICAgIGxhc3ROYW1lOiB0aGlzLmxhc3ROYW1lLFxuICAgICAgcm9sZXM6IHRoaXMucm9sZXMsXG4gICAgfSk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHt9XG5cbiAgcHJpdmF0ZSB1cGRhdGVGb3JtKHVzZXI6IFVzZXIgfCB1bmRlZmluZWQpOiB2b2lkIHtcbiAgICBpZiAoIXVzZXIpIHtcbiAgICAgIHRoaXMuZm9ybS5yZXNldCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmVtYWlsLnNldFZhbHVlKHVzZXIuZW1haWwpO1xuICAgICAgdGhpcy5lbWFpbENvbmZpcm1lZC5zZXRWYWx1ZSh1c2VyLmVtYWlsQ29uZmlybWVkKTtcbiAgICAgIHRoaXMubG9ja291dEVuYWJsZWQuc2V0VmFsdWUodXNlci5sb2Nrb3V0RW5hYmxlZCk7XG4gICAgICB0aGlzLmZpcnN0TmFtZS5zZXRWYWx1ZSh1c2VyLmZpcnN0TmFtZSk7XG4gICAgICB0aGlzLmxhc3ROYW1lLnNldFZhbHVlKHVzZXIubGFzdE5hbWUpO1xuICAgICAgaWYgKHVzZXIucm9sZXM/Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5yb2xlcy5zZXRWYWx1ZSh1c2VyLnJvbGVzLmpvaW4oJyAnKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnJvbGVzLnNldFZhbHVlKG51bGwpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0VXNlckZyb21Gb3JtKCk6IFVzZXIge1xuICAgIHJldHVybiB7XG4gICAgICB1c2VyTmFtZTogdGhpcy5fdXNlcj8udXNlck5hbWUgfHwgJycsXG4gICAgICBlbWFpbDogdGhpcy5lbWFpbC52YWx1ZSxcbiAgICAgIGVtYWlsQ29uZmlybWVkOiB0aGlzLmVtYWlsQ29uZmlybWVkLnZhbHVlLFxuICAgICAgbG9ja291dEVuYWJsZWQ6IHRoaXMubG9ja291dEVuYWJsZWQudmFsdWUsXG4gICAgICBmaXJzdE5hbWU6IHRoaXMuZmlyc3ROYW1lLnZhbHVlLFxuICAgICAgbGFzdE5hbWU6IHRoaXMubGFzdE5hbWUudmFsdWUsXG4gICAgICByb2xlczogdGhpcy5yb2xlcy52YWx1ZVxuICAgICAgICA/IHRoaXMucm9sZXMudmFsdWUuc3BsaXQoJyAnKS5maWx0ZXIoKHM6IHN0cmluZykgPT4gcylcbiAgICAgICAgOiBbXSxcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIGVuZExvY2tvdXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMudW5sb2NrZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fdXNlciEubG9ja291dEVuZCA9IHRoaXMuX2F1dGhTZXJ2aWNlLmdldFVUQ0RhdGUoKTtcbiAgICB0aGlzLnVubG9ja2VkID0gdHJ1ZTtcbiAgfVxuXG4gIHB1YmxpYyBjbG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLmVkaXRvckNsb3NlLmVtaXQoKTtcbiAgfVxuXG4gIHB1YmxpYyBzYXZlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmZvcm0uaW52YWxpZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnVzZXJDaGFuZ2UuZW1pdCh0aGlzLmdldFVzZXJGcm9tRm9ybSgpKTtcbiAgfVxufVxuIiwiPGZvcm0gW2Zvcm1Hcm91cF09XCJmb3JtXCIgKHN1Ym1pdCk9XCJzYXZlKClcIj5cbiAgPGRpdiBjbGFzcz1cImZvcm0tcm93XCI+XG4gICAgPCEtLSBlbWFpbCAtLT5cbiAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICA8bWF0LWxhYmVsIGkxOG4+ZW1haWw8L21hdC1sYWJlbD5cbiAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIG1hdElucHV0IFtmb3JtQ29udHJvbF09XCJlbWFpbFwiIC8+XG4gICAgICA8bWF0LWVycm9yXG4gICAgICAgIGkxOG5cbiAgICAgICAgKm5nSWY9XCJlbWFpbC5oYXNFcnJvcigncmVxdWlyZWQnKSAmJiAoZW1haWwuZGlydHkgfHwgZW1haWwudG91Y2hlZClcIlxuICAgICAgPlxuICAgICAgICBlbWFpbCBhZGRyZXNzIHJlcXVpcmVkXG4gICAgICA8L21hdC1lcnJvcj5cbiAgICAgIDxtYXQtZXJyb3JcbiAgICAgICAgaTE4blxuICAgICAgICAqbmdJZj1cImVtYWlsLmhhc0Vycm9yKCdwYXR0ZXJuJykgJiYgKGVtYWlsLmRpcnR5IHx8IGVtYWlsLnRvdWNoZWQpXCJcbiAgICAgID5cbiAgICAgICAgaW52YWxpZCBlbWFpbCBhZGRyZXNzXG4gICAgICA8L21hdC1lcnJvcj5cbiAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgPCEtLSBlbWFpbENvbmZpcm1lZCAtLT5cbiAgICA8bWF0LWNoZWNrYm94IFtmb3JtQ29udHJvbF09XCJlbWFpbENvbmZpcm1lZFwiIGkxOG5cbiAgICAgID5lbWFpbCBhZGRyZXNzIGNvbmZpcm1lZDwvbWF0LWNoZWNrYm94XG4gICAgPlxuICA8L2Rpdj5cblxuICA8IS0tIGxvY2tvdXRFbmFibGVkIC0tPlxuICA8ZGl2IGNsYXNzPVwiZm9ybS1yb3dcIj5cbiAgICA8bWF0LWNoZWNrYm94IFtmb3JtQ29udHJvbF09XCJsb2Nrb3V0RW5hYmxlZFwiIGkxOG5cbiAgICAgID5sb2Nrb3V0IGVuYWJsZWQ8L21hdC1jaGVja2JveFxuICAgID5cbiAgICA8YnV0dG9uXG4gICAgICBtYXQtaWNvbi1idXR0b25cbiAgICAgIGNvbG9yPVwicHJpbWFyeVwiXG4gICAgICAoY2xpY2spPVwiZW5kTG9ja291dCgpXCJcbiAgICAgIFtkaXNhYmxlZF09XCJ1bmxvY2tlZFwiXG4gICAgICBpMThuLW1hdFRvb2x0aXBcbiAgICAgIG1hdFRvb2x0aXA9XCJVbmxvY2sgdGhpcyB1c2VyIGlmIGxvY2tlZFwiXG4gICAgPlxuICAgICAgPG1hdC1pY29uPmxvY2tfb3BlbjwvbWF0LWljb24+XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJmb3JtLXJvd1wiPlxuICAgIDwhLS0gZmlyc3ROYW1lIC0tPlxuICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgIDxtYXQtbGFiZWwgaTE4bj5maXJzdCBuYW1lPC9tYXQtbGFiZWw+XG4gICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBtYXRJbnB1dCBbZm9ybUNvbnRyb2xdPVwiZmlyc3ROYW1lXCIgLz5cbiAgICAgIDxtYXQtZXJyb3JcbiAgICAgICAgaTE4blxuICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgIGZpcnN0TmFtZS5oYXNFcnJvcigncmVxdWlyZWQnKSAmJlxuICAgICAgICAgIChmaXJzdE5hbWUuZGlydHkgfHwgZmlyc3ROYW1lLnRvdWNoZWQpXG4gICAgICAgIFwiXG4gICAgICA+XG4gICAgICAgIGZpcnN0IG5hbWUgcmVxdWlyZWRcbiAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgPG1hdC1lcnJvclxuICAgICAgICBpMThuXG4gICAgICAgICpuZ0lmPVwiXG4gICAgICAgICAgZmlyc3ROYW1lLmhhc0Vycm9yKCdtYXhsZW5ndGgnKSAmJlxuICAgICAgICAgIChmaXJzdE5hbWUuZGlydHkgfHwgZmlyc3ROYW1lLnRvdWNoZWQpXG4gICAgICAgIFwiXG4gICAgICA+XG4gICAgICAgIGZpcnN0IG5hbWUgdG9vIGxvbmdcbiAgICAgIDwvbWF0LWVycm9yPlxuICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICA8IS0tIGxhc3ROYW1lIC0tPlxuICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgIDxtYXQtbGFiZWwgaTE4bj5sYXN0IG5hbWU8L21hdC1sYWJlbD5cbiAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIG1hdElucHV0IFtmb3JtQ29udHJvbF09XCJsYXN0TmFtZVwiIC8+XG4gICAgICA8bWF0LWVycm9yXG4gICAgICAgIGkxOG5cbiAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICBsYXN0TmFtZS5oYXNFcnJvcigncmVxdWlyZWQnKSAmJiAobGFzdE5hbWUuZGlydHkgfHwgbGFzdE5hbWUudG91Y2hlZClcbiAgICAgICAgXCJcbiAgICAgID5cbiAgICAgICAgbGFzdCBuYW1lIHJlcXVpcmVkXG4gICAgICA8L21hdC1lcnJvcj5cbiAgICAgIDxtYXQtZXJyb3JcbiAgICAgICAgaTE4blxuICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgIGxhc3ROYW1lLmhhc0Vycm9yKCdtYXhsZW5ndGgnKSAmJiAobGFzdE5hbWUuZGlydHkgfHwgbGFzdE5hbWUudG91Y2hlZClcbiAgICAgICAgXCJcbiAgICAgID5cbiAgICAgICAgbGFzdCBuYW1lIHRvbyBsb25nXG4gICAgICA8L21hdC1lcnJvcj5cbiAgICA8L21hdC1mb3JtLWZpZWxkPlxuICA8L2Rpdj5cblxuICA8IS0tIHJvbGVzIC0tPlxuICA8ZGl2PlxuICAgIDxtYXQtZm9ybS1maWVsZCBzdHlsZT1cIndpZHRoOiAxNmVtXCI+XG4gICAgICA8bWF0LWxhYmVsIGkxOG4+cm9sZXM8L21hdC1sYWJlbD5cbiAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIG1hdElucHV0IFtmb3JtQ29udHJvbF09XCJyb2xlc1wiIC8+XG4gICAgICA8bWF0LWVycm9yXG4gICAgICAgIGkxOG5cbiAgICAgICAgKm5nSWY9XCJyb2xlcy5oYXNFcnJvcignbWF4bGVuZ3RoJykgJiYgKHJvbGVzLmRpcnR5IHx8IHJvbGVzLnRvdWNoZWQpXCJcbiAgICAgID5cbiAgICAgICAgdG9vIGxvbmdcbiAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgPG1hdC1oaW50IGkxOG4+cm9sZXMgKHNlcGFyYXRlZCBieSBzcGFjZSk8L21hdC1oaW50PlxuICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gIDwvZGl2PlxuXG4gIDwhLS0gYnV0dG9ucyAtLT5cbiAgPGJyIC8+XG4gIDxkaXY+XG4gICAgPGJ1dHRvblxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICBtYXQtaWNvbi1idXR0b25cbiAgICAgIGNvbG9yPVwid2FyblwiXG4gICAgICBpMThuLW1hdFRvb2x0aXBcbiAgICAgIG1hdFRvb2x0aXA9XCJDbG9zZVwiXG4gICAgICAoY2xpY2spPVwiY2xvc2UoKVwiXG4gICAgPlxuICAgICAgPG1hdC1pY29uPmNhbmNlbDwvbWF0LWljb24+XG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvblxuICAgICAgdHlwZT1cInN1Ym1pdFwiXG4gICAgICBtYXQtaWNvbi1idXR0b25cbiAgICAgIGNvbG9yPVwicHJpbWFyeVwiXG4gICAgICBbZGlzYWJsZWRdPVwiZm9ybS5pbnZhbGlkXCJcbiAgICAgIGkxOG4tbWF0VG9vbHRpcFxuICAgICAgbWF0VG9vbHRpcD1cIlNhdmUgdXNlclwiXG4gICAgPlxuICAgICAgPG1hdC1pY29uPmNoZWNrX2NpcmNsZTwvbWF0LWljb24+XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuPC9mb3JtPlxuIl19
@@ -0,0 +1,56 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "@angular/forms";
4
+ import * as i2 from "../state/user-list.repository";
5
+ import * as i3 from "@angular/material/button";
6
+ import * as i4 from "@angular/material/icon";
7
+ import * as i5 from "@angular/material/input";
8
+ import * as i6 from "@angular/material/form-field";
9
+ import * as i7 from "@angular/material/tooltip";
10
+ class UserFilterComponent {
11
+ constructor(formBuilder, _repository) {
12
+ this._repository = _repository;
13
+ this.filter$ = _repository.filter$;
14
+ // form
15
+ this.name = formBuilder.control(null);
16
+ this.form = formBuilder.group({
17
+ name: this.name,
18
+ });
19
+ }
20
+ ngOnInit() {
21
+ this.filter$.subscribe((f) => {
22
+ this.updateForm(f);
23
+ });
24
+ }
25
+ updateForm(filter) {
26
+ this.name.setValue(filter.name || null);
27
+ this.form.markAsPristine();
28
+ }
29
+ reset() {
30
+ this.form.reset();
31
+ this.apply();
32
+ }
33
+ getFilter() {
34
+ return {
35
+ name: this.name.value?.trim(),
36
+ };
37
+ }
38
+ apply() {
39
+ if (this.form.invalid) {
40
+ return;
41
+ }
42
+ const filter = this.getFilter();
43
+ // update filter in state
44
+ this._repository.setFilter(filter);
45
+ }
46
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: UserFilterComponent, deps: [{ token: i1.FormBuilder }, { token: i2.UserListRepository }], target: i0.ɵɵFactoryTarget.Component }); }
47
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.1", type: UserFilterComponent, selector: "auth-jwt-user-filter", inputs: { disabled: "disabled" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"apply()\" ng-disabled=\"disabled\">\n <div class=\"form-row\">\n <mat-form-field>\n <mat-label i18n>name or ID</mat-label>\n <input matInput [formControl]=\"name\" />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n (click)=\"reset()\"\n color=\"warn\"\n i18n-matTooltip\n matTooltip=\"Reset filters\"\n [disabled]=\"disabled\"\n >\n <mat-icon>clear</mat-icon>\n </button>\n </mat-form-field>\n\n <button\n style=\"margin-top: -20px\"\n type=\"submit\"\n mat-icon-button\n color=\"primary\"\n [disabled]=\"disabled\"\n i18n-matTooltip\n matTooltip=\"Apply filters\"\n >\n <mat-icon>check_circle</mat-icon>\n </button>\n </div>\n</form>\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"], dependencies: [{ kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5.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: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] }); }
48
+ }
49
+ export { UserFilterComponent };
50
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: UserFilterComponent, decorators: [{
51
+ type: Component,
52
+ args: [{ selector: 'auth-jwt-user-filter', template: "<form [formGroup]=\"form\" (submit)=\"apply()\" ng-disabled=\"disabled\">\n <div class=\"form-row\">\n <mat-form-field>\n <mat-label i18n>name or ID</mat-label>\n <input matInput [formControl]=\"name\" />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n (click)=\"reset()\"\n color=\"warn\"\n i18n-matTooltip\n matTooltip=\"Reset filters\"\n [disabled]=\"disabled\"\n >\n <mat-icon>clear</mat-icon>\n </button>\n </mat-form-field>\n\n <button\n style=\"margin-top: -20px\"\n type=\"submit\"\n mat-icon-button\n color=\"primary\"\n [disabled]=\"disabled\"\n i18n-matTooltip\n matTooltip=\"Apply filters\"\n >\n <mat-icon>check_circle</mat-icon>\n </button>\n </div>\n</form>\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"] }]
53
+ }], ctorParameters: function () { return [{ type: i1.FormBuilder }, { type: i2.UserListRepository }]; }, propDecorators: { disabled: [{
54
+ type: Input
55
+ }] } });
56
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1maWx0ZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbXlybWlkb24vYXV0aC1qd3QtYWRtaW4vc3JjL2xpYi9jb21wb25lbnRzL3VzZXItZmlsdGVyL3VzZXItZmlsdGVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL215cm1pZG9uL2F1dGgtand0LWFkbWluL3NyYy9saWIvY29tcG9uZW50cy91c2VyLWZpbHRlci91c2VyLWZpbHRlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBVSxNQUFNLGVBQWUsQ0FBQzs7Ozs7Ozs7O0FBT3pELE1BS2EsbUJBQW1CO0lBUzlCLFlBQ0UsV0FBd0IsRUFDaEIsV0FBK0I7UUFBL0IsZ0JBQVcsR0FBWCxXQUFXLENBQW9CO1FBRXZDLElBQUksQ0FBQyxPQUFPLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQztRQUVuQyxPQUFPO1FBQ1AsSUFBSSxDQUFDLElBQUksR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFnQixJQUFJLENBQUMsQ0FBQztRQUNyRCxJQUFJLENBQUMsSUFBSSxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUM7WUFDNUIsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO1NBQ2hCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxRQUFRO1FBQ04sSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUMzQixJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLFVBQVUsQ0FBQyxNQUFrQjtRQUNuQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxDQUFDO1FBQ3hDLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVNLEtBQUs7UUFDVixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNmLENBQUM7SUFFTyxTQUFTO1FBQ2YsT0FBTztZQUNMLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUU7U0FDOUIsQ0FBQztJQUNKLENBQUM7SUFFTSxLQUFLO1FBQ1YsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNyQixPQUFPO1NBQ1I7UUFDRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFFaEMseUJBQXlCO1FBQ3pCLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3JDLENBQUM7OEdBcERVLG1CQUFtQjtrR0FBbkIsbUJBQW1CLDhGQ1poQyxpMEJBZ0NBOztTRHBCYSxtQkFBbUI7MkZBQW5CLG1CQUFtQjtrQkFML0IsU0FBUzsrQkFDRSxzQkFBc0I7bUlBTXpCLFFBQVE7c0JBRGQsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUJ1aWxkZXIsIEZvcm1Db250cm9sLCBGb3JtR3JvdXAgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IFVzZXJGaWx0ZXIgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9hdXRoLWp3dC1hY2NvdW50LnNlcnZpY2UnO1xuaW1wb3J0IHsgVXNlckxpc3RSZXBvc2l0b3J5IH0gZnJvbSAnLi4vc3RhdGUvdXNlci1saXN0LnJlcG9zaXRvcnknO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhdXRoLWp3dC11c2VyLWZpbHRlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi91c2VyLWZpbHRlci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3VzZXItZmlsdGVyLmNvbXBvbmVudC5jc3MnXSxcbn0pXG5leHBvcnQgY2xhc3MgVXNlckZpbHRlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBkaXNhYmxlZDogYm9vbGVhbiB8IHVuZGVmaW5lZDtcblxuICBwdWJsaWMgZmlsdGVyJDogT2JzZXJ2YWJsZTxVc2VyRmlsdGVyPjtcblxuICBwdWJsaWMgbmFtZTogRm9ybUNvbnRyb2w8c3RyaW5nIHwgbnVsbD47XG4gIHB1YmxpYyBmb3JtOiBGb3JtR3JvdXA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgZm9ybUJ1aWxkZXI6IEZvcm1CdWlsZGVyLFxuICAgIHByaXZhdGUgX3JlcG9zaXRvcnk6IFVzZXJMaXN0UmVwb3NpdG9yeVxuICApIHtcbiAgICB0aGlzLmZpbHRlciQgPSBfcmVwb3NpdG9yeS5maWx0ZXIkO1xuXG4gICAgLy8gZm9ybVxuICAgIHRoaXMubmFtZSA9IGZvcm1CdWlsZGVyLmNvbnRyb2w8c3RyaW5nIHwgbnVsbD4obnVsbCk7XG4gICAgdGhpcy5mb3JtID0gZm9ybUJ1aWxkZXIuZ3JvdXAoe1xuICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgIH0pO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5maWx0ZXIkLnN1YnNjcmliZSgoZikgPT4ge1xuICAgICAgdGhpcy51cGRhdGVGb3JtKGYpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVGb3JtKGZpbHRlcjogVXNlckZpbHRlcik6IHZvaWQge1xuICAgIHRoaXMubmFtZS5zZXRWYWx1ZShmaWx0ZXIubmFtZSB8fCBudWxsKTtcbiAgICB0aGlzLmZvcm0ubWFya0FzUHJpc3RpbmUoKTtcbiAgfVxuXG4gIHB1YmxpYyByZXNldCgpOiB2b2lkIHtcbiAgICB0aGlzLmZvcm0ucmVzZXQoKTtcbiAgICB0aGlzLmFwcGx5KCk7XG4gIH1cblxuICBwcml2YXRlIGdldEZpbHRlcigpOiBVc2VyRmlsdGVyIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogdGhpcy5uYW1lLnZhbHVlPy50cmltKCksXG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyBhcHBseSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5mb3JtLmludmFsaWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZmlsdGVyID0gdGhpcy5nZXRGaWx0ZXIoKTtcblxuICAgIC8vIHVwZGF0ZSBmaWx0ZXIgaW4gc3RhdGVcbiAgICB0aGlzLl9yZXBvc2l0b3J5LnNldEZpbHRlcihmaWx0ZXIpO1xuICB9XG59XG4iLCI8Zm9ybSBbZm9ybUdyb3VwXT1cImZvcm1cIiAoc3VibWl0KT1cImFwcGx5KClcIiBuZy1kaXNhYmxlZD1cImRpc2FibGVkXCI+XG4gIDxkaXYgY2xhc3M9XCJmb3JtLXJvd1wiPlxuICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgIDxtYXQtbGFiZWwgaTE4bj5uYW1lIG9yIElEPC9tYXQtbGFiZWw+XG4gICAgICA8aW5wdXQgbWF0SW5wdXQgW2Zvcm1Db250cm9sXT1cIm5hbWVcIiAvPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBtYXQtaWNvbi1idXR0b25cbiAgICAgICAgbWF0U3VmZml4XG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAoY2xpY2spPVwicmVzZXQoKVwiXG4gICAgICAgIGNvbG9yPVwid2FyblwiXG4gICAgICAgIGkxOG4tbWF0VG9vbHRpcFxuICAgICAgICBtYXRUb29sdGlwPVwiUmVzZXQgZmlsdGVyc1wiXG4gICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG4gICAgICA+XG4gICAgICAgIDxtYXQtaWNvbj5jbGVhcjwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgPGJ1dHRvblxuICAgICAgc3R5bGU9XCJtYXJnaW4tdG9wOiAtMjBweFwiXG4gICAgICB0eXBlPVwic3VibWl0XCJcbiAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgY29sb3I9XCJwcmltYXJ5XCJcbiAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG4gICAgICBpMThuLW1hdFRvb2x0aXBcbiAgICAgIG1hdFRvb2x0aXA9XCJBcHBseSBmaWx0ZXJzXCJcbiAgICA+XG4gICAgICA8bWF0LWljb24+Y2hlY2tfY2lyY2xlPC9tYXQtaWNvbj5cbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG48L2Zvcm0+XG4iXX0=
@@ -0,0 +1,71 @@
1
+ import { Component } from '@angular/core';
2
+ import { take } from 'rxjs/operators';
3
+ import '@angular/localize/init';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "../state/user-list.repository";
6
+ import * as i2 from "../../services/dialog.service";
7
+ import * as i3 from "@myrmidon/auth-jwt-login";
8
+ import * as i4 from "@angular/common";
9
+ import * as i5 from "@angular/material/button";
10
+ import * as i6 from "@angular/material/expansion";
11
+ import * as i7 from "@angular/material/icon";
12
+ import * as i8 from "@angular/material/paginator";
13
+ import * as i9 from "@angular/material/progress-bar";
14
+ import * as i10 from "@angular/material/tooltip";
15
+ import * as i11 from "../user-filter/user-filter.component";
16
+ import * as i12 from "../user-editor/user-editor.component";
17
+ class UserListComponent {
18
+ constructor(_repository, _dialogService, _gravatarService) {
19
+ this._repository = _repository;
20
+ this._dialogService = _dialogService;
21
+ this._gravatarService = _gravatarService;
22
+ this.pagination$ = _repository.pagination$;
23
+ this.active$ = _repository.activeUser$;
24
+ this.loading$ = _repository.loading$;
25
+ }
26
+ pageChange(event) {
27
+ this._repository.loadPage(event.pageIndex + 1, event.pageSize);
28
+ }
29
+ deleteUser(user) {
30
+ this._dialogService
31
+ .confirm($localize `Confirm`, $localize `Delete user ${user.userName}?`)
32
+ .pipe(take(1))
33
+ .subscribe((yes) => {
34
+ if (!yes) {
35
+ return;
36
+ }
37
+ this._repository.deleteUser(user.userName).finally(() => {
38
+ this._repository.clearCache();
39
+ this._repository.loadPage(1);
40
+ });
41
+ });
42
+ }
43
+ setActiveUser(user) {
44
+ this._repository.setActive(user?.userName || null);
45
+ }
46
+ resetActiveUser() {
47
+ this._repository.setActive(null);
48
+ }
49
+ saveActiveUser(user) {
50
+ this._repository.updateActive(user);
51
+ this._repository.setActive(null);
52
+ }
53
+ onUserEditorClose() {
54
+ this._repository.setActive(null);
55
+ }
56
+ getGravatarUrl(email, size = 80) {
57
+ return this._gravatarService.buildGravatarUrl(email, size);
58
+ }
59
+ clearCache() {
60
+ this._repository.clearCache();
61
+ this._repository.loadPage(1);
62
+ }
63
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: UserListComponent, deps: [{ token: i1.UserListRepository }, { token: i2.DialogService }, { token: i3.GravatarService }], target: i0.ɵɵFactoryTarget.Component }); }
64
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.1", type: UserListComponent, selector: "auth-jwt-user-list", ngImport: i0, template: "<div id=\"container\">\n <div>\n <!-- filters -->\n <div id=\"filters\">\n <auth-jwt-user-filter></auth-jwt-user-filter>\n </div>\n\n <!-- list -->\n <div id=\"list\" *ngIf=\"pagination$ | async as pagination\">\n <div *ngIf=\"loading$ | async\" gdArea=\"progress\">\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n <table>\n <thead>\n <td></td>\n <td></td>\n <th i18n>name</th>\n <th i18n class=\"noif-lt-md\">first</th>\n <th i18n class=\"noif-lt-md\">last</th>\n <th i18n class=\"noif-lt-md\">email</th>\n <th i18n>roles</th>\n <th i18n class=\"noif-lt-md\">lock end</th>\n </thead>\n <tbody>\n <tr *ngFor=\"let user of pagination.data\">\n <td>\n <button\n mat-icon-button\n type=\"button\"\n i18n-matTooltip\n matTooltip=\"Edit this user\"\n color=\"primary\"\n (click)=\"setActiveUser(user)\"\n >\n <mat-icon>mode_edit</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n i18n-matTooltip\n matTooltip=\"Delete this user\"\n color=\"warn\"\n (click)=\"deleteUser(user)\"\n >\n <mat-icon>remove_circle</mat-icon>\n </button>\n </td>\n <td>\n <img\n alt=\"avatar\"\n [src]=\"getGravatarUrl(user.email, 32)\"\n [alt]=\"user.userName\"\n />\n </td>\n <td>{{ user.userName }}</td>\n <td class=\"noif-lt-md\">{{ user.firstName }}</td>\n <td class=\"noif-lt-md\">{{ user.lastName }}</td>\n <td class=\"noif-lt-md\">\n <a [href]=\"'mailto:' + user.email\">{{ user.email }}</a>\n </td>\n <td>{{ user.roles.join(\" \") }}</td>\n <td class=\"noif-lt-md\">{{ user.lockoutEnd }}</td>\n </tr>\n </tbody>\n </table>\n\n <!-- paginator -->\n <div id=\"paginator\" class=\"form-row\">\n <button\n type=\"button\"\n mat-icon-button\n color=\"warn\"\n i18n-matmatTooltip\n matTooltip=\"Clear items cache\"\n (click)=\"clearCache()\"\n >\n <mat-icon>autorenew</mat-icon>\n </button>\n\n <mat-paginator\n gdArea=\"pager\"\n gdAlignColumns=\"center\"\n gdAlignRows=\"start\"\n [length]=\"pagination.total\"\n [pageSize]=\"pagination.perPage\"\n [pageSizeOptions]=\"[20, 50, 75, 100]\"\n [pageIndex]=\"pagination.currentPage - 1\"\n [showFirstLastButtons]=\"true\"\n (page)=\"pageChange($event)\"\n ></mat-paginator>\n </div>\n </div>\n </div>\n\n <!-- editor -->\n <mat-expansion-panel\n id=\"editor\"\n [expanded]=\"active$ | async\"\n [disabled]=\"!(active$ | async)\"\n >\n <div *ngIf=\"active$ | async as active\">\n <fieldset>\n <legend>{{ active.userName }}</legend>\n <auth-jwt-user-editor\n [user]=\"active\"\n (userChange)=\"saveActiveUser($event)\"\n (editorClose)=\"resetActiveUser()\"\n ></auth-jwt-user-editor>\n </fieldset>\n </div>\n </mat-expansion-panel>\n</div>\n", styles: ["tr:nth-child(odd){background-color:#f8f8f8}th{padding:0 8px;text-align:left;color:silver;font-weight:400}td{padding:0 8px}td.command{width:24px}table{width:100%;border-collapse:collapse}fieldset{border:1px solid silver;border-radius:8px;padding:16px}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}div#filters{grid-area:filters}div#list{grid-area:list}div#paginator{grid-area:paginator;justify-content:end}div#editor{grid-area:editor}div#container{display:grid;grid-template-rows:auto 1fr auto auto;grid-template-columns:1fr;grid-template-areas:\"filters\" \"list\" \"paginator\" \"editor\";gap:8px}@media only screen and (max-width: 959px){.noif-lt-md{display:none}}@media only screen and (min-width: 1920px){div#container{grid-template-rows:auto 1fr auto;grid-template-columns:1fr auto;grid-template-areas:\"filters filters\" \"list editor\" \"paginator .\"}}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i5.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i6.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["disabled", "expanded", "hideToggle", "togglePosition"], outputs: ["opened", "closed", "expandedChange", "afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i8.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }, { kind: "component", type: i9.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i11.UserFilterComponent, selector: "auth-jwt-user-filter", inputs: ["disabled"] }, { kind: "component", type: i12.UserEditorComponent, selector: "auth-jwt-user-editor", inputs: ["user"], outputs: ["userChange", "editorClose"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }] }); }
65
+ }
66
+ export { UserListComponent };
67
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: UserListComponent, decorators: [{
68
+ type: Component,
69
+ args: [{ selector: 'auth-jwt-user-list', template: "<div id=\"container\">\n <div>\n <!-- filters -->\n <div id=\"filters\">\n <auth-jwt-user-filter></auth-jwt-user-filter>\n </div>\n\n <!-- list -->\n <div id=\"list\" *ngIf=\"pagination$ | async as pagination\">\n <div *ngIf=\"loading$ | async\" gdArea=\"progress\">\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n <table>\n <thead>\n <td></td>\n <td></td>\n <th i18n>name</th>\n <th i18n class=\"noif-lt-md\">first</th>\n <th i18n class=\"noif-lt-md\">last</th>\n <th i18n class=\"noif-lt-md\">email</th>\n <th i18n>roles</th>\n <th i18n class=\"noif-lt-md\">lock end</th>\n </thead>\n <tbody>\n <tr *ngFor=\"let user of pagination.data\">\n <td>\n <button\n mat-icon-button\n type=\"button\"\n i18n-matTooltip\n matTooltip=\"Edit this user\"\n color=\"primary\"\n (click)=\"setActiveUser(user)\"\n >\n <mat-icon>mode_edit</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n i18n-matTooltip\n matTooltip=\"Delete this user\"\n color=\"warn\"\n (click)=\"deleteUser(user)\"\n >\n <mat-icon>remove_circle</mat-icon>\n </button>\n </td>\n <td>\n <img\n alt=\"avatar\"\n [src]=\"getGravatarUrl(user.email, 32)\"\n [alt]=\"user.userName\"\n />\n </td>\n <td>{{ user.userName }}</td>\n <td class=\"noif-lt-md\">{{ user.firstName }}</td>\n <td class=\"noif-lt-md\">{{ user.lastName }}</td>\n <td class=\"noif-lt-md\">\n <a [href]=\"'mailto:' + user.email\">{{ user.email }}</a>\n </td>\n <td>{{ user.roles.join(\" \") }}</td>\n <td class=\"noif-lt-md\">{{ user.lockoutEnd }}</td>\n </tr>\n </tbody>\n </table>\n\n <!-- paginator -->\n <div id=\"paginator\" class=\"form-row\">\n <button\n type=\"button\"\n mat-icon-button\n color=\"warn\"\n i18n-matmatTooltip\n matTooltip=\"Clear items cache\"\n (click)=\"clearCache()\"\n >\n <mat-icon>autorenew</mat-icon>\n </button>\n\n <mat-paginator\n gdArea=\"pager\"\n gdAlignColumns=\"center\"\n gdAlignRows=\"start\"\n [length]=\"pagination.total\"\n [pageSize]=\"pagination.perPage\"\n [pageSizeOptions]=\"[20, 50, 75, 100]\"\n [pageIndex]=\"pagination.currentPage - 1\"\n [showFirstLastButtons]=\"true\"\n (page)=\"pageChange($event)\"\n ></mat-paginator>\n </div>\n </div>\n </div>\n\n <!-- editor -->\n <mat-expansion-panel\n id=\"editor\"\n [expanded]=\"active$ | async\"\n [disabled]=\"!(active$ | async)\"\n >\n <div *ngIf=\"active$ | async as active\">\n <fieldset>\n <legend>{{ active.userName }}</legend>\n <auth-jwt-user-editor\n [user]=\"active\"\n (userChange)=\"saveActiveUser($event)\"\n (editorClose)=\"resetActiveUser()\"\n ></auth-jwt-user-editor>\n </fieldset>\n </div>\n </mat-expansion-panel>\n</div>\n", styles: ["tr:nth-child(odd){background-color:#f8f8f8}th{padding:0 8px;text-align:left;color:silver;font-weight:400}td{padding:0 8px}td.command{width:24px}table{width:100%;border-collapse:collapse}fieldset{border:1px solid silver;border-radius:8px;padding:16px}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}div#filters{grid-area:filters}div#list{grid-area:list}div#paginator{grid-area:paginator;justify-content:end}div#editor{grid-area:editor}div#container{display:grid;grid-template-rows:auto 1fr auto auto;grid-template-columns:1fr;grid-template-areas:\"filters\" \"list\" \"paginator\" \"editor\";gap:8px}@media only screen and (max-width: 959px){.noif-lt-md{display:none}}@media only screen and (min-width: 1920px){div#container{grid-template-rows:auto 1fr auto;grid-template-columns:1fr auto;grid-template-areas:\"filters filters\" \"list editor\" \"paginator .\"}}\n"] }]
70
+ }], ctorParameters: function () { return [{ type: i1.UserListRepository }, { type: i2.DialogService }, { type: i3.GravatarService }]; } });
71
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1saXN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL215cm1pZG9uL2F1dGgtand0LWFkbWluL3NyYy9saWIvY29tcG9uZW50cy91c2VyLWxpc3QvdXNlci1saXN0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL215cm1pZG9uL2F1dGgtand0LWFkbWluL3NyYy9saWIvY29tcG9uZW50cy91c2VyLWxpc3QvdXNlci1saXN0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHMUMsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RDLE9BQU8sd0JBQXdCLENBQUM7Ozs7Ozs7Ozs7Ozs7O0FBU2hDLE1BS2EsaUJBQWlCO0lBSzVCLFlBQ1UsV0FBK0IsRUFDL0IsY0FBNkIsRUFDN0IsZ0JBQWlDO1FBRmpDLGdCQUFXLEdBQVgsV0FBVyxDQUFvQjtRQUMvQixtQkFBYyxHQUFkLGNBQWMsQ0FBZTtRQUM3QixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWlCO1FBRXpDLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDLFdBQVcsQ0FBQztRQUMzQyxJQUFJLENBQUMsT0FBTyxHQUFHLFdBQVcsQ0FBQyxXQUFXLENBQUM7UUFDdkMsSUFBSSxDQUFDLFFBQVEsR0FBRyxXQUFXLENBQUMsUUFBUSxDQUFDO0lBQ3ZDLENBQUM7SUFFTSxVQUFVLENBQUMsS0FBZ0I7UUFDaEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxDQUFDLEVBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2pFLENBQUM7SUFFTSxVQUFVLENBQUMsSUFBVTtRQUMxQixJQUFJLENBQUMsY0FBYzthQUNoQixPQUFPLENBQUMsU0FBUyxDQUFBLFNBQVMsRUFBRSxTQUFTLENBQUEsZUFBZSxJQUFJLENBQUMsUUFBUSxHQUFHLENBQUM7YUFDckUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUNiLFNBQVMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1lBQ2pCLElBQUksQ0FBQyxHQUFHLEVBQUU7Z0JBQ1IsT0FBTzthQUNSO1lBQ0QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUU7Z0JBQ3RELElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQzlCLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQy9CLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU0sYUFBYSxDQUFDLElBQWlCO1FBQ3BDLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxRQUFRLElBQUksSUFBSSxDQUFDLENBQUM7SUFDckQsQ0FBQztJQUVNLGVBQWU7UUFDcEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVNLGNBQWMsQ0FBQyxJQUFVO1FBQzlCLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFTSxpQkFBaUI7UUFDdEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVNLGNBQWMsQ0FBQyxLQUFhLEVBQUUsSUFBSSxHQUFHLEVBQUU7UUFDNUMsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQzdELENBQUM7SUFFTSxVQUFVO1FBQ2YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUM5QixJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMvQixDQUFDOzhHQTFEVSxpQkFBaUI7a0dBQWpCLGlCQUFpQiwwRENsQjlCLHU5R0FnSEE7O1NEOUZhLGlCQUFpQjsyRkFBakIsaUJBQWlCO2tCQUw3QixTQUFTOytCQUNFLG9CQUFvQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBQYWdlRXZlbnQgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9wYWdpbmF0b3InO1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IHRha2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCAnQGFuZ3VsYXIvbG9jYWxpemUvaW5pdCc7XHJcblxyXG5pbXBvcnQgeyBQYWdpbmF0aW9uRGF0YSB9IGZyb20gJ0BuZ25lYXQvZWxmLXBhZ2luYXRpb24nO1xyXG5cclxuaW1wb3J0IHsgR3JhdmF0YXJTZXJ2aWNlLCBVc2VyIH0gZnJvbSAnQG15cm1pZG9uL2F1dGgtand0LWxvZ2luJztcclxuXHJcbmltcG9ydCB7IERpYWxvZ1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9kaWFsb2cuc2VydmljZSc7XHJcbmltcG9ydCB7IFVzZXJMaXN0UmVwb3NpdG9yeSB9IGZyb20gJy4uL3N0YXRlL3VzZXItbGlzdC5yZXBvc2l0b3J5JztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnYXV0aC1qd3QtdXNlci1saXN0JyxcclxuICB0ZW1wbGF0ZVVybDogJy4vdXNlci1saXN0LmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi91c2VyLWxpc3QuY29tcG9uZW50LmNzcyddLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgVXNlckxpc3RDb21wb25lbnQge1xyXG4gIHB1YmxpYyBwYWdpbmF0aW9uJDogT2JzZXJ2YWJsZTxQYWdpbmF0aW9uRGF0YSAmIHsgZGF0YTogVXNlcltdIH0+O1xyXG4gIHB1YmxpYyBhY3RpdmUkOiBPYnNlcnZhYmxlPFVzZXIgfCB1bmRlZmluZWQ+O1xyXG4gIHB1YmxpYyBsb2FkaW5nJDogT2JzZXJ2YWJsZTxib29sZWFuPjtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIF9yZXBvc2l0b3J5OiBVc2VyTGlzdFJlcG9zaXRvcnksXHJcbiAgICBwcml2YXRlIF9kaWFsb2dTZXJ2aWNlOiBEaWFsb2dTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBfZ3JhdmF0YXJTZXJ2aWNlOiBHcmF2YXRhclNlcnZpY2VcclxuICApIHtcclxuICAgIHRoaXMucGFnaW5hdGlvbiQgPSBfcmVwb3NpdG9yeS5wYWdpbmF0aW9uJDtcclxuICAgIHRoaXMuYWN0aXZlJCA9IF9yZXBvc2l0b3J5LmFjdGl2ZVVzZXIkO1xyXG4gICAgdGhpcy5sb2FkaW5nJCA9IF9yZXBvc2l0b3J5LmxvYWRpbmckO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHBhZ2VDaGFuZ2UoZXZlbnQ6IFBhZ2VFdmVudCk6IHZvaWQge1xyXG4gICAgdGhpcy5fcmVwb3NpdG9yeS5sb2FkUGFnZShldmVudC5wYWdlSW5kZXggKyAxLCBldmVudC5wYWdlU2l6ZSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZGVsZXRlVXNlcih1c2VyOiBVc2VyKTogdm9pZCB7XHJcbiAgICB0aGlzLl9kaWFsb2dTZXJ2aWNlXHJcbiAgICAgIC5jb25maXJtKCRsb2NhbGl6ZWBDb25maXJtYCwgJGxvY2FsaXplYERlbGV0ZSB1c2VyICR7dXNlci51c2VyTmFtZX0/YClcclxuICAgICAgLnBpcGUodGFrZSgxKSlcclxuICAgICAgLnN1YnNjcmliZSgoeWVzKSA9PiB7XHJcbiAgICAgICAgaWYgKCF5ZXMpIHtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fcmVwb3NpdG9yeS5kZWxldGVVc2VyKHVzZXIudXNlck5hbWUpLmZpbmFsbHkoKCkgPT4ge1xyXG4gICAgICAgICAgdGhpcy5fcmVwb3NpdG9yeS5jbGVhckNhY2hlKCk7XHJcbiAgICAgICAgICB0aGlzLl9yZXBvc2l0b3J5LmxvYWRQYWdlKDEpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzZXRBY3RpdmVVc2VyKHVzZXI6IFVzZXIgfCBudWxsKTogdm9pZCB7XHJcbiAgICB0aGlzLl9yZXBvc2l0b3J5LnNldEFjdGl2ZSh1c2VyPy51c2VyTmFtZSB8fCBudWxsKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyByZXNldEFjdGl2ZVVzZXIoKTogdm9pZCB7XHJcbiAgICB0aGlzLl9yZXBvc2l0b3J5LnNldEFjdGl2ZShudWxsKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzYXZlQWN0aXZlVXNlcih1c2VyOiBVc2VyKTogdm9pZCB7XHJcbiAgICB0aGlzLl9yZXBvc2l0b3J5LnVwZGF0ZUFjdGl2ZSh1c2VyKTtcclxuICAgIHRoaXMuX3JlcG9zaXRvcnkuc2V0QWN0aXZlKG51bGwpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG9uVXNlckVkaXRvckNsb3NlKCk6IHZvaWQge1xyXG4gICAgdGhpcy5fcmVwb3NpdG9yeS5zZXRBY3RpdmUobnVsbCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0R3JhdmF0YXJVcmwoZW1haWw6IHN0cmluZywgc2l6ZSA9IDgwKTogc3RyaW5nIHwgbnVsbCB7XHJcbiAgICByZXR1cm4gdGhpcy5fZ3JhdmF0YXJTZXJ2aWNlLmJ1aWxkR3JhdmF0YXJVcmwoZW1haWwsIHNpemUpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGNsZWFyQ2FjaGUoKTogdm9pZCB7XHJcbiAgICB0aGlzLl9yZXBvc2l0b3J5LmNsZWFyQ2FjaGUoKTtcclxuICAgIHRoaXMuX3JlcG9zaXRvcnkubG9hZFBhZ2UoMSk7XHJcbiAgfVxyXG59XHJcbiIsIjxkaXYgaWQ9XCJjb250YWluZXJcIj5cbiAgPGRpdj5cbiAgICA8IS0tIGZpbHRlcnMgLS0+XG4gICAgPGRpdiBpZD1cImZpbHRlcnNcIj5cbiAgICAgIDxhdXRoLWp3dC11c2VyLWZpbHRlcj48L2F1dGgtand0LXVzZXItZmlsdGVyPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBsaXN0IC0tPlxuICAgIDxkaXYgaWQ9XCJsaXN0XCIgKm5nSWY9XCJwYWdpbmF0aW9uJCB8IGFzeW5jIGFzIHBhZ2luYXRpb25cIj5cbiAgICAgIDxkaXYgKm5nSWY9XCJsb2FkaW5nJCB8IGFzeW5jXCIgZ2RBcmVhPVwicHJvZ3Jlc3NcIj5cbiAgICAgICAgPG1hdC1wcm9ncmVzcy1iYXIgbW9kZT1cImluZGV0ZXJtaW5hdGVcIj48L21hdC1wcm9ncmVzcy1iYXI+XG4gICAgICA8L2Rpdj5cbiAgICAgIDx0YWJsZT5cbiAgICAgICAgPHRoZWFkPlxuICAgICAgICAgIDx0ZD48L3RkPlxuICAgICAgICAgIDx0ZD48L3RkPlxuICAgICAgICAgIDx0aCBpMThuPm5hbWU8L3RoPlxuICAgICAgICAgIDx0aCBpMThuIGNsYXNzPVwibm9pZi1sdC1tZFwiPmZpcnN0PC90aD5cbiAgICAgICAgICA8dGggaTE4biBjbGFzcz1cIm5vaWYtbHQtbWRcIj5sYXN0PC90aD5cbiAgICAgICAgICA8dGggaTE4biBjbGFzcz1cIm5vaWYtbHQtbWRcIj5lbWFpbDwvdGg+XG4gICAgICAgICAgPHRoIGkxOG4+cm9sZXM8L3RoPlxuICAgICAgICAgIDx0aCBpMThuIGNsYXNzPVwibm9pZi1sdC1tZFwiPmxvY2sgZW5kPC90aD5cbiAgICAgICAgPC90aGVhZD5cbiAgICAgICAgPHRib2R5PlxuICAgICAgICAgIDx0ciAqbmdGb3I9XCJsZXQgdXNlciBvZiBwYWdpbmF0aW9uLmRhdGFcIj5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgIGkxOG4tbWF0VG9vbHRpcFxuICAgICAgICAgICAgICAgIG1hdFRvb2x0aXA9XCJFZGl0IHRoaXMgdXNlclwiXG4gICAgICAgICAgICAgICAgY29sb3I9XCJwcmltYXJ5XCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwic2V0QWN0aXZlVXNlcih1c2VyKVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24+bW9kZV9lZGl0PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICBtYXQtaWNvbi1idXR0b25cbiAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICBpMThuLW1hdFRvb2x0aXBcbiAgICAgICAgICAgICAgICBtYXRUb29sdGlwPVwiRGVsZXRlIHRoaXMgdXNlclwiXG4gICAgICAgICAgICAgICAgY29sb3I9XCJ3YXJuXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiZGVsZXRlVXNlcih1c2VyKVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24+cmVtb3ZlX2NpcmNsZTwvbWF0LWljb24+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICAgIGFsdD1cImF2YXRhclwiXG4gICAgICAgICAgICAgICAgW3NyY109XCJnZXRHcmF2YXRhclVybCh1c2VyLmVtYWlsLCAzMilcIlxuICAgICAgICAgICAgICAgIFthbHRdPVwidXNlci51c2VyTmFtZVwiXG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPnt7IHVzZXIudXNlck5hbWUgfX08L3RkPlxuICAgICAgICAgICAgPHRkIGNsYXNzPVwibm9pZi1sdC1tZFwiPnt7IHVzZXIuZmlyc3ROYW1lIH19PC90ZD5cbiAgICAgICAgICAgIDx0ZCBjbGFzcz1cIm5vaWYtbHQtbWRcIj57eyB1c2VyLmxhc3ROYW1lIH19PC90ZD5cbiAgICAgICAgICAgIDx0ZCBjbGFzcz1cIm5vaWYtbHQtbWRcIj5cbiAgICAgICAgICAgICAgPGEgW2hyZWZdPVwiJ21haWx0bzonICsgdXNlci5lbWFpbFwiPnt7IHVzZXIuZW1haWwgfX08L2E+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPnt7IHVzZXIucm9sZXMuam9pbihcIiBcIikgfX08L3RkPlxuICAgICAgICAgICAgPHRkIGNsYXNzPVwibm9pZi1sdC1tZFwiPnt7IHVzZXIubG9ja291dEVuZCB9fTwvdGQ+XG4gICAgICAgICAgPC90cj5cbiAgICAgICAgPC90Ym9keT5cbiAgICAgIDwvdGFibGU+XG5cbiAgICAgIDwhLS0gcGFnaW5hdG9yIC0tPlxuICAgICAgPGRpdiBpZD1cInBhZ2luYXRvclwiIGNsYXNzPVwiZm9ybS1yb3dcIj5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgIGNvbG9yPVwid2FyblwiXG4gICAgICAgICAgaTE4bi1tYXRtYXRUb29sdGlwXG4gICAgICAgICAgbWF0VG9vbHRpcD1cIkNsZWFyIGl0ZW1zIGNhY2hlXCJcbiAgICAgICAgICAoY2xpY2spPVwiY2xlYXJDYWNoZSgpXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxtYXQtaWNvbj5hdXRvcmVuZXc8L21hdC1pY29uPlxuICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICA8bWF0LXBhZ2luYXRvclxuICAgICAgICAgIGdkQXJlYT1cInBhZ2VyXCJcbiAgICAgICAgICBnZEFsaWduQ29sdW1ucz1cImNlbnRlclwiXG4gICAgICAgICAgZ2RBbGlnblJvd3M9XCJzdGFydFwiXG4gICAgICAgICAgW2xlbmd0aF09XCJwYWdpbmF0aW9uLnRvdGFsXCJcbiAgICAgICAgICBbcGFnZVNpemVdPVwicGFnaW5hdGlvbi5wZXJQYWdlXCJcbiAgICAgICAgICBbcGFnZVNpemVPcHRpb25zXT1cIlsyMCwgNTAsIDc1LCAxMDBdXCJcbiAgICAgICAgICBbcGFnZUluZGV4XT1cInBhZ2luYXRpb24uY3VycmVudFBhZ2UgLSAxXCJcbiAgICAgICAgICBbc2hvd0ZpcnN0TGFzdEJ1dHRvbnNdPVwidHJ1ZVwiXG4gICAgICAgICAgKHBhZ2UpPVwicGFnZUNoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgPjwvbWF0LXBhZ2luYXRvcj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuICA8IS0tIGVkaXRvciAtLT5cbiAgPG1hdC1leHBhbnNpb24tcGFuZWxcbiAgICBpZD1cImVkaXRvclwiXG4gICAgW2V4cGFuZGVkXT1cImFjdGl2ZSQgfCBhc3luY1wiXG4gICAgW2Rpc2FibGVkXT1cIiEoYWN0aXZlJCB8IGFzeW5jKVwiXG4gID5cbiAgICA8ZGl2ICpuZ0lmPVwiYWN0aXZlJCB8IGFzeW5jIGFzIGFjdGl2ZVwiPlxuICAgICAgPGZpZWxkc2V0PlxuICAgICAgICA8bGVnZW5kPnt7IGFjdGl2ZS51c2VyTmFtZSB9fTwvbGVnZW5kPlxuICAgICAgICA8YXV0aC1qd3QtdXNlci1lZGl0b3JcbiAgICAgICAgICBbdXNlcl09XCJhY3RpdmVcIlxuICAgICAgICAgICh1c2VyQ2hhbmdlKT1cInNhdmVBY3RpdmVVc2VyKCRldmVudClcIlxuICAgICAgICAgIChlZGl0b3JDbG9zZSk9XCJyZXNldEFjdGl2ZVVzZXIoKVwiXG4gICAgICAgID48L2F1dGgtand0LXVzZXItZWRpdG9yPlxuICAgICAgPC9maWVsZHNldD5cbiAgICA8L2Rpdj5cbiAgPC9tYXQtZXhwYW5zaW9uLXBhbmVsPlxuPC9kaXY+XG4iXX0=