From cb6a042f4aa7f21c7d20ef3b667dd484fec9393c Mon Sep 17 00:00:00 2001 From: August Andersen Date: Wed, 25 Sep 2024 14:55:26 +0200 Subject: [PATCH 1/5] UX for test-connection --- .../applications-routing.module.ts | 2 + .../datatarget-detail-tabs-common.ts | 6 ++ .../datatarget-test-connection.component.html | 78 +++++++++++++++++++ .../datatarget-test-connection.component.scss | 3 + ...tatarget-test-connection.component.spec.ts | 23 ++++++ .../datatarget-test-connection.component.ts | 22 ++++++ .../datatarget/datatarget.module.ts | 4 + .../httppush-detail-tabs.component.scss | 48 ++++++++++++ .../httppush-detail-tabs.component.ts | 1 - src/assets/i18n/da.json | 13 ++++ 10 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.html create mode 100644 src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.scss create mode 100644 src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.spec.ts create mode 100644 src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.ts diff --git a/src/app/applications/applications-routing.module.ts b/src/app/applications/applications-routing.module.ts index fd12d219..a9f0a002 100644 --- a/src/app/applications/applications-routing.module.ts +++ b/src/app/applications/applications-routing.module.ts @@ -23,6 +23,7 @@ import { IoTDeviceDetailComponent } from "./iot-devices/iot-device-detail/iot-de import { IotDeviceEditComponent } from "./iot-devices/iot-device-edit/iot-device-edit.component"; import { MulticastDetailComponent } from "./multicast/multicast-detail/multicast-detail.component"; import { MulticastEditComponent } from "./multicast/multicast-edit/multicast-edit.component"; +import { DatatargetTestConnectionComponent } from "./datatarget/datatarget-test-connection/datatarget-test-connection.component"; const applicationRoutes: Routes = [ { @@ -76,6 +77,7 @@ const applicationRoutes: Routes = [ component: DatatargetDetailComponent, children: [ { path: "datatarget-log", component: DatatargetLogComponent }, + { path: "datatarget-test-connection", component: DatatargetTestConnectionComponent }, { path: "httppush-detail", component: HttppushDetailComponent }, { path: "fiware-detail", component: FiwareDetailComponent }, { path: "mqtt-detail", component: MqttDetailComponent }, diff --git a/src/app/applications/datatarget/datatarget-detail/datatarget-detail-tabs-common.ts b/src/app/applications/datatarget/datatarget-detail/datatarget-detail-tabs-common.ts index d4ab3967..22b024c9 100644 --- a/src/app/applications/datatarget/datatarget-detail/datatarget-detail-tabs-common.ts +++ b/src/app/applications/datatarget/datatarget-detail/datatarget-detail-tabs-common.ts @@ -20,6 +20,7 @@ export abstract class DatatargetDetailTabsCommon implements DatatargetDetail { faExclamationTriangle = faExclamationTriangle; logLink: "datatarget-log" = "datatarget-log"; + testConnectionLink: "datatarget-test-connection" = "datatarget-test-connection"; navTabs: NavTab[] = [ { label: "APPLICATION.DETAILS", @@ -31,6 +32,11 @@ export abstract class DatatargetDetailTabsCommon implements DatatargetDetail { link: this.logLink, index: 1, }, + { + label: "Test forbindelse", + link: this.testConnectionLink, + index: 2, + }, ]; datatarget: Datatarget; diff --git a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.html b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.html new file mode 100644 index 00000000..ccd87ee6 --- /dev/null +++ b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.html @@ -0,0 +1,78 @@ +
+
+
+
+

{{ "DATATARGET.TEST_CONNECTION.TEST-CONNECTION" | translate }}

+ +

{{ "DATATARGET.TEST_CONNECTION.SEND-PING-TO-DATATARGET" | translate }}

+ +

{{ "DATATARGET.TEST_CONNECTION.SEND-LATEST-PACKAGE" | translate }}

+ + + +

+ {{ "DATATARGET.TEST_CONNECTION.SEND-DATA-PACKAGE-DESCRIPTION" | translate }} +

+
+
+
+
+

{{ "DATATARGET.TEST_CONNECTION.CHOSEN-DATA-PACKAGE" | translate }}

+ + +
+
+
+
+

{{ "DATATARGET.TEST_CONNECTION.SENT-HTTP-REQUEST" | translate }}

+

{{ "DATATARGET.TEST_CONNECTION.HEADERS" | translate }}

+ + + +

{{ "DATATARGET.TEST_CONNECTION.BODY" | translate }}

+ + +
+
+
+
+

{{ "DATATARGET.TEST_CONNECTION.RECEIVED-HTTP-RESPONSE" | translate }}

+

{{ "DATATARGET.TEST_CONNECTION.HEADERS" | translate }}

+ + + +

{{ "DATATARGET.TEST_CONNECTION.BODY" | translate }}

