File

projects/core/src/lib/action-group/action-group.ts

Description

ActionGroup used to group certain actions in one logical component Can be used either as group either as dropdown

Example

const group = new ActionGroup({
children: [
new ActionButton({ title: 'Test' }),
new ActionGroup({ dropdown: true }),
new ActionToggle({ checked: true })
]
});

Or

const group = actionFactory.createGroup().appendChildren([
actionFactory.createButton().setTitle('Test'),
actionFactory.createGroup().enableDropdown(),
actionFactory.createToggle().check()
]);

Or

const group = actionFactory.createGroup();
group.createButton().setTitle('Test');
group.createGroup().enableDropdown();
group.createToggle().check();

Extends

ActionAbstract

Implements

ActionOutlet

Index

Properties
Methods

Constructor

constructor(options: ActionGroupOptions, component?: Type<ActionGroupComponentImpl>)

Public constructor used to instantiate ActionGroup

Parameters :
Name Type Optional Description
options ActionGroupOptions No

Options for ActionGroup

component Type<ActionGroupComponentImpl> Yes

Optional custom Component

Properties

Readonly changes$
Type : Observable<ActionGroupOptions>
Inherited from ActionAbstract
Defined in ActionAbstract:74

Observable that notifies subscriptions on following changes: title, icon, visibility, disabled, children, dropdown

Readonly children$
Type : Observable<AnyAction[]>

Observable that notifies subscriptions to any change to children: append, prepend, remove, etc.

Readonly dropdown$
Type : Observable<boolean>

Observable that notifies subscriptions when ActionGroup is changed to dropdown or vice versa

Readonly fire$
Type : Observable<ActionGroupEvent>
Inherited from ActionAbstract
Defined in ActionAbstract:69

Observable that notifies subscriptions on action triggering Empty observable in case of 'ActionGroup'

Readonly ariaLabel$
Type : Observable<string>
Inherited from ActionAbstract
Defined in ActionAbstract:124

Observable that notifies subscribers when the ariaLabel changes.

Readonly disabled$
Type : Observable<boolean>
Inherited from ActionAbstract
Defined in ActionAbstract:115

Observable that notifies subscriptions when disabled state changes

Readonly icon$
Type : Observable<string>
Inherited from ActionAbstract
Defined in ActionAbstract:106

Observable that notifies subscriptions when icon changes

Readonly state$
Type : Observable<ActionState>
Inherited from ActionAbstract
Defined in ActionAbstract:120

Observable that notifies subscriptions when action state changes e.g. Active, Inactive, Destroyed

Readonly title$
Type : Observable<string>
Inherited from ActionAbstract
Defined in ActionAbstract:102

Observable that notifies subscriptions when title changes

Readonly visible$
Type : Observable<boolean>
Inherited from ActionAbstract
Defined in ActionAbstract:111

Observable that notifies subscriptions when visibility state changes (visible or hidden)

Methods

activate
activate()
Inherited from ActionAbstract
Defined in ActionAbstract:147

Activates group action and all it's children

Example:

group.activate();
appendChild
appendChild(action: AnyAction)

Adds provided action at the end of children stach

Example:

const child = actionFactory.createButton({ title: 'Test' });
group.appendChild(child);
Parameters :
Name Type Optional Description
action AnyAction No

Action to append

appendChildren
appendChildren(actions: AnyAction[])

Adds provided actions at the end of children stach

Example:

const child1 = actionFactory.createButton({ title: 'Test 1' });
const child2 = actionFactory.createButton({ title: 'Test 2' });
group.appendChildren([ child1, child2 ]);
Parameters :
Name Type Optional Description
actions AnyAction[] No

Actions to append

createButton
createButton(options?: ActionButtonOptions, component?: Type<ActionButtonComponentImpl>)

Creates a new ActionButton and appends it to the children stack

Example:

const childButton = group.createButton({ title: 'Test' });
Parameters :
Name Type Optional Description
options ActionButtonOptions Yes

Options for ActionButton

component Type<ActionButtonComponentImpl> Yes

