repository/firmware/list/firmware-details.component.ts
OnInit
OnDestroy
selector | c8y-firmware-details |
imports |
TitleComponent
BreadcrumbComponent
BreadcrumbItemComponent
ActionBarItemComponent
NgIf
IconDirective
NgClass
FormGroupComponent
RequiredInputPlaceholderDirective
FormsModule
NgStyle
PopoverDirective
C8yTranslateDirective
EmptyStateComponent
ListGroupComponent
ForOfDirective
ListItemComponent
ListItemIconComponent
ListItemBodyComponent
FileDownloadComponent
NgPlural
NgPluralCase
TooltipDirective
ListItemCollapseComponent
AsyncPipe
C8yTranslatePipe
|
templateUrl | ./firmware-details.component.html |
Properties |
Methods |
constructor(activatedRoute: ActivatedRoute, inventoryService: InventoryService, repositoryService: RepositoryService, alertService: AlertService, translateService: TranslateService, modalService: ModalService, bsModalService: BsModalService, gainsightService: GainsightService, router: Router)
|
||||||||||||||||||||||||||||||
Parameters :
|
addBaseVersion |
addBaseVersion()
|
Returns :
void
|
addPatchVersion |
addPatchVersion()
|
Returns :
void
|
Async deleteBaseVersion | ||||||
deleteBaseVersion(baseVersion: IManagedObject)
|
||||||
Parameters :
Returns :
any
|
Async deletePatchVersion | ||||||
deletePatchVersion(patchVersion: IManagedObject)
|
||||||
Parameters :
Returns :
any
|
getBinaryName$ | ||||
getBinaryName$(binaryUrl)
|
||||
Decorators :
@memoize()
|
||||
Parameters :
Returns :
any
|
getPatchVersions$ | ||||
getPatchVersions$(baseVersion)
|
||||
Decorators :
@memoize(undefined)
|
||||
Parameters :
Returns :
any
|
getPatchVersionsCount$ | ||||||
getPatchVersionsCount$(baseVersion: FirmwareBinary)
|
||||||
Decorators :
@memoize(undefined)
|
||||||
Parameters :
Returns :
any
|
ngOnDestroy |
ngOnDestroy()
|
Returns :
void
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
baseVersionsUpdated$ |
Type : Subject<void>
|
Default value : new Subject()
|
destroy$ |
Type : Subject<boolean>
|
Default value : new Subject<boolean>()
|
expanded |
Type : literal type
|
Default value : {}
|
firmware |
Type : IManagedObject
|
firmwareUpdated$ |
Type : Subject<IManagedObject>
|
Default value : new Subject()
|
isLegacy$ |
Type : Observable<boolean>
|
Default value : this.firmware$.pipe(
map(firmware => this.repositoryService.isLegacyEntry(firmware)),
shareReplay(1)
)
|
patchVersionsUpdated$ |
Type : Subject<void>
|
Default value : new Subject()
|
reload$ |
Type : Subject<void>
|
Default value : new Subject()
|
reloading$ |
Type : BehaviorSubject<boolean>
|
Default value : new BehaviorSubject(false)
|
updateFirmware$ |
Type : Subject<Partial<IManagedObject>>
|
Default value : new Subject()
|
<c8y-title>
{{ (firmware$ | async)?.name }}
</c8y-title>
<c8y-breadcrumb>
<c8y-breadcrumb-item
icon="c8y-management"
label="{{ 'Management' | translate }}"
></c8y-breadcrumb-item>
<c8y-breadcrumb-item
icon="c8y-firmware"
path="#/firmware"
label="{{ 'Firmware repository' | translate }}"
></c8y-breadcrumb-item>
<c8y-breadcrumb-item
icon="c8y-firmware"
label="{{ (firmware$ | async)?.name }}"
></c8y-breadcrumb-item>
</c8y-breadcrumb>
<c8y-action-bar-item [placement]="'right'">
<button
class="btn btn-link"
title="{{ 'Add firmware' | translate }}"
type="button"
*ngIf="!(isLegacy$ | async)"
data-cy="firmware-details--add-firmware-btn"
(click)="addBaseVersion()"
>
<i c8yIcon="plus-circle"></i>
{{ 'Add firmware' | translate }}
</button>
</c8y-action-bar-item>
<c8y-action-bar-item [placement]="'right'">
<button
class="btn btn-link"
title="{{ 'Add firmware patch' | translate }}"
type="button"
*ngIf="canAddPatchVersions$ | async"
data-cy="firmware-details--add-firmware-patch-btn"
(click)="addPatchVersion()"
>
<i c8yIcon="plus-circle"></i>
{{ 'Add firmware patch' | translate }}
</button>
</c8y-action-bar-item>
<c8y-action-bar-item [placement]="'right'">
<button
class="btn btn-link"
title="{{ 'Reload' | translate }}"
type="button"
(click)="reload$.next()"
>
<i
c8yIcon="refresh"
[ngClass]="{ 'icon-spin': reloading$ | async }"
></i>
{{ 'Reload' | translate }}
</button>
</c8y-action-bar-item>
<div class="row">
<div class="col-lg-12 col-lg-max">
<div class="card card--fullpage">
<div class="card-block bg-level-1 flex-no-shrink p-t-24 p-b-24">
<div class="content-flex-70">
<div class="text-center">
<i class="c8y-icon-duocolor icon-48 c8y-icon c8y-icon-firmware"></i>
<p>
<small class="label label-info">Firmware</small>
</p>
</div>
<div class="flex-grow col-10">
<div class="row">
<div class="col-md-4">
<c8y-form-group>
<label class="control-label">
{{ 'Name' | translate }}
</label>
<div class="input-group input-group-editable">
<input
class="form-control"
[ngStyle]="{ 'width.ch': (firmware$ | async)?.name?.length + 2 || 36 }"
placeholder="{{ 'e.g. My firmware' | translate }}"
type="text"
required
#nameInput
[ngModel]="(firmware$ | async)?.name"
#nameModel="ngModel"
data-cy="firmware-details--name-input"
/>
<span></span>
<div class="input-group-btn">
<button
class="btn btn-primary"
title="{{ 'Save' | translate }}"
type="button"
data-cy="firmware-details--name-save-btn"
(click)="updateFirmware$.next({ name: nameInput.value }); nameModel.reset()"
[disabled]="nameInput.value.length == 0"
>
{{ 'Save' | translate }}
</button>
</div>
</div>
</c8y-form-group>
</div>
<div class="col-md-4">
<c8y-form-group>
<label class="control-label">
{{ 'Description' | translate }}
</label>
<div class="input-group input-group-editable">
<input
class="form-control"
[ngStyle]="{ 'width.ch': (firmware$ | async)?.description?.length || 36 }"
placeholder="{{ 'e.g. Firmware for hardware revision B' | translate }}"
type="text"
#descriptionInput
[ngModel]="(firmware$ | async)?.description"
#descriptionModel="ngModel"
data-cy="firmware-details--description-input"
/>
<span></span>
<div class="input-group-btn">
<button
class="btn btn-primary"
title="{{ 'Save' | translate }}"
type="button"
data-cy="firmware-details--description-save-btn"
(click)="
updateFirmware$.next({ description: descriptionInput.value });
descriptionModel.reset()
"
>
{{ 'Save' | translate }}
</button>
</div>
</div>
</c8y-form-group>
</div>
<div class="col-md-4">
<c8y-form-group>
<label class="control-label">
{{ 'Device type filter' | translate }}
<button
class="btn-help"
[attr.aria-label]="'Help' | translate"
popover="{{
'If the filter is set, the firmware will show up for installation only for devices of that type. If no filter is set, it will be available for all devices.'
| translate
}}"
placement="right"
triggers="focus"
container="body"
type="button"
>
<i c8yIcon="question-circle-o"></i>
</button>
</label>
<div class="input-group input-group-editable">
<input
class="form-control"
[ngStyle]="{ 'width.ch': (firmware$ | async)?.type?.length || 36 }"
placeholder="{{ 'e.g.' | translate }} c8y_Linux"
type="text"
#deviceTypeInput
[ngModel]="(firmware$ | async)?.c8y_Filter?.type"
#deviceTypeModel="ngModel"
data-cy="firmware-details--device-type-filter-input"
/>
<span></span>
<div class="input-group-btn">
<button
class="btn btn-primary"
title="{{ 'Save' | translate }}"
type="button"
data-cy="firmware-details--device-type-filter-save-btn"
(click)="
updateFirmware$.next({ c8y_Filter: { type: deviceTypeInput.value } });
deviceTypeModel.reset()
"
>
{{ 'Save' | translate }}
</button>
</div>
</div>
</c8y-form-group>
</div>
</div>
</div>
</div>
</div>
<div class="inner-scroll">
<div class="card-header separator-top-bottom bg-component sticky-top">
<div
class="card-title"
translate
>
Versions and patches
</div>
</div>
<div class="card-block p-t-0 p-b-24">
<div *ngIf="(baseVersions$ | async)?.data.length === 0">
<c8y-ui-empty-state
[icon]="'c8y-firmware'"
[title]="'No versions to display.' | translate"
[subtitle]="'Add a new version by clicking below.' | translate"
[horizontal]="true"
>
<button
class="btn btn-sm btn-default m-t-8"
title="{{ 'Add firmware' | translate }}"
type="button"
(click)="addBaseVersion()"
>
<i c8yIcon="plus-circle"></i>
{{ 'Add firmware' | translate }}
</button>
</c8y-ui-empty-state>
</div>
<c8y-list-group *ngIf="(baseVersions$ | async)?.data.length > 0">
<c8y-li
*c8yFor="let baseVersion of baseVersions$ | async; let i = index; loadMore: 'auto'"
[emptyActions]="!(getPatchVersions$(baseVersion) | async)?.data.length"
[collapsed]="!expanded[baseVersion.id]"
(collapsedChange)="expanded[baseVersion.id] = !$event"
>
<c8y-li-icon>
<i c8yIcon="c8y-firmware"></i>
</c8y-li-icon>
<c8y-li-body class="content-flex-50">
<div class="col-4">
<p
class="text-truncate"
title="{{ baseVersion.c8y_Firmware.version }}"
>
{{ baseVersion.c8y_Firmware.version }}
</p>
</div>
<div class="col-5">
<p class="text-truncate">
<span
class="text-label-small m-r-8"
translate
>
File
</span>
<ng-container
*ngIf="baseVersion.c8y_Firmware.url === '$PROVIDED'; else fileDownload"
>
<span title="{{ 'Provided by device' | translate }}">
{{ 'Provided by device' | translate }}
</span>
</ng-container>
<ng-template #fileDownload>
<span title="{{ getBinaryName$(baseVersion.c8y_Firmware.url) | async }}">
<c8y-file-download
url="{{ baseVersion.c8y_Firmware.url }}"
></c8y-file-download>
</span>
</ng-template>
</p>
</div>
<div class="col-2 d-flex a-i-start">
<span
class="label label-warning m-l-auto-sm"
*ngIf="isLegacy$ | async"
>
{{ 'Legacy' | translate }}
</span>
<span *ngIf="!(isLegacy$ | async)">
<span *ngIf="(getPatchVersionsCount$(baseVersion) | async) === null">
<span class="label label-info">
<i
class="icon-spin"
c8yIcon="circle-o-notch"
></i>
</span>
</span>
<span *ngIf="(getPatchVersionsCount$(baseVersion) | async) !== null">
<span [ngPlural]="getPatchVersionsCount$(baseVersion) | async">
<ng-template ngPluralCase="=0">
<span class="label label-default m-l-auto-sm">
<span translate>No patches</span>
</span>
</ng-template>
<ng-template ngPluralCase="=1">
<span class="label label-info">
<span translate>1 patch</span>
</span>
</ng-template>
<ng-template ngPluralCase="other">
<span class="label label-info">
<span
ngNonBindable
translate
[translateParams]="{
count: getPatchVersionsCount$(baseVersion) | async
}"
>
{{ count }} patches
</span>
</span>
</ng-template>
</span>
</span>
</span>
</div>
<div
class="fit-h-20 visible-xs"
*ngIf="!(isLegacy$ | async)"
>
<button
class="btn btn-default btn-sm m-t-8"
title="{{ 'Delete' | translate }}"
type="button"
(click)="deleteBaseVersion(baseVersion)"
>
<i c8yIcon="delete"></i>
{{ 'Delete' | translate }}
</button>
</div>
<div
class="m-l-auto fit-h-20 p-r-8 hidden-xs"
*ngIf="!(isLegacy$ | async)"
>
<button
class="btn btn-dot btn-dot--danger showOnHover"
[attr.aria-label]="'Delete' | translate"
tooltip="{{ 'Delete' | translate }}"
type="button"
data-cy="firmware-details--delete-base-version"
[delay]="500"
(click)="deleteBaseVersion(baseVersion)"
>
<i c8yIcon="delete"></i>
</button>
</div>
</c8y-li-body>
<c8y-li-collapse *ngIf="(getPatchVersions$(baseVersion) | async)?.data.length">
<c8y-list-group class="separator-top">
<c8y-li
*c8yFor="
let patchVersion of getPatchVersions$(baseVersion) | async;
let i = index;
loadMore: 'auto'
"
>
<c8y-li-icon>
<i c8yIcon="c8y-firmware"></i>
</c8y-li-icon>
<c8y-li-body class="content-flex-50">
<div class="col-4">
{{ patchVersion.c8y_Firmware.version }}
</div>
<div class="col-5">
<div class="text-truncate">
<span
class="text-label-small m-r-8"
translate
>
File
</span>
<ng-container
*ngIf="
patchVersion?.c8y_Firmware?.url === '$PROVIDED';
else fileDownload
"
>
<span title="{{ 'Provided by device' | translate }}">
{{ 'Provided by device' | translate }}
</span>
</ng-container>
<ng-template #fileDownload>
<span title="patchVersion.c8y_Firmware.url">
<c8y-file-download
[url]="patchVersion.c8y_Firmware.url"
></c8y-file-download>
</span>
</ng-template>
</div>
</div>
<div class="visible-xs m-t-8">
<button
class="btn btn-danger btn-xs"
title="{{ 'Delete' | translate }}"
type="button"
data-cy="firmware-details--delete-patch-version"
(click)="deletePatchVersion(patchVersion)"
>
<i c8yIcon="delete"></i>
{{ 'Delete' | translate }}
</button>
</div>
<div class="m-l-auto p-r-8 hidden-xs fit-h-20">
<button
class="btn btn-dot text-danger showOnHover"
[attr.aria-label]="'Delete' | translate"
tooltip="{{ 'Delete' | translate }}"
placement="right"
type="button"
[delay]="500"
(click)="deletePatchVersion(patchVersion)"
>
<i
c8yIcon="delete"
data-cy="firmware-details--Remove-icon"
></i>
</button>
</div>
</c8y-li-body>
</c8y-li>
</c8y-list-group>
</c8y-li-collapse>
</c8y-li>
</c8y-list-group>
</div>
</div>
</div>
</div>
</div>