src/app/viya-api-explorer/viya-api-explorer.component.ts

Implements

OnInit

Metadata

Relationships

Used by

Depends on

Index

Properties
Methods

Constructor

constructor(helperService: HelperService, sasViyaService: SasViyaService, sasService: SasService, eventService: EventService)
Parameters :
Name Type Optional
helperService HelperService No
sasViyaService SasViyaService No
sasService SasService No
eventService EventService No

Methods

applyQueryParams
applyQueryParams()
Returns : void
collapseTreeItems
collapseTreeItems(tree: any, itemToSkip: any)
Parameters :
Name Type Optional
tree any No
itemToSkip any No
Returns : void
copyBreadcrums
copyBreadcrums()
Returns : void
copyJson
copyJson()
Returns : void
itemOnClick
itemOnClick(item: any)
Parameters :
Name Type Optional
item any No
Returns : void
itemsListOnFilter
itemsListOnFilter()
Returns : void
linkOnClick
linkOnClick(link: Link)
Parameters :
Name Type Optional
link Link No
Returns : void
linksListOnFilter
linksListOnFilter()
Returns : void
loadUrl
loadUrl(url: string)
Parameters :
Name Type Optional
url string No
Returns : void
ngOnInit
ngOnInit()
Returns : void
onBreadcumsClick
onBreadcumsClick(event: any)
Parameters :
Name Type Optional
event any No
Returns : void
onJsonClick
onJsonClick(event: any)
Parameters :
Name Type Optional
event any No
Returns : void
onJsonLinkClick
onJsonLinkClick(link: string)
Parameters :
Name Type Optional
link string No
Returns : void
treeNodeClicked
treeNodeClicked(event: any, item: any, tree: any)
Parameters :
Name Type Optional
event any No
item any No
tree any No
Returns : void
updateSelectedCollection
updateSelectedCollection()
Returns : void

Properties

collection
Type : string
Default value : ''
collectionLoading
Type : boolean
Default value : false
collections
Type : ViyaApis
Default value : {}
endpoint
Type : { url: string; start: number | undefined; limit: number | undefined }
Default value : { url: '', start: -1, limit: -1 }
endpointItems
Type : any[]
Default value : []
endpointJson
Type : any
endpointLinks
Type : Link[]
Default value : []
endpointLoading
Type : boolean
Default value : false
itemsSearch
Type : string
Default value : ''
linksSearch
Type : string
Default value : ''
rawJson
Type : boolean
Default value : false
Public sasjsConfig
Type : SASjsConfig
Default value : new SASjsConfig()
import { Component, OnInit, ViewEncapsulation } from '@angular/core'
import { SASjsConfig } from '@sasjs/adapter'
import { EventService, HelperService, SasService } from '../services'
import { SasViyaService } from '../services/sas-viya.service'
import { globals } from '../_globals'
import { Collection } from './models/collection.model'
import { Link } from './models/link.model'
import { ViyaApis } from './models/viya-apis.models'

@Component({
  selector: 'app-viya-api-explorer',
  templateUrl: './viya-api-explorer.component.html',
  styleUrls: ['./viya-api-explorer.component.scss'],
  host: {
    class: 'content-container'
  },
  encapsulation: ViewEncapsulation.None,
  standalone: false
})
export class ViyaApiExplorerComponent implements OnInit {
  collections: ViyaApis = {}
  collection: string = ''

  endpointLinks: Link[] = []
  endpointItems: any[] = []
  endpointJson: any
  endpoint: {
    url: string
    start: number | undefined
    limit: number | undefined
  } = {
    url: '',
    start: -1,
    limit: -1
  }

  endpointLoading: boolean = false
  collectionLoading: boolean = false
  rawJson: boolean = false

  linksSearch: string = ''
  itemsSearch: string = ''

  public sasjsConfig: SASjsConfig = new SASjsConfig()

  constructor(
    private helperService: HelperService,
    private sasViyaService: SasViyaService,
    private sasService: SasService,
    private eventService: EventService
  ) {}

  ngOnInit(): void {
    this.sasjsConfig = this.sasService.getSasjsConfig()
    this.collections = this.sasViyaService.getAllCollections()
  }

  linksListOnFilter() {
    this.helperService.libraryOnFilter(
      this.endpointLinks,
      this.linksSearch,
      'rel'
    )

    globals.viyaApi.linkssSearch = this.linksSearch
  }

  itemsListOnFilter() {
    this.helperService.libraryOnFilter(
      this.endpointItems,
      this.itemsSearch,
      'name'
    )

    globals.viyaApi.itemsSearch = this.itemsSearch
  }

  linkOnClick(link: Link) {
    this.loadUrl(link.href)
  }

  itemOnClick(item: any) {
    this.loadUrl(item.links[0].href)
  }

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

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

  updateSelectedCollection() {
    globals.viyaApi.selectedCollection = this.collection
    this.endpoint.url = this.collection

    this.collectionLoading = true

    this.sasViyaService.getByCollection(this.collection).subscribe(
      (collection: Collection) => {
        this.endpointLinks = collection.links
        this.endpointItems = collection.items ? collection.items : []
        this.collectionLoading = false

        this.endpointJson = collection

        this.endpoint.start = collection.start
        this.endpoint.limit = collection.limit
      },
      (err: any) => {
        this.collectionLoading = false

        let message = 'Error occurred while sending request'

        if (err.message) message = err.message
        if (err.error) {
          if (err.error.message) message = err.error.message
          if (err.error.remediation)
            message = `${message}\n${err.error.remediation}`
        }

        this.eventService.showAbortModal(null, message, null, 'HTTP Error')
      }
    )
  }

  onJsonLinkClick(link: string) {
    this.loadUrl(link)
  }

  onJsonClick(event: any) {
    event.preventDefault()

    if (event.srcElement.tagName === 'A') {
      const url = event.srcElement.href.split(event.srcElement.host)[1]

      this.loadUrl(url)
    }
  }

  onBreadcumsClick(event: any) {
    event.preventDefault()

    if (!event.srcElement.href) return

    const url = event.srcElement.href.split(event.srcElement.host)[1]

    this.loadUrl(url)
  }

  copyJson() {
    if (this.endpointJson)
      navigator.clipboard.writeText(JSON.stringify(this.endpointJson, null, 2))
  }

  copyBreadcrums() {
    if (this.endpoint && this.endpoint.url)
      navigator.clipboard.writeText(this.endpoint.url)
  }

  applyQueryParams() {
    const start = this.endpoint.start
    const limit = this.endpoint.limit
    const params = `?${start !== undefined ? 'start=' + start : ''}${
      limit !== undefined ? '&limit=' + limit : ''
    }`

    const url = `${this.endpoint.url.split('?')[0]}${params}`
    this.loadUrl(url)
  }

  loadUrl(url: string) {
    this.endpointLoading = true

    this.sasViyaService.getByUrl(url).subscribe(
      (collection: Collection) => {
        this.endpointLinks = collection.links
        this.endpointItems = collection.items ? collection.items : []
        this.endpointJson = collection
        this.endpointLoading = false

        this.endpoint.url = url
        this.endpoint.start = collection.start
        this.endpoint.limit = collection.limit
      },
      (err: any) => {
        this.endpointLoading = false

        let message = 'Error occurred while sending request'

        if (err.message) message = err.message
        if (err.error) {
          if (err.error.message) message = err.error.message
          if (err.error.remediation)
            message = `${message}\n${err.error.remediation}`
        }

        this.eventService.showAbortModal(null, message, null, 'HTTP Error')
      }
    )
  }
}
<app-sidebar>
  <div class="api-collection-dropdown">
    <clr-select-container>
      <label>API Collection</label>
      <select
        clrSelect
        id="repository"
        [(ngModel)]="collection"
        (change)="updateSelectedCollection()"
      >
        @for (collection of collections | keyvalue; track collection) {
          <optgroup [label]="collection.key">
            @for (
              endpoint of collections[collection.key] | keyvalue;
              track endpoint
            ) {
              <option value="{{ endpoint.value }}">
                {{ endpoint.key }}
              </option>
            }
          </optgroup>
        }
      </select>
    </clr-select-container>
  </div>

  @if (endpointLinks.length < 1 && !collectionLoading) {
    <p class="w-100 text-center">Select collection to start</p>
  }

  <div class="d-flex clr-justify-content-center">
    @if (collectionLoading) {
      <clr-spinner clrMedium></clr-spinner>
    }
  </div>

  <clr-tree>
    @if (endpointLinks.length > 0) {
      <clr-tree-node class="search-node">
        <div class="tree-search-wrapper">
          <input
            appStealFocus
            clrInput
            #searchLinksTreeInput
            placeholder="Search links"
            name="input"
            [(ngModel)]="linksSearch"
            (keyup)="linksListOnFilter()"
            autocomplete="off"
          />
          @if (searchLinksTreeInput.value.length < 1) {
            <clr-icon shape="search"></clr-icon>
          }
          @if (searchLinksTreeInput.value.length > 0) {
            <clr-icon
              (click)="linksSearch = ''; linksListOnFilter()"
              shape="times"
            ></clr-icon>
          }
        </div>
      </clr-tree-node>
    }
    @for (link of endpointLinks; track link) {
      @if (!link['hidden']) {
        <clr-tree-node
          (click)="treeNodeClicked($event, link, endpointLinks)"
          [(clrExpanded)]="link['expanded']"
          [clrLoading]="!!link['loadingTables'] && !link.tables"
        >
          <p (click)="linkOnClick(link)" class="m-0 cursor-pointer">
            <clr-icon shape="block"></clr-icon>
            {{ link.method }} {{ link.rel }}
          </p>
        </clr-tree-node>
      }
    }
  </clr-tree>

  <clr-tree>
    @if (endpointItems.length > 0) {
      <clr-tree-node class="search-node">
        <div class="tree-search-wrapper">
          <input
            clrInput
            #searchItemsTreeInput
            placeholder="Search items"
            name="input"
            [(ngModel)]="itemsSearch"
            (keyup)="itemsListOnFilter()"
            autocomplete="off"
          />
          @if (searchItemsTreeInput.value.length < 1) {
            <clr-icon shape="search"></clr-icon>
          }
          @if (searchItemsTreeInput.value.length > 0) {
            <clr-icon
              (click)="itemsSearch = ''; itemsListOnFilter()"
              shape="times"
            ></clr-icon>
          }
        </div>
      </clr-tree-node>
    }
    @for (item of endpointItems; track item) {
      @if (!item['hidden']) {
        <clr-tree-node
          (click)="treeNodeClicked($event, item, endpointItems)"
          [(clrExpanded)]="item['expanded']"
          [clrLoading]="!!item['loadingTables'] && !item.tables"
        >
          <p (click)="itemOnClick(item)" class="m-0 cursor-pointer">
            <clr-icon shape="block"></clr-icon>
            {{ item.name || item.id }}
          </p>
        </clr-tree-node>
      }
    }
  </clr-tree>
</app-sidebar>

<div class="content-area">
  <div class="card h-100 p-10 d-flex clr-flex-column">
    <div
      class="w-100 d-flex clr-align-items-center clr-justify-content-center sition-relative"
    >
      <div class="json-toggle d-flex clr-align-items-center">
        <clr-toggle-container class="m-0">
          <clr-toggle-wrapper>
            <input [(ngModel)]="rawJson" type="checkbox" clrToggle />
            <label>RAW Json</label>
          </clr-toggle-wrapper>
        </clr-toggle-container>

        <button (click)="copyJson()" type="button" class="btn btn-link btn-sm">
          <clr-icon shape="copy"></clr-icon>
        </button>
      </div>

      <h4 class="text-center m-0">
        API Explorer
        @if (endpointLoading) {
          <clr-spinner clrSmall></clr-spinner>
        }
      </h4>
    </div>
    <hr class="w-100 light" />

    @if (collection.length > 0) {
      <div class="d-flex clr-align-items-center clr-justify-content-between">
        <span class="d-flex clr-align-items-center">
          GET
          <p
            (click)="onBreadcumsClick($event)"
            class="text-center endpoint-breadcrums"
            [innerHTML]="endpoint.url | linkinze"
          ></p>
          <button
            (click)="copyBreadcrums()"
            type="button"
            class="btn btn-link btn-sm"
          >
            <clr-icon shape="copy"></clr-icon>
          </button>
        </span>
        <div class="d-flex clr-align-items-center query-params">
          <clr-input-container class="m-0">
            <label>Start</label>
            <input
              clrInput
              type="number"
              [(ngModel)]="endpoint.start"
              [disabled]="endpoint.start === undefined"
            />
          </clr-input-container>
          <clr-input-container class="m-0">
            <label>Limit</label>
            <input
              clrInput
              type="number"
              [(ngModel)]="endpoint.limit"
              [disabled]="endpoint.limit === undefined"
            />
          </clr-input-container>
          <button
            (click)="applyQueryParams()"
            type="button"
            class="btn btn-link btn-sm"
            [disabled]="
              endpoint.limit === undefined && endpoint.start === undefined
            "
          >
            <clr-icon shape="play"></clr-icon>
          </button>
        </div>
      </div>
      <pre class="json-area">
        @if (endpointJson) {
          @if (!rawJson) {
            <ngx-json-viewer class="d-block" [json]="endpointJson" [expanded]="false" (segmentLinkClicked)="onJsonLinkClick($event)"></ngx-json-viewer>
          }
          @if (rawJson) {
            {{ endpointJson | prettyjson }}
          }
        }
      </pre>
    }
  </div>
</div>

./viya-api-explorer.component.scss

Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""