Optional Component

Returns : ActionButton
createGroup
createGroup(options?: ActionGroupOptions, component?: Type<ActionGroupComponentImpl>)

Creates a new ActionGroup and appends it to the children stack

Example:

const childGroup = group.createGroup({ dropdown: true });
Parameters :
Name Type Optional Description
options ActionGroupOptions Yes

Options for ActionGroup

component Type<ActionGroupComponentImpl> Yes

Optional Component

Returns : ActionGroup
createToggle
createToggle(options?: ActionToggleOptions, component?: Type<ActionToggleComponentImpl>)

Creates a new ActionToggle and appends it to the children stack

Example:

const childToggle = group.createToggle({ checked: true });
Parameters :
Name Type Optional Description
options ActionToggleOptions Yes

Options for ActionToggle

component Type<ActionToggleComponentImpl> Yes

Optional Component

Returns : ActionToggle
deactivate
deactivate()
Inherited from ActionAbstract
Defined in ActionAbstract:166

Deactivates group action and all it's children

Example:

group.deactivate();
destroy
destroy()
Inherited from ActionAbstract
Defined in ActionAbstract:185

Destroys group action, destroys and removes all it's children

Example:

group.destroy();
disable
disable()
Inherited from ActionAbstract
Defined in ActionAbstract:216

Disables group action and all it's children

Example:

group.disable();
disableDropdown
disableDropdown()

Transforms dropdown to group

Example:

group.disableDropdown();
enable
enable()
Inherited from ActionAbstract
Defined in ActionAbstract:201

Enables group action and all it's children

Example:

group.enable();
enableDropdown
enableDropdown()

Transforms the group to dropdown

Example:

group.enableDropdown();
getChild
getChild(index: number)

Returns child action at given index

Example:

const child = group.getChild(0);
Parameters :
Name Type Optional Description
index number No

Index of child action

getChildren
getChildren()

Returns the current children

Example:

const children = group.getChildren();
Returns : AnyAction[]
isDropdown
isDropdown()

Returns boolean defining whether group is dropdown or not

Example:

const isDropdown = group.isDropdown();
Returns : boolean
prependChild
prependChild(action: AnyAction)

Adds provided action at the beginning of children stack

Example:

const child = actionFactory.createButton({ title: 'Test' });
group.prependChild(child);
Parameters :
Name Type Optional Description
action AnyAction No

Action to prepend

prependChildren
prependChildren(actions: AnyAction[])

Adds provided actions at the beginning of children stack

Example:

const child1 = actionFactory.createButton({ title: 'Test 1' });
const child2 = actionFactory.createButton({ title: 'Test 2' });
group.prependChildren([ child1, child2 ]);
Parameters :
Name Type Optional Description
actions AnyAction[] No

Actions to prepend

removeChild
removeChild(action: AnyAction)

Removes provided child action from group

Example:

group.removeChild(child);
Parameters :
Name Type Optional Description
action AnyAction No

Child action to be removed

removeChildByIndex
removeChildByIndex(index: number)

Removes child action from group at given index

Example:

group.removeChildByIndex(0);
Parameters :
Name Type Optional Description
index number No

Index of child action

removeChildren
removeChildren()

Removes all children from group

Example:

group.removeChildren();
setChildren
setChildren(children: AnyAction[])

Provided actions will replace existing children and will:

  • Apply as unique array
  • Ignore actions with different parent

Example:

const child1 = actionFactory.createButton({ title: 'Test 1' });
const child2 = actionFactory.createButton({ title: 'Test 2' });
group.setChildren([ child1, child2 ]);
Parameters :
Name Type Optional Description
children AnyAction[] No

Actions to become children

trigger
trigger()
Inherited from ActionAbstract
Defined in ActionAbstract:133

Trigger for group action. In case of ActionGroup Noop

Example:

group.trigger();
getAriaLabel
getAriaLabel()
Inherited from ActionAbstract
Defined in ActionAbstract:355

Returns current action ariaLabel

Returns : string
getForcedComponent
getForcedComponent()
Inherited from ActionAbstract
Defined in ActionAbstract:451

