ichec-angular-core 0.0.13 → 0.1.1
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/fesm2022/ichec-angular-core.mjs +836 -211
- package/fesm2022/ichec-angular-core.mjs.map +1 -1
- package/index.d.ts +388 -118
- package/package.json +1 -1
- package/styles/styles.scss +1 -0
|
@@ -1,37 +1,70 @@
|
|
|
1
|
-
import { map, catchError, mergeMap, throwError, BehaviorSubject, mergeAll,
|
|
2
|
-
import {
|
|
1
|
+
import { map, catchError, tap, mergeMap, throwError, BehaviorSubject, mergeAll, merge, debounceTime, distinctUntilChanged, Subscription, of, finalize } from 'rxjs';
|
|
2
|
+
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { InjectionToken, inject, Injectable, input, signal, Component, computed, output
|
|
5
|
-
import { NgIf, Location,
|
|
6
|
-
import * as
|
|
4
|
+
import { InjectionToken, inject, Injectable, input, signal, Component, viewChild, computed, output } from '@angular/core';
|
|
5
|
+
import { NgIf, Location, NgTemplateOutlet, TitleCasePipe } from '@angular/common';
|
|
6
|
+
import * as i1 from '@angular/router';
|
|
7
7
|
import { RouterModule, RouterOutlet, Router, ActivatedRoute } from '@angular/router';
|
|
8
8
|
import * as i2 from '@angular/material/toolbar';
|
|
9
9
|
import { MatToolbarModule } from '@angular/material/toolbar';
|
|
10
|
-
import * as i3
|
|
10
|
+
import * as i3 from '@angular/material/icon';
|
|
11
11
|
import { MatIconModule } from '@angular/material/icon';
|
|
12
12
|
import * as i2$1 from '@angular/material/button';
|
|
13
13
|
import { MatButtonModule } from '@angular/material/button';
|
|
14
14
|
import * as i5 from '@angular/material/menu';
|
|
15
15
|
import { MatMenuModule } from '@angular/material/menu';
|
|
16
|
-
import * as i1 from '@angular/material/sidenav';
|
|
17
|
-
import { MatSidenavModule } from '@angular/material/sidenav';
|
|
16
|
+
import * as i1$1 from '@angular/material/sidenav';
|
|
17
|
+
import { MatSidenavContent, MatSidenavModule } from '@angular/material/sidenav';
|
|
18
18
|
import * as i2$2 from '@angular/material/list';
|
|
19
19
|
import { MatListModule } from '@angular/material/list';
|
|
20
|
-
import * as i1$
|
|
21
|
-
import { FormsModule,
|
|
20
|
+
import * as i1$2 from '@angular/forms';
|
|
21
|
+
import { FormsModule, FormControl, ReactiveFormsModule, FormBuilder } from '@angular/forms';
|
|
22
22
|
import * as i3$2 from '@angular/material/input';
|
|
23
23
|
import { MatInputModule } from '@angular/material/input';
|
|
24
|
-
import * as
|
|
24
|
+
import * as i3$1 from '@angular/material/form-field';
|
|
25
25
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
26
|
-
import * as
|
|
26
|
+
import * as i1$3 from '@angular/material/card';
|
|
27
27
|
import { MatCardModule } from '@angular/material/card';
|
|
28
|
-
import * as i1$
|
|
28
|
+
import * as i1$4 from '@angular/material/table';
|
|
29
29
|
import { MatTable, MatTableModule } from '@angular/material/table';
|
|
30
|
-
import * as
|
|
30
|
+
import * as i6 from '@angular/material/select';
|
|
31
31
|
import { MatSelectModule } from '@angular/material/select';
|
|
32
|
+
import * as i6$1 from '@angular/material/autocomplete';
|
|
33
|
+
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
|
34
|
+
import * as i3$3 from '@angular/material/sort';
|
|
35
|
+
import { MatSort, MatSortModule } from '@angular/material/sort';
|
|
36
|
+
import * as i1$5 from '@angular/material/button-toggle';
|
|
37
|
+
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
|
38
|
+
import * as i2$5 from '@angular/material/progress-spinner';
|
|
39
|
+
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
40
|
+
import * as i4 from '@angular/material/tooltip';
|
|
41
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
42
|
+
import * as i2$3 from '@angular/material/paginator';
|
|
43
|
+
import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
|
|
44
|
+
import * as i2$4 from '@angular/cdk/scrolling';
|
|
45
|
+
import { ScrollingModule } from '@angular/cdk/scrolling';
|
|
46
|
+
import { DataSource } from '@angular/cdk/collections';
|
|
32
47
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
33
48
|
|
|
49
|
+
class Paginated {
|
|
50
|
+
count = 0;
|
|
51
|
+
next = null;
|
|
52
|
+
previous = null;
|
|
53
|
+
results = [];
|
|
54
|
+
}
|
|
55
|
+
class Permission {
|
|
56
|
+
id = 0;
|
|
57
|
+
url = "";
|
|
58
|
+
codename = "";
|
|
59
|
+
static typename = "permission";
|
|
60
|
+
static plural = "permissions";
|
|
61
|
+
constructor(params = {}) {
|
|
62
|
+
Object.assign(this, params);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
34
65
|
class PortalMember {
|
|
66
|
+
static typename = "member";
|
|
67
|
+
static plural = "members";
|
|
35
68
|
id = 0;
|
|
36
69
|
url = "";
|
|
37
70
|
username = "";
|
|
@@ -41,16 +74,44 @@ class PortalMember {
|
|
|
41
74
|
phone = "";
|
|
42
75
|
organization = "";
|
|
43
76
|
profile_url = "";
|
|
77
|
+
all_permissions = [];
|
|
44
78
|
constructor(params = {}) {
|
|
45
79
|
Object.assign(this, params);
|
|
46
80
|
}
|
|
47
81
|
}
|
|
48
82
|
class Group {
|
|
83
|
+
static typename = "group";
|
|
84
|
+
static plural = "groups";
|
|
49
85
|
name = "";
|
|
50
86
|
url = "";
|
|
51
87
|
id = 0;
|
|
88
|
+
constructor(params = {}) {
|
|
89
|
+
Object.assign(this, params);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
class Address {
|
|
94
|
+
static typename = "address";
|
|
95
|
+
static plural = "addresses";
|
|
96
|
+
id = 0;
|
|
97
|
+
url = "";
|
|
98
|
+
line1 = "";
|
|
99
|
+
line2 = "";
|
|
100
|
+
line3 = "";
|
|
101
|
+
city = "";
|
|
102
|
+
region = "";
|
|
103
|
+
postcode = "";
|
|
104
|
+
country = "";
|
|
105
|
+
country_name = "";
|
|
106
|
+
country_flag = "";
|
|
107
|
+
members = [];
|
|
108
|
+
constructor(params = {}) {
|
|
109
|
+
Object.assign(this, params);
|
|
110
|
+
}
|
|
52
111
|
}
|
|
53
112
|
class Organization {
|
|
113
|
+
static typename = "organization";
|
|
114
|
+
static plural = "organizations";
|
|
54
115
|
id = 0;
|
|
55
116
|
url = "";
|
|
56
117
|
name = "";
|
|
@@ -58,13 +119,24 @@ class Organization {
|
|
|
58
119
|
description = "";
|
|
59
120
|
address = "";
|
|
60
121
|
website = "";
|
|
61
|
-
country = "";
|
|
62
122
|
members = [];
|
|
63
123
|
constructor(params = {}) {
|
|
64
124
|
Object.assign(this, params);
|
|
65
125
|
}
|
|
66
126
|
}
|
|
67
127
|
|
|
128
|
+
class ItemQuery {
|
|
129
|
+
queries = new Map();
|
|
130
|
+
page = 0;
|
|
131
|
+
page_size = 0;
|
|
132
|
+
sort_field = "";
|
|
133
|
+
sort_order = "";
|
|
134
|
+
filter_field = "";
|
|
135
|
+
filter = "";
|
|
136
|
+
constructor(params = {}) {
|
|
137
|
+
Object.assign(this, params);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
68
140
|
var ErrorCode;
|
|
69
141
|
(function (ErrorCode) {
|
|
70
142
|
ErrorCode[ErrorCode["UnknownError"] = 1] = "UnknownError";
|
|
@@ -76,22 +148,42 @@ class ApiError {
|
|
|
76
148
|
|
|
77
149
|
const ENDPOINT_URL = new InjectionToken("Default endpoint url");
|
|
78
150
|
class RestService {
|
|
79
|
-
_url;
|
|
80
|
-
_endpoint_url;
|
|
81
|
-
_http;
|
|
82
|
-
constructor(_url, _endpoint_url, _http) {
|
|
83
|
-
this._url = _url;
|
|
84
|
-
this._endpoint_url = _endpoint_url;
|
|
85
|
-
this._http = _http;
|
|
86
|
-
}
|
|
151
|
+
_url = "";
|
|
152
|
+
_endpoint_url = inject(ENDPOINT_URL);
|
|
153
|
+
_http = inject(HttpClient);
|
|
87
154
|
deleteItem(id) {
|
|
88
155
|
return this._http.delete(this.getBaseUrl() + id + "/", { headers: this.getHeaders() }).pipe(map(_response => { return void (0); }), catchError(this.handleError));
|
|
89
156
|
}
|
|
90
|
-
getForUser(user) {
|
|
91
|
-
|
|
157
|
+
getForUser(user, query = new ItemQuery()) {
|
|
158
|
+
query.queries.set('user', user.id.toString());
|
|
159
|
+
return this.get(query);
|
|
92
160
|
}
|
|
93
|
-
get(query =
|
|
94
|
-
|
|
161
|
+
get(query = new ItemQuery()) {
|
|
162
|
+
const params = query.queries;
|
|
163
|
+
if (query.page > 0) {
|
|
164
|
+
params.set('page', query.page.toString());
|
|
165
|
+
}
|
|
166
|
+
if (query.page_size > 0) {
|
|
167
|
+
params.set('page_size', query.page_size.toString());
|
|
168
|
+
}
|
|
169
|
+
if (query.sort_field) {
|
|
170
|
+
let sort_field = query.sort_field;
|
|
171
|
+
if (query.sort_order === "desc") {
|
|
172
|
+
sort_field = "-" + sort_field;
|
|
173
|
+
}
|
|
174
|
+
params.set('ordering', sort_field);
|
|
175
|
+
}
|
|
176
|
+
if (query.filter_field) {
|
|
177
|
+
params.set('search_field', query.filter_field);
|
|
178
|
+
}
|
|
179
|
+
if (query.filter) {
|
|
180
|
+
params.set('search', query.filter);
|
|
181
|
+
}
|
|
182
|
+
console.log(params);
|
|
183
|
+
return this._http.get(this.getBaseUrl(), {
|
|
184
|
+
headers: this.getHeaders(),
|
|
185
|
+
params: new HttpParams({ fromObject: Object.fromEntries(params) })
|
|
186
|
+
}).pipe(tap(response => console.log(response)), catchError(this.handleError));
|
|
95
187
|
}
|
|
96
188
|
getItem(id) {
|
|
97
189
|
return this._http.get(this.getBaseUrl() + id, { headers: this.getHeaders() }).pipe(catchError(this.handleError));
|
|
@@ -99,6 +191,9 @@ class RestService {
|
|
|
99
191
|
getUrl(url) {
|
|
100
192
|
return this._http.get(url, { headers: this.getHeaders() }).pipe(catchError(this.handleError));
|
|
101
193
|
}
|
|
194
|
+
getPaginatedUrl(url) {
|
|
195
|
+
return this._http.get(url, { headers: this.getHeaders() }).pipe(catchError(this.handleError));
|
|
196
|
+
}
|
|
102
197
|
getOptions() {
|
|
103
198
|
return this._http.options(this.getBaseUrl(), { headers: this.getHeaders() }).pipe(catchError(this.handleError));
|
|
104
199
|
}
|
|
@@ -165,12 +260,44 @@ class RestService {
|
|
|
165
260
|
}
|
|
166
261
|
}
|
|
167
262
|
|
|
168
|
-
class
|
|
169
|
-
|
|
263
|
+
class ItemService extends RestService {
|
|
264
|
+
itemType = "";
|
|
265
|
+
canEdit() {
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
canCreate() {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
canDelete() {
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
canView() {
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
instantiateType(_) {
|
|
278
|
+
throw new Error('Not Implemented');
|
|
279
|
+
}
|
|
280
|
+
getItem(id) {
|
|
281
|
+
return super.getItem(id).pipe(map(x => this.instantiateType(x)));
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
class ResolvedPermission {
|
|
286
|
+
canEdit = false;
|
|
287
|
+
canAdd = false;
|
|
288
|
+
canView = false;
|
|
289
|
+
canDelete = false;
|
|
290
|
+
}
|
|
291
|
+
class UserService extends ItemService {
|
|
292
|
+
/**
|
|
293
|
+
Service to handle IPortalMember via REST and also handle logins.
|
|
170
294
|
*/
|
|
171
295
|
loggedInUser = new BehaviorSubject(null);
|
|
172
|
-
|
|
173
|
-
|
|
296
|
+
_url = PortalMember.plural;
|
|
297
|
+
itemType = PortalMember.plural;
|
|
298
|
+
permissions = new Map();
|
|
299
|
+
instantiateType(item) {
|
|
300
|
+
return new PortalMember(item);
|
|
174
301
|
}
|
|
175
302
|
login(username, password) {
|
|
176
303
|
console.log("Attempting login");
|
|
@@ -181,6 +308,34 @@ class UserService extends RestService {
|
|
|
181
308
|
const api_auth_endpoint = this._endpoint_url + "/api-token-auth/";
|
|
182
309
|
return this._http.post(api_auth_endpoint, body.toString(), { headers: headers }).pipe(map(token => this.onLoginToken(token)), mergeAll(), catchError(this.handleError));
|
|
183
310
|
}
|
|
311
|
+
hasAddPermission(feature) {
|
|
312
|
+
const perm = this.permissions.get(feature);
|
|
313
|
+
if (!perm) {
|
|
314
|
+
return false;
|
|
315
|
+
}
|
|
316
|
+
return perm.canAdd;
|
|
317
|
+
}
|
|
318
|
+
hasDeletePermission(feature) {
|
|
319
|
+
const perm = this.permissions.get(feature);
|
|
320
|
+
if (!perm) {
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
return perm.canDelete;
|
|
324
|
+
}
|
|
325
|
+
hasEditPermission(feature) {
|
|
326
|
+
const perm = this.permissions.get(feature);
|
|
327
|
+
if (!perm) {
|
|
328
|
+
return false;
|
|
329
|
+
}
|
|
330
|
+
return perm.canEdit;
|
|
331
|
+
}
|
|
332
|
+
hasViewPermission(feature) {
|
|
333
|
+
const perm = this.permissions.get(feature);
|
|
334
|
+
if (!perm) {
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
return perm.canView;
|
|
338
|
+
}
|
|
184
339
|
logout() {
|
|
185
340
|
if (this.loggedInUser === null) {
|
|
186
341
|
return;
|
|
@@ -195,10 +350,39 @@ class UserService extends RestService {
|
|
|
195
350
|
return this.getItem(Number(token_response.user_id)).pipe(tap(user => this.onLoggedIn(user)), map(_response => { return void (0); }), catchError(this.handleError));
|
|
196
351
|
}
|
|
197
352
|
onLoggedIn(user) {
|
|
198
|
-
console.log("Log in
|
|
353
|
+
console.log("Log in successful for user: " + user.username);
|
|
199
354
|
this.loggedInUser.next(user);
|
|
355
|
+
this.processPermissions();
|
|
356
|
+
}
|
|
357
|
+
parsePermission(p) {
|
|
358
|
+
const split_module = p.split(".");
|
|
359
|
+
const split_cap = split_module[split_module.length - 1].split("_");
|
|
360
|
+
return { feature: split_cap[1], capability: split_cap[0] };
|
|
361
|
+
}
|
|
362
|
+
processPermissions() {
|
|
363
|
+
const user = this.loggedInUser.value;
|
|
364
|
+
if (!user) {
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
user.all_permissions.forEach(p => this.permissions.set(this.parsePermission(p).feature, new ResolvedPermission()));
|
|
368
|
+
user.all_permissions.forEach(p => {
|
|
369
|
+
const permission = this.parsePermission(p);
|
|
370
|
+
if (permission.capability === "view") {
|
|
371
|
+
this.permissions.get(permission.feature).canView = true;
|
|
372
|
+
}
|
|
373
|
+
else if (permission.capability === "delete") {
|
|
374
|
+
this.permissions.get(permission.feature).canDelete = true;
|
|
375
|
+
}
|
|
376
|
+
else if (permission.capability === "change") {
|
|
377
|
+
this.permissions.get(permission.feature).canEdit = true;
|
|
378
|
+
}
|
|
379
|
+
else if (permission.capability === "add") {
|
|
380
|
+
this.permissions.get(permission.feature).canAdd = true;
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
console.log("Got permissions:", this.permissions);
|
|
200
384
|
}
|
|
201
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserService, deps:
|
|
385
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
202
386
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserService, providedIn: 'root' });
|
|
203
387
|
}
|
|
204
388
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserService, decorators: [{
|
|
@@ -206,23 +390,44 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
206
390
|
args: [{
|
|
207
391
|
providedIn: 'root',
|
|
208
392
|
}]
|
|
209
|
-
}]
|
|
393
|
+
}] });
|
|
210
394
|
|
|
211
|
-
class
|
|
395
|
+
class AddressService extends ItemService {
|
|
396
|
+
_url = Address.plural;
|
|
397
|
+
itemType = Address.plural;
|
|
398
|
+
instantiateType(item) {
|
|
399
|
+
return new Address(item);
|
|
400
|
+
}
|
|
401
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
402
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressService, providedIn: 'root' });
|
|
403
|
+
}
|
|
404
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressService, decorators: [{
|
|
405
|
+
type: Injectable,
|
|
406
|
+
args: [{
|
|
407
|
+
providedIn: 'root'
|
|
408
|
+
}]
|
|
409
|
+
}] });
|
|
410
|
+
|
|
411
|
+
class GroupService extends ItemService {
|
|
212
412
|
userService = inject(UserService);
|
|
213
413
|
userItems = new BehaviorSubject([]);
|
|
414
|
+
_url = Group.plural;
|
|
415
|
+
itemType = Group.plural;
|
|
214
416
|
constructor() {
|
|
215
|
-
super(
|
|
417
|
+
super();
|
|
216
418
|
this.userService.loggedInUser.subscribe(user => this.refreshUserItems(user));
|
|
217
419
|
}
|
|
218
420
|
refreshUserItems(user) {
|
|
219
421
|
if (user) {
|
|
220
|
-
this.getForUser(user).subscribe(items => this.userItems.next(items));
|
|
422
|
+
this.getForUser(user).subscribe(items => this.userItems.next(items.results));
|
|
221
423
|
}
|
|
222
424
|
else {
|
|
223
425
|
this.userItems.next([]);
|
|
224
426
|
}
|
|
225
427
|
}
|
|
428
|
+
instantiateType(item) {
|
|
429
|
+
return new Group(item);
|
|
430
|
+
}
|
|
226
431
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: GroupService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
227
432
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: GroupService, providedIn: 'root' });
|
|
228
433
|
}
|
|
@@ -233,11 +438,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
233
438
|
}]
|
|
234
439
|
}], ctorParameters: () => [] });
|
|
235
440
|
|
|
236
|
-
class OrganizationService extends
|
|
237
|
-
|
|
238
|
-
|
|
441
|
+
class OrganizationService extends ItemService {
|
|
442
|
+
_url = Organization.plural;
|
|
443
|
+
itemType = Organization.plural;
|
|
444
|
+
userService = inject(UserService);
|
|
445
|
+
instantiateType(item) {
|
|
446
|
+
return new Organization(item);
|
|
447
|
+
}
|
|
448
|
+
canCreate() {
|
|
449
|
+
return this.userService.hasAddPermission(Organization.typename);
|
|
450
|
+
}
|
|
451
|
+
canView() {
|
|
452
|
+
return this.userService.hasViewPermission(Organization.typename);
|
|
453
|
+
}
|
|
454
|
+
canEdit() {
|
|
455
|
+
return this.userService.hasEditPermission(Organization.typename);
|
|
456
|
+
}
|
|
457
|
+
canDelete() {
|
|
458
|
+
return this.userService.hasDeletePermission(Organization.typename);
|
|
239
459
|
}
|
|
240
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationService, deps:
|
|
460
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
241
461
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationService, providedIn: 'root' });
|
|
242
462
|
}
|
|
243
463
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationService, decorators: [{
|
|
@@ -245,7 +465,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
245
465
|
args: [{
|
|
246
466
|
providedIn: 'root'
|
|
247
467
|
}]
|
|
248
|
-
}]
|
|
468
|
+
}] });
|
|
249
469
|
|
|
250
470
|
class LeftNavService {
|
|
251
471
|
activeOptions = new Set();
|
|
@@ -298,7 +518,7 @@ class TopBarComponent {
|
|
|
298
518
|
this.userService.logout();
|
|
299
519
|
}
|
|
300
520
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: TopBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
301
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: TopBarComponent, isStandalone: true, selector: "lib-top-bar", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "\n@if(user(); as user){\n<mat-toolbar style=\"height:60px\">\n <a mat-icon-button aria-label=\"Home\" [routerLink]=\"['home']\">\n <mat-icon>home</mat-icon>\n </a>\n <span>{{title()}}</span>\n <span class=\"topbar-spacer\"></span>\n <span>{{user.username}}</span>\n \n <button mat-icon-button aria-label=\"User Profile\" [matMenuTriggerFor]=\"profile_menu\">\n <mat-icon>person</mat-icon>\n </button>\n\n <mat-menu #profile_menu=\"matMenu\">\n <button mat-menu-item (click)=\"onLogout()\">Log Out</button>\n </mat-menu>\n</mat-toolbar>\n}\n", styles: [".topbar-spacer{flex:1 1 auto}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type:
|
|
521
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: TopBarComponent, isStandalone: true, selector: "lib-top-bar", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "\n@if(user(); as user){\n<mat-toolbar style=\"height:60px\">\n <a mat-icon-button aria-label=\"Home\" [routerLink]=\"['home']\">\n <mat-icon>home</mat-icon>\n </a>\n <span>{{title()}}</span>\n <span class=\"topbar-spacer\"></span>\n <span>{{user.username}}</span>\n \n <button mat-icon-button aria-label=\"User Profile\" [matMenuTriggerFor]=\"profile_menu\">\n <mat-icon>person</mat-icon>\n </button>\n\n <mat-menu #profile_menu=\"matMenu\">\n <button mat-menu-item (click)=\"onLogout()\">Log Out</button>\n </mat-menu>\n</mat-toolbar>\n}\n", styles: [".topbar-spacer{flex:1 1 auto}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "component", type: i2.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i5.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i5.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i5.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }] });
|
|
302
522
|
}
|
|
303
523
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: TopBarComponent, decorators: [{
|
|
304
524
|
type: Component,
|
|
@@ -307,15 +527,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
307
527
|
|
|
308
528
|
class LeftNavComponent {
|
|
309
529
|
_leftNavService = inject(LeftNavService);
|
|
530
|
+
sideNavContent = viewChild(MatSidenavContent, ...(ngDevMode ? [{ debugName: "sideNavContent" }] : []));
|
|
310
531
|
getOptions() {
|
|
311
532
|
return this._leftNavService.activeOptions;
|
|
312
533
|
}
|
|
313
534
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: LeftNavComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
314
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: LeftNavComponent, isStandalone: true, selector: "lib-left-nav", ngImport: i0, template: "<mat-sidenav-container class=\"leftnav-container\">\n <mat-sidenav mode=\"side\" class=\"leftnav-side\" opened>\n <mat-nav-list>\n @for (option of getOptions(); track option) {\n <a mat-list-item [routerLink]=\"option.route\" [routerLinkActive]=\"['is-active']\">{{ option.name }}</a>\n }\n </mat-nav-list>\n </mat-sidenav>\n <mat-sidenav-content class=\"leftnav-content\"> \n <router-outlet/>\n </mat-sidenav-content>\n</mat-sidenav-container>\n", styles: [":host{display:flex;flex-direction:column}.leftnav-container{flex-grow:1;display:flex}.leftnav-content{display:flex;flex-grow:1;height:90vh}.leftnav-side{padding:5px;width:160px}.is-active{background-color:#d3d3d3}\n"], dependencies: [{ kind: "ngmodule", type: MatSidenavModule }, { kind: "component", type: i1.MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: i1.MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: i1.MatSidenavContent, selector: "mat-sidenav-content" }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i2$2.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "component", type: i2$2.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type:
|
|
535
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: LeftNavComponent, isStandalone: true, selector: "lib-left-nav", viewQueries: [{ propertyName: "sideNavContent", first: true, predicate: MatSidenavContent, descendants: true, isSignal: true }], ngImport: i0, template: "<mat-sidenav-container class=\"leftnav-container\">\n <mat-sidenav mode=\"side\" class=\"leftnav-side\" opened>\n <mat-nav-list>\n @for (option of getOptions(); track option) {\n <a mat-list-item [routerLink]=\"option.route\" [routerLinkActive]=\"['is-active']\">{{ option.name }}</a>\n }\n </mat-nav-list>\n </mat-sidenav>\n <mat-sidenav-content class=\"leftnav-content\"> \n <router-outlet />\n </mat-sidenav-content>\n</mat-sidenav-container>\n", styles: [":host{display:flex;flex-direction:column}.leftnav-container{flex-grow:1;display:flex}.leftnav-content{display:flex;flex-grow:1;height:90vh}.leftnav-side{padding:5px;width:160px}.is-active{background-color:#d3d3d3}\n"], dependencies: [{ kind: "ngmodule", type: MatSidenavModule }, { kind: "component", type: i1$1.MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: i1$1.MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: i1$1.MatSidenavContent, selector: "mat-sidenav-content" }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i2$2.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "component", type: i2$2.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i1.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }] });
|
|
315
536
|
}
|
|
316
537
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: LeftNavComponent, decorators: [{
|
|
317
538
|
type: Component,
|
|
318
|
-
args: [{ selector: 'lib-left-nav', imports: [MatSidenavModule, MatListModule, RouterOutlet, RouterModule], template: "<mat-sidenav-container class=\"leftnav-container\">\n <mat-sidenav mode=\"side\" class=\"leftnav-side\" opened>\n <mat-nav-list>\n @for (option of getOptions(); track option) {\n <a mat-list-item [routerLink]=\"option.route\" [routerLinkActive]=\"['is-active']\">{{ option.name }}</a>\n }\n </mat-nav-list>\n </mat-sidenav>\n <mat-sidenav-content class=\"leftnav-content\"> \n <router-outlet/>\n </mat-sidenav-content>\n</mat-sidenav-container>\n", styles: [":host{display:flex;flex-direction:column}.leftnav-container{flex-grow:1;display:flex}.leftnav-content{display:flex;flex-grow:1;height:90vh}.leftnav-side{padding:5px;width:160px}.is-active{background-color:#d3d3d3}\n"] }]
|
|
539
|
+
args: [{ selector: 'lib-left-nav', imports: [MatSidenavModule, MatListModule, RouterOutlet, RouterModule], template: "<mat-sidenav-container class=\"leftnav-container\">\n <mat-sidenav mode=\"side\" class=\"leftnav-side\" opened>\n <mat-nav-list>\n @for (option of getOptions(); track option) {\n <a mat-list-item [routerLink]=\"option.route\" [routerLinkActive]=\"['is-active']\">{{ option.name }}</a>\n }\n </mat-nav-list>\n </mat-sidenav>\n <mat-sidenav-content class=\"leftnav-content\"> \n <router-outlet />\n </mat-sidenav-content>\n</mat-sidenav-container>\n", styles: [":host{display:flex;flex-direction:column}.leftnav-container{flex-grow:1;display:flex}.leftnav-content{display:flex;flex-grow:1;height:90vh}.leftnav-side{padding:5px;width:160px}.is-active{background-color:#d3d3d3}\n"] }]
|
|
319
540
|
}] });
|
|
320
541
|
|
|
321
542
|
const LOGIN_USER = new InjectionToken("Default login user - used for testing");
|
|
@@ -354,7 +575,7 @@ class LandingComponent {
|
|
|
354
575
|
this.router.navigateByUrl("/home");
|
|
355
576
|
}
|
|
356
577
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: LandingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
357
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: LandingComponent, isStandalone: true, selector: "lib-landing", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "\n @if(message(); as message){\n <p>{{message}}</p>\n }\n \n <mat-card style=\"text-align:center;\">\n <form class=\"base-form\" #loginForm=\"ngForm\" (ngSubmit)=\"login()\">\n <mat-card-content>\n <mat-form-field class=\"form-field\">\n <input matInput\n placeholder=\"Username\"\n type=\"text\"\n [(ngModel)]=\"loginUser.name\"\n name=\"username\"\n required>\n </mat-form-field>\n <mat-form-field class=\"form-field\">\n <input matInput\n placeholder=\"Password\"\n type=\"password\"\n [(ngModel)]=\"loginUser.password\"\n name=\"password\"\n required>\n </mat-form-field>\n </mat-card-content>\n <div *ngIf=\"loginError\" class=\"error\">\n <mat-icon>error</mat-icon><p>{{loginError()}}</p>\n </div>\n <button mat-flat-button\n type=\"submit\"\n [disabled]=\"!loginForm.form.valid\">Log In</button>\n </form>\n </mat-card>\n\n\n \n", styles: [":host{display:flex;align-items:center;flex-grow:1;background-color:#a5b3c9;flex-direction:column}.base-form{padding:10px}.form-field{display:flex}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$
|
|
578
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: LandingComponent, isStandalone: true, selector: "lib-landing", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "\n @if(message(); as message){\n <p>{{message}}</p>\n }\n \n <mat-card style=\"text-align:center;\">\n <form class=\"base-form\" #loginForm=\"ngForm\" (ngSubmit)=\"login()\">\n <mat-card-content>\n <mat-form-field class=\"form-field\">\n <input matInput\n placeholder=\"Username\"\n type=\"text\"\n [(ngModel)]=\"loginUser.name\"\n name=\"username\"\n required>\n </mat-form-field>\n <mat-form-field class=\"form-field\">\n <input matInput\n placeholder=\"Password\"\n type=\"password\"\n [(ngModel)]=\"loginUser.password\"\n name=\"password\"\n required>\n </mat-form-field>\n </mat-card-content>\n <div *ngIf=\"loginError\" class=\"error\">\n <mat-icon>error</mat-icon><p>{{loginError()}}</p>\n </div>\n <button mat-flat-button\n type=\"submit\"\n [disabled]=\"!loginForm.form.valid\">Log In</button>\n </form>\n </mat-card>\n\n\n \n", styles: [":host{display:flex;align-items:center;flex-grow:1;background-color:#a5b3c9;flex-direction:column}.base-form{padding:10px}.form-field{display:flex}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i1$3.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i1$3.MatCardContent, selector: "mat-card-content" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
358
579
|
}
|
|
359
580
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: LandingComponent, decorators: [{
|
|
360
581
|
type: Component,
|
|
@@ -365,26 +586,38 @@ class DetailView {
|
|
|
365
586
|
item = signal(null, ...(ngDevMode ? [{ debugName: "item" }] : []));
|
|
366
587
|
route = inject(ActivatedRoute);
|
|
367
588
|
userService = inject(UserService);
|
|
368
|
-
|
|
369
|
-
constructor(
|
|
370
|
-
this.
|
|
589
|
+
itemService;
|
|
590
|
+
constructor(itemService) {
|
|
591
|
+
this.itemService = itemService;
|
|
371
592
|
}
|
|
372
593
|
onInit() {
|
|
373
594
|
this.getItem();
|
|
374
595
|
}
|
|
375
|
-
onItemAvailable() {
|
|
596
|
+
onItemAvailable(item) {
|
|
597
|
+
this.item.set(item);
|
|
376
598
|
this.userService.loggedInUser.subscribe(user => { if (user) {
|
|
377
|
-
this.onItemAndUserAvailable(user);
|
|
599
|
+
this.onItemAndUserAvailable(item, user);
|
|
378
600
|
} });
|
|
379
601
|
}
|
|
380
|
-
onItemAndUserAvailable(
|
|
602
|
+
onItemAndUserAvailable(_item, _user) { }
|
|
381
603
|
getItem() {
|
|
382
604
|
const id = Number(this.route.snapshot.paramMap.get('id'));
|
|
383
|
-
this.
|
|
384
|
-
this.
|
|
385
|
-
this.onItemAvailable();
|
|
605
|
+
this.itemService.getItem(id).subscribe(item => {
|
|
606
|
+
this.onItemAvailable(item);
|
|
386
607
|
});
|
|
387
608
|
}
|
|
609
|
+
onDelete() {
|
|
610
|
+
const item = this.item();
|
|
611
|
+
if (item) {
|
|
612
|
+
this.itemService.deleteItem(item.id);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
canEdit() {
|
|
616
|
+
return this.itemService.canEdit();
|
|
617
|
+
}
|
|
618
|
+
canDelete() {
|
|
619
|
+
return this.itemService.canDelete();
|
|
620
|
+
}
|
|
388
621
|
}
|
|
389
622
|
|
|
390
623
|
class EditView {
|
|
@@ -396,8 +629,8 @@ class EditView {
|
|
|
396
629
|
_location = inject(Location);
|
|
397
630
|
_userService = inject(UserService);
|
|
398
631
|
_restService;
|
|
399
|
-
constructor(
|
|
400
|
-
this._restService =
|
|
632
|
+
constructor(_restService) {
|
|
633
|
+
this._restService = _restService;
|
|
401
634
|
}
|
|
402
635
|
onInit() {
|
|
403
636
|
this.getItem();
|
|
@@ -494,48 +727,155 @@ class EditView {
|
|
|
494
727
|
}
|
|
495
728
|
|
|
496
729
|
class ListView {
|
|
497
|
-
user;
|
|
498
|
-
items = signal([], ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
499
|
-
displayedColumns = [];
|
|
500
730
|
_route = inject(ActivatedRoute);
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
731
|
+
userService = inject(UserService);
|
|
732
|
+
user = signal(null, ...(ngDevMode ? [{ debugName: "user" }] : []));
|
|
733
|
+
getUser() {
|
|
734
|
+
this.userService.loggedInUser.subscribe(user => {
|
|
735
|
+
if (user) {
|
|
736
|
+
this.user.set(user);
|
|
737
|
+
}
|
|
738
|
+
});
|
|
506
739
|
}
|
|
507
|
-
|
|
508
|
-
this.
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
740
|
+
isSelfList() {
|
|
741
|
+
const url_segments = this._route.snapshot.url;
|
|
742
|
+
return (url_segments.length == 2) && (url_segments[1].path == "self");
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
class SelectTableComponent {
|
|
747
|
+
itemType = input("", ...(ngDevMode ? [{ debugName: "itemType" }] : []));
|
|
748
|
+
selected = input([], ...(ngDevMode ? [{ debugName: "selected" }] : []));
|
|
749
|
+
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
|
|
750
|
+
columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
|
|
751
|
+
itemAdded = output();
|
|
752
|
+
itemRemoved = output();
|
|
753
|
+
searchChanged = output();
|
|
754
|
+
columnNames = computed(() => this.columns().map(c => c.name), ...(ngDevMode ? [{ debugName: "columnNames" }] : []));
|
|
755
|
+
searchControl = new FormControl('');
|
|
756
|
+
table = viewChild(MatTable, ...(ngDevMode ? [{ debugName: "table" }] : []));
|
|
757
|
+
ngOnInit() {
|
|
758
|
+
this.searchControl.valueChanges.subscribe(value => this.searchChanged.emit(value));
|
|
759
|
+
}
|
|
760
|
+
remove(id) {
|
|
761
|
+
this.itemRemoved.emit(id);
|
|
762
|
+
this.table()?.renderRows();
|
|
763
|
+
}
|
|
764
|
+
add() {
|
|
765
|
+
if (this.searchControl.value) {
|
|
766
|
+
this.itemAdded.emit(this.searchControl.value);
|
|
517
767
|
}
|
|
518
|
-
|
|
519
|
-
|
|
768
|
+
this.table()?.renderRows();
|
|
769
|
+
}
|
|
770
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: SelectTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
771
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: SelectTableComponent, isStandalone: true, selector: "lib-select-table", inputs: { itemType: { classPropertyName: "itemType", publicName: "itemType", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemAdded: "itemAdded", itemRemoved: "itemRemoved", searchChanged: "searchChanged" }, viewQueries: [{ propertyName: "table", first: true, predicate: MatTable, descendants: true, isSignal: true }], ngImport: i0, template: "<div class='select-container'>\n <div>\n <mat-form-field>\n <mat-label>Add {{itemType()}}</mat-label>\n <input \n type=\"text\"\n aria-label=\"Selected item\"\n matInput\n [formControl]=\"searchControl\" \n [matAutocomplete]=\"auto\">\n\n <mat-autocomplete #auto=\"matAutocomplete\">\n @for(item of options(); track item.item.id){\n <mat-option [value]=\"item.title\">{{item.title}}\n </mat-option>\n }\n </mat-autocomplete>\n </mat-form-field>\n\n <button mat-mini-fab type=\"button\" class=\"form_action_button\" (click)=\"add()\">\n <mat-icon>add\n </mat-icon>\n </button>\n </div>\n\n @if(selected().length > 0){\n <table mat-table [dataSource]=\"selected()\" class=\"mat-elevation-z8\">\n @for (column of columns(); track column.name) {\n <ng-container matColumnDef=\"{{ column.name }}\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>\n {{ column.title }}\n </th>\n <td mat-cell *matCellDef=\"let element\">{{ element[column.name] }}</td>\n </ng-container>\n }\n\n <ng-container matColumnDef=\"remove\">\n <th mat-header-cell *matHeaderCellDef>Remove\n </th>\n <td mat-cell *matCellDef=\"let element\">\n <button mat-icon-button\n color=\"primary\"\n aria-label=\"Remove an item\"\n (click)=\"remove(element.id)\">\n <mat-icon>remove\n </mat-icon>\n </button>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"columnNames()\">\n </tr>\n <tr mat-row *matRowDef=\"let row; columns: columnNames();\">\n </tr>\n </table>\n }\n</div>", styles: [".select-container,.table_container{display:flex;text-align:center;justify-content:center;flex-direction:column}.form_action_button{padding:5px;margin:5px}\n"], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$4.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$4.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$4.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$4.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$4.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$4.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$4.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$4.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$4.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$4.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i6$1.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i6$1.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }] });
|
|
772
|
+
}
|
|
773
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: SelectTableComponent, decorators: [{
|
|
774
|
+
type: Component,
|
|
775
|
+
args: [{ selector: 'lib-select-table', imports: [MatTableModule,
|
|
776
|
+
MatFormFieldModule,
|
|
777
|
+
MatButtonModule,
|
|
778
|
+
MatSelectModule,
|
|
779
|
+
MatIconModule,
|
|
780
|
+
MatAutocompleteModule,
|
|
781
|
+
ReactiveFormsModule,
|
|
782
|
+
MatInputModule], template: "<div class='select-container'>\n <div>\n <mat-form-field>\n <mat-label>Add {{itemType()}}</mat-label>\n <input \n type=\"text\"\n aria-label=\"Selected item\"\n matInput\n [formControl]=\"searchControl\" \n [matAutocomplete]=\"auto\">\n\n <mat-autocomplete #auto=\"matAutocomplete\">\n @for(item of options(); track item.item.id){\n <mat-option [value]=\"item.title\">{{item.title}}\n </mat-option>\n }\n </mat-autocomplete>\n </mat-form-field>\n\n <button mat-mini-fab type=\"button\" class=\"form_action_button\" (click)=\"add()\">\n <mat-icon>add\n </mat-icon>\n </button>\n </div>\n\n @if(selected().length > 0){\n <table mat-table [dataSource]=\"selected()\" class=\"mat-elevation-z8\">\n @for (column of columns(); track column.name) {\n <ng-container matColumnDef=\"{{ column.name }}\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>\n {{ column.title }}\n </th>\n <td mat-cell *matCellDef=\"let element\">{{ element[column.name] }}</td>\n </ng-container>\n }\n\n <ng-container matColumnDef=\"remove\">\n <th mat-header-cell *matHeaderCellDef>Remove\n </th>\n <td mat-cell *matCellDef=\"let element\">\n <button mat-icon-button\n color=\"primary\"\n aria-label=\"Remove an item\"\n (click)=\"remove(element.id)\">\n <mat-icon>remove\n </mat-icon>\n </button>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"columnNames()\">\n </tr>\n <tr mat-row *matRowDef=\"let row; columns: columnNames();\">\n </tr>\n </table>\n }\n</div>", styles: [".select-container,.table_container{display:flex;text-align:center;justify-content:center;flex-direction:column}.form_action_button{padding:5px;margin:5px}\n"] }]
|
|
783
|
+
}] });
|
|
784
|
+
|
|
785
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
786
|
+
class ListTableViewComponent {
|
|
787
|
+
itemType = input("", ...(ngDevMode ? [{ debugName: "itemType" }] : []));
|
|
788
|
+
columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
|
|
789
|
+
dataSource = input(...(ngDevMode ? [undefined, { debugName: "dataSource" }] : []));
|
|
790
|
+
searchFilter = input("", ...(ngDevMode ? [{ debugName: "searchFilter" }] : []));
|
|
791
|
+
pageSizeOptions = [20, 50, 100];
|
|
792
|
+
initialPageSize = 20;
|
|
793
|
+
columnNames = computed(() => this.columns().map(c => c.name), ...(ngDevMode ? [{ debugName: "columnNames" }] : []));
|
|
794
|
+
sort = viewChild(MatSort, ...(ngDevMode ? [{ debugName: "sort" }] : []));
|
|
795
|
+
paginator = viewChild(MatPaginator, ...(ngDevMode ? [{ debugName: "paginator" }] : []));
|
|
796
|
+
ngOnInit() {
|
|
797
|
+
const data_source = this.dataSource();
|
|
798
|
+
if (data_source) {
|
|
799
|
+
data_source.fetch(new ItemQuery({ page_size: this.initialPageSize }));
|
|
520
800
|
}
|
|
521
801
|
}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
802
|
+
ngAfterViewInit() {
|
|
803
|
+
const paginator = this.paginator();
|
|
804
|
+
const sort = this.sort();
|
|
805
|
+
if (!paginator || !sort) {
|
|
806
|
+
return;
|
|
807
|
+
}
|
|
808
|
+
sort.sortChange.subscribe(() => this.reset());
|
|
809
|
+
merge(sort.sortChange, paginator.page)
|
|
810
|
+
.pipe(tap(() => this.fetch()))
|
|
811
|
+
.subscribe();
|
|
812
|
+
}
|
|
813
|
+
reset() {
|
|
814
|
+
const paginator = this.paginator();
|
|
815
|
+
if (!paginator) {
|
|
816
|
+
return;
|
|
817
|
+
}
|
|
818
|
+
paginator.pageIndex = 0;
|
|
525
819
|
}
|
|
526
|
-
|
|
527
|
-
const
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
820
|
+
fetch() {
|
|
821
|
+
const paginator = this.paginator();
|
|
822
|
+
const sort = this.sort();
|
|
823
|
+
const data_source = this.dataSource();
|
|
824
|
+
if (!paginator || !sort || !data_source) {
|
|
825
|
+
return;
|
|
532
826
|
}
|
|
533
|
-
|
|
827
|
+
data_source.fetch(new ItemQuery({
|
|
828
|
+
page: paginator.pageIndex + 1,
|
|
829
|
+
page_size: paginator.pageSize,
|
|
830
|
+
sort_order: sort.direction,
|
|
831
|
+
sort_field: sort.active,
|
|
832
|
+
filter: this.searchFilter()
|
|
833
|
+
}));
|
|
534
834
|
}
|
|
535
|
-
|
|
536
|
-
|
|
835
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ListTableViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
836
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: ListTableViewComponent, isStandalone: true, selector: "lib-list-table-view", inputs: { itemType: { classPropertyName: "itemType", publicName: "itemType", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: false, transformFunction: null }, searchFilter: { classPropertyName: "searchFilter", publicName: "searchFilter", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "sort", first: true, predicate: MatSort, descendants: true, isSignal: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true, isSignal: true }], ngImport: i0, template: "@if (dataSource(); as dataSource) {\n <table\n mat-table\n [dataSource]=\"dataSource\"\n matSort\n matSortActive=\"name\"\n matSortDisableClear\n matSortDirection=\"desc\"\n class=\"mat-elevation-z8\"\n >\n @for (column of columns(); track column.name) {\n <ng-container matColumnDef=\"{{ column.name }}\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>\n {{ column.title }}\n </th>\n <td mat-cell *matCellDef=\"let element\">{{ element[column.name] }}</td>\n </ng-container>\n }\n\n <tr mat-header-row *matHeaderRowDef=\"columnNames()\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: columnNames()\"\n [routerLink]=\"['/' + itemType() + '/detail/', row.id]\"\n [routerLinkActive]=\"['is-active']\"\n ></tr>\n </table>\n\n <mat-paginator\n [length]=\"dataSource.length()\"\n [pageSize]=\"20\"\n [pageSizeOptions]=\"pageSizeOptions\"\n aria-label=\"Select page\"\n >\n </mat-paginator>\n}\n", styles: [".mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.is-active{font-weight:700}\n"], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$4.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$4.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$4.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$4.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$4.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$4.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$4.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$4.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$4.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$4.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i2$3.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "directive", type: i3$3.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i3$3.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i1.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }] });
|
|
837
|
+
}
|
|
838
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ListTableViewComponent, decorators: [{
|
|
839
|
+
type: Component,
|
|
840
|
+
args: [{ selector: 'lib-list-table-view', imports: [MatTableModule,
|
|
841
|
+
ReactiveFormsModule,
|
|
842
|
+
MatButtonModule,
|
|
843
|
+
MatInputModule,
|
|
844
|
+
MatIconModule,
|
|
845
|
+
MatPaginatorModule,
|
|
846
|
+
MatSortModule,
|
|
847
|
+
RouterModule
|
|
848
|
+
], template: "@if (dataSource(); as dataSource) {\n <table\n mat-table\n [dataSource]=\"dataSource\"\n matSort\n matSortActive=\"name\"\n matSortDisableClear\n matSortDirection=\"desc\"\n class=\"mat-elevation-z8\"\n >\n @for (column of columns(); track column.name) {\n <ng-container matColumnDef=\"{{ column.name }}\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>\n {{ column.title }}\n </th>\n <td mat-cell *matCellDef=\"let element\">{{ element[column.name] }}</td>\n </ng-container>\n }\n\n <tr mat-header-row *matHeaderRowDef=\"columnNames()\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: columnNames()\"\n [routerLink]=\"['/' + itemType() + '/detail/', row.id]\"\n [routerLinkActive]=\"['is-active']\"\n ></tr>\n </table>\n\n <mat-paginator\n [length]=\"dataSource.length()\"\n [pageSize]=\"20\"\n [pageSizeOptions]=\"pageSizeOptions\"\n aria-label=\"Select page\"\n >\n </mat-paginator>\n}\n", styles: [".mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.is-active{font-weight:700}\n"] }]
|
|
849
|
+
}] });
|
|
850
|
+
|
|
851
|
+
// Datasource needs any
|
|
852
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
853
|
+
class ListScrollViewComponent {
|
|
854
|
+
searchTerm = input("", ...(ngDevMode ? [{ debugName: "searchTerm" }] : []));
|
|
855
|
+
pageSize = input(20, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
|
|
856
|
+
dataSource = input(...(ngDevMode ? [undefined, { debugName: "dataSource" }] : []));
|
|
857
|
+
listItemTemplate = input(null, ...(ngDevMode ? [{ debugName: "listItemTemplate" }] : []));
|
|
858
|
+
ngOnInit() {
|
|
859
|
+
this.reset();
|
|
860
|
+
}
|
|
861
|
+
reset() {
|
|
862
|
+
const data_source = this.dataSource();
|
|
863
|
+
if (!data_source) {
|
|
864
|
+
return;
|
|
865
|
+
}
|
|
866
|
+
// sort_order: this.sort!.direction,
|
|
867
|
+
// sort_field: this.sort!.active,
|
|
868
|
+
data_source.reset(this.searchTerm(), this.pageSize());
|
|
537
869
|
}
|
|
870
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ListScrollViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
871
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.1.1", type: ListScrollViewComponent, isStandalone: true, selector: "lib-list-scroll-view", inputs: { searchTerm: { classPropertyName: "searchTerm", publicName: "searchTerm", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: false, transformFunction: null }, listItemTemplate: { classPropertyName: "listItemTemplate", publicName: "listItemTemplate", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mat-nav-list>\n <cdk-virtual-scroll-viewport\n itemSize=\"150\"\n class=\"scrollable-list\"\n style=\"height: 600px; width: 500px\"\n >\n <ng-container *cdkVirtualFor=\"let item of dataSource()\">\n <ng-container\n *ngTemplateOutlet=\"listItemTemplate(); context: { item: item }\"\n >\n </ng-container>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n</mat-nav-list>\n", styles: [":host{flex-grow:1}.mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.is-active{font-weight:700}\n"], dependencies: [{ kind: "ngmodule", type: MatListModule }, { kind: "component", type: i2$2.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i2$4.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i2$4.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i2$4.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }] });
|
|
538
872
|
}
|
|
873
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ListScrollViewComponent, decorators: [{
|
|
874
|
+
type: Component,
|
|
875
|
+
args: [{ selector: 'lib-list-scroll-view', imports: [MatListModule,
|
|
876
|
+
NgTemplateOutlet,
|
|
877
|
+
ScrollingModule], template: "<mat-nav-list>\n <cdk-virtual-scroll-viewport\n itemSize=\"150\"\n class=\"scrollable-list\"\n style=\"height: 600px; width: 500px\"\n >\n <ng-container *cdkVirtualFor=\"let item of dataSource()\">\n <ng-container\n *ngTemplateOutlet=\"listItemTemplate(); context: { item: item }\"\n >\n </ng-container>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n</mat-nav-list>\n", styles: [":host{flex-grow:1}.mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.is-active{font-weight:700}\n"] }]
|
|
878
|
+
}] });
|
|
539
879
|
|
|
540
880
|
class BackButtonComponent {
|
|
541
881
|
location = inject(Location);
|
|
@@ -543,26 +883,223 @@ class BackButtonComponent {
|
|
|
543
883
|
this.location.back();
|
|
544
884
|
}
|
|
545
885
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: BackButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
546
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.1", type: BackButtonComponent, isStandalone: true, selector: "lib-back-button", ngImport: i0, template: "<a mat-icon-button class=\"padded-button\"\n (click)=\"goBack()\"\n (keydown)=\"goBack()\"\n tabindex=\"0\"\n role=\"button\">\n<mat-icon>arrow_back</mat-icon>\n</a>\n\n", styles: [".padded-button{
|
|
886
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.1", type: BackButtonComponent, isStandalone: true, selector: "lib-back-button", ngImport: i0, template: "<a mat-icon-button class=\"padded-button\"\n (click)=\"goBack()\"\n (keydown)=\"goBack()\"\n tabindex=\"0\"\n role=\"button\">\n<mat-icon>arrow_back</mat-icon>\n</a>\n\n", styles: [".padded-button{margin:5px}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }] });
|
|
547
887
|
}
|
|
548
888
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: BackButtonComponent, decorators: [{
|
|
549
889
|
type: Component,
|
|
550
|
-
args: [{ selector: 'lib-back-button', imports: [MatIconModule, MatButtonModule], template: "<a mat-icon-button class=\"padded-button\"\n (click)=\"goBack()\"\n (keydown)=\"goBack()\"\n tabindex=\"0\"\n role=\"button\">\n<mat-icon>arrow_back</mat-icon>\n</a>\n\n", styles: [".padded-button{
|
|
890
|
+
args: [{ selector: 'lib-back-button', imports: [MatIconModule, MatButtonModule], template: "<a mat-icon-button class=\"padded-button\"\n (click)=\"goBack()\"\n (keydown)=\"goBack()\"\n tabindex=\"0\"\n role=\"button\">\n<mat-icon>arrow_back</mat-icon>\n</a>\n\n", styles: [".padded-button{margin:5px}\n"] }]
|
|
891
|
+
}] });
|
|
892
|
+
|
|
893
|
+
class SearchBarComponent {
|
|
894
|
+
itemType = input("", ...(ngDevMode ? [{ debugName: "itemType" }] : []));
|
|
895
|
+
sortFields = input([], ...(ngDevMode ? [{ debugName: "sortFields" }] : []));
|
|
896
|
+
sortAscending = signal(true, ...(ngDevMode ? [{ debugName: "sortAscending" }] : []));
|
|
897
|
+
searchChanged = output();
|
|
898
|
+
searchFilter = new FormControl();
|
|
899
|
+
ngAfterViewInit() {
|
|
900
|
+
this.searchFilter.valueChanges.pipe(debounceTime(150), distinctUntilChanged(), tap(() => {
|
|
901
|
+
this.searchEntered();
|
|
902
|
+
})).subscribe();
|
|
903
|
+
}
|
|
904
|
+
clearSearch() {
|
|
905
|
+
this.searchFilter.setValue("");
|
|
906
|
+
}
|
|
907
|
+
searchEntered() {
|
|
908
|
+
this.searchChanged.emit(this.searchFilter.value);
|
|
909
|
+
}
|
|
910
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: SearchBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
911
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: SearchBarComponent, isStandalone: true, selector: "lib-search-bar", inputs: { itemType: { classPropertyName: "itemType", publicName: "itemType", isSignal: true, isRequired: false, transformFunction: null }, sortFields: { classPropertyName: "sortFields", publicName: "sortFields", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchChanged: "searchChanged" }, ngImport: i0, template: "<div class=\"container\">\n <mat-form-field class=\"search\" style=\"margin: 10px;\">\n <mat-label>Search</mat-label>\n <input matInput [formControl]=\"searchFilter\" placeholder=\"Search {{ itemType() | titlecase }}\" />\n\n @if(searchFilter.value){\n <button matSuffix mat-icon-button aria-label=\"Cancel\" (click)=\"clearSearch()\">\n <mat-icon>cancel</mat-icon>\n </button>\n }\n @else(){\n <button matSuffix mat-icon-button aria-label=\"Search\">\n <mat-icon>search</mat-icon>\n </button>\n }\n </mat-form-field>\n\n @if(sortFields().length > 0){\n <mat-form-field style=\"margin: 10px\">\n <mat-label>Sort By</mat-label>\n <mat-select>\n @for(field of sortFields(); track field)\n {\n <mat-option>{{field}}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n <button mat-icon-button aria-label=\"Sort Order\" matTooltip=\"Toggle sort order\">\n <mat-icon>sort</mat-icon>\n </button>\n }\n</div>", styles: [".container{width:100%;display:flex;flex-wrap:wrap;flex-direction:row;align-items:center;justify-content:center}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }] });
|
|
912
|
+
}
|
|
913
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: SearchBarComponent, decorators: [{
|
|
914
|
+
type: Component,
|
|
915
|
+
args: [{ selector: 'lib-search-bar', imports: [ReactiveFormsModule,
|
|
916
|
+
MatInputModule,
|
|
917
|
+
MatTooltipModule,
|
|
918
|
+
MatButtonModule,
|
|
919
|
+
MatSelectModule,
|
|
920
|
+
MatIconModule,
|
|
921
|
+
TitleCasePipe], template: "<div class=\"container\">\n <mat-form-field class=\"search\" style=\"margin: 10px;\">\n <mat-label>Search</mat-label>\n <input matInput [formControl]=\"searchFilter\" placeholder=\"Search {{ itemType() | titlecase }}\" />\n\n @if(searchFilter.value){\n <button matSuffix mat-icon-button aria-label=\"Cancel\" (click)=\"clearSearch()\">\n <mat-icon>cancel</mat-icon>\n </button>\n }\n @else(){\n <button matSuffix mat-icon-button aria-label=\"Search\">\n <mat-icon>search</mat-icon>\n </button>\n }\n </mat-form-field>\n\n @if(sortFields().length > 0){\n <mat-form-field style=\"margin: 10px\">\n <mat-label>Sort By</mat-label>\n <mat-select>\n @for(field of sortFields(); track field)\n {\n <mat-option>{{field}}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n <button mat-icon-button aria-label=\"Sort Order\" matTooltip=\"Toggle sort order\">\n <mat-icon>sort</mat-icon>\n </button>\n }\n</div>", styles: [".container{width:100%;display:flex;flex-wrap:wrap;flex-direction:row;align-items:center;justify-content:center}\n"] }]
|
|
922
|
+
}] });
|
|
923
|
+
|
|
924
|
+
class ListDataSource extends DataSource {
|
|
925
|
+
length = signal(0, ...(ngDevMode ? [{ debugName: "length" }] : []));
|
|
926
|
+
loading = signal(true, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
927
|
+
searchTerm = signal("", ...(ngDevMode ? [{ debugName: "searchTerm" }] : []));
|
|
928
|
+
pageSize = signal(20, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
|
|
929
|
+
consumerType;
|
|
930
|
+
items = new BehaviorSubject([]);
|
|
931
|
+
itemService;
|
|
932
|
+
subscription = new Subscription();
|
|
933
|
+
fetchedPages = new Set();
|
|
934
|
+
constructor(itemService, consumerType = "table") {
|
|
935
|
+
super();
|
|
936
|
+
this.itemService = itemService;
|
|
937
|
+
this.consumerType = consumerType;
|
|
938
|
+
}
|
|
939
|
+
connect(collectionViewer) {
|
|
940
|
+
if (!this.hasTableConsumer()) {
|
|
941
|
+
this.subscription.add(collectionViewer.viewChange.subscribe((range) => this.onRange(range)));
|
|
942
|
+
}
|
|
943
|
+
return this.items.asObservable();
|
|
944
|
+
}
|
|
945
|
+
hasTableConsumer() {
|
|
946
|
+
return this.consumerType === "table";
|
|
947
|
+
}
|
|
948
|
+
onRange(range) {
|
|
949
|
+
const start_page = Math.floor(range.start / this.pageSize());
|
|
950
|
+
const end_page = Math.floor(range.end / this.pageSize());
|
|
951
|
+
for (let idx = start_page; idx <= end_page; idx++) {
|
|
952
|
+
this.fetchPage(idx);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
reset(searchTerm = "", pageSize = 20) {
|
|
956
|
+
this.fetchedPages = new Set();
|
|
957
|
+
this.length.set(0);
|
|
958
|
+
this.searchTerm.set(searchTerm);
|
|
959
|
+
this.pageSize.set(pageSize);
|
|
960
|
+
this.loading.set(true);
|
|
961
|
+
this.items.next([]);
|
|
962
|
+
this.fetchPage(0);
|
|
963
|
+
}
|
|
964
|
+
fetchPage(idx) {
|
|
965
|
+
if (this.fetchedPages.has(idx)) {
|
|
966
|
+
return;
|
|
967
|
+
}
|
|
968
|
+
this.fetchedPages.add(idx);
|
|
969
|
+
this.fetch(new ItemQuery({ page: idx + 1,
|
|
970
|
+
page_size: this.pageSize(),
|
|
971
|
+
filter: this.searchTerm() }));
|
|
972
|
+
}
|
|
973
|
+
fetch(query) {
|
|
974
|
+
this.loading.set(true);
|
|
975
|
+
this.itemService.get(query).pipe(catchError(() => of(new Paginated())), finalize(() => this.loading.set(false))).subscribe(response => this.onResponse(response));
|
|
976
|
+
}
|
|
977
|
+
onResponse(response) {
|
|
978
|
+
this.length.set(response.count);
|
|
979
|
+
if (this.hasTableConsumer()) {
|
|
980
|
+
this.items.next(response.results);
|
|
981
|
+
}
|
|
982
|
+
else {
|
|
983
|
+
this.items.next([...this.items.value, ...response.results]);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
disconnect() {
|
|
987
|
+
this.items.complete();
|
|
988
|
+
if (this.subscription) {
|
|
989
|
+
this.subscription.unsubscribe();
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
class ListViewComponent {
|
|
995
|
+
viewType = input("table", ...(ngDevMode ? [{ debugName: "viewType" }] : []));
|
|
996
|
+
itemService = input(...(ngDevMode ? [undefined, { debugName: "itemService" }] : []));
|
|
997
|
+
itemDetailTemplate = input(null, ...(ngDevMode ? [{ debugName: "itemDetailTemplate" }] : []));
|
|
998
|
+
columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
|
|
999
|
+
sortFields = input([], ...(ngDevMode ? [{ debugName: "sortFields" }] : []));
|
|
1000
|
+
noSelfItemsMessage = input(...(ngDevMode ? [undefined, { debugName: "noSelfItemsMessage" }] : []));
|
|
1001
|
+
noItemsCanCreateMessage = input(...(ngDevMode ? [undefined, { debugName: "noItemsCanCreateMessage" }] : []));
|
|
1002
|
+
noItemsMessage = input(...(ngDevMode ? [undefined, { debugName: "noItemsMessage" }] : []));
|
|
1003
|
+
selectedViewType = signal("table", ...(ngDevMode ? [{ debugName: "selectedViewType" }] : []));
|
|
1004
|
+
pageSize = 20;
|
|
1005
|
+
pageSizeOptions = [20, 50, 100];
|
|
1006
|
+
route = inject(ActivatedRoute);
|
|
1007
|
+
dataSource = undefined;
|
|
1008
|
+
sort = viewChild(MatSort, ...(ngDevMode ? [{ debugName: "sort" }] : []));
|
|
1009
|
+
columnNames = computed(() => this.columns().map(c => c.name), ...(ngDevMode ? [{ debugName: "columnNames" }] : []));
|
|
1010
|
+
searchTerm = "";
|
|
1011
|
+
ngOnInit() {
|
|
1012
|
+
this.selectedViewType.set(this.viewType());
|
|
1013
|
+
this.resetDataSource();
|
|
1014
|
+
}
|
|
1015
|
+
ngAfterViewInit() {
|
|
1016
|
+
const sort = this.sort();
|
|
1017
|
+
if (sort) {
|
|
1018
|
+
sort.sortChange.pipe(tap(() => this.reset())).subscribe();
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
onSearchChange(value) {
|
|
1022
|
+
this.searchTerm = value;
|
|
1023
|
+
this.reset();
|
|
1024
|
+
}
|
|
1025
|
+
canCreate() {
|
|
1026
|
+
const item_service = this.itemService();
|
|
1027
|
+
if (item_service) {
|
|
1028
|
+
return item_service.canCreate();
|
|
1029
|
+
}
|
|
1030
|
+
return false;
|
|
1031
|
+
}
|
|
1032
|
+
itemType() {
|
|
1033
|
+
const item_service = this.itemService();
|
|
1034
|
+
if (item_service) {
|
|
1035
|
+
return item_service.itemType;
|
|
1036
|
+
}
|
|
1037
|
+
return "";
|
|
1038
|
+
}
|
|
1039
|
+
isTableView() {
|
|
1040
|
+
return this.selectedViewType() === "table";
|
|
1041
|
+
}
|
|
1042
|
+
resetDataSource() {
|
|
1043
|
+
const item_service = this.itemService();
|
|
1044
|
+
if (item_service) {
|
|
1045
|
+
this.dataSource = new ListDataSource(item_service, this.selectedViewType());
|
|
1046
|
+
}
|
|
1047
|
+
this.reset();
|
|
1048
|
+
}
|
|
1049
|
+
reset() {
|
|
1050
|
+
if (this.dataSource) {
|
|
1051
|
+
this.dataSource.reset(this.searchTerm, this.pageSize);
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
viewChanged(event) {
|
|
1055
|
+
this.selectedViewType.set(event.value);
|
|
1056
|
+
console.log(this.selectedViewType());
|
|
1057
|
+
this.resetDataSource();
|
|
1058
|
+
}
|
|
1059
|
+
isSelfList() {
|
|
1060
|
+
const url_segments = this.route.snapshot.url;
|
|
1061
|
+
return (url_segments.length == 2) && (url_segments[1].path == "self");
|
|
1062
|
+
}
|
|
1063
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ListViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1064
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: ListViewComponent, isStandalone: true, selector: "lib-list-view", inputs: { viewType: { classPropertyName: "viewType", publicName: "viewType", isSignal: true, isRequired: false, transformFunction: null }, itemService: { classPropertyName: "itemService", publicName: "itemService", isSignal: true, isRequired: false, transformFunction: null }, itemDetailTemplate: { classPropertyName: "itemDetailTemplate", publicName: "itemDetailTemplate", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, sortFields: { classPropertyName: "sortFields", publicName: "sortFields", isSignal: true, isRequired: false, transformFunction: null }, noSelfItemsMessage: { classPropertyName: "noSelfItemsMessage", publicName: "noSelfItemsMessage", isSignal: true, isRequired: false, transformFunction: null }, noItemsCanCreateMessage: { classPropertyName: "noItemsCanCreateMessage", publicName: "noItemsCanCreateMessage", isSignal: true, isRequired: false, transformFunction: null }, noItemsMessage: { classPropertyName: "noItemsMessage", publicName: "noItemsMessage", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "sort", first: true, predicate: MatSort, descendants: true, isSignal: true }], ngImport: i0, template: "<lib-back-button></lib-back-button>\n\n<div class=\"container\">\n <div class=\"header\">\n <h1 class=\"title\">{{ itemType() | titlecase }}</h1>\n\n @if (canCreate()) {\n <div class=\"button-container\">\n <a mat-fab class=\"padded-button\" aria-label=\"Add new item\" matTooltip=\"Add new item\" [routerLink]=\"['create']\">\n <mat-icon>add</mat-icon></a>\n </div>\n }\n </div>\n\n <div class=\"controls\">\n <lib-search-bar [itemType]=\"itemType()\" [sortFields]=\"sortFields()\"\n (searchChanged)=\"onSearchChange($event)\"></lib-search-bar>\n\n @if(itemDetailTemplate()){\n <div style=\"margin: 10px\">\n <mat-button-toggle-group name=\"viewType\" aria-label=\"View Type\" [value]=\"selectedViewType()\"\n (change)=\"viewChanged($event)\">\n\n <mat-button-toggle value=\"table\" matTooltip=\"Show as table\">\n <mat-icon>table_view</mat-icon>\n </mat-button-toggle>\n\n <mat-button-toggle value=\"scroll\" matTooltip=\"Show as list\">\n <mat-icon>list</mat-icon>\n </mat-button-toggle>\n\n </mat-button-toggle-group>\n </div>\n }\n </div>\n\n @if(dataSource)\n {\n @if (dataSource.loading()) {\n <div class=\"spinner-container\">\n <mat-spinner></mat-spinner>\n </div>\n }\n @else{\n @if(dataSource.length() === 0)\n {\n @if(isSelfList())\n {\n @if(noSelfItemsMessage())\n {\n <p>{{noSelfItemsMessage()}}</p>\n }\n @else {\n <p>You do not have any {{itemType()}}.</p> \n }\n\n }\n @else{\n @if(canCreate()){\n @if(noItemsCanCreateMessage())\n {\n <p>{{noItemsCanCreateMessage()}}</p>\n }\n @else{\n <p>There are currently no {{itemType()}}, click above to add one.</p>\n }\n }\n @else{\n @if(noItemsMessage())\n {\n <p>{{noItemsMessage()}}</p>\n }\n @else\n {\n <p>There are currently no {{itemType()}}.</p>\n }\n }\n }\n }\n @else{\n @if(isTableView()) {\n <lib-list-table-view [itemType]=\"itemType()\" [columns]=\"columns()\" [dataSource]=\"dataSource\">\n </lib-list-table-view>\n } \n @else {\n <lib-list-scroll-view [listItemTemplate]=\"itemDetailTemplate()\" [dataSource]=\"dataSource\"></lib-list-scroll-view>\n }\n }\n }\n }\n</div>", styles: [":host{flex-grow:1}.container{display:flex;padding:10px;flex-direction:column;justify-content:center;text-align:center;align-items:center}.header{display:flex;flex-direction:row;align-items:center;justify-content:center}.title{text-align:center;padding:10px}.controls{display:flex;align-items:center;justify-content:center;flex-wrap:wrap}\n"], dependencies: [{ kind: "component", type: ListTableViewComponent, selector: "lib-list-table-view", inputs: ["itemType", "columns", "dataSource", "searchFilter"] }, { kind: "component", type: ListScrollViewComponent, selector: "lib-list-scroll-view", inputs: ["searchTerm", "pageSize", "dataSource", "listItemTemplate"] }, { kind: "component", type: BackButtonComponent, selector: "lib-back-button" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i1$5.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i1$5.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i2$5.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: SearchBarComponent, selector: "lib-search-bar", inputs: ["itemType", "sortFields"], outputs: ["searchChanged"] }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }] });
|
|
1065
|
+
}
|
|
1066
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: ListViewComponent, decorators: [{
|
|
1067
|
+
type: Component,
|
|
1068
|
+
args: [{ selector: 'lib-list-view', imports: [ListTableViewComponent,
|
|
1069
|
+
ListScrollViewComponent,
|
|
1070
|
+
BackButtonComponent,
|
|
1071
|
+
MatFormFieldModule,
|
|
1072
|
+
MatButtonToggleModule,
|
|
1073
|
+
MatProgressSpinnerModule,
|
|
1074
|
+
MatIconModule,
|
|
1075
|
+
ReactiveFormsModule,
|
|
1076
|
+
RouterModule,
|
|
1077
|
+
TitleCasePipe,
|
|
1078
|
+
MatInputModule,
|
|
1079
|
+
MatTooltipModule,
|
|
1080
|
+
MatButtonModule,
|
|
1081
|
+
SearchBarComponent], template: "<lib-back-button></lib-back-button>\n\n<div class=\"container\">\n <div class=\"header\">\n <h1 class=\"title\">{{ itemType() | titlecase }}</h1>\n\n @if (canCreate()) {\n <div class=\"button-container\">\n <a mat-fab class=\"padded-button\" aria-label=\"Add new item\" matTooltip=\"Add new item\" [routerLink]=\"['create']\">\n <mat-icon>add</mat-icon></a>\n </div>\n }\n </div>\n\n <div class=\"controls\">\n <lib-search-bar [itemType]=\"itemType()\" [sortFields]=\"sortFields()\"\n (searchChanged)=\"onSearchChange($event)\"></lib-search-bar>\n\n @if(itemDetailTemplate()){\n <div style=\"margin: 10px\">\n <mat-button-toggle-group name=\"viewType\" aria-label=\"View Type\" [value]=\"selectedViewType()\"\n (change)=\"viewChanged($event)\">\n\n <mat-button-toggle value=\"table\" matTooltip=\"Show as table\">\n <mat-icon>table_view</mat-icon>\n </mat-button-toggle>\n\n <mat-button-toggle value=\"scroll\" matTooltip=\"Show as list\">\n <mat-icon>list</mat-icon>\n </mat-button-toggle>\n\n </mat-button-toggle-group>\n </div>\n }\n </div>\n\n @if(dataSource)\n {\n @if (dataSource.loading()) {\n <div class=\"spinner-container\">\n <mat-spinner></mat-spinner>\n </div>\n }\n @else{\n @if(dataSource.length() === 0)\n {\n @if(isSelfList())\n {\n @if(noSelfItemsMessage())\n {\n <p>{{noSelfItemsMessage()}}</p>\n }\n @else {\n <p>You do not have any {{itemType()}}.</p> \n }\n\n }\n @else{\n @if(canCreate()){\n @if(noItemsCanCreateMessage())\n {\n <p>{{noItemsCanCreateMessage()}}</p>\n }\n @else{\n <p>There are currently no {{itemType()}}, click above to add one.</p>\n }\n }\n @else{\n @if(noItemsMessage())\n {\n <p>{{noItemsMessage()}}</p>\n }\n @else\n {\n <p>There are currently no {{itemType()}}.</p>\n }\n }\n }\n }\n @else{\n @if(isTableView()) {\n <lib-list-table-view [itemType]=\"itemType()\" [columns]=\"columns()\" [dataSource]=\"dataSource\">\n </lib-list-table-view>\n } \n @else {\n <lib-list-scroll-view [listItemTemplate]=\"itemDetailTemplate()\" [dataSource]=\"dataSource\"></lib-list-scroll-view>\n }\n }\n }\n }\n</div>", styles: [":host{flex-grow:1}.container{display:flex;padding:10px;flex-direction:column;justify-content:center;text-align:center;align-items:center}.header{display:flex;flex-direction:row;align-items:center;justify-content:center}.title{text-align:center;padding:10px}.controls{display:flex;align-items:center;justify-content:center;flex-wrap:wrap}\n"] }]
|
|
551
1082
|
}] });
|
|
552
1083
|
|
|
553
1084
|
class DetailHeaderComponent {
|
|
554
1085
|
id = input(0, ...(ngDevMode ? [{ debugName: "id" }] : []));
|
|
555
1086
|
text = input("", ...(ngDevMode ? [{ debugName: "text" }] : []));
|
|
556
1087
|
route = input("", ...(ngDevMode ? [{ debugName: "route" }] : []));
|
|
1088
|
+
canEdit = input(false, ...(ngDevMode ? [{ debugName: "canEdit" }] : []));
|
|
1089
|
+
canDelete = input(false, ...(ngDevMode ? [{ debugName: "canDelete" }] : []));
|
|
1090
|
+
deleteClicked = output();
|
|
557
1091
|
fullRoute = computed(() => "/" + this.route() + "s/edit/", ...(ngDevMode ? [{ debugName: "fullRoute" }] : []));
|
|
1092
|
+
deleteClick() {
|
|
1093
|
+
this.deleteClicked.emit();
|
|
1094
|
+
}
|
|
558
1095
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: DetailHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
559
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
1096
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: DetailHeaderComponent, isStandalone: true, selector: "lib-detail-header", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null }, route: { classPropertyName: "route", publicName: "route", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, canDelete: { classPropertyName: "canDelete", publicName: "canDelete", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { deleteClicked: "deleteClicked" }, ngImport: i0, template: "<div class=\"container\">\n\n <h1 class=\"header\">{{text()}}</h1>\n\n <div class=\"controls\">\n @if(canEdit()){\n <a mat-mini-fab class=\"control-button\" matTooltip=\"Edit the item\" title=\"Click to edit this item\" aria-label=\"Click to edit this item\"\n [routerLink]=\"[fullRoute(), id()]\">\n <mat-icon>edit</mat-icon>\n </a>\n }\n\n @if(canDelete()){\n <button mat-mini-fab class=\"control-button\" (click)=\"deleteClick()\" matTooltip=\"Delete the item\" title=\"Click to delete this item\"\n aria-label=\"Click to delete this item\">\n <mat-icon>delete</mat-icon></button>\n }\n </div>\n\n</div>", styles: [".container{width:100%;max-width:500px;padding:5px}.header{width:100%;padding:5px;margin:5px}.controls{display:flex;flex-direction:row;align-content:center;justify-content:center}.control-button{padding:5px;margin:5px}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
560
1097
|
}
|
|
561
1098
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: DetailHeaderComponent, decorators: [{
|
|
562
1099
|
type: Component,
|
|
563
1100
|
args: [{ selector: 'lib-detail-header', imports: [RouterModule,
|
|
564
1101
|
MatButtonModule,
|
|
565
|
-
MatIconModule], template: "<div class=\"container\">\n
|
|
1102
|
+
MatIconModule, MatTooltipModule], template: "<div class=\"container\">\n\n <h1 class=\"header\">{{text()}}</h1>\n\n <div class=\"controls\">\n @if(canEdit()){\n <a mat-mini-fab class=\"control-button\" matTooltip=\"Edit the item\" title=\"Click to edit this item\" aria-label=\"Click to edit this item\"\n [routerLink]=\"[fullRoute(), id()]\">\n <mat-icon>edit</mat-icon>\n </a>\n }\n\n @if(canDelete()){\n <button mat-mini-fab class=\"control-button\" (click)=\"deleteClick()\" matTooltip=\"Delete the item\" title=\"Click to delete this item\"\n aria-label=\"Click to delete this item\">\n <mat-icon>delete</mat-icon></button>\n }\n </div>\n\n</div>", styles: [".container{width:100%;max-width:500px;padding:5px}.header{width:100%;padding:5px;margin:5px}.controls{display:flex;flex-direction:row;align-content:center;justify-content:center}.control-button{padding:5px;margin:5px}\n"] }]
|
|
566
1103
|
}] });
|
|
567
1104
|
|
|
568
1105
|
class FileUploadComponent {
|
|
@@ -597,7 +1134,7 @@ class FileUploadComponent {
|
|
|
597
1134
|
};
|
|
598
1135
|
}
|
|
599
1136
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FileUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
600
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: FileUploadComponent, isStandalone: true, selector: "lib-file-upload", inputs: { files: { classPropertyName: "files", publicName: "files", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { previewLoaded: "previewLoaded", fileUploaded: "fileUploaded" }, ngImport: i0, template: "<div class=\"container\">\n @for( file of files(); track file.name)\n {\n @if (file.local)\n {\n <div class=\"image_holder\">\n <p>Update {{file.display_name}}</p>\n <img alt=\"{{file.display_name}}\" src=\"{{file.local}}\" style=\"height:120px;\">\n </div> \n }\n @else\n {\n @if (file.remote){\n <div class=\"image_holder\">\n <p>Update {{file.display_name}}</p>\n <img alt=\"{{file.display_name}}\" src=\"{{file.remote}}\" style=\"height:120px;\">\n </div>\n }\n @else {\n <div>\n <span>Upload a {{file.display_name}}</span>\n </div> \n }\n \n }\n\n <div class=\"button-row\">\n <button mat-mini-fab (click)=\"fileInput.click()\">\n <mat-icon>attachment</mat-icon>\n </button>\n <input hidden type=\"file\" #fileInput (change)=\"onFileUpload(file.name, $event)\"/>\n </div> \n } \n</div>\n", styles: [".container{padding:10px;display:flex;justify-content:center;text-align:center;flex-direction:column;max-width:300px}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3
|
|
1137
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: FileUploadComponent, isStandalone: true, selector: "lib-file-upload", inputs: { files: { classPropertyName: "files", publicName: "files", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { previewLoaded: "previewLoaded", fileUploaded: "fileUploaded" }, ngImport: i0, template: "<div class=\"container\">\n @for( file of files(); track file.name)\n {\n @if (file.local)\n {\n <div class=\"image_holder\">\n <p>Update {{file.display_name}}</p>\n <img alt=\"{{file.display_name}}\" src=\"{{file.local}}\" style=\"height:120px;\">\n </div> \n }\n @else\n {\n @if (file.remote){\n <div class=\"image_holder\">\n <p>Update {{file.display_name}}</p>\n <img alt=\"{{file.display_name}}\" src=\"{{file.remote}}\" style=\"height:120px;\">\n </div>\n }\n @else {\n <div>\n <span>Upload a {{file.display_name}}</span>\n </div> \n }\n \n }\n\n <div class=\"button-row\">\n <button mat-mini-fab (click)=\"fileInput.click()\">\n <mat-icon>attachment</mat-icon>\n </button>\n <input hidden type=\"file\" #fileInput (change)=\"onFileUpload(file.name, $event)\"/>\n </div> \n } \n</div>\n", styles: [".container{padding:10px;display:flex;justify-content:center;text-align:center;flex-direction:column;max-width:300px}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }] });
|
|
601
1138
|
}
|
|
602
1139
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: FileUploadComponent, decorators: [{
|
|
603
1140
|
type: Component,
|
|
@@ -625,13 +1162,13 @@ class UserDetailComponent extends DetailView {
|
|
|
625
1162
|
this.onInit();
|
|
626
1163
|
}
|
|
627
1164
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
628
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: UserDetailComponent, isStandalone: true, selector: "lib-user-detail", usesInheritance: true, ngImport: i0, template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n @if(item(); as item){\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.username\"\n [id]=\"item.id\"\n [route]=\"typename\"></lib-detail-header>\n\n @if(item.profile_url){\n <div class=\"image-holder\">\n <img alt=\"User Profile Image\" src=\"{{item.url}}{{item.profile_url}}\" style=\"height:120px;\">\n </div> \n }\n \n <div class=\"item-field\">\n <span><b>Email: </b></span>\n {{item.email}}\n </div>\n \n <div class=\"item-field\">\n <span><b>First Name: </b></span>\n {{item.first_name}}\n </div>\n \n <div class=\"item-field\">\n <span><b>Last Name: </b></span>\n {{item.last_name}}\n </div>\n \n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}\n"], dependencies: [{ kind: "component", type: BackButtonComponent, selector: "lib-back-button" }, { kind: "component", type: DetailHeaderComponent, selector: "lib-detail-header", inputs: ["id", "text", "route"] }] });
|
|
1165
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: UserDetailComponent, isStandalone: true, selector: "lib-user-detail", usesInheritance: true, ngImport: i0, template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n @if(item(); as item){\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.username\"\n [id]=\"item.id\"\n [route]=\"typename\"\n [canEdit]=\"canEdit()\"\n [canDelete]=\"canDelete()\"\n (onDelete)=\"onDelete\"></lib-detail-header>\n\n @if(item.profile_url){\n <div class=\"image-holder\">\n <img alt=\"User Profile Image\" src=\"{{item.url}}{{item.profile_url}}\" style=\"height:120px;\">\n </div> \n }\n \n <div class=\"item-field\">\n <span><b>Email: </b></span>\n {{item.email}}\n </div>\n \n <div class=\"item-field\">\n <span><b>First Name: </b></span>\n {{item.first_name}}\n </div>\n \n <div class=\"item-field\">\n <span><b>Last Name: </b></span>\n {{item.last_name}}\n </div>\n \n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}\n"], dependencies: [{ kind: "component", type: BackButtonComponent, selector: "lib-back-button" }, { kind: "component", type: DetailHeaderComponent, selector: "lib-detail-header", inputs: ["id", "text", "route", "canEdit", "canDelete"], outputs: ["deleteClicked"] }] });
|
|
629
1166
|
}
|
|
630
1167
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserDetailComponent, decorators: [{
|
|
631
1168
|
type: Component,
|
|
632
1169
|
args: [{ selector: 'lib-user-detail', imports: [NgIf,
|
|
633
1170
|
BackButtonComponent,
|
|
634
|
-
DetailHeaderComponent], template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n @if(item(); as item){\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.username\"\n [id]=\"item.id\"\n [route]=\"typename\"></lib-detail-header>\n\n @if(item.profile_url){\n <div class=\"image-holder\">\n <img alt=\"User Profile Image\" src=\"{{item.url}}{{item.profile_url}}\" style=\"height:120px;\">\n </div> \n }\n \n <div class=\"item-field\">\n <span><b>Email: </b></span>\n {{item.email}}\n </div>\n \n <div class=\"item-field\">\n <span><b>First Name: </b></span>\n {{item.first_name}}\n </div>\n \n <div class=\"item-field\">\n <span><b>Last Name: </b></span>\n {{item.last_name}}\n </div>\n \n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}\n"] }]
|
|
1171
|
+
DetailHeaderComponent], template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n @if(item(); as item){\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.username\"\n [id]=\"item.id\"\n [route]=\"typename\"\n [canEdit]=\"canEdit()\"\n [canDelete]=\"canDelete()\"\n (onDelete)=\"onDelete\"></lib-detail-header>\n\n @if(item.profile_url){\n <div class=\"image-holder\">\n <img alt=\"User Profile Image\" src=\"{{item.url}}{{item.profile_url}}\" style=\"height:120px;\">\n </div> \n }\n \n <div class=\"item-field\">\n <span><b>Email: </b></span>\n {{item.email}}\n </div>\n \n <div class=\"item-field\">\n <span><b>First Name: </b></span>\n {{item.first_name}}\n </div>\n \n <div class=\"item-field\">\n <span><b>Last Name: </b></span>\n {{item.last_name}}\n </div>\n \n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}\n"] }]
|
|
635
1172
|
}], ctorParameters: () => [] });
|
|
636
1173
|
|
|
637
1174
|
class UserEditComponent extends EditView {
|
|
@@ -706,7 +1243,7 @@ class UserEditComponent extends EditView {
|
|
|
706
1243
|
} ; });
|
|
707
1244
|
}
|
|
708
1245
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserEditComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
709
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: UserEditComponent, isStandalone: true, selector: "lib-user-edit", usesInheritance: true, ngImport: i0, template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n @if(item(); as item){\n <div class=\"item-edit-container\">\n\n <h1 class=\"item-edit-header\">{{heading()}}</h1>\n\n <form class=\"form-card\" [formGroup]=\"form\" (ngSubmit)=\"submit()\">\n <mat-form-field class=\"form-field-wide\">\n <mat-label>Username</mat-label>\n <input matInput\n placeholder=\"Username\"\n type=\"text\"\n formControlName=\"username\"\n name=\"username\">\n </mat-form-field>\n \n <mat-form-field class=\"form-field-wide\">\n <mat-label>Email</mat-label>\n <input matInput\n placeholder=\"Email\"\n type=\"text\"\n formControlName=\"email\"\n name=\"email\">\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label>First Name</mat-label>\n <input matInput\n placeholder=\"First Name\"\n type=\"text\"\n formControlName=\"first_name\"\n name=\"first_name\">\n </mat-form-field>\n \n <mat-form-field class=\"form-field\">\n <mat-label>Last Name</mat-label>\n <input matInput\n placeholder=\"Last Name\"\n type=\"text\"\n formControlName=\"last_name\"\n name=\"last_name\">\n </mat-form-field>\n\n <lib-file-upload [files]=\"files()\"\n (previewLoaded)=\"onPreviewLoaded($event)\"\n (fileUploaded)=\"onFileUploaded($event)\"></lib-file-upload>\n \n <div class=\"button_group\">\n <button mat-fab\n class=\"form_action_button\"\n type=\"submit\"\n [disabled]=\"!form.valid\">\n <mat-icon>save</mat-icon></button>\n \n <button mat-fab\n class=\"form_action_button\"\n (click)=\"cancel()\">\n <mat-icon>cancel</mat-icon></button>\n </div>\n \n </form>\n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}.item_view{display:flex;justify-content:left;align-items:left;flex-direction:column}.checkbox_group{justify-content:left;display:flex;flex-direction:column}.button_group{margin:10px;display:flex;flex-direction:row;justify-content:center}.btn-block{padding:5px}.form_action_button{padding:5px;margin:5px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$
|
|
1246
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: UserEditComponent, isStandalone: true, selector: "lib-user-edit", usesInheritance: true, ngImport: i0, template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n @if(item(); as item){\n <div class=\"item-edit-container\">\n\n <h1 class=\"item-edit-header\">{{heading()}}</h1>\n\n <form class=\"form-card\" [formGroup]=\"form\" (ngSubmit)=\"submit()\">\n <mat-form-field class=\"form-field-wide\">\n <mat-label>Username</mat-label>\n <input matInput\n placeholder=\"Username\"\n type=\"text\"\n formControlName=\"username\"\n name=\"username\">\n </mat-form-field>\n \n <mat-form-field class=\"form-field-wide\">\n <mat-label>Email</mat-label>\n <input matInput\n placeholder=\"Email\"\n type=\"text\"\n formControlName=\"email\"\n name=\"email\">\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label>First Name</mat-label>\n <input matInput\n placeholder=\"First Name\"\n type=\"text\"\n formControlName=\"first_name\"\n name=\"first_name\">\n </mat-form-field>\n \n <mat-form-field class=\"form-field\">\n <mat-label>Last Name</mat-label>\n <input matInput\n placeholder=\"Last Name\"\n type=\"text\"\n formControlName=\"last_name\"\n name=\"last_name\">\n </mat-form-field>\n\n <lib-file-upload [files]=\"files()\"\n (previewLoaded)=\"onPreviewLoaded($event)\"\n (fileUploaded)=\"onFileUploaded($event)\"></lib-file-upload>\n \n <div class=\"button_group\">\n <button mat-fab\n class=\"form_action_button\"\n type=\"submit\"\n [disabled]=\"!form.valid\">\n <mat-icon>save</mat-icon></button>\n \n <button mat-fab\n class=\"form_action_button\"\n (click)=\"cancel()\">\n <mat-icon>cancel</mat-icon></button>\n </div>\n \n </form>\n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}.item_view{display:flex;justify-content:left;align-items:left;flex-direction:column}.checkbox_group{justify-content:left;display:flex;flex-direction:column}.button_group{margin:10px;display:flex;flex-direction:row;justify-content:center}.btn-block{padding:5px}.form_action_button{padding:5px;margin:5px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: BackButtonComponent, selector: "lib-back-button" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: FileUploadComponent, selector: "lib-file-upload", inputs: ["files"], outputs: ["previewLoaded", "fileUploaded"] }] });
|
|
710
1247
|
}
|
|
711
1248
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserEditComponent, decorators: [{
|
|
712
1249
|
type: Component,
|
|
@@ -721,51 +1258,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
721
1258
|
], template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n @if(item(); as item){\n <div class=\"item-edit-container\">\n\n <h1 class=\"item-edit-header\">{{heading()}}</h1>\n\n <form class=\"form-card\" [formGroup]=\"form\" (ngSubmit)=\"submit()\">\n <mat-form-field class=\"form-field-wide\">\n <mat-label>Username</mat-label>\n <input matInput\n placeholder=\"Username\"\n type=\"text\"\n formControlName=\"username\"\n name=\"username\">\n </mat-form-field>\n \n <mat-form-field class=\"form-field-wide\">\n <mat-label>Email</mat-label>\n <input matInput\n placeholder=\"Email\"\n type=\"text\"\n formControlName=\"email\"\n name=\"email\">\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label>First Name</mat-label>\n <input matInput\n placeholder=\"First Name\"\n type=\"text\"\n formControlName=\"first_name\"\n name=\"first_name\">\n </mat-form-field>\n \n <mat-form-field class=\"form-field\">\n <mat-label>Last Name</mat-label>\n <input matInput\n placeholder=\"Last Name\"\n type=\"text\"\n formControlName=\"last_name\"\n name=\"last_name\">\n </mat-form-field>\n\n <lib-file-upload [files]=\"files()\"\n (previewLoaded)=\"onPreviewLoaded($event)\"\n (fileUploaded)=\"onFileUploaded($event)\"></lib-file-upload>\n \n <div class=\"button_group\">\n <button mat-fab\n class=\"form_action_button\"\n type=\"submit\"\n [disabled]=\"!form.valid\">\n <mat-icon>save</mat-icon></button>\n \n <button mat-fab\n class=\"form_action_button\"\n (click)=\"cancel()\">\n <mat-icon>cancel</mat-icon></button>\n </div>\n \n </form>\n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}.item_view{display:flex;justify-content:left;align-items:left;flex-direction:column}.checkbox_group{justify-content:left;display:flex;flex-direction:column}.button_group{margin:10px;display:flex;flex-direction:row;justify-content:center}.btn-block{padding:5px}.form_action_button{padding:5px;margin:5px}\n"] }]
|
|
722
1259
|
}], ctorParameters: () => [] });
|
|
723
1260
|
|
|
724
|
-
class
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
}
|
|
728
|
-
ngOnInit() {
|
|
729
|
-
this.onInit();
|
|
730
|
-
}
|
|
731
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
732
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: UserComponent, isStandalone: true, selector: "lib-user", usesInheritance: true, ngImport: i0, template: "<div class=\"content-container\">\n <mat-nav-list>\n @for (item of items(); track item.id){\n <mat-card mat-list-item class=\"item-card\" [routerLink]=\"['/users/detail/', item.id]\" [routerLinkActive]=\"['is-active']\">\n <mat-card-header>\n <mat-card-title-group style=\"padding:5px\">\n <mat-card-title>{{item.first_name}} {{item.last_name}}</mat-card-title>\n <mat-card-subtitle>{{item.username}}</mat-card-subtitle> \n </mat-card-title-group>\n </mat-card-header>\n \n <mat-card-content>\n <p>Email: {{item.email}} </p>\n </mat-card-content>\n </mat-card>\n }\n </mat-nav-list>\n\n</div>\n", styles: [":host{flex-grow:1}.mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.is-active{font-weight:700}\n"], dependencies: [{ kind: "ngmodule", type: MatListModule }, { kind: "component", type: i2$2.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i2$3.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i2$3.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i2$3.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i2$3.MatCardSubtitle, selector: "mat-card-subtitle, [mat-card-subtitle], [matCardSubtitle]" }, { kind: "directive", type: i2$3.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "component", type: i2$3.MatCardTitleGroup, selector: "mat-card-title-group" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i3.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i3.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }] });
|
|
1261
|
+
class UserListDetailComponent {
|
|
1262
|
+
item = input(...(ngDevMode ? [undefined, { debugName: "item" }] : []));
|
|
1263
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserListDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1264
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: UserListDetailComponent, isStandalone: true, selector: "lib-user-list-detail", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mat-card mat-list-item class=\"item-card\">\n @if(item(); as item){\n <mat-card-header>\n <mat-card-title-group style=\"padding: 5px\">\n <mat-card-title\n >{{ item.first_name }} {{ item.last_name }}</mat-card-title\n >\n <mat-card-subtitle>{{ item.username }}</mat-card-subtitle>\n </mat-card-title-group>\n </mat-card-header>\n\n <mat-card-content>\n <p>Email: {{ item.email }}</p>\n </mat-card-content>\n }\n</mat-card>\n", styles: [":host{flex-grow:1}.mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.is-active{font-weight:700}\n"], dependencies: [{ kind: "ngmodule", type: MatListModule }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i1$3.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i1$3.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i1$3.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i1$3.MatCardSubtitle, selector: "mat-card-subtitle, [mat-card-subtitle], [matCardSubtitle]" }, { kind: "directive", type: i1$3.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "component", type: i1$3.MatCardTitleGroup, selector: "mat-card-title-group" }] });
|
|
733
1265
|
}
|
|
734
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type:
|
|
1266
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserListDetailComponent, decorators: [{
|
|
735
1267
|
type: Component,
|
|
736
|
-
args: [{ selector: 'lib-user', imports: [MatListModule,
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
RouterModule], template: "<div class=\"content-container\">\n <mat-nav-list>\n @for (item of items(); track item.id){\n <mat-card mat-list-item class=\"item-card\" [routerLink]=\"['/users/detail/', item.id]\" [routerLinkActive]=\"['is-active']\">\n <mat-card-header>\n <mat-card-title-group style=\"padding:5px\">\n <mat-card-title>{{item.first_name}} {{item.last_name}}</mat-card-title>\n <mat-card-subtitle>{{item.username}}</mat-card-subtitle> \n </mat-card-title-group>\n </mat-card-header>\n \n <mat-card-content>\n <p>Email: {{item.email}} </p>\n </mat-card-content>\n </mat-card>\n }\n </mat-nav-list>\n\n</div>\n", styles: [":host{flex-grow:1}.mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.is-active{font-weight:700}\n"] }]
|
|
740
|
-
}], ctorParameters: () => [] });
|
|
1268
|
+
args: [{ selector: 'lib-user-list-detail', imports: [MatListModule,
|
|
1269
|
+
MatCardModule], template: "<mat-card mat-list-item class=\"item-card\">\n @if(item(); as item){\n <mat-card-header>\n <mat-card-title-group style=\"padding: 5px\">\n <mat-card-title\n >{{ item.first_name }} {{ item.last_name }}</mat-card-title\n >\n <mat-card-subtitle>{{ item.username }}</mat-card-subtitle>\n </mat-card-title-group>\n </mat-card-header>\n\n <mat-card-content>\n <p>Email: {{ item.email }}</p>\n </mat-card-content>\n }\n</mat-card>\n", styles: [":host{flex-grow:1}.mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.is-active{font-weight:700}\n"] }]
|
|
1270
|
+
}] });
|
|
741
1271
|
|
|
742
|
-
class
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
table = viewChild(MatTable, ...(ngDevMode ? [{ debugName: "table" }] : []));
|
|
749
|
-
tableColumns = ["first_name", "last_name", "email", "remove"];
|
|
750
|
-
remove(id) {
|
|
751
|
-
this.itemRemoved.emit(id);
|
|
752
|
-
this.table()?.renderRows();
|
|
753
|
-
}
|
|
754
|
-
add() {
|
|
755
|
-
this.itemAdded.emit(this.toAdd());
|
|
756
|
-
this.table()?.renderRows();
|
|
757
|
-
}
|
|
758
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
759
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: UserSelectComponent, isStandalone: true, selector: "lib-user-select", inputs: { selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemAdded: "itemAdded", itemRemoved: "itemRemoved" }, viewQueries: [{ propertyName: "table", first: true, predicate: MatTable, descendants: true, isSignal: true }], ngImport: i0, template: "<div class='select-container'>\n <p style=\"padding:5px\">\n <b>Members</b>\n </p>\n \n <div>\n <mat-form-field>\n <mat-label>Add Member</mat-label>\n <mat-select [(ngModel)]=\"toAdd\" name=\"to_add\">\n @for(item of options(); track item.id){\n <mat-option [value]=\"item.id\">{{item.username}}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n \n <button mat-mini-fab\n type=\"button\"\n class=\"form_action_button\"\n (click)=\"add()\">\n <mat-icon>add\n </mat-icon>\n </button>\n </div>\n\n @if(selected().length > 0){\n <table mat-table [dataSource]=\"selected()\" class=\"mat-elevation-z8\">\n\n <ng-container matColumnDef=\"first_name\">\n <th mat-header-cell *matHeaderCellDef>First Name\n </th>\n <td mat-cell *matCellDef=\"let element\">\n {{element.first_name}}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"last_name\">\n <th mat-header-cell *matHeaderCellDef>\n Last Name\n </th>\n <td mat-cell *matCellDef=\"let element\">\n {{element.last_name}}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"email\">\n <th mat-header-cell *matHeaderCellDef>\n Email\n </th>\n <td mat-cell *matCellDef=\"let element\">\n {{element.email}}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"remove\">\n <th mat-header-cell *matHeaderCellDef>Remove\n </th>\n <td mat-cell *matCellDef=\"let element\">\n <button mat-icon-button\n color=\"primary\"\n aria-label=\"Remove an item\"\n (click)=\"remove(element.id)\">\n <mat-icon>remove\n </mat-icon>\n </button>\n </td>\n </ng-container>\n\n <tr mat-header-row\n *matHeaderRowDef=\"tableColumns\">\n </tr>\n <tr mat-row\n *matRowDef=\"let row; columns: tableColumns;\">\n </tr>\n </table>\n }\n</div>\n", styles: [".select-container,.table_container{display:flex;text-align:center;justify-content:center;flex-direction:column}.form_action_button{padding:5px;margin:5px}\n"], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$2.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$2.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$2.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$2.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$2.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$2.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$2.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$2.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$2.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$2.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
1272
|
+
class UserComponent {
|
|
1273
|
+
viewType = signal("list", ...(ngDevMode ? [{ debugName: "viewType" }] : []));
|
|
1274
|
+
itemService = inject(UserService);
|
|
1275
|
+
columns = [{ name: 'username', title: 'Name', element_type: 'string' }];
|
|
1276
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1277
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.1", type: UserComponent, isStandalone: true, selector: "lib-user", ngImport: i0, template: "<lib-list-view\n [itemService]=\"itemService\"\n [itemDetailTemplate]=\"listItemTemplate\"\n [columns]=\"columns\"\n [viewType]=\"viewType()\"\n >\n <ng-template #listItemTemplate let-item=\"item\">\n <lib-user-list-detail [item]=\"item\"\n [routerLink]=\"['/' + itemService.itemType + '/detail/', item.id]\"\n [routerLinkActive]=\"['is-active']\">\n </lib-user-list-detail>\n </ng-template>\n</lib-list-view>\n", styles: [":host{flex-grow:1}\n"], dependencies: [{ kind: "component", type: ListViewComponent, selector: "lib-list-view", inputs: ["viewType", "itemService", "itemDetailTemplate", "columns", "sortFields", "noSelfItemsMessage", "noItemsCanCreateMessage", "noItemsMessage"] }, { kind: "component", type: UserListDetailComponent, selector: "lib-user-list-detail", inputs: ["item"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i1.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }] });
|
|
760
1278
|
}
|
|
761
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type:
|
|
1279
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: UserComponent, decorators: [{
|
|
762
1280
|
type: Component,
|
|
763
|
-
args: [{ selector: 'lib-user
|
|
764
|
-
MatFormFieldModule,
|
|
765
|
-
MatButtonModule,
|
|
766
|
-
MatSelectModule,
|
|
767
|
-
MatIconModule,
|
|
768
|
-
FormsModule], template: "<div class='select-container'>\n <p style=\"padding:5px\">\n <b>Members</b>\n </p>\n \n <div>\n <mat-form-field>\n <mat-label>Add Member</mat-label>\n <mat-select [(ngModel)]=\"toAdd\" name=\"to_add\">\n @for(item of options(); track item.id){\n <mat-option [value]=\"item.id\">{{item.username}}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n \n <button mat-mini-fab\n type=\"button\"\n class=\"form_action_button\"\n (click)=\"add()\">\n <mat-icon>add\n </mat-icon>\n </button>\n </div>\n\n @if(selected().length > 0){\n <table mat-table [dataSource]=\"selected()\" class=\"mat-elevation-z8\">\n\n <ng-container matColumnDef=\"first_name\">\n <th mat-header-cell *matHeaderCellDef>First Name\n </th>\n <td mat-cell *matCellDef=\"let element\">\n {{element.first_name}}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"last_name\">\n <th mat-header-cell *matHeaderCellDef>\n Last Name\n </th>\n <td mat-cell *matCellDef=\"let element\">\n {{element.last_name}}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"email\">\n <th mat-header-cell *matHeaderCellDef>\n Email\n </th>\n <td mat-cell *matCellDef=\"let element\">\n {{element.email}}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"remove\">\n <th mat-header-cell *matHeaderCellDef>Remove\n </th>\n <td mat-cell *matCellDef=\"let element\">\n <button mat-icon-button\n color=\"primary\"\n aria-label=\"Remove an item\"\n (click)=\"remove(element.id)\">\n <mat-icon>remove\n </mat-icon>\n </button>\n </td>\n </ng-container>\n\n <tr mat-header-row\n *matHeaderRowDef=\"tableColumns\">\n </tr>\n <tr mat-row\n *matRowDef=\"let row; columns: tableColumns;\">\n </tr>\n </table>\n }\n</div>\n", styles: [".select-container,.table_container{display:flex;text-align:center;justify-content:center;flex-direction:column}.form_action_button{padding:5px;margin:5px}\n"] }]
|
|
1281
|
+
args: [{ selector: 'lib-user', imports: [ListViewComponent, UserListDetailComponent, RouterModule], template: "<lib-list-view\n [itemService]=\"itemService\"\n [itemDetailTemplate]=\"listItemTemplate\"\n [columns]=\"columns\"\n [viewType]=\"viewType()\"\n >\n <ng-template #listItemTemplate let-item=\"item\">\n <lib-user-list-detail [item]=\"item\"\n [routerLink]=\"['/' + itemService.itemType + '/detail/', item.id]\"\n [routerLinkActive]=\"['is-active']\">\n </lib-user-list-detail>\n </ng-template>\n</lib-list-view>\n", styles: [":host{flex-grow:1}\n"] }]
|
|
769
1282
|
}] });
|
|
770
1283
|
|
|
771
1284
|
class GroupDetailComponent extends DetailView {
|
|
@@ -777,7 +1290,7 @@ class GroupDetailComponent extends DetailView {
|
|
|
777
1290
|
this.onInit();
|
|
778
1291
|
}
|
|
779
1292
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: GroupDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
780
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: GroupDetailComponent, isStandalone: true, selector: "lib-group-detail", usesInheritance: true, ngImport: i0, template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n @if(item(); as item) {\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.name\"\n [id]=\"item.id\"\n [route]=\"typename\"></lib-detail-header>\n \n <div class=\"item-field\">{{item.name}}</div>\n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}\n"], dependencies: [{ kind: "component", type: BackButtonComponent, selector: "lib-back-button" }, { kind: "component", type: DetailHeaderComponent, selector: "lib-detail-header", inputs: ["id", "text", "route"] }] });
|
|
1293
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: GroupDetailComponent, isStandalone: true, selector: "lib-group-detail", usesInheritance: true, ngImport: i0, template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n @if(item(); as item) {\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.name\"\n [id]=\"item.id\"\n [route]=\"typename\"></lib-detail-header>\n \n <div class=\"item-field\">{{item.name}}</div>\n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}\n"], dependencies: [{ kind: "component", type: BackButtonComponent, selector: "lib-back-button" }, { kind: "component", type: DetailHeaderComponent, selector: "lib-detail-header", inputs: ["id", "text", "route", "canEdit", "canDelete"], outputs: ["deleteClicked"] }] });
|
|
781
1294
|
}
|
|
782
1295
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: GroupDetailComponent, decorators: [{
|
|
783
1296
|
type: Component,
|
|
@@ -786,113 +1299,214 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
786
1299
|
DetailHeaderComponent], template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n @if(item(); as item) {\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.name\"\n [id]=\"item.id\"\n [route]=\"typename\"></lib-detail-header>\n \n <div class=\"item-field\">{{item.name}}</div>\n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}\n"] }]
|
|
787
1300
|
}], ctorParameters: () => [] });
|
|
788
1301
|
|
|
789
|
-
class GroupComponent
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
super(inject(GroupService));
|
|
793
|
-
}
|
|
794
|
-
ngOnInit() {
|
|
795
|
-
this.onInit();
|
|
796
|
-
}
|
|
1302
|
+
class GroupComponent {
|
|
1303
|
+
itemService = inject(GroupService);
|
|
1304
|
+
columns = [{ name: 'name', title: 'Name', element_type: 'string' }];
|
|
797
1305
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: GroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
798
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.1", type: GroupComponent, isStandalone: true, selector: "lib-group",
|
|
1306
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.1", type: GroupComponent, isStandalone: true, selector: "lib-group", ngImport: i0, template: "<lib-list-view\n [itemService]=\"itemService\"\n [columns]=\"columns\"\n >\n</lib-list-view>\n\n", styles: [":host{flex-grow:1}\n"], dependencies: [{ kind: "component", type: ListViewComponent, selector: "lib-list-view", inputs: ["viewType", "itemService", "itemDetailTemplate", "columns", "sortFields", "noSelfItemsMessage", "noItemsCanCreateMessage", "noItemsMessage"] }] });
|
|
799
1307
|
}
|
|
800
1308
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: GroupComponent, decorators: [{
|
|
801
1309
|
type: Component,
|
|
802
|
-
args: [{ selector: 'lib-group', imports: [
|
|
803
|
-
|
|
804
|
-
MatButtonModule,
|
|
805
|
-
MatIconModule,
|
|
806
|
-
RouterModule
|
|
807
|
-
], template: "<div class=\"tabular-list-container\">\n <div>\n <table mat-table [dataSource]=\"items()\" class=\"mat-elevation-z8\">\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef>Name</th>\n <td mat-cell *matCellDef=\"let element\"> {{element.name}} </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"\n [routerLink]=\"['/groups/detail/', row.id]\"\n [routerLinkActive]=\"['is-active']\"\n ></tr>\n </table>\n </div>\n</div>\n", styles: [".mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.is-active{font-weight:700}\n"] }]
|
|
808
|
-
}], ctorParameters: () => [] });
|
|
1310
|
+
args: [{ selector: 'lib-group', imports: [ListViewComponent], template: "<lib-list-view\n [itemService]=\"itemService\"\n [columns]=\"columns\"\n >\n</lib-list-view>\n\n", styles: [":host{flex-grow:1}\n"] }]
|
|
1311
|
+
}] });
|
|
809
1312
|
|
|
810
|
-
class
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
1313
|
+
class AddressEditComponent {
|
|
1314
|
+
countryOptions = input([], ...(ngDevMode ? [{ debugName: "countryOptions" }] : []));
|
|
1315
|
+
form = input(...(ngDevMode ? [undefined, { debugName: "form" }] : []));
|
|
1316
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressEditComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1317
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: AddressEditComponent, isStandalone: true, selector: "lib-address-edit", inputs: { countryOptions: { classPropertyName: "countryOptions", publicName: "countryOptions", isSignal: true, isRequired: false, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if(form(); as form){\n<div [formGroup]=\"form\" style=\"display: flex; flex-direction: column; width:100%\">\n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"line1\">Line 1</mat-label>\n <input matInput placeholder=\"Address Line 1\" type=\"text\" id=\"line1\" formControlName=\"line1\" name=\"line1\"\n required>\n </mat-form-field>\n\n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"line2\">Line 2</mat-label>\n <input matInput placeholder=\"Address Line 2\" type=\"text\" id=\"line2\" formControlName=\"line2\" name=\"line1\" required>\n </mat-form-field>\n\n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"line3\">Line 3</mat-label>\n <input matInput placeholder=\"Address Line 3\" type=\"text\" id=\"line3\" formControlName=\"line3\" name=\"line3\" required>\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label for=\"city\">City</mat-label>\n <input matInput placeholder=\"City\" type=\"text\" id=\"city\" formControlName=\"city\" name=\"city\" required>\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label for=\"region\">Region</mat-label>\n <input matInput placeholder=\"Region\" type=\"text\" id=\"region\" formControlName=\"region\" name=\"region\" required>\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label for=\"line1\">Post Code</mat-label>\n <input matInput placeholder=\"Post Code\" type=\"text\" id=\"postcode\" formControlName=\"postcode\" name=\"postcode\" required>\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label for=\"country\">Country</mat-label>\n <mat-select formControlName=\"country\" name=\"country\" id=\"country\" required>\n @for(country of countryOptions(); track $index){\n <mat-option [value]=\"country.code\">{{country.name}}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n</div>\n}", styles: [""], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
|
|
1318
|
+
}
|
|
1319
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressEditComponent, decorators: [{
|
|
1320
|
+
type: Component,
|
|
1321
|
+
args: [{ selector: 'lib-address-edit', imports: [MatFormFieldModule,
|
|
1322
|
+
MatSelectModule,
|
|
1323
|
+
MatInputModule,
|
|
1324
|
+
ReactiveFormsModule
|
|
1325
|
+
], template: "@if(form(); as form){\n<div [formGroup]=\"form\" style=\"display: flex; flex-direction: column; width:100%\">\n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"line1\">Line 1</mat-label>\n <input matInput placeholder=\"Address Line 1\" type=\"text\" id=\"line1\" formControlName=\"line1\" name=\"line1\"\n required>\n </mat-form-field>\n\n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"line2\">Line 2</mat-label>\n <input matInput placeholder=\"Address Line 2\" type=\"text\" id=\"line2\" formControlName=\"line2\" name=\"line1\" required>\n </mat-form-field>\n\n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"line3\">Line 3</mat-label>\n <input matInput placeholder=\"Address Line 3\" type=\"text\" id=\"line3\" formControlName=\"line3\" name=\"line3\" required>\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label for=\"city\">City</mat-label>\n <input matInput placeholder=\"City\" type=\"text\" id=\"city\" formControlName=\"city\" name=\"city\" required>\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label for=\"region\">Region</mat-label>\n <input matInput placeholder=\"Region\" type=\"text\" id=\"region\" formControlName=\"region\" name=\"region\" required>\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label for=\"line1\">Post Code</mat-label>\n <input matInput placeholder=\"Post Code\" type=\"text\" id=\"postcode\" formControlName=\"postcode\" name=\"postcode\" required>\n </mat-form-field>\n\n <mat-form-field class=\"form-field\">\n <mat-label for=\"country\">Country</mat-label>\n <mat-select formControlName=\"country\" name=\"country\" id=\"country\" required>\n @for(country of countryOptions(); track $index){\n <mat-option [value]=\"country.code\">{{country.name}}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n</div>\n}" }]
|
|
1326
|
+
}] });
|
|
1327
|
+
|
|
1328
|
+
class AddressDetailComponent {
|
|
1329
|
+
address = input(...(ngDevMode ? [undefined, { debugName: "address" }] : []));
|
|
1330
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1331
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: AddressDetailComponent, isStandalone: true, selector: "lib-address-detail", inputs: { address: { classPropertyName: "address", publicName: "address", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if(address(); as address){\n<div class=\"item-field\" style=\"display:flex;flex-wrap: wrap;justify-content: center;align-content: center;\">\n <span style=\"margin-left: 3px;\">{{address.line1}}, </span>\n <span style=\"margin-left: 3px;\">{{address.line2}},</span>\n @if(address.line3){\n <span style=\"margin-left: 3px;\">{{address.line3}},</span>\n }\n @if(address.city){\n <span style=\"margin-left: 3px;\">{{address.city}},</span>\n }\n <span style=\"margin-left: 3px;\">{{address.region}},</span>\n @if(address.postcode){ \n <span style=\"margin-left: 3px;\">{{address.postcode}},</span>\n }\n <span style=\"margin-left: 3px;\">{{address.country_name}}</span>\n</div>\n}", styles: [""] });
|
|
1332
|
+
}
|
|
1333
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: AddressDetailComponent, decorators: [{
|
|
1334
|
+
type: Component,
|
|
1335
|
+
args: [{ selector: 'lib-address-detail', imports: [], template: "@if(address(); as address){\n<div class=\"item-field\" style=\"display:flex;flex-wrap: wrap;justify-content: center;align-content: center;\">\n <span style=\"margin-left: 3px;\">{{address.line1}}, </span>\n <span style=\"margin-left: 3px;\">{{address.line2}},</span>\n @if(address.line3){\n <span style=\"margin-left: 3px;\">{{address.line3}},</span>\n }\n @if(address.city){\n <span style=\"margin-left: 3px;\">{{address.city}},</span>\n }\n <span style=\"margin-left: 3px;\">{{address.region}},</span>\n @if(address.postcode){ \n <span style=\"margin-left: 3px;\">{{address.postcode}},</span>\n }\n <span style=\"margin-left: 3px;\">{{address.country_name}}</span>\n</div>\n}" }]
|
|
1336
|
+
}] });
|
|
1337
|
+
|
|
1338
|
+
class AddressForm {
|
|
1339
|
+
formBuilder = inject(FormBuilder);
|
|
1340
|
+
form = this.formBuilder.group({
|
|
1341
|
+
line1: [''],
|
|
1342
|
+
line2: [''],
|
|
1343
|
+
line3: [''],
|
|
1344
|
+
city: [''],
|
|
1345
|
+
region: [''],
|
|
1346
|
+
postcode: [''],
|
|
1347
|
+
country: ['']
|
|
1348
|
+
});
|
|
1349
|
+
setValue(item) {
|
|
1350
|
+
this.form.setValue({
|
|
1351
|
+
line1: item.line1,
|
|
1352
|
+
line2: item.line2,
|
|
1353
|
+
line3: item.line3,
|
|
1354
|
+
city: item.city,
|
|
1355
|
+
region: item.region,
|
|
1356
|
+
postcode: item.postcode,
|
|
1357
|
+
country: item.country
|
|
1358
|
+
});
|
|
814
1359
|
}
|
|
815
|
-
|
|
816
|
-
this.
|
|
1360
|
+
updateItem(item) {
|
|
1361
|
+
const value = this.form.value;
|
|
1362
|
+
item.line1 = value.line1 || "";
|
|
1363
|
+
item.line2 = value.line2 || "";
|
|
1364
|
+
item.line3 = value.line3 || "";
|
|
1365
|
+
item.city = value.city || "";
|
|
1366
|
+
item.region = value.region || "";
|
|
1367
|
+
item.postcode = value.postcode || "";
|
|
1368
|
+
item.country = value.country || "";
|
|
1369
|
+
return item;
|
|
817
1370
|
}
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
class OrganizationComponent {
|
|
1374
|
+
itemService = inject(OrganizationService);
|
|
1375
|
+
columns = [{ name: 'name', title: 'Name', element_type: 'string' },
|
|
1376
|
+
{ name: 'website', title: 'Website', element_type: 'url' },
|
|
1377
|
+
{ name: 'is_partner', title: 'Is Partner', element_type: 'boolean' }];
|
|
818
1378
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
819
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.1", type: OrganizationComponent, isStandalone: true, selector: "lib-organization",
|
|
1379
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.1", type: OrganizationComponent, isStandalone: true, selector: "lib-organization", ngImport: i0, template: "<lib-list-view\n [itemService]=\"itemService\"\n [columns]=\"columns\"\n >\n</lib-list-view>\n\n\n\n", styles: [":host{flex-grow:1}\n"], dependencies: [{ kind: "component", type: ListViewComponent, selector: "lib-list-view", inputs: ["viewType", "itemService", "itemDetailTemplate", "columns", "sortFields", "noSelfItemsMessage", "noItemsCanCreateMessage", "noItemsMessage"] }] });
|
|
820
1380
|
}
|
|
821
1381
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationComponent, decorators: [{
|
|
822
1382
|
type: Component,
|
|
823
1383
|
args: [{ selector: 'lib-organization', imports: [
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
RouterModule
|
|
828
|
-
], template: "<div class=\"tabular-list-container\">\n <div>\n <table mat-table [dataSource]=\"items()\" class=\"mat-elevation-z8\">\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef>Name</th>\n <td mat-cell *matCellDef=\"let element\"> {{element.name}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"website\">\n <th mat-header-cell *matHeaderCellDef> Website </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.website}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"is_partner\">\n <th mat-header-cell *matHeaderCellDef> Is Partner </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.is_partner}} </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"\n [routerLink]=\"['/organizations/detail/', row.id]\"\n [routerLinkActive]=\"['is-active']\"\n ></tr>\n\n </table>\n </div>\n \n <div class=\"button-container\">\n <a mat-fab class=\"padded-button\" [routerLink]=\"['create']\">\n <mat-icon>add</mat-icon></a>\n </div>\n</div>\n", styles: [".mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.is-active{font-weight:700}\n"] }]
|
|
829
|
-
}], ctorParameters: () => [] });
|
|
1384
|
+
ListViewComponent
|
|
1385
|
+
], template: "<lib-list-view\n [itemService]=\"itemService\"\n [columns]=\"columns\"\n >\n</lib-list-view>\n\n\n\n", styles: [":host{flex-grow:1}\n"] }]
|
|
1386
|
+
}] });
|
|
830
1387
|
|
|
831
1388
|
class OrganizationDetailComponent extends DetailView {
|
|
832
1389
|
typename = "organization";
|
|
1390
|
+
address = signal(null, ...(ngDevMode ? [{ debugName: "address" }] : []));
|
|
1391
|
+
addressService = inject(AddressService);
|
|
833
1392
|
constructor() {
|
|
834
1393
|
super(inject(OrganizationService));
|
|
835
1394
|
}
|
|
836
1395
|
ngOnInit() {
|
|
837
1396
|
this.onInit();
|
|
838
1397
|
}
|
|
1398
|
+
onItemAndUserAvailable(item, _user) {
|
|
1399
|
+
this.addressService.getUrl(item.address).subscribe(address => this.address.set(address));
|
|
1400
|
+
}
|
|
839
1401
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
840
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: OrganizationDetailComponent, isStandalone: true, selector: "lib-organization-detail", usesInheritance: true, ngImport: i0, template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n @if(item(); as item){\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.name\"\n [id]=\"item.id\"\n [route]=\"typename\"></lib-detail-header>\n\n
|
|
1402
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: OrganizationDetailComponent, isStandalone: true, selector: "lib-organization-detail", usesInheritance: true, ngImport: i0, template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n @if(item(); as item){\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.name\"\n [id]=\"item.id\"\n [canEdit]=\"itemService.canEdit()\"\n [canDelete]=\"itemService.canDelete()\"\n [route]=\"typename\"></lib-detail-header>\n\n <div class=\"item-field\">\n {{item.description}}\n </div>\n \n @if(address(); as address)\n {\n <h3>Address</h3>\n <lib-address-detail [address]=\"address\"></lib-address-detail>\n }\n <div class=\"item-field\">\n <h3>Website</h3>{{item.website}}\n </div>\n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}.padded_button{padding:5px}\n"], dependencies: [{ kind: "component", type: BackButtonComponent, selector: "lib-back-button" }, { kind: "component", type: DetailHeaderComponent, selector: "lib-detail-header", inputs: ["id", "text", "route", "canEdit", "canDelete"], outputs: ["deleteClicked"] }, { kind: "component", type: AddressDetailComponent, selector: "lib-address-detail", inputs: ["address"] }] });
|
|
841
1403
|
}
|
|
842
1404
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationDetailComponent, decorators: [{
|
|
843
1405
|
type: Component,
|
|
844
|
-
args: [{ selector: 'lib-organization-detail', imports: [
|
|
845
|
-
|
|
846
|
-
DetailHeaderComponent], template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n @if(item(); as item){\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.name\"\n [id]=\"item.id\"\n [route]=\"typename\"></lib-detail-header>\n\n\n <div class=\"item-field\">\n {{item.description}}\n </div>\n \n <div class=\"item-field\">\n <h3>Address</h3>{{item.address}}\n </div>\n \n <div class=\"item-field\">\n <h3>Website</h3>{{item.website}}\n </div>\n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}.padded_button{padding:5px}\n"] }]
|
|
1406
|
+
args: [{ selector: 'lib-organization-detail', imports: [BackButtonComponent,
|
|
1407
|
+
DetailHeaderComponent, AddressDetailComponent], template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n @if(item(); as item){\n <div class=\"item-detail-container\">\n\n <lib-detail-header\n [text]=\"item.name\"\n [id]=\"item.id\"\n [canEdit]=\"itemService.canEdit()\"\n [canDelete]=\"itemService.canDelete()\"\n [route]=\"typename\"></lib-detail-header>\n\n <div class=\"item-field\">\n {{item.description}}\n </div>\n \n @if(address(); as address)\n {\n <h3>Address</h3>\n <lib-address-detail [address]=\"address\"></lib-address-detail>\n }\n <div class=\"item-field\">\n <h3>Website</h3>{{item.website}}\n </div>\n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}.padded_button{padding:5px}\n"] }]
|
|
847
1408
|
}], ctorParameters: () => [] });
|
|
848
1409
|
|
|
1410
|
+
class OrganizationForm {
|
|
1411
|
+
formBuilder = inject(FormBuilder);
|
|
1412
|
+
form;
|
|
1413
|
+
address = new AddressForm();
|
|
1414
|
+
constructor() {
|
|
1415
|
+
this.form = this.formBuilder.group({
|
|
1416
|
+
name: [''],
|
|
1417
|
+
acronym: [''],
|
|
1418
|
+
description: [''],
|
|
1419
|
+
website: [''],
|
|
1420
|
+
address: [this.address.form]
|
|
1421
|
+
});
|
|
1422
|
+
}
|
|
1423
|
+
updateFromItem(item) {
|
|
1424
|
+
this.form.setValue({
|
|
1425
|
+
name: item.name,
|
|
1426
|
+
acronym: item.acronym,
|
|
1427
|
+
description: item.description,
|
|
1428
|
+
website: item.website,
|
|
1429
|
+
address: this.address.form
|
|
1430
|
+
});
|
|
1431
|
+
}
|
|
1432
|
+
updateItem(item) {
|
|
1433
|
+
item.name = this.form.value.name || "";
|
|
1434
|
+
item.acronym = this.form.value.acronym || "";
|
|
1435
|
+
item.description = this.form.value.description || "";
|
|
1436
|
+
item.website = this.form.value.website || "";
|
|
1437
|
+
return item;
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
|
|
849
1441
|
class OrganizationEditComponent extends EditView {
|
|
1442
|
+
typename = "Organization";
|
|
850
1443
|
countryOptions = signal([], ...(ngDevMode ? [{ debugName: "countryOptions" }] : []));
|
|
851
1444
|
candidateMembers = signal([], ...(ngDevMode ? [{ debugName: "candidateMembers" }] : []));
|
|
852
1445
|
selectedMembers = signal([], ...(ngDevMode ? [{ debugName: "selectedMembers" }] : []));
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
country: [''] });
|
|
1446
|
+
columns = [{ name: 'first_name', title: 'First Name', element_type: 'string' },
|
|
1447
|
+
{ name: 'last_name', title: 'Surname', element_type: 'string' },
|
|
1448
|
+
{ name: 'username', title: 'Username', element_type: 'string' },
|
|
1449
|
+
{ name: 'email', title: 'Email', element_type: 'string' }];
|
|
1450
|
+
form = new OrganizationForm();
|
|
1451
|
+
address = new Address();
|
|
1452
|
+
addressService = inject(AddressService);
|
|
861
1453
|
constructor() {
|
|
862
1454
|
super(inject(OrganizationService));
|
|
863
1455
|
}
|
|
864
1456
|
ngOnInit() {
|
|
865
1457
|
this.onInit();
|
|
866
|
-
this.
|
|
1458
|
+
this.addressService.getOptions().subscribe(options => this.onOptions(options));
|
|
867
1459
|
}
|
|
868
1460
|
onItemAndUserAvailable(_) {
|
|
869
1461
|
const item = this.item();
|
|
870
1462
|
if (item) {
|
|
871
|
-
this.
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
});
|
|
878
|
-
this._userService.get("?organization=" + item.id).subscribe(users => this.selectedMembers.set(users));
|
|
879
|
-
this._userService.get().subscribe(users => this.candidateMembers.set(users));
|
|
1463
|
+
this.fetchAddress(item.address);
|
|
1464
|
+
this.form.updateFromItem(item);
|
|
1465
|
+
const queries = new Map([["organization", item.id.toString()]]);
|
|
1466
|
+
const query = new ItemQuery({ queries: queries });
|
|
1467
|
+
this._userService.get(query).subscribe(users => this.selectedMembers.set(users.results));
|
|
1468
|
+
this._userService.get().subscribe(users => this.updateCandidates(users));
|
|
880
1469
|
}
|
|
881
1470
|
}
|
|
1471
|
+
updateCandidates(users) {
|
|
1472
|
+
this.candidateMembers.set(users.results.map(user => { return { title: user.username, item: user }; }));
|
|
1473
|
+
}
|
|
882
1474
|
submit() {
|
|
883
|
-
this.
|
|
884
|
-
|
|
1475
|
+
this.syncFromForm();
|
|
1476
|
+
if (this.createMode()) {
|
|
1477
|
+
this.createAddress().subscribe(_ => super.submit());
|
|
1478
|
+
}
|
|
1479
|
+
else {
|
|
1480
|
+
this.updateAddress();
|
|
1481
|
+
super.submit();
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
fetchAddress(url) {
|
|
1485
|
+
if (url) {
|
|
1486
|
+
this.addressService.getUrl(url).subscribe(address => this.onAddressUpdated(address));
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
updateAddress() {
|
|
1490
|
+
this.addressService.putItem(this.address).subscribe(address => this.onAddressUpdated(address));
|
|
1491
|
+
}
|
|
1492
|
+
createAddress() {
|
|
1493
|
+
return this.addressService.postItem(this.address).pipe(tap(address => { this.onAddressCreated(address); }));
|
|
1494
|
+
}
|
|
1495
|
+
onAddressUpdated(address) {
|
|
1496
|
+
this.address = address;
|
|
1497
|
+
this.form.address.setValue(this.address);
|
|
1498
|
+
}
|
|
1499
|
+
onAddressCreated(address) {
|
|
1500
|
+
this.onAddressUpdated(address);
|
|
1501
|
+
this.item.update(item => { if (item) {
|
|
1502
|
+
item.address = address.url;
|
|
885
1503
|
} return item; });
|
|
886
|
-
super.submit();
|
|
887
1504
|
}
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
item.
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
item.website = this.form.value.website || "";
|
|
894
|
-
item.country = this.form.value.country || "";
|
|
895
|
-
return item;
|
|
1505
|
+
syncFromForm() {
|
|
1506
|
+
this.address = this.form.address.updateItem(this.address);
|
|
1507
|
+
this.item.update((item) => { if (item) {
|
|
1508
|
+
item = this.form.updateItem(item);
|
|
1509
|
+
} return item; });
|
|
896
1510
|
}
|
|
897
1511
|
getTemplateItem() {
|
|
898
1512
|
return new Organization();
|
|
@@ -903,7 +1517,7 @@ class OrganizationEditComponent extends EditView {
|
|
|
903
1517
|
}
|
|
904
1518
|
}
|
|
905
1519
|
onCountryChoices(choices) {
|
|
906
|
-
this.countryOptions.update(() => choices.map(c => c.display_name));
|
|
1520
|
+
this.countryOptions.update(() => choices.map(c => { return { name: c.display_name, code: c.value, flag: "" }; }));
|
|
907
1521
|
}
|
|
908
1522
|
onMemberRemoved(id) {
|
|
909
1523
|
const url = this.selectedMembers().find(m => m.id == id).url;
|
|
@@ -912,24 +1526,32 @@ class OrganizationEditComponent extends EditView {
|
|
|
912
1526
|
item.members.filter(m => m != url);
|
|
913
1527
|
} return item; });
|
|
914
1528
|
}
|
|
915
|
-
onMemberAdded(
|
|
916
|
-
const selected = this.candidateMembers().find(m => m.
|
|
1529
|
+
onMemberAdded(title) {
|
|
1530
|
+
const selected = this.candidateMembers().find(m => m.title == title);
|
|
917
1531
|
if (selected) {
|
|
918
|
-
this.selectedMembers.update(members => { members.push(selected); return members; });
|
|
1532
|
+
this.selectedMembers.update(members => { members.push(selected.item); return members; });
|
|
919
1533
|
}
|
|
920
|
-
this.candidateMembers.update(members => members.filter(m => m.
|
|
921
|
-
const url = this.selectedMembers().find(m => m.
|
|
1534
|
+
this.candidateMembers.update(members => members.filter(m => m.title != title));
|
|
1535
|
+
const url = this.selectedMembers().find(m => m.username == title).url;
|
|
922
1536
|
this.item.update(item => { if (item) {
|
|
923
1537
|
item.members.push(url);
|
|
924
1538
|
} return item; });
|
|
925
1539
|
}
|
|
1540
|
+
onSearchChanged(searchTerm) {
|
|
1541
|
+
console.log("Batch requested");
|
|
1542
|
+
if (searchTerm) {
|
|
1543
|
+
this._userService.get(new ItemQuery({ filter: searchTerm })).subscribe(users => this.updateCandidates(users));
|
|
1544
|
+
}
|
|
1545
|
+
else {
|
|
1546
|
+
this._userService.get().subscribe(users => this.updateCandidates(users));
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
926
1549
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationEditComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
927
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: OrganizationEditComponent, isStandalone: true, selector: "lib-organization-edit", usesInheritance: true, ngImport: i0, template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n @if(item(); as item){\n <div class=\"item-edit-container\">\n \n <h1 class=\"item-edit-header\">{{heading()}}</h1>\n\n <form class=\"form-card\" [formGroup]=\"form\" (ngSubmit)=\"submit()\">\n\n <mat-form-field class=\"form-field-wide\">\n <mat-label
|
|
1550
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.1", type: OrganizationEditComponent, isStandalone: true, selector: "lib-organization-edit", usesInheritance: true, ngImport: i0, template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n @if(item(); as item){\n <div class=\"item-edit-container\">\n \n <h1 class=\"item-edit-header\">{{heading()}}</h1>\n\n <form class=\"form-card\" [formGroup]=\"form.form\" (ngSubmit)=\"submit()\">\n\n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"name\">Name</mat-label>\n <input matInput placeholder=\"Name\"\n type=\"text\"\n id=\"name\"\n formControlName=\"name\"\n name=\"name\"\n required>\n </mat-form-field>\n \n <mat-form-field class=\"form-field\">\n <mat-label for=\"acronym\">Acronym</mat-label> \n <input matInput placeholder=\"Acronym\"\n type=\"text\"\n id=\"acronym\"\n formControlName=\"acronym\"\n name=\"acronym\">\n </mat-form-field>\n \n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"description\">Description</mat-label>\n <textarea matInput placeholder=\"Description\"\n type=\"text\"\n id=\"description\"\n formControlName=\"description\"\n name=\"description\"\n class=\"medium-textarea\"\n required></textarea>\n </mat-form-field>\n\n <h3>Address</h3>\n <lib-address-edit \n [countryOptions]=\"countryOptions()\"\n [form]=\"form.address.form\"\n ></lib-address-edit>\n\n <h3>Members</h3>\n <lib-select-table [selected]=\"selectedMembers()\"\n [itemType]=\"'Members'\"\n [columns]=\"columns\"\n [options]=\"candidateMembers()\"\n (itemAdded)=\"onMemberAdded($event)\"\n (itemRemoved)=\"onMemberRemoved($event)\"\n (searchChanged)=\"onSearchChanged($event)\">\n </lib-select-table>\n\n <div class=\"button_group\">\n <button mat-fab\n class=\"form_action_button\"\n type=\"submit\"\n [disabled]=\"!form.form.valid\">\n <mat-icon>save</mat-icon>\n </button>\n \n <button mat-fab\n class=\"form_action_button\"\n (click)=\"cancel()\">\n <mat-icon>cancel</mat-icon>\n </button>\n </div>\n \n </form>\n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}.medium-textarea{min-height:150px}.checkbox_group{justify-content:left;display:flex;flex-direction:column}.button_group{margin:10px;display:flex;flex-direction:row;justify-content:center}.btn-block{padding:5px}.form_action_button{padding:5px;margin:5px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatSelectModule }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: BackButtonComponent, selector: "lib-back-button" }, { kind: "component", type: AddressEditComponent, selector: "lib-address-edit", inputs: ["countryOptions", "form"] }, { kind: "component", type: SelectTableComponent, selector: "lib-select-table", inputs: ["itemType", "selected", "options", "columns"], outputs: ["itemAdded", "itemRemoved", "searchChanged"] }] });
|
|
928
1551
|
}
|
|
929
1552
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImport: i0, type: OrganizationEditComponent, decorators: [{
|
|
930
1553
|
type: Component,
|
|
931
|
-
args: [{ selector: 'lib-organization-edit', imports: [
|
|
932
|
-
UserSelectComponent,
|
|
1554
|
+
args: [{ selector: 'lib-organization-edit', imports: [
|
|
933
1555
|
ReactiveFormsModule,
|
|
934
1556
|
MatButtonModule,
|
|
935
1557
|
MatInputModule,
|
|
@@ -937,7 +1559,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
937
1559
|
MatFormFieldModule,
|
|
938
1560
|
MatIconModule,
|
|
939
1561
|
MatCheckboxModule,
|
|
940
|
-
BackButtonComponent
|
|
1562
|
+
BackButtonComponent,
|
|
1563
|
+
AddressEditComponent,
|
|
1564
|
+
SelectTableComponent
|
|
1565
|
+
], template: "<lib-back-button></lib-back-button>\n\n<div class=\"content-container\">\n\n @if(item(); as item){\n <div class=\"item-edit-container\">\n \n <h1 class=\"item-edit-header\">{{heading()}}</h1>\n\n <form class=\"form-card\" [formGroup]=\"form.form\" (ngSubmit)=\"submit()\">\n\n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"name\">Name</mat-label>\n <input matInput placeholder=\"Name\"\n type=\"text\"\n id=\"name\"\n formControlName=\"name\"\n name=\"name\"\n required>\n </mat-form-field>\n \n <mat-form-field class=\"form-field\">\n <mat-label for=\"acronym\">Acronym</mat-label> \n <input matInput placeholder=\"Acronym\"\n type=\"text\"\n id=\"acronym\"\n formControlName=\"acronym\"\n name=\"acronym\">\n </mat-form-field>\n \n <mat-form-field class=\"form-field-wide\">\n <mat-label for=\"description\">Description</mat-label>\n <textarea matInput placeholder=\"Description\"\n type=\"text\"\n id=\"description\"\n formControlName=\"description\"\n name=\"description\"\n class=\"medium-textarea\"\n required></textarea>\n </mat-form-field>\n\n <h3>Address</h3>\n <lib-address-edit \n [countryOptions]=\"countryOptions()\"\n [form]=\"form.address.form\"\n ></lib-address-edit>\n\n <h3>Members</h3>\n <lib-select-table [selected]=\"selectedMembers()\"\n [itemType]=\"'Members'\"\n [columns]=\"columns\"\n [options]=\"candidateMembers()\"\n (itemAdded)=\"onMemberAdded($event)\"\n (itemRemoved)=\"onMemberRemoved($event)\"\n (searchChanged)=\"onSearchChanged($event)\">\n </lib-select-table>\n\n <div class=\"button_group\">\n <button mat-fab\n class=\"form_action_button\"\n type=\"submit\"\n [disabled]=\"!form.form.valid\">\n <mat-icon>save</mat-icon>\n </button>\n \n <button mat-fab\n class=\"form_action_button\"\n (click)=\"cancel()\">\n <mat-icon>cancel</mat-icon>\n </button>\n </div>\n \n </form>\n </div>\n }\n</div>\n", styles: [":host{flex-grow:1}.medium-textarea{min-height:150px}.checkbox_group{justify-content:left;display:flex;flex-direction:column}.button_group{margin:10px;display:flex;flex-direction:row;justify-content:center}.btn-block{padding:5px}.form_action_button{padding:5px;margin:5px}\n"] }]
|
|
941
1566
|
}], ctorParameters: () => [] });
|
|
942
1567
|
|
|
943
1568
|
/*
|
|
@@ -948,5 +1573,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.1", ngImpor
|
|
|
948
1573
|
* Generated bundle index. Do not edit.
|
|
949
1574
|
*/
|
|
950
1575
|
|
|
951
|
-
export { ApiError, BackButtonComponent, DetailHeaderComponent, DetailView, ENDPOINT_URL, EditView, ErrorCode, FileRecord, FileUploadComponent, Group, GroupComponent, GroupDetailComponent, GroupService, LOGIN_USER, LandingComponent, LeftNavComponent, LeftNavService, ListView, Organization, OrganizationComponent, OrganizationDetailComponent, OrganizationEditComponent, OrganizationService, PortalMember, RestService, TopBarComponent, UserComponent, UserDetailComponent, UserEditComponent,
|
|
1576
|
+
export { Address, AddressDetailComponent, AddressEditComponent, AddressForm, AddressService, ApiError, BackButtonComponent, DetailHeaderComponent, DetailView, ENDPOINT_URL, EditView, ErrorCode, FileRecord, FileUploadComponent, Group, GroupComponent, GroupDetailComponent, GroupService, ItemQuery, ItemService, LOGIN_USER, LandingComponent, LeftNavComponent, LeftNavService, ListTableViewComponent, ListView, ListViewComponent, Organization, OrganizationComponent, OrganizationDetailComponent, OrganizationEditComponent, OrganizationService, Paginated, Permission, PortalMember, ResolvedPermission, RestService, SearchBarComponent, SelectTableComponent, TopBarComponent, UserComponent, UserDetailComponent, UserEditComponent, UserService };
|
|
952
1577
|
//# sourceMappingURL=ichec-angular-core.mjs.map
|