From c2772ce3442eedcdd8c41d9c9ecc3f8491c185e7 Mon Sep 17 00:00:00 2001 From: jcorrea97 Date: Wed, 27 Sep 2023 15:18:06 -0300 Subject: [PATCH] =?UTF-8?q?feat(breadcrumb):=20implementa=20defini=C3=A7?= =?UTF-8?q?=C3=B5es=20do=20AnimaliaDS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implementa definições do AnimaliaDS no Breadcrumb fixes DTHFUI-7558 --- .../po-breadcrumb-base.component.spec.ts | 22 +- .../po-breadcrumb-base.component.ts | 25 +++ .../po-breadcrumb-dropdown.component.html | 5 - .../po-breadcrumb-dropdown.component.spec.ts | 44 ---- .../po-breadcrumb-dropdown.component.ts | 19 -- .../po-breadcrumb-favorite.component.html | 16 +- .../po-breadcrumb-favorite.component.ts | 3 + .../po-breadcrumb-item.component.html | 24 --- .../po-breadcrumb-item.component.spec.ts | 93 --------- .../po-breadcrumb-item.component.ts | 26 --- .../po-breadcrumb.component.html | 100 +++++++-- .../po-breadcrumb.component.spec.ts | 190 +++++++++--------- .../po-breadcrumb/po-breadcrumb.component.ts | 96 ++++++--- .../po-breadcrumb/po-breadcrumb.module.ts | 14 +- .../po-popup/po-popup-base.component.ts | 4 +- .../po-popup/po-popup.component.spec.ts | 4 +- .../components/po-popup/po-popup.component.ts | 1 + 17 files changed, 311 insertions(+), 375 deletions(-) delete mode 100644 projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-dropdown/po-breadcrumb-dropdown.component.html delete mode 100644 projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-dropdown/po-breadcrumb-dropdown.component.spec.ts delete mode 100644 projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-dropdown/po-breadcrumb-dropdown.component.ts delete mode 100644 projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-item/po-breadcrumb-item.component.html delete mode 100644 projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-item/po-breadcrumb-item.component.spec.ts delete mode 100644 projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-item/po-breadcrumb-item.component.ts diff --git a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-base.component.spec.ts b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-base.component.spec.ts index 276b563c1c..da17241535 100644 --- a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-base.component.spec.ts @@ -8,8 +8,8 @@ describe('PoDisclaimerBaseComponent:', () => { const items: Array = [ { label: 'Teste nível 1', link: '/test/nivel/1' }, - { label: 'Teste nível 2', link: '/test/nivel/2' }, - { label: 'Teste nível 3', link: '/test/nivel/3' }, + { label: 'Teste nível 2', link: '/test/nivel/2', action: () => {} }, + { label: 'Teste nível 3', action: () => {} }, { label: 'Teste nível 4', link: '/test/nivel/4' } ]; @@ -30,4 +30,22 @@ describe('PoDisclaimerBaseComponent:', () => { expect(component.itemsView).toEqual(itemsEmpty); }); }); + + describe('Methods:', () => { + it('transformToArrayPopup: should remove first, penultimate and last item .', () => { + component['transformToArrayPopup'](items); + expect(component.itemsViewPopup.length).toEqual(1); + }); + + it('transformArrayToActionPopUp: should edit property to `link` to `url` and remove action if exists `link`', () => { + const newItem = component['transformArrayToActionPopUp'](items); + const expectedOutputItems = [ + { label: 'Teste nível 1', url: '/test/nivel/1' }, + { label: 'Teste nível 2', url: '/test/nivel/2' }, + { label: 'Teste nível 3', action: jasmine.any(Function) }, + { label: 'Teste nível 4', url: '/test/nivel/4' } + ]; + expect(newItem).toEqual(expectedOutputItems); + }); + }); }); diff --git a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-base.component.ts b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-base.component.ts index 6dca7b58ed..195f1e8364 100644 --- a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-base.component.ts +++ b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-base.component.ts @@ -92,6 +92,7 @@ export class PoBreadcrumbBaseComponent { @Input('p-params-service') paramsService?: object; itemsView: Array = []; + itemsViewPopup: Array = []; protected clickoutListener: () => void; protected resizeListener: () => void; @@ -111,9 +112,33 @@ export class PoBreadcrumbBaseComponent { @Input('p-items') set items(items: Array) { this._items = items; this.itemsView = [].concat(items); + if (this.itemsView.length >= 4) { + this.transformToArrayPopup(items); + } } get items() { return this._items; } + + private transformToArrayPopup(items: Array) { + const itemsCopy = items.map(obj => ({ ...obj })); + itemsCopy.shift(); + itemsCopy.splice(-2, 1); + itemsCopy.pop(); + this.itemsViewPopup = this.transformArrayToActionPopUp(itemsCopy); + } + + private transformArrayToActionPopUp(items: Array) { + return items.map(obj => { + if (obj.hasOwnProperty('link')) { + obj['url'] = obj.link; + delete obj.link; + if (obj.hasOwnProperty('action')) { + delete obj.action; + } + } + return obj; + }); + } } diff --git a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-dropdown/po-breadcrumb-dropdown.component.html b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-dropdown/po-breadcrumb-dropdown.component.html deleted file mode 100644 index 07d7f7e5c4..0000000000 --- a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-dropdown/po-breadcrumb-dropdown.component.html +++ /dev/null @@ -1,5 +0,0 @@ -
    -
  • - {{ item.label }} -
  • -
diff --git a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-dropdown/po-breadcrumb-dropdown.component.spec.ts b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-dropdown/po-breadcrumb-dropdown.component.spec.ts deleted file mode 100644 index c7efa584f5..0000000000 --- a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-dropdown/po-breadcrumb-dropdown.component.spec.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { DocumentationComponent, GuidesComponent, routes } from './../po-breadcrumb.component.spec'; -import { PoBreadcrumbDropdownComponent } from './po-breadcrumb-dropdown.component'; -import { PoBreadcrumbItem } from './../po-breadcrumb-item.interface'; - -describe('PoBreadcrumbDropdownComponent:', () => { - let component: PoBreadcrumbDropdownComponent; - let fixture: ComponentFixture; - let nativeElement; - - const items: Array = [ - { label: 'Teste nível 1', link: '/test/nivel/1' }, - { label: 'Teste nível 2', link: '/test/nivel/2' }, - { label: 'Teste nível 3', link: '/test/nivel/3' }, - { label: 'Teste nível 4', link: '/test/nivel/4' } - ]; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes(routes)], - declarations: [PoBreadcrumbDropdownComponent, DocumentationComponent, GuidesComponent] - }).compileComponents(); - - fixture = TestBed.createComponent(PoBreadcrumbDropdownComponent); - component = fixture.componentInstance; - component.items = items; - nativeElement = fixture.debugElement.nativeElement; - - fixture.detectChanges(); - }); - - it('should be created', () => { - expect(component).toBeTruthy(); - expect(nativeElement.querySelector('.po-breadcrumb-dropdown')).toBeTruthy(); - }); - - describe('Templates:', () => { - it('should find four items dropdown', () => { - expect(nativeElement.querySelectorAll('.po-breadcrumb-dropdown-item').length).toBe(4); - }); - }); -}); diff --git a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-dropdown/po-breadcrumb-dropdown.component.ts b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-dropdown/po-breadcrumb-dropdown.component.ts deleted file mode 100644 index 5b9d096025..0000000000 --- a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-dropdown/po-breadcrumb-dropdown.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Component, Input } from '@angular/core'; - -import { PoBreadcrumbItem } from './../po-breadcrumb-item.interface'; - -/** - * @docsPrivate - * - * @description - * - * Componente que renderiza o dropdown do po-breadcrumb. - */ -@Component({ - selector: 'po-breadcrumb-dropdown', - templateUrl: './po-breadcrumb-dropdown.component.html' -}) -export class PoBreadcrumbDropdownComponent { - // Itens a serem apresentados na lista do dropdown. - @Input('p-items') items: Array; -} diff --git a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.component.html b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.component.html index 90bdd397f9..b9ce63f9c4 100644 --- a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.component.html +++ b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.component.html @@ -1,10 +1,20 @@ -
+
- {{ literals?.unfavorite }} - {{ literals?.favorite }} + {{ + literals?.unfavorite + }} + {{ + literals?.favorite + }}
diff --git a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.component.ts b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.component.ts index 7becf58c84..536b161a8c 100644 --- a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.component.ts +++ b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.component.ts @@ -48,6 +48,9 @@ export class PoBreadcrumbFavoriteComponent implements OnInit, OnDestroy { // Parâmetro que será enviado junto com o serviço de favoritar. @Input('p-params-service') paramsService: object; + // Esconde literal e mantém apenas icone + @Input('p-hidden-literal') hiddenLiteral: boolean = false; + favorite: boolean = false; literals; diff --git a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-item/po-breadcrumb-item.component.html b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-item/po-breadcrumb-item.component.html deleted file mode 100644 index c3a8106b23..0000000000 --- a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-item/po-breadcrumb-item.component.html +++ /dev/null @@ -1,24 +0,0 @@ -
  • - - -
    -
    - - - -
    -
    - - - -
    -
    -
  • - -
  • - -
  • diff --git a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-item/po-breadcrumb-item.component.spec.ts b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-item/po-breadcrumb-item.component.spec.ts deleted file mode 100644 index 21ce6c9461..0000000000 --- a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-item/po-breadcrumb-item.component.spec.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { DocumentationComponent, GuidesComponent, routes } from './../po-breadcrumb.component.spec'; -import { PoBreadcrumbItemComponent } from './po-breadcrumb-item.component'; - -describe('PoBreadcrumbItemComponent:', () => { - let component: PoBreadcrumbItemComponent; - let fixture: ComponentFixture; - let nativeElement; - - const label = 'Documentation'; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes(routes)], - declarations: [PoBreadcrumbItemComponent, DocumentationComponent, GuidesComponent] - }).compileComponents(); - - fixture = TestBed.createComponent(PoBreadcrumbItemComponent); - component = fixture.componentInstance; - component.label = label; - nativeElement = fixture.debugElement.nativeElement; - - fixture.detectChanges(); - }); - - it('should be created', () => { - expect(component).toBeTruthy(); - }); - - describe('Templates:', () => { - it('should create a breadcrumb item with link', () => { - component.link = 'test/'; - - fixture.detectChanges(); - - expect(nativeElement.querySelector('[href]')).toBeTruthy(); - expect(nativeElement.querySelector('.po-breadcrumb-item')).toBeTruthy(); - expect(nativeElement.querySelector('.po-breadcrumb-arrow')).toBeTruthy(); - expect(nativeElement.querySelector('.po-breadcrumb-label')).toBeTruthy(); - }); - - it('should create a breadcrumb item with link when link and action are defined', () => { - component.link = 'test/'; - component.action = () => {}; - - fixture.detectChanges(); - - expect(nativeElement.querySelector('[href]')).toBeTruthy(); - expect(nativeElement.querySelector('.po-breadcrumb-item')).toBeTruthy(); - expect(nativeElement.querySelector('.po-breadcrumb-arrow')).toBeTruthy(); - expect(nativeElement.querySelector('.po-breadcrumb-label')).toBeTruthy(); - }); - - it('should create a breadcrumb item with action', () => { - component.link = undefined; - component.action = () => {}; - - fixture.detectChanges(); - - expect(nativeElement.querySelector('[href]')).toBeFalsy(); - expect(nativeElement.querySelector('.po-breadcrumb-item')).toBeTruthy(); - expect(nativeElement.querySelector('.po-breadcrumb-arrow')).toBeTruthy(); - expect(nativeElement.querySelector('.po-breadcrumb-label')).toBeTruthy(); - }); - - it('should create a unclickable breadcrumb item and not active', () => { - component.itemActive = false; - component.link = undefined; - component.action = undefined; - - fixture.detectChanges(); - - expect(nativeElement.querySelector('[href]')).toBeFalsy(); - expect(nativeElement.querySelector('.po-breadcrumb-item')).toBeFalsy(); - expect(nativeElement.querySelector('.po-breadcrumb-item-unclickable')).toBeTruthy(); - expect(nativeElement.querySelector('.po-breadcrumb-arrow')).toBeTruthy(); - expect(nativeElement.querySelector('.po-breadcrumb-label')).toBeTruthy(); - }); - - it('should create a unclickable breadcrumb item and active', () => { - component.itemActive = true; - - fixture.detectChanges(); - - expect(nativeElement.querySelector('.po-breadcrumb-item')).toBeFalsy(); - expect(nativeElement.querySelector('.po-breadcrumb-item-unclickable')).toBeTruthy(); - expect(nativeElement.querySelector('.po-breadcrumb-arrow')).toBeFalsy(); - expect(nativeElement.querySelector('.po-breadcrumb-label')).toBeTruthy(); - }); - }); -}); diff --git a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-item/po-breadcrumb-item.component.ts b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-item/po-breadcrumb-item.component.ts deleted file mode 100644 index fe51217e8f..0000000000 --- a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-item/po-breadcrumb-item.component.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Component, Input } from '@angular/core'; - -/** - * @docsPrivate - * - * @description - * - * Componente que renderiza cada item do po-breadcrumb. - */ -@Component({ - selector: 'po-breadcrumb-item', - templateUrl: './po-breadcrumb-item.component.html' -}) -export class PoBreadcrumbItemComponent { - // Ação que será executada ao clicar sobre o item. - @Input('p-action') action: Function; - - // Label do item. - @Input('p-label') label: string; - - // Link do item. - @Input('p-link') link: string; - - // Especifica se item é o link ativo. - @Input('p-item-active') itemActive: boolean = false; -} diff --git a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.html b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.html index ac5d6248ab..a0618731e1 100644 --- a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.html +++ b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.html @@ -1,28 +1,92 @@ -
    -
      -
    • - -
      -
    • +
    + +
      +
    • + + {{ item.label }} + +
    • +
    +
    - - -
    + diff --git a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.spec.ts b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.spec.ts index 06128dd083..442fcb7400 100644 --- a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.spec.ts +++ b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.spec.ts @@ -5,10 +5,8 @@ import { Routes } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; import { PoBreadcrumbComponent } from './po-breadcrumb.component'; -import { PoBreadcrumbDropdownComponent } from './po-breadcrumb-dropdown/po-breadcrumb-dropdown.component'; import { PoBreadcrumbFavoriteComponent } from './po-breadcrumb-favorite/po-breadcrumb-favorite.component'; import { PoBreadcrumbItem } from './po-breadcrumb-item.interface'; -import { PoBreadcrumbItemComponent } from './po-breadcrumb-item/po-breadcrumb-item.component'; @Component({ template: 'Documentation' }) export class DocumentationComponent {} @@ -42,20 +40,11 @@ describe('PoBreadcrumbComponent:', () => { const calcBreadcrumb = 'calcBreadcrumb'; const debounceResize = 'debounceResize'; const disableBreadcrumbResponsive = 'disableBreadcrumbResponsive'; - const enableBreadcrumbResponsive = 'enableBreadcrumbResponsive'; - const wasClickedonDropdown = 'wasClickedonDropdown'; beforeEach(async () => { await TestBed.configureTestingModule({ imports: [RouterTestingModule.withRoutes(routes)], - declarations: [ - PoBreadcrumbComponent, - PoBreadcrumbDropdownComponent, - PoBreadcrumbFavoriteComponent, - PoBreadcrumbItemComponent, - DocumentationComponent, - GuidesComponent - ], + declarations: [PoBreadcrumbComponent, PoBreadcrumbFavoriteComponent, DocumentationComponent, GuidesComponent], providers: [HttpClient, HttpHandler] }).compileComponents(); @@ -109,10 +98,64 @@ describe('PoBreadcrumbComponent:', () => { expect(fakeThis.enableBreadcrumbResponsive).not.toHaveBeenCalled(); }); - it('toggleDropdown: should set `showDropdown` to `false` when called.', () => { - component.showDropdown = true; - component.toggleDropdown(); - expect(component.showDropdown).toBeFalsy(false); + it('calcBreadcrumb: should set `hiddenLiteralFavorite` to true if tooltip is bigger than breadcrumb', () => { + const fakeThis = { + getBreadcrumbFavoriteWidth: () => 100, + getBreadcrumbWidth: () => 100, + _breadcrumbItemsLenght: 300, + breadcrumbTooltip: 300, + favoriteService: 'http://fakeUrlPo.com', + enableBreadcrumbResponsive: () => {}, + disableBreadcrumbResponsive: () => {}, + existsFavoritelabel: () => {}, + getBreadcrumbTooltipWidth: () => 400, + hiddenLiteralFavorite: false + }; + + spyOn(fakeThis, 'getBreadcrumbTooltipWidth').and.returnValue(500); + + component[calcBreadcrumb].call(fakeThis); + + expect(fakeThis.hiddenLiteralFavorite).toBeTruthy(); + }); + + it('emitAction: should emit item action.', () => { + const item = { label: 'teste', action: () => {}, link: '/test' }; + spyOn(item, 'action'); + component.emitAction(item); + + expect(item.action).toHaveBeenCalled(); + }); + + it('openPopup: should open popup if event is "Enter"', () => { + const fakeThis = { popupContainer: { open: () => {} } }; + const fakeEvent = { code: 'Enter' }; + spyOn(fakeThis.popupContainer, 'open'); + component.openPopup.call(fakeThis, fakeEvent); + expect(fakeThis.popupContainer.open).toHaveBeenCalled(); + }); + + it('openPopup: should open popup if event is "Space"', () => { + const fakeThis = { popupContainer: { open: () => {} } }; + const fakeEvent = { code: 'Space' }; + spyOn(fakeThis.popupContainer, 'open'); + component.openPopup.call(fakeThis, fakeEvent); + expect(fakeThis.popupContainer.open).toHaveBeenCalled(); + }); + + it(`openPopup: shouldn't open popup if event is not "Space" or "Enter"`, () => { + const fakeThis = { popupContainer: { open: () => {} } }; + const fakeEvent = { code: 'Tab' }; + spyOn(fakeThis.popupContainer, 'open'); + component.openPopup.call(fakeThis, fakeEvent); + expect(fakeThis.popupContainer.open).not.toHaveBeenCalled(); + }); + + it(`closePopUp: should focus in Svg More`, () => { + const fakeThis = { svgTarget: { nativeElement: { focus: () => {} } } }; + spyOn(fakeThis.svgTarget.nativeElement, 'focus'); + component.closePopUp.call(fakeThis); + expect(fakeThis.svgTarget.nativeElement.focus).toHaveBeenCalled(); }); describe('debounceResize:', () => { @@ -207,7 +250,7 @@ describe('PoBreadcrumbComponent:', () => { expect(component['getBreadcrumbFavoriteWidth'].call(fakeThis)).toBe(0); }); - it('getBreadcrumbWidth: should return a truthy value when have breadcrumb and favorite service.', () => { + it('getBreadcrumbTooltipWidth: should return 0 when don`t have tooltip.', () => { const fakeThis = { element: { nativeElement: { @@ -216,63 +259,54 @@ describe('PoBreadcrumbComponent:', () => { } } }, - favoriteService: 'http://fakeUrlPo.com' + favoriteService: undefined }; - expect(component['getBreadcrumbFavoriteWidth'].call(fakeThis)).toBe(120); + expect(component['getBreadcrumbTooltipWidth'].call(fakeThis)).toBe(0); }); - it('getBreadcrumbWidth: should return value breadcrumb legth', () => { + it('getBreadcrumbTooltipWidth: should return widht when have tooltip.', () => { const fakeThis = { element: { nativeElement: { querySelector: function (selector) { - return { offsetWidth: 200 }; + return { offsetWidth: 100 }; } } - } + }, + favoriteService: true }; - expect(component['getBreadcrumbWidth'].call(fakeThis, 50)).toBe(150); - }); - - it('initializeClickoutListener: should call `renderer.listen` with params', () => { - spyOn(component.renderer, 'listen'); - - component['initializeClickoutListener'](); - - expect(component.renderer.listen).toHaveBeenCalledWith('document', 'click', component[wasClickedonDropdown]); + expect(component['getBreadcrumbTooltipWidth'].call(fakeThis)).toBe(100); }); - it('wasClickedonDropdown: should call `removeClickoutListener` if `checkClickOutElement` returned true', () => { - component.showDropdown = true; - const event: any = { - target: '' + it('getBreadcrumbWidth: should return a truthy value when have breadcrumb and favorite service.', () => { + const fakeThis = { + element: { + nativeElement: { + querySelector: function (selector) { + return { offsetWidth: 100 }; + } + } + }, + favoriteService: 'http://fakeUrlPo.com' }; - spyOn(component, 'removeClickoutListener'); - spyOn(component, 'checkClickOutElement').and.returnValue(true); - - component[wasClickedonDropdown](event); - - expect(component.showDropdown).toBe(false); - expect(component['checkClickOutElement']).toHaveBeenCalled(); - expect(component['removeClickoutListener']).toHaveBeenCalled(); + expect(component['getBreadcrumbFavoriteWidth'].call(fakeThis)).toBe(120); }); - it('wasClickedonDropdown: should not call `removeClickoutListener` if `checkClickOutElement` returned false', () => { - component.showDropdown = true; - const event: any = { - target: '' + it('getBreadcrumbWidth: should return value breadcrumb lenght', () => { + const fakeThis = { + element: { + nativeElement: { + querySelector: function (selector) { + return { offsetWidth: 200 }; + } + } + } }; - spyOn(component, 'removeClickoutListener'); - spyOn(component, 'checkClickOutElement').and.returnValue(false); - - component[wasClickedonDropdown](event); - - expect(component.showDropdown).toBe(true); - expect(component['removeClickoutListener']).not.toHaveBeenCalled(); + expect(component['getBreadcrumbWidth'].call(fakeThis, 50, true)).toBe(150); }); describe('ngDoCheck:', () => { @@ -389,50 +423,15 @@ describe('PoBreadcrumbComponent:', () => { }); }); - describe('Properties:', () => { - it('showDropdown: should set to `false` when click in breadcrumb item.', () => { - const breadcrumbitem = nativeElement.querySelector('po-breadcrumb-item'); - component[enableBreadcrumbResponsive](); - component.showDropdown = true; - fixture.detectChanges(); - - breadcrumbitem.dispatchEvent(eventClick); - - fixture.detectChanges(); - component[wasClickedonDropdown](eventClick); - - expect(component.showDropdown).toBeFalsy(); - }); - - it('showDropdown: should set to `false` when click in dropdown.', () => { - spyOn(component, 'getBreadcrumbWidth').and.returnValue(300); - - component['calcBreadcrumb'](); - - component.toggleDropdown(); - - fixture.detectChanges(); - - const dropdown = nativeElement.querySelector('po-breadcrumb-dropdown'); - dropdown.click(); - - expect(component.showDropdown).toBe(false); - expect(component['getBreadcrumbWidth']).toHaveBeenCalled(); - }); - }); - describe('Templates:', () => { it('should enable breadcrumb responsive', () => { const itemsView = [ + { label: 'Teste nível 1', link: '/test/nivel/1' }, + { label: 'Teste nível 2', link: '/test/nivel/2' }, { label: 'Teste nível 3', link: '/test/nivel/3' }, { label: 'Teste nível 4', link: '/test/nivel/4' } ]; - const dropdownItems = [ - { label: 'Teste nível 2', link: '/test/nivel/2' }, - { label: 'Teste nível 1', link: '/test/nivel/1' } - ]; - spyOn(component, 'getBreadcrumbWidth').and.returnValue(300); component['calcBreadcrumb'](); @@ -440,10 +439,7 @@ describe('PoBreadcrumbComponent:', () => { fixture.detectChanges(); expect(component.itemsView).toEqual(itemsView); - expect(component.dropdownItems).toEqual(dropdownItems); expect(component.showDropdownToggle).toBeTruthy(); - expect(nativeElement.querySelector('.po-breadcrumb-icon-more')).toBeTruthy(); - expect(component['getBreadcrumbWidth']).toHaveBeenCalled(); }); it('should disable breadcrumb responsive', () => { @@ -452,8 +448,6 @@ describe('PoBreadcrumbComponent:', () => { expect(component.showDropdown).toBeFalsy(); expect(component.showDropdownToggle).toBeFalsy(); - expect(nativeElement.querySelector('po-breadcrumb-dropdown')).toBeFalsy(); - expect(nativeElement.querySelector('.po-breadcrumb-icon-more')).toBeFalsy(); }); }); }); @@ -465,6 +459,8 @@ function createFakeThis(breadWidth: number) { _breadcrumbItemsLenght: 300, favoriteService: 'http://fakeUrlPo.com', enableBreadcrumbResponsive: () => {}, - disableBreadcrumbResponsive: () => {} + disableBreadcrumbResponsive: () => {}, + existsFavoritelabel: () => {}, + getBreadcrumbTooltipWidth: () => {} }; } diff --git a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.ts b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.ts index 06433b0777..20bd60b7fa 100644 --- a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.ts +++ b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.ts @@ -11,6 +11,23 @@ import { import { PoBreadcrumbBaseComponent } from './po-breadcrumb-base.component'; import { PoBreadcrumbItem } from './po-breadcrumb-item.interface'; +import { PoPopupComponent } from '../po-popup/po-popup.component'; +import { PoLanguageService } from '../../services/po-language/po-language.service'; + +export const poBreadcrumbLiterals: Object = { + en: { + literalButtonPopup: 'Menu pop up collapsed' + }, + es: { + literalButtonPopup: 'Menú pop up colapsado' + }, + pt: { + literalButtonPopup: 'Menu pop up colapsado' + }, + ru: { + literalButtonPopup: 'меню свернуто' + } +}; /** * @docsExtends PoBreadcrumbBaseComponent @@ -34,10 +51,14 @@ import { PoBreadcrumbItem } from './po-breadcrumb-item.interface'; export class PoBreadcrumbComponent extends PoBreadcrumbBaseComponent implements AfterViewInit, DoCheck, OnDestroy { @ViewChild('breadcrumb', { read: ElementRef, static: true }) breadcrumbElement: ElementRef; @ViewChild('dropdownIcon', { read: ElementRef }) dropdownIcon: ElementRef; + @ViewChild('target', { read: ElementRef }) svgTarget: ElementRef; + @ViewChild('popup') popupContainer: PoPopupComponent; showDropdown: boolean = false; showDropdownToggle: boolean = false; dropdownItems: Array; + literals; + hiddenLiteralFavorite = false; private _breadcrumbItemsLenght: number = 0; private calculatedElement = false; @@ -46,9 +67,19 @@ export class PoBreadcrumbComponent extends PoBreadcrumbBaseComponent implements private initialized = false; private timeoutResize; - constructor(differs: IterableDiffers, private element: ElementRef, public renderer: Renderer2) { + constructor( + differs: IterableDiffers, + private element: ElementRef, + public renderer: Renderer2, + public languageService: PoLanguageService + ) { super(); this.differ = differs.find([]).create(null); + const language = languageService.getShortLanguage(); + + this.literals = { + ...poBreadcrumbLiterals[language] + }; } ngAfterViewInit() { @@ -75,26 +106,23 @@ export class PoBreadcrumbComponent extends PoBreadcrumbBaseComponent implements } ngOnDestroy() { - this.removeClickoutListener(); this.removeResizeListener(); } - toggleDropdown() { - this.showDropdown = !this.showDropdown; - this.initializeClickoutListener(); + emitAction(item: PoBreadcrumbItem) { + if (item.action) { + item.action(); + } } - private wasClickedonDropdown = (event: MouseEvent) => { - const clickedOutIconDropdown = this.checkClickOutElement(event, this.dropdownIcon); - - if (clickedOutIconDropdown) { - this.showDropdown = false; - this.removeClickoutListener(); + openPopup(event) { + if (event.code === 'Enter' || event.code === 'Space') { + this.popupContainer.open(); } - }; + } - private checkClickOutElement(event, element) { - return element && !element.nativeElement.contains(event.target); + closePopUp() { + this.svgTarget.nativeElement.focus(); } private checkChangeOnItems() { @@ -109,13 +137,20 @@ export class PoBreadcrumbComponent extends PoBreadcrumbBaseComponent implements private calcBreadcrumb() { const breadcrumbFavorite = this.getBreadcrumbFavoriteWidth(); - const breadcrumb = this.getBreadcrumbWidth(breadcrumbFavorite); - + const existLabel = this.existsFavoritelabel(); + const breadcrumb = this.getBreadcrumbWidth(breadcrumbFavorite, existLabel); + const breadcrumbTooltip = this.getBreadcrumbTooltipWidth(); if (breadcrumb <= this._breadcrumbItemsLenght) { this.enableBreadcrumbResponsive(); } else { this.disableBreadcrumbResponsive(); } + + if (breadcrumbTooltip && breadcrumb <= breadcrumbTooltip) { + this.hiddenLiteralFavorite = true; + } else { + this.hiddenLiteralFavorite = false; + } } private getBreadcrumbFavoriteWidth() { @@ -124,14 +159,21 @@ export class PoBreadcrumbComponent extends PoBreadcrumbBaseComponent implements : 0; } - private getBreadcrumbWidth(breadcrumbFavorite) { - return this.element.nativeElement.querySelector('.po-breadcrumb').offsetWidth - breadcrumbFavorite; + private getBreadcrumbTooltipWidth() { + return this.favoriteService ? this.element.nativeElement.querySelector('.po-breadcrumb-tooltip')?.offsetWidth : 0; + } + + private existsFavoritelabel() { + return !!this.element.nativeElement.querySelector('.po-breadcrumb-favorite-label'); + } + + private getBreadcrumbWidth(breadcrumbFavorite, existLabel) { + const widthSpan = !existLabel ? 95 : 0; + return this.element.nativeElement.querySelector('.po-breadcrumb').offsetWidth - (breadcrumbFavorite + widthSpan); } private calcBreadcrumbItemsWidth() { - const breadcrumbItem = this.element.nativeElement.querySelectorAll( - '.po-breadcrumb-item, .po-breadcrumb-item-unclickable' - ); + const breadcrumbItem = this.element.nativeElement.querySelectorAll('.po-breadcrumb-item'); this._breadcrumbItemsLenght = Array.from(breadcrumbItem) .map(breadcrumb => breadcrumb['offsetWidth']) @@ -140,8 +182,6 @@ export class PoBreadcrumbComponent extends PoBreadcrumbBaseComponent implements private enableBreadcrumbResponsive() { this.showDropdownToggle = true; - this.itemsView = this.items.slice(-2); - this.dropdownItems = this.items.slice(0, -2).reverse(); } private disableBreadcrumbResponsive() { @@ -171,22 +211,12 @@ export class PoBreadcrumbComponent extends PoBreadcrumbBaseComponent implements this.calculatedElement = true; } - private initializeClickoutListener() { - this.clickoutListener = this.renderer.listen('document', 'click', this.wasClickedonDropdown); - } - private initializeResizeListener() { this.resizeListener = this.renderer.listen('window', 'resize', (event: MouseEvent) => { this.debounceResize(); }); } - private removeClickoutListener() { - if (this.clickoutListener) { - this.clickoutListener(); - } - } - private removeResizeListener() { this.resizeListener(); } diff --git a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.module.ts b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.module.ts index bb6bedc289..51f634bbd5 100644 --- a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.module.ts +++ b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.module.ts @@ -3,9 +3,10 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; import { PoBreadcrumbComponent } from './po-breadcrumb.component'; -import { PoBreadcrumbDropdownComponent } from './po-breadcrumb-dropdown/po-breadcrumb-dropdown.component'; import { PoBreadcrumbFavoriteComponent } from './po-breadcrumb-favorite/po-breadcrumb-favorite.component'; -import { PoBreadcrumbItemComponent } from './po-breadcrumb-item/po-breadcrumb-item.component'; +import { PoLinkModule } from '../po-link/po-link.module'; +import { PoPopupModule } from '../po-popup/po-popup.module'; +import { PoIconModule } from '../po-icon/po-icon.module'; /** * @description @@ -14,13 +15,8 @@ import { PoBreadcrumbItemComponent } from './po-breadcrumb-item/po-breadcrumb-it * */ @NgModule({ - imports: [CommonModule, RouterModule], - declarations: [ - PoBreadcrumbComponent, - PoBreadcrumbDropdownComponent, - PoBreadcrumbFavoriteComponent, - PoBreadcrumbItemComponent - ], + imports: [CommonModule, RouterModule, PoLinkModule, PoPopupModule, PoIconModule], + declarations: [PoBreadcrumbComponent, PoBreadcrumbFavoriteComponent], exports: [PoBreadcrumbComponent] }) export class PoBreadcrumbModule {} diff --git a/projects/ui/src/lib/components/po-popup/po-popup-base.component.ts b/projects/ui/src/lib/components/po-popup/po-popup-base.component.ts index a4ce3f77e9..44bc4b6f77 100644 --- a/projects/ui/src/lib/components/po-popup/po-popup-base.component.ts +++ b/projects/ui/src/lib/components/po-popup/po-popup-base.component.ts @@ -1,4 +1,4 @@ -import { ElementRef, Input, Directive } from '@angular/core'; +import { ElementRef, Input, Directive, Output, EventEmitter } from '@angular/core'; import { convertToBoolean } from '../../utils/util'; import { PO_CONTROL_POSITIONS } from './../../services/po-control-position/po-control-position.constants'; @@ -196,4 +196,6 @@ export class PoPopupBaseComponent { get target() { return this._target; } + + @Output('p-close') closeEvent: EventEmitter = new EventEmitter(); } diff --git a/projects/ui/src/lib/components/po-popup/po-popup.component.spec.ts b/projects/ui/src/lib/components/po-popup/po-popup.component.spec.ts index c47a0e3f15..d54d9fdfbd 100644 --- a/projects/ui/src/lib/components/po-popup/po-popup.component.spec.ts +++ b/projects/ui/src/lib/components/po-popup/po-popup.component.spec.ts @@ -316,15 +316,17 @@ describe('PoPopupComponent:', () => { expect(component.close).not.toHaveBeenCalled(); }); - it('close: should set left style to 0 and showPopup to false', () => { + it('close: should set left style to 0, showPopup to false and emit close', () => { component.showPopup = true; spyOn(component, 'removeListeners'); + spyOn(component.closeEvent, 'emit'); component.close(); expect(component.showPopup).toBeFalsy(); expect(component['removeListeners']).toHaveBeenCalled(); + expect(component.closeEvent.emit).toHaveBeenCalled(); }); it('checkAllActionIsInvisible: should return true is all itens are invisible', () => { diff --git a/projects/ui/src/lib/components/po-popup/po-popup.component.ts b/projects/ui/src/lib/components/po-popup/po-popup.component.ts index 13bcfd52cd..fd58c90bd2 100644 --- a/projects/ui/src/lib/components/po-popup/po-popup.component.ts +++ b/projects/ui/src/lib/components/po-popup/po-popup.component.ts @@ -61,6 +61,7 @@ export class PoPopupComponent extends PoPopupBaseComponent { this.removeListeners(); this.showPopup = false; + this.closeEvent.emit(); } onActionClick(popupAction: PoPopupAction) {