File

core/wizard/wizard.component.ts

Description

A generic component that is intended to serve as the building block of more wizards.

Example

<button
   title="Add application"
   class="btn btn-primary"
   (click)="addApplication()"
 >
   Add application
 </button>
import { Component } from '@angular/core';
import { WizardConfig, WizardService, Wizard } from '@c8y/ngx-components';
import { ModalOptions } from 'ngx-bootstrap/modal';

@Component({
 selector: 'c8y-add-application-wizard',
 templateUrl: './templatePath'
})
export class AddApplicationWizardComponent {
  constructor(private wizardService: WizardService) {}

  addApplication() {
    const wizardConfig: WizardConfig = {
      headerText: 'Add Application',
      headerIcon: 'c8y-icon-modules',
      bodyHeaderText: 'Select methods',
      bodyHeaderIcon: 'c8y-icon-modules'
    };

    const initialState: Wizard = {
      wizardConfig,
      id: 'uploadApplication'
    };

    const modalOptions: ModalOptions = { initialState };

    this.wizardService.show(modalOptions);
  }
}

Implements

Wizard OnInit

Metadata

Index

Properties
Methods
Inputs
Outputs

Constructor

constructor(wizardService: WizardService, bsModalRef: BsModalRef)
Parameters :
Name Type Optional
wizardService WizardService No
bsModalRef BsModalRef No

Inputs

id
Type : string

The id parameter identifies the particular wizard and can be used to refer to it when hooking wizard entries. Example: "wizardId".

wizardConfig
Type : WizardConfig
Default value : {}

A configuration object that allows you to set header values, both text and icon.

Outputs

onClose
Type : EventEmitter<any>

The event that is emitted when the wizard is closed.

onReset
Type : EventEmitter<any>

The event that is emitted when the wizard is reseted.

onSelect
Type : EventEmitter<WizardEntry>

The event that is emitted when the wizard entry is clicked.

Methods

close
close(result?: any)

Closes the wizard.

Parameters :
Name Type Optional Description
result any Yes

Custom result object which will be emitted via onClose output.

Returns : void
ngOnInit
ngOnInit()
Returns : void
onPath
onPath()
Returns : void
reset
reset(result?: any)

Resets the wizard.

Parameters :
Name Type Optional Description
result any Yes

Custom result object which will be emitted via onReset output.

Returns : void

Properties

body
Type : TemplateRef<any>
Decorators :
@ViewChild('bodyRef', {static: true})
Readonly bodyTemplate$
Default value : this.wizardService.bodyTemplate$.pipe( filter(body => body.wizardId === this.id) )
Public bsModalRef
Type : BsModalRef
componentInitialState
Type : Partial<T>
Default value : {}

A state that will be assigned to the actual component contained by the wizard.

footer
Type : TemplateRef<any>
Decorators :
@ViewChild('footerRef', {static: true})
Readonly footerTemplate$
Default value : this.wizardService.footerTemplate$.pipe( filter(footer => footer.wizardId === this.id) )
header
Type : TemplateRef<any>
Decorators :
@ViewChild('headerRef', {static: true})
Readonly headerTemplate$
Default value : this.wizardService.headerTemplate$.pipe( filter(header => header.wizardId === this.id) )
outlet
Type : WizardOutletComponent
Decorators :
@ViewChild(WizardOutletComponent)
Public wizardService
Type : WizardService

Wizard component

This is a generic component serving as a base block for building custom wizards. It provides many possibilities for composing custom wizards, all of these methods will be described below.

The main responsibility of a generic wizard is to present the available options to the user, and then respond to the user's choice. On this basis, the user will be redirected to a specific component under the given path, or that component will be rendered in the wizard.

Usage examples

Minimal setup

By using the wizard configuration object (represented by WizardConfig interface), you can provide the content that will be displayed in the header and in the body header section.

The id parameter determines the display type of the wizard.

import { Component } from '@angular/core';
import { WizardConfig, WizardModalService } from '@c8y/ngx-components';
import { ModalOptions } from 'ngx-bootstrap/modal';

@Component({
  selector: 'wizard-demo'
})
export class WizardDemoComponent {
  constructor(private c8yWizardModalService: WizardModalService) {}

  addApplication() {
    const wizardConfig: WizardConfig = {
      headerText: 'Add Application',
      headerIcon: 'c8y-icon-modules',
      bodyHeaderText: 'Select methods',
      bodyHeaderIcon: 'c8y-icon-modules'
    };

    const initialState = {
      id: 'wizardId',
      wizardConfig
    };

    const modalOptions: ModalOptions = { initialState };

    this.c8yWizardModalService.show(modalOptions);
  }
}

You can use BsModalService directly from ngx-bootstrap/modal to show the wizard.

import { Component } from '@angular/core';
import { WizardConfig, WizardComponent } from '@c8y/ngx-components';
import { ModalOptions } from 'ngx-bootstrap/modal';

@Component({
  selector: 'wizard-demo'
})
export class WizardDemoComponent {
  constructor(private bsModalService: BsModalService) {}

  addApplication() {
    const wizardConfig: WizardConfig = {
      headerText: 'Add Application',
      headerIcon: 'c8y-icon-modules',
      bodyHeaderText: 'Select methods',
      bodyHeaderIcon: 'c8y-icon-modules'
    };

    // Configure the initial state of the wizard.
    const initialState = {
      id: 'wizardId',
      wizardConfig
    };
    const modalOptions: ModalOptions = { initialState };

    // Configure modal options.
    const options = {
      class: 'modal-sm',
      backdrop: 'static',
      ...modalOptions
    } as ModalOptions<WizardComponent>;

    this.bsModalService.show<WizardComponent>(WizardComponent, options);
  }
}

