Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { SharedVariableService } from "@shared/shared-variable/shared-variable.s
import { Observable, Subscription } from "rxjs";
import { map } from "rxjs/operators";
import { ApplicationChangeOrganizationDialogComponent } from "../application-change-organization-dialog/application-change-organization-dialog.component";
import moment from "moment/moment";

@Component({
selector: "app-application",
Expand Down Expand Up @@ -53,12 +54,12 @@ export class ApplicationDetailComponent implements OnInit, OnDestroy, AfterViewI
public canEdit = false;
public devices: IotDevicesApplicationMapResponse[];
public coordinateList = [];
private deviceSubscription: Subscription;
private gatewaysSubscription: Subscription;
public gateways: Gateway[];
public redMarker = "/assets/images/red-marker.png";
public greenMarker = "/assets/images/green-marker.png";
public greyMarker = "/assets/images/grey-marker.png";
private deviceSubscription: Subscription;
private gatewaysSubscription: Subscription;

constructor(
private applicationService: ApplicationService,
Expand Down Expand Up @@ -125,6 +126,57 @@ export class ApplicationDetailComponent implements OnInit, OnDestroy, AfterViewI
});
}

onDeleteApplication() {
this.deleteDialogService.showApplicationDialog(this.application).subscribe(response => {
if (response) {
this.applicationService.deleteApplication(this.application.id).subscribe(response => {
if (response.ok && response.body.affected > 0) {
console.log("delete application with id:" + this.application.id.toString());
this.router.navigate(["applications"]);
} else {
this.errorMessage = response?.error?.message;
}
});
} else {
console.log(response);
}
});
}

onOpenChangeOrganizationDialog() {
this.changeOrganizationDialog.open(ApplicationChangeOrganizationDialogComponent, {
data: {
applicationId: this.id,
organizationId: this.application.belongsTo.id,
} as ApplicationDialogModel,
});
}

bindApplication(id: number): void {
this.applicationsSubscription = this.applicationService.getApplication(id).subscribe(application => {
this.application = application;
this.cdr.detectChanges();
});
}

getDevices(): Observable<IotDevicesApplicationMapResponse[]> {
return this.restService.get(`application/${this.id}/iot-devices-map`).pipe(
map((data: IotDevicesApplicationMapResponse[]) => {
// For some reason, the backend is not capable to sort MQTT_EXTERNAL_BROKER and MQTT_INTERNAL_BROKER.
// Therefore we do it manually in the frontend.
return data;
})
);
}

ngOnDestroy() {
this.gatewaysSubscription.unsubscribe();
this.deviceSubscription?.unsubscribe();
if (this.applicationsSubscription) {
this.applicationsSubscription.unsubscribe();
}
}

