xref: /openbmc/phosphor-webui/app/common/components/table/table-toolbar.js (revision 5b8cef81cfa896ecdb0b6ad9d43c78d67d087a62)
1*5b8cef81SYoshie Muranakawindow.angular && (function(angular) {
2*5b8cef81SYoshie Muranaka  'use strict';
3*5b8cef81SYoshie Muranaka
4*5b8cef81SYoshie Muranaka  /**
5*5b8cef81SYoshie Muranaka   *
6*5b8cef81SYoshie Muranaka   * tableToolbar Component
7*5b8cef81SYoshie Muranaka   *
8*5b8cef81SYoshie Muranaka   * To use:
9*5b8cef81SYoshie Muranaka   * The <table-toolbar> component expects an 'actions' attribute
10*5b8cef81SYoshie Muranaka   * that should be an array of action objects.
11*5b8cef81SYoshie Muranaka   * Each action object should have 'type', 'label', and 'file'
12*5b8cef81SYoshie Muranaka   * properties.
13*5b8cef81SYoshie Muranaka   *
14*5b8cef81SYoshie Muranaka   * actions: [
15*5b8cef81SYoshie Muranaka   *  {type: 'Edit', label: 'Edit', file: 'icon-edit.svg'},
16*5b8cef81SYoshie Muranaka   *  {type: 'Delete', label: 'Edit', file: 'icon-trashcan.svg'}
17*5b8cef81SYoshie Muranaka   * ]
18*5b8cef81SYoshie Muranaka   *
19*5b8cef81SYoshie Muranaka   * The 'type' property is a string value that will be emitted to the
20*5b8cef81SYoshie Muranaka   * parent component when clicked.
21*5b8cef81SYoshie Muranaka   *
22*5b8cef81SYoshie Muranaka   * The 'label' property is a string value that will render as text in
23*5b8cef81SYoshie Muranaka   * the button
24*5b8cef81SYoshie Muranaka   *
25*5b8cef81SYoshie Muranaka   * The 'file' property is a string value of the filename of the svg icon
26*5b8cef81SYoshie Muranaka   * to provide <icon> directive.
27*5b8cef81SYoshie Muranaka   *
28*5b8cef81SYoshie Muranaka   */
29*5b8cef81SYoshie Muranaka
30*5b8cef81SYoshie Muranaka  const controller = function() {
31*5b8cef81SYoshie Muranaka    /**
32*5b8cef81SYoshie Muranaka     * Set defaults if properties undefined
33*5b8cef81SYoshie Muranaka     * @param {[]} actions
34*5b8cef81SYoshie Muranaka     */
35*5b8cef81SYoshie Muranaka    const setActions = (actions = []) => {
36*5b8cef81SYoshie Muranaka      return actions
37*5b8cef81SYoshie Muranaka          .map((action) => {
38*5b8cef81SYoshie Muranaka            if (action.type === undefined) {
39*5b8cef81SYoshie Muranaka              return;
40*5b8cef81SYoshie Muranaka            }
41*5b8cef81SYoshie Muranaka            if (action.file === undefined) {
42*5b8cef81SYoshie Muranaka              action.file = null;
43*5b8cef81SYoshie Muranaka            }
44*5b8cef81SYoshie Muranaka            return action;
45*5b8cef81SYoshie Muranaka          })
46*5b8cef81SYoshie Muranaka          .filter((action) => action);
47*5b8cef81SYoshie Muranaka    };
48*5b8cef81SYoshie Muranaka
49*5b8cef81SYoshie Muranaka    /**
50*5b8cef81SYoshie Muranaka     * Callback when button action clicked
51*5b8cef81SYoshie Muranaka     * Emits the action type to the parent component
52*5b8cef81SYoshie Muranaka     */
53*5b8cef81SYoshie Muranaka    this.onClick = (action) => {
54*5b8cef81SYoshie Muranaka      this.emitAction({action});
55*5b8cef81SYoshie Muranaka    };
56*5b8cef81SYoshie Muranaka
57*5b8cef81SYoshie Muranaka    this.onClickClose = () => {
58*5b8cef81SYoshie Muranaka      this.emitClose();
59*5b8cef81SYoshie Muranaka    };
60*5b8cef81SYoshie Muranaka
61*5b8cef81SYoshie Muranaka    /**
62*5b8cef81SYoshie Muranaka     * onInit Component lifecycle hook
63*5b8cef81SYoshie Muranaka     */
64*5b8cef81SYoshie Muranaka    this.$onInit = () => {
65*5b8cef81SYoshie Muranaka      this.actions = setActions(this.actions);
66*5b8cef81SYoshie Muranaka    };
67*5b8cef81SYoshie Muranaka  };
68*5b8cef81SYoshie Muranaka
69*5b8cef81SYoshie Muranaka  /**
70*5b8cef81SYoshie Muranaka   * Component template
71*5b8cef81SYoshie Muranaka   */
72*5b8cef81SYoshie Muranaka  const template = `
73*5b8cef81SYoshie Muranaka    <div class="bmc-table__toolbar" ng-if="$ctrl.active">
74*5b8cef81SYoshie Muranaka      <p class="toolbar__selection-count">{{$ctrl.selectionCount}} selected</p>
75*5b8cef81SYoshie Muranaka      <div class="toolbar__batch-actions" ng-show="$ctrl.actions.length > 0">
76*5b8cef81SYoshie Muranaka        <button
77*5b8cef81SYoshie Muranaka          class="btn  btn-tertiary"
78*5b8cef81SYoshie Muranaka          type="button"
79*5b8cef81SYoshie Muranaka          aria-label="{{action.label}}"
80*5b8cef81SYoshie Muranaka          ng-repeat="action in $ctrl.actions"
81*5b8cef81SYoshie Muranaka          ng-click="$ctrl.onClick(action.type)">
82*5b8cef81SYoshie Muranaka          <icon ng-if="action.file !== null"
83*5b8cef81SYoshie Muranaka                ng-file="{{action.file}}"
84*5b8cef81SYoshie Muranaka                aria-hidden="true">
85*5b8cef81SYoshie Muranaka          </icon>
86*5b8cef81SYoshie Muranaka          {{action.label || action.type}}
87*5b8cef81SYoshie Muranaka        </button>
88*5b8cef81SYoshie Muranaka        <button
89*5b8cef81SYoshie Muranaka          class="btn  btn-tertiary  btn-close"
90*5b8cef81SYoshie Muranaka          type="button"
91*5b8cef81SYoshie Muranaka          aria-label="Cancel"
92*5b8cef81SYoshie Muranaka          ng-click="$ctrl.onClickClose()">
93*5b8cef81SYoshie Muranaka          Cancel
94*5b8cef81SYoshie Muranaka        </button>
95*5b8cef81SYoshie Muranaka      </div>
96*5b8cef81SYoshie Muranaka    </div>`
97*5b8cef81SYoshie Muranaka
98*5b8cef81SYoshie Muranaka  /**
99*5b8cef81SYoshie Muranaka   * Register tableToolbar component
100*5b8cef81SYoshie Muranaka   */
101*5b8cef81SYoshie Muranaka  angular.module('app.common.components').component('tableToolbar', {
102*5b8cef81SYoshie Muranaka    controller,
103*5b8cef81SYoshie Muranaka    template,
104*5b8cef81SYoshie Muranaka    bindings: {
105*5b8cef81SYoshie Muranaka      actions: '<',
106*5b8cef81SYoshie Muranaka      selectionCount: '<',
107*5b8cef81SYoshie Muranaka      active: '<',
108*5b8cef81SYoshie Muranaka      emitAction: '&',
109*5b8cef81SYoshie Muranaka      emitClose: '&'
110*5b8cef81SYoshie Muranaka    }
111*5b8cef81SYoshie Muranaka  })
112*5b8cef81SYoshie Muranaka})(window.angular);