From 67ed6552b831df66713bac9e672738796128d33f Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 23 Jun 2020 14:10:17 +0200 Subject: Reorganize client shared modules --- .../shared-main/misc/list-overflow.component.ts | 120 +++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 client/src/app/shared/shared-main/misc/list-overflow.component.ts (limited to 'client/src/app/shared/shared-main/misc/list-overflow.component.ts') diff --git a/client/src/app/shared/shared-main/misc/list-overflow.component.ts b/client/src/app/shared/shared-main/misc/list-overflow.component.ts new file mode 100644 index 000000000..144e0f156 --- /dev/null +++ b/client/src/app/shared/shared-main/misc/list-overflow.component.ts @@ -0,0 +1,120 @@ +import { lowerFirst, uniqueId } from 'lodash-es' +import { take } from 'rxjs/operators' +import { + AfterViewInit, + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + ElementRef, + HostListener, + Input, + QueryList, + TemplateRef, + ViewChild, + ViewChildren +} from '@angular/core' +import { ScreenService } from '@app/core' +import { NgbDropdown, NgbModal } from '@ng-bootstrap/ng-bootstrap' + +export interface ListOverflowItem { + label: string + routerLink: string | any[] +} + +@Component({ + selector: 'list-overflow', + templateUrl: './list-overflow.component.html', + styleUrls: [ './list-overflow.component.scss' ], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ListOverflowComponent implements AfterViewInit { + @Input() items: T[] + @Input() itemTemplate: TemplateRef<{item: T}> + + @ViewChild('modal', { static: true }) modal: ElementRef + @ViewChild('itemsParent', { static: true }) parent: ElementRef + @ViewChildren('itemsRendered') itemsRendered: QueryList + + showItemsUntilIndexExcluded: number + active = false + isInTouchScreen = false + isInMobileView = false + + private openedOnHover = false + + constructor ( + private cdr: ChangeDetectorRef, + private modalService: NgbModal, + private screenService: ScreenService + ) {} + + ngAfterViewInit () { + setTimeout(() => this.onWindowResize(), 0) + } + + isMenuDisplayed () { + return !!this.showItemsUntilIndexExcluded + } + + @HostListener('window:resize') + onWindowResize () { + this.isInTouchScreen = !!this.screenService.isInTouchScreen() + this.isInMobileView = !!this.screenService.isInMobileView() + + const parentWidth = this.parent.nativeElement.getBoundingClientRect().width + let showItemsUntilIndexExcluded: number + let accWidth = 0 + + for (const [index, el] of this.itemsRendered.toArray().entries()) { + accWidth += el.nativeElement.getBoundingClientRect().width + if (showItemsUntilIndexExcluded === undefined) { + showItemsUntilIndexExcluded = (parentWidth < accWidth) ? index : undefined + } + + const e = document.getElementById(this.getId(index)) + const shouldBeVisible = showItemsUntilIndexExcluded ? index < showItemsUntilIndexExcluded : true + e.style.visibility = shouldBeVisible ? 'inherit' : 'hidden' + } + + this.showItemsUntilIndexExcluded = showItemsUntilIndexExcluded + this.cdr.markForCheck() + } + + openDropdownOnHover (dropdown: NgbDropdown) { + this.openedOnHover = true + dropdown.open() + + // Menu was closed + dropdown.openChange + .pipe(take(1)) + .subscribe(() => this.openedOnHover = false) + } + + dropdownAnchorClicked (dropdown: NgbDropdown) { + if (this.openedOnHover) { + this.openedOnHover = false + return + } + + return dropdown.toggle() + } + + closeDropdownIfHovered (dropdown: NgbDropdown) { + if (this.openedOnHover === false) return + + dropdown.close() + this.openedOnHover = false + } + + toggleModal () { + this.modalService.open(this.modal, { centered: true }) + } + + dismissOtherModals () { + this.modalService.dismissAll() + } + + getId (id: number | string = uniqueId()): string { + return lowerFirst(this.constructor.name) + '_' + id + } +} -- cgit v1.2.3