Skip to content

Commit

Permalink
Feature/IOT-1209-MoveGateway (#168)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
MadsApollo authored Sep 13, 2024
1 parent 963a660 commit 56e5f70
Show file tree
Hide file tree
Showing 12 changed files with 199 additions and 3 deletions.
14 changes: 14 additions & 0 deletions src/app/admin/organisation/organisation.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,20 @@ export class OrganisationService {
});
}

getMultipleWithGatewayAdmin(
limit: number = 1000,
offset: number = 0,
orderByColumn?: string,
orderByDirection?: string
): Observable<OrganisationGetManyResponse> {
return this.restService.get(`${this.URL}/gatewayAdmin`, {
limit,
offset,
orderOn: orderByColumn,
sort: orderByDirection,
});
}

delete(id: number) {
return this.restService.delete(this.URL, id);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<div class="gateway-change-organization-dialog">
<h1 mat-dialog-title>{{ "GATEWAY.CHANGE-ORGANIZATION.TITLE" | translate }}</h1>
<div mat-dialog-content>
<label class="form-label" for="organizationSelect">{{
"GATEWAY.CHANGE-ORGANIZATION.CHOOSE-ORGANIZATION" | translate
}}</label>
<mat-select
id="organizationSelect"
class="form-control"
panelClass="overflow-x-hidden"
[(value)]="gateway.organizationId"
[compareWith]="compare"
>
<mat-option *ngFor="let organization of filteredOrganizations | async" [value]="organization.id">
{{ organization.name }}
</mat-option>
</mat-select>
</div>
<div mat-dialog-actions class="d-flex flex-row">
<button (click)="onSubmit()" class="btn btn-primary">
{{ "GEN.SAVE" | translate }}
</button>
<button mat-dialog-close [mat-dialog-close]="false" class="btn btn-secondary ml-2">
{{ "GEN.CANCEL" | translate }}
</button>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.gateway-change-organization-dialog {
width: 50vw;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Component, Inject, OnInit } from "@angular/core";
import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog";
import { MatSnackBar } from "@angular/material/snack-bar";
import { Organisation } from "@app/admin/organisation/organisation.model";
import { OrganisationService } from "@app/admin/organisation/organisation.service";
import { TranslateService } from "@ngx-translate/core";
import { GatewayDialogModel } from "@shared/models/dialog.model";
import { ChirpstackGatewayService } from "@shared/services/chirpstack-gateway.service";
import { SharedVariableService } from "@shared/shared-variable/shared-variable.service";
import { ReplaySubject, Subscription } from "rxjs";
import { UpdateGatewayOrganization } from "../gateway.model";

@Component({
selector: "app-gateway-change-organization-dialog",
templateUrl: "./gateway-change-organization-dialog.component.html",
styleUrls: ["./gateway-change-organization-dialog.component.scss"],
})
export class GatewayChangeOrganizationDialogComponent implements OnInit {
public gatewaysSubscription: Subscription;
public organizationsSubscription: Subscription;
public gateway: UpdateGatewayOrganization;
public organizations: Organisation[];
public filteredOrganizations: ReplaySubject<Organisation[]> = new ReplaySubject<Organisation[]>(1);

constructor(
private gatewayService: ChirpstackGatewayService,
public translate: TranslateService,
private organizationService: OrganisationService,
private sharedVariableService: SharedVariableService,
private snackBar: MatSnackBar,
private dialog: MatDialogRef<GatewayChangeOrganizationDialogComponent>,
@Inject(MAT_DIALOG_DATA) public dialogModel: GatewayDialogModel
) {
this.gateway = {
organizationId: this.dialogModel.organizationId ?? this.sharedVariableService.getSelectedOrganisationId(),
};
}

ngOnInit(): void {
this.translate.use("da");
this.getOrganizations();
}

getOrganizations() {
this.organizationsSubscription = this.organizationService.getMultipleWithGatewayAdmin().subscribe(res => {
this.organizations = res.data;
this.filteredOrganizations.next(this.organizations.slice());
});
}

public compare(o1: any, o2: any): boolean {
return o1 === o2;
}

onSubmit() {
this.gatewaysSubscription = this.gatewayService
.updateGatewayOrganization(this.gateway, this.dialogModel.gatewayDbId)
.subscribe(gateway => {
this.snackBar.open(
this.translate.instant("GATEWAY.CHANGE-ORGANIZATION.SNACKBAR-SAVED", {
gatewayName: gateway.name,
organizationName: gateway.organization.name,
}),
"",
{
duration: 10000,
}
);
this.dialog.close(true);
});
}
}
30 changes: 29 additions & 1 deletion src/app/gateway/gateway-detail/gateway-detail.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import { ChartConfiguration } from "chart.js";
import { ColorGraphBlue1 } from "@shared/constants/color-constants";
import { formatDate } from "@angular/common";
import { DefaultPageSizeOptions } from "@shared/constants/page.constants";
import { MatDialog } from "@angular/material/dialog";
import { GatewayChangeOrganizationDialogComponent } from "../gateway-change-organization-dialog/gateway-change-organization-dialog.component";
import { GatewayDialogModel } from "@shared/models/dialog.model";

@Component({
selector: "app-gateway-detail",
Expand Down Expand Up @@ -50,7 +53,8 @@ export class GatewayDetailComponent implements OnInit, OnDestroy, AfterViewInit
private translate: TranslateService,
private router: Router,
private meService: MeService,
private deleteDialogService: DeleteDialogService
private deleteDialogService: DeleteDialogService,
private changeOrganizationDialog: MatDialog
) {}

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

this.translate.get("GATEWAY.CHANGE-ORGANIZATION.TITLE").subscribe(translation => {
this.dropdownButton.extraOptions.push({
id: this.gatewayId,
label: translation,
onClick: () => this.onOpenChangeOrganizationDialog(),
});
});

this.translate.get(["LORA-GATEWAY-TABLE-ROW.SHOW-OPTIONS"]).subscribe(translations => {
if (this.dropdownButton) {
this.dropdownButton.label = translations["LORA-GATEWAY-TABLE-ROW.SHOW-OPTIONS"];
Expand Down Expand Up @@ -188,6 +201,21 @@ export class GatewayDetailComponent implements OnInit, OnDestroy, AfterViewInit
});
}

onOpenChangeOrganizationDialog() {
const dialog = this.changeOrganizationDialog.open(GatewayChangeOrganizationDialogComponent, {
data: {
gatewayDbId: this.gateway.id,
organizationId: this.gateway.organizationId,
} as GatewayDialogModel,
});

dialog.afterClosed().subscribe(res => {
if (!res) return;

location.reload();
});
}

ngOnDestroy() {
if (this.gatewaySubscription) {
this.gatewaySubscription.unsubscribe();
Expand Down
5 changes: 5 additions & 0 deletions src/app/gateway/gateway-table/gateway-table.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,11 @@
"GEN.EDIT" | translate
}}</a>
</li>
<li class="dropdown-item">
<a (click)="onOpenChangeOrganizationDialog(gateway.id)" routerLinkActive="active">{{
"GATEWAY.CHANGE-ORGANIZATION.TITLE" | translate
}}</a>
</li>
<li class="dropdown-item">
<a (click)="clickDelete(gateway)" [routerLink]="[]">{{ "GEN.DELETE" | translate }}</a>
</li>
Expand Down
20 changes: 19 additions & 1 deletion src/app/gateway/gateway-table/gateway-table.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import { OrganizationAccessScope } from "@shared/enums/access-scopes";
import { DefaultPageSizeOptions } from "@shared/constants/page.constants";
import { TableColumn } from "@shared/types/table.type";
import { catchError, map, startWith, switchMap } from "rxjs/operators";
import { MatDialog } from "@angular/material/dialog";
import { GatewayDialogModel } from "@shared/models/dialog.model";
import { GatewayChangeOrganizationDialogComponent } from "../gateway-change-organization-dialog/gateway-change-organization-dialog.component";

const columnDefinitions: TableColumn[] = [
{
Expand Down Expand Up @@ -138,7 +141,8 @@ export class GatewayTableComponent implements AfterViewInit, OnDestroy, OnInit {
public translate: TranslateService,
private meService: MeService,
private deleteDialogService: DeleteDialogService,
private cdRef: ChangeDetectorRef
private cdRef: ChangeDetectorRef,
private changeOrganizationDialog: MatDialog
) {
this.translate.use("da");
moment.locale("da");
Expand Down Expand Up @@ -254,5 +258,19 @@ export class GatewayTableComponent implements AfterViewInit, OnDestroy, OnInit {
});
}

onOpenChangeOrganizationDialog(id: number) {
const dialog = this.changeOrganizationDialog.open(GatewayChangeOrganizationDialogComponent, {
data: {
gatewayDbId: id,
} as GatewayDialogModel,
});

dialog.afterClosed().subscribe(res => {
if (!res) return;

location.reload();
});
}

protected readonly columnDefinitions = columnDefinitions;
}
6 changes: 6 additions & 0 deletions src/app/gateway/gateway.model.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { EditPermission } from "@shared/models/edit-permission.model";
import { CommonLocation } from "@shared/models/common-location.model";
import { GatewayPlacement, GatewaySetupStatus, GatewayStatusInterval } from "./enums/gateway-status-interval.enum";
import { Organisation } from "@app/admin/organisation/organisation.model";

export class Gateway extends EditPermission {
id: number;
Expand All @@ -26,6 +27,7 @@ export class Gateway extends EditPermission {
lastSeenAt: Date;
organizationId: number;
organizationName: string;
organization: Organisation;
createdAt: Date;
updatedAt: Date;
createdBy: number;
Expand Down Expand Up @@ -93,3 +95,7 @@ export interface AllGatewayStatusResponse {
data: GatewayStatus[];
count: number;
}

export class UpdateGatewayOrganization {
public organizationId: number;
}
2 changes: 2 additions & 0 deletions src/app/gateway/gateway.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { GraphModule } from "@app/graph/graph.module";
import { GatewayListComponent } from "./gateway-overview/gateway-tabs/gateway-list/gateway-list.component";
import { GatewayMapComponent } from "./gateway-overview/gateway-tabs/gateway-map/gateway-map.component";
import { GatewayStatusOverviewComponent } from "./gateway-overview/gateway-tabs/gateway-status-overview/gateway-status-overview.component";
import { GatewayChangeOrganizationDialogComponent } from "./gateway-change-organization-dialog/gateway-change-organization-dialog.component";

const gatewayRoutes: Routes = [
{
Expand Down Expand Up @@ -51,6 +52,7 @@ const gatewayRoutes: Routes = [
GatewayListComponent,
GatewayMapComponent,
GatewayStatusOverviewComponent,
GatewayChangeOrganizationDialogComponent,
],
imports: [
CommonModule,
Expand Down
5 changes: 5 additions & 0 deletions src/app/shared/models/dialog.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,8 @@ export class ApplicationDialogModel {
applicationId: number;
organizationId?: number;
}

export class GatewayDialogModel {
gatewayDbId: number;
organizationId?: number;
}
13 changes: 12 additions & 1 deletion src/app/shared/services/chirpstack-gateway.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { Injectable } from "@angular/core";
import { RestService } from "./rest.service";
import { Observable } from "rxjs";
import { GatewayResponse, Gateway, GatewayData, GatewayRequest, GatewayResponseMany } from "@app/gateway/gateway.model";
import {
GatewayResponse,
Gateway,
GatewayData,
GatewayRequest,
GatewayResponseMany,
UpdateGatewayOrganization,
} from "@app/gateway/gateway.model";
import moment from "moment";
import { SharedVariableService } from "@shared/shared-variable/shared-variable.service";
import { map } from "rxjs/operators";
Expand Down Expand Up @@ -69,6 +76,10 @@ export class ChirpstackGatewayService {
return this.restService.put(this.chripstackGatewayUrl, gatewayRequest, id);
}

public updateGatewayOrganization(body: UpdateGatewayOrganization, id: number): Observable<Gateway> {
return this.restService.put(`${this.chripstackGatewayUrl}/updateGatewayOrganization`, body, id);
}

public delete(gatewayId: string): Observable<any> {
return this.restService.delete(this.chripstackGatewayUrl, gatewayId);
}
Expand Down
5 changes: 5 additions & 0 deletions src/assets/i18n/da.json
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,11 @@
"PROJECT": "Projekt",
"PROTOTYPE": "Prototype",
"OTHER": "Andet"
},
"CHANGE-ORGANIZATION": {
"TITLE": "Skift organisation",
"CHOOSE-ORGANIZATION": "Vælg hvilken organisation denne gateway skal tilhøre",
"SNACKBAR-SAVED": "{{gatewayName}} tilhører nu {{organizationName}}"
}
},
"IOT-DEVICE": {
Expand Down

0 comments on commit 56e5f70

Please sign in to comment.