File

register-device/general/general-device-registration.component.ts

Implements

AfterViewInit OnDestroy

Metadata

Index

Properties
Methods

Constructor

constructor(tenantUIService: TenantUiService, tenantService: TenantService, registerDeviceService: RegisterDeviceService, inventoryService: InventoryService, cd: ChangeDetectorRef, bsModalRef: BsModalRef, gainsightService: GainsightService, deviceRegistrationService: DeviceRegistrationBulkService, featureCacheService: FeatureCacheService)
Parameters :
Name Type Optional
tenantUIService TenantUiService No
tenantService TenantService No
registerDeviceService RegisterDeviceService No
inventoryService InventoryService No
cd ChangeDetectorRef No
bsModalRef BsModalRef No
gainsightService GainsightService No
deviceRegistrationService DeviceRegistrationBulkService No
featureCacheService FeatureCacheService No

Methods

cancel
cancel()
Returns : void
close
close()
Returns : void
fixErrors
fixErrors(event: literal type, failedRequests: any)
Parameters :
Name Type Optional
event literal type No
failedRequests any No
Returns : void
ngAfterViewInit
ngAfterViewInit()
Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
registerDevice
registerDevice(eventObject: literal type)
Parameters :
Name Type Optional
eventObject literal type No
Returns : void

Properties

Public bsModalRef
Type : BsModalRef
certificateAuthorityFeatureEnabled
Default value : this.featureCacheService.getFeatureState('certificate-authority')
failed
Type : literal type[]
Default value : []
fields
Type : FormlyFieldConfig[]
Default value : [ { type: 'array', key: 'devicesToCreate', props: { addText: gettext('Add device'), addTextDataCy: 'add-device' }, fieldArray: { fieldGroup: [ { key: 'id', type: 'string', focus: true, props: { placeholder: '0123ab32fcd', label: gettext('Device ID'), required: true }, validators: { unique: { expression: (control: FormControl) => { const found = ( control.root.get('devicesToCreate') as FormArray< FormGroup<{ id: FormControl<string> }> > ).controls .map(el => el.controls.id) .find(el => el !== control && el.value === control.value); return !found; }, message: () => gettext('Device ID duplicates are not allowed') } } }, { key: 'tenant', type: 'typeahead', expressions: { hide: field => { const formState = field.options?.formState; if (!formState?.canLoadTenants) { field.formControl.setValue(null); } return !formState?.canLoadTenants || false; } }, defaultValue: { id: this.MANAGEMENT }, props: { label: gettext('Add to tenant'), required: true, c8yForOptions: this.canLoadTenants$().pipe( filter(canLoad => canLoad), switchMap(() => this.getTenants$()) ) as Observable<IResultList<ITenant>>, container: 'body', displayProperty: 'id', valueProperties: ['id'] }, hooks: { onInit: _field => this.canLoadTenants$().pipe( tap(canLoad => { this.options.formState.canLoadTenants = canLoad; this.cd.detectChanges(); }) ) } }, { key: 'group', type: 'typeahead', expressions: { 'props.disabled': (field: FormlyFieldConfig) => { const formState = field.options?.formState; const model = field.model; if (formState?.canLoadTenants) { if (model?.tenant?.id !== this.MANAGEMENT) { field.formControl.setValue(null); } return !(model?.tenant?.id === this.MANAGEMENT); } delete field?.props?.description; return false; } }, props: { disabled: false, label: gettext('Add to group'), description: gettext( 'You can add device to specific group for management tenant only.' ), container: 'body', displayProperty: 'name', valueProperties: ['id'], c8yForOptions: this.getGroups$() }, hooks: { onInit: _field => this.canLoadTenants$().pipe( tap(canLoad => { this.options.formState.canLoadTenants = canLoad; this.cd.detectChanges(); }) ) } }, { key: 'oneTimePassword', type: 'string', expressions: { hide: field => !field.options?.formState?.useEST }, props: { placeholder: 'TruDN3H45L0', label: gettext('One-time password'), required: true }, hooks: { onInit: _field => this.useEST$.pipe( tap(useEST => { this.options.formState.useEST = useEST; this.cd.detectChanges(); }) ) } } ] } } ]
Readonly FILTER
Type : object
Default value : { withTotalPages: true, pageSize: 25 }
form
Default value : new FormGroup({})
isLoading$
Type : Observable<boolean>
Readonly MANAGEMENT
Type : string
Default value : 'management'
model
Type : object
Default value : { devicesToCreate: [{} as GeneralDeviceRegistrationModelType] }
options
Type : FormlyFormOptions
Default value : { formState: { canLoadTenants: true, useEST: this.useEST$.getValue() } }
PRODUCT_EXPERIENCE
Type : object
Default value : { EVENT: 'deviceRegistration', COMPONENT: 'single-general-registration', RESULT: { SUCCESS: 'registrationSuccess', FAILURE: 'registrationFailure' } }
result
Default value : new Promise<void>((resolve, reject) => { this.onSuccessfulClosing = resolve; this.onCancel = reject; })
success
Type : literal type[]
Default value : []
useEST$
Default value : new BehaviorSubject<boolean>(false)
<c8y-modal
  [title]="'Register devices' | translate"
  [headerClasses]="'dialog-header'"
  [customFooter]="true"