Returns a Component, that is provided as forced component via action constructor This component should be used by ActionOutletDirective, to represent the action in DOM, instead the component, provided via Angular Injector

Returns : Type | undefined
getIcon
getIcon()
Inherited from ActionAbstract
Defined in ActionAbstract:372

Returns current action icon

Returns : string
getParent
getParent()
Inherited from ActionAbstract
Defined in ActionAbstract:458

Returns current parent of the action

getTitle
getTitle()
Inherited from ActionAbstract
Defined in ActionAbstract:338

Returns current action title

Returns : string
hide
hide()
Inherited from ActionAbstract
Defined in ActionAbstract:387

Will nide the action, if previously visible

isActive
isActive()
Inherited from ActionAbstract
Defined in ActionAbstract:307

Returns boolean defining whether action has state ActionState.Active

Returns : boolean
isDestroyed
isDestroyed()
Inherited from ActionAbstract
Defined in ActionAbstract:321

Returns boolean defining whether action has state ActionState.Destroyed

Returns : boolean
isDisabled
isDisabled()
Inherited from ActionAbstract
Defined in ActionAbstract:435

Returns boolean defining whether action is disabled

Returns : boolean
isEnabled
isEnabled()
Inherited from ActionAbstract
Defined in ActionAbstract:442

Returns boolean defining whether action is enabled

Returns : boolean
isHidden
isHidden()
Inherited from ActionAbstract
Defined in ActionAbstract:412

Returns boolean defining whether action is hidden

Returns : boolean
isInactive
isInactive()
Inherited from ActionAbstract
Defined in ActionAbstract:314

Returns boolean defining whether action has state ActionState.Inactive

Returns : boolean
isVisible
isVisible()
Inherited from ActionAbstract
Defined in ActionAbstract:405

Returns boolean defining whether action is visible

Returns : boolean
setAriaLabel
setAriaLabel(ariaLabel: string)
Inherited from ActionAbstract
Defined in ActionAbstract:347

Will set the new ariaLabel and notify all ariaLabel subscribers

Parameters :
Name Type Optional Description
ariaLabel string No

The new action title

setIcon
setIcon(icon: string)
Inherited from ActionAbstract
Defined in ActionAbstract:364

Will set the new icon and notify all icon subscriptions

Parameters :
Name Type Optional Description
icon string No

The new action icon

setTitle
setTitle(title: string)
Inherited from ActionAbstract
Defined in ActionAbstract:330

Will set the new title and notify all title subscriptions

Parameters :
Name Type Optional Description
title string No

The new action title

setVisibility
setVisibility(visibility: boolean)
Inherited from ActionAbstract
Defined in ActionAbstract:397

Will show or hide the action depending from the provided visibility boolean

Parameters :
Name Type Optional Description
visibility boolean No

The new visibility

show
show()
Inherited from ActionAbstract
Defined in ActionAbstract:379

Will show the action, if previously hidden

import { Type } from '@angular/core';
import { BehaviorSubject, Observable, NEVER, merge } from 'rxjs';
import { map } from 'rxjs/operators';

import { ActionAbstract } from '../action-abstract/action-abstract';
import { ActionButton } from '../action-button/action-button';
import { ActionButtonComponentImpl, ActionButtonOptions } from '../action-button/action-button.model';
import { ActionOutlet, AnyAction } from '../action-outlet.model';
import { ActionToggle } from '../action-toggle/action-toggle';
import { ActionToggleComponentImpl, ActionToggleOptions } from '../action-toggle/action-toggle.model';
import { ActionGroupComponentImpl, ActionGroupEvent, ActionGroupOptions } from './action-group.model';

/**
 * Default options for `ActionGroup`
 * Extended by provided options in action `constructor`
 */
const defaultGroupOptions: ActionGroupOptions = {
  children: [],
  dropdown: false,
};

/**
 * Will return a unique array of actions
 *
 * @param children The array of actions
 */
const unique = (children: AnyAction[]) => Array.from(new Set(children));

