File

ecosystem/application-plugins/application-plugins.component.ts

Implements

OnInit OnDestroy

Metadata

Index

Properties
Methods
Inputs

Constructor

constructor(activatedRoute: ActivatedRoute, ecosystemService: EcosystemService, bsModalService: BsModalService, pluginsService: PluginsService, alertService: AlertService, gainsightService: GainsightService)
Parameters :
Name Type Optional
activatedRoute ActivatedRoute No
ecosystemService EcosystemService No
bsModalService BsModalService No
pluginsService PluginsService No
alertService AlertService No
gainsightService GainsightService No

Inputs

appId
Type : string | number

Methods

Async cleanupOrphanedPlugins
cleanupOrphanedPlugins(plugins: ApplicationPlugin[])
Parameters :
Name Type Optional
plugins ApplicationPlugin[] No
Returns : any
getActionControls
getActionControls()
Returns : ActionControl[]
getBulkActionControls
getBulkActionControls()
Async installPlugins
installPlugins()
Returns : any
Async loadData
loadData()
Returns : any
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
refresh
refresh()
Returns : void
Async removePlugins
removePlugins(plugins: string[])
Parameters :
Name Type Optional
plugins string[] No
Returns : any
Async resetToDefault
resetToDefault()
Returns : any
Async updatePlugin
updatePlugin(app: IApplication, plugin: ApplicationPlugin, downgrade)
Parameters :
Name Type Optional Default value
app IApplication No
plugin ApplicationPlugin No
downgrade No false
Returns : any

Properties

actionControls
Type : ActionControl[]
Default value : this.getActionControls()
allAvailablePlugins$
Type : BehaviorSubject<ApplicationPlugin[]>
Default value : new BehaviorSubject([])
app
Type : IApplication
bulkActionControls
Type : BulkActionControl[]
Default value : this.getBulkActionControls()
columns
Type : Column[]
Default value : [ { name: 'name', header: gettext('Plugin name'), path: 'name', filterable: true }, { name: 'Version', header: gettext('Version'), path: 'version', filterable: false }, { name: 'Tag', header: gettext('Tag`noun`'), path: 'installedViaTag', filterable: false, cellRendererComponent: LabelCellRendererComponent }, { name: 'description', header: gettext('Description'), path: 'description', filterable: false, cellCSSClassName: 'small' }, { name: 'contextPath', header: gettext('Source'), path: 'contextPath', filterable: false, cellRendererComponent: LabelCellRendererComponent }, { name: 'scope', header: gettext('Scope'), path: 'scope', filterable: false, visible: false, cellRendererComponent: LabelCellRendererComponent }, { name: 'status', header: gettext('Status'), path: 'status', filterable: false, cellRendererComponent: OrphanedStatusCellRendererComponent } ]
CURRENT_LOCATION
Default value : location.href
dataGrid
Type : DataGridComponent
Decorators :
@ViewChild(DataGridComponent, {static: false})
displayOptions
Type : DisplayOptions
Default value : { bordered: false, striped: true, filter: true, gridHeader: true, hover: true }
headerActionControls
Type : HeaderActionControl[]
Default value : []
installedPlugins$
Type : Observable<ApplicationPlugin[]>
Default value : combineLatest([ this.remotePlugins$.pipe(map(remotes => PluginsService.convertInstalledRemotesToIds(remotes))), this.allAvailablePlugins$ ]).pipe( map(([remotePlugins, allPlugins]) => this.getInstalledPlugins(allPlugins, remotePlugins)), shareReplay(1) )
isLoading
Type : boolean
isStandard$
Default value : combineLatest([this.installedPlugins$, this.selfPlugins$]).pipe( map(([installedPlugins, selfPlugins]) => { const manifestRemotes = this.app?.manifest?.remotes || {}; // ensure that every installed plugin is a self plugin or a plugin from the manifest const allInstalledPluginsAreSelf = installedPlugins.every( p => selfPlugins.some(selfPlugin => selfPlugin.id === p.id) || (Array.isArray(manifestRemotes[p.contextPath]) && manifestRemotes[p.contextPath].includes(p.module)) ); // ensure that every self plugin is installed const allSelfPluginsAreInstalled = selfPlugins.every(selfPlugin => installedPlugins.some(p => p.id === selfPlugin.id) ); const configRemotes = this.app?.config?.remotes || {}; // ensure that every remote from the manifest is in the config // if no config exists we are also all good const everyRemoteFromManifestIsInConfig = !this.app?.config?.remotes || Object.keys(manifestRemotes).every( contextPath => Array.isArray(configRemotes[contextPath]) && Array.isArray(manifestRemotes[contextPath]) && manifestRemotes[contextPath].every(module => configRemotes[contextPath].includes(module) ) ); return ( allInstalledPluginsAreSelf && allSelfPluginsAreInstalled && everyRemoteFromManifestIsInConfig ); }) )
loadingItemsLabel
Type : string
Default value : gettext('Loading packages…')
loadMoreItemsLabel
Type : string
Default value : gettext('Load more packages')
noDataMessage
Default value : gettext('No plugins installed.')
noDataSubtitle
Default value : gettext("This application doesn't have any plugin. Click below to install.")
noResultsMessage
Default value : gettext('No plugins to display.')
noResultsSubtitle
Default value : gettext('Refine your search terms or check your spelling.')
orphanedPlugins$
Default value : this.installedPlugins$.pipe( map(plugins => plugins.filter(p => p.status === ApplicationPluginStatus.ORPHANED)) )
pagination
Type : Pagination
Default value : { pageSize: 10, currentPage: 1 }
PRODUCT_EXPERIENCE
Default value : PRODUCT_EXPERIENCE_ECOSYSTEM
remotePlugins$
Type : BehaviorSubject<ApplicationRemotePlugins>
Default value : new BehaviorSubject({})
selfPlugins$
Type : BehaviorSubject<ApplicationPlugin[]>
Default value : new BehaviorSubject([])
title
Type : string
Default value : gettext('Installed plugins')
<c8y-title>{{ app | humanizeAppName | async }}</c8y-title>

<c8y-breadcrumb>
  <c8y-breadcrumb-item
    [icon]="'c8y-atom'"
    [label]="'Ecosystem' | translate"
  ></c8y-breadcrumb-item>
  <c8y-breadcrumb-item
    [icon]="'c8y-modules'"
    [label]="'Applications' | translate"
    [path]="'ecosystem/application/applications'"
  ></c8y-breadcrumb-item>
  <c8y-breadcrumb-item [label]="app | humanizeAppName | async"></c8y-breadcrumb-item>
  <c8y-breadcrumb-item [label]="'Plugins' | translate"></c8y-breadcrumb-item>
</c8y-breadcrumb>

<c8y-action-bar-item
  [placement]="'right'"
  *ngIf="!(isStandard$ | async)"
>
  <button
    class="btn btn-link"
    title="{{ 'Reset to default plugins' | translate }}"
    [ngClass]="{ 'btn-pending': isLoading }"
    (click)="resetToDefault()"
  >
    <i c8yIcon="undo"></i>
    {{ 'Reset to default' | translate }}
  </button>
</c8y-action-bar-item>

<c8y-action-bar-item [placement]="'right'">
  <button
    class="btn btn-link"
    title="{{ 'Install plugins' | translate }}"
    (click)="installPlugins()"
    [ngClass]="{ 'btn-pending': isLoading }"
  >
    <i c8yIcon="plus-circle"></i>
    {{ 'Install plugins' | translate }}
  </button>
</c8y-action-bar-item>

<ng-container *ngIf="orphanedPlugins$ | async as orphanedPlugins">
  <c8y-action-bar-item
    *ngIf="orphanedPlugins?.length"
    [placement]="'right'"
  >
    <button
      class="btn btn-link"
      title="{{ 'Clean up orphaned plugins' | translate }}"
      (click)="cleanupOrphanedPlugins(orphanedPlugins)"
      [ngClass]="{ 'btn-pending': isLoading }"
    >
      <i c8yIcon="erase"></i>
      {{ 'Clean up orphaned plugins' | translate }}
    </button>
  </c8y-action-bar-item>
</ng-container>

<div class="content-fullpage d-flex d-col border-top">
  <c8y-data-grid
    class="d-contents"
    [title]="title"
    [loadMoreItemsLabel]="loadMoreItemsLabel"
    [loadingItemsLabel]="loadingItemsLabel"
    [displayOptions]="displayOptions"
    [columns]="columns"
    [rows]="installedPlugins$ | async"
    [pagination]="pagination"
    [selectable]="true"
    [actionControls]="actionControls"
    [bulkActionControls]="bulkActionControls"
    [headerActionControls]="headerActionControls"
    (onReload)="refresh()"
  >
    <c8y-ui-empty-state
      [icon]="stats?.size > 0 ? 'search' : 'plugin'"
      [title]="stats?.size > 0 ? (noResultsMessage | translate) : (noDataMessage | translate)"
      [subtitle]="stats?.size > 0 ? (noResultsSubtitle | translate) : (noDataSubtitle | translate)"
      *emptyStateContext="let stats"
      [horizontal]="stats?.size > 0"
    >
      <p *ngIf="stats?.size === 0">
        <button
          class="btn btn-primary btn-sm"
          title="{{ 'Install plugins' | translate }}"
          (click)="installPlugins()"
          [ngClass]="{ 'btn-pending': isLoading }"
          translate
        >
          Install plugins
        </button>
      </p>
    </c8y-ui-empty-state>
  </c8y-data-grid>
</div>

results matching ""

    No results matching ""