>
  <ng-container c8y-modal-title>
    <span [c8yIcon]="'c8y-device-connect'"></span>
  </ng-container>
  <c8y-stepper
    [hideStepProgress]="true"
    linear
    c8y-modal-body
  >
    <cdk-step [stepControl]="form">
      <div class="text-center sticky-top bg-component">
        <p
          class="text-medium text-16 separator-bottom p-16"
          translate
        >
          Register general devices
        </p>
        <label
          class="c8y-switch m-24 a-i-center"
          title="{{ 'Create device certificates during device registration' | translate }}"
          for="useEST"
          *ngIf="certificateAuthorityFeatureEnabled | async"
        >
          <input
            id="useEST"
            name="useEST"
            type="checkbox"
            [ngModel]="useEST$.getValue()"
            (ngModelChange)="useEST$.next($event)"
          />
          <span></span>
          <span class="control-label">
            {{ 'Create device certificates during device registration' | translate }}
          </span>
          <button
            class="btn-help"
            [attr.aria-label]="'Help' | translate"
            popover="{{
              'The device registration process includes creating device certificates, which are issued by the tenant\'s Certificate Authority (CA).'
                | translate
            }}"
            placement="right"
            triggers="focus"
            container="body"
            type="button"
          ></button>
        </label>
      </div>
      <div>
        <formly-form
          class="formly-group-array-cols d-block p-l-24 p-b-24 min-height-fit p-r-8"
          [form]="form"
          [fields]="fields"
          [model]="model"
          [options]="options"
          [ngClass]="{ 'p-t-24': !(certificateAuthorityFeatureEnabled | async) }"
        ></formly-form>
      </div>
      <c8y-stepper-buttons
        class="sticky-bottom d-block p-t-16 p-b-16 separator-top bg-level-0"
        (onNext)="registerDevice($event)"
        (onCancel)="cancel()"
        [showButtons]="{ cancel: true, next: true }"
        [disabled]="!form?.valid"
        [pending]="isLoading$ | async"
      ></c8y-stepper-buttons>
    </cdk-step>
    <cdk-step state="final">
      <div class="p-24 min-height-fit">
        <c8y-operation-result
          class="lead"
          type="success"
          *ngIf="success.length === 1 && failed.length === 0"
          text="{{ 'Device registered' | translate }}"
          [size]="84"
          [vertical]="true"
        ></c8y-operation-result>
        <c8y-operation-result
          class="lead"
          type="error"
          *ngIf="success.length === 0 && failed.length === 1"
          text="{{ 'Failed to register device' | translate }}"
          [size]="84"
          [vertical]="true"
        ></c8y-operation-result>

        <ng-container *ngIf="success.length > 1 || failed.length > 1">
          <c8y-operation-result
            class="lead"
            type="success"
            *ngIf="failed.length === 0"
            [text]="
              '{{ successfulDevicesCount }} devices registered'
                | translate: { successfulDevicesCount: success.length }
            "
            [size]="84"
            [vertical]="true"
          ></c8y-operation-result>
          <c8y-operation-result
            class="lead"
            type="error"
            *ngIf="success.length === 0"
            [text]="
              '{{ failedDevicesCount }} devices failed to register'
                | translate: { failedDevicesCount: failed.length }
            "
            [size]="84"
            [vertical]="true"
          ></c8y-operation-result>
        </ng-container>

        <div
          class="p-l-24 p-r-24 text-center"
          *ngIf="success.length > 0 && failed.length > 0"
        >
          <c8y-operation-result
            class="lead"
            type="error"
            text="{{ 'Several devices failed to register' | translate }}"
            [size]="84"
            [vertical]="true"
          ></c8y-operation-result>
          <p
            class="p-b-16 text-danger"
            ngNonBindable
            translate
            [translateParams]="{ count: failed.length, total: failed.length + success.length }"
          >
            Registration failed for {{ count }} devices out of {{ total }}.
          </p>
        </div>

        <div
          class="m-b-8 p-l-24 p-r-24"
          data-cy="device-registration-success-message"
          *ngIf="success.length > 0"
        >
          <span
            *ngIf="!(useEST$ | async)"
            translate
          >
            Turn on the registered devices and wait for connections to be established. Once a device
            is connected, its status will change to "Pending acceptance". You will need to approve
            it by clicking on the "Accept" button.
          </span>
          <span
            *ngIf="useEST$ | async"
            translate
          >
            The successfully enrolled devices can now request signed certificates and use them to
            connect and authenticate to the platform via certificate-based authentication.
          </span>
        </div>

        <c8y-list-group class="separator-top m-t-16">
          <c8y-li *ngFor="let fail of failed">
            <c8y-li-icon
              class="text-danger"
              [icon]="'ban'"
            ></c8y-li-icon>
            <p>{{ fail?.id }}</p>
            <small>{{ fail?.message | translate }}</small>
            <c8y-li-collapse>
              <pre><code>{{ fail?.details | json }}</code></pre>
            </c8y-li-collapse>
          </c8y-li>

          <c8y-li *ngFor="let s of success">
            <c8y-li-icon
              class="text-success"
              [icon]="'check-circle'"
            ></c8y-li-icon>
            {{ s?.id }}
          </c8y-li>
        </c8y-list-group>
      </div>
      <c8y-stepper-buttons
        class="sticky-bottom d-block p-t-16 p-b-16 separator-top bg-level-0"
        (onCustom)="close()"
        (onBack)="fixErrors($event, failed)"
        [showButtons]="{ back: failed.length > 0, custom: true }"
        [labels]="{ back: 'Fix errors', custom: 'Close' }"
      ></c8y-stepper-buttons>
    </cdk-step>
  </c8y-stepper>
</c8y-modal>

results matching ""

    No results matching ""