/**
 * `ActionGroup` used to group certain actions in one logical component
 * Can be used either as **group** either as **dropdown**
 *
 * ## Example
 *
```typescript
const group = new ActionGroup({
   children: [
       new ActionButton({ title: 'Test' }),
       new ActionGroup({ dropdown: true }),
       new ActionToggle({ checked: true })
   ]
});
```
 *
 * **Or**
 *
```typescript
const group = actionFactory.createGroup().appendChildren([
    actionFactory.createButton().setTitle('Test'),
    actionFactory.createGroup().enableDropdown(),
    actionFactory.createToggle().check()
]);
```
 *
 * **Or**
 *
```typescript
const group = actionFactory.createGroup();
group.createButton().setTitle('Test');
group.createGroup().enableDropdown();
group.createToggle().check();
```
 */
export class ActionGroup extends ActionAbstract<ActionGroupOptions, ActionGroupEvent> implements ActionOutlet {
  /**
   * `Observable` that notifies subscriptions on action triggering
   * Empty observable in case of 'ActionGroup'
   */
  readonly fire$: Observable<ActionGroupEvent>;
  /**
   * `Observable` that notifies subscriptions on following changes:
   * *title, icon, visibility, disabled, children, dropdown*
   */
  readonly changes$: Observable<ActionGroupOptions>;
  /**
   * `Observable` that notifies subscriptions to any change to children:
   * *append, prepend, remove, etc.*
   */
  readonly children$: Observable<AnyAction[]>;
  /**
   * `Observable` that notifies subscriptions when `ActionGroup` is changed to dropdown or vice versa
   */
  readonly dropdown$: Observable<boolean>;

  /**
   * `BehaviorSubject`, holding **all** children of `ActionGroup` instance
   */
  protected readonly children: BehaviorSubject<AnyAction[]>;
  /**
   * `BehaviorSubject`, holding boolean to define whether `ActionGroup` instance is dropdown
   */
  protected readonly dropdown: BehaviorSubject<boolean>;

  /**
   * Public `constructor` used to instantiate `ActionGroup`
   *
   * @param options Options for `ActionGroup`
   * @param component Optional custom `Component`
   */
  constructor(options: ActionGroupOptions = defaultGroupOptions, component?: Type<ActionGroupComponentImpl>) {
    super({ ...defaultGroupOptions, ...options }, component);

    this.children = new BehaviorSubject(unique(this.options.children.map(action => action._setParent(this))));
    this.dropdown = new BehaviorSubject(!!this.options.dropdown);

    this.fire$ = this.handleLivecycle(NEVER, false);
    this.children$ = this.handleLivecycle(this.children.asObservable());
    this.dropdown$ = this.handleLivecycleDistinct(this.dropdown.asObservable());

    this.changes$ = this.handleLivecycle(
      merge(
        this.title$.pipe(map(title => <ActionGroupOptions>{ title })),
        this.icon$.pipe(map(icon => <ActionGroupOptions>{ icon })),
        this.visible$.pipe(map(visible => <ActionGroupOptions>{ visible })),
        this.disabled$.pipe(map(disabled => <ActionGroupOptions>{ disabled })),
        this.children$.pipe(map(children => <ActionGroupOptions>{ children })),
        this.dropdown$.pipe(map(dropdown => <ActionGroupOptions>{ dropdown })),
      ),
    );
  }

  /**
     * Trigger for group action.
     * In case of `ActionGroup` **Noop**
     *
     * #### Example:
```typescript
group.trigger();
```
     *
     * @method trigger
     */
  trigger(): this {
    return this;
  }

  /**
     * Activates group action and **all** it's children
     *
     * #### Example:
```typescript
group.activate();
```
     *
     * @method activate
     */
  activate(): this {
    if (this.isDestroyed()) {
      return this;
    }

    this.getChildren().forEach(child => child.activate());
    return super.activate();
  }

  /**
     * Deactivates group action and **all** it's children
     *
     * #### Example:
```typescript
group.deactivate();
```
     *
     * @method deactivate
     */
  deactivate(): this {
    if (this.isDestroyed()) {
      return this;
    }

    this.getChildren().forEach(child => child.deactivate());
    return super.deactivate();
  }

