From 2c831030f2a4889413dc6ebc87d7a5231528e59d Mon Sep 17 00:00:00 2001 From: Chris Johansen Date: Wed, 19 Apr 2023 17:50:34 +0200 Subject: [PATCH 1/5] IOT-1416: Made the main changes to OpenDataDK data-target in UI (including cleaning up HTTP Push) and controller. Still missing some details, like keyworks-input etc.. --- .../datatarget/datatarget-types.service.ts | 3 +- .../datatarget/datatarget.service.ts | 1 + .../fiware-edit/fiware-edit.component.ts | 2 +- .../httppush-detail.component.html | 22 +- .../httppush-detail.component.ts | 5 +- .../httppush-edit.component.html | 12 +- .../httppush-edit/httppush-edit.component.ts | 77 +--- .../opendatadk/opendatadk-dataset.model.ts | 2 +- .../opendatadk-detail.component.html | 4 +- .../opendatadk-edit.component.html | 432 +++++++++++++++--- .../opendatadk-edit.component.scss | 4 + .../opendatadk-edit.component.ts | 364 ++++++++++++++- src/assets/i18n/da.json | 29 +- 13 files changed, 776 insertions(+), 181 deletions(-) diff --git a/src/app/applications/datatarget/datatarget-types.service.ts b/src/app/applications/datatarget/datatarget-types.service.ts index 67e7f9592..a1ef01684 100644 --- a/src/app/applications/datatarget/datatarget-types.service.ts +++ b/src/app/applications/datatarget/datatarget-types.service.ts @@ -9,6 +9,7 @@ import { HttppushDetailComponent } from './httppush/httppush-detail/httppush-det import { HttppushEditComponent } from './httppush/httppush-edit/httppush-edit.component'; import { MqttDetailComponent } from './mqtt-detail/mqtt-detail.component'; import { MqttEditComponent } from './mqtt-edit/mqtt-edit.component'; +import { OpendatadkEditComponent } from './opendatadk/opendatadk-edit/opendatadk-edit.component'; @Injectable({ providedIn: 'root', @@ -77,7 +78,7 @@ export class DatatargetTypesService { } if (dataTargetType === DataTargetType.OPENDATADK) { - return HttppushEditComponent; + return OpendatadkEditComponent; } if (dataTargetType === DataTargetType.FIWARE) { diff --git a/src/app/applications/datatarget/datatarget.service.ts b/src/app/applications/datatarget/datatarget.service.ts index e803524f3..8a7afad94 100644 --- a/src/app/applications/datatarget/datatarget.service.ts +++ b/src/app/applications/datatarget/datatarget.service.ts @@ -78,6 +78,7 @@ export class DatatargetService { datatarget.openDataDkDataset = null; } if (datatarget.setToOpendataDk) { + //TODO: Probably not needed if we have multi-select drop-down..? datatarget.openDataDkDataset.keywords = datatarget.openDataDkDataset?.keywordsInput?.split(','); datatarget.openDataDkDataset.keywordsInput = undefined; } 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 afc7d21c9..32fb4fb4d 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 @@ -2,7 +2,7 @@ import { Component, OnInit, Input, OnDestroy } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { ActivatedRoute, Router } from '@angular/router'; import { Datatarget } from '../../datatarget.model'; -import { Observable, Subscription } from 'rxjs'; +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'; diff --git a/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.html b/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.html index ad21eba71..37b36bcf1 100644 --- a/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.html +++ b/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.html @@ -8,19 +8,23 @@

{{ 'DATATARGET.DETAILS' | translate }}

-

{{ 'DATATARGET.URL' | translate }}{{datatarget.url}}

-

{{ 'DATATARGET.TIMEOUT' | translate }}{{datatarget.timeout}}

+ +

{{ 'DATATARGET.URL' | translate }}{{datatarget.url}}

+

{{ 'DATATARGET.TIMEOUT' | translate }}{{datatarget.timeout}}

+

{{ 'DATATARGET.TYPE' | translate }}{{'DATATARGET.' + datatarget.type + '.TYPE' | translate}}

- -

{{ 'DATATARGET.AUTHORIZATIONHEADER' | translate }}

-
{{datatarget.authorizationHeader}}
- -

{{ 'DATATARGET.NO-AUTHORIZATIONHEADER' | translate }}

-
+ + +

{{ 'DATATARGET.AUTHORIZATIONHEADER' | translate }}

+
{{datatarget.authorizationHeader}}
+ +

{{ 'DATATARGET.NO-AUTHORIZATIONHEADER' | translate }}

+
+
-
+