+ + + +
+
+
+
diff --git a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.scss b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.scss new file mode 100644 index 00000000..cba444d1 --- /dev/null +++ b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.scss @@ -0,0 +1,3 @@ +.marginTop5 { + margin-top: 5px !important +} diff --git a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.spec.ts b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.spec.ts new file mode 100644 index 00000000..8bf4bbf2 --- /dev/null +++ b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DatatargetTestConnectionComponent } from './datatarget-test-connection.component'; + +describe('DatatargetTestConnectionComponent', () => { + let component: DatatargetTestConnectionComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [DatatargetTestConnectionComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(DatatargetTestConnectionComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.ts b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.ts new file mode 100644 index 00000000..defb8f74 --- /dev/null +++ b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.ts @@ -0,0 +1,22 @@ +import { Component, OnInit } from "@angular/core"; + +@Component({ + selector: "app-datatarget-test-connection", + templateUrl: "./datatarget-test-connection.component.html", + styleUrl: "./datatarget-test-connection.component.scss", +}) +export class DatatargetTestConnectionComponent implements OnInit { + + codeOutput = "" + editorJsonOutpuOptions = { + theme: "vs", + language: "json", + autoIndent: true, + roundedSelection: true, + minimap: { enabled: false }, + readOnly: true, + }; + constructor() {} + + ngOnInit(): void {} +} diff --git a/src/app/applications/datatarget/datatarget.module.ts b/src/app/applications/datatarget/datatarget.module.ts index 97d2b495..4a6fa239 100644 --- a/src/app/applications/datatarget/datatarget.module.ts +++ b/src/app/applications/datatarget/datatarget.module.ts @@ -29,6 +29,8 @@ import { OpendatadkDetailComponent } from "./opendatadk/opendatadk-detail/openda import { OpendatadkEditComponent } from "./opendatadk/opendatadk-edit/opendatadk-edit.component"; import { OpenDataDkMailDialogComponent } from "./opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog"; import { OpenDataDkWarningDialogComponent } from "./opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog"; +import { DatatargetTestConnectionComponent } from "./datatarget-test-connection/datatarget-test-connection.component"; +import { MonacoEditorModule } from "ngx-monaco-editor-v2"; @NgModule({ declarations: [ @@ -53,6 +55,7 @@ import { OpenDataDkWarningDialogComponent } from "./opendatadk/opendatadk-edit/o DatatargetDetailTypeSelectorDirective, DatatargetEditTypeSelectorDirective, DatatargetTabComponent, + DatatargetTestConnectionComponent, ], imports: [ CommonModule, @@ -65,6 +68,7 @@ import { OpenDataDkWarningDialogComponent } from "./opendatadk/opendatadk-edit/o FormsModule, SharedModule, PipesModule, + MonacoEditorModule, ], exports: [ DatatargetTableComponent, diff --git a/src/app/applications/datatarget/httppush/httppush-detail-tabs/httppush-detail-tabs.component.scss b/src/app/applications/datatarget/httppush/httppush-detail-tabs/httppush-detail-tabs.component.scss index 3297737e..3c31f075 100644 --- a/src/app/applications/datatarget/httppush/httppush-detail-tabs/httppush-detail-tabs.component.scss +++ b/src/app/applications/datatarget/httppush/httppush-detail-tabs/httppush-detail-tabs.component.scss @@ -1,6 +1,54 @@ +@import "src/assets/scss/setup/variables"; + :host { .fa-error { color: red !important; margin-left: 5px; } } + +a { + color: $color-link; + border-bottom: 0px transparent !important; + cursor: pointer; + text-decoration: none; + + &:hover, + &.link-hover, + &:visited:hover { + color: $color-link-hover; + border-bottom: 0px $color-link-hover-bg !important; + + &:disabled, + .disabled { + background-color: transparent !important; + } + } + + &:active, + &.link-active { + background-color: inherit; + color: $color-active; + border-bottom: 0px $color-link-active-bg !important; + } + + &:focus, + &.link-focus { + color: $color-link-focus; + background-color: transparent; + border-bottom: 0px $color-link-focus-bg !important; + } + + &:disabled, + &.disabled { + box-shadow: none !important; + cursor: not-allowed !important; + //color: #000 !important; // FIXME: Hvad skal der der være her? + outline-offset: inherit !important; + + &:focus { + outline: none; + background-color: transparent; + } + } +} diff --git a/src/app/applications/datatarget/httppush/httppush-detail-tabs/httppush-detail-tabs.component.ts b/src/app/applications/datatarget/httppush/httppush-detail-tabs/httppush-detail-tabs.component.ts index 82aec38b..c82f7efd 100644 --- a/src/app/applications/datatarget/httppush/httppush-detail-tabs/httppush-detail-tabs.component.ts +++ b/src/app/applications/datatarget/httppush/httppush-detail-tabs/httppush-detail-tabs.component.ts @@ -3,7 +3,6 @@ import { Component, OnDestroy } from "@angular/core"; import { ActivatedRoute, Router } from "@angular/router"; import { DatatargetDetailTabsCommon } from "@applications/datatarget/datatarget-detail/datatarget-detail-tabs-common"; import { DatatargetService } from "@applications/datatarget/datatarget.service"; -import { faExclamationTriangle } from "@fortawesome/free-solid-svg-icons"; import { TranslateService } from "@ngx-translate/core"; import { DeleteDialogService } from "@shared/components/delete-dialog/delete-dialog.service"; import { DataTargetType } from "@shared/enums/datatarget-type"; diff --git a/src/assets/i18n/da.json b/src/assets/i18n/da.json index 5b71d91a..225b8002 100644 --- a/src/assets/i18n/da.json +++ b/src/assets/i18n/da.json @@ -278,6 +278,19 @@ "RESPONSE_TYPE": { "ERROR": "Fejl", "OK": "Ok" + }, + "TEST_CONNECTION": { + "TEST-CONNECTION": "Test forbindelse", + "SEND-PING-TO-DATATARGET": "Send et ping til dette datatarget", + "SEND-LATEST-PACKAGE": "Send seneste datapakke", + "CHOOSE-IOT-DEVICE": "Vælg IoT-enhed", + "SEND-DATA-PACKAGE": "Send datapakke", + "SEND-DATA-PACKAGE-DESCRIPTION": "Send seneste datapakke fra den valgte IoT-enhed til dette data target Bemærk at datapakken potentielt indgår i jeres driftsdata, hvis det modtages succesfuldt", + "CHOSEN-DATA-PACKAGE": "Valgt datapakke", + "SENT-HTTP-REQUEST": "Sendt - HTTP request", + "RECEIVED-HTTP-RESPONSE": "Modtaget - HTTP response", + "HEADERS": "Headers", + "BODY": "Body" } }, "MULTICAST": { From 8793ebb5ed4bd6c7d5aaec57d21df719e5250363 Mon Sep 17 00:00:00 2001 From: Frederik Christ Vestergaard Date: Thu, 26 Sep 2024 16:11:56 +0200 Subject: [PATCH 2/5] Fetch latest datapackage from selected device --- .../datatarget-test-connection.component.html | 23 ++++---- ...tatarget-test-connection.component.spec.ts | 23 -------- .../datatarget-test-connection.component.ts | 54 ++++++++++++++++--- .../payload-decoder-edit.component.html | 44 +++++++-------- 4 files changed, 83 insertions(+), 61 deletions(-) delete mode 100644 src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.spec.ts diff --git a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.html b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.html index ccd87ee6..a20adb4b 100644 --- a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.html +++ b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.html @@ -8,12 +8,15 @@

{{ "DATATARGET.TEST_CONNECTION.TEST-CONNECTION" | translate }}

{{ "DATATARGET.TEST_CONNECTION.SEND-LATEST-PACKAGE" | translate }}

+ + {{ iotDevice.name }} +

@@ -25,10 +28,10 @@

{{ "DATATARGET.TEST_CONNECTION.TEST-CONNECTION" | translate }}

{{ "DATATARGET.TEST_CONNECTION.CHOSEN-DATA-PACKAGE" | translate }}

@@ -38,17 +41,17 @@

{{ "DATATARGET.TEST_CONNECTION.CHOSEN-DATA-PACKAGE" | translate }}

{{ "DATATARGET.TEST_CONNECTION.SENT-HTTP-REQUEST" | translate }}

{{ "DATATARGET.TEST_CONNECTION.HEADERS" | translate }}

{{ "DATATARGET.TEST_CONNECTION.BODY" | translate }}

@@ -58,18 +61,18 @@

{{ "DATATARGET.TEST_CONNECTION.SENT-HTTP-REQUEST" | translate }}

{{ "DATATARGET.TEST_CONNECTION.RECEIVED-HTTP-RESPONSE" | translate }}

{{ "DATATARGET.TEST_CONNECTION.HEADERS" | translate }}

{{ "DATATARGET.TEST_CONNECTION.BODY" | translate }}

diff --git a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.spec.ts b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.spec.ts deleted file mode 100644 index 8bf4bbf2..00000000 --- a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { DatatargetTestConnectionComponent } from './datatarget-test-connection.component'; - -describe('DatatargetTestConnectionComponent', () => { - let component: DatatargetTestConnectionComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [DatatargetTestConnectionComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(DatatargetTestConnectionComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.ts b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.ts index defb8f74..bc593dfb 100644 --- a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.ts +++ b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.ts @@ -1,13 +1,18 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnDestroy, OnInit } from "@angular/core"; +import { IoTDeviceService } from "@applications/iot-devices/iot-device.service"; +import { ApplicationService } from "@applications/application.service"; +import { Application } from "@applications/application.model"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { ActivatedRoute } from "@angular/router"; +import { MatSelectChange } from "@angular/material/select"; @Component({ selector: "app-datatarget-test-connection", templateUrl: "./datatarget-test-connection.component.html", styleUrl: "./datatarget-test-connection.component.scss", }) -export class DatatargetTestConnectionComponent implements OnInit { - - codeOutput = "" +export class DatatargetTestConnectionComponent implements OnInit, OnDestroy { + codeOutput = ""; editorJsonOutpuOptions = { theme: "vs", language: "json", @@ -16,7 +21,44 @@ export class DatatargetTestConnectionComponent implements OnInit { minimap: { enabled: false }, readOnly: true, }; - constructor() {} + public iotDevices: IotDevice[]; + public payloadData = ""; + + private applicationId: number; + private subscriptions = []; + + constructor( + private deviceService: IoTDeviceService, + private route: ActivatedRoute, + public applicationService: ApplicationService + ) {} + + ngOnInit(): void { + this.applicationId = +this.route.parent.snapshot.paramMap.get("id"); + this.getDevices(); + } + + ngOnDestroy() { + this.subscriptions.forEach(s => s?.unsubscribe()); + } + + getDevices() { + const deviceSubscription = this.applicationService + .getApplication(this.applicationId) + .subscribe((application: Application) => { + this.iotDevices = application.iotDevices.sort((a, b) => a.name.localeCompare(b.name, "en", { numeric: true })); + }); + + this.subscriptions.push(deviceSubscription); + } + + getLastPackage(event: MatSelectChange) { + const sub = this.deviceService.getIoTDevice(event.value).subscribe((device: IotDevice) => { + if (device.latestReceivedMessage) { + this.payloadData = JSON.stringify(device.latestReceivedMessage.rawData, null, 2); + } + }); - ngOnInit(): void {} + this.subscriptions.push(sub); + } } diff --git a/src/app/payload-decoder/payload-decoder-edit/payload-decoder-edit.component.html b/src/app/payload-decoder/payload-decoder-edit/payload-decoder-edit.component.html index 4adeaf69..7fe44aa1 100644 --- a/src/app/payload-decoder/payload-decoder-edit/payload-decoder-edit.component.html +++ b/src/app/payload-decoder/payload-decoder-edit/payload-decoder-edit.component.html @@ -1,4 +1,4 @@ - +
@@ -13,20 +13,20 @@
- +
@@ -58,17 +58,17 @@
+ "QUESTION.GIVE-PAYLOADDECODER-DECODINGFUNCTION" | translate + }}
@@ -77,30 +77,30 @@
-
+
{{ "QUESTION.GIVE-PAYLOADDECODER-TESTBUTTON" | translate }}
@@ -109,14 +109,14 @@
From a976afbdbd06e8e2e2fc91d60685478084039c1b Mon Sep 17 00:00:00 2001 From: Frederik Christ Vestergaard Date: Mon, 30 Sep 2024 14:32:25 +0200 Subject: [PATCH 3/5] Enabled data target testing --- .../datatarget-test-connection.component.html | 61 ++++---- .../datatarget-test-connection.component.ts | 71 +++++++++- .../datatarget/datatarget.model.ts | 7 + .../datatarget/datatarget.service.ts | 47 ++++--- .../fiware-detail/fiware-detail.component.ts | 4 +- .../fiware-edit/fiware-edit.component.ts | 50 +++---- .../httppush-detail.component.ts | 4 +- .../httppush-edit/httppush-edit.component.ts | 67 +++++---- .../mqtt/mqtt-detail/mqtt-detail.component.ts | 4 +- .../mqtt/mqtt-edit/mqtt-edit.component.ts | 117 ++++++++-------- .../opendatadk-edit.component.ts | 131 ++++++++++-------- .../payload-device-data.model.ts | 6 +- .../payload-device-datatarget.service.ts | 6 +- src/assets/i18n/da.json | 11 +- 14 files changed, 341 insertions(+), 245 deletions(-) diff --git a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.html b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.html index a20adb4b..309e6f4a 100644 --- a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.html +++ b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.html @@ -3,24 +3,41 @@

{{ "DATATARGET.TEST_CONNECTION.TEST-CONNECTION" | translate }}

- -

{{ "DATATARGET.TEST_CONNECTION.SEND-PING-TO-DATATARGET" | translate }}

- +
+ +

{{ "DATATARGET.TEST_CONNECTION.SEND-PING-TO-DATATARGET" | translate }}

+ +

{{ "DATATARGET.TEST_CONNECTION.SEND-LATEST-PACKAGE" | translate }}

{{ iotDevice.name }} - -

+ + + {{ "QUESTION.DATATARGET.NO-PAYLOAD-DECODER-SELECTED" | translate }} + + + {{ payloadDecoder.name }} + + + +

{{ "DATATARGET.TEST_CONNECTION.SEND-DATA-PACKAGE-DESCRIPTION" | translate }} + {{ dataTarget.type === DataTargetType.MQTT ? ("DATATARGET.TEST_CONNECTION.MQTT-DISCLAIMER"| translate) : "" }}

@@ -38,18 +55,9 @@

{{ "DATATARGET.TEST_CONNECTION.CHOSEN-DATA-PACKAGE" | translate }}

-

{{ "DATATARGET.TEST_CONNECTION.SENT-HTTP-REQUEST" | translate }}

-

{{ "DATATARGET.TEST_CONNECTION.HEADERS" | translate }}

- - - -

{{ "DATATARGET.TEST_CONNECTION.BODY" | translate }}

+

{{ "DATATARGET.TEST_CONNECTION.SENT-DECODED-REQUEST" | translate }}

@@ -58,19 +66,12 @@

{{ "DATATARGET.TEST_CONNECTION.SENT-HTTP-REQUEST" | translate }}

-

{{ "DATATARGET.TEST_CONNECTION.RECEIVED-HTTP-RESPONSE" | translate }}

-

{{ "DATATARGET.TEST_CONNECTION.HEADERS" | translate }}

- - - -

{{ "DATATARGET.TEST_CONNECTION.BODY" | translate }}

- +

{{ "DATATARGET.TEST_CONNECTION.RECEIVED-RESPONSE" | translate }}

+
+ +
diff --git a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.ts b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.ts index bc593dfb..a825e759 100644 --- a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.ts +++ b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.ts @@ -5,6 +5,12 @@ import { Application } from "@applications/application.model"; import { IotDevice } from "@applications/iot-devices/iot-device.model"; import { ActivatedRoute } from "@angular/router"; import { MatSelectChange } from "@angular/material/select"; +import { DatatargetService } from "@applications/datatarget/datatarget.service"; +import { Datatarget } from "@applications/datatarget/datatarget.model"; +import { DataTargetType } from "@shared/enums/datatarget-type"; +import { PayloadDecoder } from "@payload-decoder/payload-decoder.model"; +import { PayloadDecoderService } from "@payload-decoder/payload-decoder.service"; +import { PayloadDeviceDatatargetService } from "@payload-decoder/payload-device-datatarget.service"; @Component({ selector: "app-datatarget-test-connection", @@ -12,7 +18,6 @@ import { MatSelectChange } from "@angular/material/select"; styleUrl: "./datatarget-test-connection.component.scss", }) export class DatatargetTestConnectionComponent implements OnInit, OnDestroy { - codeOutput = ""; editorJsonOutpuOptions = { theme: "vs", language: "json", @@ -21,21 +26,36 @@ export class DatatargetTestConnectionComponent implements OnInit, OnDestroy { minimap: { enabled: false }, readOnly: true, }; + public iotDevices: IotDevice[]; + public payloadDecoders: PayloadDecoder[]; public payloadData = ""; - + public testResponse = ""; + public decodedData = ""; + public dataTarget: Datatarget; + public payloadDecoderId: number; + public loading = false; + protected readonly DataTargetType = DataTargetType; private applicationId: number; + private dataTargetId: number; + private iotDeviceId: number; private subscriptions = []; constructor( private deviceService: IoTDeviceService, + private dataTargetService: DatatargetService, private route: ActivatedRoute, + private payloadDecoderService: PayloadDecoderService, + private payloadDeviceDataTargetService: PayloadDeviceDatatargetService, public applicationService: ApplicationService ) {} ngOnInit(): void { this.applicationId = +this.route.parent.snapshot.paramMap.get("id"); + this.dataTargetId = +this.route.parent.snapshot.paramMap.get("datatargetId"); this.getDevices(); + this.getDatatarget(); + this.getPayloadDecoders(); } ngOnDestroy() { @@ -53,12 +73,57 @@ export class DatatargetTestConnectionComponent implements OnInit, OnDestroy { } getLastPackage(event: MatSelectChange) { - const sub = this.deviceService.getIoTDevice(event.value).subscribe((device: IotDevice) => { + this.iotDeviceId = event.value; + const deviceSub = this.deviceService.getIoTDevice(event.value).subscribe((device: IotDevice) => { if (device.latestReceivedMessage) { this.payloadData = JSON.stringify(device.latestReceivedMessage.rawData, null, 2); } }); + const connectionSub = this.payloadDeviceDataTargetService.getByDataTarget(this.dataTargetId).subscribe(c => { + const connection = c.data.find(x => x.iotDevices.some(d => d.id === event.value)); + this.payloadDecoderId = connection.payloadDecoder.id; + }); + + this.subscriptions.push(deviceSub, connectionSub); + } + + pingDataTarget(dataPackage?: string) { + this.loading = true; + this.dataTargetService + .testDataTarget({ + dataTargetId: this.dataTargetId, + iotDeviceId: this.iotDeviceId, + payloadDecoderId: this.payloadDecoderId, + dataPackage: dataPackage, + }) + .subscribe( + response => { + this.testResponse = response?.result ? JSON.stringify(response.result, null, 2) : ""; + this.decodedData = response?.decodedPayload ? JSON.stringify(response.decodedPayload, null, 2) : ""; + }, + error => { + console.log(error); + }, + () => { + this.loading = false; + } + ); + } + + private getDatatarget() { + const dataTargetSubscription = this.dataTargetService.get(this.dataTargetId).subscribe((datatarget: Datatarget) => { + this.dataTarget = datatarget; + }); + + this.subscriptions.push(dataTargetSubscription); + } + + private getPayloadDecoders() { + const sub = this.payloadDecoderService.getMultiple(100, 0, "asc", "name").subscribe(({ data }) => { + this.payloadDecoders = data; + }); + this.subscriptions.push(sub); } } diff --git a/src/app/applications/datatarget/datatarget.model.ts b/src/app/applications/datatarget/datatarget.model.ts index ecebb18a..d63d806a 100644 --- a/src/app/applications/datatarget/datatarget.model.ts +++ b/src/app/applications/datatarget/datatarget.model.ts @@ -53,3 +53,10 @@ export class OddkMailInfo { comment?: string; sharingUrl?: string; } + +export class TestDataTargetDto { + dataTargetId: number; + iotDeviceId?: number; + payloadDecoderId?: number; + dataPackage?: string; +} diff --git a/src/app/applications/datatarget/datatarget.service.ts b/src/app/applications/datatarget/datatarget.service.ts index f6527bce..91cc1d04 100644 --- a/src/app/applications/datatarget/datatarget.service.ts +++ b/src/app/applications/datatarget/datatarget.service.ts @@ -2,7 +2,7 @@ import { Injectable } from "@angular/core"; import { Observable } from "rxjs"; import { DatatargetResponse } from "@applications/datatarget/datatarget-response.model"; import { RestService } from "@shared/services/rest.service"; -import { DatatargetData, Datatarget, OddkMailInfo } from "./datatarget.model"; +import { Datatarget, DatatargetData, OddkMailInfo, TestDataTargetDto } from "./datatarget.model"; import { map } from "rxjs/operators"; import { OpenDataDkDataset } from "./opendatadk/opendatadk-dataset.model"; import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; @@ -34,9 +34,6 @@ export class DatatargetService { limit, offset, applicationId, - // sort: sort, - // orderOn: orderOn, - // todo tilføj når iot-314 er tilføjet }; return this.restService.get(this.dataTargetURL, body); } @@ -65,6 +62,30 @@ export class DatatargetService { return this.restService.delete(this.dataTargetURL, id); } + getOpendataSharingApiUrl(): string { + return this.restService.createResourceUrl( + "open-data-dk-sharing", + this.sharedVariableService.getSelectedOrganisationId() + ); + } + + getOpenDataDkRegistered(organizationId: number): Observable { + return this.restService.get(this.dataTargetURL + "/getOpenDataDkRegistered", undefined, organizationId); + } + + updateOpenDataDkRegistered(organizationId: number): Observable { + return this.restService.put(this.dataTargetURL + "/updateOpenDataDkRegistered", undefined, organizationId); + } + + sendOpenDataDkMail(mailDto: OddkMailInfo): Observable { + mailDto.sharingUrl = this.getOpendataSharingApiUrl(); + return this.restService.post(this.dataTargetURL + "/sendOpenDataDkMail", mailDto); + } + + testDataTarget(testDataTargetDto: TestDataTargetDto): Observable { + return this.restService.post(this.dataTargetURL + "/testDataTarget", testDataTargetDto); + } + private trimModel(datatarget: Datatarget) { if (!datatarget.setToOpendataDk) { datatarget.openDataDkDataset = null; @@ -107,22 +128,4 @@ export class DatatargetService { model.openDataDkDataset.url = this.getOpendataSharingApiUrl(); return model; } - - getOpendataSharingApiUrl(): string { - return this.restService.createResourceUrl( - "open-data-dk-sharing", - this.sharedVariableService.getSelectedOrganisationId() - ); - } - - getOpenDataDkRegistered(organizationId: number): Observable { - return this.restService.get(this.dataTargetURL + "/getOpenDataDkRegistered", undefined, organizationId); - } - updateOpenDataDkRegistered(organizationId: number): Observable { - return this.restService.put(this.dataTargetURL + "/updateOpenDataDkRegistered", undefined, organizationId); - } - sendOpenDataDkMail(mailDto: OddkMailInfo): Observable { - mailDto.sharingUrl = this.getOpendataSharingApiUrl(); - return this.restService.post(this.dataTargetURL + "/sendOpenDataDkMail", mailDto); - } } diff --git a/src/app/applications/datatarget/fiware/fiware-detail/fiware-detail.component.ts b/src/app/applications/datatarget/fiware/fiware-detail/fiware-detail.component.ts index 8a0d423e..49e5dd3b 100644 --- a/src/app/applications/datatarget/fiware/fiware-detail/fiware-detail.component.ts +++ b/src/app/applications/datatarget/fiware/fiware-detail/fiware-detail.component.ts @@ -1,6 +1,6 @@ import { Component, OnDestroy } from "@angular/core"; import { ActivatedRoute } from "@angular/router"; -import { PayloadDeviceDatatargetGetByDataTarget } from "@app/payload-decoder/payload-device-data.model"; +import { PayloadDeviceDatatargetResponse } from "@app/payload-decoder/payload-device-data.model"; import { PayloadDeviceDatatargetService } from "@app/payload-decoder/payload-device-datatarget.service"; import { DatatargetDetail } from "@applications/datatarget/datatarget-detail/datatarget-detail"; import { faArrowsAltH } from "@fortawesome/free-solid-svg-icons"; @@ -17,7 +17,7 @@ export class FiwareDetailComponent implements DatatargetDetail, OnDestroy { arrowsAltH = faArrowsAltH; datatarget: Datatarget; - dataTargetRelations: PayloadDeviceDatatargetGetByDataTarget[]; + dataTargetRelations: PayloadDeviceDatatargetResponse[]; private subscriptions: Subscription[]; 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 3e361ce9..f7b54bd1 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 @@ -1,14 +1,14 @@ -import { Component, OnInit, Input, OnDestroy } from "@angular/core"; +import { Component, Input, OnDestroy, OnInit } from "@angular/core"; import { TranslateService } from "@ngx-translate/core"; import { ActivatedRoute, Router } from "@angular/router"; import { Datatarget } from "../../datatarget.model"; import { 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 { faQuestionCircle, faTimesCircle } from "@fortawesome/free-solid-svg-icons"; import { PayloadDeviceDatatarget, - PayloadDeviceDatatargetGetByDataTargetResponse, + PayloadDeviceDatatargetGetManyResponse, } from "@payload-decoder/payload-device-data.model"; import { DatatargetService } from "../../datatarget.service"; import { ApplicationService } from "@applications/application.service"; @@ -22,7 +22,6 @@ import { DeleteDialogComponent } from "@shared/components/delete-dialog/delete-d import { ErrorMessageService } from "@shared/error-message.service"; import { ScrollToTopService } from "@shared/services/scroll-to-top.service"; import { DataTargetType } from "@shared/enums/datatarget-type"; -import { faQuestionCircle } from "@fortawesome/free-solid-svg-icons"; import { DatatargetEdit } from "@applications/datatarget/datatarget-edit/datatarget-edit"; import { MeService } from "@shared/services/me.service"; import { OrganizationAccessScope } from "@shared/enums/access-scopes"; @@ -48,15 +47,15 @@ export class FiwareEditComponent implements DatatargetEdit, OnInit, OnDestroy { public errorFields: string[]; public formFailedSubmit = false; public datatargetid: number; - private applicationId: number; public application: Application; public devices: IotDevice[]; public payloadDecoders = []; - private counter: number; payloadDeviceDatatarget: PayloadDeviceDatatarget[]; newDynamic: any = {}; faQuestionCircle = faQuestionCircle; canEdit: boolean; + private applicationId: number; + private counter: number; constructor( public translate: TranslateService, @@ -117,17 +116,6 @@ export class FiwareEditComponent implements DatatargetEdit, OnInit, OnDestroy { }); } - private deleteRow(index) { - if (this.payloadDeviceDatatarget.length === 0) { - } else if (this.payloadDeviceDatatarget[index]?.id === null) { - this.payloadDeviceDatatarget.splice(index, 1); - } else { - this.payloadDeviceDataTargetService.delete(this.payloadDeviceDatatarget[index].id).subscribe(response => { - this.payloadDeviceDatatarget.splice(index, 1); - }); - } - } - openDeleteDialog(index) { const dialog = this.dialog.open(DeleteDialogComponent, { data: { @@ -213,7 +201,7 @@ export class FiwareEditComponent implements DatatargetEdit, OnInit, OnDestroy { getPayloadDeviceDatatarget(id: number) { this.relationSubscription = this.payloadDeviceDataTargetService .getByDataTarget(id) - .subscribe((response: PayloadDeviceDatatargetGetByDataTargetResponse) => { + .subscribe((response: PayloadDeviceDatatargetGetManyResponse) => { this.mapToDatatargetDevicePayload(response); }); } @@ -235,12 +223,6 @@ export class FiwareEditComponent implements DatatargetEdit, OnInit, OnDestroy { ); } - private resetErrors() { - this.errorFields = []; - this.errorMessages = undefined; - this.formFailedSubmit = false; - } - getDevices(): void { this.applicationSubscription = this.applicationService .getApplication(this.applicationId) @@ -281,6 +263,7 @@ export class FiwareEditComponent implements DatatargetEdit, OnInit, OnDestroy { replaceUrl: true, }); } + onCoordinateKey(event: any) { if (event.target.value.length > event.target.maxLength) { event.target.value = event.target.value.slice(0, event.target.maxLength); @@ -318,7 +301,24 @@ export class FiwareEditComponent implements DatatargetEdit, OnInit, OnDestroy { } } - private mapToDatatargetDevicePayload(dto: PayloadDeviceDatatargetGetByDataTargetResponse) { + private deleteRow(index) { + if (this.payloadDeviceDatatarget.length === 0) { + } else if (this.payloadDeviceDatatarget[index]?.id === null) { + this.payloadDeviceDatatarget.splice(index, 1); + } else { + this.payloadDeviceDataTargetService.delete(this.payloadDeviceDatatarget[index].id).subscribe(response => { + this.payloadDeviceDatatarget.splice(index, 1); + }); + } + } + + private resetErrors() { + this.errorFields = []; + this.errorMessages = undefined; + this.formFailedSubmit = false; + } + + private mapToDatatargetDevicePayload(dto: PayloadDeviceDatatargetGetManyResponse) { this.payloadDeviceDatatarget = []; dto.data.forEach(element => { this.payloadDeviceDatatarget.push({ diff --git a/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.ts b/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.ts index e66a67db..54d30d32 100644 --- a/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.ts +++ b/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.ts @@ -1,6 +1,6 @@ import { Component, OnDestroy } from "@angular/core"; import { ActivatedRoute } from "@angular/router"; -import { PayloadDeviceDatatargetGetByDataTarget } from "@app/payload-decoder/payload-device-data.model"; +import { PayloadDeviceDatatargetResponse } from "@app/payload-decoder/payload-device-data.model"; import { PayloadDeviceDatatargetService } from "@app/payload-decoder/payload-device-datatarget.service"; import { DatatargetDetail } from "@applications/datatarget/datatarget-detail/datatarget-detail"; import { faArrowsAltH } from "@fortawesome/free-solid-svg-icons"; @@ -19,7 +19,7 @@ export class HttppushDetailComponent implements DatatargetDetail, OnDestroy { arrowsAltH = faArrowsAltH; datatarget: Datatarget; - dataTargetRelations: PayloadDeviceDatatargetGetByDataTarget[]; + dataTargetRelations: PayloadDeviceDatatargetResponse[]; private subscriptions: Subscription[]; 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 7287283c..6bec04cb 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 @@ -1,4 +1,4 @@ -import { Component, OnInit, OnDestroy } from "@angular/core"; +import { Component, OnDestroy, OnInit } from "@angular/core"; import { TranslateService } from "@ngx-translate/core"; import { ActivatedRoute, Router } from "@angular/router"; import { Datatarget } from "../../datatarget.model"; @@ -8,7 +8,7 @@ import { IotDevice } from "@applications/iot-devices/iot-device.model"; import { faTimesCircle } from "@fortawesome/free-solid-svg-icons"; import { PayloadDeviceDatatarget, - PayloadDeviceDatatargetGetByDataTargetResponse, + PayloadDeviceDatatargetGetManyResponse, } from "@payload-decoder/payload-device-data.model"; import { DatatargetService } from "../../datatarget.service"; import { ApplicationService } from "@applications/application.service"; @@ -46,15 +46,14 @@ export class HttppushEditComponent implements DatatargetEdit, OnInit, OnDestroy public errorFields: string[]; public formFailedSubmit = false; public datatargetid: number; - private applicationId: number; public application: Application; public devices: IotDevice[]; public payloadDecoders = []; - private counter: number; - payloadDeviceDatatarget: PayloadDeviceDatatarget[]; newDynamic: any = {}; canEdit: boolean; + private applicationId: number; + private counter: number; constructor( public translate: TranslateService, @@ -116,17 +115,6 @@ export class HttppushEditComponent implements DatatargetEdit, OnInit, OnDestroy }); } - private deleteRow(index) { - if (this.payloadDeviceDatatarget.length === 0) { - } else if (this.payloadDeviceDatatarget[index]?.id === null) { - this.payloadDeviceDatatarget.splice(index, 1); - } else { - this.payloadDeviceDataTargetService.delete(this.payloadDeviceDatatarget[index].id).subscribe(response => { - this.payloadDeviceDatatarget.splice(index, 1); - }); - } - } - openDeleteDialog(index) { const dialog = this.dialog.open(DeleteDialogComponent, { data: { @@ -202,16 +190,6 @@ export class HttppushEditComponent implements DatatargetEdit, OnInit, OnDestroy }); } - private validatePayloadDeviceDatatarget = () => { - const isError = this.payloadDeviceDatatarget?.some(relation => (relation.iotDeviceIds?.length ?? 0) < 1); - if (isError) { - this.errorFields = ["devices"]; - this.errorMessages = ["Must attach at least one IoT-device for each element in list of devices / decoders"]; - this.scrollToTopService.scrollToTop(); - } - return !isError; - }; - countToRedirect() { this.counter -= 1; if (this.counter <= 0 && !this.formFailedSubmit) { @@ -223,7 +201,7 @@ export class HttppushEditComponent implements DatatargetEdit, OnInit, OnDestroy getPayloadDeviceDatatarget(id: number) { this.relationSubscription = this.payloadDeviceDataTargetService .getByDataTarget(id) - .subscribe((response: PayloadDeviceDatatargetGetByDataTargetResponse) => { + .subscribe((response: PayloadDeviceDatatargetGetManyResponse) => { this.mapToDatatargetDevicePayload(response); }); } @@ -245,12 +223,6 @@ export class HttppushEditComponent implements DatatargetEdit, OnInit, OnDestroy ); } - private resetErrors() { - this.errorFields = []; - this.errorMessages = undefined; - this.formFailedSubmit = false; - } - getDevices(): void { this.applicationSubscription = this.applicationService .getApplication(this.applicationId) @@ -323,7 +295,34 @@ export class HttppushEditComponent implements DatatargetEdit, OnInit, OnDestroy } } - private mapToDatatargetDevicePayload(dto: PayloadDeviceDatatargetGetByDataTargetResponse) { + private deleteRow(index) { + if (this.payloadDeviceDatatarget.length === 0) { + } else if (this.payloadDeviceDatatarget[index]?.id === null) { + this.payloadDeviceDatatarget.splice(index, 1); + } else { + this.payloadDeviceDataTargetService.delete(this.payloadDeviceDatatarget[index].id).subscribe(response => { + this.payloadDeviceDatatarget.splice(index, 1); + }); + } + } + + private validatePayloadDeviceDatatarget = () => { + const isError = this.payloadDeviceDatatarget?.some(relation => (relation.iotDeviceIds?.length ?? 0) < 1); + if (isError) { + this.errorFields = ["devices"]; + this.errorMessages = ["Must attach at least one IoT-device for each element in list of devices / decoders"]; + this.scrollToTopService.scrollToTop(); + } + return !isError; + }; + + private resetErrors() { + this.errorFields = []; + this.errorMessages = undefined; + this.formFailedSubmit = false; + } + + private mapToDatatargetDevicePayload(dto: PayloadDeviceDatatargetGetManyResponse) { this.payloadDeviceDatatarget = []; dto.data.forEach(element => { this.payloadDeviceDatatarget.push({ diff --git a/src/app/applications/datatarget/mqtt/mqtt-detail/mqtt-detail.component.ts b/src/app/applications/datatarget/mqtt/mqtt-detail/mqtt-detail.component.ts index dd870c64..1cff60dd 100644 --- a/src/app/applications/datatarget/mqtt/mqtt-detail/mqtt-detail.component.ts +++ b/src/app/applications/datatarget/mqtt/mqtt-detail/mqtt-detail.component.ts @@ -1,6 +1,6 @@ import { Component, OnDestroy } from "@angular/core"; import { ActivatedRoute } from "@angular/router"; -import { PayloadDeviceDatatargetGetByDataTarget } from "@app/payload-decoder/payload-device-data.model"; +import { PayloadDeviceDatatargetResponse } from "@app/payload-decoder/payload-device-data.model"; import { PayloadDeviceDatatargetService } from "@app/payload-decoder/payload-device-datatarget.service"; import { DatatargetDetail } from "@applications/datatarget/datatarget-detail/datatarget-detail"; import { faArrowsAltH } from "@fortawesome/free-solid-svg-icons"; @@ -17,7 +17,7 @@ export class MqttDetailComponent implements DatatargetDetail, OnDestroy { arrowsAltH = faArrowsAltH; datatarget: Datatarget; - dataTargetRelations: PayloadDeviceDatatargetGetByDataTarget[]; + dataTargetRelations: PayloadDeviceDatatargetResponse[]; private subscriptions: Subscription[]; diff --git a/src/app/applications/datatarget/mqtt/mqtt-edit/mqtt-edit.component.ts b/src/app/applications/datatarget/mqtt/mqtt-edit/mqtt-edit.component.ts index 0f7f9625..0a12f962 100644 --- a/src/app/applications/datatarget/mqtt/mqtt-edit/mqtt-edit.component.ts +++ b/src/app/applications/datatarget/mqtt/mqtt-edit/mqtt-edit.component.ts @@ -13,7 +13,7 @@ import { PayloadDecoder, PayloadDecoderMappedResponse } from "@payload-decoder/p import { PayloadDecoderService } from "@payload-decoder/payload-decoder.service"; import { PayloadDeviceDatatarget, - PayloadDeviceDatatargetGetByDataTargetResponse, + PayloadDeviceDatatargetGetManyResponse, } from "@payload-decoder/payload-device-data.model"; import { PayloadDeviceDatatargetService } from "@payload-decoder/payload-device-datatarget.service"; import { DeleteDialogComponent } from "@shared/components/delete-dialog/delete-dialog.component"; @@ -36,17 +36,17 @@ export class MqttEditComponent implements DatatargetEdit, OnInit, OnDestroy { public formFailedSubmit = false; public datatarget: Datatarget = new Datatarget(); public datatargetId: number; + public payloadDecoders: PayloadDecoder[] = []; + public payloadDeviceDatatarget: PayloadDeviceDatatarget[]; + public devices: IotDevice[]; + faTimesCircle = faTimesCircle; + faQuestionCircle = faQuestionCircle; private applicationId: number; private datatargetSubscription: Subscription; private applicationSubscription: Subscription; private relationSubscription: Subscription; private payloadDecoderSubscription: Subscription; - public payloadDecoders: PayloadDecoder[] = []; - public payloadDeviceDatatarget: PayloadDeviceDatatarget[]; - public devices: IotDevice[]; private activeApiCalls: number; - faTimesCircle = faTimesCircle; - faQuestionCircle = faQuestionCircle; constructor( private route: ActivatedRoute, @@ -76,20 +76,6 @@ export class MqttEditComponent implements DatatargetEdit, OnInit, OnDestroy { this.getPayloadDecoders(); } - private getPayloadDecoders() { - this.payloadDecoderSubscription = this.payloadDecoderService - .getMultiple(1000, 0, "id", "ASC") - .subscribe((response: PayloadDecoderMappedResponse) => { - this.payloadDecoders = response.data.sort((a, b) => a.name.localeCompare(b.name, "en", { numeric: true })); - }); - } - - private handleError(error: HttpErrorResponse) { - const errors = this.errorMessageService.handleErrorMessageWithFields(error); - this.errorFields = errors.errorFields; - this.errorMessages = errors.errorMessages; - this.scrollToTopService.scrollToTop(); - } routeToDatatargets() { this.router.navigate(["applications", this.applicationId, "data-targets"]); } @@ -117,23 +103,11 @@ export class MqttEditComponent implements DatatargetEdit, OnInit, OnDestroy { getPayloadDeviceDatatarget(id: number) { this.relationSubscription = this.payloadDeviceDatatargetService .getByDataTarget(id) - .subscribe((response: PayloadDeviceDatatargetGetByDataTargetResponse) => { + .subscribe((response: PayloadDeviceDatatargetGetManyResponse) => { this.mapToDatatargetDevicePayload(response); }); } - 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, - }); - }); - } - public selectAllDevices(index: number) { this.payloadDeviceDatatarget[index].iotDeviceIds = this.devices.map(device => device.id); } @@ -154,17 +128,6 @@ export class MqttEditComponent implements DatatargetEdit, OnInit, OnDestroy { }); } - private deleteRow(index) { - if (this.payloadDeviceDatatarget.length === 0) { - } else if (this.payloadDeviceDatatarget[index]?.id === null) { - this.payloadDeviceDatatarget.splice(index, 1); - } else { - this.payloadDeviceDatatargetService.delete(this.payloadDeviceDatatarget[index].id).subscribe(() => { - this.payloadDeviceDatatarget.splice(index, 1); - }); - } - } - openDeleteDialog(index) { const dialog = this.dialog.open(DeleteDialogComponent, { data: { @@ -181,13 +144,6 @@ export class MqttEditComponent implements DatatargetEdit, OnInit, OnDestroy { }); } - private resetErrors() { - this.errorFields = []; - this.errorMessages = undefined; - this.formFailedSubmit = false; - this.activeApiCalls = 0; - } - onSubmit(): void { this.resetErrors(); if (this.datatargetId) { @@ -198,6 +154,58 @@ export class MqttEditComponent implements DatatargetEdit, OnInit, OnDestroy { } } + ngOnDestroy(): void { + this.relationSubscription?.unsubscribe(); + this.applicationSubscription?.unsubscribe(); + this.datatargetSubscription?.unsubscribe(); + this.payloadDecoderSubscription?.unsubscribe(); + } + + private getPayloadDecoders() { + this.payloadDecoderSubscription = this.payloadDecoderService + .getMultiple(1000, 0, "id", "ASC") + .subscribe((response: PayloadDecoderMappedResponse) => { + this.payloadDecoders = response.data.sort((a, b) => a.name.localeCompare(b.name, "en", { numeric: true })); + }); + } + + private handleError(error: HttpErrorResponse) { + const errors = this.errorMessageService.handleErrorMessageWithFields(error); + this.errorFields = errors.errorFields; + this.errorMessages = errors.errorMessages; + this.scrollToTopService.scrollToTop(); + } + + private mapToDatatargetDevicePayload(dto: PayloadDeviceDatatargetGetManyResponse) { + 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, + }); + }); + } + + private deleteRow(index) { + if (this.payloadDeviceDatatarget.length === 0) { + } else if (this.payloadDeviceDatatarget[index]?.id === null) { + this.payloadDeviceDatatarget.splice(index, 1); + } else { + this.payloadDeviceDatatargetService.delete(this.payloadDeviceDatatarget[index].id).subscribe(() => { + this.payloadDeviceDatatarget.splice(index, 1); + }); + } + } + + private resetErrors() { + this.errorFields = []; + this.errorMessages = undefined; + this.formFailedSubmit = false; + this.activeApiCalls = 0; + } + private updateDatatarget(): void { this.activeApiCalls += 1; this.datatargetService.update(this.datatarget).subscribe( @@ -266,11 +274,4 @@ export class MqttEditComponent implements DatatargetEdit, OnInit, OnDestroy { this.routeToDatatargets(); } } - - ngOnDestroy(): void { - this.relationSubscription?.unsubscribe(); - this.applicationSubscription?.unsubscribe(); - this.datatargetSubscription?.unsubscribe(); - this.payloadDecoderSubscription?.unsubscribe(); - } } diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.ts b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.ts index 58b1b7b0..bbd0ebb1 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.ts +++ b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.ts @@ -12,7 +12,7 @@ import { PayloadDecoderMappedResponse } from "@payload-decoder/payload-decoder.m import { PayloadDecoderService } from "@payload-decoder/payload-decoder.service"; import { PayloadDeviceDatatarget, - PayloadDeviceDatatargetGetByDataTargetResponse, + PayloadDeviceDatatargetGetManyResponse, } from "@payload-decoder/payload-device-data.model"; import { PayloadDeviceDatatargetService } from "@payload-decoder/payload-device-datatarget.service"; import { DeleteDialogComponent } from "@shared/components/delete-dialog/delete-dialog.component"; @@ -62,18 +62,15 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { errorFields: string[]; datatarget: Datatarget = new Datatarget(); - private subscriptions = []; - formFailedSubmit = false; datatargetId: number; - private applicationId: number; devices: IotDevice[]; payloadDecoders = []; - private pendingRequestsCounter: number; - payloadDeviceDatatarget: PayloadDeviceDatatarget[]; canEdit: boolean; - + private subscriptions = []; + private applicationId: number; + private pendingRequestsCounter: number; private alreadySentOddkMail: boolean = false; constructor( @@ -120,11 +117,67 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { this.subscriptions.forEach(s => s?.unsubscribe()); } + onSubmit(): void { + this.resetErrors(); + if (this.datatargetId) { + if (!this.validatePayloadDeviceDatatarget()) return; + this.pendingRequestsCounter = 1 + (this.payloadDeviceDatatarget?.length ?? 0); + this.updateDatatarget(); + this.addPayloadDeviceDatatarget(); + } else { + this.createDatatarget(); + } + } + + routeToDatatargets = () => this.router.navigate(["applications", this.applicationId, "data-targets"]); + + routeToCreatedDatatarget = () => + this.router.navigate(["applications", this.applicationId, "datatarget", this.datatarget.id], { + replaceUrl: true, + }); + + addRow() { + if (!this.payloadDeviceDatatarget) { + this.payloadDeviceDatatarget = []; + } + this.payloadDeviceDatatarget.push({ + id: null, + iotDeviceIds: [], + payloadDecoderId: null, + dataTargetId: this.datatargetId, + }); + } + + openDeleteDialog(index) { + const dialog = this.dialog.open(DeleteDialogComponent, { + data: { + showAccept: true, + showCancel: true, + message: "Er du sikker på at du vil slette?", + }, + }); + dialog.afterClosed().subscribe(result => { + if (result === true) { + this.deleteRow(index); + } + }); + } + + payloadDevicesDropdownCompare = (o1: any, o2: any): boolean => o1 === o2; + + selectAllDevices(index: number) { + this.payloadDeviceDatatarget[index].iotDeviceIds = this.devices.map(device => device.id); + } + + deSelectAllDevices(index: number) { + this.payloadDeviceDatatarget[index].iotDeviceIds = []; + } + private getPayloadDeviceDatatarget(id: number) { this.subscriptions.push( this.payloadDeviceDataTargetService .getByDataTarget(id) - .subscribe((dto: PayloadDeviceDatatargetGetByDataTargetResponse) => { + .subscribe((dto: PayloadDeviceDatatargetGetManyResponse) => { this.payloadDeviceDatatarget = []; dto.data.forEach(element => { this.payloadDeviceDatatarget.push({ @@ -149,17 +202,6 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { ); } - onSubmit(): void { - this.resetErrors(); - if (this.datatargetId) { - if (!this.validatePayloadDeviceDatatarget()) return; - this.pendingRequestsCounter = 1 + (this.payloadDeviceDatatarget?.length ?? 0); - this.updateDatatarget(); - this.addPayloadDeviceDatatarget(); - } else { - this.createDatatarget(); - } - } private updateDatatarget() { this.subscriptions.push( this.datatargetService.update(this.datatarget).subscribe( @@ -178,6 +220,7 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { ) ); } + private addPayloadDeviceDatatarget() { this.payloadDeviceDatatarget.forEach(relation => { if (relation.payloadDecoderId === 0) { @@ -200,6 +243,7 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { } }); } + private validatePayloadDeviceDatatarget = () => { const isError = this.payloadDeviceDatatarget?.some(relation => (relation.iotDeviceIds?.length ?? 0) < 1); if (isError) { @@ -209,6 +253,7 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { } return !isError; }; + private createDatatarget() { this.pendingRequestsCounter = 0; this.datatarget.applicationId = this.applicationId; @@ -231,6 +276,7 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { ) ); } + private showMailOrRedirect = () => { if (!this.alreadySentOddkMail) { this.openMailDialog(); @@ -238,6 +284,7 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { this.routeToCreatedDatatarget(); } }; + // Note: When updating, we send multiple async request, and use this counter to know when everything is done, so we can redirect private countToRedirect() { this.pendingRequestsCounter -= 1; @@ -246,17 +293,20 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { this.showMailOrRedirect(); } } + private resetErrors() { this.errorFields = []; this.errorMessages = undefined; this.formFailedSubmit = false; } + private checkDataTargetModelOpendatadkdatasaet() { this.datatarget.setToOpendataDk = true; if (!this.datatarget.openDataDkDataset) { this.datatarget.openDataDkDataset = new OpenDataDkDataset(); } } + private handleError(error: HttpErrorResponse) { const errors = this.errorMessageService.handleErrorMessageWithFields(error); this.errorFields = errors.errorFields; @@ -264,12 +314,6 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { this.scrollToTopService.scrollToTop(); } - routeToDatatargets = () => this.router.navigate(["applications", this.applicationId, "data-targets"]); - routeToCreatedDatatarget = () => - this.router.navigate(["applications", this.applicationId, "datatarget", this.datatarget.id], { - replaceUrl: true, - }); - // For mail dialog private getAlreadySentOddkMail = () => { const orgId = this.sharedVariableService.getSelectedOrganisationId(); @@ -279,10 +323,12 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { }) ); }; + private setAlreadySentOddkMail = async () => { const orgId = this.sharedVariableService.getSelectedOrganisationId(); await this.datatargetService.updateOpenDataDkRegistered(orgId).pipe(first()).toPromise(); }; + private openMailDialog = () => { const dialog = this.dialog.open(OpenDataDkMailDialogComponent); dialog.afterClosed().subscribe(async (result: OddkMailInfo) => { @@ -296,6 +342,7 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { } }); }; + private openMailWarningDialog = () => { const dialog = this.dialog.open(OpenDataDkWarningDialogComponent); dialog.afterClosed().subscribe(async result => { @@ -320,6 +367,7 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { }) ); } + private getPayloadDecoders() { this.subscriptions.push( this.payloadDecoderService @@ -329,17 +377,7 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { }) ); } - addRow() { - if (!this.payloadDeviceDatatarget) { - this.payloadDeviceDatatarget = []; - } - this.payloadDeviceDatatarget.push({ - id: null, - iotDeviceIds: [], - payloadDecoderId: null, - dataTargetId: this.datatargetId, - }); - } + private deleteRow(index) { if (this.payloadDeviceDatatarget.length === 0) { } else if (this.payloadDeviceDatatarget[index]?.id === null) { @@ -352,25 +390,4 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { ); } } - openDeleteDialog(index) { - const dialog = this.dialog.open(DeleteDialogComponent, { - data: { - showAccept: true, - showCancel: true, - message: "Er du sikker på at du vil slette?", - }, - }); - dialog.afterClosed().subscribe(result => { - if (result === true) { - this.deleteRow(index); - } - }); - } - payloadDevicesDropdownCompare = (o1: any, o2: any): boolean => o1 === o2; - selectAllDevices(index: number) { - this.payloadDeviceDatatarget[index].iotDeviceIds = this.devices.map(device => device.id); - } - deSelectAllDevices(index: number) { - this.payloadDeviceDatatarget[index].iotDeviceIds = []; - } } diff --git a/src/app/payload-decoder/payload-device-data.model.ts b/src/app/payload-decoder/payload-device-data.model.ts index b3681339..0e218afe 100644 --- a/src/app/payload-decoder/payload-device-data.model.ts +++ b/src/app/payload-decoder/payload-device-data.model.ts @@ -9,11 +9,11 @@ export class PayloadDeviceDatatarget { dataTargetId: number; } -export interface PayloadDeviceDatatargetGetByDataTargetResponse { - data: PayloadDeviceDatatargetGetByDataTarget[]; +export interface PayloadDeviceDatatargetGetManyResponse { + data: PayloadDeviceDatatargetResponse[]; } -export interface PayloadDeviceDatatargetGetByDataTarget { +export interface PayloadDeviceDatatargetResponse { id: number; iotDevices: IotDevice[]; payloadDecoder: PayloadDecoder; diff --git a/src/app/payload-decoder/payload-device-datatarget.service.ts b/src/app/payload-decoder/payload-device-datatarget.service.ts index 8f517c8e..85e3037a 100644 --- a/src/app/payload-decoder/payload-device-datatarget.service.ts +++ b/src/app/payload-decoder/payload-device-datatarget.service.ts @@ -1,7 +1,7 @@ import { Injectable } from "@angular/core"; import { RestService } from "@shared/services/rest.service"; import { Observable } from "rxjs"; -import { PayloadDeviceDatatarget, PayloadDeviceDatatargetGetByDataTargetResponse } from "./payload-device-data.model"; +import { PayloadDeviceDatatarget, PayloadDeviceDatatargetGetManyResponse } from "./payload-device-data.model"; @Injectable({ providedIn: "root", @@ -30,11 +30,11 @@ export class PayloadDeviceDatatargetService { return this.restService.delete(this.BASEURL, id); } - getByDataTarget(id: number): Observable { + getByDataTarget(id: number): Observable { return this.restService.get(this.BASEURL + this.BYDATATARGETURL, null, id); } - mapToDatatargetDevicePayload(dto: PayloadDeviceDatatargetGetByDataTargetResponse): PayloadDeviceDatatarget[] { + mapToDatatargetDevicePayload(dto: PayloadDeviceDatatargetGetManyResponse): PayloadDeviceDatatarget[] { const payloadDeviceDatatargetList = []; dto.data.forEach(element => { payloadDeviceDatatargetList.push({ diff --git a/src/assets/i18n/da.json b/src/assets/i18n/da.json index 7fa6c614..d99d2d9d 100644 --- a/src/assets/i18n/da.json +++ b/src/assets/i18n/da.json @@ -281,14 +281,17 @@ }, "TEST_CONNECTION": { "TEST-CONNECTION": "Test forbindelse", - "SEND-PING-TO-DATATARGET": "Send et ping til dette datatarget", + "SEND-PING-TO-DATATARGET": "Forsøg at forbinde til datatarget", "SEND-LATEST-PACKAGE": "Send seneste datapakke", "CHOOSE-IOT-DEVICE": "Vælg IoT-enhed", + "CHOOSE-PAYLOAD-DECODER": "Vælg payload decoder", "SEND-DATA-PACKAGE": "Send datapakke", - "SEND-DATA-PACKAGE-DESCRIPTION": "Send seneste datapakke fra den valgte IoT-enhed til dette data target Bemærk at datapakken potentielt indgår i jeres driftsdata, hvis det modtages succesfuldt", + "SEND-DATA-PACKAGE-DESCRIPTION": "Send seneste datapakke fra den valgte IoT-enhed til dette data target\n Bemærk at datapakken potentielt indgår i jeres driftsdata, hvis det modtages succesfuldt", "CHOSEN-DATA-PACKAGE": "Valgt datapakke", - "SENT-HTTP-REQUEST": "Sendt - HTTP request", - "RECEIVED-HTTP-RESPONSE": "Modtaget - HTTP response", + "MQTT-DISCLAIMER": "\n Hvis datapakken fejler skal resultatet ses i loggen", + "SENT-DECODED-REQUEST": "Sendt - Dekodet request", + "RECEIVED-RESPONSE": "Modtaget", + "RESPONSE": "Svar", "HEADERS": "Headers", "BODY": "Body" } From cdc7f14b8707887eb7214764378e63afea7cb802 Mon Sep 17 00:00:00 2001 From: Frederik Christ Vestergaard Date: Mon, 30 Sep 2024 14:37:02 +0200 Subject: [PATCH 4/5] Most merge fix --- src/app/payload-decoder/payload-device-datatarget.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/payload-decoder/payload-device-datatarget.service.ts b/src/app/payload-decoder/payload-device-datatarget.service.ts index 5110c1df..37276d96 100644 --- a/src/app/payload-decoder/payload-device-datatarget.service.ts +++ b/src/app/payload-decoder/payload-device-datatarget.service.ts @@ -9,7 +9,7 @@ import { PayloadDeviceDatatarget, PayloadDeviceDatatargetGetManyResponse } from export class PayloadDeviceDatatargetService { private BASEURL = "iot-device-payload-decoder-data-target-connection"; private BYDATATARGETURL = "/byDataTarget"; - private BYDIOTDEVICEIDURL = "/byIoTDevice"; + private BYIOTDEVICEIURL = "/byIoTDevice"; constructor(private restService: RestService) {} @@ -36,7 +36,7 @@ export class PayloadDeviceDatatargetService { } getByIoTDevice(id: number): Observable { - return this.restService.get(this.BASEURL + this.BYDIOTDEVICEIDURL, null, id); + return this.restService.get(this.BASEURL + this.BYIOTDEVICEIURL, null, id); } mapToDatatargetDevicePayload(dto: PayloadDeviceDatatargetGetManyResponse): PayloadDeviceDatatarget[] { From 52770e9c27b175ae1d9137d705f183a0a069d834 Mon Sep 17 00:00:00 2001 From: Frederik Christ Vestergaard Date: Tue, 1 Oct 2024 09:01:13 +0200 Subject: [PATCH 5/5] PR fixes --- .../datatarget-detail-tabs-common.ts | 29 +++++------ .../datatarget-test-connection.component.html | 16 ++++--- .../datatarget-test-connection.component.scss | 8 +++- .../datatarget-test-connection.component.ts | 8 ++-- .../fiware-detail-tabs.component.scss | 48 +++++++++++++++++++ .../mqtt-detail-tabs.component.scss | 48 +++++++++++++++++++ .../payload-decoder/payload-decoder.model.ts | 10 ++++ .../payload-decoder.service.ts | 9 +++- 8 files changed, 145 insertions(+), 31 deletions(-) diff --git a/src/app/applications/datatarget/datatarget-detail/datatarget-detail-tabs-common.ts b/src/app/applications/datatarget/datatarget-detail/datatarget-detail-tabs-common.ts index 22b024c9..0faeff39 100644 --- a/src/app/applications/datatarget/datatarget-detail/datatarget-detail-tabs-common.ts +++ b/src/app/applications/datatarget/datatarget-detail/datatarget-detail-tabs-common.ts @@ -15,10 +15,7 @@ import { NavTab } from "@shared/types/nav-tabs.type"; import { Subscription } from "rxjs"; export abstract class DatatargetDetailTabsCommon implements DatatargetDetail { - protected abstract getDetailsLink(): string; - faExclamationTriangle = faExclamationTriangle; - logLink: "datatarget-log" = "datatarget-log"; testConnectionLink: "datatarget-test-connection" = "datatarget-test-connection"; navTabs: NavTab[] = [ @@ -33,17 +30,15 @@ export abstract class DatatargetDetailTabsCommon implements DatatargetDetail { index: 1, }, { - label: "Test forbindelse", + label: "DATATARGET.TEST_CONNECTION.TEST-CONNECTION", link: this.testConnectionLink, index: 2, }, ]; - datatarget: Datatarget; backButton: BackButton = { label: "", routerLink: undefined }; dropdownButton: DropdownButton; canEdit: boolean; - private subscriptions: Subscription[] = []; private deleteDialogSubscription: Subscription; @@ -85,16 +80,6 @@ export abstract class DatatargetDetailTabsCommon implements DatatargetDetail { this.canEdit = meService.hasAccessToTargetOrganization(OrganizationAccessScope.ApplicationWrite, undefined, appId); } - protected onDestroy(): void { - this.subscriptions?.forEach(s => s?.unsubscribe()); - this.deleteDialogSubscription?.unsubscribe(); - } - - private getDatatarget = (id: number) => - this.datatargetService.get(id).subscribe((dataTarget: Datatarget) => { - this.datatarget = dataTarget; - }); - onDeleteDatatarget() { this.deleteDialogSubscription?.unsubscribe(); this.deleteDialogSubscription = this.deleteDialogService.showSimpleDialog().subscribe(response => { @@ -112,4 +97,16 @@ export abstract class DatatargetDetailTabsCommon implements DatatargetDetail { ); }); } + + protected abstract getDetailsLink(): string; + + protected onDestroy(): void { + this.subscriptions?.forEach(s => s?.unsubscribe()); + this.deleteDialogSubscription?.unsubscribe(); + } + + private getDatatarget = (id: number) => + this.datatargetService.get(id).subscribe((dataTarget: Datatarget) => { + this.datatarget = dataTarget; + }); } diff --git a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.html b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.html index 309e6f4a..e044f0b4 100644 --- a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.html +++ b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.html @@ -41,42 +41,44 @@

{{ "DATATARGET.TEST_CONNECTION.TEST-CONNECTION" | translate }}

-
+

{{ "DATATARGET.TEST_CONNECTION.CHOSEN-DATA-PACKAGE" | translate }}

-
+

{{ "DATATARGET.TEST_CONNECTION.SENT-DECODED-REQUEST" | translate }}

-
+

{{ "DATATARGET.TEST_CONNECTION.RECEIVED-RESPONSE" | translate }}

-
- -
+
+ +
diff --git a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.scss b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.scss index cba444d1..c03d6211 100644 --- a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.scss +++ b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.scss @@ -1,3 +1,7 @@ -.marginTop5 { - margin-top: 5px !important +.height-85 { + height: 85%; +} + +.min-height-400 { + min-height: 400px; } diff --git a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.ts b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.ts index a825e759..77953158 100644 --- a/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.ts +++ b/src/app/applications/datatarget/datatarget-test-connection/datatarget-test-connection.component.ts @@ -8,7 +8,7 @@ import { MatSelectChange } from "@angular/material/select"; import { DatatargetService } from "@applications/datatarget/datatarget.service"; import { Datatarget } from "@applications/datatarget/datatarget.model"; import { DataTargetType } from "@shared/enums/datatarget-type"; -import { PayloadDecoder } from "@payload-decoder/payload-decoder.model"; +import { PayloadDecoderMinimal } from "@payload-decoder/payload-decoder.model"; import { PayloadDecoderService } from "@payload-decoder/payload-decoder.service"; import { PayloadDeviceDatatargetService } from "@payload-decoder/payload-device-datatarget.service"; @@ -28,7 +28,7 @@ export class DatatargetTestConnectionComponent implements OnInit, OnDestroy { }; public iotDevices: IotDevice[]; - public payloadDecoders: PayloadDecoder[]; + public payloadDecoders: PayloadDecoderMinimal[]; public payloadData = ""; public testResponse = ""; public decodedData = ""; @@ -120,8 +120,8 @@ export class DatatargetTestConnectionComponent implements OnInit, OnDestroy { } private getPayloadDecoders() { - const sub = this.payloadDecoderService.getMultiple(100, 0, "asc", "name").subscribe(({ data }) => { - this.payloadDecoders = data; + const sub = this.payloadDecoderService.getMinimal().subscribe(result => { + this.payloadDecoders = result.data; }); this.subscriptions.push(sub); diff --git a/src/app/applications/datatarget/fiware/fiware-detail-tabs/fiware-detail-tabs.component.scss b/src/app/applications/datatarget/fiware/fiware-detail-tabs/fiware-detail-tabs.component.scss index 3297737e..3c31f075 100644 --- a/src/app/applications/datatarget/fiware/fiware-detail-tabs/fiware-detail-tabs.component.scss +++ b/src/app/applications/datatarget/fiware/fiware-detail-tabs/fiware-detail-tabs.component.scss @@ -1,6 +1,54 @@ +@import "src/assets/scss/setup/variables"; + :host { .fa-error { color: red !important; margin-left: 5px; } } + +a { + color: $color-link; + border-bottom: 0px transparent !important; + cursor: pointer; + text-decoration: none; + + &:hover, + &.link-hover, + &:visited:hover { + color: $color-link-hover; + border-bottom: 0px $color-link-hover-bg !important; + + &:disabled, + .disabled { + background-color: transparent !important; + } + } + + &:active, + &.link-active { + background-color: inherit; + color: $color-active; + border-bottom: 0px $color-link-active-bg !important; + } + + &:focus, + &.link-focus { + color: $color-link-focus; + background-color: transparent; + border-bottom: 0px $color-link-focus-bg !important; + } + + &:disabled, + &.disabled { + box-shadow: none !important; + cursor: not-allowed !important; + //color: #000 !important; // FIXME: Hvad skal der der være her? + outline-offset: inherit !important; + + &:focus { + outline: none; + background-color: transparent; + } + } +} diff --git a/src/app/applications/datatarget/mqtt/mqtt-detail-tabs/mqtt-detail-tabs.component.scss b/src/app/applications/datatarget/mqtt/mqtt-detail-tabs/mqtt-detail-tabs.component.scss index 3297737e..3c31f075 100644 --- a/src/app/applications/datatarget/mqtt/mqtt-detail-tabs/mqtt-detail-tabs.component.scss +++ b/src/app/applications/datatarget/mqtt/mqtt-detail-tabs/mqtt-detail-tabs.component.scss @@ -1,6 +1,54 @@ +@import "src/assets/scss/setup/variables"; + :host { .fa-error { color: red !important; margin-left: 5px; } } + +a { + color: $color-link; + border-bottom: 0px transparent !important; + cursor: pointer; + text-decoration: none; + + &:hover, + &.link-hover, + &:visited:hover { + color: $color-link-hover; + border-bottom: 0px $color-link-hover-bg !important; + + &:disabled, + .disabled { + background-color: transparent !important; + } + } + + &:active, + &.link-active { + background-color: inherit; + color: $color-active; + border-bottom: 0px $color-link-active-bg !important; + } + + &:focus, + &.link-focus { + color: $color-link-focus; + background-color: transparent; + border-bottom: 0px $color-link-focus-bg !important; + } + + &:disabled, + &.disabled { + box-shadow: none !important; + cursor: not-allowed !important; + //color: #000 !important; // FIXME: Hvad skal der der være her? + outline-offset: inherit !important; + + &:focus { + outline: none; + background-color: transparent; + } + } +} diff --git a/src/app/payload-decoder/payload-decoder.model.ts b/src/app/payload-decoder/payload-decoder.model.ts index be3f25af..fc05a3d1 100644 --- a/src/app/payload-decoder/payload-decoder.model.ts +++ b/src/app/payload-decoder/payload-decoder.model.ts @@ -71,3 +71,13 @@ export interface GetPayloadDecoderParameters { orderOn: string; organizationId?: number; } + +export class PayloadDecoderMinimal { + name: string; + id: number; +} + +export interface PayloadDecoderMinimalResponse { + data: PayloadDecoderMinimal[]; + count: number; +} diff --git a/src/app/payload-decoder/payload-decoder.service.ts b/src/app/payload-decoder/payload-decoder.service.ts index e6692967..5c287031 100644 --- a/src/app/payload-decoder/payload-decoder.service.ts +++ b/src/app/payload-decoder/payload-decoder.service.ts @@ -2,11 +2,12 @@ import { Injectable } from "@angular/core"; import { RestService } from "../shared/services/rest.service"; import { Observable } from "rxjs"; import { - PayloadDecoderResponse, + GetPayloadDecoderParameters, PayloadDecoder, PayloadDecoderBodyResponse, PayloadDecoderMappedResponse, - GetPayloadDecoderParameters, + PayloadDecoderMinimalResponse, + PayloadDecoderResponse, } from "src/app/payload-decoder/payload-decoder.model"; import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; import { map } from "rxjs/operators"; @@ -101,6 +102,10 @@ export class PayloadDecoderService { ); } + getMinimal(): Observable { + return this.restService.get(this.URL + "/minimal"); + } + delete(id: number) { return this.restService.delete(this.URL, id); }