Skip to content

Commit b5c9bc8

Browse files
authored
Merge pull request #43 from OS2iot/develop
Merge develop into master
2 parents 2a8a77d + a0acc33 commit b5c9bc8

File tree

76 files changed

+1326
-582
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+1326
-582
lines changed

src/app/admin/admin.module.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { UserTableComponent } from './users/user-list/user-table/user-table.comp
2727
import { UsersComponent } from './users/users.component';
2828
import { MatSelectModule } from '@angular/material/select';
2929
import { MatFormFieldModule } from '@angular/material/form-field';
30+
import { MatSelectSearchModule } from '@shared/components/mat-select-search/mat-select-search.module';
3031

3132
@NgModule({
3233
declarations: [
@@ -60,6 +61,7 @@ import { MatFormFieldModule } from '@angular/material/form-field';
6061
SharedModule,
6162
MatSelectModule,
6263
MatFormFieldModule,
64+
MatSelectSearchModule,
6365
],
6466
exports: [
6567
UserDetailComponent,
@@ -79,4 +81,4 @@ import { MatFormFieldModule } from '@angular/material/form-field';
7981
OrganisationListComponent,
8082
],
8183
})
82-
export class AdminModule { }
84+
export class AdminModule {}

src/app/admin/organisation/organisation-detail/organisation-detail.component.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dia
1414
import { DropdownButton } from '@shared/models/dropdown-button.model';
1515
import { ApplicationService } from '@applications/application.service';
1616
import { environment } from '@environments/environment';
17+
import { Title } from '@angular/platform-browser';
1718

1819
@Component({
1920
selector: 'app-organisation-detail',
@@ -47,7 +48,8 @@ export class OrganisationDetailComponent implements OnInit, OnChanges, OnDestroy
4748
private organisationService: OrganisationService,
4849
private permissionsService: PermissionService,
4950
private deleteDialogService: DeleteDialogService,
50-
private location: Location
51+
private location: Location,
52+
private titleService: Title
5153
) { }
5254

5355
ngOnChanges(changes: SimpleChanges): void {
@@ -64,10 +66,11 @@ export class OrganisationDetailComponent implements OnInit, OnChanges, OnDestroy
6466
editRouterLink: 'edit-organisation',
6567
isErasable: true,
6668
}
67-
this.translate.get(['NAV.ORGANISATIONS', 'ORGANISATION.DROPDOWN'])
69+
this.translate.get(['NAV.ORGANISATIONS', 'ORGANISATION.DROPDOWN', 'TITLE.ORGANIZATION'])
6870
.subscribe(translations => {
6971
this.backButton.label = translations['NAV.ORGANISATIONS'];
7072
this.dropdownButton.label = translations['ORGANISATION.DROPDOWN'];
73+
this.titleService.setTitle(translations['TITLE.ORGANIZATION'])
7174
});
7275
}
7376

src/app/admin/organisation/organisation-list/organisation-list.component.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Component, OnInit } from '@angular/core';
2+
import { Title } from '@angular/platform-browser';
23
import { TranslateService } from '@ngx-translate/core';
34
import { Sort } from '@shared/models/sort.model';
45

