src/app/shared/dc-tree/dc-tree.component.ts

Implements

OnInit AfterViewInit OnChanges

Metadata

Relationships

Index

Properties
Methods
Inputs
Outputs
HostListeners

Constructor

constructor(helperService: HelperService, licenceService: LicenceService)
Parameters :
Name Type Optional
helperService HelperService No
licenceService LicenceService No

Inputs

hasColumns
Type : boolean
Default value : false
libraryList
Type : any[] | undefined
paging
Type : boolean
Default value : true

Outputs

libraryOnClickEmitter
Type : EventEmitter
tableOnClickEmitter
Type : EventEmitter

HostListeners

scroll
Arguments : '$event'
scroll(event: Event)

Methods

Public collapseTreeItems
collapseTreeItems(tree: any, itemToSkip: any)
Parameters :
Name Type Optional
tree any No
itemToSkip any No
Returns : void
columnOnClick
columnOnClick(libColumn: any, library: any, libTable: any)
Parameters :
Name Type Optional
libColumn any No
library any No
libTable any No
Returns : void
handleScroll
handleScroll(event: Event)
Decorators :
@HostListener('scroll', ['$event'])
Parameters :
Name Type Optional
event Event No
Returns : void
Public libColumnActive
libColumnActive(libColumnUri: string)
Parameters :
Name Type Optional
libColumnUri string No
Returns : boolean
libraryOnClick
libraryOnClick(libid: string, library: any, libTreeNode: any)
Parameters :
Name Type Optional
libid string No
library any No
libTreeNode any No
Returns : void
libraryOnFilter
libraryOnFilter()
Returns : void
Public libTabActive
libTabActive(library: string, table: string)
Parameters :
Name Type Optional
library string No
table string No
Returns : boolean
Public loadMoreLibraries
loadMoreLibraries()
Returns : void
ngAfterViewInit
ngAfterViewInit()
Returns : void
ngOnChanges
ngOnChanges(changes: SimpleChanges)
Parameters :
Name Type Optional
changes SimpleChanges No
Returns : void
ngOnInit
ngOnInit()
Returns : void
Public Async tableOnClick
tableOnClick(tableuri: string, libTable: any, library: any)
Parameters :
Name Type Optional
tableuri string No
libTable any No
library any No
Returns : any
treeNodeClicked
treeNodeClicked(event: any, item: any, tree: any)
Parameters :
Name Type Optional
event any No
item any No
tree any No
Returns : void
treeOnFilter
treeOnFilter(array: any, arrToFilter: string)
Parameters :
Name Type Optional
array any No
arrToFilter string No
Returns : void

Properties

Public column
Type : string | undefined
Public lib
Type : any
Default value : ''
Public librariesPaging
Type : boolean
Default value : false
Public librariesSearch
Type : string
Default value : ''
Public licenceState
Type : unknown
Default value : this.licenceService.licenceState
searchLibInputList
Type : QueryList<any>
Default value : new QueryList()
Decorators :
@ViewChildren('searchLibTreeInput')
Public table
Type : any
Default value : ''
import {
  AfterViewInit,
  Component,
  EventEmitter,
  HostListener,
  Input,
  OnChanges,
  OnInit,
  Output,
  QueryList,
  SimpleChanges,
  ViewChildren,
  ViewEncapsulation
} from '@angular/core'
import { HelperService } from 'src/app/services/helper.service'
import { LicenceService } from 'src/app/services/licence.service'
import { globals } from 'src/app/_globals'
import { LibraryClickEmitter } from './models/LibraryClickEmitter'
import { TableClickEmitter } from './models/TableClickEmitter'

@Component({
  selector: 'dc-tree',
  templateUrl: './dc-tree.component.html',
  styleUrls: ['./dc-tree.component.scss'],
  encapsulation: ViewEncapsulation.None,
  standalone: false
})
export class DcTreeComponent implements OnInit, AfterViewInit, OnChanges {
  // REFACTOR NOTICE
  // This component ideally should be used in whole app instead of `clr-tree` being copied again in every component

  @ViewChildren('searchLibTreeInput')
  searchLibInputList: QueryList<any> = new QueryList()

  @Output() tableOnClickEmitter = new EventEmitter<TableClickEmitter>()
  @Output() libraryOnClickEmitter = new EventEmitter<LibraryClickEmitter>()

  @Input() hasColumns: boolean = false
  @Input() paging: boolean = true
  @Input() libraryList: any[] | undefined
  public librariesSearch: string = ''

  public lib: any = ''
  public table: any = ''
  public column: string | undefined

  public librariesPaging: boolean = false

  public licenceState = this.licenceService.licenceState

  constructor(
    private helperService: HelperService,
    private licenceService: LicenceService
  ) {}

  ngOnInit(): void {}

