Skip to content

pfEmptyState for Context Views (list, card, table) #391

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jan 25, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,15 @@ Note:
<script src="node_modules/angular-patternfly/node_modules/patternfly/node_modules/c3/c3.min.js"></script>
<script src="node_modules/angular-patternfly/node_modules/patternfly/node_modules/d3/d3.min.js"></script>

5. (optional) The 'patternfly.charts' module is not a dependency in the default angular 'patternfly' module.
In order to use patternfly charts you must add 'patternfly.charts' as a dependency in your application:
5. (optional) The 'patternfly.charts' and 'patternfly.table' modules are not dependencies in the default angular 'patternfly' module.
In order to use patternfly charts and/or patternfly.table, you must add them as dependencies in your application:

my-app.module.js:

angular.module('myApp', [
'patternfly',
'patternfly.charts'
'patternfly.charts',
'patternfly.table'
]);

### Using with Webpack
Expand Down
50 changes: 39 additions & 11 deletions src/table/tableview/examples/table-view-basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
*
* @param {object} config Optional configuration object
* <ul style='list-style-type: none'>
* <li>.selectionMatchProp - (string) Property of the items to use for determining matching, default is 'uuid'
* <li>.onCheckBoxChange - ( function(item) ) Called to notify when a checkbox selection changes, default is none
* <li>.selectionMatchProp - (string) Property of the items to use for determining matching, default is 'uuid'
* <li>.onCheckBoxChange - ( function(item) ) Called to notify when a checkbox selection changes, default is none
* <li>.itemsAvailable - (boolean) If 'false', displays the {@link patternfly.views.component:pfEmptyState Empty State} component.
* </ul>
* @param {object} dtOptions Optional angular-datatables DTOptionsBuilder configuration object. See {@link http://l-lin.github.io/angular-datatables/archives/#/api angular-datatables: DTOptionsBuilder}
* @param {array} items Array of items to display in the table view.
Expand All @@ -31,31 +32,46 @@
* <li>.title - (String) Optional title, used for the tooltip
* <li>.actionFn - (function(action)) Function to invoke when the action selected
* </ul>
* @param {object} emptyStateConfig Optional configuration settings for the empty state component. See the {@link patternfly.views.component:pfEmptyState Empty State} component
* @example
<example module="patternfly.table">
<example module="patternfly.tableview.demo">
<file name="index.html">
<div ng-controller="TableCtrl" class="row example-container">
<div class="col-md-12">
<pf-table-view id="exampleTableView"
config="config"
empty-state-config="emptyStateConfig"
dt-options="dtOptions"
colummns="colummns"
items="items"
action-buttons="actionButtons"
menu-actions="menuActions">
</pf-table-view>
<div class="col-md-12" style="padding-top: 12px;">
<label style="font-weight:normal;vertical-align:center;">Events: </label>
</div>
<div class="col-md-12">
<textarea rows="10" class="col-md-12">{{eventText}}</textarea>
</div>
<div class="col-md-12" style="padding-top: 12px;">
<div class="form-group">
<label class="checkbox-inline">
<input type="checkbox" ng-model="config.itemsAvailable">Items Available</input>
</label>
</div>
</div>
</div>
<hr class="col-md-12">
<div class="col-md-12">
<div class="col-md-12" style="padding-top: 12px;">
<label style="font-weight:normal;vertical-align:center;">Events: </label>
</div>
<div class="col-md-12">
<textarea rows="10" class="col-md-12">{{eventText}}</textarea>
</div>
</div>
</file>

<file name="modules.js">
angular.module('patternfly.tableview.demo', ['patternfly.views','patternfly.table']);
</file>

<file name="script.js">
angular.module('patternfly.table').controller('TableCtrl', ['$scope',
angular.module('patternfly.tableview.demo').controller('TableCtrl', ['$scope',
function ($scope) {
$scope.dtOptions = {
order: [[2, "asc"]],
Expand Down Expand Up @@ -123,7 +139,19 @@

$scope.config = {
onCheckBoxChange: handleCheckBoxChange,
selectionMatchProp: "name"
selectionMatchProp: "name",
itemsAvailable: true
};

$scope.emptyStateConfig = {
icon: 'pficon-warning-triangle-o',
title: 'No Items Available',
info: "This is the Empty State component. The goal of a empty state pattern is to provide a good first impression that helps users to achieve their goals. It should be used when a view is empty because no objects exists and you want to guide the user to perform specific actions.",
helpLink: {
label: 'For more information please see',
urlLabel: 'pfExample',
url : '#/api/patternfly.views.component:pfEmptyState'
}
};

function handleCheckBoxChange (item) {
Expand Down
47 changes: 39 additions & 8 deletions src/table/tableview/examples/table-view-with-toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
*
* @param {object} config Optional configuration object
* <ul style='list-style-type: none'>
* <li>.selectionMatchProp - (string) Property of the items to use for determining matching, default is 'uuid'
* <li>.onCheckBoxChange - ( function(item) ) Called to notify when a checkbox selection changes, default is none
* <li>.selectionMatchProp - (string) Property of the items to use for determining matching, default is 'uuid'
* <li>.onCheckBoxChange - ( function(item) ) Called to notify when a checkbox selection changes, default is none
* <li>.itemsAvailable - (boolean) If 'false', displays the {@link patternfly.views.component:pfEmptyState Empty State} component.
* </ul>
* @param {object} dtOptions Optional angular-datatables DTOptionsBuilder configuration object. See {@link http://l-lin.github.io/angular-datatables/archives/#/api angular-datatables: DTOptionsBuilder}
* @param {array} items Array of items to display in the table view.
Expand All @@ -30,6 +31,7 @@
* <li>.title - (String) Optional title, used for the tooltip
* <li>.actionFn - (function(action)) Function to invoke when the action selected
* </ul>
* @param {object} emptyStateConfig Optional configuration settings for the empty state component. See the {@link patternfly.views.component:pfEmptyState Empty State} component
* @example
<example module="patternfly.tableview.demo">
<file name="index.html">
Expand All @@ -39,22 +41,27 @@
</div>
<div class="col-md-12">
<pf-table-view config="tableConfig"
empty-state-config="emptyStateConfig"
dt-options="dtOptions"
colummns="colummns"
items="items"
action-buttons="tableActionButtons"
menu-actions="tableMenuActions">
</pf-table-view>
<!-- form role="form" //[WIP] issues dynamically changing displayLength and turning on/off pagination >
<div class="form-group">
</div>
<div class="col-md-12">
<div class="form-group">
<label class="checkbox-inline">
<input type="checkbox" ng-model="tableConfig.itemsAvailable" ng-change="updateItemsAvailable()">Items Available</input>
</label>
<!-- //[WIP] issues dynamically changing displayLength and turning on/off pagination
<label class="checkbox-inline">
<input type="checkbox" ng-model="usePagination" ng-change="togglePagination()">Use Pagination</input>
</label>
<label>
<input ng-model="dtOptions.displayLength" ng-disabled="!usePagination" style="width: 24px; padding-left: 6px;"> # Rows Per Page</input>
</label>
</div>
</form --!>
</label> --!>
</div>
</div>
<hr class="col-md-12">
<div class="col-md-12">
Expand Down Expand Up @@ -379,7 +386,19 @@

$scope.tableConfig = {
onCheckBoxChange: handleCheckBoxChange,
selectionMatchProp: "name"
selectionMatchProp: "name",
itemsAvailable: true
};

$scope.emptyStateConfig = {
icon: 'pficon-warning-triangle-o',
title: 'No Items Available',
info: "This is the Empty State component. The goal of a empty state pattern is to provide a good first impression that helps users to achieve their goals. It should be used when a view is empty because no objects exists and you want to guide the user to perform specific actions.",
helpLink: {
label: 'For more information please see',
urlLabel: 'pfExample',
url : '#/api/patternfly.views.component:pfEmptyState'
}
};

$scope.tableActionButtons = [
Expand Down Expand Up @@ -426,6 +445,18 @@
actionFn: performTableAction
}
];

$scope.updateItemsAvailable = function () {
if(!$scope.tableConfig.itemsAvailable) {
$scope.toolbarConfig.filterConfig.resultsCount = 0;
$scope.toolbarConfig.filterConfig.totalCount = 0;
$scope.toolbarConfig.filterConfig.selectedCount = 0;
} else {
$scope.toolbarConfig.filterConfig.resultsCount = $scope.items.length;
$scope.toolbarConfig.filterConfig.totalCount = $scope.allItems.length;
handleCheckBoxChange();
}
};
}
]);
</file>
Expand Down
3 changes: 2 additions & 1 deletion src/table/tableview/table-view.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ angular.module('patternfly.table').component('pfTableView', {
colummns: '<',
items: '<',
actionButtons: '<?',
menuActions: '<?'
menuActions: '<?',
emptyStateConfig: '=?'
},
templateUrl: 'table/tableview/table-view.html',
controller: function (DTOptionsBuilder, DTColumnDefBuilder, $element, pfUtils, $log, $filter, $timeout) {
Expand Down
96 changes: 50 additions & 46 deletions src/table/tableview/table-view.html
Original file line number Diff line number Diff line change
@@ -1,47 +1,51 @@
<table datatable="ng" dt-options="$ctrl.dtOptions" dt-column-defs="$ctrl.dtColumnDefs" dt-instance="$ctrl.dtInstanceCallback"
class="table-view-container table table-striped table-bordered table-hover dataTable">
<thead>
<tr role="row">
<th class="table-view-pf-select"><input type="checkbox" value="$ctrl.selectAll" ng-model="$ctrl.selectAll" ng-change="$ctrl.toggleAll()"/></th>
<th ng-repeat="col in $ctrl.colummns">{{col.header}}</th>
<th ng-if="$ctrl.areActions()" colspan="{{$ctrl.calcActionsColspan()}}">Actions</th>
<span>
<table ng-if="$ctrl.config.itemsAvailable !== false"
datatable="ng" dt-options="$ctrl.dtOptions" dt-column-defs="$ctrl.dtColumnDefs" dt-instance="$ctrl.dtInstanceCallback"
class="table-view-container table table-striped table-bordered table-hover dataTable">
<thead>
<tr role="row">
<th class="table-view-pf-select"><input type="checkbox" value="$ctrl.selectAll" ng-model="$ctrl.selectAll" ng-change="$ctrl.toggleAll()"/></th>
<th ng-repeat="col in $ctrl.colummns">{{col.header}}</th>
<th ng-if="$ctrl.areActions()" colspan="{{$ctrl.calcActionsColspan()}}">Actions</th>
</tr>
</thead>
<tbody>
<tr role="row" ng-repeat="item in $ctrl.items track by $index">
<td class="table-view-pf-select">
<input type="checkbox" value="item.selected" ng-model="item.selected" ng-change="$ctrl.toggleOne(item)"/>
</td>
<td ng-repeat="(key, value) in item" ng-if="$ctrl.isColItemFld(key)">{{ value }}</td>
<td ng-if="$ctrl.actionButtons && $ctrl.actionButtons.length > 0" class="table-view-pf-actions" ng-repeat="actionButton in $ctrl.actionButtons">
<div class="table-view-pf-btn">
<button class="btn btn-default" title="{{actionButton.title}}"
ng-click="$ctrl.handleButtonAction(actionButton, item)">
<span ng-if="!actionButton.include">{{actionButton.name}}</span>
</button>
</div>
</td>
<td ng-if="$ctrl.menuActions && $ctrl.menuActions.length > 0" class="table-view-pf-actions list-group-item-header">
<div uib-dropdown class="{{$ctrl.dropdownClass}} dropdown-kebab-pf"
id="kebab_{{$index}}"
ng-if="$ctrl.menuActions && $ctrl.menuActions.length > 0">
<button uib-dropdown-toggle class="btn btn-default dropdown-toggle" type="button"
id="dropdownKebabRight_{{$index}}"
ng-click="$ctrl.setupActions(item, $event)">
<span class="fa fa-ellipsis-v"></span>
</button>
<ul uib-dropdown-menu class="dropdown-menu dropdown-menu-right {{$index}}" aria-labelledby="dropdownKebabRight_{{$index}}" >
<li ng-repeat="menuAction in $ctrl.menuActions"
ng-if="menuAction.isVisible !== false"
role="{{menuAction.isSeparator === true ? 'separator' : 'menuitem'}}"
ng-class="{'divider': (menuAction.isSeparator === true), 'disabled': (menuAction.isDisabled === true)}">
<a ng-if="menuAction.isSeparator !== true" title="{{menuAction.title}}" ng-click="$ctrl.handleMenuAction(menuAction, item)">
{{menuAction.name}}
</a>
</li>
</ul>
</div>
</td>
</tr>
</thead>
<tbody>
<tr role="row" ng-repeat="item in $ctrl.items track by $index">
<td class="table-view-pf-select">
<input type="checkbox" value="item.selected" ng-model="item.selected" ng-change="$ctrl.toggleOne(item)"/>
</td>
<td ng-repeat="(key, value) in item" ng-if="$ctrl.isColItemFld(key)">{{ value }}</td>
<td ng-if="$ctrl.actionButtons && $ctrl.actionButtons.length > 0" class="table-view-pf-actions" ng-repeat="actionButton in $ctrl.actionButtons">
<div class="table-view-pf-btn">
<button class="btn btn-default" title="{{actionButton.title}}"
ng-click="$ctrl.handleButtonAction(actionButton, item)">
<span ng-if="!actionButton.include">{{actionButton.name}}</span>
</button>
</div>
</td>
<td ng-if="$ctrl.menuActions && $ctrl.menuActions.length > 0" class="table-view-pf-actions list-group-item-header">
<div uib-dropdown class="{{$ctrl.dropdownClass}} dropdown-kebab-pf"
id="kebab_{{$index}}"
ng-if="$ctrl.menuActions && $ctrl.menuActions.length > 0">
<button uib-dropdown-toggle class="btn btn-link" type="button"
id="dropdownKebabRight_{{$index}}"
ng-click="$ctrl.setupActions(item, $event)">
<span class="fa fa-ellipsis-v"></span>
</button>
<ul uib-dropdown-menu class="dropdown-menu dropdown-menu-right {{$index}}" aria-labelledby="dropdownKebabRight_{{$index}}" >
<li ng-repeat="menuAction in $ctrl.menuActions"
ng-if="menuAction.isVisible !== false"
role="{{menuAction.isSeparator === true ? 'separator' : 'menuitem'}}"
ng-class="{'divider': (menuAction.isSeparator === true), 'disabled': (menuAction.isDisabled === true)}">
<a ng-if="menuAction.isSeparator !== true" title="{{menuAction.title}}" ng-click="$ctrl.handleMenuAction(menuAction, item)">
{{menuAction.name}}
</a>
</li>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</tbody>
</table>
<pf-empty-state ng-if="$ctrl.config.itemsAvailable === false" config="$ctrl.emptyStateConfig"></pf-empty-state>
</span>
46 changes: 42 additions & 4 deletions src/toolbars/examples/toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@
</pf-toolbar>
</div>
<div class="col-md-12" ng-if="viewType == 'listView'">
<pf-list-view config="listConfig" items="items">
<pf-list-view config="listConfig"
items="items"
empty-state-config="emptyStateConfig">
<div class="list-view-pf-description">
<div class="list-group-item-heading">
{{item.name}}
Expand All @@ -100,7 +102,9 @@
</pf-list-view>
</div>
<div class="col-md-12" ng-if="viewType == 'cardView'">
<pf-card-view config="listConfig" items="items">
<pf-card-view config="listConfig"
items="items"
empty-state-config="emptyStateConfig">
<div class="col-md-12">
<span>{{item.name}}</span>
</div>
Expand All @@ -115,9 +119,17 @@
<div class="col-md-12" ng-show="viewType == 'tableView'">
<pf-table-view config="tableConfig"
colummns="colummns"
items="items">
items="items"
empty-state-config="emptyStateConfig">
</pf-table-view>
</div>
<div class="col-md-12" style="padding-top: 12px;">
<div class="form-group">
<label class="checkbox-inline">
<input type="checkbox" ng-model="listConfig.itemsAvailable" ng-change="updateItemsAvailable()">Items Available</input>
</label>
</div>
</div>
<hr class="col-md-12">
<div class="col-md-12">
<label class="events-label">Current Filters: </label>
Expand Down Expand Up @@ -446,12 +458,25 @@
$scope.listConfig = {
selectionMatchProp: 'name',
checkDisabled: false,
itemsAvailable: true,
onCheckBoxChange: handleCheckBoxChange
};

$scope.emptyStateConfig = {
icon: 'pficon-warning-triangle-o',
title: 'No Items Available',
info: "This is the Empty State component. The goal of a empty state pattern is to provide a good first impression that helps users to achieve their goals. It should be used when a view is empty because no objects exists and you want to guide the user to perform specific actions.",
helpLink: {
label: 'For more information please see',
urlLabel: 'pfExample',
url : '#/api/patternfly.views.component:pfEmptyState'
}
};

$scope.tableConfig = {
onCheckBoxChange: handleCheckBoxChange,
selectionMatchProp: "name"
selectionMatchProp: "name",
itemsAvailable: true,
};

$scope.doAdd = function () {
Expand All @@ -462,6 +487,19 @@
$scope.actionsText = "Option " + option + " selected\n" + $scope.actionsText;
};

$scope.updateItemsAvailable = function () {
$scope.tableConfig.itemsAvailable = $scope.listConfig.itemsAvailable;
if(!$scope.listConfig.itemsAvailable) {
$scope.toolbarConfig.filterConfig.resultsCount = 0;
$scope.toolbarConfig.filterConfig.totalCount = 0;
$scope.toolbarConfig.filterConfig.selectedCount = 0;
} else {
$scope.toolbarConfig.filterConfig.resultsCount = $scope.items.length;
$scope.toolbarConfig.filterConfig.totalCount = $scope.allItems.length;
handleCheckBoxChange();
}
};

function handleCheckBoxChange (item) {
var selectedItems = $filter('filter')($scope.allItems, {selected: true});
if (selectedItems) {
Expand Down
Loading