{{ 'DATATARGET.OPENDATA-DK.TYPE' | translate }}

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 844f9c3a3..47878a841 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 @@ -14,6 +14,7 @@ import { faArrowsAltH } from '@fortawesome/free-solid-svg-icons'; import { DatatargetDetail } from '@applications/datatarget/datatarget-detail/datatarget-detail'; import { MeService } from '@shared/services/me.service'; import { OrganizationAccessScope } from '@shared/enums/access-scopes'; +import { DataTargetType } from '@shared/enums/datatarget-type'; @Component({ selector: 'app-httppush-detail', @@ -22,6 +23,8 @@ import { OrganizationAccessScope } from '@shared/enums/access-scopes'; }) export class HttppushDetailComponent implements DatatargetDetail, OnInit, OnDestroy { + dataTargetType = DataTargetType; + public datatargetSubscription: Subscription; public datatarget: Datatarget; public backButton: BackButton = { label: '', routerLink: undefined }; @@ -29,7 +32,6 @@ export class HttppushDetailComponent private deleteDialogSubscription: Subscription; public dropdownButton: DropdownButton; arrowsAltH = faArrowsAltH; - private applicationName: string; canEdit: boolean; constructor( @@ -45,7 +47,6 @@ export class HttppushDetailComponent ngOnInit(): void { const id: number = +this.route.snapshot.paramMap.get('datatargetId'); const appId: number = +this.route.snapshot.paramMap.get('id'); - this.applicationName = this.route.snapshot.paramMap.get('name'); if (id) { this.getDatatarget(id); this.getDatatargetRelations(id); diff --git a/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.html b/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.html index 73725f599..b43dabc25 100644 --- a/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.html +++ b/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.html @@ -12,14 +12,8 @@
- - {{'DATATARGET.ADD-TO-OPENDATADK' | translate}} -
-
+
*
-
- -
+
{{'QUESTION.DATATARGET.RELATIONS' | translate}}
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 0ee5bac9a..f5e2b6486 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,8 +1,8 @@ -import { Component, OnInit, Input, OnDestroy } from '@angular/core'; +import { Component, OnInit, OnDestroy } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { ActivatedRoute, Router } from '@angular/router'; import { Datatarget } from '../../datatarget.model'; -import { Observable, Subscription } from 'rxjs'; +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'; @@ -20,11 +20,7 @@ import { HttpErrorResponse } from '@angular/common/http'; import { PayloadDecoderMappedResponse } from '@payload-decoder/payload-decoder.model'; import { DeleteDialogComponent } from '@shared/components/delete-dialog/delete-dialog.component'; import { ErrorMessageService } from '@shared/error-message.service'; -import { OpendatadkDialogService } from '@shared/components/opendatadk-dialog/opendatadk-dialog.service'; -import { OpendatadkService } from '@shared/services/opendatadk.service'; import { ScrollToTopService } from '@shared/services/scroll-to-top.service'; -import { OpenDataDkDataset } from '../../opendatadk/opendatadk-dataset.model'; -import { DataTargetType } from '@shared/enums/datatarget-type'; import { DatatargetEdit } from '@applications/datatarget/datatarget-edit/datatarget-edit'; import { MeService } from '@shared/services/me.service'; import { OrganizationAccessScope } from '@shared/enums/access-scopes'; @@ -52,13 +48,10 @@ export class HttppushEditComponent public formFailedSubmit = false; public datatargetid: number; private applicationId: number; - private applicationName: string; public application: Application; public devices: IotDevice[]; public payloadDecoders = []; private counter: number; - private dataSetExcists = false; - private isMailDialogAlreadyShown = false; payloadDeviceDatatarget: PayloadDeviceDatatarget[]; newDynamic: any = {}; @@ -75,8 +68,6 @@ export class HttppushEditComponent private saveSnackService: SnackService, private dialog: MatDialog, private errorMessageService: ErrorMessageService, - private opendatadkService: OpendatadkService, - private opendatadkDialogService: OpendatadkDialogService, private scrollToTopService: ScrollToTopService, private meService: MeService ) { @@ -104,7 +95,6 @@ export class HttppushEditComponent this.datatargetid = +this.route.snapshot.paramMap.get('datatargetId'); this.applicationId = +this.route.snapshot.paramMap.get('id'); - this.applicationName = this.route.snapshot.paramMap.get('name'); if (this.datatargetid !== 0) { this.getDatatarget(this.datatargetid); this.getPayloadDeviceDatatarget(this.datatargetid); @@ -113,7 +103,6 @@ export class HttppushEditComponent this.getDevices(); } this.getPayloadDecoders(); - this.setDataSetExcists(); this.canEdit = this.meService.hasAccessToTargetOrganization( OrganizationAccessScope.ApplicationWrite, undefined, @@ -186,15 +175,8 @@ export class HttppushEditComponent this.datatargetService.update(this.datatarget).subscribe( (response: Datatarget) => { this.datatarget = response; - if (this.datatarget.openDataDkDataset != null) { - this.datatarget.openDataDkDataset.acceptTerms = true; - } - this.shouldShowMailDialog().subscribe((response) => { - this.countToRedirect(); - }); }, (error: HttpErrorResponse) => { - this.checkDataTargetModelOpendatadkdatasaet(); this.handleError(error); this.formFailedSubmit = true; } @@ -253,14 +235,10 @@ export class HttppushEditComponent (response: Datatarget) => { this.datatargetid = response.id; this.datatarget = response; - if (this.datatarget.openDataDkDataset != null) { - this.datatarget.openDataDkDataset.acceptTerms = true; - } this.showSavedSnack(); this.routeToDatatargets(); }, (error: HttpErrorResponse) => { - this.checkDataTargetModelOpendatadkdatasaet(); this.handleError(error); this.formFailedSubmit = true; } @@ -273,12 +251,6 @@ export class HttppushEditComponent this.formFailedSubmit = false; } - checkDataTargetModelOpendatadkdatasaet() { - if (!this.datatarget.openDataDkDataset) { - this.datatarget.openDataDkDataset = new OpenDataDkDataset(); - } - } - getDevices(): void { this.applicationSubscription = this.applicationService .getApplication(this.applicationId) @@ -338,51 +310,8 @@ export class HttppushEditComponent this.saveSnackService.showSavedSnack(); } - private setDataSetExcists() { - this.opendatadkService.get().subscribe((response) => { - this.dataSetExcists = response.dataset.length === 0 ? false : true; - }); - } - - private shouldShowMailDialog(): Observable { - return new Observable((observer) => { - if ( - !this.dataSetExcists && - this.datatarget.setToOpendataDk && - !this.isMailDialogAlreadyShown - ) { - this.isMailDialogAlreadyShown = true; - this.opendatadkDialogService.showDialog().subscribe((response) => { - if (response) { - this.showMailClient(); - } - observer.next(response); - }); - } else { - observer.next(true); - } - }); - } - - private showMailClient() { - if (!this.datatarget.openDataDkDataset.url) { - this.datatarget.openDataDkDataset.url = this.datatargetService.getOpendataSharingApiUrl(); - } - window.location.href = - 'mailto:FG2V@kk.dk?subject=Oprettelse%20af%20datas%C3%A6t%20i%20OpenDataDK&body=K%C3%A6re%20Frans%0D%0A%0D%0AHermed%20fremsendes%20linket%20til%20DCAT%20kataloget%20%2C%20du%20bedes%20registrere%20p%C3%A5%20Open%20Data%20DK%20platformen.%0D%0A%0D%0ALink%3A ' + - this.datatarget.openDataDkDataset.url; - } - disableSaveButton(): boolean { - let disable = true; - if (!this.datatarget.setToOpendataDk) { - disable = false; - } else if (this.datatarget.openDataDkDataset?.acceptTerms) { - disable = false; - } else { - disable = true; - } - return disable; + return false; } ngOnDestroy(): void { diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-dataset.model.ts b/src/app/applications/datatarget/opendatadk/opendatadk-dataset.model.ts index 36fe3b5cb..031f23095 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-dataset.model.ts +++ b/src/app/applications/datatarget/opendatadk/opendatadk-dataset.model.ts @@ -5,7 +5,7 @@ export class OpenDataDkDataset { description: string; keywords: string[]; keywordsInput: string; - license = 'http://portal.opendata.dk/dataset/open-data-dk-licens'; + license = 'https://creativecommons.org/publicdomain/zero/1.0/'; authorName: string; //required authorEmail: string; //reqired url: string; // autogenerated with orgid as input diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.html b/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.html index e2beb2af0..f505eb538 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.html +++ b/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.html @@ -18,10 +18,10 @@ {{openDataDkDataset.keywords ? openDataDkDataset.keywords : ('OPENDATADK.DETAILS.NA' | translate) }}

-

+

{{ 'OPENDATADK.DETAILS.AUTHORNAME' | translate }} diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.html b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.html index 9030bc5a8..9ebca19a6 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.html +++ b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.html @@ -1,86 +1,386 @@ -

-

- OpenDataDK datasæt -

-
-
+ + + +
+
+
    +
  • {{ error | translate }}
  • +
+
+ + + + + +

+ {{ 'OPENDATADK.INTRO.GUIDE_HEADER' | translate }} +

+
+
+

+ {{ 'OPENDATADK.INTRO.GUIDE1' | translate }} +

+ {{ 'OPENDATADK.INTRO.GUIDE2' | translate }} +

+ {{ 'OPENDATADK.INTRO.GUIDE3' | translate }} +

+ {{ 'OPENDATADK.INTRO.GUIDE4' | translate }} + {{ 'OPENDATADK.INTRO.GUIDE5' | translate }} +

+

+
+ + + + +

+ {{ 'OPENDATADK.INTRO.PROCEDURE_HEADER' | translate }} +

+
+
+
    +
  1. + 1. {{ 'OPENDATADK.INTRO.PROCEDURE1' | translate }} + https://www.opendata.dk/ +

  2. +
  3. 2. {{ 'OPENDATADK.INTRO.PROCEDURE2' | translate }}

  4. +
  5. 3. {{ 'OPENDATADK.INTRO.PROCEDURE3' | translate }}

  6. +
  7. + 4. {{ 'OPENDATADK.INTRO.PROCEDURE4' | translate }} + {{ 'OPENDATADK.INTRO.PROCEDURE4_LINK' | translate }} +

  8. +
+
+ + +
+
+ + + + +
+
+ + +
- * - + + + +
-
+
-
+ +
- - + + + +
-
+
-
+ +
- * - + +
-
+
-
+ +
- * - + + + +
-
+
-
+ +
- - + +
-
+
-
+ + +
- - + +
-
+
-
+ + +
- -

- {{'OPENDATADK.QUESTION.ACCEPT-TERMS-PART-ONE' | translate}} - - {{'OPENDATADK.QUESTION.TERMS-AND-CONDITIONS' | translate}} - -

-

- {{'OPENDATADK.QUESTION.ACCEPT-TERMS-PART-TWO' | translate}} -

-
+ +

+ {{ 'OPENDATADK.QUESTION.ACCEPT-TERMS-PART-ONE' | translate }} + + {{ 'OPENDATADK.QUESTION.TERMS-AND-CONDITIONS' | translate }} + +

+

{{ 'OPENDATADK.QUESTION.ACCEPT-TERMS-PART-TWO' | translate }}

+
-
\ No newline at end of file +
+ + +
{{ 'QUESTION.DATATARGET.RELATIONS' | translate }}
+ + + +
+ + {{'QUESTION.ADD-RELATIONS' | translate}} + + + + + + + + + + +
+
+ + {{'QUESTION.DATATARGET.SELECT-DEVICES' | translate}} + + + + + + {{ device.name }} + + +
+
+
+ + {{ + 'QUESTION.DATATARGET.SELECT-PAYLOADDECODER' | translate + }} + + + {{ + 'QUESTION.DATATARGET.NO-PAYLOAD-DECODER-SELECTED' + | translate + }} + + + {{ payloadDecoder.name }} + + + +
+
+ +
+ +

{{ 'DATATARGET.DELETE' | translate }}

+
+
+
+
+
+ + +
+ + +
+ diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.scss b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.scss index e69de29bb..276abe9d1 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.scss +++ b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.scss @@ -0,0 +1,4 @@ +.form-info-icon { + margin-left: 5px; + cursor: pointer; +} 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 8ec2e7a2b..355c50e11 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 @@ -1,21 +1,363 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { OpenDataDkDataset } from '../opendatadk-dataset.model'; +import { HttpErrorResponse } from '@angular/common/http'; +import { Component, OnDestroy } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { ActivatedRoute, Router } from '@angular/router'; +import { Application } from '@applications/application.model'; +import { ApplicationService } from '@applications/application.service'; +import { DatatargetEdit } from '@applications/datatarget/datatarget-edit/datatarget-edit'; +import { IotDevice } from '@applications/iot-devices/iot-device.model'; +import { + faQuestionCircle, + faTimesCircle, +} from '@fortawesome/free-solid-svg-icons'; +import { TranslateService } from '@ngx-translate/core'; +import { PayloadDecoderMappedResponse } from '@payload-decoder/payload-decoder.model'; +import { PayloadDecoderService } from '@payload-decoder/payload-decoder.service'; +import { + PayloadDeviceDatatarget, + PayloadDeviceDatatargetGetByDataTargetResponse, +} 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'; +import { OpendatadkDialogService } from '@shared/components/opendatadk-dialog/opendatadk-dialog.service'; +import { OrganizationAccessScope } from '@shared/enums/access-scopes'; +import { DataTargetType } from '@shared/enums/datatarget-type'; +import { ErrorMessageService } from '@shared/error-message.service'; +import { MeService } from '@shared/services/me.service'; +import { OpendatadkService } from '@shared/services/opendatadk.service'; +import { ScrollToTopService } from '@shared/services/scroll-to-top.service'; +import { SnackService } from '@shared/services/snack.service'; +import { Observable, Subscription } from 'rxjs'; +import { Datatarget } from '../../datatarget.model'; +import { DatatargetService } from '../../datatarget.service'; +import { OpenDataDkDataset } from '../../opendatadk/opendatadk-dataset.model'; @Component({ selector: 'app-opendatadk-edit', templateUrl: './opendatadk-edit.component.html', styleUrls: ['./opendatadk-edit.component.scss'], }) -export class OpendatadkEditComponent implements OnInit { - public errorMessages: any; - @Input() errorFields: string[]; - @Input() formFailedSubmit = false; - @Input() openDataDk: OpenDataDkDataset; +export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { + faQuestionCircle = faQuestionCircle; + faTimesCircle = faTimesCircle; - constructor() {} + title = 'FORM.CREATE-NEW-DATATARGET'; - ngOnInit(): void { - // Set box to checked, if this already exists. - this.openDataDk.acceptTerms = this.openDataDk.id != null; + errorMessages: any[]; + errorFields: string[]; + + datatarget: Datatarget = new Datatarget(); + private datatargetSubscription: Subscription; + private relationSubscription: Subscription; + private applicationSubscription: Subscription; + private payloadDecoderSubscription: Subscription; + private dataExistsSubscription: Subscription; + + formFailedSubmit = false; + datatargetId: number; + private applicationId: number; + devices: IotDevice[]; + payloadDecoders = []; + private counter: number; + private dataSetExists = false; + private isMailDialogAlreadyShown = false; + + payloadDeviceDatatarget: PayloadDeviceDatatarget[]; + canEdit: boolean; + + constructor( + translate: TranslateService, + private route: ActivatedRoute, + private router: Router, + private datatargetService: DatatargetService, + private applicationService: ApplicationService, + private payloadDecoderService: PayloadDecoderService, + private payloadDeviceDataTargetService: PayloadDeviceDatatargetService, + private saveSnackService: SnackService, + private dialog: MatDialog, + private errorMessageService: ErrorMessageService, + private opendatadkService: OpendatadkService, + private opendatadkDialogService: OpendatadkDialogService, + private scrollToTopService: ScrollToTopService, + private meService: MeService + ) { + translate.use('da'); + + this.datatarget.type = DataTargetType.OPENDATADK; + this.datatarget.setToOpendataDk = true; + + this.datatargetId = +this.route.snapshot.paramMap.get('datatargetId'); + this.applicationId = +this.route.snapshot.paramMap.get('id'); + if (this.datatargetId !== 0) { + this.title = 'FORM.EDIT-DATATARGET'; + this.getDatatarget(this.datatargetId); + this.getPayloadDeviceDatatarget(this.datatargetId); + } + if (this.applicationId !== 0) { + this.getDevices(); + } + this.getPayloadDecoders(); + this.getDataSetExists(); + this.canEdit = this.meService.hasAccessToTargetOrganization( + OrganizationAccessScope.ApplicationWrite, + undefined, + this.applicationId + ); + } + + ngOnDestroy(): void { + this.relationSubscription?.unsubscribe(); + this.applicationSubscription?.unsubscribe(); + this.datatargetSubscription?.unsubscribe(); + this.payloadDecoderSubscription?.unsubscribe(); + this.dataExistsSubscription?.unsubscribe(); + } + + private getPayloadDeviceDatatarget(id: number) { + this.relationSubscription = this.payloadDeviceDataTargetService + .getByDataTarget(id) + .subscribe((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, + }); + }); + }); + } + + private getDatatarget(id: number) { + this.datatargetSubscription = this.datatargetService + .get(id) + .subscribe((response: Datatarget) => { + this.datatarget = response; + if (this.datatarget.openDataDkDataset != null) { + this.datatarget.openDataDkDataset.acceptTerms = true; + } + }); + } + private getDataSetExists() { + this.dataExistsSubscription = this.opendatadkService + .get() + .subscribe((response) => { + this.dataSetExists = response.dataset.length !== 0; + }); + } + + onSubmit(): void { + this.resetErrors(); + if (this.datatargetId) { + this.updateDatatarget(); + this.addPayloadDeviceDatatarget(); + } else { + this.createDatatarget(); + } + } + private updateDatatarget() { + this.counter = 1 + (this.payloadDeviceDatatarget?.length ?? 0); + this.datatargetService.update(this.datatarget).subscribe( + (response: Datatarget) => { + this.datatarget = response; + if (this.datatarget.openDataDkDataset != null) { + this.datatarget.openDataDkDataset.acceptTerms = true; + } + this.shouldShowMailDialog().subscribe((response) => { + this.countToRedirect(); + }); + }, + (error: HttpErrorResponse) => { + this.checkDataTargetModelOpendatadkdatasaet(); + this.handleError(error); + this.formFailedSubmit = true; + } + ); + } + private addPayloadDeviceDatatarget() { + this.payloadDeviceDatatarget.map((pdd) => { + if (pdd.payloadDecoderId === 0) { + pdd.payloadDecoderId = null; + } + }); + this.payloadDeviceDatatarget.forEach((relation) => { + if (relation.id) { + this.payloadDeviceDataTargetService.put(relation).subscribe( + (response) => { + this.countToRedirect(); + }, + (error) => { + this.handleError(error); + } + ); + } else { + this.payloadDeviceDataTargetService.post(relation).subscribe( + (res: any) => { + this.countToRedirect(); + }, + (error) => { + this.handleError(error); + } + ); + } + }); + } + private createDatatarget() { + this.counter = 0; + this.datatarget.applicationId = this.applicationId; + this.datatargetService.create(this.datatarget).subscribe( + (response: Datatarget) => { + this.datatargetId = response.id; + this.datatarget = response; + if (this.datatarget.openDataDkDataset != null) { + this.datatarget.openDataDkDataset.acceptTerms = true; + } + this.saveSnackService.showSavedSnack(); + this.routeToDatatargets(); + }, + (error: HttpErrorResponse) => { + this.checkDataTargetModelOpendatadkdatasaet(); + this.handleError(error); + this.formFailedSubmit = true; + } + ); + } + private countToRedirect() { + this.counter -= 1; + if (this.counter <= 0 && !this.formFailedSubmit) { + this.saveSnackService.showSavedSnack(); + this.routeToDatatargets(); + } + } + 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; + this.errorMessages = errors.errorMessages; + this.scrollToTopService.scrollToTop(); + } + private shouldShowMailDialog(): Observable { + return new Observable((observer) => { + if ( + !this.dataSetExists && + this.datatarget.setToOpendataDk && + !this.isMailDialogAlreadyShown + ) { + this.isMailDialogAlreadyShown = true; + this.opendatadkDialogService.showDialog().subscribe((response) => { + if (response) { + this.showMailClient(); + } + observer.next(response); + }); + } else { + observer.next(true); + } + }); + } + private showMailClient() { + if (!this.datatarget.openDataDkDataset.url) { + this.datatarget.openDataDkDataset.url = this.datatargetService.getOpendataSharingApiUrl(); + } + window.location.href = + 'mailto:FG2V@kk.dk?subject=Oprettelse%20af%20datas%C3%A6t%20i%20OpenDataDK&body=K%C3%A6re%20Frans%0D%0A%0D%0AHermed%20fremsendes%20linket%20til%20DCAT%20kataloget%20%2C%20du%20bedes%20registrere%20p%C3%A5%20Open%20Data%20DK%20platformen.%0D%0A%0D%0ALink%3A ' + + this.datatarget.openDataDkDataset.url; + } + + routeToDatatargets(): void { + this.router.navigate(['applications', this.applicationId.toString()]); + } + + //TODO: Would be better to store this as a flag/field instead + disableSaveButton(): boolean { + let disable = true; + if (!this.datatarget.setToOpendataDk) { + disable = false; + } else if (this.datatarget.openDataDkDataset?.acceptTerms) { + disable = false; + } else { + disable = true; + } + return disable; + } + + // For list of devices / payload-decoders + private getDevices(): void { + this.applicationSubscription = this.applicationService + .getApplication(this.applicationId) + .subscribe((application: Application) => { + this.devices = application.iotDevices.sort((a, b) => + a.name.localeCompare(b.name, 'en', { numeric: true }) + ); + }); + } + 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 }) + ); + }); + } + 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) { + 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: { + 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/assets/i18n/da.json b/src/assets/i18n/da.json index 580da59ab..3dc1a17e7 100644 --- a/src/assets/i18n/da.json +++ b/src/assets/i18n/da.json @@ -237,6 +237,9 @@ "QOS": "QoS", "USERNAME": "Brugernavn", "PASSWORD": "Adgangskode" + }, + "OPENDATADK": { + "TYPE": "OpenDataDK" } }, "MULTICAST": { @@ -260,18 +263,35 @@ } }, "OPENDATADK": { + "INTRO": { + "GUIDE_HEADER": "Guide til Open Data DK-data target", + "GUIDE1": "Det er nemt at sende data fra OS2iot til Open Data DK (ODDK). Første gange der oprettes et ODDK-data target, bliver det muligt for ODDK at høste oplysninger om jeres datasæt til opendata.dk. Når først høstningen er sat op, vil alle jeres ODDK-data targets automatisk blive oprettet og opdateret på opendata.dk.", + "GUIDE2": "Senest modtagede datapakke udstilles via OS2iots API og kan hentes via en URL angivet på det enkelte ODDK-data target og på jeres datasæt på opendata.dk. Der opsamles og udstilles altså ikke historisk data i hverken OS2iot eller på opendata.dk.", + "GUIDE3": "Nye ODDK-data targets høstes automatisk, og I behøver ikke gøre noget aktivt for at gøre dem tilgængelige på opendata.dk. Hvis I sletter et ODDK-data target forsvinder det af sig selv fra opendata.dk.", + "GUIDE4": "Datasæt fra OS2iot publiceres under licensen", + "GUIDE5": "Open DATA DK Licens.", + "PROCEDURE_HEADER": "Procedure ved oprettelse af første data target", + "PROCEDURE1": "Bliv medlem af Open Data DK, hvis jeres myndighed ikke allerede er det:", + "PROCEDURE2": "Opret første ODDK-data target i OS2iot", + "PROCEDURE3": "Ved oprettelsen tilbyder OS2iot at sende en mail til Open Data DK's administrator, som sætter høstningen op. I må forvente op til 2-3 ugers behandlingstid.", + "PROCEDURE4": "Når høstningen er aktiv, kan datasæt findes og beriges på", + "PROCEDURE4_LINK": "ODDK administrationsmodulet" + }, "QUESTION": { "GIVE-OPENDATADK-NAME": "Datasæt titel", "GIVE-OPENDATADK-NAME-PLACEHOLDER": "Datasæt titel", - "GIVE-OPENDATADK-RESOURCETITLE": "Datakilde titel", + "GIVE-OPENDATADK-NAME-INFO": "Overordnet titel på datasættet på opendata.dk", + "GIVE-OPENDATADK-RESOURCETITLE": "Data ressource titel", "GIVE-OPENDATADK-RESOURCETITLE-PLACEHOLDER": "Kloaksensorer - Aarhus kommune", + "GIVE-OPENDATADK-RESOURCETITLE-INFO": "Titel på den ressource, der vises i datasættet på opendata.dk", "GIVE-OPENDATADK-DESCRIPTION": "Beskrivelse", "GIVE-OPENDATADK-DESCRIPTION-PLACEHOLDER": "Beskrivelse", - "GIVE-OPENDATADK-KEYWORDS": "Angiv kommasepareret nøgleord", + "GIVE-OPENDATADK-KEYWORDS": "Angiv emneord", "GIVE-OPENDATADK-KEYWORDS-PLACEHOLDER": "IOT, sensor, LoRaWAN, temeratur", - "GIVE-OPENDATADK-AUTHORNAME": "Forfatter", + "GIVE-OPENDATADK-AUTHORNAME": "Dataejer", "GIVE-OPENDATADK-AUTHORNAME-PLACEHOLDER": "Jens Jensen", - "GIVE-OPENDATADK-AUTHOR-EMAIL": "Forfatterens e-mail", + "GIVE-OPENDATADK-AUTHORNAME-INFO": "Ansvarlig afdeling eller person", + "GIVE-OPENDATADK-AUTHOR-EMAIL": "Dataejers e-mail", "GIVE-OPENDATADK-AUTHOR-EMAIL-PLACEHOLDER": "jens@jensen.dk", "ACCEPT-TERMS-PART-ONE": "Jeg accepterer hermed de", "ACCEPT-TERMS-PART-TWO": "Heriblandt at data ikke indeholder følsomme personoplysninger eller personhenførbare informationer.", @@ -537,6 +557,7 @@ "RELATION-APPLICATION": "Tilknyttet applikation: ", "GIVE-DATATARGET-NAME": "Navngiv datatarget", "GIVE-DATATARGET-NAME-PLACEHOLDER": "Datatarget's navn", + "GIVE-DATATARGET-NAME-INFO": "Benyttes kun i OS2iot", "GIVE-DATATARGET-TIMEOUT": "Timeout i millisekunder", "GIVE-DATATARGET-AUTHORIZATIONHEADER": "Angiv authorization header", "GIVE-DATATARGET-URL": "Angiv datatargets URL", From 533b062c7a8e86de1a6bff25b5eb4bf99ad476a0 Mon Sep 17 00:00:00 2001 From: Chris Johansen Date: Thu, 20 Apr 2023 15:05:59 +0200 Subject: [PATCH 2/5] Changed OpenDataDK keywords-input to be multi-select dropdown.. --- .../datatarget/datatarget.service.ts | 5 --- .../opendatadk-edit.component.html | 36 +++++++++---------- .../opendatadk-edit.component.ts | 17 +++++++++ src/assets/i18n/da.json | 9 +++-- 4 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/app/applications/datatarget/datatarget.service.ts b/src/app/applications/datatarget/datatarget.service.ts index 8a7afad94..9fffb2266 100644 --- a/src/app/applications/datatarget/datatarget.service.ts +++ b/src/app/applications/datatarget/datatarget.service.ts @@ -77,11 +77,6 @@ export class DatatargetService { if (!datatarget.setToOpendataDk) { datatarget.openDataDkDataset = null; } - if (datatarget.setToOpendataDk) { - //TODO: Probably not needed if we have multi-select drop-down..? - datatarget.openDataDkDataset.keywords = datatarget.openDataDkDataset?.keywordsInput?.split(','); - datatarget.openDataDkDataset.keywordsInput = undefined; - } } private mapToDatatarget(dataTargetResponse: DatatargetResponse): Datatarget { diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.html b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.html index 9ebca19a6..4fa8b3b65 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.html +++ b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.html @@ -243,44 +243,42 @@
-
- + 'is-invalid': + formFailedSubmit && + errorFields.includes('openDataDkDataset.keywords'), + 'is-valid': + formFailedSubmit && + !errorFields.includes('openDataDkDataset.keywords') + }"> + {{kw}} +
-

{{ 'OPENDATADK.QUESTION.ACCEPT-TERMS-PART-ONE' | translate }} - + {{ 'OPENDATADK.QUESTION.TERMS-AND-CONDITIONS' | translate }}

-

{{ 'OPENDATADK.QUESTION.ACCEPT-TERMS-PART-TWO' | translate }}

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 355c50e11..a26048841 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 @@ -43,6 +43,23 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { title = 'FORM.CREATE-NEW-DATATARGET'; + selectableKeyword = [ + 'Befolkning og samfund', + 'Energi', + 'Internationale spørgsmål', + 'Landbrug, fiskeri, skovbrug og fødevarer', + 'Midlertidige data', + 'Miljø', + 'Regeringen og den offentlige sektor', + 'Regioner og byer', + 'Retfærdighed, retssystem og offentlig sikkerhed', + 'Sundhed', + 'Transport', + 'Uddannelse, kultur og sport', + 'Videnskab og teknologi', + 'Økonomi og finanser', + ]; + errorMessages: any[]; errorFields: string[]; diff --git a/src/assets/i18n/da.json b/src/assets/i18n/da.json index 3dc1a17e7..7b50f9556 100644 --- a/src/assets/i18n/da.json +++ b/src/assets/i18n/da.json @@ -287,21 +287,20 @@ "GIVE-OPENDATADK-DESCRIPTION": "Beskrivelse", "GIVE-OPENDATADK-DESCRIPTION-PLACEHOLDER": "Beskrivelse", "GIVE-OPENDATADK-KEYWORDS": "Angiv emneord", - "GIVE-OPENDATADK-KEYWORDS-PLACEHOLDER": "IOT, sensor, LoRaWAN, temeratur", + "GIVE-OPENDATADK-KEYWORDS-PLACEHOLDER": "Vælg nøgleord fra drop-down", "GIVE-OPENDATADK-AUTHORNAME": "Dataejer", "GIVE-OPENDATADK-AUTHORNAME-PLACEHOLDER": "Jens Jensen", "GIVE-OPENDATADK-AUTHORNAME-INFO": "Ansvarlig afdeling eller person", "GIVE-OPENDATADK-AUTHOR-EMAIL": "Dataejers e-mail", "GIVE-OPENDATADK-AUTHOR-EMAIL-PLACEHOLDER": "jens@jensen.dk", - "ACCEPT-TERMS-PART-ONE": "Jeg accepterer hermed de", - "ACCEPT-TERMS-PART-TWO": "Heriblandt at data ikke indeholder følsomme personoplysninger eller personhenførbare informationer.", - "TERMS-AND-CONDITIONS": "Gældende vilkår og betingelser for OpenDataDK" + "ACCEPT-TERMS-PART-ONE": "Jeg accepterer hermed, at datasættet udgives under en", + "TERMS-AND-CONDITIONS": "Creative Commons CC0 1.0 Universel (CC0 1.0) licens" }, "DETAILS": { "NAME": "Datasæt titel", "RESOURCETITLE": "Datakilde titel", "DESCRIPTION": "Beskrivelse", - "KEYWORDS": "Keywords", + "KEYWORDS": "Emneord", "LICENSE": "Licens", "AUTHORNAME": "Forfatterens navn", "AUTHOREMAIL": "Forfatterens email", From f54feaec82d7ccb78ed817f7ac2f688076d1e5a7 Mon Sep 17 00:00:00 2001 From: Chris Johansen Date: Mon, 24 Apr 2023 14:38:41 +0200 Subject: [PATCH 3/5] Finished implementing new flow for sending ODDK-registration-mails directly from OS2IoT, instead of having to go through users mail-client.. --- .../admin/organisation/organisation.model.ts | 1 + .../datatarget/datatarget.model.ts | 7 + .../datatarget/datatarget.module.ts | 13 +- .../datatarget/datatarget.service.ts | 12 +- .../opendatadk-edit.component.html | 4 +- .../opendatadk-edit.component.ts | 331 +++++++++--------- .../opendatadk-mail-dialog.html | 37 ++ .../opendatadk-mail-dialog.scss} | 0 .../opendatadk-mail-dialog.ts | 38 ++ .../opendatadk-warning-dialog.html | 24 ++ .../opendatadk-warning-dialog.scss | 0 .../opendatadk-warning-dialog.ts | 17 + .../opendatadk-dialog.component.html | 20 -- .../opendatadk-dialog.component.spec.ts | 25 -- .../opendatadk-dialog.component.ts | 25 -- .../opendatadk-dialog.service.ts | 26 -- src/app/shared/shared.module.ts | 3 - src/assets/i18n/da.json | 14 + 18 files changed, 330 insertions(+), 267 deletions(-) create mode 100644 src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog.html rename src/app/{shared/components/opendatadk-dialog/opendatadk-dialog.component.scss => applications/datatarget/opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog.scss} (100%) create mode 100644 src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog.ts create mode 100644 src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog.html create mode 100644 src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog.scss create mode 100644 src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog.ts delete mode 100644 src/app/shared/components/opendatadk-dialog/opendatadk-dialog.component.html delete mode 100644 src/app/shared/components/opendatadk-dialog/opendatadk-dialog.component.spec.ts delete mode 100644 src/app/shared/components/opendatadk-dialog/opendatadk-dialog.component.ts delete mode 100644 src/app/shared/components/opendatadk-dialog/opendatadk-dialog.service.ts diff --git a/src/app/admin/organisation/organisation.model.ts b/src/app/admin/organisation/organisation.model.ts index f07c0a528..fdf05791f 100644 --- a/src/app/admin/organisation/organisation.model.ts +++ b/src/app/admin/organisation/organisation.model.ts @@ -16,6 +16,7 @@ export interface OrganisationResponse { createdByName: string; updatedByName: string; name: string; + openDataDkRegistered: boolean; payloadDecoders: PayloadDecoder[]; applications: Application[]; diff --git a/src/app/applications/datatarget/datatarget.model.ts b/src/app/applications/datatarget/datatarget.model.ts index 6021d01f4..f66c885ad 100644 --- a/src/app/applications/datatarget/datatarget.model.ts +++ b/src/app/applications/datatarget/datatarget.model.ts @@ -44,3 +44,10 @@ export class DatatargetTypeDescriptor { readMoreUrl: string; provider: string; } + +export class OddkMailInfo { + organizationId?: number; + organizationOddkAlias: string; + comment?: string; + sharingUrl?: string +} \ No newline at end of file diff --git a/src/app/applications/datatarget/datatarget.module.ts b/src/app/applications/datatarget/datatarget.module.ts index 8355b03e7..2a8518acc 100644 --- a/src/app/applications/datatarget/datatarget.module.ts +++ b/src/app/applications/datatarget/datatarget.module.ts @@ -24,6 +24,8 @@ import { DatatargetEditTypeSelectorDirective } from './datatarget-edit/datatarge import { MqttEditComponent } from './mqtt-edit/mqtt-edit.component'; import { MqttDetailComponent } from './mqtt-detail/mqtt-detail.component'; import { DatatargetTabComponent } from './datatarget-tab/datatarget-tab.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'; @NgModule({ declarations: [ @@ -38,11 +40,14 @@ import { DatatargetTabComponent } from './datatarget-tab/datatarget-tab.componen OpendatadkComponent, OpendatadkEditComponent, OpendatadkDetailComponent, + OpenDataDkMailDialogComponent, + OpenDataDkWarningDialogComponent, MqttDetailComponent, MqttEditComponent, DatatargetDetailTypeSelectorDirective, DatatargetEditTypeSelectorDirective, - DatatargetTabComponent], + DatatargetTabComponent, + ], imports: [ CommonModule, RouterModule, @@ -64,7 +69,7 @@ import { DatatargetTabComponent } from './datatarget-tab/datatarget-tab.componen FiwareEditComponent, HttppushDetailComponent, HttppushEditComponent, - NGMaterialModule - ] + NGMaterialModule, + ], }) -export class DatatargetModule { } +export class DatatargetModule {} diff --git a/src/app/applications/datatarget/datatarget.service.ts b/src/app/applications/datatarget/datatarget.service.ts index 9fffb2266..1efcb30eb 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 } from './datatarget.model'; +import { DatatargetData, Datatarget, OddkMailInfo } from './datatarget.model'; import { map } from 'rxjs/operators'; import { OpenDataDkDataset } from './opendatadk/opendatadk-dataset.model'; import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; @@ -116,4 +116,14 @@ export class DatatargetService { 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/opendatadk/opendatadk-edit/opendatadk-edit.component.html b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.html index 4fa8b3b65..4d0ab4a35 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.html +++ b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.html @@ -287,7 +287,7 @@
{{ 'QUESTION.DATATARGET.RELATIONS' | translate }}
- + 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 a26048841..89631bf56 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 @@ -19,18 +19,19 @@ import { } 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'; -import { OpendatadkDialogService } from '@shared/components/opendatadk-dialog/opendatadk-dialog.service'; import { OrganizationAccessScope } from '@shared/enums/access-scopes'; import { DataTargetType } from '@shared/enums/datatarget-type'; import { ErrorMessageService } from '@shared/error-message.service'; import { MeService } from '@shared/services/me.service'; -import { OpendatadkService } from '@shared/services/opendatadk.service'; import { ScrollToTopService } from '@shared/services/scroll-to-top.service'; import { SnackService } from '@shared/services/snack.service'; -import { Observable, Subscription } from 'rxjs'; -import { Datatarget } from '../../datatarget.model'; +import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; +import { first } from 'rxjs/operators'; +import { Datatarget, OddkMailInfo } from '../../datatarget.model'; import { DatatargetService } from '../../datatarget.service'; import { OpenDataDkDataset } from '../../opendatadk/opendatadk-dataset.model'; +import { OpenDataDkMailDialogComponent } from './opendatadk-mail-dialog/opendatadk-mail-dialog'; +import { OpenDataDkWarningDialogComponent } from './opendatadk-warning-dialog/opendatadk-warning-dialog'; @Component({ selector: 'app-opendatadk-edit', @@ -64,24 +65,20 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { errorFields: string[]; datatarget: Datatarget = new Datatarget(); - private datatargetSubscription: Subscription; - private relationSubscription: Subscription; - private applicationSubscription: Subscription; - private payloadDecoderSubscription: Subscription; - private dataExistsSubscription: Subscription; + private subscriptions = []; formFailedSubmit = false; datatargetId: number; private applicationId: number; devices: IotDevice[]; payloadDecoders = []; - private counter: number; - private dataSetExists = false; - private isMailDialogAlreadyShown = false; + private pendingRequestsCounter: number; payloadDeviceDatatarget: PayloadDeviceDatatarget[]; canEdit: boolean; + private alreadySentOddkMail: boolean = false; + constructor( translate: TranslateService, private route: ActivatedRoute, @@ -93,10 +90,9 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { private saveSnackService: SnackService, private dialog: MatDialog, private errorMessageService: ErrorMessageService, - private opendatadkService: OpendatadkService, - private opendatadkDialogService: OpendatadkDialogService, private scrollToTopService: ScrollToTopService, - private meService: MeService + private meService: MeService, + private sharedVariableService: SharedVariableService ) { translate.use('da'); @@ -105,16 +101,17 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { this.datatargetId = +this.route.snapshot.paramMap.get('datatargetId'); this.applicationId = +this.route.snapshot.paramMap.get('id'); + if (this.applicationId !== 0) { + this.getDevices(); + this.getPayloadDecoders(); + } if (this.datatargetId !== 0) { this.title = 'FORM.EDIT-DATATARGET'; this.getDatatarget(this.datatargetId); this.getPayloadDeviceDatatarget(this.datatargetId); } - if (this.applicationId !== 0) { - this.getDevices(); - } - this.getPayloadDecoders(); - this.getDataSetExists(); + this.getAlreadySentOddkMail(); + this.canEdit = this.meService.hasAccessToTargetOrganization( OrganizationAccessScope.ApplicationWrite, undefined, @@ -123,53 +120,46 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { } ngOnDestroy(): void { - this.relationSubscription?.unsubscribe(); - this.applicationSubscription?.unsubscribe(); - this.datatargetSubscription?.unsubscribe(); - this.payloadDecoderSubscription?.unsubscribe(); - this.dataExistsSubscription?.unsubscribe(); + this.subscriptions.forEach((s) => s?.unsubscribe()); } private getPayloadDeviceDatatarget(id: number) { - this.relationSubscription = this.payloadDeviceDataTargetService - .getByDataTarget(id) - .subscribe((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, + this.subscriptions.push( + this.payloadDeviceDataTargetService + .getByDataTarget(id) + .subscribe((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, + }); }); - }); - }); + }) + ); } private getDatatarget(id: number) { - this.datatargetSubscription = this.datatargetService - .get(id) - .subscribe((response: Datatarget) => { + this.subscriptions.push( + this.datatargetService.get(id).subscribe((response: Datatarget) => { this.datatarget = response; if (this.datatarget.openDataDkDataset != null) { this.datatarget.openDataDkDataset.acceptTerms = true; } - }); - } - private getDataSetExists() { - this.dataExistsSubscription = this.opendatadkService - .get() - .subscribe((response) => { - this.dataSetExists = response.dataset.length !== 0; - }); + }) + ); } onSubmit(): void { this.resetErrors(); if (this.datatargetId) { + this.pendingRequestsCounter = + 1 + (this.payloadDeviceDatatarget?.length ?? 0); this.updateDatatarget(); this.addPayloadDeviceDatatarget(); } else { @@ -177,77 +167,80 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { } } private updateDatatarget() { - this.counter = 1 + (this.payloadDeviceDatatarget?.length ?? 0); - this.datatargetService.update(this.datatarget).subscribe( - (response: Datatarget) => { - this.datatarget = response; - if (this.datatarget.openDataDkDataset != null) { - this.datatarget.openDataDkDataset.acceptTerms = true; - } - this.shouldShowMailDialog().subscribe((response) => { + this.subscriptions.push( + this.datatargetService.update(this.datatarget).subscribe( + (response: Datatarget) => { + this.datatarget = response; + if (this.datatarget.openDataDkDataset != null) { + this.datatarget.openDataDkDataset.acceptTerms = true; + } this.countToRedirect(); - }); - }, - (error: HttpErrorResponse) => { - this.checkDataTargetModelOpendatadkdatasaet(); - this.handleError(error); - this.formFailedSubmit = true; - } + }, + (error: HttpErrorResponse) => { + this.checkDataTargetModelOpendatadkdatasaet(); + this.handleError(error); + this.formFailedSubmit = true; + } + ) ); } private addPayloadDeviceDatatarget() { - this.payloadDeviceDatatarget.map((pdd) => { - if (pdd.payloadDecoderId === 0) { - pdd.payloadDecoderId = null; - } - }); this.payloadDeviceDatatarget.forEach((relation) => { + if (relation.payloadDecoderId === 0) { + relation.payloadDecoderId = null; + } if (relation.id) { - this.payloadDeviceDataTargetService.put(relation).subscribe( - (response) => { - this.countToRedirect(); - }, - (error) => { - this.handleError(error); - } + this.subscriptions.push( + this.payloadDeviceDataTargetService.put(relation).subscribe( + () => this.countToRedirect(), + (error) => this.handleError(error) + ) ); } else { - this.payloadDeviceDataTargetService.post(relation).subscribe( - (res: any) => { - this.countToRedirect(); - }, - (error) => { - this.handleError(error); - } + this.subscriptions.push( + this.payloadDeviceDataTargetService.post(relation).subscribe( + () => this.countToRedirect(), + (error) => this.handleError(error) + ) ); } }); } private createDatatarget() { - this.counter = 0; + this.pendingRequestsCounter = 0; this.datatarget.applicationId = this.applicationId; - this.datatargetService.create(this.datatarget).subscribe( - (response: Datatarget) => { - this.datatargetId = response.id; - this.datatarget = response; - if (this.datatarget.openDataDkDataset != null) { - this.datatarget.openDataDkDataset.acceptTerms = true; + this.subscriptions.push( + this.datatargetService.create(this.datatarget).subscribe( + (response: Datatarget) => { + this.datatargetId = response.id; + this.datatarget = response; + if (this.datatarget.openDataDkDataset != null) { + this.datatarget.openDataDkDataset.acceptTerms = true; + } + this.saveSnackService.showSavedSnack(); + this.showMailOrRedirect(); + }, + (error: HttpErrorResponse) => { + this.checkDataTargetModelOpendatadkdatasaet(); + this.handleError(error); + this.formFailedSubmit = true; } - this.saveSnackService.showSavedSnack(); - this.routeToDatatargets(); - }, - (error: HttpErrorResponse) => { - this.checkDataTargetModelOpendatadkdatasaet(); - this.handleError(error); - this.formFailedSubmit = true; - } + ) ); } + private showMailOrRedirect = () => { + if (!this.alreadySentOddkMail) { + this.openMailDialog(); + } else { + this.routeToDatatargets(); + } + }; + // 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.counter -= 1; - if (this.counter <= 0 && !this.formFailedSubmit) { + this.pendingRequestsCounter -= 1; + if (this.pendingRequestsCounter <= 0 && !this.formFailedSubmit) { this.saveSnackService.showSavedSnack(); - this.routeToDatatargets(); + this.showMailOrRedirect(); } } private resetErrors() { @@ -267,69 +260,83 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { this.errorMessages = errors.errorMessages; this.scrollToTopService.scrollToTop(); } - private shouldShowMailDialog(): Observable { - return new Observable((observer) => { - if ( - !this.dataSetExists && - this.datatarget.setToOpendataDk && - !this.isMailDialogAlreadyShown - ) { - this.isMailDialogAlreadyShown = true; - this.opendatadkDialogService.showDialog().subscribe((response) => { - if (response) { - this.showMailClient(); - } - observer.next(response); - }); - } else { - observer.next(true); - } - }); - } - private showMailClient() { - if (!this.datatarget.openDataDkDataset.url) { - this.datatarget.openDataDkDataset.url = this.datatargetService.getOpendataSharingApiUrl(); - } - window.location.href = - 'mailto:FG2V@kk.dk?subject=Oprettelse%20af%20datas%C3%A6t%20i%20OpenDataDK&body=K%C3%A6re%20Frans%0D%0A%0D%0AHermed%20fremsendes%20linket%20til%20DCAT%20kataloget%20%2C%20du%20bedes%20registrere%20p%C3%A5%20Open%20Data%20DK%20platformen.%0D%0A%0D%0ALink%3A ' + - this.datatarget.openDataDkDataset.url; - } routeToDatatargets(): void { this.router.navigate(['applications', this.applicationId.toString()]); } - //TODO: Would be better to store this as a flag/field instead - disableSaveButton(): boolean { - let disable = true; - if (!this.datatarget.setToOpendataDk) { - disable = false; - } else if (this.datatarget.openDataDkDataset?.acceptTerms) { - disable = false; - } else { - disable = true; - } - return disable; - } + // For mail dialog + private getAlreadySentOddkMail = () => { + const orgId = this.sharedVariableService.getSelectedOrganisationId(); + this.subscriptions.push( + this.datatargetService + .getOpenDataDkRegistered(orgId) + .subscribe((response) => { + this.alreadySentOddkMail = !!response; + }) + ); + }; + 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) => { + if (result) { + // User accepted -> Send mail and continue + await this.datatargetService + .sendOpenDataDkMail(result) + .pipe(first()) + .toPromise(); + this.routeToDatatargets(); + } else { + // User cancelled -> Show the warning + this.openMailWarningDialog(); + } + }); + }; + private openMailWarningDialog = () => { + const dialog = this.dialog.open(OpenDataDkWarningDialogComponent); + dialog.afterClosed().subscribe(async (result) => { + if (result) { + // User accepted -> Save if 'never again' was checked, then continue + if (result.neverAgain) { + await this.setAlreadySentOddkMail(); + } + this.routeToDatatargets(); + } else { + // User cancelled -> Show the mail-dialog again + this.openMailDialog(); + } + }); + }; // For list of devices / payload-decoders private getDevices(): void { - this.applicationSubscription = this.applicationService - .getApplication(this.applicationId) - .subscribe((application: Application) => { - this.devices = application.iotDevices.sort((a, b) => - a.name.localeCompare(b.name, 'en', { numeric: true }) - ); - }); + this.subscriptions.push( + this.applicationService + .getApplication(this.applicationId) + .subscribe((application: Application) => { + this.devices = application.iotDevices.sort((a, b) => + a.name.localeCompare(b.name, 'en', { numeric: true }) + ); + }) + ); } 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 }) - ); - }); + this.subscriptions.push( + 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 }) + ); + }) + ); } addRow() { if (!this.payloadDeviceDatatarget) { @@ -347,11 +354,13 @@ export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { } 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); - }); + this.subscriptions.push( + this.payloadDeviceDataTargetService + .delete(this.payloadDeviceDatatarget[index].id) + .subscribe((response) => { + this.payloadDeviceDatatarget.splice(index, 1); + }) + ); } } openDeleteDialog(index) { diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog.html b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog.html new file mode 100644 index 000000000..3a60ee7ab --- /dev/null +++ b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog.html @@ -0,0 +1,37 @@ +

{{'OPENDATADK.MAIL.DIALOG_TITLE' | translate}}

+
+

+ {{'OPENDATADK.MAIL.DIALOG_TEXT1' | translate}} + {{selectedOrganizationName ?? ('OPENDATADK.MAIL.SELECTED_ORG_FALLBACK' | translate)}}{{'OPENDATADK.MAIL.DIALOG_TEXT2' | translate}} +

+

+ +
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
\ No newline at end of file diff --git a/src/app/shared/components/opendatadk-dialog/opendatadk-dialog.component.scss b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog.scss similarity index 100% rename from src/app/shared/components/opendatadk-dialog/opendatadk-dialog.component.scss rename to src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog.scss diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog.ts b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog.ts new file mode 100644 index 000000000..6eb667ffe --- /dev/null +++ b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog.ts @@ -0,0 +1,38 @@ +import { Component } from '@angular/core'; +import { MatDialogRef } from '@angular/material/dialog'; +import { OddkMailInfo } from '@applications/datatarget/datatarget.model'; +import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; + +@Component({ + selector: 'app-opendatadk-mail-dialog', + templateUrl: './opendatadk-mail-dialog.html', + styleUrls: ['./opendatadk-mail-dialog.scss'], +}) +export class OpenDataDkMailDialogComponent { + sendAttempted: boolean = false; + organizationInput: string = ''; + commentInput: string = ''; + + selectedOrganizationName: string; + + constructor( + public dialog: MatDialogRef, + private sharedVariableService: SharedVariableService + ) { + const selectedOrganisationId = sharedVariableService.getSelectedOrganisationId(); + this.selectedOrganizationName = sharedVariableService + .getOrganizationInfo() + ?.find((o) => o.id === selectedOrganisationId)?.name; + } + + send() { + this.sendAttempted = true; + if (this.organizationInput) { + this.dialog.close({ + organizationId: this.sharedVariableService.getSelectedOrganisationId(), + organizationOddkAlias: this.organizationInput, + comment: this.commentInput || undefined, + }); + } + } +} diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog.html b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog.html new file mode 100644 index 000000000..698444655 --- /dev/null +++ b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog.html @@ -0,0 +1,24 @@ +

{{'OPENDATADK.MAIL.WARNING' | translate}}

+
+

+ {{'OPENDATADK.MAIL.WARNING-TEXT' | translate}} +
+

+ +
+
+ + {{ 'OPENDATADK.MAIL.NEVER-AGAIN' | translate }} + +
+
+ +
+
+ + +
\ No newline at end of file diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog.scss b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog.ts b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog.ts new file mode 100644 index 000000000..a79b5fd1d --- /dev/null +++ b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog.ts @@ -0,0 +1,17 @@ +import { Component } from '@angular/core'; +import { MatDialogRef } from '@angular/material/dialog'; + +@Component({ + selector: 'app-opendatadk-warning-dialog', + templateUrl: './opendatadk-warning-dialog.html', + styleUrls: ['./opendatadk-warning-dialog.scss'], +}) +export class OpenDataDkWarningDialogComponent { + neverAgain: boolean = false; + + constructor(public dialog: MatDialogRef) {} + + ok() { + this.dialog.close({ neverAgain: this.neverAgain }); + } +} diff --git a/src/app/shared/components/opendatadk-dialog/opendatadk-dialog.component.html b/src/app/shared/components/opendatadk-dialog/opendatadk-dialog.component.html deleted file mode 100644 index aab0d2948..000000000 --- a/src/app/shared/components/opendatadk-dialog/opendatadk-dialog.component.html +++ /dev/null @@ -1,20 +0,0 @@ -

{{'DIALOG.OPENDATADK.TITLE' | translate}}

-
- {{'DIALOG.OPENDATADK.MESSAGE' | translate}} -
-
- - -
\ No newline at end of file diff --git a/src/app/shared/components/opendatadk-dialog/opendatadk-dialog.component.spec.ts b/src/app/shared/components/opendatadk-dialog/opendatadk-dialog.component.spec.ts deleted file mode 100644 index 5c35447d5..000000000 --- a/src/app/shared/components/opendatadk-dialog/opendatadk-dialog.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; - -import { OpendatadkDialogComponent } from './opendatadk-dialog.component'; - -describe('OpendatadkDialogComponent', () => { - let component: OpendatadkDialogComponent; - let fixture: ComponentFixture; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ OpendatadkDialogComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(OpendatadkDialogComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/shared/components/opendatadk-dialog/opendatadk-dialog.component.ts b/src/app/shared/components/opendatadk-dialog/opendatadk-dialog.component.ts deleted file mode 100644 index 0c2d965b2..000000000 --- a/src/app/shared/components/opendatadk-dialog/opendatadk-dialog.component.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { MatDialogRef } from '@angular/material/dialog'; -import { TranslateService } from '@ngx-translate/core'; - -@Component({ - selector: 'app-opendatadk-dialog', - templateUrl: './opendatadk-dialog.component.html', - styleUrls: ['./opendatadk-dialog.component.scss'] -}) -export class OpendatadkDialogComponent implements OnInit { - - constructor( - private translate: TranslateService, - public dialog: MatDialogRef) { - this.translate.use('da'); - } - - ngOnInit(): void { - } - - close() { - this.dialog.close(); - } - -} diff --git a/src/app/shared/components/opendatadk-dialog/opendatadk-dialog.service.ts b/src/app/shared/components/opendatadk-dialog/opendatadk-dialog.service.ts deleted file mode 100644 index d4e074872..000000000 --- a/src/app/shared/components/opendatadk-dialog/opendatadk-dialog.service.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Injectable } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; -import { Observable } from 'rxjs'; -import { OpendatadkDialogComponent } from './opendatadk-dialog.component'; -@Injectable({ - providedIn: 'root', -}) -export class OpendatadkDialogService { - - constructor( - private dialog: MatDialog - ) {} - - showDialog(): Observable { - return new Observable( - (observer) => { - const dialog = this.dialog.open(OpendatadkDialogComponent); - - dialog.afterClosed().subscribe((result) => { - observer.next(result); - }); - } - ); - } - -} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 5045e60d7..4d52159ed 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -10,7 +10,6 @@ import { BatteriStatusComponent } from './components/batteri-status/batteri-stat import { MapComponent } from './components/map/map.component'; import { NGMaterialModule } from './Modules/materiale.module'; import { DeleteDialogComponent } from './components/delete-dialog/delete-dialog.component'; -import { OpendatadkDialogComponent } from './components/opendatadk-dialog/opendatadk-dialog.component'; import { FormsModule } from '@angular/forms'; import { RouterModule } from '@angular/router'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; @@ -28,7 +27,6 @@ import { MetadataDetailsComponent } from './components/metadata-details/metadata BatteriStatusComponent, MapComponent, DeleteDialogComponent, - OpendatadkDialogComponent, TopBarComponent, TopBarTableComponent, GeneralDetailsComponent, @@ -52,7 +50,6 @@ import { MetadataDetailsComponent } from './components/metadata-details/metadata BatteriStatusComponent, MapComponent, DeleteDialogComponent, - OpendatadkDialogComponent, TopBarComponent, TopBarTableComponent, GeneralDetailsComponent, diff --git a/src/assets/i18n/da.json b/src/assets/i18n/da.json index 7b50f9556..8a22efb27 100644 --- a/src/assets/i18n/da.json +++ b/src/assets/i18n/da.json @@ -306,6 +306,20 @@ "AUTHOREMAIL": "Forfatterens email", "URL": "Endpoint til hentning af data", "NA": "Intet angivet" + }, + "MAIL": { + "DIALOG_TITLE": "Anmod Open Data DK om høstning af data", + "DIALOG_TEXT1": "For at få", + "DIALOG_TEXT2": "s ODDK datatargets gjort synlige på opendata.dk, skal Open Data DK have en anmodning om at begynde at høste jeres oplysninger fra OS2iot. Hvis du udfylder oplysningerne herunder, sender OS2iot automatisk en mail til Open Data DK", + "DIALOG_CONFIRM": "Send mail", + "GIVE-OPENDATADK-ORGNAME": "Organisation (i Open Data DK)", + "GIVE-OPENDATADK-ORGNAME-PLACEHOLDER": "Organisation", + "GIVE-OPENDATADK-COMMENT": "Eventuel kommentar", + "GIVE-OPENDATADK-COMMENT-PLACEHOLDER": "Kort kommentar", + "SELECTED_ORG_FALLBACK": "organisationen", + "WARNING": "Advarsel", + "WARNING-TEXT": "Hvis Open Data DK ikke får besked om integrationen, vises datasættet ikke på opendata.dk", + "NEVER-AGAIN": "Vis ikke igen. Open Data DK høster allerede denne organisation fra OS2iot." } }, "APPLICATION-TABLE": { From 95451a243aa6ba5ce54186c2dea1e35faa7065b6 Mon Sep 17 00:00:00 2001 From: Chris Johansen Date: Tue, 25 Apr 2023 11:47:46 +0200 Subject: [PATCH 4/5] IOT-1416: Minor fixes from PR.. --- .../httppush/httppush-edit/httppush-edit.component.html | 2 +- .../httppush/httppush-edit/httppush-edit.component.ts | 4 ---- .../opendatadk-detail/opendatadk-detail.component.html | 5 ----- .../opendatadk-edit/opendatadk-edit.component.html | 2 +- .../opendatadk/opendatadk-edit/opendatadk-edit.component.ts | 2 +- 5 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.html b/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.html index b43dabc25..96bbe9365 100644 --- a/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.html +++ b/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.html @@ -127,6 +127,6 @@
{{'QUESTION.DATATARGET.RELATIONS' | translate}}
- +
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 f5e2b6486..3bf2d40e4 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 @@ -310,10 +310,6 @@ export class HttppushEditComponent this.saveSnackService.showSavedSnack(); } - disableSaveButton(): boolean { - return false; - } - ngOnDestroy(): void { if (this.relationSubscription) { this.relationSubscription.unsubscribe(); diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.html b/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.html index f505eb538..cfe1e7049 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.html +++ b/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.html @@ -18,11 +18,6 @@ {{openDataDkDataset.keywords ? openDataDkDataset.keywords : ('OPENDATADK.DETAILS.NA' | translate) }}

- -

{{ 'OPENDATADK.DETAILS.AUTHORNAME' | translate }} {{openDataDkDataset.authorName}} diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.html b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.html index 4d0ab4a35..828d3e200 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.html +++ b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.html @@ -245,7 +245,7 @@

-
  1. - 1. {{ 'OPENDATADK.INTRO.PROCEDURE1' | translate }} + {{ 'OPENDATADK.INTRO.PROCEDURE1' | translate }} https://www.opendata.dk/

  2. -
  3. 2. {{ 'OPENDATADK.INTRO.PROCEDURE2' | translate }}

  4. -
  5. 3. {{ 'OPENDATADK.INTRO.PROCEDURE3' | translate }}

  6. +
  7. {{ 'OPENDATADK.INTRO.PROCEDURE2' | translate }}

  8. +
  9. {{ 'OPENDATADK.INTRO.PROCEDURE3' | translate }}

  10. - 4. {{ 'OPENDATADK.INTRO.PROCEDURE4' | translate }} + {{ 'OPENDATADK.INTRO.PROCEDURE4' | translate }} {{ 'OPENDATADK.INTRO.PROCEDURE4_LINK' | translate }}

diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.scss b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.scss index 276abe9d1..9e1cdf180 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.scss +++ b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.scss @@ -1,4 +1,15 @@ -.form-info-icon { - margin-left: 5px; - cursor: pointer; +@import 'src/assets/scss/setup/fonts'; + +:host { + .form-info-icon { + margin-left: 5px; + cursor: pointer; + } + mat-expansion-panel ol { + padding-left: 20px; + li { + font-family: $font-name, system; + display: list-item; + } + } }