- resolve HOT v17 render loops caused by unstable settings bind - tests: pin locale to en-GB - improve accessibility - improve initial bundle size, split and lazy-load feature modules Reviewed-on: #245 Co-authored-by: s <sead@4gl.io> Co-committed-by: s <sead@4gl.io>
464 lines
14 KiB
HTML
464 lines
14 KiB
HTML
<clr-modal
|
|
appDragNdrop
|
|
[clrModalOpen]="viewboxModal"
|
|
(clrModalOpenChange)="clrModalOpenChange($event)"
|
|
[clrModalClosable]="true"
|
|
[clrModalSize]="'lg'"
|
|
class="root-modal position-relative"
|
|
>
|
|
<h3 class="modal-title">
|
|
Viewboxes
|
|
<span
|
|
*ngIf="licenceState.value.viewbox_limit !== Infinity"
|
|
class="licence-notice"
|
|
>To unlock more then {{ licenceState.value.viewbox_limit }}
|
|
{{ licenceState.value.viewbox_limit === 1 ? 'viewbox' : 'viewboxes' }},
|
|
contact support@datacontroller.io</span
|
|
>
|
|
</h3>
|
|
|
|
<div class="modal-body d-flex">
|
|
<div class="add-new d-flex clr-flex-column">
|
|
<p class="mt-0">Add new</p>
|
|
|
|
<hr class="w-100" />
|
|
|
|
<div *ngIf="librariesLoading" class="my-10-mx-auto text-center">
|
|
<clr-spinner clrMedium></clr-spinner>
|
|
</div>
|
|
|
|
<p *ngIf="viewboxLimitReached" class="m-0 viewbox-limit-notice">
|
|
Viewbox open limit reached
|
|
</p>
|
|
|
|
<dc-tree
|
|
*ngIf="viewboxModal"
|
|
[libraryList]="libraries"
|
|
(libraryOnClickEmitter)="libraryOnClick($event)"
|
|
(tableOnClickEmitter)="tableOnClick($event)"
|
|
></dc-tree>
|
|
</div>
|
|
|
|
<div class="currently-open">
|
|
<div class="d-flex clr-justify-content-between">
|
|
<p class="mt-0">Currently open</p>
|
|
|
|
<div>
|
|
<a
|
|
(click)="snapToGrid()"
|
|
role="tooltip"
|
|
aria-haspopup="true"
|
|
class="tooltip tooltip-md tooltip-bottom-left ml-3"
|
|
>
|
|
<clr-icon aria-hidden="true" shape="grid-view" size="19"></clr-icon>
|
|
<span class="tooltip-content">Snap viewboxes to grid</span>
|
|
</a>
|
|
|
|
<a
|
|
(click)="minimizeAll()"
|
|
role="tooltip"
|
|
aria-haspopup="true"
|
|
class="tooltip tooltip-md tooltip-bottom-left ml-3"
|
|
>
|
|
<clr-icon aria-hidden="true" shape="minus" size="19"></clr-icon>
|
|
<span class="tooltip-content">Minimize all viewboxes</span>
|
|
</a>
|
|
|
|
<a
|
|
(click)="restoreAll()"
|
|
role="tooltip"
|
|
aria-haspopup="true"
|
|
class="tooltip tooltip-md tooltip-bottom-left ml-3"
|
|
>
|
|
<clr-icon
|
|
aria-hidden="true"
|
|
shape="window-restore"
|
|
size="19"
|
|
></clr-icon>
|
|
<span class="tooltip-content">Restore all viewboxes</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<hr />
|
|
|
|
<p *ngIf="viewboxes.length < 1" class="text-center w-100 m-0">
|
|
Pick table from the list on the left
|
|
</p>
|
|
|
|
<div
|
|
*ngFor="let viewbox of viewboxes"
|
|
(click)="selectViewbox(viewbox)"
|
|
[class.selected]="selectedViewbox?.id === viewbox.id"
|
|
class="open-viewbox d-flex clr-justify-content-between clr-align-items-center"
|
|
>
|
|
<div class="d-flex clr-align-items-center">
|
|
#{{ viewbox.id }} {{ viewbox.library }}.{{ viewbox.table }}
|
|
<clr-spinner
|
|
*ngIf="viewbox.loadingData"
|
|
clrSmall
|
|
class="ml-3"
|
|
></clr-spinner>
|
|
</div>
|
|
|
|
<div>
|
|
<a
|
|
(click)="resetPosSize(viewbox); stopPropagation($event)"
|
|
role="tooltip"
|
|
aria-haspopup="true"
|
|
class="tooltip tooltip-md tooltip-bottom-left"
|
|
[class.disabled]="viewbox.x === 0 && viewbox.y === 0"
|
|
>
|
|
<clr-icon
|
|
aria-hidden="true"
|
|
shape="cursor-move"
|
|
size="13"
|
|
></clr-icon>
|
|
<span class="tooltip-content">Reset position and size</span>
|
|
</a>
|
|
|
|
<a
|
|
*ngIf="!viewbox.minimized"
|
|
(click)="minimize(viewbox); stopPropagation($event)"
|
|
role="tooltip"
|
|
aria-haspopup="true"
|
|
class="tooltip tooltip-md tooltip-bottom-left ml-3"
|
|
>
|
|
<clr-icon aria-hidden="true" shape="minus" size="19"></clr-icon>
|
|
<span class="tooltip-content">Minimize viewbox</span>
|
|
</a>
|
|
|
|
<a
|
|
*ngIf="viewbox.minimized"
|
|
(click)="restore(viewbox); stopPropagation($event)"
|
|
role="tooltip"
|
|
aria-haspopup="true"
|
|
class="tooltip tooltip-md tooltip-bottom-left ml-3"
|
|
>
|
|
<clr-icon
|
|
aria-hidden="true"
|
|
shape="window-restore"
|
|
size="19"
|
|
></clr-icon>
|
|
<span class="tooltip-content">Restore viewbox</span>
|
|
</a>
|
|
|
|
<a
|
|
(click)="close(viewbox); stopPropagation($event)"
|
|
role="tooltip"
|
|
aria-haspopup="true"
|
|
class="tooltip tooltip-md tooltip-bottom-left ml-3"
|
|
>
|
|
<clr-icon aria-hidden="true" shape="times" size="19"></clr-icon>
|
|
<span class="tooltip-content">Close viewbox</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
class="d-flex clr-justify-content-between clr-align-items-center mt-10"
|
|
>
|
|
<p class="m-0">
|
|
Configuration ({{
|
|
selectedViewboxTable?.viewboxLibDataset
|
|
? '#' +
|
|
selectedViewboxTable?.viewboxId +
|
|
' ' +
|
|
selectedViewboxTable?.viewboxLibDataset
|
|
: 'select viewbox from above'
|
|
}})
|
|
</p>
|
|
|
|
<!-- <clr-icon shape="times" size="19"></clr-icon> -->
|
|
</div>
|
|
<hr />
|
|
|
|
<div
|
|
class="configuration-wrapper"
|
|
*ngVar="{
|
|
colHeadersHidden: $any(
|
|
selectedViewboxTable?.hotTable?.colHeadersHidden
|
|
),
|
|
colHeadersVisible: $any(
|
|
selectedViewboxTable?.hotTable?.colHeadersVisible
|
|
),
|
|
headerPks: $any(selectedViewboxTable?.hotTable?.headerPks)
|
|
} as hotColumns"
|
|
cdkDropListGroup
|
|
>
|
|
<ng-container *ngIf="hotColumns.colHeadersHidden">
|
|
<div class="cols-search">
|
|
<!-- <input #columnSearch clrInput (input)="columnSearchChange($event, selectedViewboxTable)" placeholder="Search columns"/> -->
|
|
<app-autocomplete
|
|
#input
|
|
type="text"
|
|
autocomplete="off"
|
|
[inputId]="'viewbox-column-search'"
|
|
autofocus
|
|
placeholder="Search columns"
|
|
tabindex="0"
|
|
[emitOnlySelected]="true"
|
|
(valueChange)="
|
|
onColsearchChange(input, $event, hotColumns.colHeadersHidden)
|
|
"
|
|
>
|
|
<option *ngFor="let column of hotColumns.colHeadersHidden">
|
|
{{ column }}
|
|
</option>
|
|
</app-autocomplete>
|
|
</div>
|
|
</ng-container>
|
|
|
|
<ng-container *ngIf="hotColumns.colHeadersVisible">
|
|
<p class="mt-0">Columns To Display (drag and re-order)</p>
|
|
<div
|
|
class="cols-list"
|
|
cdkDropList
|
|
[cdkDropListData]="hotColumns.colHeadersVisible"
|
|
(cdkDropListDropped)="columnsDrop($event)"
|
|
>
|
|
<div
|
|
class="col-box column-{{ column }}"
|
|
*ngFor="let column of hotColumns.colHeadersVisible"
|
|
[class.cursor-default-i]="hotColumns.headerPks.includes(column)"
|
|
[class.primaryKeyHeaderStyle]="
|
|
hotColumns.headerPks.includes(column)
|
|
"
|
|
[cdkDragData]="column"
|
|
[cdkDragDisabled]="hotColumns.headerPks.includes(column)"
|
|
cdkDrag
|
|
>
|
|
<span>
|
|
{{ column }}
|
|
{{
|
|
selectedViewboxTable?.hotTable?.$dataformats.vars[column]
|
|
.type === 'num'
|
|
? '(numeric)'
|
|
: ''
|
|
}}
|
|
<clr-icon
|
|
*ngIf="hotColumns.headerPks.includes(column)"
|
|
aria-hidden="true"
|
|
shape="key"
|
|
></clr-icon>
|
|
</span>
|
|
|
|
<clr-icon
|
|
*ngIf="!hotColumns.headerPks.includes(column)"
|
|
(click)="onColRemove(column)"
|
|
aria-label="Remove column"
|
|
shape="trash"
|
|
class="cursor-pointer"
|
|
></clr-icon>
|
|
</div>
|
|
</div>
|
|
</ng-container>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button
|
|
type="button"
|
|
class="btn btn-sm btn-outline"
|
|
(click)="viewboxModal = false"
|
|
>
|
|
Ok
|
|
</button>
|
|
</div>
|
|
</clr-modal>
|
|
|
|
<div class="viewboxes-container">
|
|
<div
|
|
*ngFor="let viewbox of viewboxes; let index = index"
|
|
(mousedown)="focusViewbox(viewbox)"
|
|
[class.focused]="viewbox.focused"
|
|
[style.display]="viewbox.minimized ? 'none' : ''"
|
|
[style.width.px]="viewbox.width"
|
|
[style.height.px]="viewbox.height"
|
|
[style.pointer-events]="viewbox.collapsed ? 'none' : ''"
|
|
[style.box-shadow]="viewbox.collapsed ? 'none' : ''"
|
|
class="viewbox"
|
|
cdkDragBoundary=".viewboxes-container"
|
|
cdkDrag
|
|
[cdkDragFreeDragPosition]="{ x: viewbox.x, y: viewbox.y }"
|
|
(cdkDragEnded)="viewboxDragEnded($event, viewbox)"
|
|
tabindex="0"
|
|
[id]="'viewbox_' + viewbox.id"
|
|
#resizeBox
|
|
>
|
|
<div
|
|
class="drag-handle d-flex clr-justify-content-between clr-align-items-center"
|
|
cdkDragHandle
|
|
>
|
|
<span class="table-title">
|
|
#{{ viewbox.id }} {{ viewbox.library }}.{{ viewbox.table }}
|
|
</span>
|
|
|
|
<div class="actions">
|
|
<clr-icon
|
|
*ngIf="!viewbox.collapsed"
|
|
(click)="collapse(viewbox)"
|
|
aria-label="Collapse"
|
|
shape="angle top"
|
|
></clr-icon>
|
|
<clr-icon
|
|
*ngIf="viewbox.collapsed"
|
|
(click)="expand(viewbox)"
|
|
aria-label="Expand"
|
|
shape="angle down"
|
|
></clr-icon>
|
|
<clr-icon
|
|
(click)="minimize(viewbox)"
|
|
aria-label="Minimize"
|
|
shape="minus"
|
|
></clr-icon>
|
|
<clr-icon
|
|
(click)="close(viewbox)"
|
|
aria-label="Close"
|
|
shape="times"
|
|
></clr-icon>
|
|
</div>
|
|
</div>
|
|
<span
|
|
#dragHandleCorner
|
|
[id]="'handle_viewbox_' + viewbox.id"
|
|
class="dragHandle corner"
|
|
cdkDrag
|
|
(cdkDragMoved)="dragMove(dragHandleCorner, resizeBox, viewbox, $event)"
|
|
></span>
|
|
<form
|
|
class="d-flex align-items-center clr-justify-content-between clr-flex-wrap table-search-wrapper"
|
|
[style.display]="viewbox.collapsed ? 'none' : ''"
|
|
clrForm
|
|
>
|
|
<div class="d-flex align-items-center clr-flex-wrap">
|
|
<div class="input-wrapper">
|
|
<input
|
|
#searchEl
|
|
(keyup.enter)="searchTable(searchEl, viewbox)"
|
|
clrInput
|
|
[type]="viewbox.searchNumeric ? 'number' : 'text'"
|
|
placeholder="Search"
|
|
name="search-input"
|
|
/>
|
|
<clr-icon
|
|
*ngIf="!viewbox.searchLoading"
|
|
(click)="searchTable(searchEl, viewbox)"
|
|
aria-label="Search"
|
|
shape="search"
|
|
></clr-icon>
|
|
<span *ngIf="viewbox.searchLoading" class="spinner spinner-inline">
|
|
Loading...
|
|
</span>
|
|
</div>
|
|
|
|
<clr-checkbox-container>
|
|
<clr-checkbox-wrapper>
|
|
<input
|
|
type="checkbox"
|
|
clrCheckbox
|
|
[(ngModel)]="viewbox.searchNumeric"
|
|
name="numeric_check"
|
|
/>
|
|
<label>Numeric</label>
|
|
</clr-checkbox-wrapper>
|
|
</clr-checkbox-container>
|
|
</div>
|
|
|
|
<div class="d-flex clr-align-items-center">
|
|
<span *ngIf="viewbox.loadingData" class="spinner spinner-sm"
|
|
>Loading...</span
|
|
>
|
|
<clr-icon
|
|
*ngIf="!viewbox.loadingData"
|
|
(click)="reloadTableData(viewbox); searchEl.value = ''"
|
|
aria-label="Reload data"
|
|
shape="refresh"
|
|
class="click-icon"
|
|
></clr-icon>
|
|
<a
|
|
(click)="openFilter(viewbox); searchEl.value = ''"
|
|
role="tooltip"
|
|
aria-haspopup="true"
|
|
class="tooltip tooltip-lg tooltip-bottom-left ml-5"
|
|
>
|
|
<clr-icon
|
|
aria-hidden="true"
|
|
shape="filter"
|
|
[class.filter-active]="viewbox.filter_pk !== '0'"
|
|
class="click-icon"
|
|
></clr-icon>
|
|
<span class="tooltip-content tooltip-long">{{
|
|
viewbox.filterText
|
|
}}</span>
|
|
</a>
|
|
<clr-icon
|
|
(click)="openTableEdit(viewbox)"
|
|
[class.disabled]="!tableEditExists(viewbox)"
|
|
aria-label="Edit table"
|
|
shape="pencil"
|
|
class="click-icon ml-5"
|
|
></clr-icon>
|
|
</div>
|
|
</form>
|
|
<div
|
|
class="content"
|
|
*ngVar="getViewboxTableIndex(viewbox) as viewboxTableIndex"
|
|
[style.display]="viewbox.collapsed ? 'none' : ''"
|
|
>
|
|
<div
|
|
*ngIf="viewbox.loadingData && viewboxTableIndex < 0"
|
|
class="hot-spinner my-10-mx-auto text-center"
|
|
>
|
|
<clr-spinner clrMedium></clr-spinner>
|
|
</div>
|
|
|
|
<hot-table
|
|
*ngIf="viewboxTableIndex > -1 && viewboxHotSettings.get(viewbox.id)"
|
|
[settings]="viewboxHotSettings.get(viewbox.id) || {}"
|
|
[id]="'hotTable_' + viewbox.id"
|
|
></hot-table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<clr-modal
|
|
[(clrModalOpen)]="filter"
|
|
[clrModalSize]="'xl'"
|
|
[clrModalClosable]="false"
|
|
class="filter-modal"
|
|
>
|
|
<h3 class="modal-title center text-center color-darker-gray">
|
|
Filter for viewbox table:
|
|
<span> #{{ filteringViewbox?.id }} {{ filterLibds }} </span>
|
|
</h3>
|
|
<div class="modal-body">
|
|
<app-query
|
|
#queryFilter
|
|
*ngIf="filter"
|
|
[viewboxId]="filteringViewbox?.id"
|
|
></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-sm btn-outline"
|
|
(click)="filter = false"
|
|
>
|
|
Cancel
|
|
</button>
|
|
<button
|
|
[clrLoading]="filterLoading"
|
|
type="button"
|
|
class="btn btn-sm btn-success-outline"
|
|
(click)="sendClause()"
|
|
>
|
|
Ok
|
|
</button>
|
|
</div>
|
|
</clr-modal>
|