  /**
     * Destroys group action, **destroys** and **removes** **all** it's children
     *
     * #### Example:
```typescript
group.destroy();
```
     *
     * @method destroy
     */
  destroy(): this {
    this.getChildren().forEach(child => child.destroy());
    this.removeChildren();
    return super.destroy();
  }

  /**
     * Enables group action and **all** it's children
     *
     * #### Example:
```typescript
group.enable();
```
     *
     * @method enable
     */
  enable(): this {
    this.getChildren().forEach(child => child.enable());
    return super.enable();
  }

  /**
     * Disables group action and **all** it's children
     *
     * #### Example:
```typescript
group.disable();
```
     *
     * @method disable
     */
  disable(): this {
    this.getChildren().forEach(child => child.disable());
    return super.disable();
  }

  /**
     * Creates a new `ActionButton` and **appends** it to the children stack
     *
     * #### Example:
 ```typescript
 const childButton = group.createButton({ title: 'Test' });
 ```
     *
     * @method createButton
     * @param options Options for `ActionButton`
     * @param component Optional `Component`
     */
  createButton(options?: ActionButtonOptions, component?: Type<ActionButtonComponentImpl>): ActionButton {
    const action = new ActionButton(options, component);
    this.appendChild(action);
    return action;
  }

  /**
     * Creates a new `ActionGroup` and **appends** it to the children stack
     *
     * #### Example:
```typescript
const childGroup = group.createGroup({ dropdown: true });
```
     *
     * @method createGroup
     * @param options Options for `ActionGroup`
     * @param component Optional `Component`
     */
  createGroup(options?: ActionGroupOptions, component?: Type<ActionGroupComponentImpl>): ActionGroup {
    const group = new ActionGroup(options, component);
    this.appendChild(group);
    return group;
  }

  /**
     * Creates a new `ActionToggle` and **appends** it to the children stack
     *
     * #### Example:
```typescript
const childToggle = group.createToggle({ checked: true });
```
     *
     * @method createToggle
     * @param options Options for `ActionToggle`
     * @param component Optional `Component`
     */
  createToggle(options?: ActionToggleOptions, component?: Type<ActionToggleComponentImpl>): ActionToggle {
    const toggle = new ActionToggle(options, component);
    this.appendChild(toggle);
    return toggle;
  }

  /**
     * Adds provided action **at the end** of children stach
     *
     * #### Example:
```typescript
const child = actionFactory.createButton({ title: 'Test' });
group.appendChild(child);
```
     *
     * @method appendChild
     * @param action Action to append
     */
  appendChild(action: AnyAction): this {
    const children = this.getChildren();
    this.setChildrenInternal([...children, action._setParent(this)]);
    return this;
  }

  /**
     * Adds provided actions **at the end** of children stach
     *
     * #### Example:
```typescript
const child1 = actionFactory.createButton({ title: 'Test 1' });
const child2 = actionFactory.createButton({ title: 'Test 2' });
group.appendChildren([ child1, child2 ]);
```
     *
     * @method appendChildren
     * @param actions Actions to append
     *
     */
  appendChildren(actions: AnyAction[]): this {
    const children = this.getChildren();
    this.setChildrenInternal([...children, ...actions.map(action => action._setParent(this))]);
    return this;
  }

  /**
     * Adds provided action **at the beginning** of children stack
     *
     * #### Example:
```typescript
const child = actionFactory.createButton({ title: 'Test' });
group.prependChild(child);
```
     *
     * @method prependChild
     * @param action Action to prepend
     */
  prependChild(action: AnyAction): this {
    const children = this.getChildren();
    this.setChildrenInternal([action._setParent(this), ...children]);
    return this;
  }

