Skip to content

Commit 56e5f70

Browse files
authored
Feature/IOT-1209-MoveGateway (#168)
* Added dialog for changing gateway organization. * rename of gateway db id. Also change to use extra button onclick event. * Added gateway endpoint for organizations and use.
1 parent 963a660 commit 56e5f70

12 files changed

+199
-3
lines changed

src/app/admin/organisation/organisation.service.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,20 @@ export class OrganisationService {
7777
});
7878
}
7979

80+
getMultipleWithGatewayAdmin(
81+
limit: number = 1000,
82+
offset: number = 0,
83+
orderByColumn?: string,
84+
orderByDirection?: string
85+
): Observable<OrganisationGetManyResponse> {
86+
return this.restService.get(`${this.URL}/gatewayAdmin`, {
87+
limit,
88+
offset,
89+
orderOn: orderByColumn,
90+
sort: orderByDirection,
91+
});
92+
}
93+
8094
delete(id: number) {
8195
return this.restService.delete(this.URL, id);
8296
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<div class="gateway-change-organization-dialog">
2+
<h1 mat-dialog-title>{{ "GATEWAY.CHANGE-ORGANIZATION.TITLE" | translate }}</h1>
3+
<div mat-dialog-content>
4+
<label class="form-label" for="organizationSelect">{{
5+
"GATEWAY.CHANGE-ORGANIZATION.CHOOSE-ORGANIZATION" | translate
6+
}}</label>
7+
<mat-select
8+
id="organizationSelect"
9+
class="form-control"
10+
panelClass="overflow-x-hidden"
11+
[(value)]="gateway.organizationId"
12+
[compareWith]="compare"
13+
>
14+
<mat-option *ngFor="let organization of filteredOrganizations | async" [value]="organization.id">
15+
{{ organization.name }}
16+
</mat-option>
17+
</mat-select>
18+
</div>
19+
<div mat-dialog-actions class="d-flex flex-row">
20+
<button (click)="onSubmit()" class="btn btn-primary">
21+
{{ "GEN.SAVE" | translate }}
22+
</button>
23+
<button mat-dialog-close [mat-dialog-close]="false" class="btn btn-secondary ml-2">
24+
{{ "GEN.CANCEL" | translate }}
25+
</button>
26+
</div>
27+
</div>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.gateway-change-organization-dialog {
2+
width: 50vw;
3+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { Component, Inject, OnInit } from "@angular/core";
2+
import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog";
3+
import { MatSnackBar } from "@angular/material/snack-bar";
4+
import { Organisation } from "@app/admin/organisation/organisation.model";
5+
import { OrganisationService } from "@app/admin/organisation/organisation.service";
6+
import { TranslateService } from "@ngx-translate/core";
7+
import { GatewayDialogModel } from "@shared/models/dialog.model";
8+
import { ChirpstackGatewayService } from "@shared/services/chirpstack-gateway.service";
9+
import { SharedVariableService } from "@shared/shared-variable/shared-variable.service";
10+
import { ReplaySubject, Subscription } from "rxjs";
11+
import { UpdateGatewayOrganization } from "../gateway.model";
12+
13+
@Component({
14+
selector: "app-gateway-change-organization-dialog",
15+
templateUrl: "./gateway-change-organization-dialog.component.html",
16+
styleUrls: ["./gateway-change-organization-dialog.component.scss"],
17+
})
18+
export class GatewayChangeOrganizationDialogComponent implements OnInit {
19+
public gatewaysSubscription: Subscription;
20+
public organizationsSubscription: Subscription;
21+
public gateway: UpdateGatewayOrganization;
22+
public organizations: Organisation[];
23+
public filteredOrganizations: ReplaySubject<Organisation[]> = new ReplaySubject<Organisation[]>(1);
24+
25+
constructor(
26+
private gatewayService: ChirpstackGatewayService,
27+
public translate: TranslateService,
28+
private organizationService: OrganisationService,
29+
private sharedVariableService: SharedVariableService,
30+
private snackBar: MatSnackBar,
31+
private dialog: MatDialogRef<GatewayChangeOrganizationDialogComponent>,
32+
@Inject(MAT_DIALOG_DATA) public dialogModel: GatewayDialogModel
33+
) {
34+
this.gateway = {
35+
organizationId: this.dialogModel.organizationId ?? this.sharedVariableService.getSelectedOrganisationId(),
36+
};
37+
}
38+
39+
ngOnInit(): void {
40+
this.translate.use("da");
41+
this.getOrganizations();
42+
}
43+
44+
getOrganizations() {
45+
this.organizationsSubscription = this.organizationService.getMultipleWithGatewayAdmin().subscribe(res => {
46+
this.organizations = res.data;
47+
this.filteredOrganizations.next(this.organizations.slice());
48+
});
49+
}
50+
51+
public compare(o1: any, o2: any): boolean {
52+
return o1 === o2;
53+
}
54+
55+
onSubmit() {
56+
this.gatewaysSubscription = this.gatewayService
57+
.updateGatewayOrganization(this.gateway, this.dialogModel.gatewayDbId)
58+
.subscribe(gateway => {
59+
this.snackBar.open(
60+
this.translate.instant("GATEWAY.CHANGE-ORGANIZATION.SNACKBAR-SAVED", {
61+
gatewayName: gateway.name,
62+
organizationName: gateway.organization.name,
63+
}),
64+
"",
65+
{
66+
duration: 10000,
67+
}
68+
);
69+
this.dialog.close(true);
70+
});
71+
}
72+
}

src/app/gateway/gateway-detail/gateway-detail.component.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ import { ChartConfiguration } from "chart.js";
1616
import { ColorGraphBlue1 } from "@shared/constants/color-constants";
1717
import { formatDate } from "@angular/common";
1818
import { DefaultPageSizeOptions } from "@shared/constants/page.constants";
19+
import { MatDialog } from "@angular/material/dialog";
20+
import { GatewayChangeOrganizationDialogComponent } from "../gateway-change-organization-dialog/gateway-change-organization-dialog.component";
21+
import { GatewayDialogModel } from "@shared/models/dialog.model";
1922

2023
@Component({
2124
selector: "app-gateway-detail",
@@ -50,7 +53,8 @@ export class GatewayDetailComponent implements OnInit, OnDestroy, AfterViewInit
5053
private translate: TranslateService,
5154
private router: Router,
5255
private meService: MeService,
53-
private deleteDialogService: DeleteDialogService
56+
private deleteDialogService: DeleteDialogService,
57+
private changeOrganizationDialog: MatDialog
5458
) {}
5559

5660
ngOnInit(): void {
@@ -120,9 +124,18 @@ export class GatewayDetailComponent implements OnInit, OnDestroy, AfterViewInit
120124
label: "LORA-GATEWAY-TABLE-ROW.SHOW-OPTIONS",
121125
editRouterLink: "../../gateway-edit/" + this.gatewayId,
122126
isErasable: true,
127+
extraOptions: [],
123128
}
124129
: null;
125130

131+
this.translate.get("GATEWAY.CHANGE-ORGANIZATION.TITLE").subscribe(translation => {
132+
this.dropdownButton.extraOptions.push({
133+
id: this.gatewayId,
134+
label: translation,
135+
onClick: () => this.onOpenChangeOrganizationDialog(),
136+
});
137+
});
138+
126139
this.translate.get(["LORA-GATEWAY-TABLE-ROW.SHOW-OPTIONS"]).subscribe(translations => {
127140
if (this.dropdownButton) {
128141
this.dropdownButton.label = translations["LORA-GATEWAY-TABLE-ROW.SHOW-OPTIONS"];
@@ -188,6 +201,21 @@ export class GatewayDetailComponent implements OnInit, OnDestroy, AfterViewInit
188201
});
189202
}
190203

204+
onOpenChangeOrganizationDialog() {
205+
const dialog = this.changeOrganizationDialog.open(GatewayChangeOrganizationDialogComponent, {
206+
data: {
207+
gatewayDbId: this.gateway.id,
208+
organizationId: this.gateway.organizationId,
209+
} as GatewayDialogModel,
210+
});
211+
212+
dialog.afterClosed().subscribe(res => {
213+
if (!res) return;
214+
215+
location.reload();
216+
});
217+
}
218+
191219
ngOnDestroy() {
192220
if (this.gatewaySubscription) {
193221
this.gatewaySubscription.unsubscribe();

src/app/gateway/gateway-table/gateway-table.component.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,11 @@
206206
"GEN.EDIT" | translate
207207
}}</a>
208208
</li>
209+
<li class="dropdown-item">
210+
<a (click)="onOpenChangeOrganizationDialog(gateway.id)" routerLinkActive="active">{{
211+
"GATEWAY.CHANGE-ORGANIZATION.TITLE" | translate
212+
}}</a>
213+
</li>
209214
<li class="dropdown-item">
210215
<a (click)="clickDelete(gateway)" [routerLink]="[]">{{ "GEN.DELETE" | translate }}</a>
211216
</li>

src/app/gateway/gateway-table/gateway-table.component.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ import { OrganizationAccessScope } from "@shared/enums/access-scopes";
1414
import { DefaultPageSizeOptions } from "@shared/constants/page.constants";
1515
import { TableColumn } from "@shared/types/table.type";
1616
import { catchError, map, startWith, switchMap } from "rxjs/operators";
17+
import { MatDialog } from "@angular/material/dialog";
18+
import { GatewayDialogModel } from "@shared/models/dialog.model";
19+
import { GatewayChangeOrganizationDialogComponent } from "../gateway-change-organization-dialog/gateway-change-organization-dialog.component";
1720

1821
const columnDefinitions: TableColumn[] = [
1922
{
@@ -138,7 +141,8 @@ export class GatewayTableComponent implements AfterViewInit, OnDestroy, OnInit {
138141
public translate: TranslateService,
139142
private meService: MeService,
140143
private deleteDialogService: DeleteDialogService,
141-
private cdRef: ChangeDetectorRef
144+
private cdRef: ChangeDetectorRef,
145+
private changeOrganizationDialog: MatDialog
142146
) {
143147
this.translate.use("da");
144148
moment.locale("da");
@@ -254,5 +258,19 @@ export class GatewayTableComponent implements AfterViewInit, OnDestroy, OnInit {
254258
});
255259
}
256260

261+
onOpenChangeOrganizationDialog(id: number) {
262+
const dialog = this.changeOrganizationDialog.open(GatewayChangeOrganizationDialogComponent, {
263+
data: {
264+
gatewayDbId: id,
265+
} as GatewayDialogModel,
266+
});
267+
268+
dialog.afterClosed().subscribe(res => {
269+
if (!res) return;
270+
271+
location.reload();
272+
});
273+
}
274+
257275
protected readonly columnDefinitions = columnDefinitions;
258276
}

src/app/gateway/gateway.model.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { EditPermission } from "@shared/models/edit-permission.model";
22
import { CommonLocation } from "@shared/models/common-location.model";
33
import { GatewayPlacement, GatewaySetupStatus, GatewayStatusInterval } from "./enums/gateway-status-interval.enum";
4+
import { Organisation } from "@app/admin/organisation/organisation.model";
45

56
export class Gateway extends EditPermission {
67
id: number;
@@ -26,6 +27,7 @@ export class Gateway extends EditPermission {
2627
lastSeenAt: Date;
2728
organizationId: number;
2829
organizationName: string;
30+
organization: Organisation;
2931
createdAt: Date;
3032
updatedAt: Date;
3133
createdBy: number;
@@ -93,3 +95,7 @@ export interface AllGatewayStatusResponse {
9395
data: GatewayStatus[];
9496
count: number;
9597
}
98+
99+
export class UpdateGatewayOrganization {
100+
public organizationId: number;
101+
}

src/app/gateway/gateway.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { GraphModule } from "@app/graph/graph.module";
1818
import { GatewayListComponent } from "./gateway-overview/gateway-tabs/gateway-list/gateway-list.component";
1919
import { GatewayMapComponent } from "./gateway-overview/gateway-tabs/gateway-map/gateway-map.component";
2020
import { GatewayStatusOverviewComponent } from "./gateway-overview/gateway-tabs/gateway-status-overview/gateway-status-overview.component";
21+
import { GatewayChangeOrganizationDialogComponent } from "./gateway-change-organization-dialog/gateway-change-organization-dialog.component";
2122

2223
const gatewayRoutes: Routes = [
2324
{
@@ -51,6 +52,7 @@ const gatewayRoutes: Routes = [
5152
GatewayListComponent,
5253
GatewayMapComponent,
5354
GatewayStatusOverviewComponent,
55+
GatewayChangeOrganizationDialogComponent,
5456
],
5557
imports: [
5658
CommonModule,

src/app/shared/models/dialog.model.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,8 @@ export class ApplicationDialogModel {
1717
applicationId: number;
1818
organizationId?: number;
1919
}
20+
21+
export class GatewayDialogModel {
22+
gatewayDbId: number;
23+
organizationId?: number;
24+
}

0 commit comments

Comments
 (0)