- Components
-
KpiWidgetViewComponent
widgets/implementations/kpi/kpi-widget-view/kpi-widget-view.component.ts
@if (displayMode() === GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD && getDashboardChild()) {
<c8y-global-context-connector
[controls]="widgetControls()"
[config]="contextConfig()"
[dashboardChild]="getDashboardChild()"
[linked]="isLinkedToGlobal()"
[propagateAutoRefresh]="false"
(configChange)="onContextChange($event)"
(refresh)="onRefresh()"
></c8y-global-context-connector>
} @else if (displayMode() !== GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD) {
<c8y-local-controls
[controls]="widgetControls()"
[displayMode]="displayMode()"
[config]="contextConfig()"
[propagateAutoRefresh]="false"
(configChange)="onContextChange($event)"
(refresh)="onRefresh()"
></c8y-local-controls>
}
@if (state$ | async; as lastState) {
<div class="kpi-widget__container d-flex d-col flex-grow fit-w a-i-center j-c-center">
<div class="d-flex a-i-center j-c-center fit-w">
@if (config.icon && config.showIcon) {
<div
class="m-r-16 flex-no-shrink text-muted"
[ngClass]="lastState.colorClass"
>
<i
class="icon-32"
[c8yIcon]="config.icon"
></i>
</div>
}
<div class="text-truncate">
<span
class="text-truncate text-medium"
[ngStyle]="{ 'font-size': (config.fontSize || '36') + 'px' }"
title="{{
lastState.colorClass === 'text-danger'
? ('Within red range:' | translate)
: lastState.colorClass === 'text-warning'
? ('Within yellow range:' | translate)
: ''
}} {{
lastState.latestMeasurement.value
| number
: '1.' +
(config.numberOfDecimalPlaces || '0') +
'-' +
(config.numberOfDecimalPlaces || '0')
}} {{ lastState.unit || '' }}"
[ngClass]="lastState.colorClass"
>
{{
lastState.latestMeasurement.value
| number
: '1.' +
(config.numberOfDecimalPlaces || '0') +
'-' +
(config.numberOfDecimalPlaces || '0')
}}
<small class="text-regular">{{ lastState.unit || '' }}</small>
</span>
</div>
@if (config?.showTrend && lastState.previousValue; as previousValue) {
<div class="dot dot-info dot-30 m-l-16 flex-no-shrink">
<i
class="icon-20"
c8yIcon="arrow-dotted-up"
[ngStyle]="{ transform: 'rotate(' + lastState.trend + ')' }"
[title]="
('Previous value' | translate) +
': ' +
(previousValue.value
| number
: '1.' +
(config.numberOfDecimalPlaces || '0') +
'-' +
(config.numberOfDecimalPlaces || '0')) +
' (' +
(previousValue.date | c8yDate: 'medium') +
')'
"
></i>
</div>
}
</div>
<div class="d-flex d-col a-i-center">
@if (config?.showTimestamp) {
<p class="icon-flex text-center text-muted small m-b-0">
<i c8yIcon="calendar"></i>
{{ lastState.latestMeasurement.date | c8yDate: 'medium' }}
</p>
}
@if (isHistoryMode()) {
<p class="text-center text-muted small m-b-0">
<span translate>Last measurement in selected time range</span>
</p>
}
</div>
</div>
} @else {
<div class="d-flex flex-grow fit-w j-c-center a-i-center">
@let noDataSubtitleLive = 'Waiting for measurements to be created.' | translate;
@let noDataSubtitleHistory = 'No data available for the selected time period.' | translate;
@if (noDataInitiallyInDB()) {
<c8y-ui-empty-state
[icon]="'line-chart'"
[title]="'No measurement to display.' | translate"
[subtitle]="isHistoryMode() ? noDataSubtitleHistory : noDataSubtitleLive"
[horizontal]="true"
></c8y-ui-empty-state>
} @else {
<c8y-loading></c8y-loading>
}
</div>
}