languages fixes
This commit is contained in:
parent
1f9aaf616e
commit
2d7c3d0f24
|
@ -33,6 +33,8 @@ public class LanguageQuery extends QueryBase<LanguageEntity> {
|
|||
private Collection<String> codes;
|
||||
|
||||
private Collection<UUID> excludedIds;
|
||||
private Collection<UUID> tenantIds;
|
||||
private Boolean tenantIsSet;
|
||||
|
||||
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
|
||||
|
||||
|
@ -101,6 +103,31 @@ public class LanguageQuery extends QueryBase<LanguageEntity> {
|
|||
return this;
|
||||
}
|
||||
|
||||
public LanguageQuery clearTenantIds() {
|
||||
this.tenantIds = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LanguageQuery tenantIds(UUID value) {
|
||||
this.tenantIds = List.of(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LanguageQuery tenantIds(UUID... value) {
|
||||
this.tenantIds = Arrays.asList(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LanguageQuery tenantIds(Collection<UUID> values) {
|
||||
this.tenantIds = values;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LanguageQuery tenantIsSet(Boolean value) {
|
||||
this.tenantIsSet = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LanguageQuery authorize(EnumSet<AuthorizationFlags> values) {
|
||||
this.authorize = values;
|
||||
return this;
|
||||
|
@ -136,7 +163,7 @@ public class LanguageQuery extends QueryBase<LanguageEntity> {
|
|||
|
||||
@Override
|
||||
protected Boolean isFalseQuery() {
|
||||
return this.isEmpty(this.ids) || this.isEmpty(this.isActives) || this.isEmpty(this.excludedIds) || this.isEmpty(this.codes);
|
||||
return this.isEmpty(this.ids) || this.isEmpty(this.isActives) || this.isEmpty(this.excludedIds) || this.isEmpty(this.codes) || this.isEmpty(this.tenantIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -169,6 +196,16 @@ public class LanguageQuery extends QueryBase<LanguageEntity> {
|
|||
notInClause.value(item);
|
||||
predicates.add(notInClause.not());
|
||||
}
|
||||
if (this.tenantIds != null) {
|
||||
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(LanguageEntity._tenantId));
|
||||
for (UUID item : this.tenantIds)
|
||||
inClause.value(item);
|
||||
predicates.add(inClause);
|
||||
}
|
||||
if (this.tenantIsSet != null) {
|
||||
if (this.tenantIsSet) predicates.add(queryContext.CriteriaBuilder.isNotNull(queryContext.Root.get(LanguageEntity._tenantId)));
|
||||
else predicates.add(queryContext.CriteriaBuilder.isNull(queryContext.Root.get(LanguageEntity._tenantId)));
|
||||
}
|
||||
if (!predicates.isEmpty()) {
|
||||
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
|
||||
return queryContext.CriteriaBuilder.and(predicatesArray);
|
||||
|
|
|
@ -3,7 +3,6 @@ package org.opencdmp.service.language;
|
|||
import gr.cite.commons.web.authz.service.AuthorizationService;
|
||||
import gr.cite.tools.data.builder.BuilderFactory;
|
||||
import gr.cite.tools.data.deleter.DeleterFactory;
|
||||
import gr.cite.tools.data.query.QueryFactory;
|
||||
import gr.cite.tools.exception.MyApplicationException;
|
||||
import gr.cite.tools.exception.MyForbiddenException;
|
||||
import gr.cite.tools.exception.MyNotFoundException;
|
||||
|
@ -23,8 +22,6 @@ import org.opencdmp.model.Language;
|
|||
import org.opencdmp.model.builder.LanguageBuilder;
|
||||
import org.opencdmp.model.deleter.LanguageDeleter;
|
||||
import org.opencdmp.model.persist.LanguagePersist;
|
||||
import org.opencdmp.query.LanguageQuery;
|
||||
import org.opencdmp.query.TenantQuery;
|
||||
import org.opencdmp.service.planblueprint.PlanBlueprintServiceImpl;
|
||||
import org.opencdmp.service.storage.StorageFileService;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -47,7 +44,6 @@ public class LanguageServiceImpl implements LanguageService {
|
|||
private final AuthorizationService authorizationService;
|
||||
private final DeleterFactory deleterFactory;
|
||||
private final BuilderFactory builderFactory;
|
||||
private final QueryFactory queryFactory;
|
||||
private final ConventionService conventionService;
|
||||
private final MessageSource messageSource;
|
||||
private final ErrorThesaurusProperties errors;
|
||||
|
@ -55,13 +51,12 @@ public class LanguageServiceImpl implements LanguageService {
|
|||
|
||||
|
||||
public LanguageServiceImpl(
|
||||
TenantEntityManager entityManager, AuthorizationService authorizationService, DeleterFactory deleterFactory, BuilderFactory builderFactory, QueryFactory queryFactory,
|
||||
TenantEntityManager entityManager, AuthorizationService authorizationService, DeleterFactory deleterFactory, BuilderFactory builderFactory,
|
||||
ConventionService conventionService, MessageSource messageSource, ErrorThesaurusProperties errors, StorageFileService storageFileService){
|
||||
this.entityManager = entityManager;
|
||||
this.authorizationService = authorizationService;
|
||||
this.deleterFactory = deleterFactory;
|
||||
this.builderFactory = builderFactory;
|
||||
this.queryFactory = queryFactory;
|
||||
this.conventionService = conventionService;
|
||||
this.messageSource = messageSource;
|
||||
this.errors = errors;
|
||||
|
@ -98,16 +93,6 @@ public class LanguageServiceImpl implements LanguageService {
|
|||
|
||||
this.entityManager.flush();
|
||||
|
||||
if (!isUpdate) {
|
||||
Long languagesWithThisCode = this.queryFactory.query(LanguageQuery.class).disableTracking()
|
||||
.isActive(IsActive.Active)
|
||||
.excludedIds(data.getId())
|
||||
.codes(data.getCode())
|
||||
.count();
|
||||
|
||||
if (languagesWithThisCode > 0) throw new MyValidationException(this.errors.getTenantCodeExists().getCode(), this.errors.getTenantCodeExists().getMessage());
|
||||
}
|
||||
|
||||
return this.builderFactory.builder(LanguageBuilder.class).authorize(AuthorizationFlags.AllExceptPublic).build(BaseFieldSet.build(fields, Language._id), data);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import gr.cite.tools.data.query.QueryFactory;
|
|||
import gr.cite.tools.exception.MyApplicationException;
|
||||
import gr.cite.tools.exception.MyForbiddenException;
|
||||
import gr.cite.tools.exception.MyNotFoundException;
|
||||
import gr.cite.tools.fieldset.BaseFieldSet;
|
||||
import gr.cite.tools.fieldset.FieldSet;
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
import gr.cite.tools.logging.MapLogEntry;
|
||||
|
@ -17,13 +18,17 @@ import jakarta.transaction.Transactional;
|
|||
import jakarta.xml.bind.JAXBException;
|
||||
import org.opencdmp.audit.AuditableAction;
|
||||
import org.opencdmp.authorization.AuthorizationFlags;
|
||||
import org.opencdmp.commons.scope.tenant.TenantScope;
|
||||
import org.opencdmp.data.LanguageEntity;
|
||||
import org.opencdmp.data.TenantEntity;
|
||||
import org.opencdmp.model.Language;
|
||||
import org.opencdmp.model.Tenant;
|
||||
import org.opencdmp.model.builder.LanguageBuilder;
|
||||
import org.opencdmp.model.censorship.LanguageCensor;
|
||||
import org.opencdmp.model.persist.LanguagePersist;
|
||||
import org.opencdmp.model.result.QueryResult;
|
||||
import org.opencdmp.query.LanguageQuery;
|
||||
import org.opencdmp.query.TenantQuery;
|
||||
import org.opencdmp.query.lookup.LanguageLookup;
|
||||
import org.opencdmp.service.language.LanguageService;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -108,14 +113,30 @@ public class LanguageController {
|
|||
return model;
|
||||
}
|
||||
|
||||
@GetMapping("public/code/{code}")
|
||||
public Language get(@PathVariable("code") String code, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, IOException {
|
||||
@GetMapping(value = {"public/code/{code}/{tenantCode}", "public/code/{code}"})
|
||||
public Language get(@PathVariable("code") String code, @PathVariable(value = "tenantCode", required = false) String tenantCode, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, IOException {
|
||||
logger.debug(new MapLogEntry("retrieving" + Language.class.getSimpleName()).And("code", code).And("fields", fieldSet));
|
||||
|
||||
this.censorFactory.censor(LanguageCensor.class).censor(fieldSet, null);
|
||||
|
||||
LanguageQuery query = this.queryFactory.query(LanguageQuery.class).disableTracking().authorize(EnumSet.of(Public)).codes(code);
|
||||
Language model = this.builderFactory.builder(LanguageBuilder.class).authorize(EnumSet.of(Public)).build(fieldSet, query.firstAs(fieldSet));
|
||||
LanguageQuery query = this.queryFactory.query(LanguageQuery.class).disableTracking().authorize(EnumSet.of(Public)).codes(code).tenantIsSet(false);
|
||||
Language model = null;
|
||||
|
||||
if (tenantCode != null && !tenantCode.isEmpty()) {
|
||||
TenantEntity tenant = this.queryFactory.query(TenantQuery.class).codes(tenantCode).firstAs(new BaseFieldSet(Tenant._id));
|
||||
if (tenant == null)
|
||||
throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{tenantCode, Tenant.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
||||
|
||||
query.tenantIds(tenant.getId()).tenantIsSet(true);
|
||||
model = this.builderFactory.builder(LanguageBuilder.class).authorize(EnumSet.of(Public)).build(fieldSet, query.firstAs(fieldSet));
|
||||
if (model == null) {
|
||||
query.clearTenantIds().tenantIsSet(false);
|
||||
model = this.builderFactory.builder(LanguageBuilder.class).authorize(EnumSet.of(Public)).build(fieldSet, query.firstAs(fieldSet));
|
||||
}
|
||||
}
|
||||
else {
|
||||
model = this.builderFactory.builder(LanguageBuilder.class).authorize(EnumSet.of(Public)).build(fieldSet, query.firstAs(fieldSet));
|
||||
}
|
||||
|
||||
if (model == null)
|
||||
throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{code, Language.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
||||
|
@ -131,20 +152,34 @@ public class LanguageController {
|
|||
return model;
|
||||
}
|
||||
|
||||
@PostMapping("public/available-languages")
|
||||
public QueryResult<String> queryLanguageCodes(@RequestBody LanguageLookup lookup) {
|
||||
@PostMapping(value = {"public/available-languages/{tenantCode}", "public/available-languages"})
|
||||
public QueryResult<String> queryLanguageCodes(@RequestBody LanguageLookup lookup, @PathVariable(value = "tenantCode", required = false) String tenantCode) {
|
||||
logger.debug("querying {}", Language.class.getSimpleName());
|
||||
|
||||
this.censorFactory.censor(LanguageCensor.class).censor(lookup.getProject(), null);
|
||||
|
||||
LanguageQuery query = lookup.enrich(this.queryFactory).authorize(EnumSet.of(Public));
|
||||
query.setOrder(new Ordering().addAscending(Language._ordinal));
|
||||
List<LanguageEntity> data = query.collectAs(lookup.getProject());
|
||||
List<Language> models = this.builderFactory.builder(LanguageBuilder.class).authorize(EnumSet.of(Public)).build(lookup.getProject(), data);
|
||||
query.tenantIsSet(false);
|
||||
|
||||
long count = (lookup.getMetadata() != null && lookup.getMetadata().getCountAll()) ? query.count() : models.size();
|
||||
List<LanguageEntity> data = query.collectAs(new BaseFieldSet(Language._code));
|
||||
if (tenantCode != null && !tenantCode.isBlank()) {
|
||||
TenantEntity tenant = this.queryFactory.query(TenantQuery.class).codes(tenantCode).firstAs(new BaseFieldSet(Tenant._id));
|
||||
if (tenant == null)
|
||||
throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{tenantCode, Tenant.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
||||
|
||||
return new QueryResult<>(models.stream().map(Language::getCode).collect(Collectors.toList()), count);
|
||||
query.tenantIsSet(true).tenantIds(tenant.getId());
|
||||
List<LanguageEntity> tenantLanguages = query.collectAs(new BaseFieldSet(Language._code));
|
||||
for (LanguageEntity l : tenantLanguages) {
|
||||
if (data.stream().noneMatch(d1 -> d1.getCode().equals(l.getCode()))) {
|
||||
data.add(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long count = (lookup.getMetadata() != null && lookup.getMetadata().getCountAll()) ? query.count() : data.size();
|
||||
|
||||
return new QueryResult<>(data.stream().map(LanguageEntity::getCode).distinct().collect(Collectors.toList()), count);
|
||||
}
|
||||
|
||||
@PostMapping("persist")
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { OverlayModule } from '@angular/cdk/overlay';
|
||||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
|
||||
import { APP_INITIALIZER, LOCALE_ID, NgModule } from '@angular/core';
|
||||
import { APP_INITIALIZER, Injector, LOCALE_ID, NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MAT_MOMENT_DATE_FORMATS, MatMomentDateModule } from '@angular/material-moment-adapter';
|
||||
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core';
|
||||
|
@ -46,8 +46,8 @@ import { OpenCDMPCustomTranslationCompiler } from './utilities/translate/opencdm
|
|||
import { Router } from '@angular/router';
|
||||
|
||||
// AoT requires an exported function for factories
|
||||
export function HttpLoaderFactory(languageHttpService: LanguageHttpService) {
|
||||
return new TranslateServerLoader(languageHttpService);
|
||||
export function HttpLoaderFactory(languageHttpService: LanguageHttpService, authService: AuthService) {
|
||||
return new TranslateServerLoader(languageHttpService, authService);
|
||||
}
|
||||
|
||||
const cookieConfig: NgcCookieConsentConfig = {
|
||||
|
@ -138,7 +138,7 @@ export function InstallationConfigurationFactory(appConfig: ConfigurationService
|
|||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useFactory: HttpLoaderFactory,
|
||||
deps: [LanguageHttpService]
|
||||
deps: [LanguageHttpService, AuthService]
|
||||
}
|
||||
}),
|
||||
OverlayModule,
|
||||
|
|
|
@ -42,7 +42,7 @@ export class AuthService extends BaseService {
|
|||
private _selectedTenant: string;
|
||||
constructor(
|
||||
private installationConfiguration: ConfigurationService,
|
||||
private language: TranslateService,
|
||||
// private language: TranslateService,
|
||||
private router: Router,
|
||||
private zone: NgZone,
|
||||
private keycloakService: KeycloakService,
|
||||
|
@ -361,22 +361,13 @@ export class AuthService extends BaseService {
|
|||
|
||||
onAuthenticateSuccess(returnUrl: string): void {
|
||||
this.authState(true);
|
||||
this.uiNotificationService.snackBarNotification(
|
||||
this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-LOGIN'),
|
||||
SnackBarNotificationLevel.Success
|
||||
);
|
||||
// this.uiNotificationService.snackBarNotification(
|
||||
// this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-LOGIN'),
|
||||
// SnackBarNotificationLevel.Success
|
||||
// );
|
||||
this.zone.run(() => this.router.navigateByUrl(returnUrl));
|
||||
}
|
||||
|
||||
onAuthenticateSuccessReload(): void {
|
||||
this.authState(true);
|
||||
this.uiNotificationService.snackBarNotification(
|
||||
this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-LOGIN'),
|
||||
SnackBarNotificationLevel.Success
|
||||
);
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
public hasPermission(permission: AppPermission): boolean {
|
||||
// if (!this.installationConfiguration.appServiceEnabled) { return true; } //TODO: maybe reconsider
|
||||
return this.evaluatePermission(this.appAccount?.permissions || [], permission);
|
||||
|
|
|
@ -38,14 +38,15 @@ export class LanguageHttpService {
|
|||
catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
getSingleWithCode(code: string, reqFields: string[] = []): Observable<Language> {
|
||||
const url = `${this.apiBase}/public/code/${code}`;
|
||||
getSingleWithCode(code: string, tenantCode: string | null, reqFields: string[] = []): Observable<Language> {
|
||||
let url = `${this.apiBase}/public/code/${code}`;
|
||||
if (tenantCode) url += `/${tenantCode}`;
|
||||
const options: HttpParamsOptions = { fromObject: { f: reqFields } };
|
||||
|
||||
let params: BaseHttpParams = new BaseHttpParams(options);
|
||||
params.interceptorContext = {
|
||||
excludedInterceptors: [InterceptorType.AuthToken,
|
||||
InterceptorType.TenantHeaderInterceptor]
|
||||
]
|
||||
};
|
||||
|
||||
return this.http
|
||||
|
|
|
@ -4,16 +4,20 @@ import { Observable } from 'rxjs';
|
|||
import { map } from 'rxjs/operators';
|
||||
import { nameof } from 'ts-simple-nameof';
|
||||
import { LanguageHttpService } from './language.http.service';
|
||||
import { Injector } from '@angular/core';
|
||||
import { AuthService } from '../auth/auth.service';
|
||||
|
||||
export class TranslateServerLoader implements TranslateLoader {
|
||||
|
||||
constructor(
|
||||
private languageHttpService: LanguageHttpService
|
||||
) {
|
||||
private languageHttpService: LanguageHttpService,
|
||||
private authService: AuthService,
|
||||
) { }
|
||||
|
||||
|
||||
}
|
||||
getTranslation(lang: string): Observable<any> {
|
||||
return this.languageHttpService.getSingleWithCode(lang, [
|
||||
const tenantCode = this.authService.selectedTenant();
|
||||
return this.languageHttpService.getSingleWithCode(lang, tenantCode == 'default' ? null : tenantCode, [
|
||||
nameof<Language>(x => x.id),
|
||||
nameof<Language>(x => x.code),
|
||||
nameof<Language>(x => x.payload),
|
||||
|
|
|
@ -199,7 +199,7 @@ export class LanguageEditorComponent extends BaseEditor<LanguageEditorModel, Lan
|
|||
|
||||
public overrideFromFile(matCheckBox: MatCheckboxChange, code: string) {
|
||||
if (matCheckBox.checked == true) {
|
||||
this.languageHttpService.getSingleWithCode(code, LanguageEditorResolver.lookupFields())
|
||||
this.languageHttpService.getSingleWithCode(code, this.authService.selectedTenant(), LanguageEditorResolver.lookupFields())
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(language => {
|
||||
this.formGroup.get('payload').patchValue(language.payload);
|
||||
|
|
|
@ -5,7 +5,6 @@ import { CultureService } from '@app/core/services/culture/culture-service';
|
|||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||
import { BaseService } from '@common/base/base.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { TranslateServerLoader } from '@app/core/services/language/server.loader';
|
||||
import { LanguageService } from '@app/core/services/language/language.service';
|
||||
import { RouterUtilsService } from '@app/core/services/router/router-utils.service';
|
||||
|
||||
|
|
Loading…
Reference in New Issue