src/app/metadata/metadata.component.ts

Implements

OnInit

Metadata

Relationships

Used by

Depends on

Index

Properties
Methods

Constructor

constructor(eventService: EventService, sasService: SasService, helperService: HelperService, location: Location, router: Router, route: ActivatedRoute)
Parameters :
Name Type Optional
eventService EventService No
sasService SasService No
helperService HelperService No
location Location No
router Router No
route ActivatedRoute No

Methods

Public assosiationNameOnClick
assosiationNameOnClick(assosiationId: any)
Parameters :
Name Type Optional
assosiationId any No
Returns : void
Public collapseTreeItems
collapseTreeItems(tree: any, itemToSkip: any)
Parameters :
Name Type Optional
tree any No
itemToSkip any No
Returns : void
Public getAssosiationsCount
getAssosiationsCount(assosiationList: Array)
Parameters :
Name Type Optional
assosiationList Array<any> No
Returns : Array<any>
Public getMetaObjectAttributes
getMetaObjectAttributes(num: number)
Parameters :
Name Type Optional
num number No
Returns : void
Public metaDataOnClick
metaDataOnClick(metaDataId: string, metaData: any)
Parameters :
Name Type Optional
metaDataId string No
metaData any No
Returns : void
Public metaListOnFilter
metaListOnFilter()
Returns : void
Public metaObjectOnClick
metaObjectOnClick(metaObjectId: string, metaObject: any)
Parameters :
Name Type Optional
metaObjectId string No
metaObject any No
Returns : void
Public metaObjectOnFilter
metaObjectOnFilter()
Returns : void
ngOnInit
ngOnInit()
Returns : void
panelChange
panelChange(event: boolean, object: any)
Parameters :
Name Type Optional
event boolean No
object any No
Returns : void
Public Async selectAssosiationsDetails
selectAssosiationsDetails($event: any, metaData?: any)
Parameters :
Name Type Optional
$event any No
metaData any Yes
Returns : any
Public Async selectmetaData
selectmetaData($event: any, metaData?: any)
Parameters :
Name Type Optional
$event any No
metaData any Yes
Returns : any
Public Async selectmetaObject
selectmetaObject($event: any, metaData?: any)
Parameters :
Name Type Optional
$event any No
metaData any Yes
Returns : any
Public setTypeAssosiations
setTypeAssosiations(assosiationType: String)
Parameters :
Name Type Optional
assosiationType String No
Returns : Array<any>
Public treeNodeClicked
treeNodeClicked(event: any, item: any, tree: any)
Parameters :
Name Type Optional
event any No
item any No
tree any No
Returns : void
updateSelectedRepository
updateSelectedRepository()
Returns : void

Properties

Public assoObjectSelected
Type : string
Default value : ''
assosiationNames
Type : Array<any> | undefined
assosiationProperties
Type : Array<any> | undefined
Public assoTypeSelected
Type : string
Default value : ''
debounce
Type : boolean
Default value : false
Public getChildren
Type : unknown
Default value : () => {...}
Public loading
Type : boolean
Default value : true
Public metaDataId
Type : string
Default value : ''
metaDataList
Type : Array<any> | undefined
metaDataSearch
Type : string
Default value : ''
metaObjectAssociations
Type : Array<any>
Default value : []
metaObjectAttributes
Type : Array<any>
Default value : []
metaObjectList
Type : Array<any> | undefined
metaObjectSearch
Type : string
Default value : ''
metaObjectShowList
Type : Array<any> | undefined
Public metaObjectSize
Type : number
Default value : 200
Public metatypesLoading
Type : unknown
Default value : true
Public nameFilter
Type : any
Public objectRoute
Type : unknown
Default value : false
Public objectView
Type : unknown
Default value : false
Public pageSize
Type : number
Public repositories
Type : Array<any> | undefined
Public repository
Type : string
Default value : ''
root$
Type : Observable<string[]> | undefined
showAcc
Type : boolean
Default value : false
Public showData
Type : unknown
Default value : false
showTable
Type : boolean
Default value : false
Public typeFilter
Type : any
Public valueFilter
Type : any
import { Location } from '@angular/common'
import { Component, OnInit, ViewEncapsulation } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'
import { ClrDatagridStringFilterInterface } from '@clr/angular'
import { Observable, of } from 'rxjs'
import { EventService } from '../services/event.service'
import { HelperService } from '../services/helper.service'
import { SasService } from '../services/sas.service'
import { globals } from '../_globals'