private getGateways(): void {
this.gatewaysSubscription = this.chirpstackGatewayService
.getForMaps()
Expand All @@ -140,6 +192,10 @@ export class ApplicationDetailComponent implements OnInit, OnDestroy, AfterViewI
if (!dev.location) {
return;
}
const isActive = dev.latestSentMessage
? moment(dev.latestSentMessage).unix() > moment(new Date()).subtract(1, "day").unix()
: false;

tempCoordinateList.push({
longitude: dev.location.coordinates[0],
latitude: dev.location.coordinates[1],
Expand All @@ -148,9 +204,10 @@ export class ApplicationDetailComponent implements OnInit, OnDestroy, AfterViewI
useGeolocation: false,
markerInfo: {
name: dev.name,
active: dev.type,
active: isActive,
id: dev.id,
isDevice: true,
isGateway: false,
internalOrganizationId: this.sharedVariableService.getSelectedOrganisationId(),
networkTechnology: dev.type,
lastActive: dev.latestSentMessage,
Expand All @@ -174,6 +231,8 @@ export class ApplicationDetailComponent implements OnInit, OnDestroy, AfterViewI
name: gateway.name,
active: this.getGatewayStatus(gateway),
id: gateway.gatewayId,
isDevice: false,
isGateway: true,
internalOrganizationId: gateway.organizationId,
internalOrganizationName: gateway.organizationName,
},
Expand All @@ -185,55 +244,4 @@ export class ApplicationDetailComponent implements OnInit, OnDestroy, AfterViewI
private getGatewayStatus(gateway: Gateway): boolean {
return this.chirpstackGatewayService.isGatewayActive(gateway);
}

onDeleteApplication() {
this.deleteDialogService.showApplicationDialog(this.application).subscribe(response => {
if (response) {
this.applicationService.deleteApplication(this.application.id).subscribe(response => {
if (response.ok && response.body.affected > 0) {
console.log("delete application with id:" + this.application.id.toString());
this.router.navigate(["applications"]);
} else {
this.errorMessage = response?.error?.message;
}
});
} else {
console.log(response);
}
});
}

onOpenChangeOrganizationDialog() {
this.changeOrganizationDialog.open(ApplicationChangeOrganizationDialogComponent, {
data: {
applicationId: this.id,
organizationId: this.application.belongsTo.id,
} as ApplicationDialogModel,
});
}

bindApplication(id: number): void {
this.applicationsSubscription = this.applicationService.getApplication(id).subscribe(application => {
this.application = application;
this.cdr.detectChanges();
});
}

getDevices(): Observable<IotDevicesApplicationMapResponse[]> {
return this.restService.get(`application/${this.id}/iot-devices-map`).pipe(
map((data: IotDevicesApplicationMapResponse[]) => {
// For some reason, the backend is not capable to sort MQTT_EXTERNAL_BROKER and MQTT_INTERNAL_BROKER.
// Therefore we do it manually in the frontend.
return data;
})
);
}

ngOnDestroy() {
this.gatewaysSubscription.unsubscribe();
this.deviceSubscription?.unsubscribe();
if (this.applicationsSubscription) {
this.applicationsSubscription.unsubscribe();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
<div class="map-page">
@if(coordinateList){
<app-map [coordinateList]="coordinateList" [isFromApplication]="true"></app-map>
@if (coordinateList) {
<app-map [coordinateList]="coordinateList" [isFromApplication]="true"></app-map>
}
<mat-checkbox (change)="mapToCoordinateList()" [(ngModel)]="displayDevices">
Devices
</mat-checkbox>
<mat-checkbox (change)="mapToCoordinateList()" [(ngModel)]="displayGateways">
Gateways
</mat-checkbox>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
:host .map-page {
background-color: #ffffff;
padding: 20px;
padding-bottom: 40px;
height: 600px;
position: relative;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,24 @@ import { MapCoordinates } from "@shared/components/map/map-coordinates.model";
import { ChirpstackGatewayService } from "@shared/services/chirpstack-gateway.service";
import { SharedVariableService } from "@shared/shared-variable/shared-variable.service";
import { forkJoin, Subscription } from "rxjs";
import { SharedModule } from "../../../shared/shared.module";
import { SharedModule } from "@shared/shared.module";
import { ApplicationsFilterService } from "../application-filter/applications-filter.service";
import moment from "moment";
import { FormsModule } from "@angular/forms";

@Component({
selector: "app-application-map",
standalone: true,
imports: [MatCheckboxModule, SharedModule],
imports: [MatCheckboxModule, SharedModule, FormsModule],
templateUrl: "./application-map.component.html",
styleUrls: ["./application-map.component.scss"],
})
export class ApplicationMapComponent implements OnInit, OnDestroy {
public devices: IotDevice[] = [];
public gateways: Gateway[] = [];
public device: boolean = true;
public gateway: boolean = true;
public displayDevices: boolean = true;
public displayGateways: boolean = true;

filterValues: {
status: ApplicationStatus | "All";
statusCheck: ApplicationStatusCheck | "All";
Expand Down Expand Up @@ -55,22 +57,10 @@ export class ApplicationMapComponent implements OnInit, OnDestroy {
}
}

private loadMapData(): void {
forkJoin({
devices: this.applicationService.getApplicationDevices(this.sharedVariableService.getSelectedOrganisationId()),
gateways: this.gatewayService.getForMaps(),
}).subscribe(({ devices, gateways }) => {
this.devices = devices;
this.gateways = gateways.resultList;

this.mapToCoordinateList();
});
}

private mapToCoordinateList() {
public mapToCoordinateList() {
const tempCoordinateList: MapCoordinates[] = [];

if (Array.isArray(this.devices)) {
if (Array.isArray(this.devices) && this.displayDevices) {
this.devices.forEach(dev => {
const [longitude, latitude] = dev.location.coordinates;

Expand Down Expand Up @@ -99,7 +89,7 @@ export class ApplicationMapComponent implements OnInit, OnDestroy {
});
}

if (Array.isArray(this.gateways)) {
if (Array.isArray(this.gateways) && this.displayGateways) {
this.gateways.forEach(gw => {
tempCoordinateList.push({
longitude: gw.location.longitude,
Expand All @@ -124,4 +114,16 @@ export class ApplicationMapComponent implements OnInit, OnDestroy {

this.coordinateList = tempCoordinateList;
}

private loadMapData(): void {
forkJoin({
devices: this.applicationService.getApplicationDevices(this.sharedVariableService.getSelectedOrganisationId()),
gateways: this.gatewayService.getForMaps(),
}).subscribe(({ devices, gateways }) => {
this.devices = devices;
this.gateways = gateways.resultList;

this.mapToCoordinateList();
});
}
}
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
<div class="info-box-containers">
<app-basic-information-box
[matSVGSrc]="'exclamation-triangle'"
[type]="'warning'"
[count]="withError"
[countOf]="total"
[count]="withError"
[description]="'APPLICATION-INFORMATION-BOX.APPLICATIONS-WITH-ERROR' | translate"
[height]="35"
[matSVGSrc]="'exclamation-triangle'"
[type]="'warning'"
[width]="25"
/>
<app-basic-information-box
[matSVGSrc]="'check-circle'"
[type]="'stable'"
[count]="withoutError"
[countOf]="total"
[count]="withoutError"
[description]="'APPLICATION-INFORMATION-BOX.APPLICATIONS-WITHOUT-ERROR' | translate"
[height]="30"
[matSVGSrc]="'check-circle'"
[type]="'stable'"
[width]="25"
/>
<app-basic-information-box
[count]="totalDevices"
[description]="'APPLICATION-INFORMATION-BOX.DEVICES' | translate"
[height]="35"
[width]="25"
[matSVGSrc]="'micro-chip'"
[type]="'default'"
[count]="totalDevices"
[description]="'APPLICATION-INFORMATION-BOX.DEVICES' | translate"
[width]="25"
/>
<app-basic-information-box
[count]="totalGateways"
[description]="'APPLICATION-INFORMATION-BOX.GATEWAYS' | translate"
[height]="35"
[width]="25"
[matSVGSrc]="'satellite-dish'"
[type]="'default'"
[count]="totalGateways"
[description]="'APPLICATION-INFORMATION-BOX.GATEWAYS' | translate"
[width]="25"
/>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
gap: 30px;
margin-bottom: 30px;
height: fit-content;
flex-wrap: wrap;
}
Loading