All files / src/app/shared/datatable/table-actions table-actions.component.ts

100% Statements 63/63
95.24% Branches 40/42
100% Functions 17/17
100% Lines 56/56

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 14993x   93x     93x 93x             93x   93x   93x   93x           93x     290x       93x 312x 312x     93x 30x                 312x 312x 1x 1x   1244x 311x 1327x       882x 882x 1927x                             983x 983x 5x   1278x 978x 290x   978x                 93x 1278x 1278x 1278x 1278x     93x 380x 242x   138x                         93x 627x 627x 627x 176x   451x 451x         93x 570x 570x     93x               2x     93x 20x   93x  
import { Component, Input, OnInit } from '@angular/core';
 
import * as _ from 'lodash';
 
import { CdTableAction } from '../../models/cd-table-action';
import { CdTableSelection } from '../../models/cd-table-selection';
import { Permission } from '../../models/permissions';
 
@Component({
  selector: 'cd-table-actions',
  template: require('./table-actions.component.html'),
  styles: []
})
export class TableActionsComponent implements OnInit {
  @Input()
  permission: Permission;
  @Input()
  selection: CdTableSelection;
  @Input()
  tableActions: CdTableAction[];
 
  // Use this if you just want to display a drop down button,
  // labeled with the given text, with all actions in it.
  // This disables the main action button.
  @Input()
  onlyDropDown?: string;
 
  // Array with all visible actions
  dropDownActions: CdTableAction[] = [];
 
  constructor() {}
 
  ngOnInit() {
    this.removeActionsWithNoPermissions();
    this.updateDropDownActions();
  }
 
  toClassName(name: string): string {
    return name
      .replace(/ /g, '-')
      .replace(/[^a-z-]/gi, '')
      .toLowerCase();
  }
 
  /**
   * Removes all actions from 'tableActions' that need a permission the user doesn't have.
   */
  private removeActionsWithNoPermissions() {
    if (!this.permission) {
      this.tableActions = [];
      return;
    }
    const permissions = Object.keys(this.permission).filter((key) => this.permission[key]);
    this.tableActions = this.tableActions.filter((action) =>
      permissions.includes(action.permission)
    );
  }
 
  private updateDropDownActions() {
    this.dropDownActions = this.tableActions.filter((action) =>
      action.visible ? action.visible(this.selection) : action
    );
  }
 
  /**
   * Finds the next action that is used as main action for the button
   *
   * The order of the list is crucial to get the right main action.
   *
   * Default button conditions of actions:
   * - 'create' actions can be used with no or multiple selections
   * - 'update' and 'delete' actions can be used with one selection
   *
   * @returns {CdTableAction}
   */
  getCurrentButton(): CdTableAction {
    if (this.onlyDropDown) {
      return;
    }
    let buttonAction = this.dropDownActions.find((tableAction) => this.showableAction(tableAction));
    if (!buttonAction && this.dropDownActions.length > 0) {
      buttonAction = this.dropDownActions[0];
    }
    return buttonAction;
  }
 
  /**
   * Determines if action can be used for the button
   *
   * @param {CdTableAction} action
   * @returns {boolean}
   */
  private showableAction(action: CdTableAction): boolean {
    const condition = action.canBePrimary;
    const singleSelection = this.selection.hasSingleSelection;
    const defaultCase = action.permission === 'create' ? !singleSelection : singleSelection;
    return (condition && condition(this.selection)) || (!condition && defaultCase);
  }
 
  useRouterLink(action: CdTableAction): string {
    if (!action.routerLink || this.disableSelectionAction(action)) {
      return;
    }
    return _.isString(action.routerLink) ? action.routerLink : action.routerLink();
  }
 
  /**
   * Determines if an action should be disabled
   *
   * Default disable conditions of 'update' and 'delete' actions:
   * - If no or multiple selections are made
   * - If one selection is made, but a task is executed on that item
   *
   * @param {CdTableAction} action
   * @returns {Boolean}
   */
  disableSelectionAction(action: CdTableAction): Boolean {
    const permission = action.permission;
    const disable = action.disable;
    if (disable) {
      return Boolean(disable(this.selection));
    }
    const selected = this.selection.hasSingleSelection && this.selection.first();
    return Boolean(
      ['update', 'delete'].includes(permission) && (!selected || selected.cdExecuting)
    );
  }
 
  showDropDownActions() {
    this.updateDropDownActions();
    return this.dropDownActions.length > 1;
  }
 
  useClickAction(action: CdTableAction) {
    /**
     * In order to show tooltips for deactivated menu items, the class
     * 'pointer-events: auto;' has been added to the .scss file which also
     * re-activates the click-event.
     * To prevent calling the click-event on deactivated elements we also have
     * to check here if it's disabled.
     */
    return !this.disableSelectionAction(action) && action.click && action.click();
  }
 
  useDisableDesc(action: CdTableAction) {
    return action.disableDesc && action.disableDesc();
  }
}