File
Implements
Methods
addBaseVersion
|
addBaseVersion()
|
|
addPatchVersion
|
addPatchVersion()
|
|
Async
deleteBaseVersion
|
deleteBaseVersion(baseVersion: IManagedObject)
|
Parameters :
Name |
Type |
Optional |
baseVersion |
IManagedObject
|
No
|
|
Async
deletePatchVersion
|
deletePatchVersion(patchVersion: IManagedObject)
|
Parameters :
Name |
Type |
Optional |
patchVersion |
IManagedObject
|
No
|
|
getBinaryName$
|
getBinaryName$(binaryUrl)
|
Decorators :
@memoize()
|
Parameters :
Name |
Optional |
binaryUrl |
No
|
|
getPatchVersions$
|
getPatchVersions$(baseVersion)
|
Decorators :
@memoize(undefined)
|
Parameters :
Name |
Optional |
baseVersion |
No
|
|
getPatchVersionsCount$
|
getPatchVersionsCount$(baseVersion: FirmwareBinary)
|
Decorators :
@memoize(undefined)
|
|
ngOnDestroy
|
ngOnDestroy()
|
|
baseVersions$
|
Type : Observable<IResultList<IManagedObject>>
|
Default value : merge(
this.firmware$.pipe(distinctUntilKeyChanged('id')),
this.baseVersionsUpdated$,
this.patchVersionsUpdated$,
this.reload$
).pipe(
switchMap(() => this.firmware$),
switchMap(firmware => this.repositoryService.listBaseVersions(firmware)),
shareReplay(1)
)
|
baseVersionsUpdated$
|
Type : Subject<void>
|
Default value : new Subject()
|
canAddPatchVersions$
|
Type : Observable<boolean>
|
Default value : combineLatest(
this.isLegacy$,
this.baseVersions$.pipe(map(({ data }) => data.length > 0))
).pipe(map(([isLegacy, hasBaseVersions]) => !isLegacy && hasBaseVersions))
|
destroy$
|
Type : Subject<boolean>
|
Default value : new Subject<boolean>()
|
expanded
|
Type : literal type
|
Default value : {}
|
firmware$
|
Type : Observable<IManagedObject>
|
Default value : merge(
this.activatedRoute.params.pipe(
map(params => params.id),
switchMap(id => defer(() => this.inventoryService.detail(id).then(result => result.data)))
),
this.reload$.pipe(
tap(() => this.reloading$.next(true)),
switchMap(() => this.activatedRoute.params),
map(params => params.id),
switchMap(id => defer(() => this.inventoryService.detail(id).then(result => result.data))),
tap(() => this.reloading$.next(false))
),
this.firmwareUpdated$
).pipe(shareReplay(1))
|
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
path="#/firmware"
label="{{ 'Firmware repository' | translate }}"
icon="c8y-firmware"
>
</c8y-breadcrumb-item>
</c8y-breadcrumb>
<c8y-action-bar-item [placement]="'right'">
<button
*ngIf="!(isLegacy$ | async)"
class="btn btn-link"
title="{{ 'Add firmware' | translate }}"
(click)="addBaseVersion()"
>
<i c8yIcon="plus-circle"></i>
{{ 'Add firmware' | translate }}
</button>
</c8y-action-bar-item>
<c8y-action-bar-item [placement]="'right'">
<button
*ngIf="canAddPatchVersions$ | async"
class="btn btn-link"
title="{{ 'Add firmware patch' | translate }}"
(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 }}" (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 m-b-4">
<div class="card-header separator">
<h4 class="card-title" translate>
Name, description and device type filter
</h4>
</div>
<div class="card-block">
<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
#nameInput
type="text"
class="form-control"
[ngModel]="(firmware$ | async)?.name"
#nameModel="ngModel"
placeholder="{{ 'e.g. My firmware' | translate }}"
[ngStyle]="{ 'width.ch': (firmware$ | async)?.name?.length || 31 }"
required
/>
<span></span>
<div class="input-group-btn">
<button
class="btn btn-primary"
title="{{ 'Save' | translate }}"
(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
#descriptionInput
type="text"
class="form-control"
[ngModel]="(firmware$ | async)?.description"
#descriptionModel="ngModel"
placeholder="{{ 'e.g. Firmware for hardware revision b' | translate }}"
[ngStyle]="{ 'width.ch': (firmware$ | async)?.description?.length || 31 }"
/>
<span></span>
<div class="input-group-btn">
<button
class="btn btn-primary"
title="{{ 'Save' | translate }}"
(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-clean"
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 }}"
[outsideClick]="true"
container="body"
>
<i c8yIcon="question-circle-o" class="text-info"></i>
</button>
</label>
<div class="input-group input-group-editable">
<input
#deviceTypeInput
type="text"
class="form-control"
[ngModel]="(firmware$ | async)?.c8y_Filter?.type"
#deviceTypeModel="ngModel"
placeholder="{{ 'e.g.' | translate }} c8y_Linux"
[ngStyle]="{ 'width.ch': (firmware$ | async)?.type?.length || 31 }"
/>
<span></span>
<div class="input-group-btn">
<button
class="btn btn-primary"
title="{{ 'Save' | translate }}"
(click)=" updateFirmware$.next({ c8y_Filter: { type: deviceTypeInput.value } }); deviceTypeModel.reset()"
>
{{ 'Save' | translate }}
</button>
</div>
</div>
</c8y-form-group>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12 col-lg-max">
<div class="card">
<div class="card-header separator">
<h4 class="card-title" translate>
Versions and patches
</h4>
</div>
<div class="card-block p-t-0 p-b-24">
<div *ngIf="(baseVersions$ | async)?.data.length === 0">
<div class="c8y-empty-state text-center">
<h1 c8yIcon="c8y-firmware" class="c8y-icon-duocolor"></h1>
<h3 translate>No versions to display.</h3>
<p translate>Add a new version by clicking below.</p>
<p>
<button
class="btn btn-primary"
title="{{ 'Add firmware' | translate }}"
(click)="addBaseVersion()"
>
{{ 'Add firmware' | translate }}
</button>
</p>
</div>
</div>
<c8y-list-group
[ngClass]="{ 'dd-low': (baseVersions$ | async)?.data.length < 10 }"
*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-wrap" title="{{ baseVersion.c8y_Firmware.version }}">
{{ baseVersion.c8y_Firmware.version }}
</p>
</div>
<div class="col-5">
<p class="text-truncate-wrap">
<span class="text-label-small m-r-8" translate>
File
</span>
<span title="{{ getBinaryName$(baseVersion.c8y_Firmware.url) | async }}">
<c8y-file-download url="{{ baseVersion.c8y_Firmware.url }}"></c8y-file-download>
</span>
</p>
</div>
<div class="col-2 flex-row a-i-start">
<span *ngIf="isLegacy$ | async" class="label label-warning flex-item-right-sm">
{{ 'Legacy' | translate }}
</span>
<span *ngIf="!(isLegacy$ | async)">
<span *ngIf="(getPatchVersionsCount$(baseVersion) | async) === null">
<span class="label label-info">
<i c8yIcon="circle-o-notch" class="icon-spin"></i>
</span>
</span>
<span *ngIf="(getPatchVersionsCount$(baseVersion) | async) !== null">
<span [ngPlural]="getPatchVersionsCount$(baseVersion) | async">
<ng-template ngPluralCase="=0">
<span class="label label-default flex-item-right-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-danger btn-xs m-t-8 "
(click)="deleteBaseVersion(baseVersion)"
title="{{ 'Delete' | translate }}"
>
<i c8yIcon="minus-circle"></i>
{{ 'Delete' | translate }}
</button>
</div>
<div *ngIf="!(isLegacy$ | async)" class="flex-item-right fit-h-20 p-r-8 hidden-xs">
<button
class="btn btn-dot text-danger showOnHover"
(click)="deleteBaseVersion(baseVersion)"
title="{{ 'Delete' | translate }}"
>
<i c8yIcon="minus-circle"></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>
<c8y-file-download
url="{{ patchVersion.c8y_Firmware.url }}"
></c8y-file-download>
</div>
</div>
<div class="visible-xs m-t-8">
<button
class="btn btn-danger btn-xs"
(click)="deletePatchVersion(patchVersion)"
title="{{ 'Delete' | translate }}"
>
<i c8yIcon="minus-circle"></i>
{{ 'Delete' | translate }}
</button>
</div>
<div class="flex-item-right p-r-8 hidden-xs fit-h-20">
<button
class="btn btn-dot text-danger showOnHover"
(click)="deletePatchVersion(patchVersion)"
title="{{ 'Delete' | translate }}"
>
<i c8yIcon="minus-circle"></i>
</button>
</div>
</c8y-li-body>
</c8y-li>
</c8y-list-group>
</c8y-li-collapse>
</c8y-li>
</c8y-list-group>
</div>
</div>
</div>
</div>