import { Injectable } from '@angular/core'
import { RequestWrapperResponse } from '../models/request-wrapper/RequestWrapperResponse'

interface MetaData {
  NAME: any
  TYPE: any
  VALUE: any
}
class NameFilter implements ClrDatagridStringFilterInterface<MetaData> {
  accepts(data: MetaData, search: string): boolean {
    return (
      '' + data.NAME === search || data.NAME.toLowerCase().indexOf(search) >= 0
    )
  }
}

class TypeFilter implements ClrDatagridStringFilterInterface<MetaData> {
  accepts(data: MetaData, search: string): boolean {
    return (
      '' + data.TYPE === search || data.TYPE.toLowerCase().indexOf(search) >= 0
    )
  }
}

class ValueFilter implements ClrDatagridStringFilterInterface<MetaData> {
  accepts(data: MetaData, search: string): boolean {
    return (
      '' + data.VALUE === search ||
      data.VALUE.toLowerCase().indexOf(search) >= 0
    )
  }
}

@Injectable({
  providedIn: 'root'
})
@Component({
  selector: 'app-metadata',
  templateUrl: './metadata.component.html',
  styleUrls: ['./metadata.component.scss'],
  host: {
    class: 'content-container'
  },
  encapsulation: ViewEncapsulation.None,
  standalone: false
})
export class MetadataComponent implements OnInit {
  metaDataList: Array<any> | undefined
  metaDataSearch: string = ''
  metaObjectList: Array<any> | undefined
  metaObjectShowList: Array<any> | undefined
  metaObjectSearch: string = ''
  metaObjectAssociations: Array<any> = []
  metaObjectAttributes: Array<any> = []
  assosiationNames: Array<any> | undefined
  assosiationProperties: Array<any> | undefined
  showTable: boolean = false
  showAcc: boolean = false
  root$: Observable<string[]> | undefined
  public metaDataId: string = ''
  public typeFilter: any
  public nameFilter: any
  public valueFilter: any
  public pageSize!: number
  public loading: boolean = true
  public metatypesLoading = true
  public metaObjectSize = 200
  public assoTypeSelected = ''
  public assoObjectSelected = ''
  public repositories: Array<any> | undefined
  public repository = ''
  public objectRoute = false
  public showData = false
  public objectView = false

  constructor(
    private eventService: EventService,
    private sasService: SasService,
    private helperService: HelperService,
    private location: Location,
    private router: Router,
    private route: ActivatedRoute
  ) {}

  ngOnInit() {
    globals.viewer.currentSelection = 'view/metadata'
    if (this.router.url.includes('/view/metadata/object/')) {
      this.objectRoute = true
      this.objectView = true
    }
    this.pageSize = 5

    // Initialize filters for accessibility
    this.typeFilter = new TypeFilter()
    this.nameFilter = new NameFilter()
    this.valueFilter = new ValueFilter()

    if (
      globals.metadata.metaDataList &&
      globals.metadata.metaRepositories &&
      !this.objectRoute
    ) {
      this.metaDataList = globals.metadata.metaDataList
      this.repositories = globals.metadata.metaRepositories
      this.repository = globals.metadata.selectedRepository
      this.loading = false
      this.metatypesLoading = false
      this.metaDataSearch = globals.metadata.metaDataSearch
    } else {
      this.sasService
        .request('metanav/metatypes', null)
        .then((res: RequestWrapperResponse) => {
          this.metaDataList = res.adapterResponse.types
          globals.metadata.metaDataList = this.metaDataList
          this.loading = false
          this.metatypesLoading = false
        })

      this.sasService
        .request('metanav/metarepos', null)
        .then((res: RequestWrapperResponse) => {
          let foundation = false
          this.repositories = []
          for (
            let index = 0;
            index < res.adapterResponse.outrepos.length;
            index++
          ) {
            this.repositories.push(res.adapterResponse.outrepos[index].NAME)
            if (res.adapterResponse.outrepos[index].NAME === 'Foundation') {
              foundation = true
            }
          }
          if (foundation) {
            this.repository = 'Foundation'
          } else {
            this.repository = res.adapterResponse.outrepos[0].NAME
          }
          globals.metadata.metaRepositories = this.repositories
          globals.metadata.selectedRepository = this.repository
          if (this.objectRoute) {
            this.eventService.closeSidebar()
            this.showData = true
            let name = ''
            let id = this.route.snapshot.params['objectID']
            // let temp = this.router.url.split("%20").join(" ").split("/").reverse();
            this.metaObjectList = []
            this.metaObjectList.push({ ID: id, NAME: name })
            this.metaObjectShowList = this.metaObjectList
            this.metaObjectOnClick(
              this.metaObjectShowList[0].ID,
              this.metaObjectShowList[0]
            )
          }
        })
    }
  }

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

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

