added tenant filter on description listing
This commit is contained in:
parent
772c62a2b4
commit
2a66a69f1e
|
@ -34,6 +34,8 @@ public class DescriptionQuery extends QueryBase<DescriptionEntity> {
|
|||
|
||||
private Collection<UUID> createdByIds;
|
||||
|
||||
private TenantQuery tenantQuery;
|
||||
|
||||
private PlanDescriptionTemplateQuery planDescriptionTemplateQuery;
|
||||
|
||||
private PlanQuery planQuery;
|
||||
|
@ -113,6 +115,11 @@ public class DescriptionQuery extends QueryBase<DescriptionEntity> {
|
|||
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<DescriptionEntity> {
|
|||
inClause.value(item);
|
||||
predicates.add(inClause);
|
||||
}
|
||||
if (this.tenantQuery != null) {
|
||||
QueryContext<TenantEntity, UUID> 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<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionEntity._createdById));
|
||||
for (UUID item : this.createdByIds)
|
||||
|
|
|
@ -17,7 +17,6 @@ public class DescriptionLookup extends Lookup {
|
|||
private String like;
|
||||
|
||||
private List<UUID> ids;
|
||||
|
||||
private List<UUID> 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));
|
||||
|
|
|
@ -13,6 +13,7 @@ public class TenantLookup extends Lookup {
|
|||
private String like;
|
||||
private List<IsActive> isActive;
|
||||
private List<UUID> ids;
|
||||
private List<String> codes;
|
||||
private List<UUID> excludedIds;
|
||||
|
||||
public String getLike() {
|
||||
|
@ -35,9 +36,11 @@ public class TenantLookup extends Lookup {
|
|||
return ids;
|
||||
}
|
||||
|
||||
public void setIds(List<UUID> ids) {
|
||||
this.ids = ids;
|
||||
}
|
||||
public void setIds(List<UUID> ids) { this.ids = ids; }
|
||||
|
||||
public List<String> getCodes() { return codes; }
|
||||
|
||||
public void setCodes(List<String> codes) { this.codes = codes; }
|
||||
|
||||
public List<UUID> 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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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[];
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="listingItems && listingItems.length > 0 || lookup.like || lookup.descriptionTemplateSubQuery || lookup.planSubQuery || lookup.descriptionTagSubQuery || lookup.descriptionReferenceSubQuery"
|
||||
<div *ngIf="hasLoadedListingItems && (hasListingItems || hasFilters)"
|
||||
class="filter-btn" [style.right]="dialog.getDialogById('filters') ? '446px' : '0px'" [style.width]="listingItems.length > 2 ? '57px' : '37px'" (click)="openFiltersDialog()">
|
||||
<button mat-raised-button class="p-0" [matBadge]="filtersCount" [matBadgeHidden]="!hasFilters" matBadgePosition="before">
|
||||
<mat-icon class="mr-4 filter-icon">filter_alt</mat-icon>
|
||||
|
@ -81,7 +81,12 @@
|
|||
</div>
|
||||
<div class="col-md-12 col-sm-12 col-md-9">
|
||||
<div *ngFor="let item of listingItems; let i = index">
|
||||
<app-description-listing-item-component [isPublic]="isPublic" [description]="item" [showDivider]="i != (listingItems.length - 1)"></app-description-listing-item-component>
|
||||
<app-description-listing-item-component
|
||||
[isPublic]="isPublic"
|
||||
[description]="item"
|
||||
[tenants]="tenants"
|
||||
[showDivider]="i != (listingItems.length - 1)"
|
||||
></app-description-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()">{{'DESCRIPTION-LISTING.ACTIONS.LOAD-MORE' | translate}}</button>
|
||||
|
|
|
@ -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<BaseDescri
|
|||
order: new UntypedFormControl()
|
||||
});
|
||||
|
||||
tenants: Tenant[] = [];
|
||||
|
||||
scrollbar: boolean;
|
||||
order = RecentActivityOrder;
|
||||
planText: string;
|
||||
|
@ -96,7 +102,8 @@ export class DescriptionListingComponent extends BaseListingComponent<BaseDescri
|
|||
get hasFilters(): boolean {
|
||||
return (this.lookup.like != null && this.lookup.like != '') || this.lookup.statuses != null ||
|
||||
this.lookup.planSubQuery != null || this.lookup.descriptionTemplateSubQuery != null ||
|
||||
this.lookup.descriptionTagSubQuery != null || this.lookup.descriptionReferenceSubQuery != null;
|
||||
this.lookup.descriptionTagSubQuery != null || this.lookup.descriptionReferenceSubQuery != null ||
|
||||
this.lookup.tenantSubQuery != null;
|
||||
}
|
||||
|
||||
constructor(
|
||||
|
@ -115,6 +122,7 @@ export class DescriptionListingComponent extends BaseListingComponent<BaseDescri
|
|||
private analyticsService: AnalyticsService,
|
||||
private fb: UntypedFormBuilder,
|
||||
protected formBuilder: FormBuilder,
|
||||
private principalService: PrincipalService,
|
||||
) {
|
||||
super(router, route, uiNotificationService, httpErrorHandlingService, queryParamsService);
|
||||
}
|
||||
|
@ -155,6 +163,10 @@ export class DescriptionListingComponent extends BaseListingComponent<BaseDescri
|
|||
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))
|
||||
.subscribe(x => this.controlModified());
|
||||
|
@ -265,6 +277,7 @@ export class DescriptionListingComponent extends BaseListingComponent<BaseDescri
|
|||
panelClass: 'dialog-side-panel',
|
||||
data: {
|
||||
isPublic: this.isPublic ?? true,
|
||||
hasSelectedTenant: this.authService.selectedTenant() != 'default',
|
||||
filterForm: this._buildFormFromLookup(this.lookup, this.referenceFilters),
|
||||
referencesWithTypeItems: this.referenceFilters ?? [],
|
||||
}
|
||||
|
@ -357,6 +370,15 @@ export class DescriptionListingComponent extends BaseListingComponent<BaseDescri
|
|||
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): DescriptionLookup {
|
||||
let lookup: DescriptionLookup = JSON.parse(params['lookup']);
|
||||
|
||||
|
@ -367,6 +389,17 @@ export class DescriptionListingComponent extends BaseListingComponent<BaseDescri
|
|||
lookup.page = { size: querySize, offset: queryOffset };
|
||||
lookup.project = { fields: this._lookupFields };
|
||||
lookup.metadata = { countAll: true };
|
||||
|
||||
if (lookup.tenantSubQuery && lookup.tenantSubQuery?.codes && lookup.tenantSubQuery?.codes?.length > 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<BaseDescri
|
|||
|
||||
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?.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<BaseDescri
|
|||
_buildFormFromLookup(lookup: DescriptionLookup, referenceFilters: ReferencesWithType[]): UntypedFormGroup {
|
||||
return (new UntypedFormBuilder()).group({
|
||||
status: [lookup.statuses?.length > 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<BaseDescri
|
|||
let count = 0;
|
||||
|
||||
if (lookup.statuses) count += lookup.statuses.length;
|
||||
if (lookup.tenantSubQuery) count += 1;
|
||||
if (lookup.descriptionTemplateSubQuery) count += lookup.descriptionTemplateSubQuery.ids?.length;
|
||||
if (lookup.descriptionTagSubQuery) count += lookup.descriptionTagSubQuery.tagIds?.length;
|
||||
if (lookup.planSubQuery) {
|
||||
|
|
|
@ -4,5 +4,6 @@
|
|||
[filterFormGroup]="data.filterForm"
|
||||
[referencesWithTypeItems]="data.referencesWithTypeItems"
|
||||
[isPublic]="data.isPublic"
|
||||
[hasSelectedTenant]="data.hasSelectedTenant"
|
||||
(filterChanged)="onFilterChanged($event)"
|
||||
></app-description-filter-component>
|
||||
|
|
|
@ -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[],
|
||||
}
|
||||
|
|
|
@ -21,6 +21,14 @@
|
|||
</div>
|
||||
<!-- End of Status 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 Filters -->
|
||||
<div class="col-10">
|
||||
<h6 class="category-title">{{'DESCRIPTION-LISTING.FILTERS.RELATED-DESCRIPTION-TEMPLATES.NAME' | translate}}</h6>
|
||||
|
|
|
@ -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<any> = new EventEmitter();
|
||||
|
|
|
@ -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<Tenant>(x => x.code),
|
||||
]
|
||||
};
|
||||
|
||||
return lookup;
|
||||
}
|
||||
}
|
|
@ -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<Description> = 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<Array<Tenant>> {
|
||||
const params = new BaseHttpParams();
|
||||
params.interceptorContext = {
|
||||
excludedInterceptors: [InterceptorType.TenantHeaderInterceptor]
|
||||
};
|
||||
return this.principalService.myTenants({ params: params });
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue