File

core/dashboard/widgets-dashboard.component.ts

Metadata

Index

Properties
Methods
Inputs
Outputs
Accessors

Constructor

constructor(dynamic: DynamicComponentService, translateService: TranslateService, route: ActivatedRoute, modal: ModalService, widgetGlobalAutoRefresh: WidgetGlobalAutoRefreshService, router: Router, elementRef: ElementRef)
Parameters :
Name Type Optional
dynamic DynamicComponentService No
translateService TranslateService No
route ActivatedRoute No
modal ModalService No
widgetGlobalAutoRefresh WidgetGlobalAutoRefreshService No
router Router No
elementRef ElementRef No

Inputs

breadcrumb
Type : BreadcrumbItem
context
Type : any
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
isCopyDisabled
Type : DashboardCopyPermission | boolean
isSaveDisabled
Type : boolean
Default value : true
settings
Type : Partial<DashboardSettings>
widgets
Type : Widget[]

Outputs

onAddWidget
Type : EventEmitter<DashboardComponent>
onCancelDashboard
Type : EventEmitter<any>
onChangeDashboard
Type : EventEmitter<DashboardChange>
onChangeEnd
Type : EventEmitter<WidgetChange>
onChangeStart
Type : EventEmitter<WidgetChange>
onCopyDashboard
Type : EventEmitter<DashboardComponent>
onDeleteDashboard
Type : EventEmitter<DashboardComponent>
onDeleteWidget
Type : EventEmitter<WidgetChange>
onEditDashboard
Type : EventEmitter<DashboardComponent>
onEditWidget
Type : EventEmitter<WidgetChange>
onResize
Type : EventEmitter<void>
onSaveDashboard
Type : EventEmitter<any>
revertChange
Type : EventEmitter<RevertChangeType>

Methods

Async cancelDashboardSave
cancelDashboardSave()
Returns : any
Async canDeactivate
canDeactivate(omitConfirm: unknown)
Parameters :
Name Type Optional Default value
omitConfirm unknown No false
Returns : Promise<boolean>
enableEditMode
enableEditMode()
Returns : void
fullScreen
fullScreen()
Returns : boolean
ngOnChanges
ngOnChanges(changes: SimpleChanges)
Parameters :
Name Type Optional
changes SimpleChanges No
Returns : void
saveDashboard
saveDashboard()
Returns : void
toggleFullscreen
toggleFullscreen(hasWidget: unknown)
Parameters :
Name Type Optional Default value
hasWidget unknown No false
Returns : void
toggleFullscreenOnWidget
toggleFullscreenOnWidget(child: DashboardChildComponent)
Parameters :
Name Type Optional
child DashboardChildComponent No
Returns : void
updateWidgetClasses
updateWidgetClasses(widget: Widget, classes: Record)
Parameters :
Name Type Optional
widget Widget No
classes Record<string | boolean> No
Returns : void
updateWidgetConfig
updateWidgetConfig(data: any, widget: Widget)
Parameters :
Name Type Optional
data any No
widget Widget No
Returns : void

Properties

Readonly ACTION_BAR_EDIT_WIDGETS_PRIORITY
Type : number
Default value : 10
Readonly copyDashboardLabel
Type : unknown
Default value : gettext('Copy dashboard')
copyDisabledPopoverMsg
Type : string
editMode$
Type : BehaviorSubject<boolean>
Default value : new BehaviorSubject<boolean>(false)
inFullScreen$
Type : unknown
Default value : fromEvent(document, 'fullscreenchange').pipe( map(() => this.fullScreen()), startWith(this.fullScreen()) )
isLoadingWidgets$
Type : Observable<boolean>
Readonly redoMessage
Type : unknown
Default value : gettext('Redo: "{{ changeToRedo }}"')
resolvedWidgets$
Type : Observable<Widget[]>
settings
Type : DashboardSettings
Default value : { isFrozen: false, isDisabled: false, widgetMargin: 12, translateWidgetTitle: false, translateDashboardTitle: true, defaultHeight: 4, defaultWidth: 4, allowFullscreen: false, canCopy: true, canDelete: true, isLoading: false, columns: 12 }
Readonly undoMessage
Type : unknown
Default value : gettext('Undo: "{{ changeToUndo }}"')
widgetInFullscreenMode
Type : unknown
Default value : false

Accessors

widgets
getwidgets()
setwidgets(value: Widget[])
Parameters :
Name Type Optional
value Widget[] No
Returns : void
_settings
set_settings(settings: Partial)
Parameters :
Name Type Optional
settings Partial<DashboardSettings> No
Returns : void
isDeviceTypeDashboard
getisDeviceTypeDashboard()
nativeElement
getnativeElement()
@if (!!settings.title) {
  <c8y-title>
    @let dashboardTitle =
      settings.translateDashboardTitle ? (settings.title | translate) : settings.title;
    {{ dashboardTitle }}
  </c8y-title>
}

