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, featureService: FeatureService)
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
featureService FeatureService No

Methods

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.featureService .detail('certificate-authority') .then(({ data }) => data.active)
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').value as Array<{ id: string }> ).filter(el => el.id === control.value); return found.length === 0; }, 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' } }
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
            type="checkbox"
            name="useEST"
            id="useEST"
            [ngModel]="useEST$.getValue()"
            (ngModelChange)="useEST$.next($event)"
          />
          <span></span>
          <span class="control-label">{{ 'Create device certificates during device registration' | translate }}</span>
          <button
            type="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"
          ></button>
        </label>
      </div>
      <div>
        <formly-form
          [form]="form"
          [fields]="fields"
          [model]="model"
          [options]="options"
          class="formly-group-array-cols d-block p-l-24 p-b-24 min-height-fit p-r-8"
          [ngClass]="{'p-t-24' : !(certificateAuthorityFeatureEnabled | async)}"
        ></formly-form>
      </div>
      <c8y-stepper-buttons
        (onNext)="registerDevice($event)"
        (onCancel)="bsModalRef.hide()"
        [showButtons]="{ cancel: true, next: true }"
        [disabled]="!form?.valid"
        [pending]="isLoading$ | async"
        class="sticky-bottom d-block p-t-16 p-b-16 separator-top bg-level-0"
      ></c8y-stepper-buttons>
    </cdk-step>
    <cdk-step state="final">
      <div class="p-24 min-height-fit">
        <c8y-operation-result
          *ngIf="success.length === 1 && failed.length === 0"
          text="{{ 'Device registered' | translate }}"
          [size]="84"
          [vertical]="true"
          type="success"
          class="lead"
        ></c8y-operation-result>
        <c8y-operation-result
          *ngIf="success.length === 0 && failed.length === 1"
          text="{{ 'Failed to register device' | translate }}"
          [size]="84"
          [vertical]="true"
          type="error"
          class="lead"
        ></c8y-operation-result>

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

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

        <div class="m-b-8 p-l-24 p-r-24" *ngIf="success.length > 0" translate>
          Turn on the registered device(s) and wait for connection(s) 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.
        </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)="bsModalRef.hide()"
        (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 ""