plan listing > expandable search field, fix search view bug, small code refactor

This commit is contained in:
mchouliara 2024-08-29 14:25:27 +03:00
parent 759cfd9a77
commit 17b6a39c74
6 changed files with 124 additions and 90 deletions

View File

@ -1,6 +1,6 @@
<a class="col-auto d-flex pointer" (click)="onClose()"><span class="ml-auto mt-3 material-icons clear-icon">clear</span></a> <a class="col-auto d-flex pointer" (click)="onClose()"><span class="ml-auto mt-3 material-icons clear-icon">clear</span></a>
<app-plan-filter-component <app-plan-filter-component
[filterFormGroup]="data.filterForm" [filterFormGroup]="formGroup"
[referencesWithTypeItems]="data.referencesWithTypeItems" [referencesWithTypeItems]="data.referencesWithTypeItems"
[isPublic]="data.isPublic" [isPublic]="data.isPublic"
[hasSelectedTenant]="data.hasSelectedTenant" [hasSelectedTenant]="data.hasSelectedTenant"

View File

@ -1,9 +1,10 @@
import { Inject, Component, ViewChild, OnInit } from '@angular/core'; import { Inject, Component, ViewChild, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { UntypedFormGroup } from '@angular/forms'; import { FormGroup, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
import { PlanFilterComponent } from '../plan-filter.component'; import { PlanFilterComponent, PlanListingFilterForm, PlanListingFilters } from '../plan-filter.component';
import { ReferencesWithType } from '@app/core/query/description.lookup'; import { ReferencesWithType } from '@app/core/query/description.lookup';
import { PlanLookup } from '@app/core/query/plan.lookup';
@Component({ @Component({
selector: 'plan-filter-dialog-component', selector: 'plan-filter-dialog-component',
@ -15,20 +16,35 @@ export class PlanFilterDialogComponent implements OnInit {
@ViewChild(PlanFilterComponent, { static: true }) filter: PlanFilterComponent; @ViewChild(PlanFilterComponent, { static: true }) filter: PlanFilterComponent;
formGroup: FormGroup<PlanListingFilterForm>;
constructor( constructor(
public dialogRef: MatDialogRef<PlanFilterDialogComponent>, public dialogRef: MatDialogRef<PlanFilterDialogComponent>,
private analyticsService: AnalyticsService, private analyticsService: AnalyticsService,
@Inject(MAT_DIALOG_DATA) public data: { @Inject(MAT_DIALOG_DATA) public data: {
isPublic: boolean, isPublic: boolean,
hasSelectedTenant: boolean, hasSelectedTenant: boolean,
filterForm: UntypedFormGroup, lookup: PlanLookup,
//filterForm: UntypedFormGroup,
referencesWithTypeItems: ReferencesWithType[], referencesWithTypeItems: ReferencesWithType[],
}) { } }) {
this.formGroup = this._buildFormFromLookup(data?.lookup)
}
ngOnInit() { ngOnInit() {
this.analyticsService.trackPageView(AnalyticsService.PlanFilterDialog); this.analyticsService.trackPageView(AnalyticsService.PlanFilterDialog);
} }
private _buildFormFromLookup(lookup: PlanLookup): FormGroup<PlanListingFilterForm> {
return (new UntypedFormBuilder()).group({
status: [lookup.statuses?.length > 0 ? lookup.statuses[0] : null],
viewOnlyTenant: [lookup.tenantSubQuery?.codes?.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,
});
}
onNoClick(): void { onNoClick(): void {
this.dialogRef.close(); this.dialogRef.close();
} }
@ -38,7 +54,7 @@ export class PlanFilterDialogComponent implements OnInit {
} }
onFilterChanged(formGroup: UntypedFormGroup) { onFilterChanged(formGroup: UntypedFormGroup) {
this.dialogRef.close(formGroup); this.dialogRef.close(formGroup.value as PlanListingFilters);
} }
} }

View File

@ -1,5 +1,5 @@
import { Component, Input, OnInit, Output, EventEmitter, OnChanges, SimpleChanges } from '@angular/core'; import { Component, Input, OnInit, Output, EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
import { AbstractControl, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { AbstractControl, FormArray, FormControl, FormGroup, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { BaseCriteriaComponent } from '@app/ui/misc/criteria/base-criteria.component'; import { BaseCriteriaComponent } from '@app/ui/misc/criteria/base-criteria.component';
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@ -32,7 +32,7 @@ export class PlanFilterComponent extends BaseCriteriaComponent implements OnInit
@Input() isPublic: boolean; @Input() isPublic: boolean;
@Input() hasSelectedTenant: boolean; @Input() hasSelectedTenant: boolean;
@Input() referencesWithTypeItems: ReferencesWithType[]; @Input() referencesWithTypeItems: ReferencesWithType[];
@Input() filterFormGroup: UntypedFormGroup; @Input() filterFormGroup: FormGroup<PlanListingFilterForm>;
@Output() filterChanged: EventEmitter<any> = new EventEmitter(); @Output() filterChanged: EventEmitter<any> = new EventEmitter();
status = PlanStatusEnum; status = PlanStatusEnum;
@ -196,3 +196,21 @@ export class PlanFilterComponent extends BaseCriteriaComponent implements OnInit
}); });
} }
} }
export interface PlanListingFilters {
status: PlanStatusEnum,
viewOnlyTenant: boolean,
descriptionTemplates: Guid[],
planBlueprints: Guid[],
role: Guid,
references: ReferencesWithType[]
}
export interface PlanListingFilterForm {
status: FormControl<PlanStatusEnum>,
viewOnlyTenant: FormControl<boolean>,
descriptionTemplates: FormControl<Guid[]>,
planBlueprints: FormControl<Guid[]>,
role: FormControl<Guid>,
references: FormArray<any>
}