  public metaDataOnClick(metaDataId: string, metaData: any) {
    this.objectView = false
    this.location.replaceState('/view/metadata')
    this.showData = false
    this.loading = true
    this.selectmetaData(metaDataId, metaData)
  }

  public metaObjectOnClick(metaObjectId: string, metaObject: any) {
    this.assoObjectSelected = ' . '
    this.showAcc = false
    this.metaObjectAttributes = []
    this.selectmetaObject(metaObjectId, metaObject)
  }

  public async selectmetaData($event: any, metaData?: any) {
    const data: any = {
      SASControlTable: [{ metatype: $event, repo: this.repository }]
    }
    this.sasService
      .request('metanav/metaobjects', data)
      .then((res: RequestWrapperResponse) => {
        this.metaObjectList = res.adapterResponse.objects
        this.getMetaObjectAttributes(this.metaObjectSize)
        this.loading = false
        this.assoTypeSelected = $event
        this.eventService.closeSidebar()
        this.showData = true
      })
  }

  public async selectmetaObject($event: any, metaData?: any) {
    let data: any = {
      SASControlTable: [{ objecturi: $event }]
    }
    this.sasService
      .request('metanav/metadetails', data)
      .then((res: RequestWrapperResponse) => {
        this.metaObjectAssociations = res.adapterResponse.associations
        this.root$ = of(
          this.getAssosiationsCount(res.adapterResponse.associations)
        )
        this.showAcc = true
        this.showTable = true
        let metaObjectName = res.adapterResponse.attributes.find(
          (x: any) => x.NAME === 'Name'
        ).VALUE
        this.assoObjectSelected = metaObjectName
        metaData.NAME = metaObjectName
        let url = this.router.url
        if (this.objectRoute) {
          // this.location.replaceState(url.slice(0, url.lastIndexOf("object")) + "object/" + $event.slice(1 + $event.indexOf("\\")) + "/" + escape(metaData.NAME));
          this.location.replaceState(
            url.slice(0, url.lastIndexOf('object')) +
              'object/' +
              $event.slice(1 + $event.indexOf('\\'))
          )
        } else {
          // this.location.replaceState(url + "/object/" + $event.slice(1 + $event.indexOf("\\")) + "/" + escape(metaData.NAME));
          this.location.replaceState(
            url + '/object/' + $event.slice(1 + $event.indexOf('\\'))
          )
        }
        this.metaObjectAttributes = res.adapterResponse.attributes
      })
  }

  public async selectAssosiationsDetails($event: any, metaData?: any) {
    let data: any = {
      SASControlTable: [{ objecturi: $event }]
    }
    this.sasService
      .request('metanav/metadetails', data)
      .then((res: RequestWrapperResponse) => {
        this.metaObjectAttributes = res.adapterResponse.attributes
        this.showTable = true
      })
  }