  /**
     * Adds provided actions **at the beginning** of children stack
     *
     * #### Example:
```typescript
const child1 = actionFactory.createButton({ title: 'Test 1' });
const child2 = actionFactory.createButton({ title: 'Test 2' });
group.prependChildren([ child1, child2 ]);
```
     *
     * @method prependChildren
     * @param actions Actions to prepend
     */
  prependChildren(actions: AnyAction[]): this {
    const children = this.getChildren();
    this.setChildrenInternal([...actions.map(action => action._setParent(this)), ...children]);
    return this;
  }

  /**
     * Removes provided child action from group
     *
     * #### Example:
```typescript
group.removeChild(child);
```
     *
     * @method removeChild
     * @param action Child action to be removed
     */
  removeChild(action: AnyAction): this {
    const index = this.getChildren().indexOf(action);
    return this.removeChildByIndex(index);
  }

  /**
     * Removes child action from group at given index
     *
     * #### Example:
```typescript
group.removeChildByIndex(0);
```
     *
     * @method removeChildByIndex
     * @param index Index of child action
     */
  removeChildByIndex(index: number): this {
    const children = this.getChildren();
    const action = children[index];

    if (action) {
      action._unsetParent();
      this.setChildrenInternal(children.filter((_child, childIndex) => index !== childIndex));
    }

    return this;
  }

  /**
     * Removes **all** children from group
     *
     * #### Example:
```typescript
group.removeChildren();
```
     *
     * @method removeChildren
     */
  removeChildren(): this {
    this.getChildren().forEach(child => child._unsetParent());
    this.setChildrenInternal([]);
    return this;
  }

  /**
     * Provided actions will **replace** existing children and will:
     * - **Apply** as **unique** array
     * - **Ignore** actions with different parent
     *
     * #### Example:
```typescript
const child1 = actionFactory.createButton({ title: 'Test 1' });
const child2 = actionFactory.createButton({ title: 'Test 2' });
group.setChildren([ child1, child2 ]);
```
     *
     * @method setChildren
     * @param children Actions to become children
     */
  setChildren(children: AnyAction[]): this {
    this.children.getValue().map(child => child._unsetParent());
    this.children.next(this.normalizeChildren(children).map(child => child._setParent(this)));

    return this;
  }

  /**
     * Returns the current children
     *
     * #### Example:
```typescript
const children = group.getChildren();
```
     *
     * @method getChildren
     */
  getChildren(): AnyAction[] {
    return [...this.children.getValue()];
  }

  /**
     * Returns child action at given index
     *
     * #### Example:
```typescript
const child = group.getChild(0);
```
     *
     * @method getChild
     * @param index Index of child action
     */
  getChild(index: number): AnyAction | undefined {
    const children = this.getChildren();

    if (index >= 0) {
      return children[index];
    }

    return children[children.length - -index];
  }

  /**
     * Returns boolean defining whether group is dropdown or not
     *
     * #### Example:
```typescript
const isDropdown = group.isDropdown();
```
     *
     * @method isDropdown
     */
  isDropdown(): boolean {
    return this.dropdown.getValue();
  }

  /**
     * Transforms the group to dropdown
     *
     * #### Example:
```typescript
group.enableDropdown();
```
     *
     * @method enableDropdown
     */
  enableDropdown(): this {
    this.dropdown.next(true);
    return this;
  }

  /**
     * Transforms dropdown to group
     *
     * #### Example:
```typescript
group.disableDropdown();
```
     *
     * @method disableDropdown
     */
  disableDropdown(): this {
    this.dropdown.next(false);
    return this;
  }

  /**
   * Normalizes the provided array of children by filtering out actions
   * that already belong to certain parent group.
   *
   * @method normalizeChildren
   */
  private normalizeChildren(children: AnyAction[]) {
    return unique(children).filter(child => {
      const parent = child.getParent();
      return parent === this || parent === undefined;
    });
  }

  /**
   * Does the same thing as `setChildren` but ignores `_setParent` call,
   * because parent is expceted to be correct already
   *
   * @method setChildrenInternal
   */
  private setChildrenInternal(children: AnyAction[]): this {
    this.children.next(this.normalizeChildren(children));

    return this;
  }
}

results matching ""

    No results matching ""