diff options
author | Yoshie Muranaka <yoshiemuranaka@gmail.com> | 2019-08-12 09:31:52 -0500 |
---|---|---|
committer | Gunnar Mills <gmills@us.ibm.com> | 2019-08-27 16:15:30 +0000 |
commit | bb688795ded24cd07c46de598170af41fb3bfd56 (patch) | |
tree | 88d65dfa4aa24a38c86b897991449d26d88c6098 /app/common | |
parent | b4d9c09a6c34f70260a686430e6891301a8da7b3 (diff) | |
download | phosphor-webui-bb688795ded24cd07c46de598170af41fb3bfd56.tar.gz phosphor-webui-bb688795ded24cd07c46de598170af41fb3bfd56.zip |
Add tableActions component
Creating a separate table actions component to allow
row action customizations like disabling certain
actions and rendering different icons.
Signed-off-by: Yoshie Muranaka <yoshiemuranaka@gmail.com>
Change-Id: I85e96045af27701f5ecc4af9bf824e248abccbf5
Diffstat (limited to 'app/common')
-rw-r--r-- | app/common/components/table/table-actions.js | 91 | ||||
-rw-r--r-- | app/common/components/table/table.html | 11 | ||||
-rw-r--r-- | app/common/components/table/table.js | 49 | ||||
-rw-r--r-- | app/common/directives/icon-provider.js | 7 | ||||
-rw-r--r-- | app/common/styles/components/table.scss | 6 |
5 files changed, 135 insertions, 29 deletions
diff --git a/app/common/components/table/table-actions.js b/app/common/components/table/table-actions.js new file mode 100644 index 0000000..e1e47ec --- /dev/null +++ b/app/common/components/table/table-actions.js @@ -0,0 +1,91 @@ +window.angular && (function(angular) { + 'use strict'; + + /** + * + * tableActions Component + * + * To use: + * The <table-actions> component expects an 'actions' attribute + * that should be an array of action objects. + * Each action object should have 'type', 'enabled', and 'file' + * properties. + * + * actions: [ + * {type: 'Edit', enabled: true, file: 'icon-edit.svg'}, + * {type: 'Delete', enabled: false, file: 'icon-trashcan.svg'} + * ] + * + * The 'type' property is a string value that will be emitted to the + * parent component when clicked. + * + * The 'enabled' property is a boolean that will enable/disable + * the button. + * + * The 'file' property is a string value of the filename of the svg icon + * to provide <icon> directive. + * + */ + + const controller = function() { + /** + * Set defaults if properties undefined + * @param {[]} actions + */ + const setActions = (actions = []) => { + return actions + .map((action) => { + if (action.type === undefined) { + return; + } + if (action.file === undefined) { + action.file = null; + } + if (action.enabled === undefined) { + action.enabled = true; + } + return action; + }) + .filter((action) => action); + }; + + /** + * Callback when button action clicked + * Emits the action type to the parent component + */ + this.onClick = (action) => { + this.emitAction({action}); + }; + + /** + * onInit Component lifecycle hook + */ + this.$onInit = () => { + this.actions = setActions(this.actions); + }; + }; + + /** + * Component template + */ + const template = ` + <button + class="btn btn-tertiary" + type="button" + aria-label="{{action.type}}" + ng-repeat="action in $ctrl.actions" + ng-disabled="!action.enabled" + ng-click="$ctrl.onClick(action.type)"> + <icon ng-if="action.file !== null" ng-file="{{action.file}}"></icon> + <span ng-if="action.file === null">{{action.type}}</span> + </button>` + + /** + * Register tableActions component + */ + angular.module('app.common.components').component('tableActions', { + controller, + template, + bindings: {actions: '<', emitAction: '&'} + }) +})(window.angular);
\ No newline at end of file diff --git a/app/common/components/table/table.html b/app/common/components/table/table.html index 6ec520c..b40c346 100644 --- a/app/common/components/table/table.html +++ b/app/common/components/table/table.html @@ -19,13 +19,12 @@ {{item}} </td> <!-- Row Actions --> - <td ng-if="$ctrl.model.actions.length > 0" + <td ng-if="$ctrl.rowActionsEnabled" class="bmc-table__cell bmc-table__row-actions"> - <button ng-repeat="action in $ctrl.model.actions" - ng-click="$ctrl.onClickAction(action, row);" - class="btn btn-tertiary"> - {{action}} - </button> + <table-actions + actions="row.actions" + emit-action="$ctrl.onEmitTableAction(action, row)"> + </table-actions> </td> </tr> <!-- Empty table --> diff --git a/app/common/components/table/table.js b/app/common/components/table/table.js index 2d7fc77..09a6d6d 100644 --- a/app/common/components/table/table.js +++ b/app/common/components/table/table.js @@ -3,19 +3,24 @@ window.angular && (function(angular) { /** * - * Controller for bmcTable Component + * bmcTable Component * * To use: * The <bmc-table> component expects a 'model' attribute * that will contain all the data needed to render the table. * - * The model object should contain 'header', 'data', and 'actions' + * The component also accepts a 'row-actions-enabled' attribute, + * to optionally render table row actions. Defaults to false. + * Pass true to render actions. Row actions are defined in + * model.data.actions. + * + * + * The model object should contain 'header', and 'data' * properties. * * model: { - * header: <string>[], // Array of header labels - * data: <any>[], // Array of each row object - * actions: <string>[] // Array of action labels + * header: <string>[], // Array of header labels + * data: <any>[], // Array of each row object * } * * The header property will render each label as a <th> in the table. @@ -24,13 +29,15 @@ window.angular && (function(angular) { * Each row object in the model.data array should also have a 'uiData' * property that should be an array of the properties that will render * as each table cell <td>. + * Each row object in the model.data array can optionally have an + * 'actions' property that should be an array of actions to provide the + * <bmc-table-actions> component. * - * The actions property will render into clickable buttons at the end - * of each row. - * When a user clicks an action button, the component - * will emit the action label with the associated row object. + * The 'rowActionsEnabled' property will render <bmc-table-actions> if set + * to true. * */ + const TableController = function() { /** * Init model data @@ -46,14 +53,6 @@ window.angular && (function(angular) { } return row; }) - model.actions = model.actions === undefined ? [] : model.actions; - - if (model.actions.length > 0) { - // If table actions were provided, push an empty - // string to the header array to account for additional - // table actions cell - model.header.push(''); - } return model; }; @@ -64,7 +63,7 @@ window.angular && (function(angular) { * @param {string} action : action type * @param {any} row : user object */ - this.onClickAction = (action, row) => { + this.onEmitTableAction = (action, row) => { if (action !== undefined && row !== undefined) { const value = {action, row}; this.emitAction({value}); @@ -75,7 +74,19 @@ window.angular && (function(angular) { * onInit Component lifecycle hooked */ this.$onInit = () => { + if (this.model === undefined) { + console.log('<bmc-table> Component is missing "model" attribute.'); + return; + } this.model = setModel(this.model); + this.rowActionsEnabled = + this.rowActionsEnabled === undefined ? false : true; + if (this.rowActionsEnabled) { + // If table actions are enabled push an empty + // string to the header array to account for additional + // table actions cell + this.model.header.push(''); + } }; }; @@ -85,6 +96,6 @@ window.angular && (function(angular) { angular.module('app.common.components').component('bmcTable', { template: require('./table.html'), controller: TableController, - bindings: {model: '<', emitAction: '&'} + bindings: {model: '<', rowActionsEnabled: '<', emitAction: '&'} }) })(window.angular); diff --git a/app/common/directives/icon-provider.js b/app/common/directives/icon-provider.js index 5554fdd..bee6150 100644 --- a/app/common/directives/icon-provider.js +++ b/app/common/directives/icon-provider.js @@ -13,8 +13,9 @@ window.angular && ((angular) => { angular.module('app.common.directives').directive('icon', () => { return { - restrict: 'E', link: (scope, element, attrs) => { - const file = attrs.file; + restrict: 'E', + link: (scope, element, attrs) => { + const file = attrs.file || attrs.ngFile; if (file === undefined) { console.log('File name not provided for <icon> directive.') return; @@ -23,6 +24,6 @@ window.angular && ((angular) => { element.html(svg); element.addClass('icon'); } - } + }; }) })(window.angular);
\ No newline at end of file diff --git a/app/common/styles/components/table.scss b/app/common/styles/components/table.scss index 17df264..40b6a64 100644 --- a/app/common/styles/components/table.scss +++ b/app/common/styles/components/table.scss @@ -161,10 +161,14 @@ } .bmc-table__cell { - padding: 4px 16px; + padding: 10px 16px; background-color: $base-02--07; } .bmc-table__row-actions { text-align: right; + .btn { + padding-top: 0; + padding-bottom: 0; + } }
\ No newline at end of file |