summaryrefslogtreecommitdiffstats
path: root/app/common
diff options
context:
space:
mode:
authorYoshie Muranaka <yoshiemuranaka@gmail.com>2019-08-12 09:31:52 -0500
committerGunnar Mills <gmills@us.ibm.com>2019-08-27 16:15:30 +0000
commitbb688795ded24cd07c46de598170af41fb3bfd56 (patch)
tree88d65dfa4aa24a38c86b897991449d26d88c6098 /app/common
parentb4d9c09a6c34f70260a686430e6891301a8da7b3 (diff)
downloadphosphor-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.js91
-rw-r--r--app/common/components/table/table.html11
-rw-r--r--app/common/components/table/table.js49
-rw-r--r--app/common/directives/icon-provider.js7
-rw-r--r--app/common/styles/components/table.scss6
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
OpenPOWER on IntegriCloud