diff --git a/backend/core/src/main/java/org/opencdmp/query/DescriptionQuery.java b/backend/core/src/main/java/org/opencdmp/query/DescriptionQuery.java index 2d4559413..0521c6165 100644 --- a/backend/core/src/main/java/org/opencdmp/query/DescriptionQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/DescriptionQuery.java @@ -34,6 +34,8 @@ public class DescriptionQuery extends QueryBase { private Collection createdByIds; + private TenantQuery tenantQuery; + private PlanDescriptionTemplateQuery planDescriptionTemplateQuery; private PlanQuery planQuery; @@ -113,6 +115,11 @@ public class DescriptionQuery extends QueryBase { return this; } + public DescriptionQuery tenantSubQuery(TenantQuery subQuery) { + this.tenantQuery = subQuery; + return this; + } + public DescriptionQuery planDescriptionTemplateSubQuery(PlanDescriptionTemplateQuery subQuery) { this.planDescriptionTemplateQuery = subQuery; return this; @@ -302,6 +309,10 @@ public class DescriptionQuery extends QueryBase { inClause.value(item); predicates.add(inClause); } + if (this.tenantQuery != null) { + QueryContext subQuery = this.applySubQuery(this.tenantQuery, queryContext, UUID.class, tenantEntityRoot -> tenantEntityRoot.get(TenantEntity._id)); + predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionEntity._tenantId)).value(subQuery.Query)); + } if (this.createdByIds != null) { CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionEntity._createdById)); for (UUID item : this.createdByIds) diff --git a/backend/core/src/main/java/org/opencdmp/query/lookup/DescriptionLookup.java b/backend/core/src/main/java/org/opencdmp/query/lookup/DescriptionLookup.java index d36cf7f92..a19555deb 100644 --- a/backend/core/src/main/java/org/opencdmp/query/lookup/DescriptionLookup.java +++ b/backend/core/src/main/java/org/opencdmp/query/lookup/DescriptionLookup.java @@ -17,7 +17,6 @@ public class DescriptionLookup extends Lookup { private String like; private List ids; - private List excludedIds; private Instant createdAfter; private Instant createdBefore; @@ -25,6 +24,7 @@ public class DescriptionLookup extends Lookup { private Instant finalizedBefore; private PlanLookup planSubQuery; + private TenantLookup tenantSubQuery; private DescriptionTemplateLookup descriptionTemplateSubQuery; private DescriptionReferenceLookup descriptionReferenceSubQuery; private DescriptionTagLookup descriptionTagSubQuery; @@ -79,6 +79,10 @@ public class DescriptionLookup extends Lookup { public void setPlanSubQuery(PlanLookup planSubQuery) { this.planSubQuery = planSubQuery; } + public TenantLookup getTenantSubQuery() { return this.tenantSubQuery; } + + public void setTenantSubQuery(TenantLookup tenantSubQuery) { this.tenantSubQuery = tenantSubQuery; } + public DescriptionTemplateLookup getDescriptionTemplateSubQuery() { return this.descriptionTemplateSubQuery; } public void setDescriptionTemplateSubQuery(DescriptionTemplateLookup descriptionTemplateSubQuery) { this.descriptionTemplateSubQuery = descriptionTemplateSubQuery; } @@ -129,6 +133,7 @@ public class DescriptionLookup extends Lookup { if (this.ids != null) query.ids(this.ids); if (this.excludedIds != null) query.excludedIds(this.excludedIds); if (this.planSubQuery != null) query.planSubQuery(this.planSubQuery.enrich(queryFactory)); + if (this.tenantSubQuery != null) query.tenantSubQuery(this.tenantSubQuery.enrich(queryFactory)); if (this.descriptionTemplateSubQuery != null) query.descriptionTemplateSubQuery(this.descriptionTemplateSubQuery.enrich(queryFactory)); if (this.descriptionReferenceSubQuery != null) query.descriptionReferenceSubQuery(this.descriptionReferenceSubQuery.enrich(queryFactory)); if (this.descriptionTagSubQuery != null) query.descriptionTagSubQuery(this.descriptionTagSubQuery.enrich(queryFactory)); diff --git a/backend/core/src/main/java/org/opencdmp/query/lookup/TenantLookup.java b/backend/core/src/main/java/org/opencdmp/query/lookup/TenantLookup.java index ac763326e..20672e904 100644 --- a/backend/core/src/main/java/org/opencdmp/query/lookup/TenantLookup.java +++ b/backend/core/src/main/java/org/opencdmp/query/lookup/TenantLookup.java @@ -13,6 +13,7 @@ public class TenantLookup extends Lookup { private String like; private List isActive; private List ids; + private List codes; private List excludedIds; public String getLike() { @@ -35,9 +36,11 @@ public class TenantLookup extends Lookup { return ids; } - public void setIds(List ids) { - this.ids = ids; - } + public void setIds(List ids) { this.ids = ids; } + + public List getCodes() { return codes; } + + public void setCodes(List codes) { this.codes = codes; } public List getExcludedIds() { return excludedIds; @@ -52,6 +55,7 @@ public class TenantLookup extends Lookup { if (this.like != null) query.like(this.like); if (this.isActive != null) query.isActive(this.isActive); if (this.ids != null) query.ids(this.ids); + if (this.codes != null) query.codes(this.codes); if (this.excludedIds != null) query.excludedIds(this.excludedIds); this.enrichCommon(query); diff --git a/frontend/src/app/core/query/description.lookup.ts b/frontend/src/app/core/query/description.lookup.ts index 6899bfd0e..cdf78e007 100644 --- a/frontend/src/app/core/query/description.lookup.ts +++ b/frontend/src/app/core/query/description.lookup.ts @@ -3,10 +3,10 @@ import { Guid } from '@common/types/guid'; import { IsActive } from '../common/enum/is-active.enum'; import { DescriptionStatus } from '../common/enum/description-status'; import { PlanLookup } from './plan.lookup'; -import { ReferenceType } from '../model/reference-type/reference-type'; import { DescriptionReferenceLookup } from './reference.lookup'; import { DescriptionTagLookup } from './tag.lookup'; import { DescriptionTemplateLookup } from './description-template.lookup'; +import { TenantLookup } from './tenant.lookup'; export class DescriptionLookup extends Lookup implements DescriptionFilter { ids: Guid[]; @@ -20,6 +20,7 @@ export class DescriptionLookup extends Lookup implements DescriptionFilter { statuses: DescriptionStatus[]; planSubQuery: PlanLookup; + tenantSubQuery: TenantLookup; descriptionTemplateSubQuery: DescriptionTemplateLookup; descriptionTagSubQuery: DescriptionTagLookup; descriptionReferenceSubQuery: DescriptionReferenceLookup; diff --git a/frontend/src/app/core/query/tenant.lookup.ts b/frontend/src/app/core/query/tenant.lookup.ts index 9a3611341..e5834dd00 100644 --- a/frontend/src/app/core/query/tenant.lookup.ts +++ b/frontend/src/app/core/query/tenant.lookup.ts @@ -4,6 +4,7 @@ import { IsActive } from '../common/enum/is-active.enum'; export class TenantLookup extends Lookup implements TenantFilter { ids: Guid[]; + codes: string[]; excludedIds: Guid[]; like: string; isActive: IsActive[]; diff --git a/frontend/src/app/ui/description/listing/description-listing.component.html b/frontend/src/app/ui/description/listing/description-listing.component.html index fc8a9a01c..176374f61 100644 --- a/frontend/src/app/ui/description/listing/description-listing.component.html +++ b/frontend/src/app/ui/description/listing/description-listing.component.html @@ -27,7 +27,7 @@ -
- +
diff --git a/frontend/src/app/ui/description/listing/description-listing.component.ts b/frontend/src/app/ui/description/listing/description-listing.component.ts index 8d426e87f..851f525d9 100644 --- a/frontend/src/app/ui/description/listing/description-listing.component.ts +++ b/frontend/src/app/ui/description/listing/description-listing.component.ts @@ -37,6 +37,10 @@ import { QueryParamsService } from '@app/core/services/utilities/query-params.se import { UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { Guid } from '@common/types/guid'; import { DescriptionFilterService } from './filtering/description-filter.service'; +import { Tenant } from '@app/core/model/tenant/tenant'; +import { BaseHttpParams } from '@common/http/base-http-params'; +import { InterceptorType } from '@common/http/interceptors/interceptor-type'; +import { PrincipalService } from '@app/core/services/http/principal.service'; @Component({ selector: 'app-description-listing-component', @@ -69,6 +73,8 @@ export class DescriptionListingComponent extends BaseListingComponent { + this.tenants = tenants; + }); + this.formGroup.get('like').valueChanges .pipe(takeUntil(this._destroyed), debounceTime(500)) .subscribe(x => this.controlModified()); @@ -265,6 +277,7 @@ export class DescriptionListingComponent extends BaseListingComponent> { + const params = new BaseHttpParams(); + params.interceptorContext = { + excludedInterceptors: [InterceptorType.TenantHeaderInterceptor] + }; + return this.principalService.myTenants({ params: params }); + } + private _parseLookupFromParams(params: Params): DescriptionLookup { let lookup: DescriptionLookup = JSON.parse(params['lookup']); @@ -367,6 +389,17 @@ export class DescriptionListingComponent extends BaseListingComponent 0) { + const tenantFilter = lookup.tenantSubQuery?.codes[0]; + + if (tenantFilter != this.authService.selectedTenant()) { + lookup.tenantSubQuery = null; + this.filterChanged(lookup); + return lookup; + } + } + return lookup; } @@ -384,6 +417,17 @@ export class DescriptionListingComponent extends BaseListingComponent t.code && t.code?.toString() == this.authService.selectedTenant()); + if (tenant && tenant?.code) { + lookup.tenantSubQuery = DescriptionFilterService.initializeTenantLookup(); + lookup.tenantSubQuery.codes = [tenant.code] + } + else lookup.tenantSubQuery = null; + } else lookup.tenantSubQuery = null; + // Description Templates let descriptionTemplates = formGroup.get("descriptionTemplates")?.value ?? null; if (descriptionTemplates && descriptionTemplates?.length > 0) { @@ -432,6 +476,7 @@ export class DescriptionListingComponent extends BaseListingComponent 0 ? lookup.statuses[0] : null], + viewOnlyTenant: [lookup.tenantSubQuery?.codes?.length > 0 ? true : false], role: lookup.planSubQuery?.planUserSubQuery?.userRoles ? lookup.planSubQuery?.planUserSubQuery?.userRoles[0] : [], descriptionTemplates: lookup.descriptionTemplateSubQuery?.ids ? [lookup.descriptionTemplateSubQuery?.ids] : [], associatedPlanIds: lookup.planSubQuery?.ids ? [lookup.planSubQuery?.ids] : [], @@ -443,6 +488,7 @@ export class DescriptionListingComponent extends BaseListingComponent diff --git a/frontend/src/app/ui/description/listing/filtering/description-filter-dialogue/description-filter-dialog.component.ts b/frontend/src/app/ui/description/listing/filtering/description-filter-dialogue/description-filter-dialog.component.ts index a0685c30f..71e78012a 100644 --- a/frontend/src/app/ui/description/listing/filtering/description-filter-dialogue/description-filter-dialog.component.ts +++ b/frontend/src/app/ui/description/listing/filtering/description-filter-dialogue/description-filter-dialog.component.ts @@ -20,6 +20,7 @@ export class DescriptionFilterDialogComponent implements OnInit { private analyticsService: AnalyticsService, @Inject(MAT_DIALOG_DATA) public data: { isPublic: boolean, + hasSelectedTenant: boolean, filterForm: UntypedFormGroup, referencesWithTypeItems: ReferencesWithType[], } diff --git a/frontend/src/app/ui/description/listing/filtering/description-filter.component.html b/frontend/src/app/ui/description/listing/filtering/description-filter.component.html index 8ec8a0feb..3797fbe14 100644 --- a/frontend/src/app/ui/description/listing/filtering/description-filter.component.html +++ b/frontend/src/app/ui/description/listing/filtering/description-filter.component.html @@ -21,6 +21,14 @@
+ +
+
{{ 'PLAN-LISTING.FILTERS.RELATED-TENANT.NAME' | translate}}
+ {{ 'PLAN-LISTING.FILTERS.RELATED-TENANT.FILTER-BY-TENANT' | translate }} +
+
+ +
{{'DESCRIPTION-LISTING.FILTERS.RELATED-DESCRIPTION-TEMPLATES.NAME' | translate}}
diff --git a/frontend/src/app/ui/description/listing/filtering/description-filter.component.ts b/frontend/src/app/ui/description/listing/filtering/description-filter.component.ts index 3cb6fb33a..e2556eb47 100644 --- a/frontend/src/app/ui/description/listing/filtering/description-filter.component.ts +++ b/frontend/src/app/ui/description/listing/filtering/description-filter.component.ts @@ -33,6 +33,7 @@ export class DescriptionFilterComponent extends BaseCriteriaComponent implements @Input() status; @Input() isPublic: boolean; + @Input() hasSelectedTenant: boolean; @Input() referencesWithTypeItems: ReferencesWithType[]; @Input() filterFormGroup: UntypedFormGroup; @Output() filterChanged: EventEmitter = new EventEmitter(); diff --git a/frontend/src/app/ui/description/listing/filtering/description-filter.service.ts b/frontend/src/app/ui/description/listing/filtering/description-filter.service.ts index ef36bbbb0..395e0c92c 100644 --- a/frontend/src/app/ui/description/listing/filtering/description-filter.service.ts +++ b/frontend/src/app/ui/description/listing/filtering/description-filter.service.ts @@ -4,11 +4,13 @@ import { Description, DescriptionReference, DescriptionTag } from "@app/core/mod import { Plan, PlanUser } from "@app/core/model/plan/plan"; import { Reference } from "@app/core/model/reference/reference"; import { Tag } from "@app/core/model/tag/tag"; +import { Tenant } from "@app/core/model/tenant/tenant"; import { DescriptionTemplateLookup } from "@app/core/query/description-template.lookup"; import { PlanUserLookup } from "@app/core/query/plan-user.lookup"; import { PlanLookup } from "@app/core/query/plan.lookup"; import { DescriptionReferenceLookup } from "@app/core/query/reference.lookup"; import { DescriptionTagLookup } from "@app/core/query/tag.lookup"; +import { TenantLookup } from "@app/core/query/tenant.lookup"; import { IsActive } from "@notification-service/core/enum/is-active.enum"; import { nameof } from "ts-simple-nameof"; @@ -79,4 +81,17 @@ export class DescriptionFilterService { return lookup; } + + public static initializeTenantLookup(): TenantLookup { + const lookup = new TenantLookup(); + lookup.metadata = { countAll: true }; + lookup.isActive = [IsActive.Active]; + lookup.project = { + fields: [ + nameof(x => x.code), + ] + }; + + return lookup; + } } \ No newline at end of file diff --git a/frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.ts b/frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.ts index 56b89f76f..f64415366 100644 --- a/frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.ts +++ b/frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.ts @@ -30,10 +30,6 @@ import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; import { RouterUtilsService } from '@app/core/services/router/router-utils.service'; import { Tenant } from '@app/core/model/tenant/tenant'; -import { PrincipalService } from '@app/core/services/http/principal.service'; -import { Observable } from 'rxjs'; -import { BaseHttpParams } from '@common/http/base-http-params'; -import { InterceptorType } from '@common/http/interceptors/interceptor-type'; @Component({ selector: 'app-description-listing-item-component', @@ -45,6 +41,7 @@ export class DescriptionListingItemComponent extends BaseComponent implements On @Input() description: Description; @Input() showDivider: boolean = true; @Input() isPublic: boolean = false; + @Input() tenants: Tenant[] = []; @Output() onClick: EventEmitter = new EventEmitter(); isDraft: boolean; @@ -56,7 +53,6 @@ export class DescriptionListingItemComponent extends BaseComponent implements On canDelete: boolean = false; canEdit: boolean = false; canInvitePlanUsers: boolean = false; - tenants: Tenant[] = []; constructor( public routerUtils: RouterUtilsService, @@ -78,7 +74,6 @@ export class DescriptionListingItemComponent extends BaseComponent implements On private fb: UntypedFormBuilder, private analyticsService: AnalyticsService, private httpErrorHandlingService: HttpErrorHandlingService, - private principalService: PrincipalService, ) { super(); } @@ -105,10 +100,6 @@ export class DescriptionListingItemComponent extends BaseComponent implements On this.canInvitePlanUsers = (this.authService.hasPermission(AppPermission.InvitePlanUsers) || this.description.authorizationFlags?.some(x => x === AppPermission.InvitePlanUsers)) && this.description.belongsToCurrentTenant != false; - - this.loadUserTenants().pipe(takeUntil(this._destroyed)).subscribe( tenants => { - this.tenants = tenants; - }); } public getTenantName(id: Guid): string { @@ -248,12 +239,4 @@ export class DescriptionListingItemComponent extends BaseComponent implements On canEditDescription(): boolean { return (this.isDraft) && (this.description.authorizationFlags?.some(x => x === AppPermission.EditDescription) || this.authentication.hasPermission(AppPermission.EditDescription)) && this.isPublic == false && this.description.belongsToCurrentTenant != false; } - - loadUserTenants(): Observable> { - const params = new BaseHttpParams(); - params.interceptorContext = { - excludedInterceptors: [InterceptorType.TenantHeaderInterceptor] - }; - return this.principalService.myTenants({ params: params }); - } }