  public getAssosiationsCount(assosiationList: Array<any>) {
    let assosiationsHash = new Map()
    for (let assosiation of assosiationList) {
      if (!assosiationsHash.has(assosiation.ASSOC)) {
        assosiationsHash.set(assosiation.ASSOC, {
          count: 0,
          details: []
        })
      }
      let assocObj: any = assosiationsHash.get(assosiation.ASSOC)
      assocObj.count++
      assocObj.details.push({
        ASSOCURI: assosiation.ASSOCURI,
        NAME: assosiation.NAME,
        display: assosiation.NAME,
        URI: assosiation.ASSOCURI.slice(assosiation.ASSOCURI.indexOf(':') + 1)
      })
    }
    let assocGrouped: Array<any> = []
    assosiationsHash.forEach(function (val: any, key) {
      assocGrouped.push({
        ASSOC: key,
        count: val.count,
        details: val.details,
        display: key + ' ( ' + val.count + ' )'
      })
    })
    return assocGrouped
  }

  public setTypeAssosiations(assosiationType: String) {
    let tempAssosiations: Array<any> = []
    for (let assosiation of this.metaObjectAssociations) {
      if (assosiation.ASSOC === assosiationType) {
        tempAssosiations.push(assosiation)
      }
    }
    this.assosiationNames = tempAssosiations
    return tempAssosiations
  }

  public assosiationNameOnClick(assosiationId: any) {
    this.assoObjectSelected = ' . '
    this.metaObjectAttributes = []
    this.showTable = false
    this.selectAssosiationsDetails(assosiationId)
  }

  public getChildren = (asso: any) => {
    // if group_association clicked return list of Objects
    if (asso.count) {
      return of(asso.details)
    }
    // else return following api response
    const data: any = {
      SASControlTable: [{ objecturi: asso.ASSOCURI }]
    }
    return this.sasService
      .request('metanav/metadetails', data)
      .then((res: RequestWrapperResponse) => {
        this.showTable = true
        this.metaObjectAttributes = res.adapterResponse.attributes
        this.assoObjectSelected = asso.NAME
        let url = this.router.url
        if (this.objectRoute) {
          // this.location.replaceState(url.slice(0, url.lastIndexOf("object")) + "object/" +asso.ASSOCURI.slice(1 + asso.ASSOCURI.indexOf("\\")) + "/" + escape(asso.NAME));
          this.location.replaceState(
            url.slice(0, url.lastIndexOf('object')) +
              'object/' +
              asso.ASSOCURI.slice(1 + asso.ASSOCURI.indexOf('\\'))
          )
        } else {
          // this.location.replaceState( url + "/object/" + asso.ASSOCURI.slice(1 + asso.ASSOCURI.indexOf("\\")) + "/" + escape(asso.NAME));
          this.location.replaceState(
            url +
              '/object/' +
              asso.ASSOCURI.slice(1 + asso.ASSOCURI.indexOf('\\'))
          )
        }
        return this.getAssosiationsCount(res.adapterResponse.associations)
      })
  }

  public metaListOnFilter() {
    this.helperService.libraryOnFilter(
      this.metaDataList,
      this.metaDataSearch,
      'ID'
    )

    globals.metadata.metaDataSearch = this.metaDataSearch
  }

  public metaObjectOnFilter() {
    this.metaObjectAttributes = []
    this.helperService.metaObjectOnFilter(
      this.metaObjectList,
      this.metaObjectSearch,
      'NAME'
    )
    this.getMetaObjectAttributes(this.metaObjectSize)
    globals.metadata.metaObjectSearch = this.metaObjectSearch
  }

  public getMetaObjectAttributes(num: number) {
    if (this.metaObjectList !== undefined && this.metaObjectList.length > num) {
      let counter = 0
      let breakIndex = -1
      for (let index = 0; index < this.metaObjectList.length; index++) {
        if (
          this.metaObjectList[index]['hidden'] === undefined ||
          this.metaObjectList[index]['hidden'] === false
        ) {
          counter++
        }
        if (counter === num) {
          breakIndex = index
          break
        }
      }
      if (breakIndex !== -1) {
        this.metaObjectShowList = this.metaObjectList.slice(0, breakIndex)
      } else {
        this.metaObjectShowList = this.metaObjectList
      }
    } else {
      this.metaObjectShowList = this.metaObjectList
    }
  }

