File
Index
Properties
|
|
Methods
|
|
Inputs
|
|
Outputs
|
|
Accessors
|
|
contextDashboard
|
Type : any
|
Default value : { updateTarget: true }
|
Indicates if device info in config should be overridden with values from context property.
|
editModeButtons
|
Type : literal type
|
Outputs
onCancelDashboard
|
Type : EventEmitter<any>
|
onChangeEnd
|
Type : EventEmitter<WidgetChange>
|
onChangeStart
|
Type : EventEmitter<WidgetChange>
|
onDeleteWidget
|
Type : EventEmitter<WidgetChange>
|
onEditWidget
|
Type : EventEmitter<WidgetChange>
|
onResize
|
Type : EventEmitter<void>
|
onSaveDashboard
|
Type : EventEmitter<any>
|
Methods
Async
cancelDashboardSave
|
cancelDashboardSave()
|
|
Async
canDeactivate
|
canDeactivate(omitConfirm)
|
Parameters :
Name |
Optional |
Default value |
omitConfirm |
No
|
false
|
Returns : Promise<boolean>
|
enableEditMode
|
enableEditMode()
|
|
ngOnChanges
|
ngOnChanges(undefined: SimpleChanges)
|
Parameters :
Name |
Type |
Optional |
SimpleChanges
|
No
|
|
saveDashboard
|
saveDashboard()
|
|
toggleFullscreen
|
toggleFullscreen(hasWidget)
|
Parameters :
Name |
Optional |
Default value |
hasWidget |
No
|
false
|
|
updateWidgetClasses
|
updateWidgetClasses(widget: Widget, classes: Record)
|
Parameters :
Name |
Type |
Optional |
widget |
Widget
|
No
|
classes |
Record<string | boolean>
|
No
|
|
updateWidgetConfig
|
updateWidgetConfig(data: any, widget: Widget)
|
Parameters :
Name |
Type |
Optional |
data |
any
|
No
|
widget |
Widget
|
No
|
|
Readonly
ACTION_BAR_EDIT_WIDGETS_PRIORITY
|
Type : number
|
Default value : 10
|
Readonly
copyDashboardLabel
|
Default value : gettext('Copy dashboard')
|
copyDisabledPopoverMsg
|
Type : string
|
editMode$
|
Type : BehaviorSubject<boolean>
|
Default value : new BehaviorSubject<boolean>(false)
|
inFullScreen$
|
Default value : fromEvent(document, 'fullscreenchange').pipe(
map(() => this.fullScreen()),
startWith(this.fullScreen())
)
|
isLoadingWidgets$
|
Type : Observable<boolean>
|
Readonly
redoMessage
|
Default value : gettext('Redo: "{{ changeToRedo }}"')
|
settings
|
Type : DashboardSettings
|
Default value : {
isFrozen: false,
isDisabled: false,
widgetMargin: 12,
translateWidgetTitle: false,
defaultHeight: 4,
defaultWidth: 4,
allowFullscreen: false,
canCopy: true,
canDelete: true,
isLoading: false,
columns: 12
}
|
Readonly
undoMessage
|
Default value : gettext('Undo: "{{ changeToUndo }}"')
|
widgetInFullscreenMode
|
Default value : false
|
Accessors
widgets
|
getwidgets()
|
setwidgets(value: Widget[])
|
|
<c8y-title *ngIf="!!settings.title">
{{ settings.title | translate }}
</c8y-title>
<c8y-breadcrumb *ngIf="!!breadcrumb">
<c8y-breadcrumb-item
[icon]="breadcrumb.icon"
[label]="breadcrumb.label"
[path]="breadcrumb.path"
></c8y-breadcrumb-item>
</c8y-breadcrumb>
<c8y-action-bar-item
[placement]="'left'"
[priority]="ACTION_BAR_EDIT_WIDGETS_PRIORITY"
*ngIf="!(editMode$ | async)"
>
<button
class="btn btn-link animated fadeIn hidden-xs"
title="{{ 'Edit widgets' | translate }}"
type="button"
[disabled]="settings.isDisabled"
(click)="enableEditMode()"
data-cy="c8y-widget-dashboard--edit-widgets"
>
<i c8yIcon="send-backward"></i>
<span class="m-l-4">{{ 'Edit widgets' | translate }}</span>
</button>
<button
class="btn btn-link visible-xs m-l-0"
tooltip="{{ 'Not available on mobile phone' | translate }}"
type="button"
[disabled]="true"
>
<i c8yIcon="send-backward"></i>
<span class="m-l-4">{{ 'Edit widgets' | translate }}</span>
</button>
</c8y-action-bar-item>
<c8y-action-bar-item
[placement]="'left'"
*ngIf="editMode$ | async"
>
<button
class="btn btn-link animated fadeIn"
title="{{ 'Add widget' | translate }}"
type="button"
(click)="onAddWidget.emit()"
data-cy="widget-dashboard--Add-widget"
>
<i c8yIcon="plus-circle"></i>
{{ 'Add widget' | translate }}
</button>
</c8y-action-bar-item>
<c8y-action-bar-item
[placement]="'left'"
itemClass="d-flex a-i-center gap-8"
*ngIf="editMode$ | async"
>
<div class="input-group input-group-sm animated fadeIn">
<div class="input-group-btn">
<button
class="btn btn-default btn-sm btn-icon"
[attr.aria-label]="'Undo' | translate"
[tooltip]="
editModeButtons.undoButtonDisabled
? ''
: (undoMessage
| translate: { changeToUndo: editModeButtons.changeToUndoName | translate })
"
container="body"
(click)="revertChange.emit('undo')"
[disabled]="editModeButtons.undoButtonDisabled"
>
<i [c8yIcon]="'undo'"></i>
</button>
</div>
<div class="input-group-btn">
<button
class="btn btn-default btn-sm btn-icon"
[attr.aria-label]="'Redo' | translate"
[tooltip]="
editModeButtons.redoButtonDisabled
? ''
: (redoMessage
| translate: { changeToRedo: editModeButtons.changeToRedoName | translate })
"
container="body"
(click)="revertChange.emit('redo')"
[disabled]="editModeButtons.redoButtonDisabled"
>
<i [c8yIcon]="'redo'"></i>
</button>
</div>
<span></span>
</div>
<div class="btn-group animated fadeIn">
<button
class="btn btn-default btn-sm"
title="{{ 'Cancel' | translate }}"
type="button"
(click)="cancelDashboardSave()"
>
{{ 'Cancel' | translate }}
</button>
<button
class="btn btn-primary btn-sm m-l-8"
title="{{ 'Save' | translate }}"
type="button"
[disabled]="editModeButtons.undoButtonDisabled"
(click)="saveDashboard()"
data-cy="c8y-widgets-dashboard--save"
>
{{ 'Save' | translate }}
</button>
</div>
</c8y-action-bar-item>
<c8y-action-bar-item
[placement]="'right'"
*ngIf="onEditDashboard.observers.length"
>
<button
class="btn btn-link hidden-xs m-l-0"
title="{{ 'Dashboard settings' | translate }}"
type="button"
[disabled]="settings.isDisabled || (editMode$ | async)"
(click)="onEditDashboard.emit()"
data-cy="c8y-widgets-dashboard--edit-dashboard"
>
<i c8yIcon="sorting-slider"></i>
<span class="visible-xs-inline hidden-sm visible-md-inline visible-lg-inline">
{{ 'Dashboard settings' | translate }}
</span>
</button>
<button
class="btn btn-link visible-xs m-l-0"
tooltip="{{ 'Not available on mobile phone' | translate }}"
type="button"
[disabled]="true"
>
<i c8yIcon="sorting-slider"></i>
<span class="visible-xs-inline hidden-sm visible-md-inline visible-lg-inline">
{{ 'Dashboard settings' | translate }}
</span>
</button>
</c8y-action-bar-item>
<c8y-action-bar-item
[placement]="'right'"
*ngIf="settings.allowFullscreen"
[priority]="-5000"
itemClass="pull-right"
>
<button
class="btn btn-link"
[attr.aria-label]="'Full screen' | translate"
tooltip="{{ 'Full screen' | translate }}"
placement="left"
container="body"
type="button"
[delay]="500"
(click)="toggleFullscreen()"
data-cy="widgets-dashboard--Full-screen"
>
<i [c8yIcon]="(inFullScreen$ | async) ? 'compress' : 'expand'"></i>
<span class="visible-xs-inline hidden-sm visible-md-inline visibile-lg-inline">
{{ 'Full screen' | translate }}
</span>
</button>
</c8y-action-bar-item>
<c8y-action-bar-item
[placement]="'more'"
[priority]="-2000"
*ngIf="settings.canCopy"
>
<div
[ngStyle]="{
display: 'flex',
flexDirection: 'row',
alignItems: 'center'
}"
>
<button
class="hidden-xs"
title="{{
(isCopyDisabled === true || !isCopyDisabled?.state ? 'Disabled' : copyDashboardLabel) | translate
}}"
type="button"
[ngClass]="{ 'btn btn-link': !settings.canDelete }"
data-cy="widgets-dashboard--copy-dashboard"
(click)="onCopyDashboard.emit()"
[disabled]="isCopyDisabled === true || !isCopyDisabled?.state || (editMode$ | async)"
>
<i c8yIcon="clone"></i>
<span>{{ copyDashboardLabel | translate }}</span>
</button>
<button
class="btn-help btn-help--sm m-r-16 hidden-xs"
[attr.aria-label]="'Help' | translate"
[popover]="copyDisabledPopoverMsg | translate"
placement="right"
triggers="focus"
container="body"
type="button"
*ngIf="!isCopyDisabled?.state && copyDisabledPopoverMsg"
data-cy="widgets-dashboard--info-copy-dashboard"
(click)="$event.stopPropagation()"
></button>
</div>
<button
class="visible-xs m-l-0"
tooltip="{{ 'Not available on mobile phone' | translate }}"
type="button"
[ngClass]="{ 'btn btn-link': !settings.canDelete }"
[disabled]="true"
>
<i c8yIcon="clone"></i>
<span>{{ copyDashboardLabel | translate }}</span>
</button>
</c8y-action-bar-item>
<c8y-action-bar-item
[placement]="'more'"
[priority]="-3000"
*ngIf="settings.canDelete && onDeleteDashboard.observers.length"
>
<button
class="hidden-xs"
title="{{ 'Delete dashboard' | translate }}"
type="button"
data-cy="widgets-dashboard--delete-dashboard"
[ngClass]="{ 'btn btn-link': !settings.canCopy }"
(click)="onDeleteDashboard.emit()"
[disabled]="settings.isDisabled || (editMode$ | async)"
>
<i c8yIcon="delete"></i>
<span translate>Delete dashboard</span>
</button>
<button
class="visible-xs m-l-0"
tooltip="{{ 'Not available on mobile phone' | translate }}"
type="button"
data-cy="widgets-dashboard--delete-dashboard-mobile"
[ngClass]="{ 'btn btn-link': !settings.canCopy }"
[disabled]="true"
>
<i c8yIcon="delete"></i>
<span translate>Delete dashboard</span>
</button>
</c8y-action-bar-item>
<ng-template #loadingIndicator>
<c8y-loading
class="col-xs-12 text-center"
*ngIf="isLoadingWidgets$ | async"
></c8y-loading>
</ng-template>
<ng-container *ngIf="!(isLoadingWidgets$ | async); else loadingIndicator">
<ng-container *ngIf="resolvedWidgets$ | async as widgetsToDisplay">
<!-- empty state -->
<c8y-ui-empty-state
[icon]="'c8y-device'"
[title]="'No widgets to display.' | translate"
*ngIf="widgetsToDisplay?.length === 0"
>
<div *ngIf="onAddWidget.observers.length">
<p
translate
*ngIf="editMode$ | async"
>
Add widgets to this dashboard.
</p>
<p
translate
*ngIf="!(editMode$ | async)"
>
Click "Edit widgets" to unlock
</p>
<div>
<button
class="btn btn-primary m-t-16"
title="{{ 'Add widget' | translate }}"
type="button"
[disabled]="settings.isDisabled || !(editMode$ | async)"
(click)="onAddWidget.emit()"
data-cy="c8y-widgets-dashboard--add-widget"
translate
>
Add widget
</button>
</div>
<p c8y-guide-docs>
<small
translate
ngNonBindable
>
Find out more in the
<a c8y-guide-href="/docs/cockpit/working-with-dashboards">user documentation</a>
.
</small>
</p>
</div>
</c8y-ui-empty-state>
<c8y-dashboard
[columns]="settings.columns"
(dashboardChange)="onChangeDashboard.emit($event)"
#dashboard
>
<c8y-dashboard-child
[class]="widget.classes"
*ngFor="let widget of widgetsToDisplay"
[x]="widget._x"
[y]="widget._y"
[width]="widget._width || settings.defaultWidth"
[height]="widget._height || settings.defaultHeight"
[margin]="settings.widgetMargin"
[data]="widget"
[useIntersection]="true"
[editMode]="editMode$ | async"
(changeStart)="onChangeStart.emit({ widget: widget, source: child, dashboard: dashboard })"
(changeEnd)="onChangeEnd.emit({ widget: widget, source: child, dashboard: dashboard })"
(toggleFullscreen)="toggleFullscreenOnWidget(child)"
[canToggleFullscreen]="!(inFullScreen$ | async) || widgetInFullscreenMode"
#child
>
<c8y-dashboard-child-title>
<span
data-cy="c8y-dashboard-list--device-widget"
*ngIf="settings.translateWidgetTitle"
>
{{ widget.title | translate }}
</span>
<span *ngIf="!settings.translateWidgetTitle">
{{ widget.title }}
</span>
</c8y-dashboard-child-title>
<c8y-dashboard-child-action *ngIf="onEditWidget.observers.length">
<button
title="{{ 'Edit widget' | translate }}"
type="button"
data-cy="widgets-dashboard--Edit-widget"
(click)="onEditWidget.emit({ widget: widget, source: child, dashboard: dashboard })"
>
<i c8yIcon="pencil"></i>
<span translate>Edit</span>
</button>
</c8y-dashboard-child-action>
<c8y-dashboard-child-action *ngIf="onDeleteWidget.observers.length">
<button
title="{{ 'Remove widget' | translate }}"
type="button"
data-cy="c8y-widgets-dashboard--remove-widget"
(click)="onDeleteWidget.emit({ widget: widget, source: child, dashboard: dashboard })"
>
<i c8yIcon="delete"></i>
<span translate>Remove</span>
</button>
</c8y-dashboard-child-action>
<c8y-widget-time-context
*ngIf="
(widget.config?.displaySettings?.globalTimeContext ||
widget.config?.displaySettings?.globalRealtimeContext) &&
widget.config.widgetInstanceGlobalTimeContext
"
(dateContextChange)="updateWidgetConfig($event, widget)"
[canDecouple]="widget.config.canDecoupleGlobalTimeContext"
[displaySettings]="widget.config.displaySettings"
[hidden]="(editMode$ | async)"
></c8y-widget-time-context>
<c8y-widget-auto-refresh-context
*ngIf="
widget?.config?.widgetInstanceGlobalAutoRefreshContext &&
widget.config?.displaySettings.globalAutoRefreshContext
"
[editMode$]="editMode$"
></c8y-widget-auto-refresh-context>
<c8y-dynamic-component
[componentId]="widget.componentId || widget.name"
[config]="
widget.templateUrl || widget.widgetComponent
? { child: widget, dashboard: contextDashboard, context: context }
: widget.config
"
*ngIf="child.intersected"
(updateWidgetClasses)="updateWidgetClasses(widget, $event)"
></c8y-dynamic-component>
</c8y-dashboard-child>
</c8y-dashboard>
</ng-container>
</ng-container>