Add an entry to the wizard menu (HOOK_WIZARD)

We've added a new hook that adds an entry to the wizard's menu. This menu entry will lead to a "ContainerComponent" created below.

If the wizard contains only one entry without a path, the list will be skipped.

import { NgModule } from '@angular/core';
import { HOOK_WIZARD } from '@c8y/ngx-components';
import { ContainerComponent } from 'pathToYourContainerComponent';

@NgModule({
  declarations: [ContainerComponent],
  entryComponents: [ContainerComponent],
  providers: [
    {
      provide: HOOK_WIZARD,
      useValue: {
        // The id of a wizard to which the entry should be hooked.
        wizardId: 'wizardId',
        // The container component is responsible for handling subsequent steps in the wizard.
        component: ContainerComponent,
        // Menu entry name
        name: 'Upload application',
        // Menu entry icon
        c8yIcon: 'upload'
      },
      multi: true
    }
  ]
})
export class YourModule {}

Configuration of the container component passed in the HOOK_WIZARD

Component responsible for handling subsequent steps in the wizard.

Use c8y-wizard-header, c8y-wizard-body and c8y-wizard-footer in your custom component to maintain the correct layout.

import { Component } from '@angular/core';
import { WizardComponent } from '@c8y/ngx-components';

@Component({
  selector: 'container-component',
  template: `
    <c8y-wizard-header>
      New header content
    </div>
    </c8y-wizard-header>
    <c8y-wizard-body>
      New body content
    </c8y-wizard-body>
    <c8y-wizard-footer>
      <button
        (click)="back()"
      >
        Back
      </button>

      <button 
        (click)="cancel()"
      >
        Cancel
      </button>
    </c8y-wizard-footer>
  `
})
export class ContainerComponent {
  attributeToBePassed: string;

  constructor(private wizardComponent: WizardComponent) {}

  back() {
    const result: any = 'dataToBeEmittedOnReset';
    this.wizardComponent.reset(result);
  }

  cancel() {
    const result: any = 'dataToBeEmittedOnClose';
    this.wizardComponent.close(result);
  }
}

Handling selected menu entries via the initial state

The wizard component provides outputs that allow you to handle the selected menu entry, reset and close events.

Initial state approach

component-with-wizard.component.ts

import { Component } from '@angular/core';
import { WizardEntry, WizardConfig, Wizard, WizardModalService } from '@c8y/ngx-components';
import { CustomComponent } from './custom.component.ts';
import { takeUntil } from 'rxjs/operators';
import { ModalOptions } from 'ngx-bootstrap/modal';

@Component({
  selector: 'wizard-demo'
})
export class WizardDemoComponent {
  destroy$: Subject<boolean> = new Subject<boolean>();

  constructor(private c8yWizardModalService: WizardModalService) {}

  onButtonClick() {
    const wizardConfig: WizardConfig = {
      headerIcon: 'c8y-icon-modules',
      headerText: 'Wizard header',
      bodyHeaderText: 'Body section header'
    };

    const initialState: Wizard<ContainerComponent> = {
      id: 'wizardId',
      wizardConfig,
      componentState: {
        attributeToBePassed: 'Some sample text'
      }
    };
    const modalOptions: ModalOptions = { initialState };

    const modalRef = this.c8yWizardModalService.show(modalOptions);

    modalRef.content.onSelect.pipe(takeUntil(this.destroy$)).subscribe(menuEntry => {
      // handle menu entry
    });

    modalRef.content.onClose.pipe(takeUntil(this.destroy$)).subscribe(result => {
      // handle result
    });

    modalRef.content.onReset.pipe(takeUntil(this.destroy$)).subscribe(result => {
      // handle result
    });
  }

  ngOnDestroy() {
    this.destroy$.next(true);
    this.destroy$.unsubscribe();
  }
}

<div class="viewport-modal animated fadeIn">
  <ng-template *ngTemplateOutlet="(headerTemplate$ | async)?.template"></ng-template>

  <ng-template #headerRef>
    <div class="modal-header dialog-header animated fadeIn">
      <h1 [c8yIcon]="wizardConfig.headerIcon"></h1>
      <h4>{{ wizardConfig.headerText | translate }}</h4>
    </div>
  </ng-template>

  <ng-template *ngTemplateOutlet="(bodyTemplate$ | async)?.template"></ng-template>

  <ng-template #bodyRef>
    <div class="p-16 p-t-8 text-center" *ngIf="wizardConfig.bodyHeaderText">
      <div class="c8y-wizard-nav">
        <i [c8yIcon]="wizardConfig.bodyHeaderIcon"></i>
        <span>{{ wizardConfig.bodyHeaderText | translate }}</span>
      </div>
    </div>
  </ng-template>
  <c8y-wizard-outlet
    [initialState]="componentInitialState"
    [id]="id"
    (onSelect)="onSelect.emit($event)"
    (onPath)="onPath()"
  ></c8y-wizard-outlet>

  <ng-template *ngTemplateOutlet="(footerTemplate$ | async)?.template"></ng-template>
  <ng-template #footerRef>
    <div class="modal-footer animated fadeIn">
      <button
        (click)="close()"
        type="button"
        class="btn btn-default"
        title="{{ 'Cancel' | translate }}"
      >
        <span translate>Cancel</span>
      </button>
    </div>
  </ng-template>
</div>

results matching ""

    No results matching ""