blob: c6157b7eba2bf09df04bdd7c092dee4c3a5c08b3 [file]
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
~
-->
<div
class="box"
[ngStyle]="{
background: configuredWidget.baseAppearanceConfig.backgroundColor,
color: configuredWidget.baseAppearanceConfig.textColor,
height: '100%',
border: !dataViewMode
? (dashboardChartOverrides?.borderThickness || 0) +
'px solid var(--color-bg-2)'
: 'none',
boxSizing: 'border-box',
}"
[attr.data-cy]="
'widget-' + configuredWidget.baseAppearanceConfig.widgetTitle
"
>
@if (!previewMode) {
<div class="widget-header h-40 w-100">
<div fxFlex="100" fxLayout="row">
<div
fxFlex
fxLayout="row"
fxLayoutAlign="start center"
class="text-md font-bold"
>
@if (!isEditingName) {
<ng-container>
{{
dashboardItem?.name ||
configuredWidget.baseAppearanceConfig
.widgetTitle
}}
@if (!dataViewMode && editMode) {
<button
class="ml-xs"
mat-icon-button
(click)="startEditingName()"
>
<mat-icon>edit</mat-icon>
</button>
}
</ng-container>
} @else {
<ng-container>
<input
type="text"
[(ngModel)]="tempName"
class="name-input"
(keydown.enter)="saveName()"
(keydown.escape)="cancelEditingName()"
/>
<button mat-icon-button (click)="saveName()">
<mat-icon>check</mat-icon>
</button>
<button
mat-icon-button
(click)="cancelEditingName()"
>
<mat-icon>close</mat-icon>
</button>
</ng-container>
}
</div>
@if (!kioskMode) {
<div fxLayout="row" fxLayoutAlign="end center">
@if (editMode) {
@if (timerActive) {
<sp-spinner [diameter]="20" class="mr-10">
</sp-spinner>
}
<sp-label
shape="badge"
size="small"
tone="neutral"
[color]="
configuredWidget.baseAppearanceConfig
.textColor
"
[labelText]="loadingTime + 's'"
class="mr-10"
></sp-label>
}
@if (!dataViewMode) {
<button
mat-icon-button
[matMenuTriggerFor]="menu"
[matTooltip]="'More options' | translate"
[attr.data-cy]="
'more-options-' +
configuredWidget.baseAppearanceConfig.widgetTitle.replaceAll(
' ',
''
)
"
>
<mat-icon>more_vert</mat-icon>
</button>
}
<mat-menu #menu="matMenu">
<button
mat-menu-item
(click)="downloadDataAsFile()"
>
<mat-icon>get_app</mat-icon>
<span>{{ 'Download data' | translate }}</span>
</button>
@if (hasDataExplorerWritePrivileges) {
<button
mat-menu-item
(click)="startEditMode()"
[attr.data-cy]="
'start-edit-' +
configuredWidget.baseAppearanceConfig.widgetTitle.replaceAll(
' ',
''
)
"
>
<mat-icon>edit</mat-icon>
<span>{{ 'Edit Chart' | translate }}</span>
</button>
}
</mat-menu>
@if (!globalTimeEnabled) {
<button
mat-icon-button
[matMenuTriggerFor]="optMenu"
data-cy="options-data-explorer"
#menuTrigger="matMenuTrigger"
[matTooltip]="tooltipText"
matTooltipClass="no-wrap-tooltip"
>
<mat-icon
[color]="
timeSettingsModified
? 'primary'
: 'default'
"
>alarm_clock</mat-icon
>
</button>
}
<mat-menu #optMenu="matMenu" class="large-menu">
@if (quickSelections) {
<sp-time-selector-menu
#timeSelectorMenu
[timeSettings]="clonedTimeSettings"
[quickSelections]="quickSelections"
[enableTimePicker]="enableTimePicker"
[maxDayRange]="maxDayRange"
[labels]="labels"
(timeSettingsEmitter)="
modifyWidgetTimeSettings($event)
"
class="w-100"
>
<button
mat-flat-button
class="mat-basic"
(click)="resetWidgetTimeSettings()"
>
{{ 'Reset' | translate }}
</button>
</sp-time-selector-menu>
}
</mat-menu>
@if (
!dataViewMode &&
editMode &&
hasDashboardWritePrivileges
) {
<button
mat-icon-button
(click)="removeWidget()"
[matTooltip]="'Delete Chart' | translate"
[attr.data-cy]="
'remove-' +
configuredWidget.baseAppearanceConfig
.widgetTitle
"
>
<mat-icon>clear</mat-icon>
</button>
}
</div>
}
</div>
</div>
}
<div fxLayout="column" class="widget-content p-0 ml-0 mr-0 h-100 mw-100">
@if (showRequiresAttentionMessage) {
<div
fxFlex="100"
fxLayout="column"
fxLayoutAlign="center center"
fxLayoutGap="10px"
>
<div fxLayout="row" fxLayoutAlign="center center">
<i class="material-icons warning-icon">sync_problem</i>
</div>
<div fxLayout="column" fxLayoutAlign="center center">
<div class="default-text text-xl">
{{
'Chart requires attention because the dataset schema changed'
| translate
}}
</div>
<div class="default-text text-md">
{{
'Open the chart editor to review and save the chart'
| translate
}}
</div>
</div>
</div>
}
<ng-template spWidgetHost class="h-100 p-0"></ng-template>
@if (!showRequiresAttentionMessage && errorMessage) {
<div fxFlex="100" fxLayout="column" fxLayoutAlign="center center">
<sp-exception-message
[message]="errorMessage"
[showDetails]="true"
></sp-exception-message>
</div>
}
</div>
</div>