File

messaging-management/messaging/topic/topic-subscribers-view/topic-subscribers-view.component.ts

Implements

AfterViewInit

Metadata

Index

Properties
Methods

Methods

Async bulkUnsubscribeSubscribers
bulkUnsubscribeSubscribers(subscribersNames: string[])
Parameters :
Name Type Optional
subscribersNames string[] No
Returns : Promise<void>
ngAfterViewInit
ngAfterViewInit()
Returns : void
Async onDataSourceModifier
onDataSourceModifier(dataSourceModifier: DataSourceModifier)
Parameters :
Name Type Optional
dataSourceModifier DataSourceModifier No
Async unsubscribeSubscriber
unsubscribeSubscriber(subscriber: MessagingSubscriber)
Parameters :
Name Type Optional
subscriber MessagingSubscriber No
Returns : any

Properties

actionControls
Type : ActionControl[]
Default value : [ { type: 'unsubscribeSubscriber', icon: 'unsubscribe', text: gettext('Unsubscribe'), callback: (subscriber: MessagingSubscriber) => this.unsubscribeSubscriber(subscriber), showIf: () => this.permissions.hasRole(Permissions.ROLE_TENANT_MANAGEMENT_ADMIN) } ]
appState
Default value : inject(AppStateService)
bulkActionControls
Type : BulkActionControl[]
Default value : [ { type: 'unsubscribeSubscriber', icon: 'unsubscribe', text: gettext('Unsubscribe'), callback: (subscribersNames: string[]) => this.bulkUnsubscribeSubscribers(subscribersNames), showIf: () => this.permissions.hasRole(Permissions.ROLE_TENANT_MANAGEMENT_ADMIN) } ]
columns
Type : Column[]
Default value : this.topicSubscribersDataGridService.getColumns()
dataGrid
Type : DataGridComponent
Decorators :
@ViewChild(DataGridComponent, {static: true})
destroyRef
Default value : inject(DestroyRef)
loading$
Default value : new BehaviorSubject<boolean>(false)
loadingItemsLabel
Default value : gettext('Loading subscribers...')
loadMoreItemsLabel
Default value : gettext('Load more subscribers')
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 subscribers to display.')
noDataSubtitle
Default value : gettext('Create new subscribers to monitor them here.')
noResultsMessage
Default value : gettext('No matching subscribers found.')
noResultsSubtitle
Default value : gettext('Refine your search terms or check your spelling.')
overview$
Default value : combineLatest([this.tenantId$, this.namespaceId$, this.topicId$, this.refresh]).pipe( tap(() => this.loading$.next(true)), switchMap(async ([tenantId, namespaceId, topicId]) => ({ topic: ( await this.topicsService.detail({ tenant: tenantId, namespace: namespaceId, topic: topicId, type: MessagingTopicType.Persistent }) ).data, policies: await this.namespacesService.getNamespacePolicies(tenantId, namespaceId) })), tap(() => this.loading$.next(false)), shareReplay(1) )
pagination
Type : Pagination
Default value : { pageSize: 20, currentPage: 1 }
permissions
Default value : inject(Permissions)
refresh
Default value : new EventEmitter<void>()
route
Default value : inject(ActivatedRoute)
selectable
Default value : true
serverSideDataCallback
Type : ServerSideDataCallback
Default value : this.onDataSourceModifier.bind(this)
tableTitle
Default value : gettext('Subscribers')
tenantId$
Default value : this.appState.currentTenant.pipe(map(tenant => tenant.name))
topicId$
Default value : this.route.params.pipe(map(params => params['topic'] as string))
topicName$
Default value : this.overview$.pipe(map(overview => overview.topic.name))
topicsService
Default value : inject(MessagingTopicsService)
topicSubscribersDataGridService
Default value : inject(TopicSubscribersDataGridService)
translateService
Default value : inject(TranslateService)
<c8y-title>{{ topicName$ | 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"
    [path]="'/monitoring/messaging-service/namespace/' + (namespaceId$ | async)"
  ></c8y-breadcrumb-item>
  <c8y-breadcrumb-item [label]="topicName$ | 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">
      <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]="'day-view'"
          ></i>
          <span class="tag tag--default">{{ 'Topic' | translate }}</span>
        </div>
        <span class="h4">{{ topicName$ | async }}</span>
      </div>
      <div class="col-md-4">
        <fieldset class="c8y-fieldset c8y-fieldset--lg">
          <legend translate>Topic usage</legend>

          <ng-container *ngIf="loading$ | async; else topicSummary">
            <c8y-loading></c8y-loading>
          </ng-container>

          <ng-template #topicSummary>
            <ng-container *ngIf="overview$ | async as overview">
              <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">{{ 'Active subscribers' | translate }}</label>
                  <span class="m-l-16">{{ overview.topic.activeSubscribers | number }}</span>
                </li>

                <li class="p-t-4 p-b-4 d-flex separator-bottom text-nowrap">
                  <label class="small m-b-0 m-r-auto">{{ 'Total subscribers' | translate }}</label>
                  <span class="m-l-16">{{ overview.topic.subscribers | number }}</span>
                </li>

                <li class="p-t-4 p-b-4 d-flex separator-bottom text-nowrap">
                  <label class="small m-b-0 m-r-auto">
                    {{ 'Total unacknowledged messages' | translate }}
                  </label>
                  <span class="m-l-16">{{ overview.topic.unackMsgBacklog | number }}</span>
                </li>

                <li class="p-t-4 p-b-4 d-flex separator-bottom text-nowrap">
                  <label class="small m-b-0 m-r-auto">
                    {{ 'Message rate in' | translate }}
                  </label>
                  <span
                    class="m-l-16"
                    ngNonBindable
                    translate
                    [translateParams]="{
                      messagesPerSecond: overview.topic.msgRateIn | number
                    }"
                  >
                    {{ messagesPerSecond }} msg/s
                  </span>
                </li>

                <li class="p-t-4 p-b-4 d-flex text-nowrap">
                  <label class="small m-b-0 m-r-auto">
                    {{ 'Message rate out' | translate }}
                  </label>
                  <span
                    class="m-l-16"
                    ngNonBindable
                    translate
                    [translateParams]="{
                      messagesPerSecond: overview.topic.msgRateOut | number
                    }"
                  >
                    {{ messagesPerSecond }} msg/s
                  </span>
                </li>
              </ul>
            </ng-container>
          </ng-template>
        </fieldset>
      </div>

      <div class="col-md-4">
        <fieldset class="c8y-fieldset c8y-fieldset--lg">
          <legend translate>Topic message backlog</legend>

          <ng-container *ngIf="loading$ | async; else topicBacklog">
            <c8y-loading></c8y-loading>
          </ng-container>

          <ng-template #topicBacklog>
            <ng-container *ngIf="overview$ | async as overview">
              <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"
                    translate
                  >
                    Backlog usage
                  </label>
                  <app-usage [percentage]="overview.topic.backlogUsagePercentage"></app-usage>
                  <span class="m-l-16">{{ overview.topic.backlogSize | bytes }}</span>
                </li>

                <li class="p-t-4 p-b-4 d-flex text-nowrap">
                  <label
                    class="small m-b-0 m-r-auto"
                    translate
                  >
                    Backlog quota
                  </label>
                  <span class="m-l-16">
                    {{
                      overview.policies.backlogQuota?.limit > 0
                        ? (overview.policies.backlogQuota?.limit | bytes)
                        : '-'
                    }}
                  </span>
                </li>
              </ul>
            </ng-container>
          </ng-template>
        </fieldset>
      </div>
    </div>
  </div>
  <c8y-data-grid
    class="content-fullpage d-flex d-col border-top border-bottom"
    [title]="tableTitle | translate"
    [loadingItemsLabel]="loadingItemsLabel | translate"
    [loadMoreItemsLabel]="loadMoreItemsLabel | translate"
    [columns]="columns"
    [pagination]="pagination"
    [serverSideDataCallback]="serverSideDataCallback"
    [refresh]="refresh"
    [hideReload]="true"
    [selectable]="selectable"
    [actionControls]="actionControls"
    [bulkActionControls]="bulkActionControls"
  >
    <c8y-ui-empty-state
      [icon]="stats?.size > 0 ? 'search' : 'input'"
      [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">
        <span title="{{ context.value }}">
          {{ context.value }}
        </span>
      </ng-container>
    </c8y-column>

    <c8y-column name="activeClients">
      <ng-container *c8yCellRendererDef="let context">
        <span title="{{ context.value | number }}">
          {{ context.value | number }}
        </span>
      </ng-container>
    </c8y-column>

    <c8y-column name="messageAckRate">
      <ng-container *c8yCellRendererDef="let context">
        <span title="{{ context.value | number }}">
          {{ context.value | number }}
        </span>
      </ng-container>
    </c8y-column>

    <c8y-column name="lastAcknowledgeDate">
      <ng-container *c8yCellRendererDef="let context">
        <span
          title="{{ context.value }}"
          *ngIf="context.value; else noLastAcknwoldegeDate"
        >
          {{ context.value | relativeTime }}
        </span>
        <ng-template #noLastAcknwoldegeDate>&ndash;</ng-template>
      </ng-container>
    </c8y-column>

    <c8y-column name="unackMsgBacklog">
      <ng-container *c8yCellRendererDef="let context">
        <span title="{{ context.value | number }}">
          {{ context.value | number }}
        </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>

results matching ""

    No results matching ""