  debounce: boolean = false
  panelChange(event: boolean, object: any) {
    if (!this.debounce) {
      this.metaObjectOnClick(object.ID, object)

      this.debounce = true

      setTimeout(() => {
        this.debounce = false
      }, 600)
    }
  }

  updateSelectedRepository() {
    globals.metadata.selectedRepository = this.repository
  }
}
<app-sidebar>
  <div class="repo-dropdown">
    <clr-select-container>
      <label>Metadata Repository</label>
      <select
        clrSelect
        id="repository"
        [(ngModel)]="repository"
        (change)="updateSelectedRepository()"
      >
        @for (repository of repositories; track repository) {
          <option value="{{ repository }}">
            {{ repository }}
          </option>
        }
      </select>
    </clr-select-container>
  </div>

  <clr-tree>
    @if (metaDataList) {
      <clr-tree-node class="search-node">
        <div class="tree-search-wrapper">
          <input
            appStealFocus
            clrInput
            #searchLibTreeInput
            placeholder="search SAS Types"
            name="input"
            [(ngModel)]="metaDataSearch"
            (keyup)="metaListOnFilter()"
            autocomplete="off"
          />
          @if (searchLibTreeInput.value.length < 1) {
            <clr-icon shape="search"></clr-icon>
          }
          @if (searchLibTreeInput.value.length > 0) {
            <clr-icon
              (click)="metaDataSearch = ''; metaListOnFilter()"
              shape="times"
            ></clr-icon>
          }
        </div>
      </clr-tree-node>
    }
    @for (metaData of metaDataList; track metaData) {
      @if (!metaData['hidden']) {
        <clr-tree-node
          (click)="treeNodeClicked($event, metaData, metaDataList)"
          [(clrExpanded)]="metaData['expanded']"
          [clrLoading]="metaData['loadingTables'] && !metaData.tables"
        >
          <p
            (click)="
              metaDataId = metaData.ID; metaDataOnClick(metaDataId, metaData)
            "
            class="m-0 cursor-pointer"
          >
            <clr-icon shape="block"></clr-icon>
            {{ metaData.ID }}
          </p>
        </clr-tree-node>
      }
    }
  </clr-tree>
</app-sidebar>