@@ -9,9 +10,14 @@ import { Sort } from '@shared/models/sort.model';
910
})
1011
export class OrganisationListComponent implements OnInit {
1112

12-
constructor(public translate: TranslateService) {
13+
constructor(public translate: TranslateService, private titleService: Title) {
1314
translate.use('da');
1415
}
1516

16-
ngOnInit(): void { }
17+
ngOnInit(): void {
18+
this.translate.get(['TITLE.ORGANIZATION'])
19+
.subscribe(translations => {
20+
this.titleService.setTitle(translations['TITLE.ORGANIZATION']);
21+
});
22+
}
1723
}

src/app/admin/organisation/organisation-list/organisation-tabel/organisation-tabel.component.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
<div class="mat-elevation-z8">
2+
<div class="loading-shade" *ngIf="isLoadingResults">
3+
<mat-spinner *ngIf="isLoadingResults"></mat-spinner>
4+
</div>
25
<table mat-table [dataSource]="data" matSort matSortActive="name" matSortDirection="asc" matSortDisableClear>
36

47
<!-- Name Column -->

src/app/admin/permission/permission-detail/permission-detail.component.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
1-
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
1+
import { Component, OnChanges, OnInit, SimpleChanges } from '@angular/core';
22
import { ActivatedRoute, Router } from '@angular/router';
33
import { TranslateService } from '@ngx-translate/core';
44
import { PermissionService } from '@app/admin/permission/permission.service';
55
import { Subscription } from 'rxjs';
66
import { PermissionResponse } from '../permission.model';
77
import { BackButton } from '@shared/models/back-button.model';
88
import { QuickActionButton } from '@shared/models/quick-action-button.model';
9-
import { Application } from '@applications/application.model';
10-
import { ApplicationService } from '@applications/application.service';
11-
import { SharedVariableService } from '@shared/shared-variable/shared-variable.service';
12-
import { OrganisationResponse } from '@app/admin/organisation/organisation.model';
13-
import { OrganisationService } from '@app/admin/organisation/organisation.service';
149
import { UserResponse } from '@app/admin/users/user.model';
1510
import { DropdownButton } from '@shared/models/dropdown-button.model';
1611
import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dialog.service';
1712
import { environment } from '@environments/environment';
13+
import { Title } from '@angular/platform-browser';
1814

1915

2016
@Component({
@@ -53,6 +49,7 @@ export class PermissionDetailComponent implements OnInit, OnChanges {
5349
private route: ActivatedRoute,
5450
private permissionService: PermissionService,
5551
private router: Router,
52+
private titleService: Title,
5653
private deleteDialogService: DeleteDialogService
5754
) { }
5855

@@ -67,10 +64,11 @@ export class PermissionDetailComponent implements OnInit, OnChanges {
6764
isErasable: true,
6865
}
6966
}
70-
this.translate.get(['NAV.PERMISSIONS', 'PERMISSION.DETAIL.DROPDOWN'])
67+
this.translate.get(['NAV.PERMISSIONS', 'PERMISSION.DETAIL.DROPDOWN', 'TITLE.PERMISSION'])
7168
.subscribe(translations => {
7269
this.backButton.label = translations['NAV.PERMISSIONS'];
7370
this.dropdownButton.label = translations['PERMISSION.DETAIL.DROPDOWN'];
71+
this.titleService.setTitle(translations['TITLE.PERMISSION']);
7472
});
7573
}
7674

src/app/admin/permission/permission-edit/permission-edit.component.html

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,16 @@
3131
</div>
3232

3333
<div class="form-group mt-3 col-12">
34-
<label class="form-label" for="user">{{'PERMISSION.EDIT.USERS' | translate}}</label>
3534
<mat-form-field>
36-
<mat-select
37-
name="users"
38-
[multiple]="true"
39-
#multiSelect
40-
[compareWith]="compare"
41-
[(value)]="permission.userIds">
42-
<mat-option *ngFor="let user of users" [value]="user.id">
43-
{{user.name}} ({{user.email}})
44-
</mat-option>
35+
<label class="form-label" for="user">{{'PERMISSION.EDIT.USERS' | translate}}</label>
36+
<mat-select [formControl]="userMultiCtrl" placeholder="" [multiple]="true" panelClass="overflow-x-hidden"
37+
[(value)]="permission.userIds" name="users" #multiSelect [compareWith]="compare">
38+
<mat-select-search [formControl]="userMultiFilterCtrl"></mat-select-search>
39+
<mat-option *ngFor="let user of filteredUsersMulti | async" [value]="user.id">
40+
{{getTextForUser(user)}}
41+
</mat-option>
4542
</mat-select>
46-
</mat-form-field>
43+
</mat-form-field>
4744
</div>
4845

4946
<div *ngIf="permission.level != 'GlobalAdmin'">
@@ -61,26 +58,28 @@
6158
</div>
6259
</div>
6360

64-
<div *ngIf="isOrganizationAdministrationPermission()">
65-
<div class="form-group mt-3 col-12">
61+
<div class="form-group mt-3 col-12" *ngIf="isOrganizationApplicationPermission()">
62+
<mat-form-field>
6663
<label class="form-label" for="name">{{'PERMISSION.EDIT.APPS' | translate}}</label>
6764
<div class="col-12">
68-
<select id="applicationIds" name="applicationIds" class="form-control" multiple
69-
[(ngModel)]="permission.applicationIds"
70-
placeholder="'PERMISSION.EDIT.APPS-PLACEHOLDER' | translate">
71-
<option *ngFor="let app of applications" [value]="app.id"
72-
[selected]="isApplicationPartOfPermission(app.id)">
73-
{{app.name}}</option>
74-
</select>
65+
<mat-select [formControl]="applicationMultiCtrl" placeholder="" [multiple]="true"
66+
panelClass="overflow-x-hidden" [(value)]="permission.applicationIds" id="applicationIds"
67+
name="applicationIds" #multiSelect [compareWith]="compare">
68+
<mat-select-search [formControl]="applicationMultiFilterCtrl"></mat-select-search>
69+
<mat-option *ngFor="let app of filteredApplicationsMulti | async" [value]="app.id">
70+
{{app.name}}
71+
</mat-option>
72+
</mat-select>
7573
</div>
76-
</div>
74+
</mat-form-field>
7775
</div>
7876

7977
<div *ngIf="isReadOrWrite()">
8078
<div class="form-group mt-3 col-12">
8179
<label class="form-label" for="name">{{'PERMISSION.EDIT.ADD-APPLICATION-AUTOMATIC' | translate}}</label>
8280
<div class="row">
83-
<mat-slide-toggle [(ngModel)]="permission.automaticallyAddNewApplications" id="automaticallyAddNewApplications" name="automaticallyAddNewApplications">
81+
<mat-slide-toggle [(ngModel)]="permission.automaticallyAddNewApplications"
82+
id="automaticallyAddNewApplications" name="automaticallyAddNewApplications">
8483
{{'PERMISSION.EDIT.ADD-APPLICATION-ON-CREATE' | translate}}</mat-slide-toggle>
8584
</div>
8685
</div>

src/app/admin/permission/permission-edit/permission-edit.component.ts

Lines changed: 99 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { Component, OnInit } from '@angular/core';
1+
import { Component, OnDestroy, OnInit } from '@angular/core';
22
import { HttpErrorResponse } from '@angular/common/http';
3-
import { FormGroup } from '@angular/forms';
3+
import { FormControl, FormGroup } from '@angular/forms';
44
import { ActivatedRoute } from '@angular/router';
55
import { TranslateService } from '@ngx-translate/core';
6-
import { Subscription } from 'rxjs';
6+
import { ReplaySubject, Subject, Subscription } from 'rxjs';
77
import { Location } from '@angular/common';
88
import { PermissionService } from '../permission.service';
99
import { PermissionRequest, PermissionType } from '../permission.model';
@@ -15,13 +15,14 @@ import { ApplicationService } from '@applications/application.service';
1515
import { Application } from '@applications/application.model';
1616
import { BackButton } from '@shared/models/back-button.model';
1717
import { ErrorMessageService } from '@shared/error-message.service';
18+
import { takeUntil } from 'rxjs/operators';
1819

1920
@Component({
2021
selector: 'app-permission-edit',
2122
templateUrl: './permission-edit.component.html',
2223
styleUrls: ['./permission-edit.component.scss'],
2324
})
24-
export class PermissionEditComponent implements OnInit {
25+
export class PermissionEditComponent implements OnInit, OnDestroy {
2526
permission = new PermissionRequest();
2627
public organisations: OrganisationResponse[];
2728
public users: UserResponse[];
@@ -31,7 +32,10 @@ export class PermissionEditComponent implements OnInit {
3132
public errorFields: string[];
3233
public formFailedSubmit = false;
3334
public form: FormGroup;
34-
public backButton: BackButton = { label: '', routerLink: ['admin','permissions'] };
35+
public backButton: BackButton = {
36+
label: '',
37+
routerLink: ['admin', 'permissions'],
38+
};
3539
public title = '';
3640
public submitButton = '';
3741
public isEditMode = false;
@@ -41,6 +45,18 @@ export class PermissionEditComponent implements OnInit {
4145
userSubscription: Subscription;
4246
applicationSubscription: Subscription;
4347

48+
public userMultiCtrl: FormControl = new FormControl();
49+
public userMultiFilterCtrl: FormControl = new FormControl();
50+
public filteredUsersMulti: ReplaySubject<UserResponse[]> = new ReplaySubject<
51+
UserResponse[]
52+
>(1);
53+
54+
public applicationMultiCtrl: FormControl = new FormControl();
55+
public applicationMultiFilterCtrl: FormControl = new FormControl();
56+
public filteredApplicationsMulti: ReplaySubject<
57+
Application[]
58+
> = new ReplaySubject<Application[]>(1);
59+
4460
constructor(
4561
private translate: TranslateService,
4662
private route: ActivatedRoute,
@@ -69,6 +85,64 @@ export class PermissionEditComponent implements OnInit {
6985
this.isEditMode = true;
7086
this.setBackButton();
7187
}
88+
89+
this.userMultiFilterCtrl.valueChanges
90+
.pipe(takeUntil(this._onDestroy))
91+
.subscribe(() => {
92+
this.filterUsersMulti();
93+
});
94+
95+
this.applicationMultiFilterCtrl.valueChanges
96+
.pipe(takeUntil(this._onDestroy))
97+
.subscribe(() => {
98+
this.filterApplicationsMulti();
99+
});
100+
}
101+
102+
private filterApplicationsMulti() {
103+
if (!this.applications) {
104+
return;
105+
}
106+
// get the search keyword
107+
let search = this.applicationMultiFilterCtrl.value;
108+
if (!search) {
109+
this.filteredApplicationsMulti.next(this.applications.slice());
110+
return;
111+
} else {
112+
search = search.toLowerCase();
113+
}
114+
// filter the banks
115+
this.filteredApplicationsMulti.next(
116+
this.applications.filter(
117+
(app) => app.name.toLowerCase().indexOf(search) > -1
118+
)
119+
);
120+
}
121+
122+
private filterUsersMulti() {
123+
if (!this.users) {
124+
return;
125+
}
126+
// get the search keyword
127+
let search = this.userMultiFilterCtrl?.value?.trim();
128+
if (!search) {
129+
this.filteredUsersMulti.next(this.users.slice());
130+
return;
131+
} else {
132+
search = search.toLowerCase();
133+
}
134+
const filtered = this.users.filter((user) => {
135+
return (
136+
user.name.toLocaleLowerCase().indexOf(search) > -1 ||
137+
user?.email?.toLocaleLowerCase()?.indexOf(search) > -1
138+
);
139+
});
140+
// filter the banks
141+
this.filteredUsersMulti.next(filtered);
142+
}
143+
144+
getTextForUser(user: UserResponse): string {
145+
return `${user.name}` + (user.email ? ` (${user.email})` : ``);
72146
}
73147

74148
private setBackButton() {
@@ -92,6 +166,7 @@ export class PermissionEditComponent implements OnInit {
92166
this.userSubscription = this.userService.getMultiple().subscribe(
93167
(users) => {
94168
this.users = users.data;
169+
this.filteredUsersMulti.next(this.users.slice());
95170
},
96171
(error: HttpErrorResponse) => {
97172
this.showError(error);
@@ -113,6 +188,7 @@ export class PermissionEditComponent implements OnInit {
113188
.subscribe(
114189
(res) => {
115190
this.applications = res.data;
191+
this.filteredApplicationsMulti.next(this.applications.slice());
116192
},
117193
(error: HttpErrorResponse) => {
118194
this.showError(error);
@@ -127,7 +203,9 @@ export class PermissionEditComponent implements OnInit {
127203
this.permission.name = response.name;
128204
this.permission.level = response.type;
129205
this.permission.userIds = response.users.map((x) => x.id);
130-
this.permission.automaticallyAddNewApplications = response.automaticallyAddNewApplications;
206+
this.userMultiCtrl.setValue(this.permission.userIds);
207+
this.permission.automaticallyAddNewApplications =
208+
response.automaticallyAddNewApplications;
131209

132210
if (response.type !== PermissionType.GlobalAdmin) {
133211
this.permission.organizationId = response?.organization?.id;
@@ -141,6 +219,7 @@ export class PermissionEditComponent implements OnInit {
141219
this.permission.applicationIds = response.applications.map(
142220
(x) => x.id
143221
);
222+
this.applicationMultiCtrl.setValue(this.permission.applicationIds);
144223
}
145224
},
146225
(error: HttpErrorResponse) => {
@@ -199,17 +278,19 @@ export class PermissionEditComponent implements OnInit {
199278
}
200279
}
201280

202-
isOrganizationAdministrationPermission() {
281+
isOrganizationApplicationPermission() {
203282
return (
204283
this.permission.level ==
205284
PermissionType.OrganizationApplicationPermissions ||
206-
this.permission.level == PermissionType.Write ||
207-
this.permission.level == PermissionType.Read
285+
this.isReadOrWrite()
208286
);
209287
}
210288

211289
isReadOrWrite(): boolean {
212-
return this.permission.level === PermissionType.Read || this.permission.level === PermissionType.Write
290+
return (
291+
this.permission.level === PermissionType.Read ||
292+
this.permission.level === PermissionType.Write
293+
);
213294
}
214295

215296
onSubmit(): void {
@@ -229,4 +310,12 @@ export class PermissionEditComponent implements OnInit {
229310
routeBack(): void {
230311
this.location.back();
231312
}
313+
314+
/** Subject that emits when the component has been destroyed. */
315+
private _onDestroy = new Subject<void>();
316+
317+
ngOnDestroy() {
318+
this._onDestroy.next();
319+
this._onDestroy.complete();
320+
}
232321
}

src/app/admin/permission/permission-list/permission-list.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<app-top-bar [sort]="sort" [pageLimit]="pageLimit" [title]="'NAV.PERMISSIONS' | translate"
1+
<app-top-bar [pageLimit]="pageLimit" [title]="'NAV.PERMISSIONS' | translate"
22
[ctaLabel]="'FORM.CREATE-NEW-PERMISSION' | translate" [ctaRouterLink]="'new-permission'"></app-top-bar>
33
<div class="container-fluid">
44
<div class="row">

0 commit comments

Comments
 (0)