diff --git a/src/app/admin/permission/permission-edit/permission-edit.component.ts b/src/app/admin/permission/permission-edit/permission-edit.component.ts
index 180d85f0d..ed0d4a864 100644
--- a/src/app/admin/permission/permission-edit/permission-edit.component.ts
+++ b/src/app/admin/permission/permission-edit/permission-edit.component.ts
@@ -6,7 +6,11 @@ import { TranslateService } from '@ngx-translate/core';
import { ReplaySubject, Subject, Subscription } from 'rxjs';
import { Location } from '@angular/common';
import { PermissionService } from '../permission.service';
-import { PermissionRequest, PermissionType, PermissionTypes } from '../permission.model';
+import {
+ PermissionRequest,
+ PermissionType,
+ PermissionTypes,
+} from '../permission.model';
import { OrganisationResponse } from '../../organisation/organisation.model';
import { OrganisationService } from '../../organisation/organisation.service';
import { UserService } from '../../users/user.service';
@@ -80,8 +84,7 @@ export class PermissionEditComponent implements OnInit, OnDestroy {
private location: Location,
private errormEssageService: ErrorMessageService,
private meService: MeService
- ) {
- }
+ ) {}
ngOnInit(): void {
this.getOrganizations();
@@ -167,7 +170,7 @@ export class PermissionEditComponent implements OnInit, OnDestroy {
private getOrganizations() {
this.organisationSubscription = this.organisationService
- .getMultiple()
+ .getMultiple(1000, 0, 'name', 'asc')
.subscribe(
(orgs) => {
this.organisations = orgs.data;
@@ -179,15 +182,17 @@ export class PermissionEditComponent implements OnInit, OnDestroy {
}
private getUsers() {
- this.userSubscription = this.userService.getMultiple().subscribe(
- (users) => {
- this.users = users.data;
- this.filteredUsersMulti.next(this.users.slice());
- },
- (error: HttpErrorResponse) => {
- this.showError(error);
- }
- );
+ this.userSubscription = this.userService
+ .getMultiple(1000, 0, 'name', 'asc')
+ .subscribe(
+ (users) => {
+ this.users = users.data;
+ this.filteredUsersMulti.next(this.users.slice());
+ },
+ (error: HttpErrorResponse) => {
+ this.showError(error);
+ }
+ );
}
public compare(o1: any, o2: any): boolean {
@@ -207,7 +212,9 @@ export class PermissionEditComponent implements OnInit, OnDestroy {
.getApplicationsByOrganizationId(organizationId)
.subscribe(
(res) => {
- this.applications = res.data;
+ this.applications = res.data.sort((a, b) =>
+ a.name.localeCompare(b.name, 'en', { numeric: true })
+ );
this.filteredApplicationsMulti.next(this.applications.slice());
},
(error: HttpErrorResponse) => {
@@ -251,7 +258,6 @@ export class PermissionEditComponent implements OnInit, OnDestroy {
);
this.applicationMultiCtrl.setValue(this.permission.applicationIds);
}
-
},
(error: HttpErrorResponse) => {
this.showError(error);
diff --git a/src/app/admin/users/user-list/awaiting-users-table/awaiting-users-table.component.html b/src/app/admin/users/user-list/awaiting-users-table/awaiting-users-table.component.html
index 35f0e2638..88817e562 100644
--- a/src/app/admin/users/user-list/awaiting-users-table/awaiting-users-table.component.html
+++ b/src/app/admin/users/user-list/awaiting-users-table/awaiting-users-table.component.html
@@ -9,7 +9,7 @@
mat-table
[dataSource]="users"
matSort
- matSortActive="id"
+ matSortActive="name"
matSortDirection="asc"
matSortDisableClear
>
diff --git a/src/app/admin/users/user-list/user-table/user-table.component.html b/src/app/admin/users/user-list/user-table/user-table.component.html
index d729f65e0..56fe30c4f 100644
--- a/src/app/admin/users/user-list/user-table/user-table.component.html
+++ b/src/app/admin/users/user-list/user-table/user-table.component.html
@@ -2,7 +2,7 @@
-
+
diff --git a/src/app/admin/users/user-list/user-table/user-table.component.ts b/src/app/admin/users/user-list/user-table/user-table.component.ts
index baac24d7e..547f8c6cd 100644
--- a/src/app/admin/users/user-list/user-table/user-table.component.ts
+++ b/src/app/admin/users/user-list/user-table/user-table.component.ts
@@ -1,117 +1,111 @@
-import {
- AfterViewInit,
- Component,
- Input,
- ViewChild,
-} from '@angular/core';
-import { MatPaginator } from '@angular/material/paginator';
-import { MatSort } from '@angular/material/sort';
-import { TranslateService } from '@ngx-translate/core';
-import { startWith, switchMap, map, catchError } from 'rxjs/operators';
-import { UserGetManyResponse, UserResponse } from '../../user.model';
-import { UserService } from '../../user.service';
-import { merge, Observable, of as observableOf } from 'rxjs';
-import { environment } from '@environments/environment';
-import { DefaultPageSizeOptions } from '@shared/constants/page.constants';
-import { ActivatedRoute } from '@angular/router';
-import { MeService } from '@shared/services/me.service';
-
-@Component({
- selector: 'app-user-table',
- templateUrl: './user-table.component.html',
- styleUrls: ['./user-table.component.scss'],
-})
-export class UserTableComponent implements AfterViewInit {
- displayedColumns: string[] = [
- 'name',
- 'email',
- 'global',
- 'status',
- 'lastLogin',
- 'menu',
- ];
- data: UserResponse[];
-
- public pageSize = environment.tablePageSize;
- pageSizeOptions = DefaultPageSizeOptions;
- resultsLength = 0;
- isLoadingResults = true;
- @ViewChild(MatPaginator) paginator: MatPaginator;
- @ViewChild(MatSort) sort: MatSort;
-
- // If supplied, users will only be retrieved for the specified organization
- // If supplied, permissionId will ignored, even if supplied
- @Input() organizationId?: number;
-
- // If supplied, users will be retrieved on the permissionId (userGroup/brugerGruppe)
- @Input() permissionId?: number;
-
- @Input() canSort = true;
- isGlobalAdmin: boolean;
-
- constructor(
- public translate: TranslateService,
- private userService: UserService,
- private meService: MeService
- ) {
- this.isGlobalAdmin = this.meService.hasGlobalAdmin();
- }
-
- getUsers(
- orderByColumn: string,
- orderByDirection: string
- ): Observable {
- if (this.organizationId !== null && this.organizationId !== undefined) {
- if (this.isGlobalAdmin) {
- return this.userService.getMultiple(
- this.paginator.pageSize,
- this.paginator.pageIndex * this.paginator.pageSize,
- orderByColumn,
- orderByDirection
- );
- } else {
- return this.userService.getMultipleByOrganization(
- this.paginator.pageSize,
- this.paginator.pageIndex * this.paginator.pageSize,
- orderByColumn,
- orderByDirection,
- this.organizationId
- );
- }
- } else {
- return this.userService.getMultiple(
- this.paginator.pageSize,
- this.paginator.pageIndex * this.paginator.pageSize,
- orderByColumn,
- orderByDirection,
- this.permissionId
- );
- }
- }
-
- ngAfterViewInit() {
- // If the user changes the sort order, reset back to the first page.
- this.sort.sortChange.subscribe(() => (this.paginator.pageIndex = 0));
-
- merge(this.sort.sortChange, this.paginator.page)
- .pipe(
- startWith({}),
- switchMap(() => {
- this.isLoadingResults = true;
- return this.getUsers(this.sort.active, this.sort.direction);
- }),
- map((data) => {
- // Flip flag to show that loading has finished.
- this.isLoadingResults = false;
- this.resultsLength = data.count;
-
- return data.data;
- }),
- catchError(() => {
- this.isLoadingResults = false;
- return observableOf([]);
- })
- )
- .subscribe((data) => (this.data = data));
- }
-}
+import { AfterViewInit, Component, Input, ViewChild } from '@angular/core';
+import { MatPaginator } from '@angular/material/paginator';
+import { MatSort } from '@angular/material/sort';
+import { TranslateService } from '@ngx-translate/core';
+import { catchError, map, startWith, switchMap } from 'rxjs/operators';
+import { UserGetManyResponse, UserResponse } from '../../user.model';
+import { UserService } from '../../user.service';
+import { merge, Observable, of as observableOf } from 'rxjs';
+import { environment } from '@environments/environment';
+import { DefaultPageSizeOptions } from '@shared/constants/page.constants';
+import { MeService } from '@shared/services/me.service';
+
+@Component({
+ selector: 'app-user-table',
+ templateUrl: './user-table.component.html',
+ styleUrls: ['./user-table.component.scss'],
+})
+export class UserTableComponent implements AfterViewInit {
+ displayedColumns: string[] = [
+ 'name',
+ 'email',
+ 'global',
+ 'status',
+ 'lastLogin',
+ 'menu',
+ ];
+ data: UserResponse[];
+
+ public pageSize = environment.tablePageSize;
+ pageSizeOptions = DefaultPageSizeOptions;
+ resultsLength = 0;
+ isLoadingResults = true;
+ @ViewChild(MatPaginator) paginator: MatPaginator;
+ @ViewChild(MatSort) sort: MatSort;
+
+ // If supplied, users will only be retrieved for the specified organization
+ // If supplied, permissionId will ignored, even if supplied
+ @Input() organizationId?: number;
+
+ // If supplied, users will be retrieved on the permissionId (userGroup/brugerGruppe)
+ @Input() permissionId?: number;
+
+ @Input() canSort = true;
+ isGlobalAdmin: boolean;
+
+ constructor(
+ public translate: TranslateService,
+ private userService: UserService,
+ private meService: MeService
+ ) {
+ this.isGlobalAdmin = this.meService.hasGlobalAdmin();
+ }
+
+ getUsers(
+ orderByColumn: string,
+ orderByDirection: string
+ ): Observable {
+ if (this.organizationId !== null && this.organizationId !== undefined) {
+ if (this.isGlobalAdmin) {
+ return this.userService.getMultiple(
+ this.paginator.pageSize,
+ this.paginator.pageIndex * this.paginator.pageSize,
+ orderByColumn,
+ orderByDirection
+ );
+ } else {
+ return this.userService.getMultipleByOrganization(
+ this.paginator.pageSize,
+ this.paginator.pageIndex * this.paginator.pageSize,
+ orderByColumn,
+ orderByDirection,
+ this.organizationId
+ );
+ }
+ } else {
+ return this.userService.getMultiple(
+ this.paginator.pageSize,
+ this.paginator.pageIndex * this.paginator.pageSize,
+ orderByColumn,
+ orderByDirection,
+ this.permissionId
+ );
+ }
+ }
+
+ ngAfterViewInit() {
+ // If the user changes the sort order, reset back to the first page.
+ this.sort.sortChange.subscribe(() => (this.paginator.pageIndex = 0));
+
+ merge(this.sort.sortChange, this.paginator.page)
+ .pipe(
+ startWith({}),
+ switchMap(() => {
+ this.isLoadingResults = true;
+ return this.getUsers(this.sort.active, this.sort.direction);
+ }),
+ map((data) => {
+ // Flip flag to show that loading has finished.
+ this.isLoadingResults = false;
+ this.resultsLength = data.count;
+
+ return data.data;
+ }),
+ catchError(() => {
+ this.isLoadingResults = false;
+ return observableOf([]);
+ })
+ )
+ .subscribe((data) => (this.data = data));
+ }
+}
diff --git a/src/app/applications/datatarget/datatarget-edit/datatarget-edit.component.ts b/src/app/applications/datatarget/datatarget-edit/datatarget-edit.component.ts
index 432a5e2b4..e73d1aab3 100644
--- a/src/app/applications/datatarget/datatarget-edit/datatarget-edit.component.ts
+++ b/src/app/applications/datatarget/datatarget-edit/datatarget-edit.component.ts
@@ -1,4 +1,11 @@
-import { AfterViewInit, Component, ComponentFactoryResolver, OnDestroy, OnInit, QueryList, Type, ViewChild, ViewChildren } from '@angular/core';
+import {
+ Component,
+ ComponentFactoryResolver,
+ OnDestroy,
+ OnInit,
+ Type,
+ ViewChild,
+} from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { DataTargetType } from '@shared/enums/datatarget-type';
import { DatatargetTypesService } from '../datatarget-types.service';
@@ -10,60 +17,68 @@ import { DatatargetEditTypeSelectorDirective } from './datatarget-edit-type-sele
@Component({
selector: 'app-datatarget-edit',
templateUrl: './datatarget-edit.component.html',
- styleUrls: ['./datatarget-edit.component.scss']
+ styleUrls: ['./datatarget-edit.component.scss'],
})
export class DatatargetEditComponent implements OnInit, OnDestroy {
-
- @ViewChild(DatatargetEditTypeSelectorDirective, {static: true}) adHost!: DatatargetEditTypeSelectorDirective;
+ @ViewChild(DatatargetEditTypeSelectorDirective, { static: true })
+ adHost!: DatatargetEditTypeSelectorDirective;
public datatarget: Datatarget;
private datatargetType: DataTargetType;
- constructor(private componentFactoryResolver: ComponentFactoryResolver,
- private datatargetService: DatatargetService,
- private route: ActivatedRoute,
- private datatargetTypesService: DatatargetTypesService
- ) { }
-
+ constructor(
+ private componentFactoryResolver: ComponentFactoryResolver,
+ private datatargetService: DatatargetService,
+ private route: ActivatedRoute,
+ private datatargetTypesService: DatatargetTypesService
+ ) {}
loadComponent(componentType: Type) {
- const viewContainerRef = this.adHost.viewContainerRef;
- viewContainerRef.clear();
- const factory = this.componentFactoryResolver.resolveComponentFactory(componentType);
- viewContainerRef.createComponent(factory);
+ const viewContainerRef = this.adHost.viewContainerRef;
+ viewContainerRef.clear();
+ const factory = this.componentFactoryResolver.resolveComponentFactory(
+ componentType
+ );
+ viewContainerRef.createComponent(factory);
}
ngOnInit(): void {
+ const id: number = +this.route.snapshot.paramMap.get('datatargetId');
- const id: number = +this.route.snapshot.paramMap.get('datatargetId');
-
- if (id > 0) {
- this.datatargetService.get(id)
- .subscribe((dataTarget: Datatarget) => {
- this.datatarget = dataTarget;
- this.datatargetType = dataTarget.type;
- const component = this.datatargetTypesService.getEditComponent(this.datatargetType);
- this.loadComponent(component);
- });
- } else {
- let datatargetTypeParam = this.route.snapshot.paramMap.get('datatargetType');
- this.datatargetType = this.enumFromStringValue(DataTargetType, datatargetTypeParam);
- if (this.datatargetType) {
- const component = this.datatargetTypesService.getEditComponent(this.datatargetType);
- this.loadComponent(component);
- }
+ if (id > 0) {
+ this.datatargetService.get(id).subscribe((dataTarget: Datatarget) => {
+ this.datatarget = dataTarget;
+ this.datatargetType = dataTarget.type;
+ const component = this.datatargetTypesService.getEditComponent(
+ this.datatargetType
+ );
+ this.loadComponent(component);
+ });
+ } else {
+ let datatargetTypeParam = this.route.snapshot.paramMap.get(
+ 'datatargetType'
+ );
+ this.datatargetType = this.enumFromStringValue(
+ DataTargetType,
+ datatargetTypeParam
+ );
+ if (this.datatargetType) {
+ const component = this.datatargetTypesService.getEditComponent(
+ this.datatargetType
+ );
+ this.loadComponent(component);
}
-
-
+ }
}
- enumFromStringValue(enm: { [s: string]: T}, value: string): T | undefined {
- return (Object.values(enm) as unknown as string[]).includes(value)
- ? value as unknown as T
+ enumFromStringValue(
+ enm: { [s: string]: T },
+ value: string
+ ): T | undefined {
+ return ((Object.values(enm) as unknown) as string[]).includes(value)
+ ? ((value as unknown) as T)
: undefined;
}
- ngOnDestroy() {
-
- }
+ ngOnDestroy() {}
}
diff --git a/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.ts b/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.ts
index 92567fe66..afc7d21c9 100644
--- a/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.ts
+++ b/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.ts
@@ -6,7 +6,10 @@ import { Observable, Subscription } from 'rxjs';
import { Application } from '@applications/application.model';
import { IotDevice } from '@applications/iot-devices/iot-device.model';
import { faTimesCircle } from '@fortawesome/free-solid-svg-icons';
-import { PayloadDeviceDatatarget, PayloadDeviceDatatargetGetByDataTargetResponse } from '@payload-decoder/payload-device-data.model';
+import {
+ PayloadDeviceDatatarget,
+ PayloadDeviceDatatargetGetByDataTargetResponse,
+} from '@payload-decoder/payload-device-data.model';
import { DatatargetService } from '../../datatarget.service';
import { ApplicationService } from '@applications/application.service';
import { PayloadDecoderService } from '@payload-decoder/payload-decoder.service';
@@ -27,11 +30,9 @@ import { OrganizationAccessScope } from '@shared/enums/access-scopes';
@Component({
selector: 'app-fiware-edit',
templateUrl: './fiware-edit.component.html',
- styleUrls: ['./fiware-edit.component.scss']
+ styleUrls: ['./fiware-edit.component.scss'],
})
export class FiwareEditComponent implements DatatargetEdit, OnInit, OnDestroy {
-
-
public multiPage = false;
public title = '';
public sectionTitle = '';
@@ -69,13 +70,11 @@ export class FiwareEditComponent implements DatatargetEdit, OnInit, OnDestroy {
private dialog: MatDialog,
private errorMessageService: ErrorMessageService,
private scrollToTopService: ScrollToTopService,
- private meService: MeService,
+ private meService: MeService
) {
translate.use('da');
}
-
-
ngOnInit() {
this.translate
.get([
@@ -108,15 +107,21 @@ export class FiwareEditComponent implements DatatargetEdit, OnInit, OnDestroy {
this.getDevices();
}
this.getPayloadDecoders();
- this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.ApplicationWrite);
+ this.canEdit = this.meService.hasAccessToTargetOrganization(
+ OrganizationAccessScope.ApplicationWrite
+ );
}
-
addRow() {
if (!this.payloadDeviceDatatarget) {
this.payloadDeviceDatatarget = [];
}
- this.payloadDeviceDatatarget.push({ id: null, iotDeviceIds: [], payloadDecoderId: null, dataTargetId: this.datatargetid });
+ this.payloadDeviceDatatarget.push({
+ id: null,
+ iotDeviceIds: [],
+ payloadDecoderId: null,
+ dataTargetId: this.datatargetid,
+ });
}
private deleteRow(index) {
@@ -124,7 +129,8 @@ export class FiwareEditComponent implements DatatargetEdit, OnInit, OnDestroy {
} else if (this.payloadDeviceDatatarget[index]?.id === null) {
this.payloadDeviceDatatarget.splice(index, 1);
} else {
- this.payloadDeviceDataTargetService.delete(this.payloadDeviceDatatarget[index].id)
+ this.payloadDeviceDataTargetService
+ .delete(this.payloadDeviceDatatarget[index].id)
.subscribe((response) => {
this.payloadDeviceDatatarget.splice(index, 1);
});
@@ -136,8 +142,8 @@ export class FiwareEditComponent implements DatatargetEdit, OnInit, OnDestroy {
data: {
showAccept: true,
showCancel: true,
- message: 'Er du sikker på at du vil slette?'
- }
+ message: 'Er du sikker på at du vil slette?',
+ },
});
dialog.afterClosed().subscribe((result) => {
@@ -163,28 +169,29 @@ export class FiwareEditComponent implements DatatargetEdit, OnInit, OnDestroy {
updateDatatarget() {
this.resetErrors();
- this.counter = 1 + (this.payloadDeviceDatatarget?.length ? this.payloadDeviceDatatarget?.length : 0);
- this.datatargetService.update(this.datatarget)
- .subscribe(
- (response: Datatarget) => {
- this.datatarget = response;
- this.countToRedirect();
- },
- (error: HttpErrorResponse) => {
- this.handleError(error);
- this.formFailedSubmit = true;
- }
- );
+ this.counter =
+ 1 +
+ (this.payloadDeviceDatatarget?.length
+ ? this.payloadDeviceDatatarget?.length
+ : 0);
+ this.datatargetService.update(this.datatarget).subscribe(
+ (response: Datatarget) => {
+ this.datatarget = response;
+ this.countToRedirect();
+ },
+ (error: HttpErrorResponse) => {
+ this.handleError(error);
+ this.formFailedSubmit = true;
+ }
+ );
}
addPayloadDeviceDatatarget() {
- this.payloadDeviceDatatarget.map(
- pdd => {
- if (pdd.payloadDecoderId === 0) {
- pdd.payloadDecoderId = null;
- }
+ this.payloadDeviceDatatarget.map((pdd) => {
+ if (pdd.payloadDecoderId === 0) {
+ pdd.payloadDecoderId = null;
}
- );
+ });
this.payloadDeviceDatatarget.forEach((relation) => {
if (relation.id) {
this.payloadDeviceDataTargetService.put(relation).subscribe(
@@ -227,17 +234,17 @@ export class FiwareEditComponent implements DatatargetEdit, OnInit, OnDestroy {
createDatatarget() {
this.resetErrors();
this.datatarget.applicationId = this.applicationId;
- this.datatargetService.create(this.datatarget)
- .subscribe((response: Datatarget) => {
+ this.datatargetService.create(this.datatarget).subscribe(
+ (response: Datatarget) => {
this.datatargetid = response.id;
this.datatarget = response;
this.showSavedSnack();
},
- (error: HttpErrorResponse) => {
- this.handleError(error);
- this.formFailedSubmit = true;
- });
-
+ (error: HttpErrorResponse) => {
+ this.handleError(error);
+ this.formFailedSubmit = true;
+ }
+ );
}
private resetErrors() {
@@ -246,17 +253,20 @@ export class FiwareEditComponent implements DatatargetEdit, OnInit, OnDestroy {
this.formFailedSubmit = false;
}
-
-
getDevices(): void {
- this.applicationSubscription = this.applicationService.getApplication(this.applicationId)
+ this.applicationSubscription = this.applicationService
+ .getApplication(this.applicationId)
.subscribe((application: Application) => {
- this.devices = application.iotDevices;
+ this.devices = application.iotDevices.sort((a, b) =>
+ a.name.localeCompare(b.name, 'en', { numeric: true })
+ );
});
}
public selectAllDevices(index: number) {
- this.payloadDeviceDatatarget[index].iotDeviceIds = this.devices.map(device => device.id);
+ this.payloadDeviceDatatarget[index].iotDeviceIds = this.devices.map(
+ (device) => device.id
+ );
}
public deSelectAllDevices(index: number) {
@@ -264,9 +274,12 @@ export class FiwareEditComponent implements DatatargetEdit, OnInit, OnDestroy {
}
getPayloadDecoders() {
- this.payloadDecoderSubscription = this.payloadDecoderService.getMultiple(1000, 0, 'id', 'ASC')
+ this.payloadDecoderSubscription = this.payloadDecoderService
+ .getMultiple(1000, 0, 'id', 'ASC')
.subscribe((response: PayloadDecoderMappedResponse) => {
- this.payloadDecoders = response.data;
+ this.payloadDecoders = response.data.sort((a, b) =>
+ a.name.localeCompare(b.name, 'en', { numeric: true })
+ );
});
}
@@ -283,10 +296,7 @@ export class FiwareEditComponent implements DatatargetEdit, OnInit, OnDestroy {
onCoordinateKey(event: any) {
if (event.target.value.length > event.target.maxLength) {
- event.target.value = event.target.value.slice(
- 0,
- event.target.maxLength
- );
+ event.target.value = event.target.value.slice(0, event.target.maxLength);
}
}
@@ -323,17 +333,20 @@ export class FiwareEditComponent implements DatatargetEdit, OnInit, OnDestroy {
}
}
- private mapToDatatargetDevicePayload(dto: PayloadDeviceDatatargetGetByDataTargetResponse) {
+ private mapToDatatargetDevicePayload(
+ dto: PayloadDeviceDatatargetGetByDataTargetResponse
+ ) {
this.payloadDeviceDatatarget = [];
- dto.data.forEach(
- (element) => {
- this.payloadDeviceDatatarget.push({
- id: element.id,
- iotDeviceIds: element.iotDevices.map((x) => x.id),
- payloadDecoderId: element.payloadDecoder?.id === undefined ? 0 : element.payloadDecoder?.id,
- dataTargetId: element.dataTarget.id
- });
- }
- );
+ dto.data.forEach((element) => {
+ this.payloadDeviceDatatarget.push({
+ id: element.id,
+ iotDeviceIds: element.iotDevices.map((x) => x.id),
+ payloadDecoderId:
+ element.payloadDecoder?.id === undefined
+ ? 0
+ : element.payloadDecoder?.id,
+ dataTargetId: element.dataTarget.id,
+ });
+ });
}
}
diff --git a/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.ts b/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.ts
index c68dc4304..0ee5bac9a 100644
--- a/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.ts
+++ b/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.ts
@@ -78,7 +78,7 @@ export class HttppushEditComponent
private opendatadkService: OpendatadkService,
private opendatadkDialogService: OpendatadkDialogService,
private scrollToTopService: ScrollToTopService,
- private meService: MeService,
+ private meService: MeService
) {
translate.use('da');
}
@@ -114,7 +114,11 @@ export class HttppushEditComponent
}
this.getPayloadDecoders();
this.setDataSetExcists();
- this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.ApplicationWrite, undefined, this.applicationId);
+ this.canEdit = this.meService.hasAccessToTargetOrganization(
+ OrganizationAccessScope.ApplicationWrite,
+ undefined,
+ this.applicationId
+ );
}
addRow() {
@@ -279,7 +283,9 @@ export class HttppushEditComponent
this.applicationSubscription = this.applicationService
.getApplication(this.applicationId)
.subscribe((application: Application) => {
- this.devices = application.iotDevices;
+ this.devices = application.iotDevices.sort((a, b) =>
+ a.name.localeCompare(b.name, 'en', { numeric: true })
+ );
});
}
@@ -297,7 +303,9 @@ export class HttppushEditComponent
this.payloadDecoderSubscription = this.payloadDecoderService
.getMultiple(1000, 0, 'id', 'ASC')
.subscribe((response: PayloadDecoderMappedResponse) => {
- this.payloadDecoders = response.data;
+ this.payloadDecoders = response.data.sort((a, b) =>
+ a.name.localeCompare(b.name, 'en', { numeric: true })
+ );
});
}
diff --git a/src/app/applications/datatarget/mqtt-edit/mqtt-edit.component.ts b/src/app/applications/datatarget/mqtt-edit/mqtt-edit.component.ts
index 7d3e8f62d..512ab6e10 100644
--- a/src/app/applications/datatarget/mqtt-edit/mqtt-edit.component.ts
+++ b/src/app/applications/datatarget/mqtt-edit/mqtt-edit.component.ts
@@ -86,7 +86,9 @@ export class MqttEditComponent implements DatatargetEdit, OnInit, OnDestroy {
this.payloadDecoderSubscription = this.payloadDecoderService
.getMultiple(1000, 0, 'id', 'ASC')
.subscribe((response: PayloadDecoderMappedResponse) => {
- this.payloadDecoders = response.data;
+ this.payloadDecoders = response.data.sort((a, b) =>
+ a.name.localeCompare(b.name, 'en', { numeric: true })
+ );
});
}
@@ -113,7 +115,9 @@ export class MqttEditComponent implements DatatargetEdit, OnInit, OnDestroy {
this.applicationSubscription = this.applicationService
.getApplication(this.applicationId)
.subscribe((application: Application) => {
- this.devices = application.iotDevices;
+ this.devices = application.iotDevices.sort((a, b) =>
+ a.name.localeCompare(b.name, 'en', { numeric: true })
+ );
});
}
diff --git a/src/app/applications/iot-devices/iot-device-edit/iot-device-edit.component.ts b/src/app/applications/iot-devices/iot-device-edit/iot-device-edit.component.ts
index c1458f336..f39d2af56 100644
--- a/src/app/applications/iot-devices/iot-device-edit/iot-device-edit.component.ts
+++ b/src/app/applications/iot-devices/iot-device-edit/iot-device-edit.component.ts
@@ -10,7 +10,10 @@ import { DeviceModel } from '@app/device-model/device.model';
import { TranslateService } from '@ngx-translate/core';
import { DeviceProfile } from '@profiles/device-profiles/device-profile.model';
import { DeviceProfileService } from '@profiles/device-profiles/device-profile.service';
-import { ServiceProfile, ServiceProfileResponseMany } from '@profiles/service-profiles/service-profile.model';
+import {
+ ServiceProfile,
+ ServiceProfileResponseMany,
+} from '@profiles/service-profiles/service-profile.model';
import { ServiceProfileService } from '@profiles/service-profiles/service-profile.service';
import { ActivationType } from '@shared/enums/activation-type';
import { DeviceType } from '@shared/enums/device-type';
@@ -25,345 +28,359 @@ import { IoTDeviceService } from '../iot-device.service';
import { MeService } from '@shared/services/me.service';
import { OrganizationAccessScope } from '@shared/enums/access-scopes';
-
@Component({
- selector: 'app-iot-device-edit',
- templateUrl: './iot-device-edit.component.html',
- styleUrls: ['./iot-device-edit.component.scss'],
+ selector: 'app-iot-device-edit',
+ templateUrl: './iot-device-edit.component.html',
+ styleUrls: ['./iot-device-edit.component.scss'],
})
export class IotDeviceEditComponent implements OnInit, OnDestroy {
- public errorMessages: any;
- public errorFields: string[];
- public formFailedSubmit = false;
- public application: Application;
- private deviceId: number;
- public disableChoseApplication = true;
- public loraDevice = DeviceType.LORAWAN;
- public sigfoxDevice = DeviceType.SIGFOX;
- public serviceProfiles: ServiceProfile[];
- public deviceProfiles: DeviceProfile[];
- public deviceModels: DeviceModel[];
- iotDevice = new IotDevice();
- editmode = false;
- public OTAA = true;
- metadataTags: {key?: string, value?: string}[] = [];
- errorMetadataFieldId: string | undefined;
-
- public deviceSubscription: Subscription;
- private applicationsSubscription: Subscription;
- private serviceProfilesSubscription: Subscription;
- private deviceProfileSubscription: Subscription;
- private devicesProfileSubscription: Subscription;
+ public errorMessages: any;
+ public errorFields: string[];
+ public formFailedSubmit = false;
+ public application: Application;
+ private deviceId: number;
+ public disableChoseApplication = true;
+ public loraDevice = DeviceType.LORAWAN;
+ public sigfoxDevice = DeviceType.SIGFOX;
+ public serviceProfiles: ServiceProfile[];
+ public deviceProfiles: DeviceProfile[];
+ public deviceModels: DeviceModel[];
+ iotDevice = new IotDevice();
+ editmode = false;
+ public OTAA = true;
+ metadataTags: { key?: string; value?: string }[] = [];
+ errorMetadataFieldId: string | undefined;
+
+ public deviceSubscription: Subscription;
+ private applicationsSubscription: Subscription;
+ private serviceProfilesSubscription: Subscription;
+ private deviceProfileSubscription: Subscription;
+ private devicesProfileSubscription: Subscription;
canEdit: boolean;
- constructor(
- private route: ActivatedRoute,
- public translate: TranslateService,
- private router: Router,
- private serviceProfileService: ServiceProfileService,
- private deviceProfileService: DeviceProfileService,
- private applicationService: ApplicationService,
- private iotDeviceService: IoTDeviceService,
- private location: Location,
- private shareVariable: SharedVariableService,
- private deviceModelService: DeviceModelService,
- private errorMessageService: ErrorMessageService,
- private scrollToTopService: ScrollToTopService,
- private titleService: Title,
- private meService: MeService
- ) { }
-
- ngOnInit(): void {
- this.translate.use('da');
- this.iotDevice.applicationId = +this.route.snapshot.paramMap.get('id');
- this.deviceId = +this.route.snapshot.paramMap.get('deviceId');
-
- if (this.iotDevice.applicationId && this.deviceId) {
- this.editmode = true;
- this.getDevice(this.deviceId);
- this.disableChoseApplication = false;
- }
-
- this.translate.get(['TITLE.IOTDEVICE'])
- .subscribe(translations => {
- this.titleService.setTitle(translations['TITLE.IOTDEVICE']);
- });
-
- this.getApplication();
- this.getServiceProfiles();
- this.getDeviceProfiles();
- this.getDeviceModels();
- this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.ApplicationWrite, undefined, this.iotDevice.applicationId);
+ constructor(
+ private route: ActivatedRoute,
+ public translate: TranslateService,
+ private router: Router,
+ private serviceProfileService: ServiceProfileService,
+ private deviceProfileService: DeviceProfileService,
+ private applicationService: ApplicationService,
+ private iotDeviceService: IoTDeviceService,
+ private location: Location,
+ private shareVariable: SharedVariableService,
+ private deviceModelService: DeviceModelService,
+ private errorMessageService: ErrorMessageService,
+ private scrollToTopService: ScrollToTopService,
+ private titleService: Title,
+ private meService: MeService
+ ) {}
+
+ ngOnInit(): void {
+ this.translate.use('da');
+ this.iotDevice.applicationId = +this.route.snapshot.paramMap.get('id');
+ this.deviceId = +this.route.snapshot.paramMap.get('deviceId');
+
+ if (this.iotDevice.applicationId && this.deviceId) {
+ this.editmode = true;
+ this.getDevice(this.deviceId);
+ this.disableChoseApplication = false;
}
- public compare(o1: any, o2: any): boolean {
- return o1 === o2;
- }
-
- getDeviceModels() {
- this.deviceModelService.getMultiple(
- 1000,
- 0,
- 'id',
- 'ASC',
- this.shareVariable.getSelectedOrganisationId()
- ).subscribe(
- (response) => {
- this.deviceModels = response.data;
- }
+ this.translate.get(['TITLE.IOTDEVICE']).subscribe((translations) => {
+ this.titleService.setTitle(translations['TITLE.IOTDEVICE']);
+ });
+
+ this.getApplication();
+ this.getServiceProfiles();
+ this.getDeviceProfiles();
+ this.getDeviceModels();
+ this.canEdit = this.meService.hasAccessToTargetOrganization(
+ OrganizationAccessScope.ApplicationWrite,
+ undefined,
+ this.iotDevice.applicationId
+ );
+ }
+
+ public compare(o1: any, o2: any): boolean {
+ return o1 === o2;
+ }
+
+ getDeviceModels() {
+ this.deviceModelService
+ .getMultiple(
+ 1000,
+ 0,
+ 'id',
+ 'ASC',
+ this.shareVariable.getSelectedOrganisationId()
+ )
+ .subscribe((response) => {
+ this.deviceModels = response.data.sort((a, b) =>
+ a.body.name.localeCompare(b.body.name, 'en', { numeric: true })
);
- }
-
- getApplication(): void {
- this.applicationsSubscription = this.applicationService
- .getApplication(this.iotDevice.applicationId)
- .subscribe((application: Application) => {
- this.application = application;
- });
- }
-
- getDevice(id: number): void {
- this.deviceSubscription = this.iotDeviceService
- .getIoTDevice(id)
- .subscribe((device: IotDevice) => {
- this.iotDevice = device;
- if (this.iotDevice?.application?.id) {
- this.iotDevice.applicationId = device.application?.id;
- }
- if (device.location) {
- this.iotDevice.longitude = device.location.coordinates[0];
- this.iotDevice.latitude = device.location.coordinates[1];
- }
- this.OTAA = this.iotDevice.lorawanSettings?.OTAAapplicationKey ? true : false;
- if (device.sigfoxSettings) {
- }
- if (!device.deviceModelId || device.deviceModelId === null) {
- this.iotDevice.deviceModelId = 0;
- }
- if (device.metadata) {
- this.metadataTags = jsonToList(device.metadata);
- }
- });
- }
+ });
+ }
- onChangeDeviceProfile(deviceProfileId: string) {
- this.getDeviceProfile(deviceProfileId);
- }
+ getApplication(): void {
+ this.applicationsSubscription = this.applicationService
+ .getApplication(this.iotDevice.applicationId)
+ .subscribe((application: Application) => {
+ this.application = application;
+ });
+ }
+
+ getDevice(id: number): void {
+ this.deviceSubscription = this.iotDeviceService
+ .getIoTDevice(id)
+ .subscribe((device: IotDevice) => {
+ this.iotDevice = device;
+ if (this.iotDevice?.application?.id) {
+ this.iotDevice.applicationId = device.application?.id;
+ }
+ if (device.location) {
+ this.iotDevice.longitude = device.location.coordinates[0];
+ this.iotDevice.latitude = device.location.coordinates[1];
+ }
+ this.OTAA = this.iotDevice.lorawanSettings?.OTAAapplicationKey
+ ? true
+ : false;
+ if (device.sigfoxSettings) {
+ }
+ if (!device.deviceModelId || device.deviceModelId === null) {
+ this.iotDevice.deviceModelId = 0;
+ }
+ if (device.metadata) {
+ this.metadataTags = jsonToList(device.metadata);
+ }
+ });
+ }
- getDeviceProfile(deviceProfileId: string) {
- this.deviceProfileSubscription = this.deviceProfileService.getOne(deviceProfileId)
- .subscribe((response) => {
- this.OTAA = response.deviceProfile.supportsJoin;
- });
- }
+ onChangeDeviceProfile(deviceProfileId: string) {
+ this.getDeviceProfile(deviceProfileId);
+ }
- getServiceProfiles() {
- this.serviceProfilesSubscription = this.serviceProfileService
- .getMultiple().subscribe((result: ServiceProfileResponseMany) => {
- this.serviceProfiles = result.result;
- });
+ getDeviceProfile(deviceProfileId: string) {
+ this.deviceProfileSubscription = this.deviceProfileService
+ .getOne(deviceProfileId)
+ .subscribe((response) => {
+ this.OTAA = response.deviceProfile.supportsJoin;
+ });
+ }
+
+ getServiceProfiles() {
+ this.serviceProfilesSubscription = this.serviceProfileService
+ .getMultiple()
+ .subscribe((result: ServiceProfileResponseMany) => {
+ this.serviceProfiles = result.result.sort((a, b) =>
+ a.name.localeCompare(b.name, 'en', { numeric: true })
+ );
+ });
+ }
+
+ getDeviceProfiles() {
+ this.devicesProfileSubscription = this.deviceProfileService
+ .getMultiple()
+ .subscribe((result) => {
+ this.deviceProfiles = result.result.sort((a, b) =>
+ a.name.localeCompare(b.name, 'en', { numeric: true })
+ );
+ });
+ }
+
+ getCoordinates() {
+ return {
+ longitude: this.iotDevice.longitude,
+ latitude: this.iotDevice.latitude,
+ draggable: true,
+ editEnabled: false,
+ useGeolocation: !this.editmode,
+ };
+ }
+
+ updateCoordinates(event: any) {
+ this.iotDevice.longitude = event.longitude;
+ this.iotDevice.latitude = event.latitude;
+ }
+
+ onSubmit(): void {
+ this.adjustModelBasedOnType();
+
+ if (this.metadataTags.length === 0) {
+ this.iotDevice.metadata = JSON.stringify({});
+ } else if (this.isMetadataSet()) {
+ const invalidKey = this.validateMetadata();
+
+ if (!invalidKey) {
+ this.setMetadata();
+ } else {
+ this.handleMetadataError(invalidKey);
+ return;
+ }
}
- getDeviceProfiles() {
- this.devicesProfileSubscription = this.deviceProfileService
- .getMultiple().subscribe((result) => {
- this.deviceProfiles = result.result;
- });
+ if (this.deviceId !== 0) {
+ this.updateIoTDevice(this.deviceId);
+ } else {
+ this.postIoTDevice();
}
-
- getCoordinates() {
- return {
- longitude: this.iotDevice.longitude,
- latitude: this.iotDevice.latitude,
- draggable: true,
- editEnabled: false,
- useGeolocation: !this.editmode
- };
+ }
+
+ private handleMetadataError(invalidKey: string) {
+ this.handleError({
+ error: {
+ message: [
+ {
+ field: 'metadata',
+ message: 'MESSAGE.DUPLICATE-METADATA-KEY',
+ },
+ ],
+ },
+ });
+ this.errorMetadataFieldId = invalidKey;
+ this.formFailedSubmit = true;
+ }
+
+ setActivationType() {
+ if (this.OTAA) {
+ this.iotDevice.lorawanSettings.activationType = ActivationType.OTAA;
+ } else {
+ this.iotDevice.lorawanSettings.activationType = ActivationType.ABP;
}
+ }
- updateCoordinates(event: any) {
- this.iotDevice.longitude = event.longitude;
- this.iotDevice.latitude = event.latitude;
+ private adjustModelBasedOnType() {
+ if (this.iotDevice.deviceModelId === 0) {
+ this.iotDevice.deviceModelId = null;
}
-
- onSubmit(): void {
- this.adjustModelBasedOnType();
-
- if (this.metadataTags.length === 0) {
- this.iotDevice.metadata = JSON.stringify({});
- } else if (this.isMetadataSet()) {
- const invalidKey = this.validateMetadata();
-
- if (!invalidKey) {
- this.setMetadata();
- } else {
- this.handleMetadataError(invalidKey);
- return;
- }
+ switch (this.iotDevice.type) {
+ case DeviceType.GENERIC_HTTP: {
+ this.iotDevice.lorawanSettings = undefined;
+ this.iotDevice.sigfoxSettings = undefined;
+ break;
+ }
+ case DeviceType.LORAWAN: {
+ this.setActivationType();
+ this.iotDevice.sigfoxSettings = undefined;
+ if (this.iotDevice.lorawanSettings.devEUI) {
+ this.iotDevice.lorawanSettings.devEUI = this.iotDevice.lorawanSettings.devEUI.toLowerCase();
}
-
- if (this.deviceId !== 0) {
- this.updateIoTDevice(this.deviceId);
- } else {
- this.postIoTDevice();
+ break;
+ }
+ case DeviceType.SIGFOX: {
+ this.iotDevice.lorawanSettings = undefined;
+ if (this.iotDevice.sigfoxSettings.endProductCertificate) {
+ this.iotDevice.sigfoxSettings.prototype = false;
}
+ break;
+ }
}
+ }
- private handleMetadataError(invalidKey: string) {
- this.handleError({
- error: {
- message: [
- {
- field: 'metadata',
- message: 'MESSAGE.DUPLICATE-METADATA-KEY',
- },
- ],
- },
- });
- this.errorMetadataFieldId = invalidKey;
- this.formFailedSubmit = true;
- }
-
- setActivationType() {
- if (this.OTAA) {
- this.iotDevice.lorawanSettings.activationType = ActivationType.OTAA;
- } else {
- this.iotDevice.lorawanSettings.activationType = ActivationType.ABP;
- }
- }
+ private isMetadataSet(): boolean {
+ return (
+ this.metadataTags.length &&
+ this.metadataTags.some((tag) => tag.key && tag.value)
+ );
+ }
- private adjustModelBasedOnType() {
- if (this.iotDevice.deviceModelId === 0) {
- this.iotDevice.deviceModelId = null;
- }
- switch (this.iotDevice.type) {
- case DeviceType.GENERIC_HTTP: {
- this.iotDevice.lorawanSettings = undefined;
- this.iotDevice.sigfoxSettings = undefined;
- break;
- }
- case DeviceType.LORAWAN: {
- this.setActivationType();
- this.iotDevice.sigfoxSettings = undefined;
- if (this.iotDevice.lorawanSettings.devEUI) {
- this.iotDevice.lorawanSettings.devEUI = this.iotDevice.lorawanSettings.devEUI.toLowerCase();
- }
- break;
- }
- case DeviceType.SIGFOX: {
- this.iotDevice.lorawanSettings = undefined;
- if (this.iotDevice.sigfoxSettings.endProductCertificate) {
- this.iotDevice.sigfoxSettings.prototype = false;
- }
- break;
- }
- }
- }
+ private validateMetadata(): string | undefined {
+ const seen = new Set();
- private isMetadataSet(): boolean {
- return this.metadataTags.length && this.metadataTags.some((tag) => tag.key && tag.value);
+ for (const tag of this.metadataTags) {
+ if (seen.size === seen.add(tag.key).size) {
+ return tag.key;
+ }
}
-
- private validateMetadata(): string | undefined {
- const seen = new Set();
-
- for (const tag of this.metadataTags) {
- if (seen.size === seen.add(tag.key).size) {
- return tag.key;
+ }
+
+ private setMetadata(): void {
+ if (
+ this.metadataTags.length &&
+ this.metadataTags.some((tag) => tag.key && tag.value)
+ ) {
+ const metadata: Record = {};
+ this.metadataTags.forEach((tag) => {
+ if (!tag.key) {
+ return;
}
- }
+ metadata[tag.key] = tag.value;
+ });
+ this.iotDevice.metadata = JSON.stringify(metadata);
}
-
- private setMetadata(): void {
- if (
- this.metadataTags.length &&
- this.metadataTags.some((tag) => tag.key && tag.value)
- ) {
- const metadata: Record = {};
- this.metadataTags.forEach((tag) => {
- if (!tag.key) {
- return;
- }
- metadata[tag.key] = tag.value;
- });
- this.iotDevice.metadata = JSON.stringify(metadata);
+ }
+
+ postIoTDevice() {
+ this.iotDeviceService.createIoTDevice(this.iotDevice).subscribe(
+ () => {
+ this.router.navigate(['applications/', this.iotDevice.applicationId]);
+ },
+ (error: HttpErrorResponse) => {
+ this.handleError(error);
+ this.formFailedSubmit = true;
+ }
+ );
+ }
+
+ updateIoTDevice(id: number) {
+ this.iotDevice.applicationId = Number(this.iotDevice.applicationId);
+ this.iotDeviceService.updateIoTDevice(this.iotDevice, id).subscribe(
+ () => {
+ this.routeBack();
+ },
+ (error: HttpErrorResponse) => {
+ this.handleError(error);
+ this.formFailedSubmit = true;
}
+ );
+ }
+
+ routeBack(): void {
+ this.location.back();
+ }
+
+ handleError(error: Pick) {
+ if (error?.error?.message === 'MESSAGE.OTAA-INFO-MISSING') {
+ this.errorFields = ['OTAAapplicationKey'];
+ this.errorMessages = [error?.error?.message];
+ } else if (
+ error?.error?.message === 'MESSAGE.ID-INVALID-OR-ALREADY-IN-USE'
+ ) {
+ this.errorFields = ['devEUI'];
+ this.errorMessages = [error?.error?.message];
+ } else {
+ const errorMessage: ErrorMessage = this.errorMessageService.handleErrorMessageWithFields(
+ error
+ );
+ this.errorFields = errorMessage.errorFields;
+ this.errorMessages = errorMessage.errorMessages;
}
-
- postIoTDevice() {
- this.iotDeviceService.createIoTDevice(this.iotDevice).subscribe(
- () => {
- this.router.navigate([
- 'applications/',
- this.iotDevice.applicationId,
- ]);
- },
- (error: HttpErrorResponse) => {
- this.handleError(error);
- this.formFailedSubmit = true;
- }
- );
+ this.scrollToTopService.scrollToTop();
+ }
+
+ onCoordinateKey(event: any) {
+ console.log(event.target.value);
+ console.log(event.target.maxLength);
+ if (event.target.value.length > event.target.maxLength) {
+ event.target.value = event.target.value.slice(0, event.target.maxLength);
}
+ }
- updateIoTDevice(id: number) {
- this.iotDevice.applicationId = Number(this.iotDevice.applicationId);
- this.iotDeviceService.updateIoTDevice(this.iotDevice, id).subscribe(
- () => {
- this.routeBack();
- },
- (error: HttpErrorResponse) => {
- this.handleError(error);
- this.formFailedSubmit = true;
- }
- );
+ ngOnDestroy() {
+ // prevent memory leak by unsubscribing
+ if (this.applicationsSubscription) {
+ this.applicationsSubscription.unsubscribe();
}
-
- routeBack(): void {
- this.location.back();
+ if (this.deviceSubscription) {
+ this.deviceSubscription.unsubscribe();
}
-
- handleError(error: Pick) {
- if (error?.error?.message === 'MESSAGE.OTAA-INFO-MISSING') {
- this.errorFields = ['OTAAapplicationKey'];
- this.errorMessages = [error?.error?.message];
- } else if (error?.error?.message === 'MESSAGE.ID-INVALID-OR-ALREADY-IN-USE') {
- this.errorFields = ['devEUI'];
- this.errorMessages = [error?.error?.message];
- } else {
- const errorMessage: ErrorMessage = this.errorMessageService.handleErrorMessageWithFields(error);
- this.errorFields = errorMessage.errorFields;
- this.errorMessages = errorMessage.errorMessages;
- }
- this.scrollToTopService.scrollToTop();
+ if (this.deviceProfileSubscription) {
+ this.deviceProfileSubscription.unsubscribe();
}
-
- onCoordinateKey(event: any) {
- console.log(event.target.value);
- console.log(event.target.maxLength);
- if (event.target.value.length > event.target.maxLength) {
- event.target.value = event.target.value.slice(
- 0,
- event.target.maxLength
- );
- }
+ if (this.devicesProfileSubscription) {
+ this.devicesProfileSubscription.unsubscribe();
}
-
- ngOnDestroy() {
- // prevent memory leak by unsubscribing
- if (this.applicationsSubscription) {
- this.applicationsSubscription.unsubscribe();
- }
- if (this.deviceSubscription) {
- this.deviceSubscription.unsubscribe();
- }
- if (this.deviceProfileSubscription) {
- this.deviceProfileSubscription.unsubscribe();
- }
- if (this.devicesProfileSubscription) {
- this.devicesProfileSubscription.unsubscribe();
- }
- if (this.serviceProfilesSubscription) {
- this.serviceProfilesSubscription.unsubscribe();
- }
+ if (this.serviceProfilesSubscription) {
+ this.serviceProfilesSubscription.unsubscribe();
}
+ }
}
diff --git a/src/app/device-model/device-model-table/device-model-table.component.ts b/src/app/device-model/device-model-table/device-model-table.component.ts
index 18d575ef8..f997a1ef6 100644
--- a/src/app/device-model/device-model-table/device-model-table.component.ts
+++ b/src/app/device-model/device-model-table/device-model-table.component.ts
@@ -1,21 +1,13 @@
-import { Location } from '@angular/common';
-import {
- AfterViewInit,
- Component,
- OnDestroy,
- OnInit,
- ViewChild,
-} from '@angular/core';
+import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
-import { MatTableDataSource } from '@angular/material/table';
import { environment } from '@environments/environment';
import { TranslateService } from '@ngx-translate/core';
import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dialog.service';
import { MeService } from '@shared/services/me.service';
import { SharedVariableService } from '@shared/shared-variable/shared-variable.service';
import { merge, Observable, of as observableOf, Subscription } from 'rxjs';
-import { startWith, switchMap, map, catchError } from 'rxjs/operators';
+import { catchError, map, startWith, switchMap } from 'rxjs/operators';
import { DeviceModelService } from '../device-model.service';
import { DeviceModel, DeviceModelResponse } from '../device.model';
import { OrganizationAccessScope } from '@shared/enums/access-scopes';
@@ -48,7 +40,9 @@ export class DeviceModelTableComponent implements OnInit, AfterViewInit {
) {}
ngOnInit(): void {
- this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.ApplicationWrite);
+ this.canEdit = this.meService.hasAccessToTargetOrganization(
+ OrganizationAccessScope.ApplicationWrite
+ );
this.translateService
.get(['DEVICE-MODEL.DELETE-FAILED'])
.subscribe((translations) => {
@@ -72,7 +66,9 @@ export class DeviceModelTableComponent implements OnInit, AfterViewInit {
this.isLoadingResults = false;
this.resultsLength = data.count;
- return data.data;
+ return data.data.sort((a, b) =>
+ a.body.name.localeCompare(b.body.name, 'en', { numeric: true })
+ );
}),
catchError(() => {
this.isLoadingResults = false;
diff --git a/src/app/gateway/gateway-list/gateway-list.component.ts b/src/app/gateway/gateway-list/gateway-list.component.ts
index ba7b67a7b..9c4d0f9e4 100644
--- a/src/app/gateway/gateway-list/gateway-list.component.ts
+++ b/src/app/gateway/gateway-list/gateway-list.component.ts
@@ -1,207 +1,209 @@
-import { Component, OnChanges, OnDestroy, OnInit, ViewChild } from '@angular/core';
-import { Organisation } from '@app/admin/organisation/organisation.model';
-import { TranslateService } from '@ngx-translate/core';
-import { Sort } from '@shared/models/sort.model';
-import { ChirpstackGatewayService } from '@shared/services/chirpstack-gateway.service';
-import moment from 'moment';
-import { Subject, Subscription } from 'rxjs';
-import { Gateway, GatewayResponseMany } from '../gateway.model';
-import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dialog.service';
-import { MeService } from '@shared/services/me.service';
-import { SharedVariableService } from '@shared/shared-variable/shared-variable.service';
-import { environment } from '@environments/environment';
-import { Title } from '@angular/platform-browser';
-import { OrganizationAccessScope } from '@shared/enums/access-scopes';
-import { MatTabChangeEvent } from '@angular/material/tabs';
-
-const gatewayStatusTabIndex = 2;
-
-@Component({
- selector: 'app-gateway-list',
- templateUrl: './gateway-list.component.html',
- styleUrls: ['./gateway-list.component.scss']
-})
-export class GatewayListComponent implements OnInit, OnChanges, OnDestroy {
- isLoadingResults = true;
- selectedOrg: number;
-
- public coordinateList = [];
- public showmap = false;
- public pageLimit = environment.tablePageSize;
- public selectedSortId = 1;
- public gateways: Gateway[];
- private gatewaySubscription: Subscription;
- public selectedSortObject: Sort = {
- id: 1,
- dir: 'ASC',
- col: 'name',
- label: 'SORT.NAME-ASCENDING',
- };
- organisations: Organisation[];
- orgSubscribtion: Subscription;
-
- private deleteDialogSubscription: Subscription;
- public pageOffset = 0;
- public pageTotal: number;
- organisationId: number;
- canEdit: boolean;
- tabIndex = 0;
- organisationChangeSubject: Subject = new Subject();
- isGatewayStatusVisibleSubject: Subject = new Subject();
-
- constructor(
- public translate: TranslateService,
- private chirpstackGatewayService: ChirpstackGatewayService,
- private deleteDialogService: DeleteDialogService,
- private meService: MeService,
- private titleService: Title,
- private sharedVariableService: SharedVariableService,
- ) {
- translate.use('da');
- moment.locale('da');
- }
-
- ngOnInit(): void {
- this.getGateways();
- this.organisations = this.sharedVariableService.getOrganizationInfo();
- this.translate.get(['TITLE.LORAWAN-GATEWAY'])
- .subscribe(translations => {
- this.titleService.setTitle(translations['TITLE.LORAWAN-GATEWAY']);
- });
- this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.GatewayWrite);
- }
-
- ngOnChanges() {
- }
-
- public filterGatewayByOrgId(event: number) {
- this.selectedOrg = event;
- if (event) {
- this.getGatewayWith(event);
- } else {
- this.getGateways();
- }
- }
-
- setOrgIdFilter(orgId: number) {
- this.organisationId = orgId;
- this.organisationChangeSubject.next(orgId);
-
- if (this.tabIndex === gatewayStatusTabIndex) {
- this.isGatewayStatusVisibleSubject.next();
- }
-
- this.filterGatewayByOrgId(orgId);
- }
-
- private getGateways(): void {
- this.gatewaySubscription = this.chirpstackGatewayService.getMultiple(
- {
- limit: this.pageLimit,
- offset: this.pageOffset * this.pageLimit,
- sort: this.selectedSortObject.dir,
- orderOn: this.selectedSortObject.col,
- }
- )
- .subscribe(
- (gateways: GatewayResponseMany) => {
- this.gateways = gateways.result;
- this.mapToCoordinateList();
- this.setCanEdit();
- this.isLoadingResults = false;
- }
- );
- }
-
- private getGatewayWith(orgId: number): void {
- this.gatewaySubscription = this.chirpstackGatewayService.getMultiple(
- {
- limit: this.pageLimit,
- offset: this.pageOffset * this.pageLimit,
- sort: this.selectedSortObject.dir,
- orderOn: this.selectedSortObject.col,
- organizationId: orgId,
- }
- )
- .subscribe(
- (gateways: GatewayResponseMany) => {
- this.gateways = gateways.result;
- this.mapToCoordinateList();
- this.setCanEdit();
- this.isLoadingResults = false;
- }
- );
- }
-
- selectedTabChange({index}: MatTabChangeEvent) {
- this.tabIndex = index;
-
- if (index === 1) {
- if (this.selectedOrg) {
- this.getGatewayWith(this.selectedOrg);
- } else {
- this.getGateways();
- }
- this.showmap = true;
- } else if (index === gatewayStatusTabIndex) {
- this.isGatewayStatusVisibleSubject.next();
- }
- }
-
- private mapToCoordinateList() {
- const tempcoordinateList = [];
- this.gateways.map(
- gateway => tempcoordinateList.push(
- {
- longitude: gateway.location.longitude,
- latitude: gateway.location.latitude,
- draggable: false,
- editEnabled: false,
- useGeolocation: false,
- markerInfo: {
- name: gateway.name,
- active: this.gatewayStatus(gateway),
- id: gateway.id,
- internalOrganizationId: gateway.internalOrganizationId,
- internalOrganizationName: gateway.internalOrganizationName
- }
- }
- ),
- );
- this.coordinateList = tempcoordinateList;
- }
-
- gatewayStatus(gateway: Gateway): boolean {
- return this.chirpstackGatewayService.isGatewayActive(gateway);
- }
-
- deleteGateway(id: string) {
- this.deleteDialogSubscription = this.deleteDialogService.showSimpleDialog().subscribe(
- (response) => {
- if (response) {
- this.chirpstackGatewayService.delete(id).subscribe((response) => {
- if (response.ok && response.body.success === true) {
- this.getGateways();
- }
- });
- } else {
- console.log(response);
- }
- }
- );
- }
-
- setCanEdit() {
- this.gateways.forEach(
- (gateway) => {
- gateway.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.GatewayWrite, gateway.internalOrganizationId);
- }
- );
- }
-
- ngOnDestroy() {
- // prevent memory leak by unsubscribing
- this.gatewaySubscription?.unsubscribe();
- this.deleteDialogSubscription?.unsubscribe();
- }
-}
+import {
+ Component,
+ OnChanges,
+ OnDestroy,
+ OnInit,
+ ViewChild,
+} from '@angular/core';
+import { Organisation } from '@app/admin/organisation/organisation.model';
+import { TranslateService } from '@ngx-translate/core';
+import { Sort } from '@shared/models/sort.model';
+import { ChirpstackGatewayService } from '@shared/services/chirpstack-gateway.service';
+import moment from 'moment';
+import { Subject, Subscription } from 'rxjs';
+import { Gateway, GatewayResponseMany } from '../gateway.model';
+import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dialog.service';
+import { MeService } from '@shared/services/me.service';
+import { SharedVariableService } from '@shared/shared-variable/shared-variable.service';
+import { environment } from '@environments/environment';
+import { Title } from '@angular/platform-browser';
+import { OrganizationAccessScope } from '@shared/enums/access-scopes';
+import { MatTabChangeEvent } from '@angular/material/tabs';
+
+const gatewayStatusTabIndex = 2;
+
+@Component({
+ selector: 'app-gateway-list',
+ templateUrl: './gateway-list.component.html',
+ styleUrls: ['./gateway-list.component.scss'],
+})
+export class GatewayListComponent implements OnInit, OnChanges, OnDestroy {
+ isLoadingResults = true;
+ selectedOrg: number;
+
+ public coordinateList = [];
+ public showmap = false;
+ public pageLimit = environment.tablePageSize;
+ public selectedSortId = 1;
+ public gateways: Gateway[];
+ private gatewaySubscription: Subscription;
+ public selectedSortObject: Sort = {
+ id: 1,
+ dir: 'ASC',
+ col: 'name',
+ label: 'SORT.NAME-ASCENDING',
+ };
+ organisations: Organisation[];
+ orgSubscribtion: Subscription;
+
+ private deleteDialogSubscription: Subscription;
+ public pageOffset = 0;
+ public pageTotal: number;
+ organisationId: number;
+ canEdit: boolean;
+ tabIndex = 0;
+ organisationChangeSubject: Subject = new Subject();
+ isGatewayStatusVisibleSubject: Subject = new Subject();
+
+ constructor(
+ public translate: TranslateService,
+ private chirpstackGatewayService: ChirpstackGatewayService,
+ private deleteDialogService: DeleteDialogService,
+ private meService: MeService,
+ private titleService: Title,
+ private sharedVariableService: SharedVariableService
+ ) {
+ translate.use('da');
+ moment.locale('da');
+ }
+
+ ngOnInit(): void {
+ this.getGateways();
+ this.organisations = this.sharedVariableService.getOrganizationInfo();
+ this.organisations.sort((a, b) =>
+ a.name.localeCompare(b.name, 'en', { numeric: true })
+ );
+ this.translate.get(['TITLE.LORAWAN-GATEWAY']).subscribe((translations) => {
+ this.titleService.setTitle(translations['TITLE.LORAWAN-GATEWAY']);
+ });
+ this.canEdit = this.meService.hasAccessToTargetOrganization(
+ OrganizationAccessScope.GatewayWrite
+ );
+ }
+
+ ngOnChanges() {}
+
+ public filterGatewayByOrgId(event: number) {
+ this.selectedOrg = event;
+ if (event) {
+ this.getGatewayWith(event);
+ } else {
+ this.getGateways();
+ }
+ }
+
+ setOrgIdFilter(orgId: number) {
+ this.organisationId = orgId;
+ this.organisationChangeSubject.next(orgId);
+
+ if (this.tabIndex === gatewayStatusTabIndex) {
+ this.isGatewayStatusVisibleSubject.next();
+ }
+
+ this.filterGatewayByOrgId(orgId);
+ }
+
+ private getGateways(): void {
+ this.gatewaySubscription = this.chirpstackGatewayService
+ .getMultiple({
+ limit: this.pageLimit,
+ offset: this.pageOffset * this.pageLimit,
+ sort: this.selectedSortObject.dir,
+ orderOn: this.selectedSortObject.col,
+ })
+ .subscribe((gateways: GatewayResponseMany) => {
+ this.gateways = gateways.result;
+ this.mapToCoordinateList();
+ this.setCanEdit();
+ this.isLoadingResults = false;
+ });
+ }
+
+ private getGatewayWith(orgId: number): void {
+ this.gatewaySubscription = this.chirpstackGatewayService
+ .getMultiple({
+ limit: this.pageLimit,
+ offset: this.pageOffset * this.pageLimit,
+ sort: this.selectedSortObject.dir,
+ orderOn: this.selectedSortObject.col,
+ organizationId: orgId,
+ })
+ .subscribe((gateways: GatewayResponseMany) => {
+ this.gateways = gateways.result;
+ this.mapToCoordinateList();
+ this.setCanEdit();
+ this.isLoadingResults = false;
+ });
+ }
+
+ selectedTabChange({ index }: MatTabChangeEvent) {
+ this.tabIndex = index;
+
+ if (index === 1) {
+ if (this.selectedOrg) {
+ this.getGatewayWith(this.selectedOrg);
+ } else {
+ this.getGateways();
+ }
+ this.showmap = true;
+ } else if (index === gatewayStatusTabIndex) {
+ this.isGatewayStatusVisibleSubject.next();
+ }
+ }
+
+ private mapToCoordinateList() {
+ const tempcoordinateList = [];
+ this.gateways.map((gateway) =>
+ tempcoordinateList.push({
+ longitude: gateway.location.longitude,
+ latitude: gateway.location.latitude,
+ draggable: false,
+ editEnabled: false,
+ useGeolocation: false,
+ markerInfo: {
+ name: gateway.name,
+ active: this.gatewayStatus(gateway),
+ id: gateway.id,
+ internalOrganizationId: gateway.internalOrganizationId,
+ internalOrganizationName: gateway.internalOrganizationName,
+ },
+ })
+ );
+ this.coordinateList = tempcoordinateList;
+ }
+
+ gatewayStatus(gateway: Gateway): boolean {
+ return this.chirpstackGatewayService.isGatewayActive(gateway);
+ }
+
+ deleteGateway(id: string) {
+ this.deleteDialogSubscription = this.deleteDialogService
+ .showSimpleDialog()
+ .subscribe((response) => {
+ if (response) {
+ this.chirpstackGatewayService.delete(id).subscribe((response) => {
+ if (response.ok && response.body.success === true) {
+ this.getGateways();
+ }
+ });
+ } else {
+ console.log(response);
+ }
+ });
+ }
+
+ setCanEdit() {
+ this.gateways.forEach((gateway) => {
+ gateway.canEdit = this.meService.hasAccessToTargetOrganization(
+ OrganizationAccessScope.GatewayWrite,
+ gateway.internalOrganizationId
+ );
+ });
+ }
+
+ ngOnDestroy() {
+ // prevent memory leak by unsubscribing
+ this.gatewaySubscription?.unsubscribe();
+ this.deleteDialogSubscription?.unsubscribe();
+ }
+}
diff --git a/src/app/navbar/organisation-dropdown/organisation-dropdown.component.html b/src/app/navbar/organisation-dropdown/organisation-dropdown.component.html
index 7e1dccfea..4f97fad63 100644
--- a/src/app/navbar/organisation-dropdown/organisation-dropdown.component.html
+++ b/src/app/navbar/organisation-dropdown/organisation-dropdown.component.html
@@ -26,7 +26,7 @@
-
+
diff --git a/src/app/navbar/organisation-dropdown/organisation-dropdown.component.ts b/src/app/navbar/organisation-dropdown/organisation-dropdown.component.ts
index 98bf50a57..b274fba7f 100644
--- a/src/app/navbar/organisation-dropdown/organisation-dropdown.component.ts
+++ b/src/app/navbar/organisation-dropdown/organisation-dropdown.component.ts
@@ -39,6 +39,7 @@ export class OrganisationDropdownComponent implements OnInit {
ngOnInit(): void {
this.getAllowedOrganizations();
+ this.organisations.sort((a, b) => a.name.localeCompare(b.name, 'en', {numeric: true}))
}
getAllowedOrganizations() {
diff --git a/src/app/payload-decoder/payload-decoder-edit/payload-decoder-edit.component.ts b/src/app/payload-decoder/payload-decoder-edit/payload-decoder-edit.component.ts
index dc7a57601..fc3c852f1 100644
--- a/src/app/payload-decoder/payload-decoder-edit/payload-decoder-edit.component.ts
+++ b/src/app/payload-decoder/payload-decoder-edit/payload-decoder-edit.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit, Input, ViewChild, OnChanges } from '@angular/core';
+import { Component, OnInit } from '@angular/core';
import { PayloadDecoder } from 'src/app/payload-decoder/payload-decoder.model';
import { TranslateService } from '@ngx-translate/core';
import { UntypedFormGroup } from '@angular/forms';
@@ -21,19 +21,23 @@ import { TestPayloadDecoderService } from '@payload-decoder/test-payload-decoder
import { SnackService } from '@shared/services/snack.service';
import { ErrorMessageService } from '@shared/error-message.service';
import { ScrollToTopService } from '@shared/services/scroll-to-top.service';
-import { environment } from '@environments/environment';
import { MeService } from '@shared/services/me.service';
import { OrganizationAccessScope } from '@shared/enums/access-scopes';
@Component({
selector: 'app-payload-decoder-edit',
templateUrl: './payload-decoder-edit.component.html',
- styleUrls: ['./payload-decoder-edit.component.scss']
+ styleUrls: ['./payload-decoder-edit.component.scss'],
})
export class PayloadDecoderEditComponent implements OnInit {
faExchangeAlt = faExchangeAlt;
- editorJavaScriptOptions = { theme: 'vs', language: 'javascript', autoIndent: true, roundedSelection: true, };
+ editorJavaScriptOptions = {
+ theme: 'vs',
+ language: 'javascript',
+ autoIndent: true,
+ roundedSelection: true,
+ };
payloadData = '';
metadata = '';
payloadDataErrorMessage = '';
@@ -42,8 +46,21 @@ export class PayloadDecoderEditComponent implements OnInit {
payloadInvalidJSONMessage: string;
codeOutput = '';
testPayloadDecoder = new TestPayloadDecoder();
- editorJsonOptions = { theme: 'vs', language: 'json', autoIndent: true, roundedSelection: true, minimap: { enabled: false } };
- editorJsonOutpuOptions = { theme: 'vs', language: 'json', autoIndent: true, roundedSelection: true, minimap: { enabled: false }, readOnly: true };
+ editorJsonOptions = {
+ theme: 'vs',
+ language: 'json',
+ autoIndent: true,
+ roundedSelection: true,
+ minimap: { enabled: false },
+ };
+ editorJsonOutpuOptions = {
+ theme: 'vs',
+ language: 'json',
+ autoIndent: true,
+ roundedSelection: true,
+ minimap: { enabled: false },
+ readOnly: true,
+ };
payloadDecoder = new PayloadDecoder();
payloadDecoderBody: string;
@@ -79,33 +96,41 @@ export class PayloadDecoderEditComponent implements OnInit {
private errorMessageService: ErrorMessageService,
private scrollToTopService: ScrollToTopService,
private meService: MeService
- ) { }
+ ) {}
ngOnInit(): void {
this.translate.use('da');
- this.translate.get([
- 'NAV.PAYLOAD-DECODER',
- 'FORM.EDIT-PAYLOAD-DECODER',
- 'PAYLOAD-DECODER.SAVE',
- 'QUESTION.GIVE-PAYLOADDECODER-PAYLOAD-PLACEHOLDER',
- 'QUESTION.GIVE-PAYLOADDECODER-METADATA-PLACEHOLDER',
- 'QUESTION.GIVE-PAYLOADDECODER-PAYLOAD-ERRORMESSAGE',
- 'QUESTION.GIVE-PAYLOADDECODER-METADATA-ERRORMESSAGE',
- 'QUESTION.GIVE-PAYLOADDECODER-OUTPUT-PLACEHOLDER',
- 'QUESTION.GIVE-PAYLOADDECODER-PAYLOAD-INVALID-JSON',
- 'QUESTION.GIVE-PAYLOADDECODER-METADATA-INVALID-JSON'
- ])
- .subscribe(translations => {
+ this.translate
+ .get([
+ 'NAV.PAYLOAD-DECODER',
+ 'FORM.EDIT-PAYLOAD-DECODER',
+ 'PAYLOAD-DECODER.SAVE',
+ 'QUESTION.GIVE-PAYLOADDECODER-PAYLOAD-PLACEHOLDER',
+ 'QUESTION.GIVE-PAYLOADDECODER-METADATA-PLACEHOLDER',
+ 'QUESTION.GIVE-PAYLOADDECODER-PAYLOAD-ERRORMESSAGE',
+ 'QUESTION.GIVE-PAYLOADDECODER-METADATA-ERRORMESSAGE',
+ 'QUESTION.GIVE-PAYLOADDECODER-OUTPUT-PLACEHOLDER',
+ 'QUESTION.GIVE-PAYLOADDECODER-PAYLOAD-INVALID-JSON',
+ 'QUESTION.GIVE-PAYLOADDECODER-METADATA-INVALID-JSON',
+ ])
+ .subscribe((translations) => {
this.backButton.label = translations['NAV.PAYLOAD-DECODER'];
this.title = translations['FORM.EDIT-PAYLOAD-DECODER'];
this.submitButton = translations['PAYLOAD-DECODER.SAVE'];
- this.payloadData = translations['QUESTION.GIVE-PAYLOADDECODER-PAYLOAD-PLACEHOLDER'];
- this.metadata = translations['QUESTION.GIVE-PAYLOADDECODER-METADATA-PLACEHOLDER'];
- this.payloadDataErrorMessage = translations['QUESTION.GIVE-PAYLOADDECODER-PAYLOAD-ERRORMESSAGE'];
- this.metadataErrorMessage = translations['QUESTION.GIVE-PAYLOADDECODER-METADATA-ERRORMESSAGE'];
- this.codeOutput = translations['QUESTION.GIVE-PAYLOADDECODER-OUTPUT-PLACEHOLDER'];
- this.metadataInvalidJSONMessage = translations['QUESTION.GIVE-PAYLOADDECODER-METADATA-INVALID-JSON'];
- this.payloadInvalidJSONMessage = translations['QUESTION.GIVE-PAYLOADDECODER-PAYLOAD-INVALID-JSON'];
+ this.payloadData =
+ translations['QUESTION.GIVE-PAYLOADDECODER-PAYLOAD-PLACEHOLDER'];
+ this.metadata =
+ translations['QUESTION.GIVE-PAYLOADDECODER-METADATA-PLACEHOLDER'];
+ this.payloadDataErrorMessage =
+ translations['QUESTION.GIVE-PAYLOADDECODER-PAYLOAD-ERRORMESSAGE'];
+ this.metadataErrorMessage =
+ translations['QUESTION.GIVE-PAYLOADDECODER-METADATA-ERRORMESSAGE'];
+ this.codeOutput =
+ translations['QUESTION.GIVE-PAYLOADDECODER-OUTPUT-PLACEHOLDER'];
+ this.metadataInvalidJSONMessage =
+ translations['QUESTION.GIVE-PAYLOADDECODER-METADATA-INVALID-JSON'];
+ this.payloadInvalidJSONMessage =
+ translations['QUESTION.GIVE-PAYLOADDECODER-PAYLOAD-INVALID-JSON'];
});
this.id = +this.route.snapshot.paramMap.get('id');
if (this.id > 0) {
@@ -117,24 +142,30 @@ export class PayloadDecoderEditComponent implements OnInit {
this.sharedVariableService.getValue().subscribe((organisationId) => {
this.getApplications(organisationId);
});
- this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.ApplicationWrite);
+ this.canEdit = this.meService.hasAccessToTargetOrganization(
+ OrganizationAccessScope.ApplicationWrite
+ );
}
setBackButtonLink(payloadDecoderId: number) {
if (payloadDecoderId) {
- this.backButton.routerLink = ['payload-decoder', 'payload-decoder-detail', this.id.toString()];
+ this.backButton.routerLink = [
+ 'payload-decoder',
+ 'payload-decoder-detail',
+ this.id.toString(),
+ ];
} else {
this.backButton.routerLink = ['payload-decoder'];
}
}
private getPayloadDecoder(id: number) {
- this.subscription = this.payloadDecoderService.getOne(id)
- .subscribe(
- (response) => {
- this.payloadDecoder = response;
- this.payloadDecoderBody = response.decodingFunction;
- });
+ this.subscription = this.payloadDecoderService
+ .getOne(id)
+ .subscribe((response) => {
+ this.payloadDecoder = response;
+ this.payloadDecoderBody = response.decodingFunction;
+ });
}
testPayloadFunction() {
@@ -154,7 +185,9 @@ export class PayloadDecoderEditComponent implements OnInit {
}
}
try {
- this.testPayloadDecoder.rawPayloadJsonString = JSON.parse(this.payloadData);
+ this.testPayloadDecoder.rawPayloadJsonString = JSON.parse(
+ this.payloadData
+ );
} catch (err) {
this.errorFields = ['payload'];
this.errorMessages = [this.payloadInvalidJSONMessage];
@@ -162,19 +195,21 @@ export class PayloadDecoderEditComponent implements OnInit {
return;
}
- this.testPayloadDecoderService.post(this.testPayloadDecoder)
- .subscribe(
- (response) => {
- this.codeOutput = JSON.stringify(response, null, 4);
- },
- (error: HttpErrorResponse) => {
- this.showError(error);
- }
- );
+ this.testPayloadDecoderService.post(this.testPayloadDecoder).subscribe(
+ (response) => {
+ this.codeOutput = JSON.stringify(response, null, 4);
+ },
+ (error: HttpErrorResponse) => {
+ this.showError(error);
+ }
+ );
}
private isMetadataDefaultOrEmpty() {
- return this.metadata.trim() === '' || this.metadata.split('\n').every(x => x.trim().startsWith('//'));
+ return (
+ this.metadata.trim() === '' ||
+ this.metadata.split('\n').every((x) => x.trim().startsWith('//'))
+ );
}
getCurrentOrganisationId(): number {
@@ -191,15 +226,19 @@ export class PayloadDecoderEditComponent implements OnInit {
orgId ? orgId : this.getCurrentOrganisationId()
)
.subscribe((applications) => {
- this.applications = applications.data;
+ this.applications = applications.data.sort((a, b) =>
+ a.name.localeCompare(b.name, 'en', { numeric: true })
+ );
});
}
getDevices(event: MatSelectChange): void {
- this.applicationsSubscription = this.applicationService.getApplication(event.value)
+ this.applicationsSubscription = this.applicationService
+ .getApplication(event.value)
.subscribe((application: Application) => {
- this.iotDevices = application.iotDevices;
-
+ this.iotDevices = application.iotDevices.sort((a, b) =>
+ a.name.localeCompare(b.name, 'en', { numeric: true })
+ );
});
}
@@ -208,7 +247,11 @@ export class PayloadDecoderEditComponent implements OnInit {
.getIoTDevice(event.value)
.subscribe(async (device: IotDevice) => {
if (device.latestReceivedMessage) {
- this.payloadData = JSON.stringify(device.latestReceivedMessage.rawData, null, 4);
+ this.payloadData = JSON.stringify(
+ device.latestReceivedMessage.rawData,
+ null,
+ 4
+ );
} else {
this.payloadData = this.payloadDataErrorMessage;
}
@@ -250,28 +293,27 @@ export class PayloadDecoderEditComponent implements OnInit {
}
private create(): void {
- this.payloadDecoderService.post(this.payloadDecoder)
- .subscribe(
- (response) => {
- this.routeBack();
- this.showSavedSnack();
- },
- (error: HttpErrorResponse) => {
- this.showError(error);
- }
- );
+ this.payloadDecoderService.post(this.payloadDecoder).subscribe(
+ (response) => {
+ this.routeBack();
+ this.showSavedSnack();
+ },
+ (error: HttpErrorResponse) => {
+ this.showError(error);
+ }
+ );
}
private update(): void {
- this.payloadDecoderService.put(this.payloadDecoder, this.id)
- .subscribe(
- (response) => {
- this.routeBack();
- this.showSavedSnack();
- },
- (error) => {
- this.showError(error);
- });
+ this.payloadDecoderService.put(this.payloadDecoder, this.id).subscribe(
+ (response) => {
+ this.routeBack();
+ this.showSavedSnack();
+ },
+ (error) => {
+ this.showError(error);
+ }
+ );
}
onSubmit(): void {
@@ -281,11 +323,12 @@ export class PayloadDecoderEditComponent implements OnInit {
} else {
this.create();
}
-
}
private showError(error: HttpErrorResponse) {
- const errorResponse = this.errorMessageService.handleErrorMessageWithFields(error);
+ const errorResponse = this.errorMessageService.handleErrorMessageWithFields(
+ error
+ );
this.errorFields = errorResponse.errorFields;
this.errorMessages = errorResponse.errorMessages;
this.formFailedSubmit = true;
@@ -295,5 +338,4 @@ export class PayloadDecoderEditComponent implements OnInit {
routeBack(): void {
this.location.back();
}
-
}
diff --git a/src/app/payload-decoder/payload-decoder-list/payload-decoder-table/payload-decoder-table.component.ts b/src/app/payload-decoder/payload-decoder-list/payload-decoder-table/payload-decoder-table.component.ts
index 7755db562..2cfdd793b 100644
--- a/src/app/payload-decoder/payload-decoder-list/payload-decoder-table/payload-decoder-table.component.ts
+++ b/src/app/payload-decoder/payload-decoder-list/payload-decoder-table/payload-decoder-table.component.ts
@@ -54,6 +54,9 @@ export class PayloadDecoderTableComponent
ngOnInit(): void {
this.organizations = this.sharedVariableService.getOrganizationInfo();
+ this.organizations.sort((a, b) =>
+ a.name.localeCompare(b.name, 'en', { numeric: true })
+ );
this.translateService
.get(['PAYLOAD-DECODER.DELETE-FAILED'])
.subscribe((translations) => {
@@ -98,7 +101,10 @@ export class PayloadDecoderTableComponent
}
getCanEdit(organizationId: number) {
- return this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.ApplicationWrite, organizationId);
+ return this.meService.hasAccessToTargetOrganization(
+ OrganizationAccessScope.ApplicationWrite,
+ organizationId
+ );
}
public filterByOrgId(event: number) {
diff --git a/src/app/sigfox/sigfox-groups-detail/sigfox-device-type-table/sigfox-device-type-table.component.ts b/src/app/sigfox/sigfox-groups-detail/sigfox-device-type-table/sigfox-device-type-table.component.ts
index 97adbdc6f..7cd94008b 100644
--- a/src/app/sigfox/sigfox-groups-detail/sigfox-device-type-table/sigfox-device-type-table.component.ts
+++ b/src/app/sigfox/sigfox-groups-detail/sigfox-device-type-table/sigfox-device-type-table.component.ts
@@ -11,7 +11,7 @@ import { DefaultPageSizeOptions } from '@shared/constants/page.constants';
@Component({
selector: 'app-sigfox-device-type-table',
templateUrl: './sigfox-device-type-table.component.html',
- styleUrls: ['./sigfox-device-type-table.component.scss']
+ styleUrls: ['./sigfox-device-type-table.component.scss'],
})
export class SigfoxDeviceTypeTableComponent implements OnInit, OnChanges {
@Input() sigfoxDevices: SigfoxDeviceType[];
@@ -28,24 +28,26 @@ export class SigfoxDeviceTypeTableComponent implements OnInit, OnChanges {
constructor(
private translate: TranslateService,
private route: ActivatedRoute,
- private router: Router) {
+ private router: Router
+ ) {
this.translate.use('da');
}
- ngOnInit(): void {
- }
+ ngOnInit(): void {}
ngOnChanges() {
if (this.sigfoxDevices) {
- this.dataSource.data = this.sigfoxDevices;
+ this.dataSource.data = this.sigfoxDevices.sort((a, b) =>
+ a.name.localeCompare(b.name, 'en', { numeric: true })
+ );
this.dataSource.paginator = this.paginator;
this.resultsLength = this.sigfoxDevices.length;
}
}
editDeviceType(row: any) {
- this.router.navigate([row.id, 'edit-device-type'], { relativeTo: this.route });
- console.log(row);
+ this.router.navigate([row.id, 'edit-device-type'], {
+ relativeTo: this.route,
+ });
}
-
}
diff --git a/src/assets/i18n/da.json b/src/assets/i18n/da.json
index a94ac64be..580da59ab 100644
--- a/src/assets/i18n/da.json
+++ b/src/assets/i18n/da.json
@@ -90,7 +90,7 @@
"PROFILES": {
"NAME": "Sigfox enhedstyper",
"DEVICE-TYPE": "Sigfox enhedstyper",
- "DEVICE-TYPE-NAME": "navn",
+ "DEVICE-TYPE-NAME": "Navn",
"DEVICE-TYPE-CONTRACT-ID": "kontrakt id",
"DEVICE-TYPE-ALERT-EMAIL": "Alarm email",
"CREATE-NEW-DEVICE-TYPE": "Opret ny enhedstype",