<div class="content-area">
  <div class="card background-transparent-i">
    <h3 class="color-gray">{{ assoTypeSelected }}</h3>

    @if (!loading && !metaObjectList) {
      <div class="no-table-selected">
        <clr-icon
          shape="warning-standard"
          size="60"
          class="is-info icon-dc-fill"
        ></clr-icon>
        <p class="text-center color-gray mt-10" cds-text="section">
          Please select a type
        </p>
      </div>
    }

    @if (loading) {
      <div class="loadingSpinner">
        <span class="spinner"> Loading... </span>
        @if (loading) {
          <div>
            @if (metatypesLoading) {
              <h4>Loading metadata types</h4>
            }
            @if (!metatypesLoading) {
              <h4>Loading metadata objects</h4>
            }
          </div>
        }
      </div>
    }
    @if (showData) {
      <div class="clr-row clr-flex-grow-1">
        <div class="clr-col-6">
          @if (metaObjectList && !objectRoute) {
            <div class="search-input">
              <input
                clrInput
                #searchObjTreeInput
                placeholder="search"
                name="input"
                [(ngModel)]="metaObjectSearch"
                (keyup)="metaObjectOnFilter()"
                autocomplete="off"
              />
            </div>
          }
          <br />
          @if (!objectView) {
            <div class="objects-col">
              <clr-accordion>
                @for (metaObject of metaObjectShowList; track metaObject) {
                  @if (!metaObject['hidden']) {
                    <clr-accordion-panel
                      (clrAccordionPanelOpenChange)="
                        $event ? panelChange($event, metaObject) : ''
                      "
                    >
                      <clr-accordion-title
                        ><clr-icon shape="rack-server"></clr-icon>
                        {{ metaObject.NAME }}
                        <p class="float-right">{{ metaObject.ID }}</p>
                      </clr-accordion-title>
                      <clr-accordion-content *clrIfExpanded>
                        @if (showAcc) {
                          <clr-tree [clrLazy]="true">
                            <clr-tree-node
                              *clrRecursiveFor="
                                let entry of root$ | async;
                                getChildren: getChildren
                              "
                              [clrExpandable]="true"
                            >
                              <div
                                [class.object-header]="!entry.count"
                                class="full-width"
                              >
                                <div>
                                  @if (!entry.count) {
                                    <clr-icon shape="rack-server"></clr-icon>
                                  }
                                  @if (entry.count) {
                                    <clr-icon shape="block"></clr-icon>
                                  }
                                  {{ entry.display }}
                                </div>
                                @if (!entry.count) {
                                  <p class="float-right object-uri">
                                    {{ entry.URI }}
                                  </p>
                                }
                              </div>
                            </clr-tree-node>
                          </clr-tree>
                        }
                      </clr-accordion-content>
                    </clr-accordion-panel>
                  }
                }
              </clr-accordion>
            </div>
          }
          @if (objectView) {
            <div class="objects-col">
              @for (metaObject of metaObjectShowList; track metaObject) {
                <div class="cols-head">
                  <clr-icon shape="rack-server"></clr-icon>
                  <div class="object-text">
                    <p class="m-0 word-break mr-20">
                      {{ metaObject.NAME }}
                    </p>
                    <p class="float-right ml-3">
                      {{ metaObject.ID }}
                    </p>
                  </div>
                </div>
                @if (showAcc) {
                  <clr-tree [clrLazy]="true">
                    <clr-tree-node
                      *clrRecursiveFor="
                        let entry of root$ | async;
                        getChildren: getChildren
                      "
                      [clrExpandable]="true"
                    >
                      <div
                        [class.object-header]="!entry.count"
                        class="full-width"
                      >
                        <div>
                          @if (!entry.count) {
                            <clr-icon shape="rack-server"></clr-icon>
                          }
                          @if (entry.count) {
                            <clr-icon shape="block"></clr-icon>
                          }
                          {{ entry.display }}
                        </div>
                        @if (!entry.count) {
                          <p class="float-right object-uri">
                            {{ entry.URI }}
                          </p>
                        }
                      </div>
                    </clr-tree-node>
                  </clr-tree>
                }
              }
            </div>
          }
        </div>
        <div class="clr-col-6 text-center">
          <h3>{{ assoObjectSelected }}</h3>
          @if (showTable) {
            <clr-datagrid class="datagrid-custom-footer">
              <clr-dg-column>
                TYPE
                <clr-dg-string-filter
                  [clrDgStringFilter]="typeFilter"
                ></clr-dg-string-filter>
              </clr-dg-column>
              <clr-dg-column>
                NAME
                <clr-dg-string-filter
                  [clrDgStringFilter]="nameFilter"
                ></clr-dg-string-filter>
              </clr-dg-column>
              <clr-dg-column>
                VALUE
                <clr-dg-string-filter
                  [clrDgStringFilter]="valueFilter"
                ></clr-dg-string-filter>
              </clr-dg-column>
              <clr-dg-row
                *clrDgItems="let metaObjectAttribute of metaObjectAttributes"
              >
                <clr-dg-cell>{{ metaObjectAttribute.TYPE }}</clr-dg-cell>
                <clr-dg-cell>{{ metaObjectAttribute.NAME }}</clr-dg-cell>
                <clr-dg-cell>{{ metaObjectAttribute.VALUE }}</clr-dg-cell>
              </clr-dg-row>
              <clr-dg-footer>
                <clr-dg-pagination #pagination [clrDgPageSize]="10">
                  <clr-dg-page-size [clrPageSizeOptions]="[10, 20, 50, 100]"
                    >Attributes per page</clr-dg-page-size
                  >
                  {{ pagination.firstItem + 1 }} -
                  {{ pagination.lastItem + 1 }} of
                  {{ pagination.totalItems }} Attributes
                </clr-dg-pagination>
              </clr-dg-footer>
            </clr-datagrid>
          }
        </div>
      </div>
    }
  </div>
</div>

./metadata.component.scss

Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""