-
+

{{'DESCRIPTION-LISTING.TEXT-INFO' | translate}} {{'DESCRIPTION-LISTING.LINK-PUBLIC-DESCRIPTIONS' | translate}} {{'DESCRIPTION-LISTING.TEXT-INFO-REST' | translate}}

{{'DESCRIPTION-LISTING.TEXT-INFO-PAR' | translate}} @@ -13,29 +13,25 @@

-
-
-
- -
-
+
+
-
+
-
-
-
+
@@ -44,11 +40,11 @@
- - {{enumUtils.toRecentActivityOrderString(order.UpdatedAt)}} - {{enumUtils.toRecentActivityOrderString(order.PublishedAt)}} - {{enumUtils.toRecentActivityOrderString(order.Label)}} - {{enumUtils.toRecentActivityOrderString(order.Status)}} + + {{enumUtils.toRecentActivityOrderString(RecentActivityOrder.UpdatedAt)}} + {{enumUtils.toRecentActivityOrderString(RecentActivityOrder.PublishedAt)}} + {{enumUtils.toRecentActivityOrderString(RecentActivityOrder.Label)}} + {{enumUtils.toRecentActivityOrderString(RecentActivityOrder.Status)}}
@@ -63,38 +59,36 @@
- {{ 'DESCRIPTION-LISTING.ACTIONS.TAKE-A-TOUR'| translate }} + {{ 'DESCRIPTION-LISTING.ACTIONS.TAKE-A-TOUR'| translate }}
- - search - - {{formGroup.get('like').getError('backendError').message}} - +
-
-
- + @if(!isLoading) { +
+
+ +
+
+ +
-
- +
+ {{'DESCRIPTION-LISTING.EMPTY-LIST' | translate}}
-
-
- {{'DESCRIPTION-LISTING.EMPTY-LIST' | translate}} -
+ }
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 434e5f530..e36fc0789 100644 --- a/frontend/src/app/ui/description/listing/description-listing.component.ts +++ b/frontend/src/app/ui/description/listing/description-listing.component.ts @@ -1,6 +1,6 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { FormBuilder, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms'; -import { MatDialog } from '@angular/material/dialog'; +import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { MatPaginator } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; import { ActivatedRoute, Params, Router } from '@angular/router'; @@ -41,6 +41,8 @@ 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'; +import { DescriptionListingFilters } from './filtering/description-filter.component'; +import { MatSelectChange } from '@angular/material/select'; @Component({ selector: 'app-description-listing-component', @@ -60,7 +62,7 @@ export class DescriptionListingComponent extends BaseListingComponent 0) { - - let ordering = this.lookup.order.items[0]; - let sortBy = ordering.substring(1, ordering.length); - - this.formGroup.get('order').setValue(this._getRecentActivityOrder(sortBy)); - ordering.charAt(0) == '-' ? this.sortDirection = SortDirection.Descending : this.sortDirection = SortDirection.Ascending; - } - + this.sortBy = this._getRecentActivityOrder(this.lookup.order.items[0]?.substring(1)); this.onPageLoad({ offset: this.lookup.page.offset / this.lookup.page.size } as PageLoadEvent); }); @@ -168,10 +154,6 @@ export class DescriptionListingComponent extends BaseListingComponent this.controlModified()); } ngAfterContentChecked(): void { @@ -179,23 +161,24 @@ export class DescriptionListingComponent extends BaseListingComponent> { + this.isLoading = true; if (this.isPublic) { return this.descriptionService.publicQuery(this.lookup).pipe(takeUntil(this._destroyed)) .pipe(tap(result => { + this.isLoading = false; if (!result) { return []; } this.totalCount = result.count; if (this.lookup?.page?.offset === 0) this.listingItems = []; this.listingItems.push(...result.items); - this.hasLoadedListingItems = true; })); } else { return this.descriptionService.query(this.lookup).pipe(takeUntil(this._destroyed)) .pipe(tap(result => { + this.isLoading = false; if (!result) { return []; } this.totalCount = result.count; if (this.lookup?.page?.offset === 0) this.listingItems = []; this.listingItems.push(...result.items); - this.hasLoadedListingItems = true; })); } } @@ -245,7 +228,6 @@ export class DescriptionListingComponent extends BaseListingComponent(x => x.status)] }; - } else if (this.formGroup.get('order').value == RecentActivityOrder.Label) { - this.lookup.order = { items: [this.sortingDirectionPrefix + nameof(x => x.label)] }; - } else if (this.formGroup.get('order').value == RecentActivityOrder.PublishedAt) { - this.lookup.order = { items: [this.sortingDirectionPrefix + nameof(x => x.finalizedAt)] }; - }else { - this.lookup.order = { items: [this.sortingDirectionPrefix + nameof(x => x.updatedAt)] }; - } + orderByChanged($event: MatSelectChange) { + const value = $event.value as RecentActivityOrder; + const directionPrefix = this.isAscending ? '-' : '+'; + + switch (value) { + case RecentActivityOrder.Status: { + this.lookup.order = { items: [directionPrefix + nameof(x => x.status)] }; + break; + } + case RecentActivityOrder.Label: { + this.lookup.order = { items: [directionPrefix + nameof(x => x.label)] }; + break; + } + case RecentActivityOrder.PublishedAt: { + this.lookup.order = { items: [directionPrefix + nameof(x => x.finalizedAt)] }; + break; + } + default: { + this.lookup.order = { items: [directionPrefix + nameof(x => x.updatedAt)] }; + break; + } + }; + this.filterChanged(this.lookup); } openFiltersDialog(): void { - const dialogRef = this.dialog.open(DescriptionFilterDialogComponent, { + const dialogRef: MatDialogRef = this.dialog.open(DescriptionFilterDialogComponent, { width: '456px', height: '100%', id: 'filters', @@ -280,7 +275,7 @@ export class DescriptionListingComponent extends BaseListingComponent(x => x.updatedAt); + const sortDirection = this.isAscending ? '+' : '-'; + this.lookup.order.items = [`${sortDirection}${orderBy}`]; + this.filterChanged(this.lookup); } @@ -385,6 +381,7 @@ 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] + this.lookup.tenantSubQuery = DescriptionFilterService.initializeTenantLookup(); + this.lookup.tenantSubQuery.codes = [tenant.code] } - else lookup.tenantSubQuery = null; - } else lookup.tenantSubQuery = null; + else this.lookup.tenantSubQuery = null; + } else this.lookup.tenantSubQuery = null; // Description Templates - let descriptionTemplates = formGroup.get("descriptionTemplates")?.value ?? null; + let descriptionTemplates = filters.descriptionTemplates ?? null; if (descriptionTemplates && descriptionTemplates?.length > 0) { - lookup.descriptionTemplateSubQuery = DescriptionFilterService.initializeDescriptionTemplateLookup(); - lookup.descriptionTemplateSubQuery.ids = descriptionTemplates; - } else lookup.descriptionTemplateSubQuery = null; + this.lookup.descriptionTemplateSubQuery = DescriptionFilterService.initializeDescriptionTemplateLookup(); + this.lookup.descriptionTemplateSubQuery.ids = descriptionTemplates; + } else this.lookup.descriptionTemplateSubQuery = null; // Plans - let plans = formGroup.get("associatedPlanIds")?.value ?? null; let addPlans = plans && plans?.length > 0; - let roles = formGroup.get("role")?.value !== null ? [formGroup.get("role")?.value] : null; let addRoles = roles && roles?.length > 0; + let plans = filters.associatedPlanIds ?? null; let addPlans = plans && plans?.length > 0; + let roles = filters.role !== null ? [filters.role] : null; let addRoles = roles && roles?.length > 0; if (addPlans || addRoles) { - lookup.planSubQuery = DescriptionFilterService.initializePlanLookup(); + this.lookup.planSubQuery = DescriptionFilterService.initializePlanLookup(); - if (addPlans) lookup.planSubQuery.ids = plans?.length > 0 ? plans : null; + if (addPlans) this.lookup.planSubQuery.ids = plans?.length > 0 ? plans : null; if (addRoles) { - lookup.planSubQuery.planUserSubQuery = DescriptionFilterService.initializePlanUserLookup(); - lookup.planSubQuery.planUserSubQuery.userRoles = roles; + this.lookup.planSubQuery.planUserSubQuery = DescriptionFilterService.initializePlanUserLookup(); + this.lookup.planSubQuery.planUserSubQuery.userRoles = roles; } - } else lookup.planSubQuery = null; + } else this.lookup.planSubQuery = null; // Tags - let tags = formGroup.get("tags")?.value ?? null; + let tags = filters.tags ?? null; if (tags && tags?.length > 0) { - lookup.descriptionTagSubQuery = DescriptionFilterService.initializeTagLookup(); - lookup.descriptionTagSubQuery.tagIds = tags; - } else lookup.descriptionTagSubQuery = null; + this.lookup.descriptionTagSubQuery = DescriptionFilterService.initializeTagLookup(); + this.lookup.descriptionTagSubQuery.tagIds = tags; + } else this.lookup.descriptionTagSubQuery = null; // References - let references: Guid[] = formGroup.get("references")?.value + let references: Guid[] = filters.references ?.filter((reference: ReferencesWithType) => reference.referenceTypeId != null && reference.referenceIds?.length > 0) ?.flatMap((referencesWithType: ReferencesWithType) => referencesWithType.referenceIds) as Guid[]; if (references && references?.length > 0) { - lookup.descriptionReferenceSubQuery = DescriptionFilterService.initializeReferenceLookup(); - lookup.descriptionReferenceSubQuery.referenceIds = references; - } else lookup.descriptionReferenceSubQuery = null; + this.lookup.descriptionReferenceSubQuery = DescriptionFilterService.initializeReferenceLookup(); + this.lookup.descriptionReferenceSubQuery.referenceIds = references; + } else this.lookup.descriptionReferenceSubQuery = null; - return lookup; + return this.lookup; } - _patchReferenceFiltersFromForm(formGroup: UntypedFormGroup): ReferencesWithType[] { - return formGroup?.get("references")?.value?.filter(( referencesWithType: ReferencesWithType ) => referencesWithType.referenceTypeId != null && referencesWithType.referenceIds?.length > 0) ?? null; - } - - _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] : [], - tags: lookup.descriptionTagSubQuery?.tagIds ? [lookup.descriptionTagSubQuery?.tagIds] : [], - }); + _patchReferenceFilters(filters: DescriptionListingFilters): ReferencesWithType[] { + return filters.references?.filter(( referencesWithType: ReferencesWithType ) => referencesWithType.referenceTypeId != null && referencesWithType.referenceIds?.length > 0) ?? null; } private _countFilters(lookup: DescriptionLookup): number { diff --git a/frontend/src/app/ui/description/listing/description-listing.module.ts b/frontend/src/app/ui/description/listing/description-listing.module.ts index de260cf3f..6a574be9b 100644 --- a/frontend/src/app/ui/description/listing/description-listing.module.ts +++ b/frontend/src/app/ui/description/listing/description-listing.module.ts @@ -11,6 +11,7 @@ import { DescriptionFilterDialogComponent } from './filtering/description-filter import { DescriptionFilterComponent } from './filtering/description-filter.component'; import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module'; import { DescriptionFilterService } from './filtering/description-filter.service'; +import { TextFilterModule } from '@common/modules/text-filter/text-filter.module'; @NgModule({ imports: [ @@ -21,6 +22,7 @@ import { DescriptionFilterService } from './filtering/description-filter.service StartNewDescriptionDialogModule, DescriptionListingRoutingModule, AutoCompleteModule, + TextFilterModule, ], declarations: [ DescriptionListingComponent, diff --git a/frontend/src/app/ui/description/listing/filtering/description-filter-dialogue/description-filter-dialog.component.html b/frontend/src/app/ui/description/listing/filtering/description-filter-dialogue/description-filter-dialog.component.html index e555aad9c..cd9acab2f 100644 --- a/frontend/src/app/ui/description/listing/filtering/description-filter-dialogue/description-filter-dialog.component.html +++ b/frontend/src/app/ui/description/listing/filtering/description-filter-dialogue/description-filter-dialog.component.html @@ -1,7 +1,7 @@ clear ; + constructor( public dialogRef: MatDialogRef, private analyticsService: AnalyticsService, @Inject(MAT_DIALOG_DATA) public data: { isPublic: boolean, hasSelectedTenant: boolean, - filterForm: UntypedFormGroup, + lookup: DescriptionLookup, referencesWithTypeItems: ReferencesWithType[], } - ) { } + ) { + this.formGroup = this._buildFormFromLookup(data?.lookup); + } ngOnInit() { this.analyticsService.trackPageView(AnalyticsService.DescriptionFilterDialog); @@ -39,6 +43,17 @@ export class DescriptionFilterDialogComponent implements OnInit { } onFilterChanged(formGroup: UntypedFormGroup) { - this.dialogRef.close(formGroup); + this.dialogRef.close(formGroup.value as DescriptionListingFilters); + } + + private _buildFormFromLookup(lookup: DescriptionLookup): FormGroup { + 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] : [], + tags: lookup.descriptionTagSubQuery?.tagIds ? [lookup.descriptionTagSubQuery?.tagIds] : [], + }); } } 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 990606715..b738f5911 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 @@ -1,6 +1,6 @@ import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; -import { AbstractControl, FormBuilder, UntypedFormArray, UntypedFormGroup } from '@angular/forms'; +import { AbstractControl, FormArray, FormBuilder, FormControl, UntypedFormArray, UntypedFormGroup } from '@angular/forms'; import { DescriptionStatusEnum } from '@app/core/common/enum/description-status'; import { PlanUserRole } from '@app/core/common/enum/plan-user-role'; import { ReferenceType } from '@app/core/model/reference-type/reference-type'; @@ -200,3 +200,23 @@ export class DescriptionFilterComponent extends BaseCriteriaComponent implements }); } } + +export interface DescriptionListingFilters { + status: DescriptionStatusEnum, + viewOnlyTenant: boolean, + role: Guid, + descriptionTemplates: Guid[], + associatedPlanIds: Guid[], + tags: Guid[], + references: ReferencesWithType[] +} + +export interface DescriptionListingFilterForm { + status: FormControl, + viewOnlyTenant: FormControl, + role: FormControl, + descriptionTemplates: FormControl, + associatedPlanIds: FormControl, + tags: FormControl, + references: FormArray +} diff --git a/frontend/src/app/ui/plan/listing/filtering/plan-filter-dialog/plan-filter-dialog.component.ts b/frontend/src/app/ui/plan/listing/filtering/plan-filter-dialog/plan-filter-dialog.component.ts index 3a4c93421..8c49ee7ee 100644 --- a/frontend/src/app/ui/plan/listing/filtering/plan-filter-dialog/plan-filter-dialog.component.ts +++ b/frontend/src/app/ui/plan/listing/filtering/plan-filter-dialog/plan-filter-dialog.component.ts @@ -25,7 +25,6 @@ export class PlanFilterDialogComponent implements OnInit { isPublic: boolean, hasSelectedTenant: boolean, lookup: PlanLookup, - //filterForm: UntypedFormGroup, referencesWithTypeItems: ReferencesWithType[], }) { this.formGroup = this._buildFormFromLookup(data?.lookup) diff --git a/frontend/src/app/ui/plan/listing/filtering/plan-filter.component.ts b/frontend/src/app/ui/plan/listing/filtering/plan-filter.component.ts index d57555bb7..e1b551503 100644 --- a/frontend/src/app/ui/plan/listing/filtering/plan-filter.component.ts +++ b/frontend/src/app/ui/plan/listing/filtering/plan-filter.component.ts @@ -202,7 +202,7 @@ export interface PlanListingFilters { viewOnlyTenant: boolean, descriptionTemplates: Guid[], planBlueprints: Guid[], - role: Guid, + role: Guid, references: ReferencesWithType[] }