widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table/datapoints-table.component.ts
OnChanges
| changeDetection | ChangeDetectionStrategy.OnPush |
| host | { |
| selector | c8y-datapoints-table |
| standalone | true |
| imports |
AdjustAggregatedTimeRangePipe
ApplyRangeClassPipe
ColumnTitlePipe
CommonModule
DocsModule
DynamicColumnDirective
DynamicComponentModule
ListGroupModule
VirtualScrollListenerDirective
|
| templateUrl | ./datapoints-table.component.html |
Properties |
Methods |
Inputs |
Outputs |
| aggregationType |
Type : AggregationOption
|
| datapointsTableItems |
Type : GroupedDatapointTableItem[]
|
| decimalPlaces |
Type : number
|
| devicesColumnHeaders |
Type : TableColumnHeader[]
|
| hasMultipleDatapoints |
Type : boolean
|
| isLoading |
Type : boolean
|
| seriesWithoutPermissionToReadCount |
Type : number
|
| isScrolling |
Type : EventEmitter
|
| getFractionSize | ||||||||
getFractionSize(value: number)
|
||||||||
|
Determines the fraction size format based on whether the number is an integer or has decimal places.
Parameters :
Returns :
string
Returns '1.0-0' if the number is an integer, otherwise returns the current fraction size. |
| getRangeValues | ||||||
getRangeValues(row: KPIDetails)
|
||||||
|
Parameters :
Returns :
ColorRangeBoundaries
|
| ngOnChanges |
ngOnChanges()
|
|
Returns :
void
|
| onListScrolled |
onListScrolled()
|
|
Returns :
void
|
| onListScrolledToTop |
onListScrolledToTop()
|
|
Returns :
void
|
| hasNoPermissionsToReadAnyMeasurement |
Type : unknown
|
Default value : false
|
| missingAllPermissionsAlert |
Type : unknown
|
Default value : new DynamicComponentAlertAggregator()
|
@if (!hasNoPermissionsToReadAnyMeasurement) {
<div class="c8y-cq-440">
<div
class="hidden-xs c8y-list__item c8y-list--timeline hidden-cq"
[ngClass]="{ 'separator-top-bottom': devicesColumnHeaders.length > 0 }"
>
<div class="d-flex container-fluid">
<div class="c8y-list--timeline__item__date"></div>
<div class="c8y-list__item__block flex-grow min-width-0">
<div class="c8y-list__item__body">
<div class="d-flex row">
@if (hasMultipleDatapoints) {
<div
class="min-width-0"
[title]="'Device' | translate"
[c8yDynamicColumn]="devicesColumnHeaders.length"
>
<span class="text-medium text-truncate">
{{ 'Device' | translate }}
</span>
</div>
}
<!-- Data points column headers -->
@for (header of devicesColumnHeaders; track header) {
<div
class="min-width-0"
title="{{ header | columnTitle }}"
[c8yDynamicColumn]="devicesColumnHeaders.length"
>
<span class="text-medium text-truncate">
{{ header.label }} {{ header.unit }}
</span>
</div>
}
</div>
</div>
</div>
</div>
</div>
</div>
<!-- The record list -->
@if (!isLoading) {
@if (datapointsTableItems.length) {
<c8y-list-group
class="p-t-8 flex-grow c8y-cq-440"
c8yVirtualScrollListener
(scrolled)="onListScrolled()"
(scrolledToTop)="onListScrolledToTop()"
>
<c8y-li-timeline
*c8yFor="
let tableItem of { data: datapointsTableItems, res: null };
enableVirtualScroll: true;
virtualScrollElementSize: 48;
virtualScrollStrategy: 'fixed'
"
>
{{ tableItem.dateAndTime | c8yDate: 'mediumDate' }}
{{
tableItem.dateAndTime
| c8yDate: 'mediumTime'
| adjustAggregatedTimeRange: aggregationType
}}
<c8y-li>
<c8y-li-body>
<div class="d-flex row">
@if (devicesColumnHeaders.length > 1) {
<div
class="min-width-0"
[c8yDynamicColumn]="devicesColumnHeaders.length"
[attr.data-label]="'Device' | translate"
>
<div
class="text-truncate"
title="{{ tableItem.deviceName }}"
>
{{ tableItem.deviceName }}
</div>
</div>
}
<!-- Data point value row cells -->
@for (row of tableItem.rowItems; track row) {
@if (row !== null) {
@switch (row.renderType) {
@case ('min') {
<div
[c8yDynamicColumn]="devicesColumnHeaders.length"
[ngClass]="row.value.min ?? null | applyRangeClass: getRangeValues(row)"
[attr.data-label]="row.label"
data-cy="c8y-datapoints-table--value-min"
>
<div
class="text-truncate"
title="{{
row.value.min ?? '' | number: getFractionSize(row.value.min)
}}"
>
{{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}
</div>
</div>
}
@case ('max') {
<div
class="col-md-4"
[ngClass]="row.value.max ?? null | applyRangeClass: getRangeValues(row)"
data-cy="c8y-datapoints-table--value-max"
>
<div
class="text-truncate"
title="{{
row.value.max ?? '' | number: getFractionSize(row.value.max)
}}"
>
{{ row.value.max ?? '' | number: getFractionSize(row.value.max) }}
</div>
</div>
}
@case ('area') {
<div
[c8yDynamicColumn]="devicesColumnHeaders.length"
data-cy="c8y-datapoints-table--value-minmax"
>
<span
class="text-truncate"
title="{{
row.value.min ?? '' | number: getFractionSize(row.value.min)
}}"
[ngClass]="row.value.min ?? null | applyRangeClass: getRangeValues(row)"
data-cy="c8y-datapoints-table--value-minmax-min"
>
{{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}
</span>
...
<span
class="text-truncate"
title="{{
row.value.max ?? '' | number: getFractionSize(row.value.max)
}}"
[ngClass]="row.value.max ?? null | applyRangeClass: getRangeValues(row)"
data-cy="c8y-datapoints-table--value-minmax-max"
>
{{ row.value.max ?? '' | number: getFractionSize(row.value.max) }}
</span>
</div>
}
@default {
<div [c8yDynamicColumn]="devicesColumnHeaders.length">
<span
class="text-truncate"
title="{{
row.value.min ?? '' | number: getFractionSize(row.value.min)
}}"
[ngClass]="row.value.min ?? null | applyRangeClass: getRangeValues(row)"
>
{{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}
</span>
</div>
}
}
} @else {
<div [c8yDynamicColumn]="devicesColumnHeaders.length"></div>
}
}
</div>
</c8y-li-body>
</c8y-li>
</c8y-li-timeline>
</c8y-list-group>
} @else {
<div class="p-relative p-l-24">
<c8y-ui-empty-state
[icon]="'c8y-alert-idle'"
[title]="'No data to display.' | translate"
[horizontal]="true"
data-cy="datapoints-table-list--empty-state"
>
<p c8y-guide-docs>
<small
translate
ngNonBindable
>
Find out more in the
<a c8y-guide-href="/docs/cockpit/widgets-collection/#data-point-table">
user documentation</a
>.
</small>
</p>
</c8y-ui-empty-state>
</div>
}
} @else {
<c8y-loading></c8y-loading>
}
} @else {
<div class="p-t-24 p-r-16 p-l-16 p-b-16 d-flex">
<div class="center-block">
<c8y-dynamic-component-alerts
[alerts]="missingAllPermissionsAlert"
></c8y-dynamic-component-alerts>
</div>
</div>
}