@if (!!breadcrumb) {
  <c8y-breadcrumb>
    <c8y-breadcrumb-item
      [icon]="breadcrumb.icon"
      [label]="breadcrumb.label"
      [path]="breadcrumb.path"
    ></c8y-breadcrumb-item>
  </c8y-breadcrumb>
}

@if (!(editMode$ | async)) {
  <c8y-action-bar-item
    [placement]="'right'"
    [priority]="ACTION_BAR_EDIT_WIDGETS_PRIORITY"
  >
    <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>
}

@if (editMode$ | async) {
  <c8y-action-bar-item
    [placement]="'right'"
    [priority]="ACTION_BAR_EDIT_WIDGETS_PRIORITY"
  >
    <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]="'right'"
    [priority]="ACTION_BAR_EDIT_WIDGETS_PRIORITY"
    itemClass="d-flex a-i-center gap-8"
  >
    <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 && isSaveDisabled"
        (click)="saveDashboard()"
        data-cy="c8y-widgets-dashboard--save"
      >
        {{ 'Save' | translate }}
      </button>
    </div>
  </c8y-action-bar-item>
}

@if (onEditDashboard.observers.length) {
  <c8y-action-bar-item [placement]="'right'">
    <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>
}

@if (settings.allowFullscreen) {
  <c8y-action-bar-item
    [placement]="'right'"
    [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>
}

@if (settings.canCopy) {
  <c8y-action-bar-item
    [placement]="'more'"
    [priority]="-2000"
  >
    <div class="d-flex a-i-center p-r-16">
      <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>
      @if (!isCopyDisabled?.state && copyDisabledPopoverMsg) {
        <button
          class="btn-help btn-help--sm hidden-xs flex-no-shrink"
          [attr.aria-label]="'Help' | translate"
          [popover]="copyDisabledPopoverMsg | translate"
          placement="top"
          triggers="focus"
          container="body"
          type="button"
          [adaptivePosition]="false"
          data-cy="widgets-dashboard--info-copy-dashboard"
          (click)="$event.preventDefault(); $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>
}

@if (settings.canDelete && onDeleteDashboard.observers.length) {
  <c8y-action-bar-item
    [placement]="'more'"
    [priority]="-3000"
  >
    <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>
}

@if (!(isLoadingWidgets$ | async)) {
  @if (resolvedWidgets$ | async; as widgetsToDisplay) {
    <!-- empty state -->
    @if (widgetsToDisplay?.length === 0) {
      <c8y-ui-empty-state
        [icon]="'c8y-device'"
        [title]="'No widgets to display.' | translate"
      >
        @if (onAddWidget.observers.length) {
          <div>
            @if (editMode$ | async) {
              <p translate>Add widgets to this dashboard.</p>
            }
            @if (!(editMode$ | async)) {
              <p translate>Click "Edit widgets" to unlock</p>
            }
            <div>
              @if (!settings.isDisabled && (editMode$ | async)) {
                <button
                  class="btn btn-primary m-t-16"
                  title="{{ 'Add widget' | translate }}"
                  type="button"
                  (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
    >
      @for (widget of widgetsToDisplay; track widget.id || widget.name || $index) {
        <c8y-dashboard-child
          [class]="widget.classes"
          [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>
            @if (settings.translateWidgetTitle) {
              <span data-cy="c8y-dashboard-list--device-widget">
                {{ widget.title | translate }}
              </span>
            }
            @if (!settings.translateWidgetTitle) {
              <span>
                {{ widget.title }}
              </span>
            }
          </c8y-dashboard-child-title>
          @if (onEditWidget.observers.length) {
            <c8y-dashboard-child-action>
              <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>
          }
          @if (onDeleteWidget.observers.length) {
            <c8y-dashboard-child-action>
              <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>
          }

          @if (child.intersected) {
            <c8y-dynamic-component
              [componentId]="widget.componentId || widget.name"
              [config]="
                widget.templateUrl || widget.widgetComponent
                  ? { child: widget, dashboard: contextDashboard, context: context }
                  : widget.config
              "
              (updateWidgetClasses)="updateWidgetClasses(widget, $event)"
            ></c8y-dynamic-component>
          }
        </c8y-dashboard-child>
      }
    </c8y-dashboard>
  }
} @else {
  <c8y-loading class="col-xs-12 text-center"></c8y-loading>
}

results matching ""

    No results matching ""