View File

@ -1,7 +1,7 @@
<div class="main-content listing-main-container h-100"> <div class="main-content listing-main-container h-100">
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div *ngIf="hasLoadedListingItems && !hasListingItems && !hasFilters" class="col-12 card mt-0"> <div *ngIf="!isLoading && !hasListingItems && !hasFilters" class="col-12 card mt-0">
<div class="card-content info-text mb-0"> <div class="card-content info-text mb-0">
<p>{{'PLAN-LISTING.TEXT-INFO' | translate}}</p> <p>{{'PLAN-LISTING.TEXT-INFO' | translate}}</p>
<p class="mt-4 pt-2">{{'PLAN-LISTING.TEXT-INFO-QUESTION' | translate}} <a class="zenodo-link" href="https://zenodo.org/communities/liber-plan-cat/?page=1&size=20" target="_blank">{{'PLAN-LISTING.LINK-ZENODO' | translate}}</a> {{'PLAN-LISTING.GET-IDEA' | translate}}</p> <p class="mt-4 pt-2">{{'PLAN-LISTING.TEXT-INFO-QUESTION' | translate}} <a class="zenodo-link" href="https://zenodo.org/communities/liber-plan-cat/?page=1&size=20" target="_blank">{{'PLAN-LISTING.LINK-ZENODO' | translate}}</a> {{'PLAN-LISTING.GET-IDEA' | translate}}</p>
@ -11,18 +11,18 @@
</div> </div>
</div> </div>
</div> </div>
<div *ngIf="hasLoadedListingItems && (hasListingItems || hasFilters)" class="col-12"> <div class="col-12">
<app-navigation-breadcrumb /> <app-navigation-breadcrumb />
</div> </div>
<div *ngIf="!versionsModeEnabled && hasLoadedListingItems && (hasListingItems || hasFilters) && !isPublic" class="filter-btn" [style.right]="dialog.getDialogById('filters') ? '446px' : '0px'" [style.width]="listingItems.length > 2 ? '57px' : '37px'" (click)="openFiltersDialog()"> <div *ngIf="!versionsModeEnabled && !isLoading && (hasListingItems || hasFilters) && !isPublic" 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]="filtersCount === 0" matBadgePosition="before"> <button mat-raised-button class="p-0" [matBadge]="filtersCount" [matBadgeHidden]="filtersCount === 0" matBadgePosition="before">
<mat-icon class="mr-4 filter-icon">filter_alt</mat-icon> <mat-icon class="mr-4 filter-icon">filter_alt</mat-icon>
</button> </button>
</div> </div>
</div> </div>
<div> <div>
<div *ngIf="hasLoadedListingItems" class="listing row pb-2"> <div class="listing row pb-2">
<div *ngIf="hasListingItems || hasFilters" class="col-md-12"> <div class="col-md-12">
<div class="row pt-4"> <div class="row pt-4">
<!-- Sort by --> <!-- Sort by -->
<div class="col-auto d-flex align-items-center order-1"> <div class="col-auto d-flex align-items-center order-1">
@ -50,36 +50,40 @@
<span *ngIf="!isPublic" class="center-content mb-1 mb-xl-4" (click)="restartTour()">{{ 'GENERAL.ACTIONS.TAKE-A-TOUR'| translate }}</span> <span *ngIf="!isPublic" class="center-content mb-1 mb-xl-4" (click)="restartTour()">{{ 'GENERAL.ACTIONS.TAKE-A-TOUR'| translate }}</span>
</div> </div>
<div class="col-12 col-xl-auto"> <div class="col-12 col-xl-auto">
<mat-form-field class="search-form w-100" floatLabel="never"> <app-text-filter [(value)]=lookup.like (valueChange)="controlModified()" />
<!-- <mat-form-field class="search-form w-100" floatLabel="never">
<mat-icon matSuffix>search</mat-icon> <mat-icon matSuffix>search</mat-icon>
<input matInput placeholder="{{'GENERAL.CRITERIA.LIKE'| translate}}" name="likeCriteria" [formControl]="formGroup.get('like')"> <input matInput placeholder="{{'GENERAL.CRITERIA.LIKE'| translate}}" name="likeCriteria" [formControl]="formGroup.get('like')">
<mat-error *ngIf="formGroup.get('like').hasError('backendError')">{{formGroup.get('like').getError('backendError').message}}</mat-error> <mat-error *ngIf="formGroup.get('like').hasError('backendError')">{{formGroup.get('like').getError('backendError').message}}</mat-error>
</mat-form-field> </mat-form-field> -->
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-12 col-sm-12 col-md-9"> @if(!isLoading){
<div *ngFor="let item of listingItems; let i = index"> <div class="col-md-12 col-sm-12 col-md-9">
<app-plan-listing-item-component <div *ngFor="let item of listingItems; let i = index">
[showDivider]="i != (listingItems.length - 1)" <app-plan-listing-item-component
[plan]="item" [showDivider]="i != (listingItems.length - 1)"
[isPublic]="isPublic" [plan]="item"
[tenants]="tenants" [isPublic]="isPublic"
></app-plan-listing-item-component> [tenants]="tenants"
</div> ></app-plan-listing-item-component>
<div *ngIf="hasListingItems && this.lookup?.page?.offset < this.totalCount - 1 && this.pageSize < this.totalCount - 1" class="d-flex justify-content-center"> </div>
<button type="button" class="btn-load-more" (click)="loadMore()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button> <div *ngIf="hasListingItems && this.lookup?.page?.offset < this.totalCount - 1 && this.pageSize < this.totalCount - 1" class="d-flex justify-content-center">
</div> <button type="button" class="btn-load-more" (click)="loadMore()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
</div> </div>
<div *ngIf="!hasListingItems && !hasFilters" class="col-md-12 d-flex justify-content-center pt-4 mt-4 mb-4 pb-4"> </div>
<span class="empty-list">{{'PLAN-LISTING.EMPTY-LIST' | translate}}</span> <div *ngIf="!hasListingItems && !hasFilters" class="col-md-12 d-flex justify-content-center pt-4 mt-4 mb-4 pb-4">
</div> <span class="empty-list">{{'PLAN-LISTING.EMPTY-LIST' | translate}}</span>
<div *ngIf="!hasListingItems && hasFilters" class="col-md-12 d-flex justify-content-center pt-4 mt-4 mb-4 pb-4"> </div>
<span class="empty-list">{{'PLAN-LISTING.FILTERS.NO-ITEMS-FOUND' | translate}}</span> <div *ngIf="!hasListingItems && hasFilters" class="col-md-12 d-flex justify-content-center pt-4 mt-4 mb-4 pb-4">
</div> <span class="empty-list">{{'PLAN-LISTING.FILTERS.NO-ITEMS-FOUND' | translate}}</span>
</div> </div>
}
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,6 +1,6 @@
import { Component, OnInit, ViewChild } from '@angular/core'; import { Component, OnInit, ViewChild } from '@angular/core';
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms'; import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { MatPaginator } from '@angular/material/paginator'; import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort'; import { MatSort } from '@angular/material/sort';
import { ActivatedRoute, Params, Router } from '@angular/router'; import { ActivatedRoute, Params, Router } from '@angular/router';
@ -25,9 +25,8 @@ import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/
import { PageLoadEvent, SortDirection } from '@common/modules/hybrid-listing/hybrid-listing.component'; import { PageLoadEvent, SortDirection } from '@common/modules/hybrid-listing/hybrid-listing.component';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { NgDialogAnimationService } from "ng-dialog-animation"; import { NgDialogAnimationService } from "ng-dialog-animation";
import { debounceTime, takeUntil, tap } from 'rxjs/operators'; import { takeUntil, tap } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof'; import { nameof } from 'ts-simple-nameof';
import { PlanFilterDialogComponent } from './filtering/plan-filter-dialog/plan-filter-dialog.component';
import { BaseListingComponent } from '@common/base/base-listing-component'; import { BaseListingComponent } from '@common/base/base-listing-component';
import { QueryResult } from '@common/model/query-result'; import { QueryResult } from '@common/model/query-result';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
@ -41,7 +40,8 @@ import { BaseHttpParams } from '@common/http/base-http-params';
import { InterceptorType } from '@common/http/interceptors/interceptor-type'; import { InterceptorType } from '@common/http/interceptors/interceptor-type';
import { PrincipalService } from '@app/core/services/http/principal.service'; import { PrincipalService } from '@app/core/services/http/principal.service';
import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service'; import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service';
import { PlanStatusEnum } from '@app/core/common/enum/plan-status'; import { PlanFilterDialogComponent } from './filtering/plan-filter-dialog/plan-filter-dialog.component';
import { PlanListingFilters } from './filtering/plan-filter.component';
@Component({ @Component({
selector: 'app-plan-listing-component', selector: 'app-plan-listing-component',
@ -58,7 +58,7 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
totalCount: number; totalCount: number;
listingItems: any[] = []; listingItems: any[] = [];
isPublic: boolean = false; isPublic: boolean = false;
hasLoadedListingItems: boolean = false; isLoading: boolean;
protected ITEMS_PER_PAGE = 5; protected ITEMS_PER_PAGE = 5;
pageSize: number = 5; pageSize: number = 5;
filtersCount: number; filtersCount: number;
@ -168,9 +168,9 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
}); });
} }
this.formGroup.get('like').valueChanges // this.formGroup.get('like').valueChanges
.pipe(takeUntil(this._destroyed), debounceTime(500)) // .pipe(takeUntil(this._destroyed), debounceTime(500))
.subscribe(x => this.controlModified()); // .subscribe(x => this.controlModified());
} }
public dashboardTour: GuidedTour = { public dashboardTour: GuidedTour = {
@ -201,10 +201,13 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
this.scrollbar = this.hasScrollbar(); this.scrollbar = this.hasScrollbar();
} }
protected loadListing(): Observable<QueryResult<BasePlan>> { protected loadListing(): Observable<QueryResult<BasePlan>> {
this.isLoading = true;
if (this.isPublic) { if (this.isPublic) {
return this.planService.publicQuery(this.lookup).pipe(takeUntil(this._destroyed)) return this.planService.publicQuery(this.lookup).pipe(takeUntil(this._destroyed))
.pipe(tap(result => { .pipe(tap(result => {
this.isLoading = false;
if (this.versionsModeEnabled) { if (this.versionsModeEnabled) {
const latestVersionPlan: BasePlan = this._getLatestVersion(result.items); const latestVersionPlan: BasePlan = this._getLatestVersion(result.items);
this.breadcrumbService.addIdResolvedValue(this.groupId.toString(), latestVersionPlan.label); this.breadcrumbService.addIdResolvedValue(this.groupId.toString(), latestVersionPlan.label);
@ -214,11 +217,11 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
this.totalCount = result.count; this.totalCount = result.count;
if (this.lookup?.page?.offset === 0) this.listingItems = []; if (this.lookup?.page?.offset === 0) this.listingItems = [];
this.listingItems.push(...result.items); this.listingItems.push(...result.items);
this.hasLoadedListingItems = true;
})); }));
} else { } else {
return this.planService.query(this.lookup).pipe(takeUntil(this._destroyed)) return this.planService.query(this.lookup).pipe(takeUntil(this._destroyed))
.pipe(tap(result => { .pipe(tap(result => {
this.isLoading = false;
if (this.versionsModeEnabled) { if (this.versionsModeEnabled) {
const latestVersionPlan: BasePlan = this._getLatestVersion(result.items); const latestVersionPlan: BasePlan = this._getLatestVersion(result.items);
this.breadcrumbService.addIdResolvedValue(this.groupId.toString(), latestVersionPlan.label); this.breadcrumbService.addIdResolvedValue(this.groupId.toString(), latestVersionPlan.label);
@ -229,7 +232,6 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
if (this.lookup?.page?.offset === 0) this.listingItems = []; if (this.lookup?.page?.offset === 0) this.listingItems = [];
const plans = this._filterPlan([...result.items]); const plans = this._filterPlan([...result.items]);
this.listingItems.push(...plans); this.listingItems.push(...plans);
this.hasLoadedListingItems = true;
})); }));
} }
} }
@ -298,13 +300,13 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
} }
controlModified(): void { controlModified(): void {
this.lookup.like = this.formGroup.get("like").value != '' ? this.formGroup.get('like').value : null; //this.lookup.like = this.lookup.like != '' ? this.lookup.like : null;
this.lookup.page = { size: this.pageSize, offset: 0 }; this.lookup.page = { size: this.pageSize, offset: 0 };
this.filterChanged(this.lookup, true); this.filterChanged(this.lookup, true);
} }
openFiltersDialog(): void { openFiltersDialog(): void {
let dialogRef = this.dialog.open(PlanFilterDialogComponent, { let dialogRef: MatDialogRef<PlanFilterDialogComponent, PlanListingFilters> = this.dialog.open(PlanFilterDialogComponent, {
width: '456px', width: '456px',
height: '100%', height: '100%',
id: 'filters', id: 'filters',
@ -314,7 +316,8 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
data: { data: {
isPublic: this.isPublic ?? true, isPublic: this.isPublic ?? true,
hasSelectedTenant: this.authService.selectedTenant() != 'default', hasSelectedTenant: this.authService.selectedTenant() != 'default',
filterForm: this._buildFormFromLookup(this.lookup), lookup: this.lookup,
//filterForm: this._buildFormFromLookup(this.lookup),
referencesWithTypeItems: this.referenceFilters ?? [], referencesWithTypeItems: this.referenceFilters ?? [],
} }
}); });
@ -326,11 +329,11 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
}); });
} }
updateDataFn(filterForm: UntypedFormGroup): void { updateDataFn(filters: PlanListingFilters): void {
this.referenceFilters = this._patchReferenceFiltersFromForm(filterForm); this.referenceFilters = this._patchReferenceFilters(filters);
this.lookup = this._patchLookupFromForm(this.lookup, filterForm); this._patchLookupFromFilters(filters);
this.filtersCount = this._countFilters(this.lookup); this.filtersCount = this._countFilters(this.lookup);
this.hasLoadedListingItems = false; this.isLoading = false;
this.filterChanged(this.lookup) this.filterChanged(this.lookup)
} }
@ -410,71 +413,62 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
} }
} }
private _patchLookupFromForm(lookup: PlanLookup, formGroup: UntypedFormGroup): PlanLookup { private _patchLookupFromFilters(filters: PlanListingFilters): PlanLookup {
if (!formGroup) return; if (!filters) return;
lookup.statuses = formGroup.get("status")?.value !== null ? [formGroup.get("status")?.value] : null; this.lookup.statuses = filters.status !== null ? [filters.status] : [];
// Tenants // Tenants
let viewOnlyTenant = formGroup.get("viewOnlyTenant")?.value ?? false; let viewOnlyTenant = filters.viewOnlyTenant ?? false;
if (viewOnlyTenant) { if (viewOnlyTenant) {
let tenant = this.tenants?.find(t => t.code && t.code?.toString() == this.authService.selectedTenant()); let tenant = this.tenants?.find(t => t.code && t.code?.toString() == this.authService.selectedTenant());
if (tenant && tenant?.code) { if (tenant && tenant?.code) {
lookup.tenantSubQuery = PlanFilterService.initializeTenantLookup(); this.lookup.tenantSubQuery = PlanFilterService.initializeTenantLookup();
lookup.tenantSubQuery.codes = [tenant.code] this.lookup.tenantSubQuery.codes = [tenant.code]
} }
else lookup.tenantSubQuery = null; else this.lookup.tenantSubQuery = null;
} else lookup.tenantSubQuery = null; } else this.lookup.tenantSubQuery = null;
// Description Templates // Description Templates
let descriptionTemplates = formGroup.get("descriptionTemplates")?.value ?? null; let descriptionTemplates = filters.descriptionTemplates ?? null;
if (descriptionTemplates && descriptionTemplates?.length > 0) { if (descriptionTemplates && descriptionTemplates?.length > 0) {
lookup.planDescriptionTemplateSubQuery = PlanFilterService.initializePlanDescriptionTemplateLookup(); this.lookup.planDescriptionTemplateSubQuery = PlanFilterService.initializePlanDescriptionTemplateLookup();
lookup.planDescriptionTemplateSubQuery.descriptionTemplateGroupIds = descriptionTemplates; this.lookup.planDescriptionTemplateSubQuery.descriptionTemplateGroupIds = descriptionTemplates;
} else lookup.planDescriptionTemplateSubQuery = null; } else this.lookup.planDescriptionTemplateSubQuery = null;
// Blueprints // Blueprints
let planBlueprints = formGroup.get("planBlueprints")?.value ?? null; let planBlueprints = filters.planBlueprints ?? null;
if (planBlueprints && planBlueprints?.length > 0) { if (planBlueprints && planBlueprints?.length > 0) {
lookup.planBlueprintSubQuery = PlanFilterService.initializePlanBlueprintLookup(); this.lookup.planBlueprintSubQuery = PlanFilterService.initializePlanBlueprintLookup();
lookup.planBlueprintSubQuery.ids = planBlueprints; this.lookup.planBlueprintSubQuery.ids = planBlueprints;
} else lookup.planBlueprintSubQuery = null; } else this.lookup.planBlueprintSubQuery = null;
// plans // plans
let roles = formGroup.get("role")?.value !== null ? [formGroup.get("role")?.value] : null; let roles = filters.role !== null ? [filters.role] : null;
if (roles && roles?.length > 0) { if (roles && roles?.length > 0) {
lookup.planUserSubQuery = PlanFilterService.initializePlanUserLookup(); this.lookup.planUserSubQuery = PlanFilterService.initializePlanUserLookup();
lookup.planUserSubQuery.userRoles = roles; this.lookup.planUserSubQuery.userRoles = roles;
} else lookup.planUserSubQuery = null; } else this.lookup.planUserSubQuery = null;
let references: Guid[] = formGroup.get("references")?.value let references: Guid[] = filters.references
?.filter((reference: ReferencesWithType) => reference.referenceTypeId != null && reference.referenceIds?.length > 0) ?.filter((reference: ReferencesWithType) => reference.referenceTypeId != null && reference.referenceIds?.length > 0)
?.flatMap((referencesWithType: ReferencesWithType) => referencesWithType.referenceIds) as Guid[]; ?.flatMap((referencesWithType: ReferencesWithType) => referencesWithType.referenceIds) as Guid[];
if (references && references?.length > 0) { if (references && references?.length > 0) {
lookup.planReferenceSubQuery = PlanFilterService.initializePlanReferenceLookup(); this.lookup.planReferenceSubQuery = PlanFilterService.initializePlanReferenceLookup();
lookup.planReferenceSubQuery.referenceIds = references; this.lookup.planReferenceSubQuery.referenceIds = references;
} else lookup.planReferenceSubQuery = null; } else this.lookup.planReferenceSubQuery = null;
return lookup; return this.lookup;
} }
_patchReferenceFiltersFromForm(formGroup: UntypedFormGroup): ReferencesWithType[] { _patchReferenceFilters(filters: PlanListingFilters): ReferencesWithType[] {
return formGroup?.get("references")?.value?.filter(( referencesWithType: ReferencesWithType ) => referencesWithType != null && referencesWithType.referenceIds?.length > 0) ?? null; return filters?.references?.filter(( referencesWithType: ReferencesWithType ) => referencesWithType != null && referencesWithType.referenceIds?.length > 0) ?? null;
} }
private _buildFormFromLookup(lookup: PlanLookup): UntypedFormGroup {
return (new UntypedFormBuilder()).group({
like: lookup.like ?? null,
status: [lookup.statuses?.length > 0 ? lookup.statuses[0] : null],
viewOnlyTenant: [lookup.tenantSubQuery?.codes?.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,
});
}
private _countFilters(lookup: PlanLookup): number { private _countFilters(lookup: PlanLookup): number {
let count = 0; let count = 0;

View File

@ -12,6 +12,7 @@ import { ClonePlanDialogModule } from '../clone-dialog/plan-clone-dialog.module'
import { PlanListingComponent } from './plan-listing.component'; import { PlanListingComponent } from './plan-listing.component';
import { PlanListingItemComponent } from './listing-item/plan-listing-item.component'; import { PlanListingItemComponent } from './listing-item/plan-listing-item.component';
import { PlanListingRoutingModule } from './plan-listing.routing'; import { PlanListingRoutingModule } from './plan-listing.routing';
import { TextFilterModule } from '@common/modules/text-filter/text-filter.module';
@NgModule({ @NgModule({
imports: [ imports: [
@ -22,7 +23,8 @@ import { PlanListingRoutingModule } from './plan-listing.routing';
ClonePlanDialogModule, ClonePlanDialogModule,
NewVersionPlanDialogModule, NewVersionPlanDialogModule,
PlanInvitationDialogModule, PlanInvitationDialogModule,
PlanListingRoutingModule PlanListingRoutingModule,
TextFilterModule
], ],
declarations: [ declarations: [
PlanListingComponent, PlanListingComponent,