diff --git a/Dockerfile.Sonar b/Dockerfile.Sonar deleted file mode 100644 index c6a20d0ba..000000000 --- a/Dockerfile.Sonar +++ /dev/null @@ -1,92 +0,0 @@ -####################################### Build stage ####################################### -FROM maven:3.9-eclipse-temurin-21-alpine - -ARG MAVEN_ACCOUNT_USR -ARG MAVEN_ACCOUNT_PSW -ARG REVISION -ARG PROFILE -ARG ORACLE_URL -ARG ORACLE_TOKEN -ARG BUILD -ENV server_username=$MAVEN_ACCOUNT_USR -ENV server_password=$MAVEN_ACCOUNT_PSW -ARG CITE_MAVEN_REPO_URL - -COPY /dmp-backend/pom.xml /build/ -COPY /dmp-backend/core /build/core/ -COPY /dmp-backend/web /build/web/ -COPY /dmp-backend/settings.xml /root/.m2/settings.xml -RUN rm -f /build/web/src/main/resources/config/*-devel.yml -RUN rm -f /build/web/src/main/resources/logging/*.xml - -COPY /notification-service/pom.xml /build-notification/ -COPY /notification-service/core /build-notification/core/ -COPY /notification-service/web /build-notification/web/ -COPY /notification-service/settings.xml /root/.m2/settings.xml -RUN rm -f /build/notification-web/src/main/resources/config/app.env -RUN rm -f /build/notification-web/src/main/resources/config/*-devel.yml -RUN rm -f /build/notification-web/src/main/resources/logging/*.xml -RUN rm -f /build/notification-web/src/main/resources/certificates/*.crt - -COPY /annotation-service/pom.xml /build-annotation/ -COPY /annotation-service/annotation /build-notification/annotation/ -COPY /annotation-service/annotation-web /build-notification/annotation-web/ -COPY /annotation-service/settings.xml /root/.m2/settings.xml -RUN rm -f /build/annotation-web/src/main/resources/config/app.env -RUN rm -f /build/annotation-web/src/main/resources/config/*-devel.yml -RUN rm -f /build/annotation-web/src/main/resources/logging/*.xml -RUN rm -f /build/annotation-web/src/main/resources/certificates/*.crt - -COPY oracle.local.cite.gr.crt $JAVA_HOME/conf/security -RUN cd "$JAVA_HOME"/conf/security && keytool -cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias oraclecert -file oracle.local.cite.gr.crt - -WORKDIR /build/ -RUN mvn -Drevision=${REVISION} -DciteMavenRepoUrl=${CITE_MAVEN_REPO_URL} -P${PROFILE} clean -RUN mvn -Drevision=${REVISION} -DciteMavenRepoUrl=${CITE_MAVEN_REPO_URL} -P${PROFILE} install -RUN mvn -Drevision=${REVISION} -DciteMavenRepoUrl=${CITE_MAVEN_REPO_URL} -P${PROFILE} package -RUN mvn sonar:sonar -Dsonar.projectKey=OpenDMP:backend-api -Dsonar.login=${ORACLE_TOKEN} -Dsonar.host.url=${ORACLE_URL} -Dsonar.projectName='OpenDMP API' - -WORKDIR /build-notification/ -RUN mvn -Drevision=${REVISION} -DciteMavenRepoUrl=${CITE_MAVEN_REPO_URL} -P${PROFILE} clean -RUN mvn -Drevision=${REVISION} -DciteMavenRepoUrl=${CITE_MAVEN_REPO_URL} -P${PROFILE} install -RUN mvn -Drevision=${REVISION} -DciteMavenRepoUrl=${CITE_MAVEN_REPO_URL} -P${PROFILE} package -RUN mvn sonar:sonar -Dsonar.projectKey=OpenDMP:notification-api -Dsonar.login=${ORACLE_TOKEN} -Dsonar.host.url=${ORACLE_URL} -Dsonar.projectName='OpenDMP Notification API' - -WORKDIR /build-annotation/ -RUN mvn -Drevision=${REVISION} -DciteMavenRepoUrl=${CITE_MAVEN_REPO_URL} -P${PROFILE} clean -RUN mvn -Drevision=${REVISION} -DciteMavenRepoUrl=${CITE_MAVEN_REPO_URL} -P${PROFILE} install -RUN mvn -Drevision=${REVISION} -DciteMavenRepoUrl=${CITE_MAVEN_REPO_URL} -P${PROFILE} package -RUN mvn sonar:sonar -Dsonar.projectKey=OpenDMP:annotation-api -Dsonar.login=${ORACLE_TOKEN} -Dsonar.host.url=${ORACLE_URL} -Dsonar.projectName='OpenDMP Annotation API' - -################################## frontend analysis ########################################## -FROM node:20 - -ARG ORACLE_URL -ARG ORACLE_TOKEN -ARG BUILD_VERSION -ENV ORACLE_URL=$ORACLE_URL -ENV ORACLE_TOKEN=$ORACLE_TOKEN -ENV BUILD_VERSION=$BUILD_VERSION - -RUN apt-get -y update && apt-get install -y openjdk-11-jdk locales && apt-get clean -RUN mkdir -p /usr/share/man/man1/ -RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \ - locale-gen -ENV LC_ALL en_US.UTF-8 -ENV LANG en_US.UTF-8 -ENV LANGUAGE en_US:en - -COPY oracle.local.cite.gr.crt /usr/local/share/ca-certificates/oracle.local.cite.gr.crt -RUN update-ca-certificates - -# copy the package.json to install dependencies -COPY /dmp-frontend/package.json ./ -COPY /dmp-frontend/package-lock.json ./ - -# Install the dependencies and make the folder -RUN npm install sonar-scanner --save-dev -RUN npm install --legacy-peer-deps && mkdir /src && mv ./node_modules ./src - -WORKDIR /src -COPY . . -RUN npm run sonar-scanner \ No newline at end of file diff --git a/annotation-service/Dockerfile.Sonar b/annotation-service/Dockerfile.Sonar new file mode 100644 index 000000000..8e310f760 --- /dev/null +++ b/annotation-service/Dockerfile.Sonar @@ -0,0 +1,30 @@ +####################################### Build stage ####################################### +FROM maven:3.9-eclipse-temurin-21-alpine + +ARG MAVEN_ACCOUNT_USR +ARG MAVEN_ACCOUNT_PSW +ARG REVISION +ARG PROFILE +ARG ORACLE_URL +ARG ORACLE_TOKEN +ENV server_username=$MAVEN_ACCOUNT_USR +ENV server_password=$MAVEN_ACCOUNT_PSW +ARG CITE_MAVEN_REPO_URL + +COPY pom.xml /build/ +COPY annotation /build/annotation/ +COPY annotation-web /build/annotation-web/ +COPY settings.xml /root/.m2/settings.xml +RUN rm -f /build/annotation-web/src/main/resources/config/app.env +RUN rm -f /build/annotation-web/src/main/resources/config/*-devel.yml +RUN rm -f /build/annotation-web/src/main/resources/logging/*.xml +RUN rm -f /build/annotation-web/src/main/resources/certificates/*.crt + +COPY oracle.local.cite.gr.crt $JAVA_HOME/conf/security +RUN cd "$JAVA_HOME"/conf/security && keytool -cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias oraclecert -file oracle.local.cite.gr.crt + +WORKDIR /build/ +RUN mvn -Drevision=${REVISION} -DciteMavenRepoUrl=${CITE_MAVEN_REPO_URL} -P${PROFILE} clean +RUN mvn -Drevision=${REVISION} -DciteMavenRepoUrl=${CITE_MAVEN_REPO_URL} -P${PROFILE} install +RUN mvn -Drevision=${REVISION} -DciteMavenRepoUrl=${CITE_MAVEN_REPO_URL} -P${PROFILE} package +RUN mvn sonar:sonar -Dsonar.projectKey=OpenDMP:annotation-api -Dsonar.login=${ORACLE_TOKEN} -Dsonar.host.url=${ORACLE_URL} -Dsonar.projectName='OpenDMP Annotation API' \ No newline at end of file diff --git a/dmp-backend/Dockerfile.Sonar b/dmp-backend/Dockerfile.Sonar new file mode 100644 index 000000000..a4de0dde7 --- /dev/null +++ b/dmp-backend/Dockerfile.Sonar @@ -0,0 +1,29 @@ +####################################### Build stage ####################################### +FROM maven:3.9-eclipse-temurin-21-alpine + +ARG MAVEN_ACCOUNT_USR +ARG MAVEN_ACCOUNT_PSW +ARG REVISION +ARG PROFILE +ARG ORACLE_URL +ARG ORACLE_TOKEN +ENV server_username=$MAVEN_ACCOUNT_USR +ENV server_password=$MAVEN_ACCOUNT_PSW +ARG CITE_MAVEN_REPO_URL + +COPY pom.xml /build/ +COPY core /build/core/ +COPY web /build/web/ +COPY settings.xml /root/.m2/settings.xml +RUN rm -f /build/web/src/main/resources/config/*-devel.yml +RUN rm -f /build/web/src/main/resources/logging/*.xml + + +COPY oracle.local.cite.gr.crt $JAVA_HOME/conf/security +RUN cd "$JAVA_HOME"/conf/security && keytool -cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias oraclecert -file oracle.local.cite.gr.crt + +WORKDIR /build/ +RUN mvn -Drevision=${REVISION} -DciteMavenRepoUrl=${CITE_MAVEN_REPO_URL} -P${PROFILE} clean +RUN mvn -Drevision=${REVISION} -DciteMavenRepoUrl=${CITE_MAVEN_REPO_URL} -P${PROFILE} install +RUN mvn -Drevision=${REVISION} -DciteMavenRepoUrl=${CITE_MAVEN_REPO_URL} -P${PROFILE} package +RUN mvn sonar:sonar -Dsonar.projectKey=OpenDMP:backend-api -Dsonar.login=${ORACLE_TOKEN} -Dsonar.host.url=${ORACLE_URL} -Dsonar.projectName='OpenDMP API' \ No newline at end of file diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/tenantconfiguration/DepositTenantConfigurationEntity.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/tenantconfiguration/DepositTenantConfigurationEntity.java index b6834ae24..22d9c0baa 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/types/tenantconfiguration/DepositTenantConfigurationEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/tenantconfiguration/DepositTenantConfigurationEntity.java @@ -6,6 +6,7 @@ import java.util.List; public class DepositTenantConfigurationEntity { private List sources; + private boolean disableSystemSources; public List getSources() { return sources; @@ -14,4 +15,12 @@ public class DepositTenantConfigurationEntity { public void setSources(List sources) { this.sources = sources; } + + public boolean getDisableSystemSources() { + return disableSystemSources; + } + + public void setDisableSystemSources(boolean disableSystemSources) { + this.disableSystemSources = disableSystemSources; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/tenantconfiguration/FileTransformerTenantConfigurationEntity.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/tenantconfiguration/FileTransformerTenantConfigurationEntity.java index 736d83c36..fddf91e0d 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/types/tenantconfiguration/FileTransformerTenantConfigurationEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/tenantconfiguration/FileTransformerTenantConfigurationEntity.java @@ -7,6 +7,7 @@ import java.util.List; public class FileTransformerTenantConfigurationEntity { private List sources; + private boolean disableSystemSources; public List getSources() { return sources; @@ -15,4 +16,12 @@ public class FileTransformerTenantConfigurationEntity { public void setSources(List sources) { this.sources = sources; } + + public boolean getDisableSystemSources() { + return disableSystemSources; + } + + public void setDisableSystemSources(boolean disableSystemSources) { + this.disableSystemSources = disableSystemSources; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/tenantconfiguration/DepositTenantConfigurationBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/tenantconfiguration/DepositTenantConfigurationBuilder.java index 3c5bd5506..ba24f8a7f 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/tenantconfiguration/DepositTenantConfigurationBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/tenantconfiguration/DepositTenantConfigurationBuilder.java @@ -51,6 +51,7 @@ public class DepositTenantConfigurationBuilder extends BaseBuilder sources; public static final String _sources = "sources"; + private Boolean disableSystemSources; + public static final String _disableSystemSources = "disableSystemSources"; public List getSources() { return sources; @@ -29,6 +31,14 @@ public class DepositTenantConfigurationPersist { this.sources = sources; } + public Boolean getDisableSystemSources() { + return disableSystemSources; + } + + public void setDisableSystemSources(Boolean disableSystemSources) { + this.disableSystemSources = disableSystemSources; + } + @Component(DepositTenantConfigurationPersist.DepositTenantConfigurationPersistValidator.ValidatorName) @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public static class DepositTenantConfigurationPersistValidator extends BaseValidator { @@ -54,6 +64,9 @@ public class DepositTenantConfigurationPersist { @Override protected List specifications(DepositTenantConfigurationPersist item) { return Arrays.asList( + this.spec() + .must(() -> !this.isNull(item.getDisableSystemSources())) + .failOn(DepositTenantConfigurationPersist._disableSystemSources).failWith(messageSource.getMessage("Validation_Required", new Object[]{DepositTenantConfigurationPersist._disableSystemSources}, LocaleContextHolder.getLocale())), this.spec() .must(() -> !this.isListNullOrEmpty(item.getSources())) .failOn(DepositTenantConfigurationPersist._sources).failWith(messageSource.getMessage("Validation_Required", new Object[]{DepositTenantConfigurationPersist._sources}, LocaleContextHolder.getLocale())), diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/tenantconfiguration/FileTransformerTenantConfigurationPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/tenantconfiguration/FileTransformerTenantConfigurationPersist.java index a81b44f91..ab4a88f02 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/tenantconfiguration/FileTransformerTenantConfigurationPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/tenantconfiguration/FileTransformerTenantConfigurationPersist.java @@ -19,6 +19,8 @@ public class FileTransformerTenantConfigurationPersist { private List sources; public static final String _sources = "sources"; + private Boolean disableSystemSources; + public static final String _disableSystemSources = "disableSystemSources"; public List getSources() { return sources; @@ -28,6 +30,14 @@ public class FileTransformerTenantConfigurationPersist { this.sources = sources; } + public Boolean getDisableSystemSources() { + return disableSystemSources; + } + + public void setDisableSystemSources(Boolean disableSystemSources) { + this.disableSystemSources = disableSystemSources; + } + @Component(FileTransformerTenantConfigurationPersist.FileTransformerTenantConfigurationPersistValidator.ValidatorName) @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public static class FileTransformerTenantConfigurationPersistValidator extends BaseValidator { @@ -53,6 +63,9 @@ public class FileTransformerTenantConfigurationPersist { @Override protected List specifications(FileTransformerTenantConfigurationPersist item) { return Arrays.asList( + this.spec() + .must(() -> !this.isNull(item.getDisableSystemSources())) + .failOn(FileTransformerTenantConfigurationPersist._disableSystemSources).failWith(messageSource.getMessage("Validation_Required", new Object[]{FileTransformerTenantConfigurationPersist._disableSystemSources}, LocaleContextHolder.getLocale())), this.spec() .must(() -> !this.isListNullOrEmpty(item.getSources())) .failOn(FileTransformerTenantConfigurationPersist._sources).failWith(messageSource.getMessage("Validation_Required", new Object[]{FileTransformerTenantConfigurationPersist._sources}, LocaleContextHolder.getLocale())), diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/tenantconfiguration/DepositTenantConfiguration.java b/dmp-backend/core/src/main/java/eu/eudat/model/tenantconfiguration/DepositTenantConfiguration.java index e4d258953..c96a5b271 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/tenantconfiguration/DepositTenantConfiguration.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/tenantconfiguration/DepositTenantConfiguration.java @@ -8,6 +8,8 @@ import java.util.List; public class DepositTenantConfiguration { private List sources; public static final String _sources = "sources"; + private Boolean disableSystemSources; + public static final String _disableSystemSources = "disableSystemSources"; public List getSources() { return sources; @@ -16,4 +18,12 @@ public class DepositTenantConfiguration { public void setSources(List sources) { this.sources = sources; } + + public Boolean getDisableSystemSources() { + return disableSystemSources; + } + + public void setDisableSystemSources(Boolean disableSystemSources) { + this.disableSystemSources = disableSystemSources; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/tenantconfiguration/FileTransformerTenantConfiguration.java b/dmp-backend/core/src/main/java/eu/eudat/model/tenantconfiguration/FileTransformerTenantConfiguration.java index 2b3dec443..ac6207f25 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/tenantconfiguration/FileTransformerTenantConfiguration.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/tenantconfiguration/FileTransformerTenantConfiguration.java @@ -9,6 +9,8 @@ public class FileTransformerTenantConfiguration { private List sources; public static final String _sources = "sources"; + private Boolean disableSystemSources; + public static final String _disableSystemSources = "disableSystemSources"; public List getSources() { return sources; @@ -17,4 +19,12 @@ public class FileTransformerTenantConfiguration { public void setSources(List sources) { this.sources = sources; } + + public Boolean getDisableSystemSources() { + return disableSystemSources; + } + + public void setDisableSystemSources(Boolean disableSystemSources) { + this.disableSystemSources = disableSystemSources; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/tenantconfiguration/TenantConfigurationServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/tenantconfiguration/TenantConfigurationServiceImpl.java index a7cc91476..bdbbc6323 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/tenantconfiguration/TenantConfigurationServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/tenantconfiguration/TenantConfigurationServiceImpl.java @@ -128,7 +128,7 @@ public class TenantConfigurationServiceImpl implements TenantConfigurationServic TenantConfigurationQuery tenantConfigurationQuery = this.queryFactory.query(TenantConfigurationQuery.class).excludedIds(data.getId()).isActive(IsActive.Active).types(data.getType()); if (data.getTenantId() == null) tenantConfigurationQuery.tenantIsSet(false); - else tenantConfigurationQuery.tenantIsSet(false).tenantIds(data.getTenantId()); + else tenantConfigurationQuery.tenantIsSet(true).tenantIds(data.getTenantId()); if (tenantConfigurationQuery.count() > 0)throw new MyValidationException(this.errors.getMultipleTenantConfigurationTypeNotAllowed().getCode(), this.errors.getMultipleTenantConfigurationTypeNotAllowed().getMessage()); switch (data.getType()){ @@ -156,6 +156,7 @@ public class TenantConfigurationServiceImpl implements TenantConfigurationServic private @NotNull DepositTenantConfigurationEntity buildDepositTenantConfigurationEntity(DepositTenantConfigurationPersist persist) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { DepositTenantConfigurationEntity data = new DepositTenantConfigurationEntity(); if (persist == null || this.conventionService.isListNullOrEmpty(persist.getSources())) return data; + data.setDisableSystemSources(persist.getDisableSystemSources()); data.setSources(new ArrayList<>()); for (DepositSourcePersist depositSourcePersist : persist.getSources()) { data.getSources().add(this.buildDepositSourceEntity(depositSourcePersist)); @@ -179,6 +180,7 @@ public class TenantConfigurationServiceImpl implements TenantConfigurationServic private @NotNull FileTransformerTenantConfigurationEntity buildFileTransformerTenantConfigurationEntity(FileTransformerTenantConfigurationPersist persist) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { FileTransformerTenantConfigurationEntity data = new FileTransformerTenantConfigurationEntity(); if (persist == null || this.conventionService.isListNullOrEmpty(persist.getSources())) return data; + data.setDisableSystemSources(persist.getDisableSystemSources()); data.setSources(new ArrayList<>()); for (FileTransformerSourcePersist depositSourcePersist : persist.getSources()) { data.getSources().add(this.buildFileTransformerSourceEntity(depositSourcePersist)); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/TenantConfigurationController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/TenantConfigurationController.java index 7685d7520..760d894d4 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/TenantConfigurationController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/TenantConfigurationController.java @@ -120,7 +120,7 @@ public class TenantConfigurationController { TenantConfigurationQuery query = this.queryFactory.query(TenantConfigurationQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).isActive(IsActive.Active).types(TenantConfigurationType.of(type)); if (this.tenantScope.isDefaultTenant()) query.tenantIsSet(false); - else query.tenantIsSet(false).tenantIds(this.tenantScope.getTenant()); + else query.tenantIsSet(true).tenantIds(this.tenantScope.getTenant()); TenantConfiguration model = this.builderFactory.builder(TenantConfigurationBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(fieldSet, query.firstAs(fieldSet)); diff --git a/dmp-frontend/Dockerfile.Sonar b/dmp-frontend/Dockerfile.Sonar new file mode 100644 index 000000000..ab9910696 --- /dev/null +++ b/dmp-frontend/Dockerfile.Sonar @@ -0,0 +1,31 @@ +FROM node:20 + +ARG ORACLE_URL +ARG ORACLE_TOKEN +ARG BUILD_VERSION +ENV ORACLE_URL=$ORACLE_URL +ENV ORACLE_TOKEN=$ORACLE_TOKEN +ENV BUILD_VERSION=$BUILD_VERSION + +RUN apt-get -y update && apt-get install -y openjdk-11-jdk locales && apt-get clean +RUN mkdir -p /usr/share/man/man1/ +RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \ + locale-gen +ENV LC_ALL en_US.UTF-8 +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en + +COPY oracle.local.cite.gr.crt /usr/local/share/ca-certificates/oracle.local.cite.gr.crt +RUN update-ca-certificates + +# copy the package.json to install dependencies +COPY /dmp-frontend/package.json ./ +COPY /dmp-frontend/package-lock.json ./ + +# Install the dependencies and make the folder +RUN npm install sonar-scanner --save-dev +RUN npm install --legacy-peer-deps && mkdir /src && mv ./node_modules ./src + +WORKDIR /src +COPY . . +RUN npm run sonar-scanner \ No newline at end of file diff --git a/dmp-frontend/package.json b/dmp-frontend/package.json index 0a830237b..48cc42d16 100644 --- a/dmp-frontend/package.json +++ b/dmp-frontend/package.json @@ -28,12 +28,13 @@ "cookieconsent": "^3.1.1", "dragula": "^3.7.3", "file-saver": "^2.0.5", - "moment": "^2.30.1", "keycloak-angular": "^15.2.1", "keycloak-js": "^24.0.2", + "moment": "^2.30.1", "moment-timezone": "^0.5.45", "ng-dialog-animation": "^9.0.4", "ng2-dragula": "^5.0.1", + "ngx-colors": "^3.5.3", "ngx-cookie-service": "^17.1.0", "ngx-cookieconsent": "^6.0.0", "ngx-dropzone": "^3.0.0", @@ -63,4 +64,4 @@ "tslint": "~6.1.0", "typescript": "^5.2.0" } -} \ No newline at end of file +} diff --git a/sonar-project.properties b/dmp-frontend/sonar-project.properties similarity index 100% rename from sonar-project.properties rename to dmp-frontend/sonar-project.properties diff --git a/dmp-frontend/src/app/app.component.ts b/dmp-frontend/src/app/app.component.ts index 457b9e729..c30f5a99d 100644 --- a/dmp-frontend/src/app/app.component.ts +++ b/dmp-frontend/src/app/app.component.ts @@ -6,7 +6,7 @@ import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { environment } from '../environments/environment'; -import { AuthService } from './core/services/auth/auth.service'; +import { AuthService, LoginStatus } from './core/services/auth/auth.service'; import { CultureService } from './core/services/culture/culture-service'; // import { BreadCrumbResolverService } from './ui/misc/breadcrumb/service/breadcrumb.service'; import { Title } from '@angular/platform-browser'; @@ -20,6 +20,10 @@ import { MatomoService } from './core/services/matomo/matomo-service'; import { SideNavService } from './core/services/sidenav/side-nav.sevice'; import { MatSidenav } from '@angular/material/sidenav'; import { TimezoneService } from './core/services/timezone/timezone-service'; +import { TenantConfigurationService } from './core/services/tenant-configuration/tenant-configuration.service'; +import { TenantConfigurationType } from './core/common/enum/tenant-configuration-type'; +import { CssColorsTenantConfiguration, TenantConfiguration } from './core/model/tenant-configuaration/tenant-configuration'; +import { nameof } from 'ts-simple-nameof'; declare const gapi: any; @@ -56,6 +60,7 @@ export class AppComponent implements OnInit, AfterViewInit { private configurationService: ConfigurationService, private location: Location, private matomoService: MatomoService, + private tenantConfigurationService: TenantConfigurationService, private sidenavService: SideNavService ) { this.initializeServices(); @@ -229,6 +234,36 @@ export class AppComponent implements OnInit, AfterViewInit { this.authentication.currentAccountIsAuthenticated() && this.authentication.getUserProfileCulture() ? this.cultureService.cultureSelected(this.authentication.getUserProfileCulture()) : this.cultureService.cultureSelected(this.configurationService.defaultCulture); this.authentication.currentAccountIsAuthenticated() && this.authentication.getUserProfileTimezone() ? this.timezoneService.timezoneSelected(this.authentication.getUserProfileTimezone()) : this.timezoneService.timezoneSelected(this.configurationService.defaultTimezone); this.authentication.currentAccountIsAuthenticated() && this.authentication.getUserProfileLanguage() ? this.language.changeLanguage(this.authentication.getUserProfileLanguage()) : (this.language.getDefaultLanguagesCode()); + + this.authentication.getAuthenticationStateObservable().subscribe(authenticationState => { + if (authenticationState.loginStatus === LoginStatus.LoggedIn) { + this.loadCssColors(); + } + }); + this.loadCssColors(); + } + + private loadCssColors() { + if (this.authentication.currentAccountIsAuthenticated() && this.authentication.selectedTenant()) { + this.tenantConfigurationService.getCurrentTenantType(TenantConfigurationType.CssColors, [ + nameof(x => x.type), + [nameof(x => x.cssColors), nameof(x => x.primaryColor)].join('.'), + [nameof(x => x.cssColors), nameof(x => x.primaryColor2)].join('.'), + [nameof(x => x.cssColors), nameof(x => x.primaryColor3)].join('.'), + [nameof(x => x.cssColors), nameof(x => x.secondaryColor)].join('.'), + ]) + .pipe(map(data => data as TenantConfiguration)) + .subscribe( + data => { + if (data?.cssColors) { + if (data.cssColors.primaryColor) document.documentElement.style.setProperty(`--primary-color`, data.cssColors.primaryColor); + if (data.cssColors.primaryColor2) document.documentElement.style.setProperty(`--primary-color-2`, data.cssColors.primaryColor2); + if (data.cssColors.primaryColor3) document.documentElement.style.setProperty(`--primary-color-3`, data.cssColors.primaryColor3); + if (data.cssColors.secondaryColor) document.documentElement.style.setProperty(`--secondary-color`, data.cssColors.secondaryColor); + } + }, + ); + } } toggleNavbar(event) { diff --git a/dmp-frontend/src/app/core/model/tenant-configuaration/tenant-configuration.ts b/dmp-frontend/src/app/core/model/tenant-configuaration/tenant-configuration.ts index 28b70c76a..111542d22 100644 --- a/dmp-frontend/src/app/core/model/tenant-configuaration/tenant-configuration.ts +++ b/dmp-frontend/src/app/core/model/tenant-configuaration/tenant-configuration.ts @@ -26,10 +26,12 @@ export interface DefaultUserLocaleTenantConfiguration{ } export interface DepositTenantConfiguration{ + disableSystemSources: boolean; sources: DepositSource[]; } export interface FileTransformerTenantConfiguration{ + disableSystemSources: boolean; sources: FileTransformerSource[]; } @@ -80,10 +82,12 @@ export interface DefaultUserLocaleTenantConfigurationPersist{ } export interface DepositTenantConfigurationPersist{ + disableSystemSources: boolean; sources: DepositSourcePersist[]; } export interface FileTransformerTenantConfigurationPersist{ + disableSystemSources: boolean; sources: FileTransformerSourcePersist[]; } diff --git a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/css-colors/css-colors-editor.component.html b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/css-colors/css-colors-editor.component.html index 6d37074a5..243cc1be5 100644 --- a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/css-colors/css-colors-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/css-colors/css-colors-editor.component.html @@ -1,30 +1,61 @@
- - {{'TENANT-CONFIGURATION-EDITOR.FIELDS.PRIMARY-COLOR' | translate}} - - {{formGroup.get('cssColors')?.get('primaryColor')?.getError('backendError').message}} - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - - - {{'TENANT-CONFIGURATION-EDITOR.FIELDS.PRIMARY-COLOR-2' | translate}} - - {{formGroup.get('cssColors')?.get('primaryColor2')?.getError('backendError').message}} - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - - - {{'TENANT-CONFIGURATION-EDITOR.FIELDS.PRIMARY-COLOR-3' | translate}} - - {{formGroup.get('cssColors')?.get('primaryColor3')?.getError('backendError').message}} - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - - - {{'TENANT-CONFIGURATION-EDITOR.FIELDS.SECONDARY-COLOR' | translate}} - - {{formGroup.get('cssColors')?.get('secondaryColor')?.getError('backendError').message}} - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - +
+ + + {{'TENANT-CONFIGURATION-EDITOR.FIELDS.PRIMARY-COLOR' | translate}} + + + {{formGroup.get('cssColors')?.get('primaryColor')?.getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.INVALID-COLOR' | translate}} + + + {{'TENANT-CONFIGURATION-EDITOR.FIELDS.PRIMARY-COLOR-2' | translate}} + + + {{formGroup.get('cssColors')?.get('primaryColor2')?.getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.INVALID-COLOR' | translate}} + + + {{'TENANT-CONFIGURATION-EDITOR.FIELDS.PRIMARY-COLOR-3' | translate}} + + + {{formGroup.get('cssColors')?.get('primaryColor3')?.getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.INVALID-COLOR' | translate}} + + + {{'TENANT-CONFIGURATION-EDITOR.FIELDS.SECONDARY-COLOR' | translate}} + + + {{formGroup.get('cssColors')?.get('secondaryColor')?.getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.INVALID-COLOR' | translate}} + +
diff --git a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/css-colors/css-colors-editor.component.ts b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/css-colors/css-colors-editor.component.ts index 77631d615..687d8ed71 100644 --- a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/css-colors/css-colors-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/css-colors/css-colors-editor.component.ts @@ -78,6 +78,50 @@ export class CssColorsEditorComponent extends BasePendingChangesComponent implem this.formGroup.disable(); } }); + + } + + private bindColorInputs() { + this.formGroup.get('cssColors')?.get('primaryColorInput').valueChanges.subscribe((color) => { + this.formGroup.get('cssColors')?.get('primaryColor').setValue(color, { + emitEvent: false, + }); + }); + this.formGroup.get('cssColors')?.get('primaryColor').valueChanges.subscribe((color) => + this.formGroup.get('cssColors')?.get('primaryColorInput').setValue(color, { + emitEvent: false, + }) + ); + this.formGroup.get('cssColors')?.get('primaryColor2Input').valueChanges.subscribe((color) => { + this.formGroup.get('cssColors')?.get('primaryColor2').setValue(color, { + emitEvent: false, + }); + }); + this.formGroup.get('cssColors')?.get('primaryColor2').valueChanges.subscribe((color) => + this.formGroup.get('cssColors')?.get('primaryColor2Input').setValue(color, { + emitEvent: false, + }) + ); + this.formGroup.get('cssColors')?.get('primaryColor3Input').valueChanges.subscribe((color) => { + this.formGroup.get('cssColors')?.get('primaryColor3').setValue(color, { + emitEvent: false, + }); + }); + this.formGroup.get('cssColors')?.get('primaryColor3').valueChanges.subscribe((color) => + this.formGroup.get('cssColors')?.get('primaryColor3Input').setValue(color, { + emitEvent: false, + }) + ); + this.formGroup.get('cssColors')?.get('secondaryColorInput').valueChanges.subscribe((color) => { + this.formGroup.get('cssColors')?.get('secondaryColor').setValue(color, { + emitEvent: false, + }); + }); + this.formGroup.get('cssColors')?.get('secondaryColor').valueChanges.subscribe((color) => + this.formGroup.get('cssColors')?.get('secondaryColorInput').setValue(color, { + emitEvent: false, + }) + ); } getItem(successFunction: (item: TenantConfiguration) => void) { @@ -119,8 +163,9 @@ export class CssColorsEditorComponent extends BasePendingChangesComponent implem prepareForm(data: TenantConfiguration) { try { this.editorModel = data ? new TenantConfigurationEditorModel().fromModel(data) : new TenantConfigurationEditorModel(); - this.buildForm(); + this.bindColorInputs(); + } catch (error) { this.logger.error('Could not parse TenantConfiguration item: ' + data + error); this.uiNotificationService.snackBarNotification(this.language.instant('COMMONS.ERRORS.DEFAULT'), SnackBarNotificationLevel.Error); @@ -172,7 +217,7 @@ export class CssColorsEditorComponent extends BasePendingChangesComponent implem const dialogRef = this.dialog.open(ConfirmationDialogComponent, { maxWidth: '300px', data: { - message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.RESET-TO-DEFAULT'), + message: this.language.instant('TENANT-CONFIGURATION-EDITOR.RESET-TO-DEFAULT-DIALOG.RESET-TO-DEFAULT'), confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL') } diff --git a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/css-colors/css-colors-editor.model.ts b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/css-colors/css-colors-editor.model.ts index 039cba2e4..e346182f8 100644 --- a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/css-colors/css-colors-editor.model.ts +++ b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/css-colors/css-colors-editor.model.ts @@ -5,6 +5,7 @@ import { BaseEditorModel } from "@common/base/base-form-editor-model"; import { BackendErrorValidator } 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 { validColorValidator } from "ngx-colors"; export class TenantConfigurationEditorModel extends BaseEditorModel implements TenantConfigurationPersist { type: TenantConfigurationType; @@ -91,7 +92,12 @@ export class CssColorsTenantConfigurationEditorModel implements CssColorsTenantC primaryColor2: [{ value: this.primaryColor2, disabled: disabled }, context.getValidation('primaryColor2').validators], primaryColor3: [{ value: this.primaryColor3, disabled: disabled }, context.getValidation('primaryColor3').validators], secondaryColor: [{ value: this.secondaryColor, disabled: disabled }, context.getValidation('secondaryColor').validators], - }); + primaryColorInput: [{ value: this.primaryColor, disabled: disabled}, context.getValidation('primaryColorInput').validators ], + primaryColor2Input: [{ value: this.primaryColor2, disabled: disabled}, context.getValidation('primaryColor2Input').validators ], + primaryColor3Input: [{ value: this.primaryColor3, disabled: disabled}, context.getValidation('primaryColor3Input').validators ], + secondaryColorInput: [{ value: this.secondaryColor, disabled: disabled}, context.getValidation('secondaryColorInput').validators ], + }, + { updateOn: "change" }); return form; } @@ -105,10 +111,14 @@ export class CssColorsTenantConfigurationEditorModel implements CssColorsTenantC const baseContext: ValidationContext = new ValidationContext(); const baseValidationArray: Validation[] = new Array(); - baseValidationArray.push({ key: 'primaryColor', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}primaryColor`)] }); - baseValidationArray.push({ key: 'primaryColor2', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}primaryColor2`)] }); - baseValidationArray.push({ key: 'primaryColor3', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}primaryColor3`)] }); - baseValidationArray.push({ key: 'secondaryColor', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}secondaryColor`)] }); + baseValidationArray.push({ key: 'primaryColor', validators: [validColorValidator(), Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}primaryColor`)] }); + baseValidationArray.push({ key: 'primaryColor2', validators: [validColorValidator(), Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}primaryColor2`)] }); + baseValidationArray.push({ key: 'primaryColor3', validators: [validColorValidator(), Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}primaryColor3`)] }); + baseValidationArray.push({ key: 'secondaryColor', validators: [validColorValidator(), Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}secondaryColor`)] }); + baseValidationArray.push({ key: 'primaryColorInput', validators: [validColorValidator()] }); + baseValidationArray.push({ key: 'primaryColor2Input', validators: [validColorValidator()] }); + baseValidationArray.push({ key: 'primaryColor3Input', validators: [validColorValidator()] }); + baseValidationArray.push({ key: 'secondaryColorInput', validators: [validColorValidator()] }); baseContext.validation = baseValidationArray; return baseContext; diff --git a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/default-user-locale/default-user-locale-editor.component.ts b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/default-user-locale/default-user-locale-editor.component.ts index e6b859e2a..2ab28a932 100644 --- a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/default-user-locale/default-user-locale-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/default-user-locale/default-user-locale-editor.component.ts @@ -185,7 +185,7 @@ export class DefaultUserLocaleEditorComponent extends BasePendingChangesComponen const dialogRef = this.dialog.open(ConfirmationDialogComponent, { maxWidth: '300px', data: { - message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.RESET-TO-DEFAULT'), + message: this.language.instant('TENANT-CONFIGURATION-EDITOR.RESET-TO-DEFAULT-DIALOG.RESET-TO-DEFAULT'), confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL') } diff --git a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.component.html b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.component.html index 420587e86..584504544 100644 --- a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.component.html @@ -1,10 +1,16 @@
-

- {{label}} - -

+
{{label}}
+
+ + {{'TENANT-CONFIGURATION-EDITOR.FIELDS.DISABLE-SYSTEM-SOURCES' | translate}} + {{ formGroup?.get('depositPlugins')?.get('disableSystemSources')?.getError('backendError')?.message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+ +
diff --git a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.component.ts b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.component.ts index 82db11db0..7a04794b0 100644 --- a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.component.ts @@ -172,7 +172,7 @@ export class DepositEditorComponent extends BasePendingChangesComponent implemen const dialogRef = this.dialog.open(ConfirmationDialogComponent, { maxWidth: '300px', data: { - message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.RESET-TO-DEFAULT'), + message: this.language.instant('TENANT-CONFIGURATION-EDITOR.RESET-TO-DEFAULT-DIALOG.RESET-TO-DEFAULT'), confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL') } diff --git a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.model.ts b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.model.ts index 7290e02fb..97dfc1f51 100644 --- a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.model.ts +++ b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.model.ts @@ -66,6 +66,7 @@ export class TenantConfigurationEditorModel extends BaseEditorModel implements T } export class DepositTenantConfigurationEditorModel implements DepositTenantConfigurationPersist { + disableSystemSources: boolean = false; sources: DepositSourceEditorModel[] = []; protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); @@ -76,6 +77,7 @@ export class DepositTenantConfigurationEditorModel implements DepositTenantConfi public fromModel(item: DepositTenantConfiguration): DepositTenantConfigurationEditorModel { if (item) { + this.disableSystemSources = item.disableSystemSources; if (item.sources) { item.sources.map(x => this.sources.push(new DepositSourceEditorModel(this.validationErrorModel).fromModel(x))); } } return this; @@ -95,6 +97,7 @@ export class DepositTenantConfigurationEditorModel implements DepositTenantConfi } const form: UntypedFormGroup = this.formBuilder.group({ + disableSystemSources: [{ value: this.disableSystemSources, disabled: disabled }, context.getValidation('disableSystemSources').validators], sources: this.formBuilder.array( (this.sources ?? []).map( (item, index) => item.buildForm({ @@ -116,6 +119,7 @@ export class DepositTenantConfigurationEditorModel implements DepositTenantConfi const baseContext: ValidationContext = new ValidationContext(); const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'disableSystemSources', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}disableSystemSources`)] }); baseValidationArray.push({ key: 'sources', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}sources`)] }); baseContext.validation = baseValidationArray; return baseContext; diff --git a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.resolver.ts b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.resolver.ts index 9a832a141..9a89a0bfb 100644 --- a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.resolver.ts +++ b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.resolver.ts @@ -29,6 +29,7 @@ export class DepositEditorResolver extends BaseEditorResolver { [nameof(x => x.depositPlugins), nameof(x => x.sources), nameof(x => x.url)].join('.'), [nameof(x => x.depositPlugins), nameof(x => x.sources), nameof(x => x.pdfTransformerId)].join('.'), [nameof(x => x.depositPlugins), nameof(x => x.sources), nameof(x => x.rdaTransformerId)].join('.'), + [nameof(x => x.depositPlugins), nameof(x => x.disableSystemSources)].join('.'), nameof(x => x.createdAt), diff --git a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.component.html b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.component.html index f8549063a..c487e5650 100644 --- a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.component.html @@ -1,10 +1,15 @@
-

- {{label}} - -

+
{{label}}
+
+ + {{'TENANT-CONFIGURATION-EDITOR.FIELDS.DISABLE-SYSTEM-SOURCES' | translate}} + {{ formGroup?.get('fileTransformerPlugins')?.get('disableSystemSources')?.getError('backendError')?.message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
diff --git a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.component.ts b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.component.ts index 6cba6ff4b..7d8009e35 100644 --- a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.component.ts @@ -172,7 +172,7 @@ export class FileTransformerEditorComponent extends BasePendingChangesComponent const dialogRef = this.dialog.open(ConfirmationDialogComponent, { maxWidth: '300px', data: { - message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.RESET-TO-DEFAULT'), + message: this.language.instant('TENANT-CONFIGURATION-EDITOR.RESET-TO-DEFAULT-DIALOG.RESET-TO-DEFAULT'), confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL') } diff --git a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.model.ts b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.model.ts index 28c33905d..eab1c6de0 100644 --- a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.model.ts +++ b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.model.ts @@ -66,6 +66,7 @@ export class TenantConfigurationEditorModel extends BaseEditorModel implements T } export class FileTransformerTenantConfigurationEditorModel implements FileTransformerTenantConfigurationPersist { + disableSystemSources: boolean = false; sources: FileTransformerSourceEditorModel[] = []; protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); @@ -76,6 +77,7 @@ export class FileTransformerTenantConfigurationEditorModel implements FileTransf public fromModel(item: FileTransformerTenantConfiguration): FileTransformerTenantConfigurationEditorModel { if (item) { + this.disableSystemSources = item.disableSystemSources; if (item.sources) { item.sources.map(x => this.sources.push(new FileTransformerSourceEditorModel(this.validationErrorModel).fromModel(x))); } } return this; @@ -95,6 +97,7 @@ export class FileTransformerTenantConfigurationEditorModel implements FileTransf } const form: UntypedFormGroup = this.formBuilder.group({ + disableSystemSources: [{ value: this.disableSystemSources, disabled: disabled }, context.getValidation('disableSystemSources').validators], sources: this.formBuilder.array( (this.sources ?? []).map( (item, index) => item.buildForm({ @@ -116,6 +119,7 @@ export class FileTransformerTenantConfigurationEditorModel implements FileTransf const baseContext: ValidationContext = new ValidationContext(); const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'disableSystemSources', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}disableSystemSources`)] }); baseValidationArray.push({ key: 'sources', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}sources`)] }); baseContext.validation = baseValidationArray; return baseContext; diff --git a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.resolver.ts b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.resolver.ts index 70e868032..e6a3ea1df 100644 --- a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.resolver.ts +++ b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.resolver.ts @@ -27,6 +27,7 @@ export class FileTransformerEditorResolver extends BaseEditorResolver { [nameof(x => x.fileTransformerPlugins), nameof(x => x.sources), nameof(x => x.transformerId)].join('.'), [nameof(x => x.fileTransformerPlugins), nameof(x => x.sources), nameof(x => x.scope)].join('.'), [nameof(x => x.fileTransformerPlugins), nameof(x => x.sources), nameof(x => x.url)].join('.'), + [nameof(x => x.fileTransformerPlugins), nameof(x => x.disableSystemSources)].join('.'), nameof(x => x.createdAt), diff --git a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/logo/logo-editor.component.ts b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/logo/logo-editor.component.ts index 7f342c5dc..6498297c1 100644 --- a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/logo/logo-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/logo/logo-editor.component.ts @@ -182,7 +182,7 @@ export class LogoEditorComponent extends BasePendingChangesComponent implements const dialogRef = this.dialog.open(ConfirmationDialogComponent, { maxWidth: '300px', data: { - message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.RESET-TO-DEFAULT'), + message: this.language.instant('TENANT-CONFIGURATION-EDITOR.RESET-TO-DEFAULT-DIALOG.RESET-TO-DEFAULT'), confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL') } diff --git a/dmp-frontend/src/app/ui/admin/tenant-configuration/tenant-configuration.module.ts b/dmp-frontend/src/app/ui/admin/tenant-configuration/tenant-configuration.module.ts index df6d8b9b4..94bab108b 100644 --- a/dmp-frontend/src/app/ui/admin/tenant-configuration/tenant-configuration.module.ts +++ b/dmp-frontend/src/app/ui/admin/tenant-configuration/tenant-configuration.module.ts @@ -18,6 +18,7 @@ import { FormattingModule } from '@app/core/formatting.module'; import { DepositEditorComponent } from './editor/deposit/deposit-editor.component'; import { FileTransformerEditorComponent } from './editor/file-transformer/file-transformer-editor.component'; import { LogoEditorComponent } from './editor/logo/logo-editor.component'; +import { NgxColorsModule } from 'ngx-colors'; @NgModule({ imports: [ @@ -33,7 +34,8 @@ import { LogoEditorComponent } from './editor/logo/logo-editor.component'; TextFilterModule, UserSettingsModule, CommonFormattingModule, - RichTextEditorModule + RichTextEditorModule, + NgxColorsModule ], declarations: [ TenantConfigurationEditorComponent, 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 507f6a053..698f3745f 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 @@ -190,7 +190,7 @@ export class DescriptionPropertyDefinitionEditorModel implements DescriptionProp let result: Map = new Map(); definitionSection?.fieldSets?.forEach(definitionFieldSet => { - const fieldSetResult = this.calculateFieldSetProperties(definitionFieldSet, item, descriptionReferences); + const fieldSetResult = this.calculateFieldSetProperties(definitionFieldSet, 0, item, descriptionReferences); if (fieldSetResult != null) { result.set(definitionFieldSet.id, fieldSetResult); } @@ -208,7 +208,7 @@ export class DescriptionPropertyDefinitionEditorModel implements DescriptionProp return result; } - public calculateFieldSetProperties(definitionFieldSet: DescriptionTemplateFieldSet, item: DescriptionPropertyDefinition, descriptionReferences: DescriptionReference[]): DescriptionPropertyDefinitionFieldSetEditorModel { + public calculateFieldSetProperties(definitionFieldSet: DescriptionTemplateFieldSet, ordinal: number, item: DescriptionPropertyDefinition, descriptionReferences: DescriptionReference[]): DescriptionPropertyDefinitionFieldSetEditorModel { if (definitionFieldSet == null) return null; // current saved values @@ -229,7 +229,7 @@ export class DescriptionPropertyDefinitionEditorModel implements DescriptionProp }) fieldSetValue.items = [{ fields: fields, - ordinal: 0 + ordinal: ordinal } as DescriptionPropertyDefinitionFieldSetItem] } @@ -744,7 +744,7 @@ export class DescriptionFieldIndicator { break; case DescriptionTemplateFieldType.TAGS: this.type = "textListValue"; - break; + break; } } } diff --git a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.ts b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.ts index 063435ee4..92de8eedf 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.ts @@ -14,6 +14,7 @@ import { Guid } from '@common/types/guid'; import { AnnotationDialogComponent } from '@app/ui/annotations/annotation-dialog-component/annotation-dialog.component'; import { AnnotationEntityType } from '@app/core/common/enum/annotation-entity-type'; import { DescriptionFormAnnotationService } from '../../description-form-annotation.service'; +import { DescriptionPropertyDefinitionFieldSet } from '@app/core/model/description/description'; @Component({ selector: 'app-description-form-field-set', @@ -88,17 +89,21 @@ export class DescriptionFormFieldSetComponent extends BaseComponent { if (formArray.disabled) { return; } - - const item: DescriptionPropertyDefinitionFieldSetEditorModel = new DescriptionPropertyDefinitionEditorModel(this.validationErrorModel).calculateFieldSetProperties(this.fieldSet, null, null); + const properties: DescriptionPropertyDefinitionFieldSet = this.propertiesFormGroup.value; + let ordinal = 0; + if (properties?.items && properties.items.map(x => x.ordinal).filter(val => !isNaN(val)).length > 0) { + ordinal = Math.max(...properties.items.map(x => x.ordinal).filter(val => !isNaN(val))) + 1; + } + const item: DescriptionPropertyDefinitionFieldSetEditorModel = new DescriptionPropertyDefinitionEditorModel(this.validationErrorModel).calculateFieldSetProperties(this.fieldSet, ordinal, null, null); formArray.push((item.buildForm({ rootPath: `properties.fieldSets[${this.fieldSet.id}].` }).get('items') as UntypedFormArray).at(0)); - + this.visibilityRulesService.reloadVisibility(); } deleteMultiplicityField(fieldSetIndex: number): void { const formArray = this.propertiesFormGroup.get('items') as UntypedFormArray; formArray.removeAt(fieldSetIndex); formArray.controls.forEach((fieldSet, index) => { - fieldSet.get('ordinal').setValue(index + 1); + fieldSet.get('ordinal').setValue(index); }); //Reapply validators @@ -110,6 +115,8 @@ export class DescriptionFormFieldSetComponent extends BaseComponent { } ); formArray.markAsDirty(); + this.visibilityRulesService.reloadVisibility(); + } editTableMultiplicityFieldInDialog(fieldSetIndex: number) { 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 c9195dbf4..2df2cfbe0 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 @@ -127,8 +127,8 @@
- {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.ACTIONS.YES" | translate }} - {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.ACTIONS.NO" | translate }} + {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.ACTIONS.YES" | translate }} + {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.ACTIONS.NO" | translate }} {{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} diff --git a/dmp-frontend/src/app/ui/navbar/navbar.component.html b/dmp-frontend/src/app/ui/navbar/navbar.component.html index ff7c062be..36c7f03d2 100644 --- a/dmp-frontend/src/app/ui/navbar/navbar.component.html +++ b/dmp-frontend/src/app/ui/navbar/navbar.component.html @@ -8,7 +8,9 @@
- + + + @@ -39,7 +41,7 @@ - +
@@ -95,7 +97,7 @@ - +
  • diff --git a/dmp-frontend/src/app/ui/navbar/navbar.component.scss b/dmp-frontend/src/app/ui/navbar/navbar.component.scss index a976156c5..99ce3843e 100644 --- a/dmp-frontend/src/app/ui/navbar/navbar.component.scss +++ b/dmp-frontend/src/app/ui/navbar/navbar.component.scss @@ -34,9 +34,17 @@ $mat-card-header-size: 40px !default; margin-left: 5px; height: 100%; } + +.extra-logo { + margin-left: 5px; + height: 100%; +} .logo-image { height: 100%; } +.extra-logo-image { + height: 100%; +} .faq-title { text-align: left; diff --git a/dmp-frontend/src/app/ui/navbar/navbar.component.ts b/dmp-frontend/src/app/ui/navbar/navbar.component.ts index 1623f4a66..c93a092b5 100644 --- a/dmp-frontend/src/app/ui/navbar/navbar.component.ts +++ b/dmp-frontend/src/app/ui/navbar/navbar.component.ts @@ -5,13 +5,13 @@ import { MatMenuTrigger } from '@angular/material/menu'; import { Router } from '@angular/router'; import { AppRole } from '@app/core/common/enum/app-role'; import { User } from '@app/core/model/user/user'; -import { AuthService } from '@app/core/services/auth/auth.service'; +import { AuthService, LoginStatus } from '@app/core/services/auth/auth.service'; import { LanguageService } from '@app/core/services/language/language.service'; import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { ProgressIndicationService } from '@app/core/services/progress-indication/progress-indication-service'; import { SideNavService } from '@app/core/services/sidenav/side-nav.sevice'; import { BaseComponent } from '@common/base/base.component'; -import { takeUntil } from 'rxjs/operators'; +import { map, takeUntil } from 'rxjs/operators'; import { StartNewDmpDialogComponent } from '../dmp/new/start-new-dmp-dialogue/start-new-dmp-dialog.component'; import { FaqDialogComponent } from '../faq/dialog/faq-dialog.component'; import { UserDialogComponent } from './user-dialog/user-dialog.component'; @@ -19,6 +19,13 @@ import { MineInAppNotificationListingDialogComponent } from '@notification-servi import { InAppNotificationService } from '@notification-service/services/http/inapp-notification.service'; import { timer } from 'rxjs'; import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; +import { TenantConfigurationService } from '@app/core/services/tenant-configuration/tenant-configuration.service'; +import { LogoTenantConfiguration, TenantConfiguration } from '@app/core/model/tenant-configuaration/tenant-configuration'; +import { TenantConfigurationType } from '@app/core/common/enum/tenant-configuration-type'; +import { nameof } from 'ts-simple-nameof'; +import { StorageFile } from '@app/core/model/storage-file/storage-file'; +import { StorageFileService } from '@app/core/services/storage-file/storage-file.service'; +import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; @Component({ selector: 'app-navbar', @@ -40,6 +47,7 @@ export class NavbarComponent extends BaseComponent implements OnInit { inAppNotificationCount = 0; @Output() sidebarToggled: EventEmitter = new EventEmitter(); @ViewChild(MatMenuTrigger) trigger: MatMenuTrigger; + extraImageURL: SafeUrl; constructor(location: Location, private element: ElementRef, @@ -50,8 +58,11 @@ export class NavbarComponent extends BaseComponent implements OnInit { private languageService: LanguageService, private matomoService: MatomoService, private sidenavService: SideNavService, + private tenantConfigurationService: TenantConfigurationService, private inappNotificationService: InAppNotificationService, - private configurationService: ConfigurationService + private configurationService: ConfigurationService, + private storageFileService: StorageFileService, + private sanitizer: DomSanitizer ) { super(); this.location = location; @@ -87,6 +98,33 @@ export class NavbarComponent extends BaseComponent implements OnInit { .subscribe(x => { this.countUnreadInappNotifications(); }); + this.authentication.getAuthenticationStateObservable().subscribe(authenticationState => { + if (authenticationState.loginStatus === LoginStatus.LoggedIn) { + this.loadLogo(); + } + }); + this.loadLogo(); + } + + private loadLogo() { + if (this.authentication.currentAccountIsAuthenticated() && this.authentication.selectedTenant()) { + this.tenantConfigurationService.getCurrentTenantType(TenantConfigurationType.Logo, [ + nameof(x => x.type), + [nameof(x => x.logo), nameof(x => x.storageFile), nameof(x => x.id)].join('.'), + ]) + .pipe(map(data => data as TenantConfiguration), takeUntil(this._destroyed)) + .subscribe( + data => { + if (data?.logo?.storageFile?.id) { + this.storageFileService.download(data?.logo?.storageFile?.id).pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body]); + this.extraImageURL = this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(response.body)) + }); + } + }, + ); + } } private countUnreadInappNotifications() { diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index 69b8f2678..ce0375ddc 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -4,6 +4,7 @@ "GENERAL": { "VALIDATION": { "REQUIRED": "Required", + "INVALID-COLOR": "Invalid color", "URL": { "LABEL": "URL", "MESSAGE": "Please provide a valid URL" @@ -186,6 +187,7 @@ "PREFILLING-SOURCES": "Prefilling Sources", "NEW-PREFILLING-SOURCE": "New", "EDIT-PREFILLING-SOURCE": "Edit", + "TENANT-CONFIGURATION": "Tenant Configuration", "ENTITY-LOCKS": "Entity Locks" }, "COOKIE": { @@ -250,6 +252,7 @@ "NOTIFICATION-TEMPLATES": "Notification Templates", "NOTIFICATIONS": "Notifications", "PREFILLING-SOURCES": "Prefilling Sources", + "TENANT-CONFIGURATION": "Tenant Configuration", "ENTITY-LOCKS": "Entity Locks" }, "DESCRIPTION-TEMPLATE-PREVIEW": { @@ -296,6 +299,60 @@ "MESSAGE": "Are you sure you want to perform this action?" } }, + "TENANT-CONFIGURATION-EDITOR": { + "TITLE": "Tenant Configuration", + "DEFAULT-USER-LOCALE":{ + "TITLE": "Default User Locale", + "HINT": "Default locale assigned to new users" + }, + "CSS-COLORS":{ + "TITLE": "App Colors", + "HINT": "App color theme" + }, + "LOGO":{ + "TITLE": "Extra Logo", + "HINT": "Add extra logo" + }, + "DEPOSIT-PLUGINS":{ + "TITLE": "Deposit Plugins", + "HINT": "Change deposit plugins" + }, + "FILE-TRANSFORMER-PLUGINS":{ + "TITLE": "File Transformer Plugins", + "HINT": "Change file transformer plugins" + }, + "FIELDS": { + "TIMEZONE": "Timezone", + "CULTURE": "Culture", + "LANGUAGE": "Language", + "PRIMARY-COLOR": "Primary Color", + "PRIMARY-COLOR-2": "Primary Color 2", + "PRIMARY-COLOR-3": "Primary Color 2", + "SECONDARY-COLOR": "Secondary Color", + "DISABLE-SYSTEM-SOURCES": "Disable System Sources", + "DEPOSIT-PLUGINS": "Plugin", + "FILE-TRANSFORMER-PLUGINS": "Plugin", + "REPOSITORY-ID": "Repository Id", + "TRANSFORMER-ID": "Transformer Id", + "URL": "Url", + "ISSUER-URL": "Issuer Url", + "CLIENT-ID": "Client Id", + "CLIENT-SECRET": "Client Secret", + "SCOPE": "Scope", + "PDF-TRANSFORMER-ID": "Pdf Transformer Id", + "RDA-TRANSFORMER-ID": "Rda Transformer Id" + }, + "RESET-TO-DEFAULT-DIALOG":{ + "RESET-TO-DEFAULT": "Reset To Default" + }, + "ACTIONS": { + "SAVE": "Save", + "UPLOAD": "Upload", + "DOWNLOAD": "Download", + "ADD-SOURCE": "Add Source", + "RESET-TO-DEFAULT": "Reset To Default" + } + }, "DESCRIPTION-TEMPLATE-EDITOR": { "TITLE": { "NEW": "New API Client", diff --git a/notification-service/Dockerfile.Sonar b/notification-service/Dockerfile.Sonar new file mode 100644 index 000000000..086fcc99e --- /dev/null +++ b/notification-service/Dockerfile.Sonar @@ -0,0 +1,30 @@ +####################################### Build stage ####################################### +FROM maven:3.9-eclipse-temurin-21-alpine + +ARG MAVEN_ACCOUNT_USR +ARG MAVEN_ACCOUNT_PSW +ARG REVISION +ARG PROFILE +ARG ORACLE_URL +ARG ORACLE_TOKEN +ENV server_username=$MAVEN_ACCOUNT_USR +ENV server_password=$MAVEN_ACCOUNT_PSW +ARG CITE_MAVEN_REPO_URL + +COPY pom.xml /build/ +COPY notification /build/notification/ +COPY notification-web /build/notification-web/ +COPY settings.xml /root/.m2/settings.xml +RUN rm -f /build/notification-web/src/main/resources/config/app.env +RUN rm -f /build/notification-web/src/main/resources/config/*-devel.yml +RUN rm -f /build/notification-web/src/main/resources/logging/*.xml +RUN rm -f /build/notification-web/src/main/resources/certificates/*.crt + +COPY oracle.local.cite.gr.crt $JAVA_HOME/conf/security +RUN cd "$JAVA_HOME"/conf/security && keytool -cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias oraclecert -file oracle.local.cite.gr.crt + +WORKDIR /build/ +RUN mvn -Drevision=${REVISION} -DciteMavenRepoUrl=${CITE_MAVEN_REPO_URL} -P${PROFILE} clean +RUN mvn -Drevision=${REVISION} -DciteMavenRepoUrl=${CITE_MAVEN_REPO_URL} -P${PROFILE} install +RUN mvn -Drevision=${REVISION} -DciteMavenRepoUrl=${CITE_MAVEN_REPO_URL} -P${PROFILE} package +RUN mvn sonar:sonar -Dsonar.projectKey=OpenDMP:notification-api -Dsonar.login=${ORACLE_TOKEN} -Dsonar.host.url=${ORACLE_URL} -Dsonar.projectName='OpenDMP Notification API' \ No newline at end of file