Skip to content

Commit

Permalink
Ethical: Add new ethical report uri field to frontend (disableable fr…
Browse files Browse the repository at this point in the history
…om the backend)
  • Loading branch information
GeoffreyKarnbach committed Dec 11, 2024
1 parent 51a7cc9 commit 1fe8af0
Show file tree
Hide file tree
Showing 19 changed files with 108 additions and 9 deletions.
2 changes: 2 additions & 0 deletions apps/damap-frontend/src/app/services/config.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ describe('ConfigService', () => {
personSearchServiceConfigs: [],
fitsServiceAvailable: false,
livePreviewAvailable: true,
ethicalReportUriEnabled: true,
};

mockOAuthService.loadDiscoveryDocumentAndTryLogin.and.returnValue(
Expand Down Expand Up @@ -117,6 +118,7 @@ describe('ConfigService', () => {
personSearchServiceConfigs: [],
fitsServiceAvailable: false,
livePreviewAvailable: true,
ethicalReportUriEnabled: true,
};

service['config'] = mockConfig;
Expand Down
5 changes: 4 additions & 1 deletion libs/damap/src/assets/i18n/templates/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,8 @@
"link": "https://www.tuwien.at/forschung/fti-support/responsible-research-practices/research-ethics-committee"
},
"suffix": ", or a similar body?"
}
},
"ethicalIssueReportUri": "Please provide the URI to the ethical issue report."
}
},
"licensing": {
Expand Down Expand Up @@ -491,6 +492,8 @@
"maxlength": "Value must not exceed {{value}} characters.",
"pattern.currency": "Invalid input, please use the following format: 1234.56",
"orcid": "Invalid ORCID iD.",
"url": "Invalid URL. Must be formatted as https://example.com",
"uri": "Invalid URI",
"doi": "Invalid DOI. Must be formatted as 10.1234/56789 or https://doi.org/10.1234/56789 or doi:10.1234/56789",
"duplicateDoi": "DOI already added."
},
Expand Down
6 changes: 2 additions & 4 deletions libs/damap/src/lib/components/dmp/dmp.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,9 @@
#legalEthicalAspects
[dmpForm]="dmpForm"
[legalEthicalStep]="legalEthicalStep"
[datasets]="datasets">
[datasets]="datasets"
[ethicalReportUriEnabled]="ethicalReportUriEnabled">
</app-dmp-legal-ethical-aspects>
<div *ngIf="legalEthicalStep.invalid" class="error-message">
{{ "dmp.steps.legal.error" | translate }}
</div>
</ng-container>
</ng-container>
<ng-container *ngIf="selectedStep === 6">
Expand Down
2 changes: 2 additions & 0 deletions libs/damap/src/lib/components/dmp/dmp.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export class DmpComponent implements OnInit, OnDestroy {
legalEthicalAspectsComponent: LegalEthicalAspectsComponent;
@ViewChild('repo') repoComponent: RepoComponent;
livePreviewEnabled: boolean = true;
ethicalReportUriEnabled: boolean = true;

selectedViewStorage: 'primaryView' | 'secondaryView' = 'primaryView';

Expand Down Expand Up @@ -120,6 +121,7 @@ export class DmpComponent implements OnInit, OnDestroy {
this.config$ = this.backendService.loadServiceConfig();
this.config$.subscribe(config => {
this.livePreviewEnabled = config.livePreviewAvailable;
this.ethicalReportUriEnabled = config.ethicalReportUriEnabled;
this.cdr.detectChanges();
});
this.dmpForm.valueChanges.subscribe(() => this.cdr.detectChanges());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,16 @@
</mat-radio-button>
</mat-radio-group>
</div>
<div
*ngIf="
legalEthicalStep.controls.committeeReviewed.value &&
ethicalReportUriEnabled
">
<app-input-wrapper
[label]="'dmp.steps.ethical.question.ethicalIssueReportUri'"
[maxLength]="255"
[control]="ethicalReportUrl"></app-input-wrapper>
</div>
<app-info-message>
{{ "info.ethical.committeeReviewed.prefix" | translate }}
<a
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
import { Component, Input } from '@angular/core';
import { UntypedFormGroup } from '@angular/forms';
import { Component, Input, OnInit } from '@angular/core';
import { UntypedFormControl, UntypedFormGroup } from '@angular/forms';

@Component({
selector: 'app-ethical-aspects',
templateUrl: './ethical-aspects.component.html',
styleUrls: ['./ethical-aspects.component.css'],
})
export class EthicalAspectsComponent {
export class EthicalAspectsComponent implements OnInit {
@Input() legalEthicalStep: UntypedFormGroup;
@Input() ethicalReportUriEnabled: boolean;

get ethicalReportUrl(): UntypedFormControl {
return this.legalEthicalStep.get('ethicalReportUrl') as UntypedFormControl;
}

ngOnInit(): void {
this.legalEthicalStep
.get('committeeReviewed')
.valueChanges.subscribe(value => {
// Set ethical Report URL to ""
this.ethicalReportUrl.setValue(null);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -263,5 +263,6 @@
>{{ "dmp.steps.ethical.heading" | translate }}</mat-label
>
<app-ethical-aspects
[legalEthicalStep]="legalEthicalStep"></app-ethical-aspects>
[legalEthicalStep]="legalEthicalStep"
[ethicalReportUriEnabled]="ethicalReportUriEnabled"></app-ethical-aspects>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export class LegalEthicalAspectsComponent {
@Input() dmpForm: UntypedFormGroup;
@Input() legalEthicalStep: UntypedFormGroup;
@Input() datasets: UntypedFormArray;
@Input() ethicalReportUriEnabled: boolean;

translateAgreementPrefixEnum = 'enum.agreement.';
translateCompliancePrefixEnum = 'enum.compliance.';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { StepIntroModule } from '../../../widgets/step-intro/step-intro.module';
import { ToggleButtonsModule } from '../../../widgets/toggle-buttons/toggle-buttons.module';
import { TooltipModule } from '../../../widgets/tooltip/tooltip.module';
import { TranslateModule } from '@ngx-translate/core';
import { TextFieldModule } from '@angular/cdk/text-field';

@NgModule({
imports: [
Expand Down
1 change: 1 addition & 0 deletions libs/damap/src/lib/domain/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ export interface Config {
readonly personSearchServiceConfigs: ServiceConfig[];
readonly fitsServiceAvailable: boolean;
readonly livePreviewAvailable: boolean;
readonly ethicalReportUriEnabled: boolean;
}
1 change: 1 addition & 0 deletions libs/damap/src/lib/domain/dmp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export interface Dmp {
ethicalIssuesExistCris: boolean;
committeeReviewed: boolean;
committeeReviewedCris: boolean;
ethicalReportUrl: string;
storage: Storage[];
externalStorage: ExternalStorage[];
externalStorageInfo: string;
Expand Down
1 change: 1 addition & 0 deletions libs/damap/src/lib/mocks/config-service-mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ export const configMockData: Config = {
personSearchServiceConfigs: serviceConfigMockData,
fitsServiceAvailable: true,
livePreviewAvailable: true,
ethicalReportUriEnabled: true,
};
2 changes: 2 additions & 0 deletions libs/damap/src/lib/mocks/dmp-mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export const completeDmp: Dmp = {
structure: 'VCS',
targetAudience: 'students',
tools: 'proprietary software needed',
ethicalReportUrl: '',
};

export const noDataDmp: Dmp = {
Expand Down Expand Up @@ -171,4 +172,5 @@ export const noDataDmp: Dmp = {
structure: 'VCS',
targetAudience: 'students',
tools: 'proprietary software needed',
ethicalReportUrl: '',
};
9 changes: 9 additions & 0 deletions libs/damap/src/lib/services/form.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import { Storage } from '../domain/storage';
import { ccBy } from '../widgets/license-wizard/license-wizard-list';
import { currencyValidator } from '../validators/currency.validator';
import { notEmptyValidator } from '../validators/not-empty.validator';
import { urlValidator } from '../validators/url.validator';
import { uriValidator } from '../validators/uri.validator';

@Injectable({
providedIn: 'root',
Expand Down Expand Up @@ -114,6 +116,11 @@ export class FormService {
ethicalIssuesCris: [null],
committeeReviewed: [false],
committeeReviewedCris: [null],
ethicalReportUrl: [
'',
Validators.maxLength(this.TEXT_SHORT_LENGTH),
uriValidator(),
],
}),
repositories: this.formBuilder.array([]),
reuse: this.formBuilder.group({
Expand Down Expand Up @@ -173,6 +180,7 @@ export class FormService {
ethicalIssuesCris: dmp.ethicalIssuesExistCris,
committeeReviewed: dmp.committeeReviewed,
committeeReviewedCris: dmp.committeeReviewedCris,
ethicalReportUrl: dmp.ethicalReportUrl,
},
reuse: {
targetAudience: dmp.targetAudience,
Expand Down Expand Up @@ -274,6 +282,7 @@ export class FormService {
tools: formValue.reuse.tools,
id: formValue.id,
project: formValue.project,
ethicalReportUrl: formValue.legal.ethicalReportUrl,
};
}

Expand Down
1 change: 1 addition & 0 deletions libs/damap/src/lib/services/summary.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -403,5 +403,6 @@ describe('SummaryService', () => {
structure: '',
targetAudience: '',
tools: '',
ethicalReportUrl: '',
};
});
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@
<mat-error *ngIf="control?.errors?.orcid">
{{ "form.error.orcid" | translate }}
</mat-error>
<mat-error *ngIf="control?.errors?.url">
{{ "form.error.url" | translate }}
</mat-error>
<mat-error *ngIf="control?.errors?.uri">
{{ "form.error.uri" | translate }}
</mat-error>
</mat-form-field>
<!--{{control.errors | json}}-->
<!--{{control.valid}}-->
1 change: 1 addition & 0 deletions libs/damap/src/lib/store/states/form.state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const initialFormState: FormState = {
tools: '',
id: null,
project: null,
ethicalReportUrl: '',
},
changed: undefined,
};
25 changes: 25 additions & 0 deletions libs/damap/src/lib/validators/uri.validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
import { Observable, of } from 'rxjs';

/**
* Validates whether a given string is a valid URI based on RFC 3986.
* @param uri The string to validate.
* @returns True if the string is a valid URI, false otherwise.
*/
function isValidURI(uri: string): boolean {
// Regular expression to match a general URI pattern based on RFC 3986.
const uriRegex = /^[a-zA-Z][a-zA-Z0-9+.-]*:[^\s]*$/;
return uriRegex.test(uri);
}

/**
* A custom validator for validating URIs.
* @returns Validator function for Angular forms.
*/
export function uriValidator(): ValidatorFn {
return (control: AbstractControl): Observable<ValidationErrors | null> => {
const uri = control.value;
const isValid = !uri || isValidURI(uri);
return of(isValid ? null : { uri: true });
};
}
20 changes: 20 additions & 0 deletions libs/damap/src/lib/validators/url.validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
import validator from 'validator';
import { Observable, of } from 'rxjs';

export function urlValidator(): ValidatorFn {
return (control: AbstractControl): Observable<ValidationErrors | null> => {
const url = control.value;
const isValid =
!url ||
validator.isURL(url, {
protocols: ['http', 'https'],
require_protocol: false,
require_valid_protocol: true,
allow_underscores: false,
allow_trailing_dot: false,
allow_protocol_relative_urls: false,
});
return of(isValid ? null : { url: true });
};
}

0 comments on commit 1fe8af0

Please sign in to comment.