  ngAfterViewInit(): void {
    setTimeout(() => {
      this.searchLibInputList.first.nativeElement.focus()
    })
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (changes.libraryList?.currentValue) {
      if (this.libraryList) {
        this.helperService.displayLibraries(this.libraryList)
      }
    }
  }

  treeOnFilter(array: any, arrToFilter: string) {
    this.helperService.treeOnFilter(array, arrToFilter)
  }

  libraryOnFilter() {
    this.helperService.libraryOnFilter(
      this.libraryList,
      this.librariesSearch,
      'LIBRARYNAME'
    )

    globals.lineage.librariesSearch = this.librariesSearch
  }

  treeNodeClicked(event: any, item: any, tree: any) {
    if (event.target.title === 'Collapse') {
      this.collapseTreeItems(tree, item)
    }
  }

  libraryOnClick(libid: string, library: any, libTreeNode: any) {
    library['inForeground'] = true //When we programatically call this function, we make sure it is visible in the sidebar

    const focusTableSearch = () =>
      setTimeout(() =>
        libTreeNode.contentContainer.nativeElement.parentElement
          .querySelector('input')
          .focus()
      )

    if (!library['tables']) {
      library['loadingTables'] = true

      this.libraryOnClickEmitter.emit({ libid, library, tablesLoaded: false })

      const interval = setInterval(() => {
        if (!library['loadingTables']) {
          focusTableSearch()

          clearInterval(interval)
        }
      }, 500)
    } else {
      library['expanded'] = !library['expanded']

      this.libraryOnClickEmitter.emit({ libid, library, tablesLoaded: true })
    }

    if (library['expanded']) {
      focusTableSearch()
    }

    this.collapseTreeItems(this.libraryList, library)
  }

  public async tableOnClick(tableuri: string, libTable: any, library: any) {
    this.helperService.debounceCall(50, () => {
      if (!this.hasColumns) {
        this.tableOnClickEmitter.emit({
          tableuri,
          libTable,
          library,
          columnsLoaded: false
        })

        return
      }

      if (!libTable['columns']) {
        libTable['expanded'] = !libTable['expanded']
        libTable['loadingColumns'] = true
        this.table = tableuri

        this.tableOnClickEmitter.emit({
          tableuri,
          libTable,
          library,
          columnsLoaded: false
        })
      } else {
        libTable['expanded'] = !libTable['expanded']

        if (libTable['expanded'] === true) {
          this.table = tableuri

          this.tableOnClickEmitter.emit({
            tableuri,
            libTable,
            library,
            columnsLoaded: true
          })
        }
      }

      this.collapseTreeItems(library['tables'], libTable)
    })
  }

  columnOnClick(libColumn: any, library: any, libTable: any) {
    this.lib = library.LIBRARYID
    this.table = libTable.TABLEURI
    this.column = libColumn.COLURI
  }

  public libTabActive(library: string, table: string) {
    if (!this.lib || !this.table) {
      return false
    }

    return library === this.lib && table === this.table
  }

  public libColumnActive(libColumnUri: string) {
    if (!this.column) {
      return false
    }

    let splitedLibColumnUri = libColumnUri.split('\\')
    let splitedColumnUri = this.column.split('\\')

    return (
      splitedLibColumnUri[splitedLibColumnUri.length - 1] ==
      splitedColumnUri[splitedColumnUri.length - 1]
    )
  }

  public collapseTreeItems(tree: any, itemToSkip: any) {
    tree.forEach((item: any) => {
      if (JSON.stringify(item) !== JSON.stringify(itemToSkip)) {
        item['expanded'] = false
      }
    })
  }

  public loadMoreLibraries() {
    if (!this.librariesPaging) {
      this.librariesPaging = true

      this.helperService.displayLibraries(this.libraryList, true)
      this.librariesPaging = false
    }
  }

