Files
dc/client/src/app/viewer/viewer.component.html
Mihajlo Medjedovic ab89600c73
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 47s
style: lint
2023-12-04 18:37:05 +01:00

660 lines
20 KiB
HTML

<app-sidebar (scrolledToBottom)="loadMoreLibraries()">
<div *ngIf="librariesLoading" class="my-10-mx-auto text-center">
<clr-spinner clrMedium></clr-spinner>
</div>
<clr-tree>
<clr-tree-node *ngIf="libraries" class="search-node">
<div class="tree-search-wrapper">
<input
clrInput
#searchLibTreeInput
[(ngModel)]="librariesSearch"
placeholder="Libraries"
name="input"
(keyup)="libraryOnFilter()"
autocomplete="off"
/>
<clr-icon
*ngIf="searchLibTreeInput.value.length < 1"
shape="search"
></clr-icon>
<clr-icon
*ngIf="searchLibTreeInput.value.length > 0"
(click)="librariesSearch = ''; libraryOnFilter()"
shape="times"
></clr-icon>
</div>
</clr-tree-node>
<ng-container *ngFor="let library of libraries">
<clr-tree-node
(click)="treeNodeClicked($event, library)"
*ngIf="!library['hidden'] && library['inForeground']"
[(clrExpanded)]="library['expanded']"
[clrLoading]="library['loadingTables'] && !library.tables"
[class.clr-expanded]="library['expanded']"
>
<p
(click)="
lib = library.LIBRARYREF;
libraryOnClick(library.LIBRARYREF, library)
"
class="m-0 cursor-pointer"
>
<clr-icon shape="rack-server"></clr-icon>
{{ library.LIBRARYNAME }}
</p>
<clr-tree-node *ngIf="library['tables']" class="search-node">
<div class="tree-search-wrapper">
<input
clrInput
#searchTreeInput
[id]="'search_' + library.LIBRARYREF"
placeholder="Tables"
name="input"
[(ngModel)]="library['searchString']"
(keyup)="treeOnFilter(library, 'tables')"
autocomplete="off"
/>
<clr-icon
*ngIf="searchTreeInput.value.length < 1"
shape="search"
></clr-icon>
<clr-icon
*ngIf="searchTreeInput.value.length > 0"
(click)="
searchTreeInput.value = '';
library['searchString'] = '';
treeOnFilter(library, 'tables')
"
shape="times"
></clr-icon>
</div>
</clr-tree-node>
<clr-tree-node
*ngFor="let libTable of library['tables']; let index = index"
>
<clr-tooltip
*ngVar="
index + 1 >
licenceState.value.tables_in_library_limit as tableLocked
"
>
<button
clrTooltipTrigger
*ngIf="libTable.length > 0"
(click)="!tableLocked ? onTableClick(libTable, library) : ''"
class="clr-treenode-link"
[class.dc-locked-control]="tableLocked"
[class.table-active]="libTabActive(library.LIBRARYREF, libTable)"
>
<ng-container [ngSwitch]="libTable.includes('-FC')">
<clr-icon *ngSwitchCase="true" shape="bolt"></clr-icon>
<clr-icon *ngSwitchCase="false" shape="table"></clr-icon>
</ng-container>
{{ libTable.replace('-FC', '') }}
</button>
<clr-tooltip-content
clrPosition="bottom-right"
clrSize="lg"
*clrIfOpen
>
<span *ngIf="tableLocked">
To unlock all tables, contact support&#64;datacontroller.io
</span>
</clr-tooltip-content>
</clr-tooltip>
</clr-tree-node>
</clr-tree-node>
</ng-container>
</clr-tree>
<div *ngIf="librariesPaging" class="w-100 text-center">
<span class="spinner spinner-sm"> Loading... </span>
</div>
</app-sidebar>
<div class="content-area">
<div class="modal z-index-highest" *ngIf="nullVariables">
<div class="modal-dialog" role="dialog" aria-hidden="true">
<div class="modal-content">
<div class="modal-header">
<button aria-label="Close" class="close" type="button">
<clr-icon aria-hidden="true" shape="close"></clr-icon>
</button>
<h3 class="modal-title">Error</h3>
</div>
<div class="modal-body">
<p>You cannot submit empty clauses</p>
</div>
<div class="modal-footer">
<button
class="btn btn-sm btn-primary"
(click)="nullVariables = false"
type="button"
>
Ok
</button>
</div>
</div>
</div>
</div>
<div *ngIf="nullVariables" class="modal-backdrop" aria-hidden="true"></div>
<clr-modal [(clrModalOpen)]="openDownload" [clrModalSize]="'md'">
<h3 class="modal-title center text-center color-darker-gray">Download</h3>
<div class="modal-body">
<div class="clr-col-md-6">
<clr-select-container class="download-select">
<label>Please choose download format</label>
<select [(ngModel)]="downloadFormat" clrSelect>
<option value="CSV">CSV</option>
<option value="SAS">Datalines (cards file)</option>
<option value="PGSQL_DDL">DDL (PGSQL Flavour)</option>
<option value="SAS_DDL">DDL (SAS Flavour)</option>
<option value="TSQL_DDL">DDL (TSQL Flavour)</option>
<option value="EXCEL">Excel (.xlsx)</option>
<option value="MARKDOWN">Markdown (.md)</option>
</select>
</clr-select-container>
</div>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-sm btn-outline"
(click)="openDownload = false"
>
Cancel
</button>
<button
[id]="tableTitle"
type="submit"
class="btn btn-sm btn-success-outline"
(click)="
downloadFormat.includes('DDL') ? downloadDDL() : downloadData()
"
>
Ok
</button>
</div>
</clr-modal>
<clr-modal [(clrModalOpen)]="webQuery" [clrModalSize]="'lg'">
<h3 class="modal-title center text-center color-darker-gray">
Web Query URL
</h3>
<div class="modal-body web-query">
<div class="row">
<div class="clr-col-lg-12 clr-col-md-12 clr-col-sm-12 clr-col-xs-12">
<div class="card">
<div class="card-header d-flex justify-content-between">
<span>Copy the below into your preferred client tool:</span>
<div class="d-block mr-0" class="btn-group">
<div
class="radio btn"
(click)="webQueryTab = true; showWebQuery()"
>
<input
type="radio"
name="btn-group-demo-radios"
[checked]="webQueryTab"
/>
<label>TAB</label>
</div>
<div
class="radio btn"
(click)="webQueryTab = false; showWebQuery()"
>
<input
type="radio"
name="btn-group-demo-radios"
[checked]="!webQueryTab"
/>
<label>CSV</label>
</div>
</div>
</div>
<div class="card-block word-break-all">
<textarea
class="web-query-text w-100"
rows="4"
cols="50"
#cliCommandInput
(focus)="onCliCommandFocus($event)"
type="text"
value="{{ webQueryText }}"
readonly
>
</textarea>
</div>
<div class="card-footer">
<button
class="btn btn-sm btn-link"
[ngxClipboard]="cliCommandInput"
(click)="copyToClip()"
>
copy to clipboard
</button>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-sm btn-outline"
(click)="webQuery = false"
>
close
</button>
<!-- <button type="submit" class="btn btn-sm btn-success-outline" (click)="downloadData()">Ok</button> -->
</div>
</clr-modal>
<clr-modal
[(clrModalOpen)]="filter"
[clrModalSize]="'xl'"
[clrModalClosable]="false"
aria-modal="true"
class="filter-modal"
>
<h3 class="modal-title center text-center color-darker-gray">
Filter for table:<span> {{ libTab }} </span>
</h3>
<div class="modal-body">
<app-query #queryFilter *ngIf="filter"></app-query>
</div>
<div class="modal-footer">
<button (click)="resetFilter()" type="button" class="btn btn-sm btn-link">
reset filter
</button>
<button
type="button"
class="btn btn-outline btn-sm"
(click)="filter = false; removeQuery()"
>
Cancel
</button>
<button
[clrLoading]="submitLoading"
type="submit"
class="btn btn-sm btn-success-outline"
(click)="sendClause()"
>
Ok
</button>
</div>
</clr-modal>
<clr-modal [(clrModalOpen)]="queryErr">
<h3 class="modal-title">Error</h3>
<div class="modal-body">
<p>{{ queryErrMessage }}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline" (click)="queryErr = false">
Cancel
</button>
<button type="button" class="btn btn-primary" (click)="queryErr = false">
Ok
</button>
</div>
</clr-modal>
<div class="loadingSpinner" *ngIf="loadingTableView">
<span class="spinner"> Loading... </span>
<div>
<h4>Loading table viewer</h4>
</div>
</div>
<div class="card h-100 d-flex clr-flex-column" *ngIf="!loadingTableView">
<div
*ngIf="table"
class="header-row clr-row justify-content-between clr-justify-content-center w-100 m-0"
>
<section class="form-block table-search-wrapper sw clr-col-md">
<form class="d-flex align-items-center" clrForm>
<div class="input-wrapper">
<input
#searchEl
(keyup.enter)="searchTable(searchEl)"
clrInput
[type]="searchNumeric ? 'number' : 'text'"
placeholder="Search"
name="search-input"
/>
<clr-icon
*ngIf="!searchLoading"
(click)="searchTable(searchEl)"
shape="search"
></clr-icon>
<span *ngIf="searchLoading" class="spinner spinner-inline">
Loading...
</span>
</div>
<clr-checkbox-container>
<clr-checkbox-wrapper>
<input
type="checkbox"
clrCheckbox
[(ngModel)]="searchNumeric"
name="numeric_check"
/>
<label>Numeric</label>
</clr-checkbox-wrapper>
</clr-checkbox-container>
</form>
</section>
<div class="title-col clr-col-auto clr-flex-column clr-flex-sm-row">
<clr-icon
(click)="datasetInfo = true"
shape="info-circle"
class="is-highlight cursor-pointer"
size="24"
></clr-icon>
<clr-icon
*ngIf="tableTitle?.includes('-FC')"
shape="bolt"
class="color-yellow mt-5 mr-5"
></clr-icon>
<h3
*ngIf="tableTitle && tableTitle.length > 0"
class="viewerTitle clr-flex-column d-flex clr-flex-sm-row clr-align-items-center"
>
{{ tableTitle?.replace('-FC', '') }}
<span *ngIf="numberOfRows !== null">
({{ numberOfRows | thousandSeparator: ',' }}
{{ numberOfRows! === 1 ? 'row' : 'rows' }}, {{ filterCols.length
}}{{ filterCols.length === 1 ? ' col' : ' cols' }})
</span>
<clr-icon
(click)="reloadTableData()"
class="refresh-table"
shape="refresh"
></clr-icon>
</h3>
</div>
<div class="options-col clr-col-md">
<clr-dropdown
*ngIf="tableTitle && !abortActive"
class="options-dropdown"
[clrCloseMenuOnItemClick]="true"
>
<button
type="button"
class="btn btn-sm btn-outline filterSide"
clrDropdownTrigger
>
<clr-icon shape="cog" size="15"></clr-icon>
options
</button>
<clr-dropdown-menu clrPosition="bottom-right" *clrIfOpen>
<button
type="button"
class="btn btn-sm btn-success-outline"
(click)="newViewbox()"
clrDropdownItem
>
<clr-icon shape="view-cards"></clr-icon>
<span>Viewboxes</span>
</button>
<button
type="button"
class="btn btn-sm btn-success-outline"
*ngIf="tableEditExists()"
(click)="editTable()"
clrDropdownItem
>
<clr-icon shape="pencil"></clr-icon>
<span>Edit</span>
</button>
<button
type="button"
class="btn btn-sm btn-success-outline"
*ngIf="tableuri"
(click)="goToLineage()"
clrDropdownItem
>
<clr-icon shape="switch"></clr-icon>
<span>Lineage</span>
</button>
<button
type="button"
class="btn btn-sm btn-outline btn-block"
(click)="openQb()"
clrDropdownItem
>
<clr-icon shape="filter"></clr-icon>
<span>Filter</span>
</button>
<button
type="button"
class="btn btn-sm btn-success-outline"
(click)="openDownload = true"
clrDropdownItem
>
<clr-icon shape="download"></clr-icon>
<span>Download</span>
</button>
<button
type="button"
class="btn btn-sm btn-success-outline"
(click)="showWebQuery()"
clrDropdownItem
>
<clr-icon shape="download-cloud"></clr-icon>
<span>Web Query URL</span>
</button>
</clr-dropdown-menu>
</clr-dropdown>
</div>
<div
*ngIf="
queryText !== '1=1' && !['', ' '].includes(queryText) && !abortActive
"
class="clr-col-md-12 infoBar"
>
<span
>FILTER : <b>{{ queryText }}</b></span
>
</div>
</div>
<div
*ngIf="!lib && !table && !noDataReqErr && !noData"
class="no-table-selected"
>
<clr-icon
shape="warning-standard"
size="60"
class="is-info icon-dc-fill"
></clr-icon>
<h3 class="text-center color-gray">Please select a library</h3>
</div>
<ng-container *ngIf="!noData && !noDataReqErr && !table && lib">
<div
class="header-row clr-row border-bottom-divider justify-content-between w-100 m-0"
>
<section
class="form-block table-search-wrapper sw clr-col-md"
></section>
<div class="title-col clr-col-auto">
<h3 class="viewerTitle mt-17">
{{ lib }}
</h3>
<clr-icon
(click)="reloadLibInfo()"
class="refresh-table"
shape="refresh"
></clr-icon>
</div>
<div class="options-col clr-col-md"></div>
</div>
<div class="text-center mt-10">
<clr-spinner *ngIf="libinfo === null" clrMedium></clr-spinner>
</div>
<div
*ngIf="libinfo !== null"
class="no-table-selected-info pointer-events-none"
>
<clr-icon
shape="info-standard"
size="40"
class="is-info icon-dc-fill"
></clr-icon>
<h3 class="text-center color-gray">Please select a table</h3>
</div>
<div *ngIf="libinfo !== null" class="libinfo m-0 clr-row">
<p *ngIf="libinfo.length < 1" class="text-center m-0 w-100">
No library info found. Click
<clr-icon
(click)="reloadLibInfo()"
class="refresh-table m-0"
shape="refresh"
></clr-icon>
button to refresh.
</p>
<ng-container *ngIf="libinfo.length > 0">
<table>
<tr *ngIf="libinfo[0].ENGINE !== ''">
<td class="m-0">ENGINE:</td>
<td class="m-0 font-bold">
{{ libinfo[0] ? libinfo[0].ENGINE : '' }}
</td>
</tr>
<tr *ngIf="libinfo[0].LIBID !== ''">
<td class="m-0">LIBID:</td>
<td class="m-0 font-bold">
{{ libinfo[0] ? libinfo[0].LIBID : '' }}
</td>
</tr>
<tr *ngIf="libinfo[0].LIBNAME !== ''">
<td class="m-0">LIBNAME:</td>
<td class="m-0 font-bold">
{{ libinfo[0] ? libinfo[0].LIBNAME : '' }}
</td>
</tr>
<tr *ngIf="libinfo[0].LIBSIZE !== null">
<td class="m-0">LIBSIZE:</td>
<td class="m-0 font-bold">
{{ libinfo[0] ? (libinfo[0].LIBSIZE | convertSize) : '' }}
</td>
</tr>
<tr *ngIf="libinfo[0].OWNERS !== ''">
<td class="m-0">OWNERS:</td>
<td class="m-0 font-bold">
{{ libinfo[0] ? libinfo[0].OWNERS : '' }}
</td>
</tr>
<tr *ngIf="libinfo[0].PATHS !== ''">
<td class="m-0">PATHS:</td>
<td class="m-0 font-bold">
{{ libinfo[0] ? libinfo[0].PATHS : '' }}
</td>
</tr>
<tr *ngIf="libinfo[0].PERMS !== ''">
<td class="m-0">PERMS:</td>
<td class="m-0 font-bold">
{{ libinfo[0] ? libinfo[0].PERMS : '' }}
</td>
</tr>
<tr *ngIf="libinfo[0].SCHEMAS !== ''">
<td class="m-0">SCHEMAS:</td>
<td class="m-0 font-bold">
{{ libinfo[0] ? libinfo[0].SCHEMAS : '' }}
</td>
</tr>
<tr *ngIf="libinfo[0].TABLE_CNT !== null">
<td class="m-0">TABLE_CNT:</td>
<td class="m-0 font-bold">
{{ libinfo[0] ? libinfo[0].TABLE_CNT : '' }}
</td>
</tr>
</table>
</ng-container>
</div>
</ng-container>
<div *ngIf="noData || noDataReqErr" class="card-block noData">
<clr-icon shape="warning-standard" size="60" class="is-info"></clr-icon>
<h3 *ngIf="noData" class="text-center color-gray">
No data found with given conditions
</h3>
<h3 *ngIf="noDataReqErr" class="text-center color-gray">
No data found due to sas request error
</h3>
</div>
<div *ngIf="!noData && !noDataReqErr && table" class="clr-flex-1">
<hot-table
hotId="hotInstance"
id="hotTable"
[multiColumnSorting]="true"
[viewportRowRenderingOffset]="50"
[data]="hotTable.data"
[colHeaders]="hotTable.colHeaders"
[columns]="hotTable.columns"
[copyPaste]="hotTable.copyPaste"
[contextMenu]="hotTable.contextMenu"
[filters]="true"
[dropdownMenu]="hotTable.dropdownMenu"
[height]="hotTable.height"
stretchH="all"
[modifyColWidth]="maxWidthCheker"
[cells]="hotTable.cells"
[maxRows]="hotTable.maxRows"
[manualColumnResize]="true"
[rowHeaders]="hotTable.rowHeaders"
[rowHeaderWidth]="hotTable.rowHeaderWidth"
[rowHeights]="hotTable.rowHeights"
[licenseKey]="hotTable.licenseKey"
>
</hot-table>
</div>
<div>
<p
*ngIf="
licenceState.value.viewer_rows_allowed !== Infinity &&
hotTable.data &&
hotTable.data.length > licenceState.value.viewer_rows_allowed
"
class="mt-2-i w-100 text-center"
>
To display more than {{ licenceState.value.viewer_rows_allowed }} rows,
contact <contact-link />
</p>
</div>
</div>
</div>
<app-dataset-info [(open)]="datasetInfo" [dsmeta]="dsmeta"></app-dataset-info>
<app-viewboxes [(viewboxModal)]="viewboxOpen"></app-viewboxes>