From 88eb654c30bc2c3350ef5305ec8d29479d25cc82 Mon Sep 17 00:00:00 2001 From: AleksanderSklorz <115619721+AleksanderSklorz@users.noreply.github.com> Date: Thu, 5 Dec 2024 08:26:35 +0100 Subject: [PATCH] [ACS-8918] search date filter changing between created and modified tabs slides the text inside the tabs too (#10455) * [ACS-8918] Fix sliding text after changing tabs * [ACS-8918] Unit tests * [ACS-8918] Retrigger jobs * [ACS-8918] Retrigger jobs * [ACS-8918] Fixed failed job, fixed sonar, addressing PR comments --- .../search-filter-tabbed.component.spec.ts | 87 +++++++++++++++++++ .../search-filter-tabbed.component.ts | 33 ++++++- 2 files changed, 117 insertions(+), 3 deletions(-) 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-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..d275d72c95 --- /dev/null +++ b/lib/content-services/src/lib/search/components/search-filter-tabbed/search-filter-tabbed.component.spec.ts @@ -0,0 +1,87 @@ +/*! + * @license + * Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ContentTestingModule, SearchFilterTabbedComponent, SearchFilterTabDirective } from '@alfresco/adf-content-services'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { MatTabGroup } from '@angular/material/tabs'; +import { Component } from '@angular/core'; +import { NoopTranslateModule } from '@alfresco/adf-core'; + +@Component({ + selector: 'adf-search-filter-tabbed-test', + template: ` + +
Tab 1 content
+
Tab 2 content
+
Tab 3 content
+
+ `, + standalone: true, + imports: [SearchFilterTabbedComponent, SearchFilterTabDirective] +}) +class SearchFilterTabbedTestComponent {} + +describe('SearchFilterTabbedComponent', () => { + let searchFilterTabbedTestFixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [SearchFilterTabbedTestComponent, NoopTranslateModule, ContentTestingModule] + }); + searchFilterTabbedTestFixture = TestBed.createComponent(SearchFilterTabbedTestComponent); + }); + + describe('ngOnInit', () => { + let searchFilterTabbedElement: HTMLElement; + let selectedIndexSpy: jasmine.Spy<(index: number) => void>; + let tabGroup: MatTabGroup; + + beforeEach(() => { + searchFilterTabbedTestFixture.detectChanges(); + searchFilterTabbedElement = searchFilterTabbedTestFixture.debugElement.query(By.directive(SearchFilterTabbedComponent)).nativeElement; + tabGroup = searchFilterTabbedTestFixture.debugElement.query(By.directive(MatTabGroup)).componentInstance; + selectedIndexSpy = spyOnProperty(tabGroup, 'selectedIndex', 'set'); + searchFilterTabbedElement.style.position = 'absolute'; + }); + + it('should double change selectedIndex when element becomes not visible on screen', (done) => { + searchFilterTabbedElement.style.top = '200%'; + setTimeout(() => { + expect(selectedIndexSpy).toHaveBeenCalledTimes(2); + expect(selectedIndexSpy).toHaveBeenCalledWith(1); + expect(selectedIndexSpy).toHaveBeenCalled(); + expect(tabGroup.selectedIndex).toBe(0); + done(); + }, 100); + }); + + it('should not change selectedIndex when element becomes visible on screen', (done) => { + searchFilterTabbedElement.style.top = '200%'; + + setTimeout(() => { + selectedIndexSpy.calls.reset(); + searchFilterTabbedElement.style.top = '0'; + setTimeout(() => { + expect(selectedIndexSpy).not.toHaveBeenCalled(); + expect(tabGroup.selectedIndex).toBe(0); + done(); + }, 100); + }, 100); + }); + }); +}); diff --git a/lib/content-services/src/lib/search/components/search-filter-tabbed/search-filter-tabbed.component.ts b/lib/content-services/src/lib/search/components/search-filter-tabbed/search-filter-tabbed.component.ts index cac2dedba6..053449927e 100644 --- a/lib/content-services/src/lib/search/components/search-filter-tabbed/search-filter-tabbed.component.ts +++ b/lib/content-services/src/lib/search/components/search-filter-tabbed/search-filter-tabbed.component.ts @@ -15,10 +15,10 @@ * limitations under the License. */ -import { Component, ContentChildren, QueryList, ViewEncapsulation } from '@angular/core'; +import { ChangeDetectorRef, Component, ContentChildren, ElementRef, OnDestroy, OnInit, QueryList, ViewChild, ViewEncapsulation } from '@angular/core'; import { SearchFilterTabDirective } from './search-filter-tab.directive'; import { CommonModule } from '@angular/common'; -import { MatTabsModule } from '@angular/material/tabs'; +import { MatTabGroup, MatTabsModule } from '@angular/material/tabs'; import { TranslateModule } from '@ngx-translate/core'; @Component({ @@ -29,12 +29,39 @@ import { TranslateModule } from '@ngx-translate/core'; styleUrls: ['./search-filter-tabbed.component.scss'], encapsulation: ViewEncapsulation.None }) -export class SearchFilterTabbedComponent { +export class SearchFilterTabbedComponent implements OnInit, OnDestroy { @ContentChildren(SearchFilterTabDirective) tabsContents: QueryList; selectedIndex: number = 0; + @ViewChild(MatTabGroup) + private readonly tabGroup: MatTabGroup; + + private readonly intersectionObserver = new IntersectionObserver( + (entries) => { + if (!entries[0].isIntersecting) { + this.tabGroup.selectedIndex = (this.selectedIndex + 1) % this.tabsContents.length; + this.changeDetector.detectChanges(); + this.tabGroup.selectedIndex = this.selectedIndex; + this.changeDetector.detectChanges(); + } + }, + { + threshold: [0, 1] + } + ); + + constructor(private readonly element: ElementRef, private readonly changeDetector: ChangeDetectorRef) {} + + ngOnInit(): void { + this.intersectionObserver.observe(this.element.nativeElement); + } + + ngOnDestroy(): void { + this.intersectionObserver.disconnect(); + } + onTabIndexChanged(index: number): void { this.selectedIndex = index; }