diff --git a/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search-base.component.spec.ts b/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search-base.component.spec.ts
index e40457f077..8d650644f9 100644
--- a/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search-base.component.spec.ts
+++ b/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search-base.component.spec.ts
@@ -183,4 +183,26 @@ describe('PoPageDynamicSearchBaseComponent:', () => {
expect(component.advancedFilterLiterals).toEqual(expectedValue);
});
});
+
+ describe('p-visible-fixed-filters:', () => {
+ it('should update `_visibleFixedFilters` when `visibleFixedFilters` is set', () => {
+ component.visibleFixedFilters = true;
+ expect(component['_visibleFixedFilters']).toBe(true);
+
+ component.visibleFixedFilters = false;
+ expect(component['_visibleFixedFilters']).toBe(false);
+ });
+
+ it('should return `_visibleFixedFilters` when `visibleFixedFilters` is accessed', () => {
+ component['_visibleFixedFilters'] = true;
+ expect(component.visibleFixedFilters).toBe(true);
+
+ component['_visibleFixedFilters'] = false;
+ expect(component.visibleFixedFilters).toBe(false);
+ });
+
+ it('should have a default value of `true` for `visibleFixedFilters` if not set', () => {
+ expect(component.visibleFixedFilters).toBeTrue();
+ });
+ });
});
diff --git a/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search-base.component.ts b/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search-base.component.ts
index 6c03109119..8da5688e4e 100644
--- a/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search-base.component.ts
+++ b/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search-base.component.ts
@@ -154,6 +154,34 @@ export abstract class PoPageDynamicSearchBaseComponent {
*/
@Input('p-quick-search-value') quickSearchValue: string;
+ _visibleFixedFilters = true;
+
+ /**
+ * @optional
+ *
+ * @description
+ *
+ * Controla a visibilidade dos filtros fixos na página.
+ *
+ * - Quando `true` (default), todos os filtros, incluindo os fixos, são exibidos, permitindo que o usuário visualize os filtros aplicados.
+ * - Quando `false`, os filtros fixos são ocultados, não sendo exibidos na interface, mas ainda sendo aplicados como filtros nas requisições.
+ *
+ * Esta propriedade trabalha em conjunto com a propriedade `fixed` dos filtros individuais. Filtros marcados como `fixed: true` não serão exibidos na interface do filtro avançado quando `visibleFixedFilters` for `false`, mas continuarão a ser aplicados de forma transparente ao usuário. Dessa forma, permite-se maior flexibilidade no controle de quais filtros devem ser visíveis ao usuário ou devem ser aplicados permanentemente sem interferência.
+ *
+ * **Exemplo de uso:**
+ * ```html
+ *
+ *
+ * ```
+ */
+ @Input('p-visible-fixed-filters') set visibleFixedFilters(visible: boolean) {
+ this._visibleFixedFilters = visible;
+ }
+
+ get visibleFixedFilters(): boolean {
+ return this._visibleFixedFilters;
+ }
+
/**
* @optional
*
@@ -189,10 +217,10 @@ export abstract class PoPageDynamicSearchBaseComponent {
private _hideCloseDisclaimers: Array = [];
private _literals: PoPageDynamicSearchLiterals;
private _quickSearchWidth: number;
-
- private previousFilters: Array;
private language: string;
+ previousFilters: Array;
+
/**
* @optional
*
@@ -258,12 +286,6 @@ export abstract class PoPageDynamicSearchBaseComponent {
*/
@Input('p-filters') set filters(filters: Array) {
this._filters = Array.isArray(filters) ? [...filters] : [];
-
- if (this.stringify(this._filters) !== this.stringify(this.previousFilters)) {
- this.onChangeFilters(this.filters);
-
- this.previousFilters = [...this._filters];
- }
}
get filters(): Array {
@@ -320,7 +342,7 @@ export abstract class PoPageDynamicSearchBaseComponent {
};
}
- private stringify(columns: Array) {
+ stringify(columns: Array) {
// não faz o stringify da propriedade searchService, pois pode conter objeto complexo e disparar um erro.
return JSON.stringify(columns, (key, value) => {
if (key !== 'searchService') {
diff --git a/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search-filters.interface.ts b/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search-filters.interface.ts
index 8b7bc0dd15..e825ff9e14 100644
--- a/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search-filters.interface.ts
+++ b/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search-filters.interface.ts
@@ -12,4 +12,9 @@ export interface PoPageDynamicSearchFilters extends PoDynamicFormField {
* Define um valor inicial para um filtro de busca avançada.
*/
initValue?: any;
+
+ /**
+ * Define um valor fixed para um filtro de busca avançada.
+ */
+ fixed?: boolean;
}
diff --git a/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search.component.spec.ts b/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search.component.spec.ts
index a93c5d5b5b..89ef14fff9 100644
--- a/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search.component.spec.ts
+++ b/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search.component.spec.ts
@@ -3,7 +3,7 @@ import { FormsModule } from '@angular/forms';
import { RouterTestingModule } from '@angular/router/testing';
import { Routes } from '@angular/router';
import { TitleCasePipe } from '@angular/common';
-import { NO_ERRORS_SCHEMA } from '@angular/core';
+import { NO_ERRORS_SCHEMA, SimpleChanges } from '@angular/core';
import { PoDynamicFieldType, PoDynamicModule } from '@po-ui/ng-components';
@@ -218,17 +218,51 @@ describe('PoPageDynamicSearchComponent:', () => {
const filter = { property: 'value1' };
const optionsService = undefined;
+ const visibleFilters =
+ component.visibleFixedFilters === false
+ ? component.filters.filter(filter => !('fixed' in filter) || !filter.fixed)
+ : component.filters;
+
spyOn(component, 'setDisclaimers');
spyOn(component.advancedSearch, 'emit');
spyOn(component, 'setFilters');
component.onAdvancedSearch({ filter, optionsService });
- expect(component['setDisclaimers']).toHaveBeenCalledWith(filter, optionsService);
+ expect(component['setDisclaimers']).toHaveBeenCalledWith(filter, optionsService, visibleFilters);
expect(component['setFilters']).toHaveBeenCalledBefore(component.advancedSearch.emit);
expect(component.advancedSearch.emit).toHaveBeenCalledWith(filter);
});
+ it('onAdvancedSearch: should correctly filter out fixed filters when visibleFixedFilters is false', () => {
+ component.visibleFixedFilters = false;
+ component.filters = [
+ { property: 'city', fixed: true, initValue: 'Toronto' },
+ { property: 'name', fixed: false, initValue: 'John Doe' },
+ { property: 'country', initValue: 'Canada' }
+ ];
+
+ const filteredItems = { filter: { city: 'Toronto' }, optionsService: undefined };
+
+ const setDisclaimersSpy = spyOn(component as any, 'setDisclaimers').and.callThrough();
+ spyOn(component, 'setFilters').and.callThrough();
+ spyOn(component.advancedSearch, 'emit');
+
+ component.onAdvancedSearch(filteredItems);
+
+ const actualVisibleFilters = setDisclaimersSpy.calls.mostRecent().args[2] as Array;
+
+ expect(actualVisibleFilters.length).toBe(2);
+ expect(actualVisibleFilters).toEqual(
+ jasmine.arrayContaining([
+ jasmine.objectContaining({ property: 'name', fixed: false }),
+ jasmine.objectContaining({ property: 'country' })
+ ])
+ );
+ expect(component['setFilters']).toHaveBeenCalledWith(filteredItems.filter);
+ expect(component.advancedSearch.emit).toHaveBeenCalledWith(filteredItems.filter);
+ });
+
it(`setFilters: should call 'convertToFilters'`, () => {
const filters = [{ property: 'value1' }];
@@ -340,9 +374,103 @@ describe('PoPageDynamicSearchComponent:', () => {
expect(component.changeDisclaimers.emit).toHaveBeenCalledWith(currentDisclaimers);
});
- it(`onRemoveAllDisclaimers: should call 'changeDisclaimers.emit' if all disclaimers are removed`, () => {
+ it(`onRemoveDisclaimer: should include fixed filters from 'this.filters' into currentDisclaimers`, () => {
+ component.filters = [
+ { property: 'status', fixed: true, initValue: 'Active', label: 'Status' },
+ { property: 'category', fixed: true, initValue: 'Finance', label: 'Category' },
+ { property: 'name', fixed: false, initValue: 'Test', label: 'Name' }
+ ];
+ const currentDisclaimers = [{ property: 'name', label: 'Name: Test', value: 'Test', hideClose: false }];
+ const removedDisclaimer = { property: 'name', label: 'Name: Test', value: 'Test', hideClose: false };
+
+ const expectedDisclaimers = [
+ { property: 'name', label: 'Name: Test', value: 'Test', hideClose: false },
+ { property: 'status', label: 'Status: Active', value: 'Active', hideClose: true },
+ { property: 'category', label: 'Category: Finance', value: 'Finance', hideClose: true }
+ ];
+
+ spyOn(component.changeDisclaimers, 'emit');
+
+ component['onRemoveDisclaimer']({ removedDisclaimer, currentDisclaimers });
+
+ expect(component.changeDisclaimers.emit).toHaveBeenCalledWith(expectedDisclaimers);
+ });
+
+ it(`onRemoveDisclaimer: should not duplicate fixed filters already present in currentDisclaimers`, () => {
+ component.filters = [
+ { property: 'status', fixed: true, initValue: 'Active', label: 'Status' },
+ { property: 'category', fixed: true, initValue: 'Finance', label: 'Category' }
+ ];
+ const currentDisclaimers = [{ property: 'status', label: 'Status: Active', value: 'Active', hideClose: true }];
+ const removedDisclaimer = { property: 'category', label: 'Category: Finance', value: 'Finance', hideClose: true };
+
+ const expectedDisclaimers = [
+ { property: 'status', label: 'Status: Active', value: 'Active', hideClose: true },
+ { property: 'category', label: 'Category: Finance', value: 'Finance', hideClose: true }
+ ];
+
+ spyOn(component.changeDisclaimers, 'emit');
+
+ component['onRemoveDisclaimer']({ removedDisclaimer, currentDisclaimers });
+
+ expect(component.changeDisclaimers.emit).toHaveBeenCalledWith(expectedDisclaimers);
+ });
+
+ it(`onRemoveDisclaimer: should not include fixed filters without 'initValue'`, () => {
+ component.filters = [
+ { property: 'status', fixed: true, label: 'Status' },
+ { property: 'category', fixed: true, initValue: 'Finance', label: 'Category' }
+ ];
+ const currentDisclaimers = [
+ { property: 'category', label: 'Category: Finance', value: 'Finance', hideClose: true }
+ ];
+ const removedDisclaimer = { property: 'category', label: 'Category: Finance', value: 'Finance', hideClose: true };
+
+ const expectedDisclaimers = [
+ { property: 'category', label: 'Category: Finance', value: 'Finance', hideClose: true }
+ ];
+
spyOn(component.changeDisclaimers, 'emit');
+ component['onRemoveDisclaimer']({ removedDisclaimer, currentDisclaimers });
+
+ expect(component.changeDisclaimers.emit).toHaveBeenCalledWith(expectedDisclaimers);
+ });
+
+ it(`onRemoveAllDisclaimers: should call 'changeDisclaimers.emit' with disclaimers that need to be kept`, () => {
+ component.filters = [
+ { property: 'status', fixed: true, initValue: 'Ativo', label: 'Status' },
+ { property: 'category', fixed: true, initValue: 'Financeiro', label: 'Categoria' },
+ { property: 'name', fixed: false }
+ ];
+ const expectedDisclaimersToKeep = [
+ {
+ property: 'status',
+ value: 'Ativo',
+ label: 'Status: Ativo',
+ hideClose: true
+ },
+ {
+ property: 'category',
+ value: 'Financeiro',
+ label: 'Categoria: Financeiro',
+ hideClose: true
+ }
+ ];
+
+ spyOn(component.changeDisclaimers, 'emit');
+ component['onRemoveAllDisclaimers']();
+
+ expect(component.changeDisclaimers.emit).toHaveBeenCalledWith(expectedDisclaimersToKeep);
+ });
+
+ it(`onRemoveAllDisclaimers: should call 'changeDisclaimers.emit' with an empty array if there are no fixed filters`, () => {
+ component.filters = [
+ { property: 'name', fixed: false, initValue: 'John Doe' },
+ { property: 'age', fixed: false, initValue: 30 }
+ ];
+
+ spyOn(component.changeDisclaimers, 'emit');
component['onRemoveAllDisclaimers']();
expect(component.changeDisclaimers.emit).toHaveBeenCalledWith([]);
@@ -671,6 +799,87 @@ describe('PoPageDynamicSearchComponent:', () => {
expect(result).toBe(123);
});
+ it('should return an array of disclaimers for filters with fixed property, initValue defined, and no duplicates', () => {
+ component.filters = [
+ { property: 'status', fixed: true, initValue: 'Active', label: 'Status' },
+ { property: 'category', fixed: true, initValue: 'Finance', label: 'Category' },
+ { property: 'name', fixed: false, initValue: 'Test', label: 'Name' }
+ ];
+
+ const currentDisclaimers = [
+ { property: 'category', label: 'Category: Finance', value: 'Finance', hideClose: true }
+ ];
+
+ const expectedDisclaimers = [{ property: 'status', label: 'Status: Active', value: 'Active', hideClose: true }];
+
+ const result = component['getFixedFiltersDisclaimers'](currentDisclaimers);
+
+ expect(result).toEqual(expectedDisclaimers);
+ });
+
+ it('should return an empty array if there are no fixed filters', () => {
+ component.filters = [
+ { property: 'name', fixed: false, initValue: 'Test', label: 'Name' },
+ { property: 'age', fixed: false, initValue: 30, label: 'Age' }
+ ];
+
+ const result = component['getFixedFiltersDisclaimers']();
+
+ expect(result).toEqual([]);
+ });
+
+ it('should ignore filters without initValue or with null/undefined initValue', () => {
+ component.filters = [
+ { property: 'status', fixed: true, label: 'Status' },
+ { property: 'category', fixed: true, initValue: null, label: 'Category' },
+ { property: 'name', fixed: true, initValue: undefined, label: 'Name' }
+ ];
+
+ const result = component['getFixedFiltersDisclaimers']();
+
+ expect(result).toEqual([]);
+ });
+
+ it('should not add disclaimers if they are already present in currentDisclaimers', () => {
+ component.filters = [
+ { property: 'status', fixed: true, initValue: 'Active', label: 'Status' },
+ { property: 'category', fixed: true, initValue: 'Finance', label: 'Category' }
+ ];
+
+ const currentDisclaimers = [
+ { property: 'status', label: 'Status: Active', value: 'Active', hideClose: true },
+ { property: 'category', label: 'Category: Finance', value: 'Finance', hideClose: true }
+ ];
+
+ const result = component['getFixedFiltersDisclaimers'](currentDisclaimers);
+
+ expect(result).toEqual([]);
+ });
+
+ it('should correctly handle an empty currentDisclaimers array', () => {
+ component.filters = [
+ { property: 'status', fixed: true, initValue: 'Active', label: 'Status' },
+ { property: 'category', fixed: true, initValue: 'Finance', label: 'Category' }
+ ];
+
+ const expectedDisclaimers = [
+ { property: 'status', label: 'Status: Active', value: 'Active', hideClose: true },
+ { property: 'category', label: 'Category: Finance', value: 'Finance', hideClose: true }
+ ];
+
+ const result = component['getFixedFiltersDisclaimers']([]);
+
+ expect(result).toEqual(expectedDisclaimers);
+ });
+
+ it('should return an empty array if filters array is empty', () => {
+ component.filters = [];
+
+ const result = component['getFixedFiltersDisclaimers']();
+
+ expect(result).toEqual([]);
+ });
+
describe('ngOnInit:', () => {
it('should call setAdvancedFilterLiterals with component.literals', () => {
spyOn(component, 'setAdvancedFilterLiterals');
@@ -736,91 +945,157 @@ describe('PoPageDynamicSearchComponent:', () => {
expect(component['onAction']).toHaveBeenCalledWith('jhon', true);
});
});
- });
- describe('Integration:', () => {
- it(`shouldn't call 'changeDisclaimers.emit' if disclaimers have been added because of quickSearch`, () => {
- component.filters = [{ property: 'city', initValue: 'Ontario' }];
+ describe('ngAfterViewInit:', () => {
+ it('should call `onChangeFilters` and update `previousFilters` if `filters` have changed', () => {
+ const filters = [{ property: 'city', label: 'City' }];
+ component.filters = filters;
+ component.previousFilters = [{ property: 'city', label: 'Previous City' }];
- spyOn(component.changeDisclaimers, 'emit');
+ spyOn(component, 'onChangeFilters');
+ component.ngAfterViewInit();
- component.literals.quickSearchLabel = 'Search';
- component.onAction('Chicago');
+ expect(component.onChangeFilters).toHaveBeenCalledWith(filters);
+ expect(component.previousFilters).toEqual(filters);
+ });
- expect(component.changeDisclaimers.emit).not.toHaveBeenCalled();
- });
+ it('should not call `onChangeFilters` if `filters` have not changed', () => {
+ const filters = [{ property: 'city', label: 'City' }];
+ component.filters = filters;
+ component.previousFilters = [...filters];
- it(`should add quickSearch and advanced filter in disclaimers if concat-filters is true and advanced filter is defined`, () => {
- component.concatFilters = true;
+ spyOn(component, 'onChangeFilters');
- component.filters = [{ property: 'city', initValue: 'Ontario' }];
+ component.ngAfterViewInit();
- component.literals.quickSearchLabel = 'Search';
- component.onAction('Chicago');
+ expect(component.onChangeFilters).not.toHaveBeenCalled();
+ expect(component.previousFilters).toEqual(filters);
+ });
+ });
+ });
- const currentDisclaimers = [
- { label: 'City: Ontario', value: 'Ontario', property: 'city', hideClose: false },
- { property: 'search', label: `Search Chicago`, value: 'Chicago', hideClose: false }
- ];
+ describe('ngOnChanges:', () => {
+ it('should call `onChangeFilters` and update `previousFilters` when `visibleFixedFilters` changes and there are fixed filters', () => {
+ const changes: SimpleChanges = {
+ visibleFixedFilters: {
+ currentValue: true,
+ previousValue: false,
+ firstChange: false,
+ isFirstChange: () => false
+ }
+ };
- expect(component.disclaimerGroup.disclaimers).toEqual(currentDisclaimers);
- });
+ spyOn(component, 'onChangeFilters'); // Espiar o método
- it(`should add advanced filter and quickSearch updated in disclaimers if concat-filters is true and advanced filter is defined`, () => {
- component.concatFilters = true;
+ component.filters = [
+ { property: 'status', fixed: true, initValue: 'Active' },
+ { property: 'category', fixed: false, initValue: 'Finance' }
+ ];
- component.filters = [{ property: 'city', initValue: 'Ontario' }];
+ component.ngOnChanges(changes);
- component.literals.quickSearchLabel = 'Search';
- component.onAction('Chicago');
+ expect(component.onChangeFilters).toHaveBeenCalledWith(component.filters);
+ expect(component.previousFilters).toEqual(component.filters);
+ });
- component.onAction('Test');
+ it('should not call `onChangeFilters` if `visibleFixedFilters` did not change', () => {
+ const changes: SimpleChanges = {
+ visibleFixedFilters: {
+ currentValue: true,
+ previousValue: true,
+ firstChange: false,
+ isFirstChange: () => false
+ }
+ };
- const currentDisclaimers = [
- { label: 'City: Ontario', value: 'Ontario', property: 'city', hideClose: false },
- { property: 'search', label: `Search Test`, value: 'Test', hideClose: false }
+ spyOn(component, 'onChangeFilters'); // Espiar o método
+
+ component.filters = [
+ { property: 'status', fixed: true, initValue: 'Active' },
+ { property: 'category', fixed: false, initValue: 'Finance' }
];
- expect(component.disclaimerGroup.disclaimers).toEqual(currentDisclaimers);
+ component.ngOnChanges(changes);
+
+ expect(component.onChangeFilters).not.toHaveBeenCalled();
+ expect(component.previousFilters).toEqual([]);
});
- it(`should add advanced search and remove quickSearch in disclaimers if concat-filters is false`, () => {
- component.concatFilters = false;
+ it('should not throw an error if `filters` is empty', () => {
+ const changes: SimpleChanges = {
+ visibleFixedFilters: {
+ currentValue: true,
+ previousValue: false,
+ firstChange: false,
+ isFirstChange: () => false
+ }
+ };
- component.literals.quickSearchLabel = 'Search';
- component.onAction('Chicago');
- const disclaimersWithQuickFilter = [
- { property: 'search', label: `Search Chicago`, value: 'Chicago', hideClose: false }
- ];
+ spyOn(component, 'onChangeFilters'); // Espiar o método
- expect(component.disclaimerGroup.disclaimers).toEqual(disclaimersWithQuickFilter);
+ component.filters = [];
- const disclaimersWithAdvancedSearch = [
- { label: 'City: Ontario', value: 'Ontario', property: 'city', hideClose: false }
- ];
+ component.ngOnChanges(changes);
+
+ expect(component.onChangeFilters).not.toHaveBeenCalled();
+ expect(component.previousFilters).toEqual([]);
+ });
+ });
+ describe('Integration:', () => {
+ it(`shouldn't call 'changeDisclaimers.emit' if disclaimers have been added because of quickSearch`, () => {
component.filters = [{ property: 'city', initValue: 'Ontario' }];
- expect(component.disclaimerGroup.disclaimers).toEqual(disclaimersWithAdvancedSearch);
+ spyOn(component.changeDisclaimers, 'emit');
+
+ component.literals.quickSearchLabel = 'Search';
+ component.onAction('Chicago');
+
+ expect(component.changeDisclaimers.emit).not.toHaveBeenCalled();
});
- it(`should add advanced search and remove quickSearch in disclaimers if concat-filters is true`, () => {
+ it(`should remove previous quickSearch disclaimer when adding a new quickSearch`, () => {
component.concatFilters = true;
+ component.literals.quickSearchLabel = 'Search';
+ component.onAction('Chicago');
+
+ expect(component.disclaimerGroup.disclaimers).toEqual([
+ {
+ property: 'search',
+ label: 'Search Chicago',
+ value: 'Chicago',
+ hideClose: false
+ }
+ ]);
+
+ component.onAction('Test');
+
+ expect(component.disclaimerGroup.disclaimers).toEqual([
+ {
+ property: 'search',
+ label: 'Search Test',
+ value: 'Test',
+ hideClose: false
+ }
+ ]);
+ });
+ it(`should add advanced search and remove quickSearch in disclaimers if concat-filters is false`, () => {
+ component.concatFilters = false;
component.literals.quickSearchLabel = 'Search';
component.onAction('Chicago');
+
const disclaimersWithQuickFilter = [
{ property: 'search', label: `Search Chicago`, value: 'Chicago', hideClose: false }
];
-
expect(component.disclaimerGroup.disclaimers).toEqual(disclaimersWithQuickFilter);
+ component.filters = [{ property: 'city', initValue: 'Ontario' }];
+ component.onAdvancedSearch({ filter: { city: 'Ontario' } });
+
const disclaimersWithAdvancedSearch = [
{ label: 'City: Ontario', value: 'Ontario', property: 'city', hideClose: false }
];
-
- component.filters = [{ property: 'city', initValue: 'Ontario' }];
-
expect(component.disclaimerGroup.disclaimers).toEqual(disclaimersWithAdvancedSearch);
});
});
diff --git a/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search.component.ts b/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search.component.ts
index 58a267189f..6154811b99 100644
--- a/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search.component.ts
+++ b/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search.component.ts
@@ -1,4 +1,12 @@
-import { Component, ViewChild, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
+import {
+ Component,
+ ViewChild,
+ OnInit,
+ OnDestroy,
+ ChangeDetectorRef,
+ AfterViewInit,
+ SimpleChanges
+} from '@angular/core';
import { Observable, Subscription } from 'rxjs';
import {
@@ -43,7 +51,10 @@ type UrlOrPoCustomizationFunction = string | (() => PoPageDynamicSearchOptions);
selector: 'po-page-dynamic-search',
templateUrl: './po-page-dynamic-search.component.html'
})
-export class PoPageDynamicSearchComponent extends PoPageDynamicSearchBaseComponent implements OnInit, OnDestroy {
+export class PoPageDynamicSearchComponent
+ extends PoPageDynamicSearchBaseComponent
+ implements OnInit, OnDestroy, AfterViewInit
+{
@ViewChild(PoAdvancedFilterComponent, { static: true }) poAdvancedFilter: PoAdvancedFilterComponent;
@ViewChild(PoPageListComponent, { static: true }) poPageList: PoPageListComponent;
@@ -107,6 +118,27 @@ export class PoPageDynamicSearchComponent extends PoPageDynamicSearchBaseCompone
}
}
+ ngAfterViewInit(): void {
+ if (this.stringify(this.filters) !== this.stringify(this.previousFilters)) {
+ this.onChangeFilters(this.filters);
+
+ this.previousFilters = [...this.filters];
+ }
+ }
+
+ ngOnChanges(changes: SimpleChanges) {
+ const visibleFixedFilters = changes.visibleFixedFilters;
+
+ if (
+ visibleFixedFilters &&
+ visibleFixedFilters.currentValue !== visibleFixedFilters.previousValue &&
+ this.filters.some(filter => filter.fixed)
+ ) {
+ this.onChangeFilters(this.filters);
+ this.previousFilters = [...this.filters];
+ }
+ }
+
onChangeFilters(filters: Array) {
const filterObjectWithValue = filters
.filter(filter => filter.initValue)
@@ -152,7 +184,12 @@ export class PoPageDynamicSearchComponent extends PoPageDynamicSearchBaseCompone
onAdvancedSearch(filteredItems, isAdvancedSearch?) {
const { filter, optionsService } = filteredItems;
- this._disclaimerGroup.disclaimers = this.setDisclaimers(filter, optionsService);
+ const visibleFilters =
+ this.visibleFixedFilters === false
+ ? this.filters.filter(filter => !('fixed' in filter) || !filter.fixed)
+ : this.filters;
+
+ this._disclaimerGroup.disclaimers = this.setDisclaimers(filter, optionsService, visibleFilters);
this.setFilters(filter);
@@ -262,41 +299,73 @@ export class PoPageDynamicSearchComponent extends PoPageDynamicSearchBaseCompone
return value;
}
- private onRemoveDisclaimer(removeData: PoDisclaimerGroupRemoveAction) {
- const { currentDisclaimers } = removeData;
-
- this.emitChangesDisclaimers(currentDisclaimers);
- }
-
private emitChangesDisclaimers(currentDisclaimers: any) {
this.changeDisclaimers.emit(currentDisclaimers);
this.setFilters(this.formatArrayToObjectKeyValue(currentDisclaimers));
}
private onRemoveAllDisclaimers() {
- this.emitChangesDisclaimers([]);
+ const disclaimersToKeep = this.getFixedFiltersDisclaimers();
+ this.emitChangesDisclaimers(disclaimersToKeep);
+ }
+
+ private onRemoveDisclaimer(removeData: PoDisclaimerGroupRemoveAction) {
+ const { currentDisclaimers } = removeData;
+
+ const updatedDisclaimers = [...currentDisclaimers, ...this.getFixedFiltersDisclaimers(currentDisclaimers)];
+
+ this.emitChangesDisclaimers(updatedDisclaimers);
}
- private setDisclaimers(filters, optionsServiceObjects?: Array) {
+ private getFixedFiltersDisclaimers(currentDisclaimers?: Array): Array {
+ const fixedFilters = this.filters.filter(
+ filter =>
+ filter.fixed === true &&
+ filter.hasOwnProperty('initValue') &&
+ filter.initValue !== undefined &&
+ filter.initValue !== null
+ );
+
+ return fixedFilters
+ .map(filter => ({
+ property: filter.property,
+ value: filter.initValue,
+ label: `${filter.label}: ${filter.initValue}`,
+ hideClose: true
+ }))
+ .filter(
+ fixedFilter =>
+ !currentDisclaimers || !currentDisclaimers.some(disclaimer => disclaimer.property === fixedFilter.property)
+ );
+ }
+
+ private setDisclaimers(
+ filters,
+ optionsServiceObjects?: Array,
+ visibleFilters?: Array
+ ) {
const disclaimers = [];
const properties = Object.keys(filters);
+ const visibleProperties = visibleFilters ? visibleFilters.map(filter => filter.property) : properties;
properties.forEach(property => {
- const field = this.getFieldByProperty(this.filters, property);
- const label = field.label || capitalizeFirstLetter(field.property);
- const value = filters[property];
- const hideClose =
- this.hideCloseDisclaimers.some(hideCloseDisclaimer => hideCloseDisclaimer === property) || false;
-
- const valueDisplayedOnTheDisclaimerLabel = this.getFilterValueToDisclaimer(field, value, optionsServiceObjects);
-
- if (valueDisplayedOnTheDisclaimerLabel !== '') {
- disclaimers.push({
- label: `${label}: ${valueDisplayedOnTheDisclaimerLabel}`,
- property,
- value,
- hideClose
- });
+ if (visibleProperties.includes(property)) {
+ const field = this.getFieldByProperty(this.filters, property);
+ const label = field.label || capitalizeFirstLetter(field.property);
+ const value = filters[property];
+ const hideClose =
+ this.hideCloseDisclaimers.some(hideCloseDisclaimer => hideCloseDisclaimer === property) || false;
+
+ const valueDisplayedOnTheDisclaimerLabel = this.getFilterValueToDisclaimer(field, value, optionsServiceObjects);
+
+ if (valueDisplayedOnTheDisclaimerLabel !== '') {
+ disclaimers.push({
+ label: `${label}: ${valueDisplayedOnTheDisclaimerLabel}`,
+ property,
+ value,
+ hideClose
+ });
+ }
}
});
diff --git a/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.html b/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.html
index a264fb61c8..0fde4aa9ff 100644
--- a/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.html
+++ b/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.html
@@ -9,6 +9,7 @@
[p-hide-remove-all-disclaimer]="hideRemoveAllDisclaimer"
[p-quick-search-width]="quickSearchWidth"
[p-title]="title"
+ [p-visible-fixed-filters]="visibleFixedFilters"
(p-advanced-search)="onAdvancedSearch($event)"
(p-change-disclaimers)="onChangeDisclaimers($event)"
(p-quick-search)="onQuickSearch($event)"
diff --git a/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.spec.ts b/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.spec.ts
index 118015dce0..d9f6c3e60c 100644
--- a/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.spec.ts
+++ b/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.spec.ts
@@ -182,6 +182,18 @@ describe('PoPageDynamicTableComponent:', () => {
component.virtualScroll = true;
expect(component.virtualScroll).toBe(true);
});
+
+ it('p-visible-fixed-filters: should update property `p-visible-filter-disclaimers` to `false` when valid boolean value is given', () => {
+ component.visibleFixedFilters = false;
+
+ expect(component.visibleFixedFilters).toBe(false);
+ });
+
+ it('p-visible-fixed-filters: should update property `p-visible-filter-disclaimers` to `true` when valid boolean value is given', () => {
+ component.visibleFixedFilters = true;
+
+ expect(component.visibleFixedFilters).toBe(true);
+ });
});
describe('Methods:', () => {
diff --git a/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.ts b/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.ts
index a890c1531a..b4164bc0af 100644
--- a/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.ts
+++ b/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.ts
@@ -595,6 +595,26 @@ export class PoPageDynamicTableComponent extends PoPageDynamicListBaseComponent
return this._virtualScroll;
}
+ /**
+ * @optional
+ *
+ * @description
+ *
+ * Controla a visibilidade dos filtros fixos na página.
+ *
+ * - Quando `true` (default), todos os filtros, incluindo os fixos, são exibidos, permitindo que o usuário visualize os filtros aplicados.
+ * - Quando `false`, os filtros fixos são ocultados, não sendo exibidos na interface, mas ainda sendo aplicados como filtros nas requisições.
+ *
+ * Esta propriedade trabalha em conjunto com a propriedade `fixed` dos filtros individuais. Filtros marcados como `fixed: true` não serão exibidos na interface do filtro avançado quando `visibleFixedFilters` for `false`, mas continuarão a ser aplicados de forma transparente ao usuário. Dessa forma, permite-se maior flexibilidade no controle de quais filtros devem ser visíveis ao usuário ou devem ser aplicados permanentemente sem interferência.
+ *
+ * **Exemplo de uso:**
+ * ```html
+ *
+ *
+ * ```
+ */
+ @Input('p-visible-fixed-filters') visibleFixedFilters: boolean = true;
+
constructor(
private router: Router,
private activatedRoute: ActivatedRoute,