added tenant filter on plan listing

This commit is contained in:
Sofia Papacharalampous 2024-07-09 13:32:34 +03:00
parent b4ae1da886
commit 772c62a2b4
21 changed files with 122 additions and 23 deletions

View File

@ -31,6 +31,8 @@ public class PlanQuery extends QueryBase<PlanEntity> {
private Collection<UUID> ids;
private Collection<UUID> tenantIds;
private Collection<UUID> creatorIds;
private Collection<UUID> excludedIds;
@ -95,6 +97,21 @@ public class PlanQuery extends QueryBase<PlanEntity> {
return this;
}
public PlanQuery tenantIds(UUID value) {
this.tenantIds = List.of(value);
return this;
}
public PlanQuery tenantIds(UUID... value) {
this.tenantIds = Arrays.asList(value);
return this;
}
public PlanQuery tenantIds(Collection<UUID> values) {
this.tenantIds = values;
return this;
}
public PlanQuery creatorIds(UUID value) {
this.creatorIds = List.of(value);
return this;
@ -318,6 +335,12 @@ public class PlanQuery extends QueryBase<PlanEntity> {
inClause.value(item);
predicates.add(inClause);
}
if (this.tenantIds != null) {
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(PlanEntity._tenantId));
for (UUID item : this.tenantIds)
inClause.value(item);
predicates.add(inClause);
}
if (this.creatorIds != null) {
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(PlanEntity._creatorId));
for (UUID item : this.creatorIds)

View File

@ -19,6 +19,7 @@ public class PlanLookup extends Lookup {
private String like;
private List<UUID> ids;
private List<UUID> tenantIds;
private List<UUID> excludedIds;
private List<UUID> groupIds;
@ -52,6 +53,10 @@ public class PlanLookup extends Lookup {
this.ids = ids;
}
public List<UUID> getTenantIds() { return this.tenantIds; }
public void setTenantIds(List<UUID> tenantIds) { this.tenantIds = tenantIds; }
public List<UUID> getExcludedIds() {
return this.excludedIds;
}
@ -137,6 +142,7 @@ public class PlanLookup extends Lookup {
PlanQuery query = queryFactory.query(PlanQuery.class);
if (this.like != null) query.like(this.like);
if (this.ids != null) query.ids(this.ids);
if (this.tenantIds != null) query.tenantIds(this.tenantIds);
if (this.groupIds != null) query.groupIds(this.groupIds);
if (this.excludedIds != null) query.excludedIds(this.excludedIds);
if (this.accessTypes != null) query.accessTypes(this.accessTypes);

View File

@ -11,6 +11,7 @@ import { PlanReferenceLookup } from './reference.lookup';
export class PlanLookup extends Lookup implements PlanFilter {
ids: Guid[];
tenantIds: Guid[];
excludedIds: Guid[];
like: string;
isActive: IsActive[];

View File

@ -3,5 +3,6 @@
[filterFormGroup]="data.filterForm"
[referencesWithTypeItems]="data.referencesWithTypeItems"
[isPublic]="data.isPublic"
[hasSelectedTenant]="data.hasSelectedTenant"
(filterChanged)="onFilterChanged($event)"
></app-plan-filter-component>

View File

@ -19,7 +19,8 @@ export class PlanFilterDialogComponent implements OnInit {
public dialogRef: MatDialogRef<PlanFilterDialogComponent>,
private analyticsService: AnalyticsService,
@Inject(MAT_DIALOG_DATA) public data: {
isPublic: boolean,
isPublic: boolean,
hasSelectedTenant: boolean,
filterForm: UntypedFormGroup,
referencesWithTypeItems: ReferencesWithType[],
}) { }

View File

@ -18,6 +18,14 @@
</div>
<!-- End of Visibility Filter-->
<!-- Tenant Filter -->
<div *ngIf="!isPublic && hasSelectedTenant" class="col-10">
<h6 class="category-title">{{ 'PLAN-LISTING.FILTERS.RELATED-TENANT.NAME' | translate}}</h6>
<mat-slide-toggle [formControl]="formGroup.get('viewOnlyTenant')">{{ 'PLAN-LISTING.FILTERS.RELATED-TENANT.FILTER-BY-TENANT' | translate }}</mat-slide-toggle>
<hr>
</div>
<!-- End of Tenant Filter -->
<!-- Related Dataset Templates Filter -->
<div class="col-10">
<h6 class="category-title">{{ 'PLAN-LISTING.FILTERS.RELATED-DESCRIPTION-TEMPLATES.NAME' | translate}}</h6>

View File

@ -30,6 +30,7 @@ import { ReferencesWithType } from '@app/core/query/description.lookup';
export class PlanFilterComponent extends BaseCriteriaComponent implements OnInit, OnChanges {
@Input() isPublic: boolean;
@Input() hasSelectedTenant: boolean;
@Input() referencesWithTypeItems: ReferencesWithType[];
@Input() filterFormGroup: UntypedFormGroup;
@Output() filterChanged: EventEmitter<any> = new EventEmitter();

View File

@ -31,12 +31,7 @@ import { PlanDeleteDialogComponent } from '../../plan-delete-dialog/plan-delete-
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 { Observable } from 'rxjs';
import { Tenant } from '@app/core/model/tenant/tenant';
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
import { BaseHttpParams } from '@common/http/base-http-params';
import { TenantHandlingService } from '@app/core/services/tenant/tenant-handling.service';
import { PrincipalService } from '@app/core/services/http/principal.service';
@Component({
selector: 'app-plan-listing-item-component',
@ -48,6 +43,7 @@ export class PlanListingItemComponent extends BaseComponent implements OnInit {
@Input() plan: Plan;
@Input() showDivider: boolean = true;
@Input() isPublic: boolean;
@Input() tenants: Tenant[] = [];
@Output() onClick: EventEmitter<Plan> = new EventEmitter();
isDraft: boolean;
@ -55,7 +51,6 @@ export class PlanListingItemComponent extends BaseComponent implements OnInit {
isPublished: boolean;
planStatusEnum = PlanStatus;
fileTransformerEntityTypeEnum = FileTransformerEntityType;
tenants: Tenant[] = [];
constructor(
public routerUtils: RouterUtilsService,
@ -76,7 +71,6 @@ export class PlanListingItemComponent extends BaseComponent implements OnInit {
private fileUtils: FileUtils,
private analyticsService: AnalyticsService,
private httpErrorHandlingService: HttpErrorHandlingService,
private principalService: PrincipalService,
) {
super();
}
@ -94,10 +88,6 @@ export class PlanListingItemComponent extends BaseComponent implements OnInit {
this.isPublished = false;
if (this.plan.status === PlanStatus.Finalized && this.plan.accessType === PlanAccessType.Public) { this.isPublished = true }
}
this.loadUserTenants().pipe(takeUntil(this._destroyed)).subscribe( tenants => {
this.tenants = tenants;
});
}
public isAuthenticated(): boolean {
@ -111,8 +101,6 @@ export class PlanListingItemComponent extends BaseComponent implements OnInit {
inviteToPlan() {
const dialogRef = this.dialog.open(PlanInvitationDialogComponent, {
// height: '250px',
// width: '700px',
autoFocus: false,
restoreFocus: false,
data: {
@ -278,12 +266,4 @@ export class PlanListingItemComponent extends BaseComponent implements OnInit {
canAssignPlanUsers(): boolean {
return (this.plan.authorizationFlags?.some(x => x === AppPermission.AssignPlanUsers) || this.authentication.hasPermission(AppPermission.AssignPlanUsers)) && this.isPublic == false && this.plan.belongsToCurrentTenant != false;
}
loadUserTenants(): Observable<Array<Tenant>> {
const params = new BaseHttpParams();
params.interceptorContext = {
excludedInterceptors: [InterceptorType.TenantHeaderInterceptor]
};
return this.principalService.myTenants({ params: params });
}
}

View File

@ -62,7 +62,12 @@
</div>
<div class="col-md-12 col-sm-12 col-md-9">
<div *ngFor="let item of listingItems; let i = index">
<app-plan-listing-item-component [showDivider]="i != (listingItems.length - 1)" [plan]="item" [isPublic]="isPublic"></app-plan-listing-item-component>
<app-plan-listing-item-component
[showDivider]="i != (listingItems.length - 1)"
[plan]="item"
[isPublic]="isPublic"
[tenants]="tenants"
></app-plan-listing-item-component>
</div>
<div *ngIf="hasListingItems && this.lookup?.page?.offset < this.totalCount - 1 && this.pageSize < this.totalCount - 1" class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadMore()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>

View File

@ -36,6 +36,10 @@ import { QueryParamsService } from '@app/core/services/utilities/query-params.se
import { ReferencesWithType } from '@app/core/query/description.lookup';
import { Guid } from '@common/types/guid';
import { PlanFilterService } from './filtering/services/plan-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-plan-listing-component',
@ -66,6 +70,8 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
scrollbar: boolean;
order = RecentActivityOrder;
tenants: Tenant[];
private _sortDirection: SortDirection = SortDirection.Descending; //SortDirection.Descending: "-"
set sortDirection(sortDirection: SortDirection) {
this._sortDirection = sortDirection;
@ -105,6 +111,7 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
private authService: AuthService,
private guidedTourService: GuidedTourService,
private analyticsService: AnalyticsService,
private principalService: PrincipalService,
) {
super(router, route, uiNotificationService, httpErrorHandlingService, queryParamsService);
}
@ -143,6 +150,10 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
this.onPageLoad({ offset: this.lookup.page.offset / this.lookup.page.size } as PageLoadEvent);
});
this._loadUserTenants().pipe(takeUntil(this._destroyed)).subscribe( tenants => {
this.tenants = tenants;
});
this.formGroup.get('like').valueChanges
.pipe(takeUntil(this._destroyed), debounceTime(500))
@ -275,6 +286,7 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
panelClass: 'dialog-side-panel',
data: {
isPublic: this.isPublic ?? true,
hasSelectedTenant: this.authService.selectedTenant() != 'default',
filterForm: this._buildFormFromLookup(this.lookup),
referencesWithTypeItems: this.referenceFilters ?? [],
}
@ -329,6 +341,14 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
this.orderByChanged();
}
private _loadUserTenants(): Observable<Array<Tenant>> {
const params = new BaseHttpParams();
params.interceptorContext = {
excludedInterceptors: [InterceptorType.TenantHeaderInterceptor]
};
return this.principalService.myTenants({ params: params });
}
private _parseLookupFromParams(params: Params): PlanLookup {
let lookup: PlanLookup = JSON.parse(params['lookup']);
@ -356,6 +376,14 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
lookup.statuses = formGroup.get("status")?.value !== null ? [formGroup.get("status")?.value] : null;
// Tenants
let viewOnlyTenant = formGroup.get("viewOnlyTenant")?.value ?? false;
if (viewOnlyTenant) {
let tenant = this.tenants?.find(t => t.code && t.code?.toString() == this.authService.selectedTenant());
if (tenant && tenant?.id) lookup.tenantIds = [tenant.id]
else lookup.tenantIds = null;
} else lookup.tenantIds = null;
// Description Templates
let descriptionTemplates = formGroup.get("descriptionTemplates")?.value ?? null;
if (descriptionTemplates && descriptionTemplates?.length > 0) {
@ -398,6 +426,7 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
private _buildFormFromLookup(lookup: PlanLookup): UntypedFormGroup {
return (new UntypedFormBuilder()).group({
status: [lookup.statuses?.length > 0 ? lookup.statuses[0] : null],
viewOnlyTenant: [lookup.tenantIds?.length > 0 ? true : false],
descriptionTemplates: lookup.planDescriptionTemplateSubQuery?.descriptionTemplateGroupIds ? [lookup.planDescriptionTemplateSubQuery?.descriptionTemplateGroupIds] : [],
planBlueprints: lookup.planBlueprintSubQuery?.ids ? [lookup.planBlueprintSubQuery?.ids]: [],
role: lookup.planUserSubQuery?.userRoles ? lookup.planUserSubQuery?.userRoles[0] : null,

View File

@ -695,6 +695,10 @@
"DRAFT": "Draft"
}
},
"RELATED-TENANT": {
"NAME": "Related Tenant",
"FILTER-BY-TENANT": "Filter by tenant"
},
"RELATED-DESCRIPTION-TEMPLATES": {
"NAME": "Related Description Templates",
"PLACEHOLDER": "Select Description Templates"

View File

@ -695,6 +695,10 @@
"DRAFT": "Draft"
}
},
"RELATED-TENANT": {
"NAME": "Related Tenant",
"FILTER-BY-TENANT": "Filter by tenant"
},
"RELATED-DESCRIPTION-TEMPLATES": {
"NAME": "Related Description Templates",
"PLACEHOLDER": "Select Description Templates"

View File

@ -695,6 +695,10 @@
"DRAFT": "Draft"
}
},
"RELATED-TENANT": {
"NAME": "Related Tenant",
"FILTER-BY-TENANT": "Filter by tenant"
},
"RELATED-DESCRIPTION-TEMPLATES": {
"NAME": "Related Description Templates",
"PLACEHOLDER": "Select Description Templates"

View File

@ -695,6 +695,10 @@
"DRAFT": "Draft"
}
},
"RELATED-TENANT": {
"NAME": "Related Tenant",
"FILTER-BY-TENANT": "Filter by tenant"
},
"RELATED-DESCRIPTION-TEMPLATES": {
"NAME": "Related Description Templates",
"PLACEHOLDER": "Select Description Templates"

View File

@ -695,6 +695,10 @@
"DRAFT": "Draft"
}
},
"RELATED-TENANT": {
"NAME": "Related Tenant",
"FILTER-BY-TENANT": "Filter by tenant"
},
"RELATED-DESCRIPTION-TEMPLATES": {
"NAME": "Related Description Templates",
"PLACEHOLDER": "Select Description Templates"

View File

@ -695,6 +695,10 @@
"DRAFT": "Draft"
}
},
"RELATED-TENANT": {
"NAME": "Related Tenant",
"FILTER-BY-TENANT": "Filter by tenant"
},
"RELATED-DESCRIPTION-TEMPLATES": {
"NAME": "Related Description Templates",
"PLACEHOLDER": "Select Description Templates"

View File

@ -695,6 +695,10 @@
"DRAFT": "Draft"
}
},
"RELATED-TENANT": {
"NAME": "Related Tenant",
"FILTER-BY-TENANT": "Filter by tenant"
},
"RELATED-DESCRIPTION-TEMPLATES": {
"NAME": "Related Description Templates",
"PLACEHOLDER": "Select Description Templates"

View File

@ -695,6 +695,10 @@
"DRAFT": "Draft"
}
},
"RELATED-TENANT": {
"NAME": "Related Tenant",
"FILTER-BY-TENANT": "Filter by tenant"
},
"RELATED-DESCRIPTION-TEMPLATES": {
"NAME": "Related Description Templates",
"PLACEHOLDER": "Select Description Templates"

View File

@ -695,6 +695,10 @@
"DRAFT": "Draft"
}
},
"RELATED-TENANT": {
"NAME": "Related Tenant",
"FILTER-BY-TENANT": "Filter by tenant"
},
"RELATED-DESCRIPTION-TEMPLATES": {
"NAME": "Related Description Templates",
"PLACEHOLDER": "Select Description Templates"

View File

@ -695,6 +695,10 @@
"DRAFT": "Draft"
}
},
"RELATED-TENANT": {
"NAME": "Related Tenant",
"FILTER-BY-TENANT": "Filter by tenant"
},
"RELATED-DESCRIPTION-TEMPLATES": {
"NAME": "Related Description Templates",
"PLACEHOLDER": "Select Description Templates"

View File

@ -695,6 +695,10 @@
"DRAFT": "Draft"
}
},
"RELATED-TENANT": {
"NAME": "Related Tenant",
"FILTER-BY-TENANT": "Filter by tenant"
},
"RELATED-DESCRIPTION-TEMPLATES": {
"NAME": "Related Description Templates",
"PLACEHOLDER": "Select Description Templates"