diff --git a/dmp-frontend/src/app/app-routing.module.ts b/dmp-frontend/src/app/app-routing.module.ts index e9bf8a867..e48784c9e 100644 --- a/dmp-frontend/src/app/app-routing.module.ts +++ b/dmp-frontend/src/app/app-routing.module.ts @@ -381,6 +381,10 @@ const appRoutes: Routes = [ const tenantEnrichedRoutes: Routes = [ { path: 't/:tenant_code', + data: { + breadcrumb: true, + hideItem: true + }, children: [ ...appRoutes ] diff --git a/dmp-frontend/src/app/app.component.ts b/dmp-frontend/src/app/app.component.ts index 4228f69bb..0187e0567 100644 --- a/dmp-frontend/src/app/app.component.ts +++ b/dmp-frontend/src/app/app.component.ts @@ -189,9 +189,6 @@ export class AppComponent implements OnInit, AfterViewInit { const enrichedUrl = this.tenantHandlingService.getUrlEnrichedWithTenantCode(event.url, this.authentication.selectedTenant() ?? 'default'); if (event.url != enrichedUrl) { this.router.navigate([enrichedUrl]); - console.log('enriched') - console.log(event.url) - console.log(enrichedUrl) } }); diff --git a/dmp-frontend/src/app/app.module.ts b/dmp-frontend/src/app/app.module.ts index 82c0f3c90..662863e8f 100644 --- a/dmp-frontend/src/app/app.module.ts +++ b/dmp-frontend/src/app/app.module.ts @@ -83,7 +83,7 @@ const appearance: MatFormFieldDefaultOptions = { // appearance: 'standard' }; -export function InstallationConfigurationFactory(appConfig: ConfigurationService, keycloak: KeycloakService, authService: AuthService, languageService: LanguageService, tenantHandlingService: TenantHandlingService) { +export function InstallationConfigurationFactory(appConfig: ConfigurationService, keycloak: KeycloakService, authService: AuthService, languageService: LanguageService, tenantHandlingService:TenantHandlingService) { return () => appConfig.loadConfiguration().then(() => { return languageService.loadAvailableLanguages().toPromise(); }).then(x => keycloak.init({ diff --git a/dmp-frontend/src/app/core/services/auth/auth.service.ts b/dmp-frontend/src/app/core/services/auth/auth.service.ts index 52e620eee..1abcd36ce 100644 --- a/dmp-frontend/src/app/core/services/auth/auth.service.ts +++ b/dmp-frontend/src/app/core/services/auth/auth.service.ts @@ -177,9 +177,6 @@ export class AuthService extends BaseService { } private ensureTenant(tenantCode: string): Observable { - // if (!this.selectedTenant()) { - // this.selectedTenant('default'); - // } const params = new BaseHttpParams(); params.interceptorContext = { excludedInterceptors: [InterceptorType.TenantHeaderInterceptor] @@ -193,16 +190,11 @@ export class AuthService extends BaseService { } else { this.selectedTenant(null); } - // if (this.selectedTenant()) { - // if (myTenants.findIndex(x => x.code.toLocaleLowerCase() == this.selectedTenant().toLocaleLowerCase()) < 0) { - // this.selectedTenant(null); - // } - // } - // if (!this.selectedTenant()) { - // if (myTenants.length > 0) { - // this.selectedTenant(myTenants[0]?.code); - // } - // } + if (!this.selectedTenant()) { + if (myTenants.length > 0) { + this.selectedTenant(myTenants[0]?.code); + } + } } else { this.selectedTenant(null); } diff --git a/dmp-frontend/src/app/ui/auth/logout/logout.component.ts b/dmp-frontend/src/app/ui/auth/logout/logout.component.ts index 8b94dc9af..483613234 100644 --- a/dmp-frontend/src/app/ui/auth/logout/logout.component.ts +++ b/dmp-frontend/src/app/ui/auth/logout/logout.component.ts @@ -1,5 +1,4 @@ import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; import { AuthService } from '@app/core/services/auth/auth.service'; import { KeycloakService } from 'keycloak-angular'; @@ -11,11 +10,10 @@ export class LogoutComponent implements OnInit { constructor( private keycloak: KeycloakService, private authService: AuthService, - ) {} + ) { } ngOnInit() { this.authService.clear(); - debugger; this.keycloak.logout(location.origin).then(() => { localStorage.clear(); // this.router.navigate(['./'], { replaceUrl: true }); diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.model.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.model.ts index bebd89a10..1d2ae594c 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.model.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.model.ts @@ -7,7 +7,7 @@ import { DescriptionTemplate, DescriptionTemplateField, DescriptionTemplateField import { Description, DescriptionExternalIdentifier, DescriptionExternalIdentifierPersist, DescriptionField, DescriptionFieldPersist, DescriptionPersist, DescriptionPropertyDefinition, DescriptionPropertyDefinitionFieldSet, DescriptionPropertyDefinitionFieldSetItem, DescriptionPropertyDefinitionFieldSetItemPersist, DescriptionPropertyDefinitionFieldSetPersist, DescriptionPropertyDefinitionPersist, DescriptionReference, DescriptionReferencePersist } from "@app/core/model/description/description"; import { ReferencePersist } from "@app/core/model/reference/reference"; import { BaseEditorModel } from "@common/base/base-form-editor-model"; -import { BackendErrorValidator, RequiredWithVisibilityRulesValidator } from '@common/forms/validation/custom-validator'; +import { BackendErrorValidator, MinMaxValidator, RequiredWithVisibilityRulesValidator, UrlValidator } from '@common/forms/validation/custom-validator'; import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; import { Validation, ValidationContext } from '@common/forms/validation/validation-context'; import { Guid } from "@common/types/guid"; @@ -270,11 +270,14 @@ export class DescriptionPropertyDefinitionFieldSetEditorModel implements Descrip items?: DescriptionPropertyDefinitionFieldSetItemEditorModel[] = []; protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + fieldSetDefinition: DescriptionTemplateFieldSet; + constructor( public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() ) { } public fromModel(item: DescriptionPropertyDefinitionFieldSet, descriptionReferences: DescriptionReference[], definitionFieldSet: DescriptionTemplateFieldSet): DescriptionPropertyDefinitionFieldSetEditorModel { + this.fieldSetDefinition = definitionFieldSet; if (item) { if (item.items) { item.items.map(x => this.items.push(new DescriptionPropertyDefinitionFieldSetItemEditorModel(this.validationErrorModel).fromModel(x, descriptionReferences, definitionFieldSet))); } } @@ -291,7 +294,8 @@ export class DescriptionPropertyDefinitionFieldSetEditorModel implements Descrip if (context == null) { context = DescriptionPropertyDefinitionFieldSetEditorModel.createValidationContext({ validationErrorModel: this.validationErrorModel, - rootPath + rootPath, + fieldSetDefinition: this.fieldSetDefinition }); } @@ -309,14 +313,25 @@ export class DescriptionPropertyDefinitionFieldSetEditorModel implements Descrip static createValidationContext(params: { rootPath?: string, - validationErrorModel: ValidationErrorModel + validationErrorModel: ValidationErrorModel, + fieldSetDefinition: DescriptionTemplateFieldSet }): ValidationContext { const { rootPath = '', validationErrorModel } = params; const baseContext: ValidationContext = new ValidationContext(); const baseValidationArray: Validation[] = new Array(); - baseValidationArray.push({ key: 'items', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}items`)] }); + const validators = []; + validators.push(BackendErrorValidator(validationErrorModel, `${rootPath}items`)); + if (params.fieldSetDefinition?.multiplicity?.min >= 0 && params.fieldSetDefinition?.multiplicity?.max >= 0) { + validators.push(MinMaxValidator(params.fieldSetDefinition.multiplicity.min, params.fieldSetDefinition.multiplicity.min)); + } else if (params.fieldSetDefinition?.multiplicity?.min >= 0) { + validators.push(Validators.min(params.fieldSetDefinition.multiplicity.min)); + } + else if (params.fieldSetDefinition?.multiplicity?.max >= 0) { + validators.push(Validators.max(params.fieldSetDefinition.multiplicity.max)); + } + baseValidationArray.push({ key: 'items', validators: validators }); baseContext.validation = baseValidationArray; return baseContext; } @@ -587,7 +602,7 @@ export class DescriptionFieldEditorModel implements DescriptionFieldPersist { validators.push(RequiredWithVisibilityRulesValidator(params.visibilityRulesService, params.visibilityRulesKey)); break; case DescriptionTemplateFieldValidationType.Url: - //TODO + validators.push(UrlValidator()); break; } }); @@ -789,45 +804,6 @@ export class DescriptionFieldIndicator { this.sectionIds = sectionIds; this.fieldSetId = fieldSetId; this.fieldId = fieldId; - - switch (type) { - case DescriptionTemplateFieldType.FREE_TEXT: - case DescriptionTemplateFieldType.TEXT_AREA: - case DescriptionTemplateFieldType.UPLOAD: - case DescriptionTemplateFieldType.RICH_TEXT_AREA: - case DescriptionTemplateFieldType.RADIO_BOX: - this.type = "textValue"; - break; - case DescriptionTemplateFieldType.DATASET_IDENTIFIER: - case DescriptionTemplateFieldType.VALIDATION: - this.type = "externalIdentifier"; - break; - case DescriptionTemplateFieldType.DATE_PICKER: - this.type = "dateValue"; - break; - case DescriptionTemplateFieldType.CHECK_BOX: - case DescriptionTemplateFieldType.BOOLEAN_DECISION: - this.type = "booleanValue"; - break; - case DescriptionTemplateFieldType.INTERNAL_ENTRIES_DESCRIPTIONS: - if (multipleSelect) this.type = "textListValue"; - else this.type = "textValue" - break; - case DescriptionTemplateFieldType.INTERNAL_ENTRIES_DMPS: - if (multipleSelect) this.type = "textListValue"; - else this.type = "textValue"; - break; - case DescriptionTemplateFieldType.REFERENCE_TYPES: - if (multipleSelect) this.type = "references"; - else this.type = "reference"; - break; - case DescriptionTemplateFieldType.SELECT: - if (multipleSelect) this.type = "textListValue"; - else this.type = "textValue"; - break; - case DescriptionTemplateFieldType.TAGS: - this.type = "tags"; - break; - } + this.type = DescriptionEditorModel.getFieldValueControlName(type, multipleSelect); } } 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 7d8660ee2..9e9d0bb7c 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 @@ -11,7 +11,7 @@
{{ field.data.label }} - + {{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} {{'GENERAL.VALIDATION.URL.MESSAGE' | translate}} @@ -31,14 +31,14 @@
- + {{opt.label}} {{propertiesFormGroup?.get(field.id).get('textListValue').getError('backendError').message}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} - + {{opt.label}} @@ -51,25 +51,25 @@
- - {{ field.data.label }} - - - {{propertiesFormGroup?.get(field.id).get('textListValue').getError('backendError').message}} - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }} - - - - - {{ field.data.label }} - - - {{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}} - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }} - - + + {{ field.data.label }} + + + {{propertiesFormGroup?.get(field.id).get('textListValue').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }} + + + + + {{ field.data.label }} + + + {{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }} + +
@@ -87,7 +87,7 @@ {{ field.data.label }} - + {{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -105,7 +105,7 @@
{{ field.data.label }} - + @@ -148,7 +148,7 @@
- + {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.ACTIONS.YES" | translate }} {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.ACTIONS.NO" | translate }} {{propertiesFormGroup?.get(field.id).get('booleanValue').getError('backendError').message}} @@ -159,7 +159,7 @@
- + {{option.label}} {{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}} @@ -170,7 +170,7 @@ {{ field.data.label }} - + {{propertiesFormGroup?.get(field.id).get('dateValue').getError('backendError').message}} @@ -185,13 +185,13 @@
{{ field.data.label }} - + {{propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier').getError('backendError').message}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} {{ field.data.label }} - + {{ type.name }} @@ -206,7 +206,7 @@
{{ field.data.label }} - + {{propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier').getError('backendError').message}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -231,4 +231,4 @@
-
+
\ No newline at end of file diff --git a/dmp-frontend/src/common/forms/validation/custom-validator.ts b/dmp-frontend/src/common/forms/validation/custom-validator.ts index 38b80f533..e59070d63 100644 --- a/dmp-frontend/src/common/forms/validation/custom-validator.ts +++ b/dmp-frontend/src/common/forms/validation/custom-validator.ts @@ -32,8 +32,8 @@ export function CustomErrorValidator(errorModel: ValidationErrorModel, propertyN export function RequiredWithVisibilityRulesValidator(visibilityRulesService: VisibilityRulesService, visibilityRulesKey: string) { return (control: AbstractControl): { [key: string]: any } => { - - if(visibilityRulesService.isVisibleMap[visibilityRulesKey] ?? true) { + + if (visibilityRulesService.isVisibleMap[visibilityRulesKey] ?? true) { return Validators.required(control); } control.setErrors(null); @@ -41,6 +41,23 @@ export function RequiredWithVisibilityRulesValidator(visibilityRulesService: Vis }; } +export function UrlValidator() { + return (control: AbstractControl): { [key: string]: any } => { + const urlRegex = /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/; + return Validators.pattern(urlRegex); + + }; +} + +export function MinMaxValidator(min: number, max: number) { + return (control: AbstractControl): { [key: string]: any } => { + + + return null; + + }; +} + export function DateValidator(): ValidatorFn { return (control: AbstractControl): { [key: string]: any } => { if (control.value) {