Methods
|
applyQueryParams
|
applyQueryParams()
|
|
|
|
|
|
collapseTreeItems
|
collapseTreeItems(tree: any, itemToSkip: any)
|
|
|
Parameters :
| Name |
Type |
Optional |
| tree |
any
|
No
|
| itemToSkip |
any
|
No
|
|
|
copyBreadcrums
|
copyBreadcrums()
|
|
|
|
|
|
itemOnClick
|
itemOnClick(item: any)
|
|
|
Parameters :
| Name |
Type |
Optional |
| item |
any
|
No
|
|
|
itemsListOnFilter
|
itemsListOnFilter()
|
|
|
|
|
|
linkOnClick
|
linkOnClick(link: Link)
|
|
|
Parameters :
| Name |
Type |
Optional |
| link |
Link
|
No
|
|
|
linksListOnFilter
|
linksListOnFilter()
|
|
|
|
|
|
loadUrl
|
loadUrl(url: string)
|
|
|
Parameters :
| Name |
Type |
Optional |
| url |
string
|
No
|
|
|
onBreadcumsClick
|
onBreadcumsClick(event: any)
|
|
|
Parameters :
| Name |
Type |
Optional |
| event |
any
|
No
|
|
|
onJsonClick
|
onJsonClick(event: any)
|
|
|
Parameters :
| Name |
Type |
Optional |
| event |
any
|
No
|
|
|
onJsonLinkClick
|
onJsonLinkClick(link: string)
|
|
|
Parameters :
| Name |
Type |
Optional |
| link |
string
|
No
|
|
|
treeNodeClicked
|
treeNodeClicked(event: any, item: any, tree: any)
|
|
|
Parameters :
| Name |
Type |
Optional |
| event |
any
|
No
|
| item |
any
|
No
|
| tree |
any
|
No
|
|
|
updateSelectedCollection
|
updateSelectedCollection()
|
|
|
|
|
|
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 : []
|
|
|
|
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>
Legend
Html element with directive