From f8455a57cc5e8875df4c6b73a342b562a1c3030a Mon Sep 17 00:00:00 2001 From: "swapnil.verma" Date: Fri, 9 Jun 2023 16:45:47 +0530 Subject: [PATCH] [ACS-4985] Added SearchFilterTabbedComponent and SearchDateRangeAdvancedComponent. Added config for using the new components --- .../search-date-range-advanced.component.html | 40 +++ .../search-date-range-advanced.component.scss | 25 ++ ...arch-date-range-advanced.component.spec.ts | 23 ++ .../search-date-range-advanced.component.ts | 238 ++++++++++++++++++ .../search-widget-chip.component.ts | 4 +- .../search-filter-tabbed.component.spec.ts | 23 ++ 6 files changed, 351 insertions(+), 2 deletions(-) create mode 100644 lib/content-services/src/lib/search/components/search-date-range-advanced/search-date-range-advanced.component.html create mode 100644 lib/content-services/src/lib/search/components/search-date-range-advanced/search-date-range-advanced.component.scss create mode 100644 lib/content-services/src/lib/search/components/search-date-range-advanced/search-date-range-advanced.component.spec.ts create mode 100644 lib/content-services/src/lib/search/components/search-date-range-advanced/search-date-range-advanced.component.ts create mode 100644 lib/content-services/src/lib/search/components/search-filter-tabbed/search-filter-tabbed.component.spec.ts diff --git a/lib/content-services/src/lib/search/components/search-date-range-advanced/search-date-range-advanced.component.html b/lib/content-services/src/lib/search/components/search-date-range-advanced/search-date-range-advanced.component.html new file mode 100644 index 0000000000..45cf7039a4 --- /dev/null +++ b/lib/content-services/src/lib/search/components/search-date-range-advanced/search-date-range-advanced.component.html @@ -0,0 +1,40 @@ + + + + {{ 'SEARCH.DATE_RANGE_ADVANCED.OPTIONS.ANYTIME' | translate }} + + + + {{ 'SEARCH.DATE_RANGE_ADVANCED.OPTIONS.IN_LAST' | translate }} + + + + + + {{ 'SEARCH.DATE_RANGE_ADVANCED.IN_LAST_LABELS.DAYS' | translate }} + {{ 'SEARCH.DATE_RANGE_ADVANCED.IN_LAST_LABELS.WEEKS' | translate }} + {{ 'SEARCH.DATE_RANGE_ADVANCED.IN_LAST_LABELS.MONTHS' | translate }} + + + + + {{ 'SEARCH.DATE_RANGE_ADVANCED.OPTIONS.BETWEEN' | translate }} + + + + + + + + + + + +
+ + +
diff --git a/lib/content-services/src/lib/search/components/search-date-range-advanced/search-date-range-advanced.component.scss b/lib/content-services/src/lib/search/components/search-date-range-advanced/search-date-range-advanced.component.scss new file mode 100644 index 0000000000..28166f5b1e --- /dev/null +++ b/lib/content-services/src/lib/search/components/search-date-range-advanced/search-date-range-advanced.component.scss @@ -0,0 +1,25 @@ +.adf-search-date-range-advanced { + .mat-radio-group { + display: flex; + flex-direction: column; + } + + .mat-radio-button { + margin: 5px; + } + + .adf-search-date-range-horizontal-container { + display: flex; + flex-direction: row; + align-items: center; + + .adf-search-date-range-input-field { + width: 75px; + } + + .adf-search-date-range-form-field { + padding-left: 10px; + flex: 1; + } + } +} diff --git a/lib/content-services/src/lib/search/components/search-date-range-advanced/search-date-range-advanced.component.spec.ts b/lib/content-services/src/lib/search/components/search-date-range-advanced/search-date-range-advanced.component.spec.ts new file mode 100644 index 0000000000..c1e851f9eb --- /dev/null +++ b/lib/content-services/src/lib/search/components/search-date-range-advanced/search-date-range-advanced.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SearchDateRangeAdvancedComponent } from './search-date-range-advanced.component'; + +describe('SearchDateRangeAdvancedComponent', () => { + let component: SearchDateRangeAdvancedComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SearchDateRangeAdvancedComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(SearchDateRangeAdvancedComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/lib/content-services/src/lib/search/components/search-date-range-advanced/search-date-range-advanced.component.ts b/lib/content-services/src/lib/search/components/search-date-range-advanced/search-date-range-advanced.component.ts new file mode 100644 index 0000000000..6fa9ba1f21 --- /dev/null +++ b/lib/content-services/src/lib/search/components/search-date-range-advanced/search-date-range-advanced.component.ts @@ -0,0 +1,238 @@ +import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; +import { + SearchQueryBuilderService, + SearchWidget, + SearchWidgetSettings +} from '@alfresco/adf-content-services'; +import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core'; +import { Moment } from 'moment'; +import { Subject } from 'rxjs'; +import { TranslateService } from '@ngx-translate/core'; +import { + MOMENT_DATE_FORMATS, + MomentDateAdapter, + UserPreferencesService, + UserPreferenceValues +} from '@alfresco/adf-core'; +import { takeUntil } from 'rxjs/operators'; + +declare let moment: any; + +enum DateRangeType { + ANY = 'ANY', + IN_LAST = 'IN_LAST', + BETWEEN = 'BETWEEN', +} + +enum InLastDateType { + DAYS = 'DAYS', + WEEKS = 'WEEKS', + MONTHS = 'MONTHS' +} + +interface SearchDateRangeAdvanced { + dateRangeType: DateRangeType; + + [indexer: string]: any; +} + +const DEFAULT_FORMAT_DATE: string = 'DD/MM/YYYY'; + +@Component({ + selector: 'adf-search-date-range-advanced', + templateUrl: './search-date-range-advanced.component.html', + styleUrls: ['./search-date-range-advanced.component.scss'], + providers: [ + {provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE]}, + {provide: MAT_DATE_FORMATS, useValue: MOMENT_DATE_FORMATS} + ], + encapsulation: ViewEncapsulation.None, + host: {class: 'adf-search-date-range-advanced'} +}) +export class SearchDateRangeAdvancedComponent implements SearchWidget, OnInit, OnDestroy { + displayValue$: Subject = new Subject(); + isActive: boolean; + + id: string; + settings?: SearchWidgetSettings; + context?: SearchQueryBuilderService; + startValue: SearchDateRangeAdvanced; + maxDate: any; + dateRangeTypeValue: DateRangeType = DateRangeType.ANY; + inLastValue: string; + inLastValueType: InLastDateType = InLastDateType.DAYS; + betweenStartDate: any; + betweenEndDate: any; + + DateRangeType = DateRangeType; + InLastDateType = InLastDateType; + + private enableChangeUpdate: boolean; + private datePickerFormat: string; + private disableUpdateOnSubmit = false; + + private onDestroy$ = new Subject(); + + constructor(private dateAdapter: DateAdapter, + private translate: TranslateService, + private userPreferencesService: UserPreferencesService) { + } + + ngOnInit(): void { + this.datePickerFormat = this.settings?.dateFormat ? this.settings.dateFormat : DEFAULT_FORMAT_DATE; + this.disableUpdateOnSubmit = this.settings?.disableUpdateOnSubmit; + if (this.settings && this.settings.maxDate) { + if (this.settings.maxDate === 'today') { + this.maxDate = this.dateAdapter.today().endOf('day'); + } else { + this.maxDate = moment(this.settings.maxDate).endOf('day'); + } + } + this.enableChangeUpdate = this.settings?.allowUpdateOnChange ?? true; + + this.userPreferencesService + .select(UserPreferenceValues.Locale) + .pipe(takeUntil(this.onDestroy$)) + .subscribe(locale => this.setLocale(locale)); + + if (this.startValue) { + this.setValue(this.startValue); + } + } + + ngOnDestroy(): void { + this.onDestroy$.next(); + this.onDestroy$.complete(); + } + + setLocale(locale) { + this.dateAdapter.setLocale(locale); + moment.locale(locale); + } + + getCurrentValue(): SearchDateRangeAdvanced { + let currentValue = {}; + switch (this.dateRangeTypeValue) { + case DateRangeType.IN_LAST: + currentValue = { + inLastValue: this.inLastValue, + inLastValueType: this.inLastValueType + }; + break; + case DateRangeType.BETWEEN: + currentValue = { + betweenStartDate: this.betweenStartDate, + betweenEndDate: this.betweenEndDate + }; + break; + } + return { + dateRangeType: this.dateRangeTypeValue, + ...currentValue + }; + } + + hasValidValue(): boolean { + let isValid = false; + switch (this.dateRangeTypeValue) { + case DateRangeType.ANY: + isValid = true; + break; + case DateRangeType.IN_LAST: + if (this.inLastValue) { + isValid = true; + } + break; + case DateRangeType.BETWEEN: + if (this.betweenStartDate && this.betweenEndDate) { + isValid = true; + } + break; + default: + isValid = false; + } + return isValid; + } + + reset(): void { + this.isActive = false; + + this.dateRangeTypeValue = DateRangeType.ANY; + this.inLastValue = ''; + this.inLastValueType = InLastDateType.DAYS; + this.betweenStartDate = ''; + this.betweenEndDate = ''; + + if (this.id && this.context) { + this.context.queryFragments[this.id] = ''; + if (this.enableChangeUpdate) { + this.updateQuery(); + } + } + + } + + setValue(value: SearchDateRangeAdvanced) { + this.dateRangeTypeValue = value.dateRangeType ? value.dateRangeType : DateRangeType.ANY; + switch (this.dateRangeTypeValue) { + case DateRangeType.IN_LAST: + this.inLastValue = value.inLastValue; + this.inLastValueType = value.inLastValueType; + break; + case DateRangeType.BETWEEN: + this.betweenStartDate = value.betweenStartDate; + this.betweenEndDate = value.betweeenEndDate; + break; + } + } + + submitValues(): void { + let query = ''; + this.isActive = true; + switch (this.dateRangeTypeValue) { + case DateRangeType.IN_LAST: + if (this.hasValidValue()) { + query = `${this.settings.field}:[NOW/DAY-${this.inLastValue}${this.inLastValueType} TO NOW/DAY+1DAY]`; + } + break; + case DateRangeType.BETWEEN: + if (this.hasValidValue()) { + const start = moment(this.betweenStartDate).startOf('day').format(); + const end = moment(this.betweenEndDate).endOf('day').format(); + query = `${this.settings.field}:['${start}' TO '${end}']`; + } + } + this.context.queryFragments[this.id] = query; + this.updateDisplayValue(); + if (!this.disableUpdateOnSubmit) { + this.updateQuery(); + } + } + + updateDisplayValue(): void { + let displayLabel = ''; + switch (this.dateRangeTypeValue) { + case DateRangeType.IN_LAST: + if (this.hasValidValue()) { + displayLabel = `${this.translate.instant('SEARCH.DATE_RANGE_ADVANCED.OPTIONS.IN_LAST')} ${this.inLastValue} ${this.translate.instant(`SEARCH.DATE_RANGE_ADVANCED.IN_LAST_LABELS.${this.inLastValueType}`)}`; + } + break; + case DateRangeType.BETWEEN: + if (this.hasValidValue()) { + const start = moment(this.betweenStartDate).startOf('day').format(this.datePickerFormat); + const end = moment(this.betweenEndDate).endOf('day').format(this.datePickerFormat); + displayLabel = `${start} - ${end}`; + } + break; + } + this.displayValue$.next(displayLabel); + } + + private updateQuery() { + if (this.id && this.context) { + this.context.update(); + } + } +} + +//TODO: Format dates for Between date range type diff --git a/lib/content-services/src/lib/search/components/search-filter-chips/search-widget-chip/search-widget-chip.component.ts b/lib/content-services/src/lib/search/components/search-filter-chips/search-widget-chip/search-widget-chip.component.ts index 4ff847a753..3845ac9494 100644 --- a/lib/content-services/src/lib/search/components/search-filter-chips/search-widget-chip/search-widget-chip.component.ts +++ b/lib/content-services/src/lib/search/components/search-filter-chips/search-widget-chip/search-widget-chip.component.ts @@ -16,10 +16,10 @@ */ import { Component, ElementRef, Input, ViewChild, ViewEncapsulation } from '@angular/core'; -import { SearchCategory } from '../../../models/search-category.interface'; +import { SearchCategory } from '@alfresco/adf-content-services'; import { ConfigurableFocusTrap, ConfigurableFocusTrapFactory } from '@angular/cdk/a11y'; import { MatMenuTrigger } from '@angular/material/menu'; -import { SearchWidgetContainerComponent } from '../../search-widget-container/search-widget-container.component'; +import { SearchWidgetContainerComponent } from '@alfresco/adf-content-services'; @Component({ selector: 'adf-search-widget-chip', diff --git a/lib/content-services/src/lib/search/components/search-filter-tabbed/search-filter-tabbed.component.spec.ts b/lib/content-services/src/lib/search/components/search-filter-tabbed/search-filter-tabbed.component.spec.ts new file mode 100644 index 0000000000..6ebb93db08 --- /dev/null +++ b/lib/content-services/src/lib/search/components/search-filter-tabbed/search-filter-tabbed.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SearchFilterTabbedComponent } from './search-filter-tabbed.component'; + +describe('SearchFilterTabbedComponent', () => { + let component: SearchFilterTabbedComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SearchFilterTabbedComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(SearchFilterTabbedComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +});