From 57cbc1d8e45d847d0590df7bc1e3e4299166f515 Mon Sep 17 00:00:00 2001 From: Sofia Papacharalampous Date: Fri, 26 Apr 2024 18:21:55 +0300 Subject: [PATCH 01/10] revert changes on "description editor > added option to skip form-refresh on save" --- .../app/ui/description/editor/description-editor.component.ts | 4 ++-- dmp-frontend/src/common/base/base-editor.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts index 812617bff..8c45dc0f2 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts @@ -628,6 +628,7 @@ export class DescriptionEditorComponent extends BaseEditor this.prepareForm(data)); + this.tocValidationService.validateForm(); } refreshOnNavigateToData(id?: Guid): void { @@ -648,8 +649,7 @@ export class DescriptionEditorComponent extends BaseEditor { - onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete, this.isNew); - this.tocValidationService.validateForm(); + onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete); this.descriptionIsOnceSaved = true; if (this.formGroup.get('status').value == DescriptionStatus.Finalized) this.isFinalized = true; }, diff --git a/dmp-frontend/src/common/base/base-editor.ts b/dmp-frontend/src/common/base/base-editor.ts index bdb75ae82..c66599d13 100644 --- a/dmp-frontend/src/common/base/base-editor.ts +++ b/dmp-frontend/src/common/base/base-editor.ts @@ -109,12 +109,12 @@ export abstract class BaseEditor Date: Mon, 29 Apr 2024 11:45:33 +0300 Subject: [PATCH 02/10] dmp progrss bar styling changes --- .../dmp-form-progress-indication.component.scss | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/form-progress-indication/dmp-form-progress-indication.component.scss b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/form-progress-indication/dmp-form-progress-indication.component.scss index b3aa2b404..fafe43a95 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/form-progress-indication/dmp-form-progress-indication.component.scss +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/form-progress-indication/dmp-form-progress-indication.component.scss @@ -31,9 +31,8 @@ // Buffer bar ::ng-deep .mdc-linear-progress__buffer { --mdc-linear-progress-track-height: 11px !important; - --mdc-linear-progress-active-indicator-color: var(--secondary-color) !important; } ::ng-deep .mdc-linear-progress__buffer-bar { - --mdc-linear-progress-track-color: var(--secondary-color) !important; + --mdc-linear-progress-track-color: #e0e2ec !important; } From e9e06fa51f54187f1f016ca3db2cbcba3f871f3a Mon Sep 17 00:00:00 2001 From: Sofia Papacharalampous Date: Mon, 29 Apr 2024 11:46:16 +0300 Subject: [PATCH 03/10] description editor change > do not validate form on save --- .../app/ui/description/editor/description-editor.component.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts index 8c45dc0f2..0dc486ee2 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts @@ -666,8 +666,6 @@ export class DescriptionEditorComponent extends BaseEditor void): void { this.formService.removeAllBackEndErrors(this.formGroup); - this.formService.touchAllFormFields(this.formGroup); - this.tocValidationService.validateForm(); if (this.formGroup.get('label').valid && this.formGroup.get('dmpId').valid && this.formGroup.get('dmpDescriptionTemplateId').valid && this.formGroup.get('descriptionTemplateId').valid && this.formGroup.get('status').valid) { this.persistEntity(onSuccess); From 80e6ffb07a6a6c5928dfe194f5f45ab1cd58665e Mon Sep 17 00:00:00 2001 From: amentis Date: Mon, 29 Apr 2024 11:48:02 +0300 Subject: [PATCH 04/10] licences fix filter type --- dmp-db-scema/updates/00.01.060_Insert_values.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmp-db-scema/updates/00.01.060_Insert_values.sql b/dmp-db-scema/updates/00.01.060_Insert_values.sql index cbfb7ed04..446f06d39 100644 --- a/dmp-db-scema/updates/00.01.060_Insert_values.sql +++ b/dmp-db-scema/updates/00.01.060_Insert_values.sql @@ -19,7 +19,7 @@ BEGIN INSERT INTO public."PrefillingSource" VALUES ('7a1ef5db-8833-45e1-85d8-476cea3d4f7a', 'OpenAIRE', 'openaire10falseapplication/jsonremote00$[''meta''][''pagination''][''page'',''pages'',''count'']{like}likereference_idoriginalIdlabeltitledescriptiondescriptiontitle.content[''title''][''content'']children.instance.license[''children''][''instance''][''license'']subject.content[''subject''][''content'']publisherpublisherlanguage.classid[''language''][''classid'']issued.content[''issued''][''content'']bestaccessright.classid[''bestaccessright''][''classid'']pid.content[''pid''][''content'']pid.classid[''pid''][''classid'']$[''results''][*][''result''][''metadata''][''oaf:entity''][''oaf:result'']https://services.openaire.eu/search/v2/api/datasets/?q={like}&page={page}&size={pageSize}&format=jsontitle.contentrda.dataset.distribution.titlelabeldescriptionrda.dataset.distribution.descriptiondescriptionchildren.instance.licenserda.dataset.distribution.license.license_refsubject.contentrda.dataset.keywordtagspublisherrda.dataset.distribution.host.titlelanguage.classidrda.dataset.metadata.languageissued.contentrda.dataset.issuedbestaccessright.classidrda.dataset.distribution.data_accesspid.contentrda.dataset.dataset_idpid.contentrda.dataset.dataset_id.identifierpid.classidrda.dataset.dataset_id.type', 1, '2024-02-28 09:12:41.051733', '2024-04-18 10:32:24.812946', NULL); INSERT INTO public."PrefillingSource" VALUES ('d79952bf-cfd9-4af4-b7b4-5a83d68890a5', 'Zenodo', 'zenodo search20falseapplication/jsonremote10$[''hits''][''total'']{like}likereference_ididlabeltitledescriptiondescription$[''hits''][''hits'']https://zenodo.org/api/records/?page={page}&size={pageSize}&q=title:"{like}" doi:"{like}" conceptdoi:"{like}"zenodo get10falseapplication/jsonremote0${like}likemetadata.title[''metadata''][''title'']metadata.description[''metadata''][''description'']metadata.license.id[''metadata''][''license''][''id'']metadata.keywords[''metadata''][''keywords'']metadata.filesize[''metadata''][''files''][''size'']metadata.language[''metadata''][''language'']metadata.dates.valid[''metadata''][''dates''][''type'']metadata.license.created[''metadata''][''license''][''created'']metadata.embargo_date[''metadata''][''embargo_date'']metadata.publication_date[''metadata''][''publication_date'']metadata.access_right[''metadata''][''access_right'']files[''files''][''key'']doidoi$https://zenodo.org/api/records/{like}metadata.titlerda.dataset.distribution.titlelabelmetadata.descriptionrda.dataset.distribution.descriptiondescriptionmetadata.license.idrda.dataset.distribution.license.license_refmetadata.keywordsrda.dataset.keywordtagsmetadata.filesizerda.dataset.distribution.byte_sizemetadata.languagerda.dataset.metadata.languagemetadata.dates.validrda.dataset.distribution.available_untilmetadata.license.createdrda.dataset.distribution.license.start_datemetadata.embargo_daterda.dataset.distribution.license.start_datemetadata.publication_daterda.dataset.issuedmetadata.access_rightrda.dataset.distribution.data_accessfilesrda.dataset.distribution.format^.*\.doirda.dataset.dataset_iddoirda.dataset.dataset_id.identifierZenodorda.dataset.distribution.host.titleMore than 99% uptime yearlyrda.dataset.distribution.host.availabilityCHrda.dataset.distribution.host.geo_locationAll files uploaded to Zenodo are stored in CERN’s EOS service in an 18 petabytes disk cluster.rda.dataset.distribution.host.storage_typedoirda.dataset.dataset_id.typehttps://schema.datacite.org/meta/kernel-4.4/rda.dataset.metadata.metadata_standard_id.identifierurlrda.dataset.metadata.metadata_standard_id.typeengrda.dataset.metadata.languageDataCite Metadata Schemarda.dataset.metadata.descriptionHourlyrda.dataset.distribution.host.backup_frequencyIncremental backuprda.dataset.distribution.host.backup_typeRepository hosted by Zenodorda.dataset.distribution.host.descriptionhttps://zenodo.orgrda.dataset.distribution.host.urldoirda.dataset.distribution.host.pid_system', 1, '2024-02-28 10:20:50.570055', '2024-04-17 07:11:52.483139', NULL); - INSERT INTO public."ReferenceType" VALUES ('2baab1e8-561f-4c15-84c3-571b811c52f6', 'Licenses', 'licenses', 'opendefinition100falseapplication/vnd.api+json; charset=utf-8remote10$[*]reference_ididlabeltitledescriptionmaintaineruriurl$[*]https://licenses.opendefinition.org/licenses/groups/all.json', 1, '2023-11-16 16:24:12.162675', '2024-02-16 09:14:22.723311', NULL); + INSERT INTO public."ReferenceType" VALUES ('2baab1e8-561f-4c15-84c3-571b811c52f6', 'Licenses', 'licenses', 'opendefinition100falseapplication/vnd.api+json; charset=utf-8local10$[*]reference_ididlabeltitledescriptionmaintaineruriurl$[*]https://licenses.opendefinition.org/licenses/groups/all.json', 1, '2023-11-16 16:24:12.162675', '2024-02-16 09:14:22.723311', NULL); INSERT INTO public."ReferenceType" VALUES ('2beacaad-3223-43ad-ad99-1e5f21328e7b', 'Registries', 'registries', 'rda-metadata-schemes100falseapplication/json; charset=utf-8remote10$[''meta''][''pagination''][''page'',''pages'',''count'']{like}likereference_idmscidlabeltitledescriptiondescriptionurluri$[''data''][''items''][*]https://rdamsc.bath.ac.uk/api2/m?q={like}&start=1&pageSize={pageSize}', 1, '2023-11-16 10:08:21.240804', '2024-02-16 09:16:50.456347', NULL); INSERT INTO public."ReferenceType" VALUES ('3d372db5-a456-45e6-a845-e41e1a8311f8', 'Projects', 'projects', 'project11', 1, '2023-11-17 08:55:05.190807', '2023-11-17 08:56:23.012619', NULL); INSERT INTO public."ReferenceType" VALUES ('51225b6a-86a6-48ac-9192-f15096dbcb8a', 'Publications', 'publications', 'openaire100falseapplication/json;charset=UTF-8remote00$[''meta''][''pagination''][''page'',''pages'',''count'']{like}*likereference_idoriginalIdlabeltitledescriptiontitlepid[''pid''][''content'']pidTypeField[''pid''][''classid'']$[''results''][*][''result''][''metadata''][''oaf:entity''][''oaf:result'']https://services.openaire.eu/search/v2/api/resources?query=oaftype exact result and {like}&page={page}&size={pageSize}&format=json', 1, '2023-11-16 13:07:20.591433', '2024-02-19 08:23:49.91191', NULL); From 7e3cebd299da59a26e299fc448bcab49cc3f774c Mon Sep 17 00:00:00 2001 From: Sofia Papacharalampous Date: Mon, 29 Apr 2024 13:26:41 +0300 Subject: [PATCH 05/10] added description editor progress bar --- .../editor/description-editor.component.html | 4 +- .../form-progress-indication.component.html | 11 +- .../form-progress-indication.component.scss | 39 ++++-- .../form-progress-indication.component.ts | 114 ++++++++++++------ 4 files changed, 117 insertions(+), 51 deletions(-) diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.component.html b/dmp-frontend/src/app/ui/description/editor/description-editor.component.html index 8d2a40aa1..e037ec587 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.component.html +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.component.html @@ -103,7 +103,7 @@ -
+
- +
diff --git a/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.html b/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.html index 56966d9ab..0befa13a7 100644 --- a/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.html +++ b/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.html @@ -1,5 +1,10 @@ 
-
{{progressSoFar}} {{'GENERAL.PREPOSITIONS.OF' | translate}} {{total}}
- -
{{value}}%
+
{{progressSoFar}} {{'GENERAL.PREPOSITIONS.OF' | translate}} {{total}} 
+ + +
+ {{value}}% + 0% +
+ diff --git a/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.scss b/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.scss index a15510639..fc7497a0f 100644 --- a/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.scss +++ b/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.scss @@ -1,16 +1,37 @@ -.percentage { - color: #212121; - opacity: 0.7; - font-weight: 400; - font-size: 0.875rem; -} +// .percentage { +// color: #212121; +// opacity: 0.7; +// font-weight: 400; +// font-size: 0.875rem; +// } +// .progress-bar { +// border-radius: 20px; +// height: 11px; + +// } + +// ::ng-deep .mat-progress-bar .mat-progress-bar-fill::after { +// border-radius: 20px !important; +// } + +// Bar container .progress-bar { + --mdc-linear-progress-active-indicator-height: 11px !important; border-radius: 20px; - height: 11px; - } -::ng-deep .mat-progress-bar .mat-progress-bar-fill::after { +//Progress bar +::ng-deep .mdc-linear-progress__bar-inner { + --mdc-linear-progress-active-indicator-color: var(--primary-color) !important; border-radius: 20px !important; } + +// Buffer bar +::ng-deep .mdc-linear-progress__buffer { + --mdc-linear-progress-track-height: 11px !important; +} + +::ng-deep .mdc-linear-progress__buffer-bar { + --mdc-linear-progress-track-color: #e0e2ec !important; +} diff --git a/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.ts b/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.ts index 908acd641..2661630b1 100644 --- a/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.ts @@ -11,13 +11,14 @@ import { takeUntil } from 'rxjs/operators'; }) export class FormProgressIndicationComponent extends BaseComponent implements OnInit, OnChanges { @Input() formGroup: UntypedFormGroup; - @Input() isDmpEditor: boolean; - @Input() isDatasetEditor: boolean; @Input() public progressValueAccuracy = 2; + @Input() checkVisibility: boolean = false; determinateProgressValue: number; progressSoFar: number; total: number; + totalIds: string[] = []; percent: number; + fieldTypes: string[] = ['dateValue', 'externalIdentifier.identifier', 'externalIdentifier.type', 'reference', 'references', 'textListValue', 'textValue']; constructor(private visibilityRulesService: VisibilityRulesService) { super(); } @@ -43,20 +44,84 @@ export class FormProgressIndicationComponent extends BaseComponent implements On } calculateValueForProgressbar() { - if (this.isDmpEditor) { - this.progressSoFar = this.countFormControlsValidForProgress(this.formGroup); - this.total = this.countFormControlsRequiredFieldsForTotal(this.formGroup); - } else if (this.isDatasetEditor) { - this.progressSoFar = this.countFormControlsValidForProgress(this.formGroup) + this.countFormControlsWithValueForProgress(this.formGroup); - this.total = this.countFormControlsRequiredFieldsForTotal(this.formGroup, true) + this.CountFormControlDepthLengthFotTotal(this.formGroup); - } else { - this.progressSoFar = this.countFormControlsWithValueForProgress(this.formGroup); - this.total = this.CountFormControlDepthLengthFotTotal(this.formGroup); - } + this.progressSoFar = this.countCompletedFields(this.formGroup.get('properties'), this.checkVisibility); + this.total = this.countTotalRequiredFields(this.formGroup.get('properties'), this.checkVisibility); this.percent = (this.progressSoFar / this.total) * 100; this.value = Number.parseFloat(this.percent.toPrecision(this.progressValueAccuracy)); } + countTotalRequiredFields(formControl: AbstractControl, checkVisibility = false): number { + let valueCurrent = 0; + if (formControl instanceof UntypedFormGroup) { + if(!checkVisibility || (!formControl.get('id')?.value || (this.visibilityRulesService.isVisibleMap[formControl.get('id').value] ?? true))) { + Object.keys(formControl.controls).forEach(item => { + const control = formControl.get(item); + valueCurrent = valueCurrent + this.countTotalRequiredFields(control, checkVisibility); + }); + } + } else if (formControl instanceof UntypedFormArray) { + formControl.controls.forEach(item => { + valueCurrent = valueCurrent + this.countTotalRequiredFieldsByFieldset(item.get('ordinal').value, item.get('fields') as UntypedFormGroup); + }); + } + return valueCurrent; + } + + countTotalRequiredFieldsByFieldset(ordinal: number, fieldsFormGroup: UntypedFormGroup): number { + let requiredFieldsCount: number = 0; + const fieldNames = Object.keys(fieldsFormGroup.controls); + for(let item of fieldNames) { + if (!this.checkVisibility || this.visibilityRulesService.isVisible(item, ordinal)) { + const fieldControl = fieldsFormGroup.get(item); + for (let fieldType of this.fieldTypes) { + const typedControl = fieldControl.get(fieldType); + if (this.controlRequired(typedControl) && this.controlEnabled(typedControl)) { + requiredFieldsCount ++; + break; + } + } + } + } + return requiredFieldsCount; + } + + countCompletedFields(formControl: AbstractControl, checkVisibility=false): number { + let completedFieldsCount: number = 0; + if (formControl instanceof UntypedFormGroup) { + if(!checkVisibility || (!formControl.get('id')?.value || (this.visibilityRulesService.isVisibleMap[formControl.get('id').value] ?? true))) { + Object.keys(formControl.controls).forEach(item => { + const control = formControl.get(item); + completedFieldsCount = completedFieldsCount + this.countCompletedFields(control, checkVisibility); + }); + } + } else if (formControl instanceof UntypedFormArray) { + formControl.controls.forEach(item => { + completedFieldsCount = completedFieldsCount + this.countCompletedRequiredFieldsByFieldset(item.get('ordinal').value, item.get('fields') as UntypedFormGroup); + }); + } + return completedFieldsCount; + } + + countCompletedRequiredFieldsByFieldset(ordinal: number, fieldsFormGroup: UntypedFormGroup): number { + let completedFieldsCount: number = 0; + const fieldNames = Object.keys(fieldsFormGroup.controls); + for(let item of fieldNames) { + if (!this.checkVisibility || this.visibilityRulesService.isVisible(item, ordinal)) { + const fieldControl = fieldsFormGroup.get(item); + for (let fieldType of this.fieldTypes) { + const typedControl = fieldControl.get(fieldType); + if (this.controlRequired(typedControl) && this.controlEnabled(typedControl) && typedControl.valid) { + completedFieldsCount ++; + break; + } + } + } + } + return completedFieldsCount; + } + + ////////////////////////////////////////////////////////////////////// + countFormControlsWithValueForProgress(formControl: AbstractControl): number { let valueCurent = 0; if (formControl instanceof UntypedFormGroup) { @@ -169,27 +234,6 @@ export class FormProgressIndicationComponent extends BaseComponent implements On return valueCurrent; } - countFormControlsRequiredFieldsForTotal(formControl: AbstractControl, checkVisibility = false): number { - let valueCurrent = 0; - if (formControl instanceof UntypedFormControl) { - if (this.controlRequired(formControl) && this.controlEnabled(formControl)) { - valueCurrent++; - } - } else if (formControl instanceof UntypedFormGroup) { - if(!checkVisibility || (!formControl.get('id')?.value || (this.visibilityRulesService.isVisibleMap[formControl.get('id').value] ?? true))) { - Object.keys(formControl.controls).forEach(item => { - const control = formControl.get(item); - valueCurrent = valueCurrent + this.countFormControlsRequiredFieldsForTotal(control, checkVisibility); - }); - } - } else if (formControl instanceof UntypedFormArray) { - formControl.controls.forEach(item => { - valueCurrent = valueCurrent + this.countFormControlsRequiredFieldsForTotal(item, checkVisibility); - }); - } - return valueCurrent; - } - controlRequired(formControl: AbstractControl) { if (formControl.validator) { const validator = formControl.validator({} as AbstractControl); @@ -204,8 +248,4 @@ export class FormProgressIndicationComponent extends BaseComponent implements On return true; } else { return false } } - - isEditor(): boolean { - return this.isDmpEditor || this.isDatasetEditor; - } } From bac8fa197ef25817ca0c9fd23dea47206887ae65 Mon Sep 17 00:00:00 2001 From: amentis Date: Mon, 29 Apr 2024 13:39:50 +0300 Subject: [PATCH 06/10] checkbox fix visible state --- .../editor/description-editor.component.ts | 2 +- .../components/form-field/form-field.component.html | 4 ++-- .../components/form-field/form-field.component.ts | 13 ++++++++++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts index 0dc486ee2..3bd5956a1 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts @@ -678,7 +678,7 @@ export class DescriptionEditorComponent extends BaseEditor { this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); - this.refreshOnNavigateToData(data ? data.id : null); + this.formGroup = null; this.backToDmp(); }); } diff --git a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.html b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.html index 8a96b965d..c3e514155 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.html +++ b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.html @@ -82,7 +82,7 @@
- + {{field.data.label}} {{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}}
@@ -119,7 +119,7 @@ {{ (field.data.label | translate)}} - diff --git a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.ts b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.ts index 7cf364498..fc58f2496 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.ts @@ -2,6 +2,7 @@ import { COMMA, ENTER } from '@angular/cdk/keycodes'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit, SimpleChanges } from '@angular/core'; import { UntypedFormControl, UntypedFormGroup } from '@angular/forms'; +import { MatCheckboxChange } from '@angular/material/checkbox'; import { MatDialog } from "@angular/material/dialog"; import { DescriptionTemplateFieldType } from '@app/core/common/enum/description-template-field-type'; import { DescriptionTemplateFieldValidationType } from '@app/core/common/enum/description-template-field-validation-type'; @@ -116,6 +117,15 @@ export class DescriptionFormFieldComponent extends BaseComponent implements OnIn } } + checkBoxChanged(event: MatCheckboxChange){ + if (event.checked){ + this.propertiesFormGroup?.get(this.field.id).get('textValue').setValue("true"); + } else{ + this.propertiesFormGroup?.get(this.field.id).get('textValue').setValue("false"); + } + this.visibilityRulesService.reloadVisibility(); + } + private applyFieldType(){ this.isRequired = this.field.validations?.includes(DescriptionTemplateFieldValidationType.Required); @@ -164,7 +174,8 @@ export class DescriptionFormFieldComponent extends BaseComponent implements OnIn // } break; case DescriptionTemplateFieldType.CHECK_BOX: - this.propertiesFormGroup?.get(this.field.id).get('textValue').setValue(this.propertiesFormGroup?.get(this.field.id).get('textValue').value === 'true'); + if (this.propertiesFormGroup?.get(this.field.id).get('textValue').value == undefined) this.propertiesFormGroup?.get(this.field.id).get('textValue').setValue("false"); + this.visibilityRulesService.reloadVisibility(); break; } From 88ba79c406e9d2ea5f4d3d6a9eded7f2a5c7b80b Mon Sep 17 00:00:00 2001 From: Sofia Papacharalampous Date: Mon, 29 Apr 2024 13:41:01 +0300 Subject: [PATCH 07/10] clean up description editor progress bar --- .../form-progress-indication.component.ts | 59 ++++--------------- 1 file changed, 13 insertions(+), 46 deletions(-) diff --git a/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.ts b/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.ts index 2661630b1..0c0453c40 100644 --- a/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.ts @@ -16,7 +16,6 @@ export class FormProgressIndicationComponent extends BaseComponent implements On determinateProgressValue: number; progressSoFar: number; total: number; - totalIds: string[] = []; percent: number; fieldTypes: string[] = ['dateValue', 'externalIdentifier.identifier', 'externalIdentifier.type', 'reference', 'references', 'textListValue', 'textValue']; @@ -44,80 +43,48 @@ export class FormProgressIndicationComponent extends BaseComponent implements On } calculateValueForProgressbar() { - this.progressSoFar = this.countCompletedFields(this.formGroup.get('properties'), this.checkVisibility); - this.total = this.countTotalRequiredFields(this.formGroup.get('properties'), this.checkVisibility); + this.progressSoFar = this.countRequiredFields(this.formGroup.get('properties'), this.checkVisibility, true); + this.total = this.countRequiredFields(this.formGroup.get('properties'), this.checkVisibility); this.percent = (this.progressSoFar / this.total) * 100; this.value = Number.parseFloat(this.percent.toPrecision(this.progressValueAccuracy)); } - countTotalRequiredFields(formControl: AbstractControl, checkVisibility = false): number { + countRequiredFields(formControl: AbstractControl, checkVisibility = false, countCompletedFields = false): number { let valueCurrent = 0; if (formControl instanceof UntypedFormGroup) { if(!checkVisibility || (!formControl.get('id')?.value || (this.visibilityRulesService.isVisibleMap[formControl.get('id').value] ?? true))) { Object.keys(formControl.controls).forEach(item => { const control = formControl.get(item); - valueCurrent = valueCurrent + this.countTotalRequiredFields(control, checkVisibility); + valueCurrent = valueCurrent + this.countRequiredFields(control, checkVisibility, countCompletedFields); }); } } else if (formControl instanceof UntypedFormArray) { formControl.controls.forEach(item => { - valueCurrent = valueCurrent + this.countTotalRequiredFieldsByFieldset(item.get('ordinal').value, item.get('fields') as UntypedFormGroup); + valueCurrent = valueCurrent + this.countRequiredFieldsByFieldset(item.get('ordinal').value, item.get('fields') as UntypedFormGroup, countCompletedFields); }); } return valueCurrent; } - countTotalRequiredFieldsByFieldset(ordinal: number, fieldsFormGroup: UntypedFormGroup): number { - let requiredFieldsCount: number = 0; + countRequiredFieldsByFieldset(ordinal: number, fieldsFormGroup: UntypedFormGroup, filterValid: boolean = false): number { + let fieldsCount: number = 0; const fieldNames = Object.keys(fieldsFormGroup.controls); for(let item of fieldNames) { if (!this.checkVisibility || this.visibilityRulesService.isVisible(item, ordinal)) { const fieldControl = fieldsFormGroup.get(item); for (let fieldType of this.fieldTypes) { const typedControl = fieldControl.get(fieldType); - if (this.controlRequired(typedControl) && this.controlEnabled(typedControl)) { - requiredFieldsCount ++; + let controlFilter: boolean = this.controlRequired(typedControl) && this.controlEnabled(typedControl); + if (filterValid) controlFilter = controlFilter && typedControl.valid; + + if (controlFilter) { + fieldsCount ++; break; } } } } - return requiredFieldsCount; - } - - countCompletedFields(formControl: AbstractControl, checkVisibility=false): number { - let completedFieldsCount: number = 0; - if (formControl instanceof UntypedFormGroup) { - if(!checkVisibility || (!formControl.get('id')?.value || (this.visibilityRulesService.isVisibleMap[formControl.get('id').value] ?? true))) { - Object.keys(formControl.controls).forEach(item => { - const control = formControl.get(item); - completedFieldsCount = completedFieldsCount + this.countCompletedFields(control, checkVisibility); - }); - } - } else if (formControl instanceof UntypedFormArray) { - formControl.controls.forEach(item => { - completedFieldsCount = completedFieldsCount + this.countCompletedRequiredFieldsByFieldset(item.get('ordinal').value, item.get('fields') as UntypedFormGroup); - }); - } - return completedFieldsCount; - } - - countCompletedRequiredFieldsByFieldset(ordinal: number, fieldsFormGroup: UntypedFormGroup): number { - let completedFieldsCount: number = 0; - const fieldNames = Object.keys(fieldsFormGroup.controls); - for(let item of fieldNames) { - if (!this.checkVisibility || this.visibilityRulesService.isVisible(item, ordinal)) { - const fieldControl = fieldsFormGroup.get(item); - for (let fieldType of this.fieldTypes) { - const typedControl = fieldControl.get(fieldType); - if (this.controlRequired(typedControl) && this.controlEnabled(typedControl) && typedControl.valid) { - completedFieldsCount ++; - break; - } - } - } - } - return completedFieldsCount; + return fieldsCount; } ////////////////////////////////////////////////////////////////////// From aa5235e950abdf99dee4226b76a14df283799cd6 Mon Sep 17 00:00:00 2001 From: Sofia Papacharalampous Date: Mon, 29 Apr 2024 14:24:12 +0300 Subject: [PATCH 08/10] clean up description editor progress bar --- .../form-progress-indication.component.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.ts b/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.ts index 0c0453c40..d73319008 100644 --- a/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/form-progress-indication/form-progress-indication.component.ts @@ -66,7 +66,7 @@ export class FormProgressIndicationComponent extends BaseComponent implements On return valueCurrent; } - countRequiredFieldsByFieldset(ordinal: number, fieldsFormGroup: UntypedFormGroup, filterValid: boolean = false): number { + countRequiredFieldsByFieldset(ordinal: number, fieldsFormGroup: UntypedFormGroup, filterValid: boolean = false): number { let fieldsCount: number = 0; const fieldNames = Object.keys(fieldsFormGroup.controls); for(let item of fieldNames) { @@ -207,7 +207,9 @@ export class FormProgressIndicationComponent extends BaseComponent implements On if (validator && validator.required) { return true; } - } else { return false } + } + + return false; } controlEnabled(formControl: AbstractControl) { From ebbc92b90899be4e6b01cb709bec2caaeb461120 Mon Sep 17 00:00:00 2001 From: Thomas Georgios Giannos Date: Mon, 29 Apr 2024 14:30:56 +0300 Subject: [PATCH 09/10] Adding docs for field types and semantics, site name fix --- .../administration/blueprints/index.md | 2 +- .../commons/_markdown-field-types.md | 45 +++++- .../commons/_markdown-semantics.md | 138 +++++++++++++++++- .../administration/tenant-configuration.md | 2 +- docs/docusaurus.config.ts | 12 +- docs/src/css/custom.css | 4 + 6 files changed, 193 insertions(+), 10 deletions(-) diff --git a/docs/docs/documentation/administration/blueprints/index.md b/docs/docs/documentation/administration/blueprints/index.md index fcab26347..2795b8b6b 100644 --- a/docs/docs/documentation/administration/blueprints/index.md +++ b/docs/docs/documentation/administration/blueprints/index.md @@ -75,7 +75,7 @@ You can add one or more **fields** by clicking the `Add Field` button. For every For a field you can specify: -- **Field Type**: There are three field types available. `System`, `External Reference` and `Custom`. There is more information available in the [Field Types](/docs/documentation/administration/blueprints/field-types) section. +- **Field Type**: There are three field types available. `System`, `External Reference` and `Custom`. There is more information available in the [Field Types](/docs/documentation/administration/blueprints/field-types?t=blueprint) section. - **System Field**: The specific system field we want to add.
*Only applicable if we add a field of type `System`.* - **Reference Type**: The type of external reference we want to add. For more information, you can refer to the [Reference Types](/docs/documentation/administration/reference-types) section of our docs.
*Only applicable if we add a field of type `External Reference`.* - **Label**: A label for the field. diff --git a/docs/docs/documentation/administration/commons/_markdown-field-types.md b/docs/docs/documentation/administration/commons/_markdown-field-types.md index 8647d59b7..719b2f54a 100644 --- a/docs/docs/documentation/administration/commons/_markdown-field-types.md +++ b/docs/docs/documentation/administration/commons/_markdown-field-types.md @@ -1 +1,44 @@ -TODO: Add info about field types \ No newline at end of file +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +In general, there are tree categories of fields that can be used. + +- **System**: These are predefined fields that refer to system or specification information when filled by the end users. The available system fields are the following: + - **Title**: Refers to a title of an entity. + - **Description**: Refers to a description of an entity. + - **Language**: Refers to the language to be used. The languages being displayed to the end user are discussed [here](/docs/documentation/administration/languages). + - **Contact**: Refers to contact information about who should be responsible for the entity. + - **Access**: Indicates if an entity is publicly available. The end user will have to select between `Public` or `Restricted`. + - **User**: Refers to users registered to the platform. +- **External Reference**: These are fields that connect to a locally defined or an external source (an external API in most cases). There is more information available in the [Reference Types](/docs/documentation/administration/reference-types) section. +- **Custom**: These are generic fields that can be added to provide any type of information. The available data types are the following: + - **Text** + - **Rich Text** + - **Date** + - **Number** + +:::info + +Let's explore some specifics based on where these fields are getting setup. + + + In the case of [plan blueprints](/docs/documentation/administration/blueprints/) you define the field you want by making two choices, what is the field category and then what is the system field type or the reference type or the data type respectively. + + + In the case of [description templates](/docs/documentation/administration/templates/) the field type options are 'combined' in one dropdown control. The only difference here is that the options are separated inside that single dropdown based on the field category. + + In the case of custom fields, you can specify the UI control that will be used in the forms. The elements that are supported are the following: + + - **Text Area**: A regular text area (multiple lines) + - **Rich Text Area**: A rich text editor + - **Free Text**: A regular text box (one line) + - **File Upload** + - **Switch** + - **Radio Box** + - **Select** + - **Checkbox** + - **Date Picker** + + + +::: \ No newline at end of file diff --git a/docs/docs/documentation/administration/commons/_markdown-semantics.md b/docs/docs/documentation/administration/commons/_markdown-semantics.md index 0b0a9e858..5df96a13f 100644 --- a/docs/docs/documentation/administration/commons/_markdown-semantics.md +++ b/docs/docs/documentation/administration/commons/_markdown-semantics.md @@ -1 +1,137 @@ -TODO: Add info about semantics \ No newline at end of file +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +:::info + +By **Semantics** we mean a relation a field can have with a part of a data archive specification. When the users try to add semantics, a list of suggestions drops down, containing semantics for `RDA` and `Zenodo`. + +::: + +These are the semantics suggestions. + + + + + + - `rda.dmp.contact` + - `rda.dmp.contact.contact_id.identifier` + - `rda.dmp.contact.contact_id.type` + - `rda.dmp.contact.mbox` + - `rda.dmp.contact.name` + - `rda.dmp.contributor` + - `rda.dmp.contributor.contributor_id.identifier` + - `rda.dmp.contributor.contributor_id.type` + - `rda.dmp.contributor.mbox` + - `rda.dmp.contributor.name` + - `rda.dmp.contributor.role` + - `rda.dmp.cost` + - `rda.dmp.cost.currency_code` + - `rda.dmp.cost.description` + - `rda.dmp.cost.title` + - `rda.dmp.cost.value` + - `rda.dmp.created` + - `rda.dmp.description` + - `rda.dmp.dmp_id` + - `rda.dmp.dmp_id.identifier` + - `rda.dmp.dmp_id.type` + - `rda.dmp.ethical_issues_description` + - `rda.dmp.ethical_issues_exist` + - `rda.dmp.ethical_issues_report` + - `rda.dmp.language` + - `rda.dmp.modified` + - `rda.dmp.project` + - `rda.dmp.project.description` + - `rda.dmp.project.end` + - `rda.dmp.project.funding` + - `rda.dmp.project.funding.funder_id.identifier` + - `rda.dmp.project.funding.funder_id.type` + - `rda.dmp.project.funding.funding_status` + - `rda.dmp.project.funding.grant_id.identifier` + - `rda.dmp.project.funding.grant_id.type` + - `rda.dmp.project.start` + - `rda.dmp.dmp.project.title` + - `rda.dmp.title` + + + - `rda.dataset.data_quality_assurance` + - `rda.dataset.distribution.access_url` + - `rda.dataset.distribution.available_until` + - `rda.dataset.distribution.byte_size` + - `rda.dataset.distribution.data_access` + - `rda.dataset.distribution.description` + - `rda.dataset.distribution.download_url` + - `rda.dataset.distribution.format` + - `rda.dataset.distribution.host.availability` + - `rda.dataset.distribution.host.backup_frequency` + - `rda.dataset.distribution.host.backup_type` + - `rda.dataset.distribution.host.certified_with` + - `rda.dataset.distribution.host.description` + - `rda.dataset.distribution.host.geo_location` + - `rda.dataset.distribution.host.pid_system` + - `rda.dataset.distribution.host.storage_type` + - `rda.dataset.distribution.host.supports_versioning` + - `rda.dataset.distribution.host.title` + - `rda.dataset.distribution.host.url` + - `rda.dataset.distribution.license.license_ref` + - `rda.dataset.distribution.license.start_date` + - `rda.dataset.distribution.title` + - `rda.dataset.keyword` + - `rda.dataset.language` + - `rda.dataset.metadata.description` + - `rda.dataset.metadata.language` + - `rda.dataset.metadata.metadata_standard_id` + - `rda.dataset.metadata.metadata_standard_id.identifier` + - `rda.dataset.metadata.metadata_standard_id.type` + - `rda.dataset.personal_data` + - `rda.dataset.preservation_statement` + - `rda.dataset.security_and_privacy` + - `rda.dataset.security_and_privacy.description` + - `rda.dataset.security_and_privacy.title` + - `rda.dataset.sensitive_data` + - `rda.dataset.technical_resource.description` + - `rda.dataset.technical_resource.name` + - `rda.dataset.title` + - `rda.dataset.type` + - `rda.dataset.issued` + - `rda.dataset.dataset_id` + - `rda.dataset.dataset_id.identifier` + - `rda.dataset.dataset_id.type` + - `rda.dataset.description` + + + + + - `zenodo.related_identifiers.isCitedBy` + - `zenodo.related_identifiers.cites` + - `zenodo.related_identifiers.isSupplementTo` + - `zenodo.related_identifiers.isSupplementedBy` + - `zenodo.related_identifiers.isContinuedBy` + - `zenodo.related_identifiers.continues` + - `zenodo.related_identifiers.isDescribedBy` + - `zenodo.related_identifiers.describes` + - `zenodo.related_identifiers.hasMetadata` + - `zenodo.related_identifiers.isMetadataFor` + - `zenodo.related_identifiers.isNewVersionOf` + - `zenodo.related_identifiers.isPreviousVersionOf` + - `zenodo.related_identifiers.isPartOf` + - `zenodo.related_identifiers.hasPart` + - `zenodo.related_identifiers.isReferencedBy` + - `zenodo.related_identifiers.references` + - `zenodo.related_identifiers.isDocumentedBy` + - `zenodo.related_identifiers.documents` + - `zenodo.related_identifiers.isCompiledBy` + - `zenodo.related_identifiers.compiles` + - `zenodo.related_identifiers.isVariantFormOf` + - `zenodo.related_identifiers.isOriginalFormof` + - `zenodo.related_identifiers.isIdenticalTo` + - `zenodo.related_identifiers.isAlternateIdentifier` + - `zenodo.related_identifiers.isReviewedBy` + - `zenodo.related_identifiers.reviews` + - `zenodo.related_identifiers.isDerivedFrom` + - `zenodo.related_identifiers.isSourceOf` + - `zenodo.related_identifiers.requires` + - `zenodo.related_identifiers.isRequiredBy` + - `zenodo.related_identifiers.isObsoletedBy` + - `zenodo.related_identifiers.obsoletes` + + \ No newline at end of file diff --git a/docs/docs/documentation/administration/tenant-configuration.md b/docs/docs/documentation/administration/tenant-configuration.md index 10e0d03ee..3199e9e44 100644 --- a/docs/docs/documentation/administration/tenant-configuration.md +++ b/docs/docs/documentation/administration/tenant-configuration.md @@ -3,4 +3,4 @@ sidebar_position: 11 description: Configure the tenant you are logged in with --- -# Tenant configuration \ No newline at end of file +# Tenant Configuration \ No newline at end of file diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index 0a1e90f91..e8ee9765a 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -3,8 +3,8 @@ import type { Config } from '@docusaurus/types'; import type * as Preset from '@docusaurus/preset-classic'; const config: Config = { - title: 'OpenDMP', - tagline: 'OpenDMP', + title: 'OpenCDMP', + tagline: 'OpenCDMP Docs', favicon: 'img/favicon.ico', // Set the production url of your site here @@ -58,9 +58,9 @@ const config: Config = { // Replace with your project's social card image: 'img/docusaurus-social-card.jpg', navbar: { - title: 'OpenDMP', + title: 'OpenCDMP', logo: { - alt: 'OpenDMP Logo', + alt: 'OpenCDMP Logo', src: 'img/logo.svg', }, items: [ @@ -78,7 +78,7 @@ const config: Config = { }, { href: 'https://test4.opendmp.eu/splash/', - label: 'Visit OpenDMP', + label: 'Visit OpenCDMP', position: 'right', }, ], @@ -138,7 +138,7 @@ const config: Config = { ], }, ], - copyright: `Copyright © ${new Date().getFullYear()} OpenDMP. Built with Docusaurus.`, + copyright: `Copyright © ${new Date().getFullYear()} OpenCDMP. Built with Docusaurus.`, }, prism: { theme: prismThemes.github, diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css index 2bc6a4cfd..e34952506 100644 --- a/docs/src/css/custom.css +++ b/docs/src/css/custom.css @@ -28,3 +28,7 @@ --ifm-color-primary-lightest: #4fddbf; --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); } + +.outer-tab { + margin-left: 1rem; +} From e871068443d6fcfecb089dca1f55c9d6ffd572c2 Mon Sep 17 00:00:00 2001 From: amentis Date: Mon, 29 Apr 2024 14:35:11 +0300 Subject: [PATCH 10/10] new version small fix --- .../src/main/java/org/opencdmp/service/dmp/DmpServiceImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/core/src/main/java/org/opencdmp/service/dmp/DmpServiceImpl.java b/backend/core/src/main/java/org/opencdmp/service/dmp/DmpServiceImpl.java index 413212986..c429b52f2 100644 --- a/backend/core/src/main/java/org/opencdmp/service/dmp/DmpServiceImpl.java +++ b/backend/core/src/main/java/org/opencdmp/service/dmp/DmpServiceImpl.java @@ -383,6 +383,7 @@ public class DmpServiceImpl implements DmpService { newDmp.setStatus(DmpStatus.Draft); newDmp.setProperties(oldDmpEntity.getProperties()); newDmp.setBlueprintId(model.getBlueprintId()); + newDmp.setAccessType(oldDmpEntity.getAccessType()); newDmp.setCreatorId(this.userScope.getUserId()); this.entityManager.persist(newDmp);