File
Implements
Methods
ngAfterViewInit
|
ngAfterViewInit()
|
|
appState
|
Default value : inject(AppStateService)
|
columns
|
Type : Column[]
|
Default value : this.topicsDataGridService.getColumns()
|
destroyRef
|
Default value : inject(DestroyRef)
|
icon$
|
Default value : this.namespaceId$.pipe(map(namespaceId => NAMESPACE_PROPS[namespaceId].icon))
|
loading$
|
Default value : new BehaviorSubject<boolean>(false)
|
loadingItemsLabel
|
Default value : gettext('Loading topics...')
|
loadMoreItemsLabel
|
Default value : gettext('Load more topics')
|
namespaceDetails$
|
Default value : combineLatest([this.tenantId$, this.namespaceId$, this.refresh]).pipe(
tap(() => this.loading$.next(true)),
switchMap(([tenantId, namespaceId]) =>
this.namespacesService.getNamespaceDetails(tenantId, namespaceId)
),
tap(() => this.loading$.next(false)),
shareReplay(1)
)
|
namespaceId$
|
Default value : this.route.params.pipe(map(params => params['namespace'] as string))
|
namespaceLabel$
|
Default value : this.namespaceId$.pipe(
map(namespaceId => this.translateService.instant(NAMESPACE_PROPS[namespaceId].label))
)
|
namespacesService
|
Default value : inject(MessagingNamespacesService)
|
noDataMessage
|
Default value : gettext('No topics to display.')
|
noDataSubtitle
|
Default value : gettext('Create new topics to monitor them here.')
|
noResultsMessage
|
Default value : gettext('No matching topics found.')
|
noResultsSubtitle
|
Default value : gettext('Refine your search terms or check your spelling.')
|
pagination
|
Type : Pagination
|
Default value : {
pageSize: 20,
currentPage: 1
}
|
refresh
|
Default value : new EventEmitter<void>()
|
route
|
Default value : inject(ActivatedRoute)
|
tableTitle
|
Default value : gettext('Topics')
|
tenantId$
|
Default value : this.appState.currentTenant.pipe(map(tenant => tenant.name))
|
topicsDataGridService
|
Default value : inject(TopicsDataGridService)
|
translateService
|
Default value : inject(TranslateService)
|
<c8y-title>{{ namespaceLabel$ | async }}</c8y-title>
<c8y-breadcrumb>
<c8y-breadcrumb-item
[icon]="'monitoring'"
[label]="'Monitoring' | translate"
></c8y-breadcrumb-item>
<c8y-breadcrumb-item
[label]="'Messaging service' | translate"
[path]="'/monitoring/messaging-service'"
></c8y-breadcrumb-item>
<c8y-breadcrumb-item [label]="namespaceLabel$ | async"></c8y-breadcrumb-item>
</c8y-breadcrumb>
<c8y-action-bar-item [placement]="'right'">
<a
class="btn btn-link"
title="{{ 'Reload' | translate }}"
(click)="refresh.emit()"
>
<i
c8yIcon="refresh"
[ngClass]="{ 'icon-spin': loading$ | async }"
></i>
{{ 'Reload' | translate }}
</a>
</c8y-action-bar-item>
<div class="card content-fullpage d-flex d-col">
<div class="bg-level-1 separator-bottom flex-no-shrink">
<div
class="card-block"
style="min-height: 172px"
>
<div
class="col-md-4 m-b-24 col-xs-12 d-flex p-t-24 gap-16 text-default a-i-center a-s-stretch"
>
<div class="text-center d-col">
<i
class="m-b-8 icon-40 c8y-icon-duocolor"
[c8yIcon]="icon$ | async"
></i>
<span class="tag tag--info">{{ 'Service' | translate }}</span>
</div>
<span class="h4 text-break-all">{{ namespaceLabel$ | async }}</span>
</div>
<div class="col-md-4">
<fieldset class="c8y-fieldset c8y-fieldset--lg">
<legend>
{{ 'Service usage/limits' | translate }}
</legend>
<ng-container *ngIf="loading$ | async; else serviceUsageLimits">
<c8y-loading></c8y-loading>
</ng-container>
<ng-template #serviceUsageLimits>
<ng-container *ngIf="(namespaceDetails$ | async)?.namespace as namespace">
<ul class="list-unstyled small animated fadeIn">
<li class="p-t-4 p-b-4 d-flex separator-bottom text-nowrap">
<label class="small m-b-0 m-r-auto">{{ 'Topics' | translate }}</label>
<ng-container *ngIf="namespace?.topics?.limit !== 0">
<app-usage
[count]="namespace?.topics?.count"
[limit]="namespace?.topics?.limit"
></app-usage>
<span class="m-l-16">
{{ namespace?.topics?.count | number }} /
{{ namespace?.topics?.limit | backlogQuotaLimit }}
</span>
</ng-container>
<ng-container *ngIf="namespace?.topics?.limit === 0">
<span class="m-l-16">{{ namespace?.topics?.count | number }}</span>
</ng-container>
</li>
<li class="p-t-4 p-b-4 d-flex separator-bottom text-nowrap">
<label class="small m-b-0 m-r-auto">{{ 'Subscribers' | translate }}</label>
<span class="m-l-16">
{{ namespace?.subscribers?.count | number }}
</span>
</li>
<li class="p-t-4 p-b-4 d-flex text-nowrap">
<label class="small m-b-0 m-r-auto">{{ 'Publishers' | translate }}</label>
<span class="m-l-16">
{{ namespace?.publishers?.count | number }}
</span>
</li>
</ul>
</ng-container>
</ng-template>
</fieldset>
</div>
<div class="col-md-4">
<fieldset class="c8y-fieldset c8y-fieldset--lg">
<legend>{{ 'Service message backlog limits' | translate }}</legend>
<ng-container *ngIf="loading$ | async; else serviceMessageBacklogLimits">
<c8y-loading></c8y-loading>
</ng-container>
<ng-template #serviceMessageBacklogLimits>
<ng-container *ngIf="(namespaceDetails$ | async)?.policies as policies">
<ul class="list-unstyled small animated fadeIn">
<li class="p-t-4 p-b-4 d-flex separator-bottom text-nowrap">
<label class="small m-b-0 m-r-auto">
{{ 'Backlog quota (per topic)' | translate }}
</label>
<span
title="{{
policies?.backlogQuota?.limit > 0
? (policies.backlogQuota.limit | bytes: 0 : true)
: '-'
}}"
>
{{
policies?.backlogQuota?.limit > 0
? (policies.backlogQuota.limit | bytes: 0)
: '-'
}}
</span>
</li>
<li class="p-t-4 p-b-4 d-flex text-nowrap">
<label class="small m-b-0 m-r-auto">
{{ 'Backlog time to live (TTL)' | translate }}
</label>
<span>{{ policies?.messageTTL | timeToLive }}</span>
</li>
</ul>
</ng-container>
</ng-template>
</fieldset>
</div>
</div>
</div>
<c8y-data-grid
class="d-contents"
[title]="tableTitle | translate"
[loadingItemsLabel]="loadingItemsLabel | translate"
[loadMoreItemsLabel]="loadMoreItemsLabel | translate"
[columns]="columns"
[pagination]="pagination"
[serverSideDataCallback]="serverSideDataCallback"
[refresh]="refresh"
[hideReload]="true"
>
<c8y-ui-empty-state
[icon]="stats?.size > 0 ? 'search' : 'day-view'"
[title]="stats?.size > 0 ? (noResultsMessage | translate) : (noDataMessage | translate)"
[subtitle]="stats?.size > 0 ? (noResultsSubtitle | translate) : (noDataSubtitle | translate)"
*emptyStateContext="let stats"
[horizontal]="stats?.size > 0"
></c8y-ui-empty-state>
<c8y-column name="name">
<ng-container *c8yCellRendererDef="let context">
<a
title="{{ context.value }}"
[routerLink]="['topic', context.item.id]"
>
{{ context.value }}
</a>
</ng-container>
</c8y-column>
<c8y-column name="msgRateIn">
<ng-container *c8yCellRendererDef="let context">
<span title="{{ context.value | number }}">
{{ context.value | number }}
</span>
</ng-container>
</c8y-column>
<c8y-column name="msgRateOut">
<ng-container *c8yCellRendererDef="let context">
<span title="{{ context.value | number }}">
{{ context.value | number }}
</span>
</ng-container>
</c8y-column>
<c8y-column name="subscribers">
<ng-container *c8yCellRendererDef="let context">
<a
title="{{ context.value | number }}"
[routerLink]="['topic', context.item.id, 'subscribers']"
>
{{ context.value | number }}
</a>
</ng-container>
</c8y-column>
<c8y-column name="backlogSize">
<ng-container *c8yCellRendererDef="let context">
<span title="{{ context.value | bytes: 2 : true }}">
{{ context.value | bytes: 2 }}
</span>
</ng-container>
</c8y-column>
<c8y-column name="backlogUsagePercentage">
<ng-container *c8yCellRendererDef="let context">
<span title="{{ context.value / 100 | percent: '1.0-2' }}">
{{ context.value / 100 | percent: '1.0-2' }}
</span>
</ng-container>
</c8y-column>
</c8y-data-grid>
</div>