  @HostListener('scroll', ['$event'])
  handleScroll(event: Event) {
    let element = event.target as HTMLElement

    if (element) {
      // When list scrolled to the bottom, load more libraries
      if (
        element.scrollTop >=
        element.scrollHeight - element.offsetHeight - 10
      ) {
        this.loadMoreLibraries()
      }
    }
  }
}
<clr-tree>
  @if (libraryList) {
    <clr-tree-node class="search-node">
      <div class="tree-search-wrapper">
        <input
          appStealFocus
          clrInput
          #searchLibTreeInput
          placeholder="Libraries"
          name="input"
          [(ngModel)]="librariesSearch"
          (keyup)="libraryOnFilter()"
          autocomplete="off"
        />
        @if (searchLibTreeInput.value.length < 1) {
          <clr-icon shape="search"></clr-icon>
        }
        @if (searchLibTreeInput.value.length > 0) {
          <clr-icon
            (click)="librariesSearch = ''; libraryOnFilter()"
            shape="times"
          ></clr-icon>
        }
      </div>
    </clr-tree-node>
  }

  @for (library of libraryList; track library) {
    @if (!library['hidden'] && library['inForeground']) {
      <clr-tree-node
        #libTreeNode
        (click)="treeNodeClicked($event, library, libraryList)"
        [(clrExpanded)]="library['expanded']"
        [clrLoading]="library['loadingTables'] && !library.tables"
        [class.clr-expanded]="library['expanded']"
      >
        <p
          (click)="
            lib = library.LIBRARYID;
            libraryOnClick(lib || '', library, libTreeNode)
          "
          class="m-0 cursor-pointer"
        >
          <clr-icon shape="rack-server"></clr-icon>
          {{ library.LIBRARYNAME }}
        </p>
        @if (library['tables']) {
          <clr-tree-node class="search-node">
            <div class="tree-search-wrapper">
              <input
                appStealFocus
                clrInput
                #searchTreeInput
                placeholder="Tables"
                name="input"
                [(ngModel)]="library['searchString']"
                (keyup)="treeOnFilter(library, 'tables')"
                autocomplete="off"
              />
              @if (searchTreeInput.value.length < 1) {
                <clr-icon shape="search"></clr-icon>
              }
              @if (searchTreeInput.value.length > 0) {
                <clr-icon
                  (click)="
                    searchTreeInput.value = '';
                    library['searchString'] = '';
                    treeOnFilter(library, 'tables.TABLENAME')
                  "
                  shape="times"
                ></clr-icon>
              }
            </div>
          </clr-tree-node>
        }
        @for (
          libTable of library['tables'];
          track libTable;
          let index = $index
        ) {
          <clr-tree-node
            (click)="treeNodeClicked($event, libTable, library['tables'])"
            [(clrExpanded)]="libTable['expanded']"
            [clrLoading]="libTable['loadingColumns'] && !libTable.columns"
            [class.clr-expanded]="libTable['expanded']"
          >
            <clr-tooltip
              *ngVar="
                index + 1 >
                licenceState.value.tables_in_library_limit as tableLocked
              "
            >
              <button
                clrTooltipTrigger
                (click)="
                  !tableLocked
                    ? tableOnClick(libTable.TABLEURI, libTable, library)
                    : ''
                "
                class="clr-treenode-link"
                [class.dc-locked-control]="tableLocked"
                [class.active]="libTabActive(library.LIBRARYREF, libTable)"
              >
                @switch (libTable.includes('-FC')) {
                  @case (true) {
                    <clr-icon shape="bolt"></clr-icon>
                  }
                  @case (false) {
                    <clr-icon shape="table"></clr-icon>
                  }
                }
                {{ libTable.replace('-FC', '') }}
              </button>
              <clr-tooltip-content
                clrPosition="bottom-right"
                clrSize="lg"
                *clrIfOpen
              >
                @if (tableLocked) {
                  <span>
                    To unlock all tables, contact support&#64;datacontroller.io
                  </span>
                }
              </clr-tooltip-content>
              @if (hasColumns) {
                @if (libTable['columns']) {
                  <clr-tree-node class="search-node">
                    <div class="tree-search-wrapper">
                      <input
                        appStealFocus
                        clrInput
                        #searchTreeInput
                        placeholder="Columns"
                        name="input"
                        [(ngModel)]="libTable['searchString']"
                        (keyup)="treeOnFilter(libTable, 'columns.COLNAME')"
                        autocomplete="off"
                      />
                      @if (searchTreeInput.value.length < 1) {
                        <clr-icon shape="search"></clr-icon>
                      }
                      @if (searchTreeInput.value.length > 0) {
                        <clr-icon
                          (click)="
                            searchTreeInput.value = '';
                            libTable['searchString'] = '';
                            treeOnFilter(libTable, 'columns.COLNAME')
                          "
                          shape="times"
                        ></clr-icon>
                      }
                    </div>
                  </clr-tree-node>
                }
                @for (libColumn of libTable['columns']; track libColumn) {
                  <clr-tree-node>
                    <button
                      (click)="columnOnClick(libColumn, library, libTable)"
                      class="clr-treenode-link"
                      [class.column-active]="libColumnActive(libColumn.COLURI)"
                    >
                      <clr-icon shape="objects"></clr-icon>
                      {{ libColumn.COLNAME }}
                    </button>
                  </clr-tree-node>
                }
              }
            </clr-tooltip>
          </clr-tree-node>
        }
      </clr-tree-node>
    }
  }
</clr-tree>

@if (librariesPaging) {
  <div class="w-100 text-center">
    <span class="spinner spinner-sm"> Loading... </span>
  </div>
}

./dc-tree.component.scss

Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""