Skip to content

Commit d92463b

Browse files
authored
Merge pull request #391 from dtaylor113/branch-4.0-dev
pfEmptyState for Context Views (list, card, table)
2 parents ff69dd8 + 3788d91 commit d92463b

16 files changed

+600
-141
lines changed

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,15 @@ Note:
7979
<script src="node_modules/angular-patternfly/node_modules/patternfly/node_modules/c3/c3.min.js"></script>
8080
<script src="node_modules/angular-patternfly/node_modules/patternfly/node_modules/d3/d3.min.js"></script>
8181

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

8585
my-app.module.js:
8686

8787
angular.module('myApp', [
8888
'patternfly',
89-
'patternfly.charts'
89+
'patternfly.charts',
90+
'patternfly.table'
9091
]);
9192

9293
### Using with Webpack

src/table/tableview/examples/table-view-basic.js

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
*
1010
* @param {object} config Optional configuration object
1111
* <ul style='list-style-type: none'>
12-
* <li>.selectionMatchProp - (string) Property of the items to use for determining matching, default is 'uuid'
13-
* <li>.onCheckBoxChange - ( function(item) ) Called to notify when a checkbox selection changes, default is none
12+
* <li>.selectionMatchProp - (string) Property of the items to use for determining matching, default is 'uuid'
13+
* <li>.onCheckBoxChange - ( function(item) ) Called to notify when a checkbox selection changes, default is none
14+
* <li>.itemsAvailable - (boolean) If 'false', displays the {@link patternfly.views.component:pfEmptyState Empty State} component.
1415
* </ul>
1516
* @param {object} dtOptions Optional angular-datatables DTOptionsBuilder configuration object. See {@link http://l-lin.github.io/angular-datatables/archives/#/api angular-datatables: DTOptionsBuilder}
1617
* @param {array} items Array of items to display in the table view.
@@ -31,31 +32,46 @@
3132
* <li>.title - (String) Optional title, used for the tooltip
3233
* <li>.actionFn - (function(action)) Function to invoke when the action selected
3334
* </ul>
35+
* @param {object} emptyStateConfig Optional configuration settings for the empty state component. See the {@link patternfly.views.component:pfEmptyState Empty State} component
3436
* @example
35-
<example module="patternfly.table">
37+
<example module="patternfly.tableview.demo">
3638
<file name="index.html">
3739
<div ng-controller="TableCtrl" class="row example-container">
3840
<div class="col-md-12">
3941
<pf-table-view id="exampleTableView"
4042
config="config"
43+
empty-state-config="emptyStateConfig"
4144
dt-options="dtOptions"
4245
colummns="colummns"
4346
items="items"
4447
action-buttons="actionButtons"
4548
menu-actions="menuActions">
4649
</pf-table-view>
47-
<div class="col-md-12" style="padding-top: 12px;">
48-
<label style="font-weight:normal;vertical-align:center;">Events: </label>
49-
</div>
50-
<div class="col-md-12">
51-
<textarea rows="10" class="col-md-12">{{eventText}}</textarea>
50+
</div>
51+
<div class="col-md-12" style="padding-top: 12px;">
52+
<div class="form-group">
53+
<label class="checkbox-inline">
54+
<input type="checkbox" ng-model="config.itemsAvailable">Items Available</input>
55+
</label>
5256
</div>
5357
</div>
54-
</div>
58+
<hr class="col-md-12">
59+
<div class="col-md-12">
60+
<div class="col-md-12" style="padding-top: 12px;">
61+
<label style="font-weight:normal;vertical-align:center;">Events: </label>
62+
</div>
63+
<div class="col-md-12">
64+
<textarea rows="10" class="col-md-12">{{eventText}}</textarea>
65+
</div>
66+
</div>
67+
</file>
68+
69+
<file name="modules.js">
70+
angular.module('patternfly.tableview.demo', ['patternfly.views','patternfly.table']);
5571
</file>
5672
5773
<file name="script.js">
58-
angular.module('patternfly.table').controller('TableCtrl', ['$scope',
74+
angular.module('patternfly.tableview.demo').controller('TableCtrl', ['$scope',
5975
function ($scope) {
6076
$scope.dtOptions = {
6177
order: [[2, "asc"]],
@@ -123,7 +139,19 @@
123139
124140
$scope.config = {
125141
onCheckBoxChange: handleCheckBoxChange,
126-
selectionMatchProp: "name"
142+
selectionMatchProp: "name",
143+
itemsAvailable: true
144+
};
145+
146+
$scope.emptyStateConfig = {
147+
icon: 'pficon-warning-triangle-o',
148+
title: 'No Items Available',
149+
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.",
150+
helpLink: {
151+
label: 'For more information please see',
152+
urlLabel: 'pfExample',
153+
url : '#/api/patternfly.views.component:pfEmptyState'
154+
}
127155
};
128156
129157
function handleCheckBoxChange (item) {

src/table/tableview/examples/table-view-with-toolbar.js

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
*
99
* @param {object} config Optional configuration object
1010
* <ul style='list-style-type: none'>
11-
* <li>.selectionMatchProp - (string) Property of the items to use for determining matching, default is 'uuid'
12-
* <li>.onCheckBoxChange - ( function(item) ) Called to notify when a checkbox selection changes, default is none
11+
* <li>.selectionMatchProp - (string) Property of the items to use for determining matching, default is 'uuid'
12+
* <li>.onCheckBoxChange - ( function(item) ) Called to notify when a checkbox selection changes, default is none
13+
* <li>.itemsAvailable - (boolean) If 'false', displays the {@link patternfly.views.component:pfEmptyState Empty State} component.
1314
* </ul>
1415
* @param {object} dtOptions Optional angular-datatables DTOptionsBuilder configuration object. See {@link http://l-lin.github.io/angular-datatables/archives/#/api angular-datatables: DTOptionsBuilder}
1516
* @param {array} items Array of items to display in the table view.
@@ -30,6 +31,7 @@
3031
* <li>.title - (String) Optional title, used for the tooltip
3132
* <li>.actionFn - (function(action)) Function to invoke when the action selected
3233
* </ul>
34+
* @param {object} emptyStateConfig Optional configuration settings for the empty state component. See the {@link patternfly.views.component:pfEmptyState Empty State} component
3335
* @example
3436
<example module="patternfly.tableview.demo">
3537
<file name="index.html">
@@ -39,22 +41,27 @@
3941
</div>
4042
<div class="col-md-12">
4143
<pf-table-view config="tableConfig"
44+
empty-state-config="emptyStateConfig"
4245
dt-options="dtOptions"
4346
colummns="colummns"
4447
items="items"
4548
action-buttons="tableActionButtons"
4649
menu-actions="tableMenuActions">
4750
</pf-table-view>
48-
<!-- form role="form" //[WIP] issues dynamically changing displayLength and turning on/off pagination >
49-
<div class="form-group">
51+
</div>
52+
<div class="col-md-12">
53+
<div class="form-group">
54+
<label class="checkbox-inline">
55+
<input type="checkbox" ng-model="tableConfig.itemsAvailable" ng-change="updateItemsAvailable()">Items Available</input>
56+
</label>
57+
<!-- //[WIP] issues dynamically changing displayLength and turning on/off pagination
5058
<label class="checkbox-inline">
5159
<input type="checkbox" ng-model="usePagination" ng-change="togglePagination()">Use Pagination</input>
5260
</label>
5361
<label>
5462
<input ng-model="dtOptions.displayLength" ng-disabled="!usePagination" style="width: 24px; padding-left: 6px;"> # Rows Per Page</input>
55-
</label>
56-
</div>
57-
</form --!>
63+
</label> --!>
64+
</div>
5865
</div>
5966
<hr class="col-md-12">
6067
<div class="col-md-12">
@@ -379,7 +386,19 @@
379386
380387
$scope.tableConfig = {
381388
onCheckBoxChange: handleCheckBoxChange,
382-
selectionMatchProp: "name"
389+
selectionMatchProp: "name",
390+
itemsAvailable: true
391+
};
392+
393+
$scope.emptyStateConfig = {
394+
icon: 'pficon-warning-triangle-o',
395+
title: 'No Items Available',
396+
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.",
397+
helpLink: {
398+
label: 'For more information please see',
399+
urlLabel: 'pfExample',
400+
url : '#/api/patternfly.views.component:pfEmptyState'
401+
}
383402
};
384403
385404
$scope.tableActionButtons = [
@@ -426,6 +445,18 @@
426445
actionFn: performTableAction
427446
}
428447
];
448+
449+
$scope.updateItemsAvailable = function () {
450+
if(!$scope.tableConfig.itemsAvailable) {
451+
$scope.toolbarConfig.filterConfig.resultsCount = 0;
452+
$scope.toolbarConfig.filterConfig.totalCount = 0;
453+
$scope.toolbarConfig.filterConfig.selectedCount = 0;
454+
} else {
455+
$scope.toolbarConfig.filterConfig.resultsCount = $scope.items.length;
456+
$scope.toolbarConfig.filterConfig.totalCount = $scope.allItems.length;
457+
handleCheckBoxChange();
458+
}
459+
};
429460
}
430461
]);
431462
</file>

src/table/tableview/table-view.component.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ angular.module('patternfly.table').component('pfTableView', {
55
colummns: '<',
66
items: '<',
77
actionButtons: '<?',
8-
menuActions: '<?'
8+
menuActions: '<?',
9+
emptyStateConfig: '=?'
910
},
1011
templateUrl: 'table/tableview/table-view.html',
1112
controller: function (DTOptionsBuilder, DTColumnDefBuilder, $element, pfUtils, $log, $filter, $timeout) {

src/table/tableview/table-view.html

Lines changed: 50 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,51 @@
1-
<table datatable="ng" dt-options="$ctrl.dtOptions" dt-column-defs="$ctrl.dtColumnDefs" dt-instance="$ctrl.dtInstanceCallback"
2-
class="table-view-container table table-striped table-bordered table-hover dataTable">
3-
<thead>
4-
<tr role="row">
5-
<th class="table-view-pf-select"><input type="checkbox" value="$ctrl.selectAll" ng-model="$ctrl.selectAll" ng-change="$ctrl.toggleAll()"/></th>
6-
<th ng-repeat="col in $ctrl.colummns">{{col.header}}</th>
7-
<th ng-if="$ctrl.areActions()" colspan="{{$ctrl.calcActionsColspan()}}">Actions</th>
1+
<span>
2+
<table ng-if="$ctrl.config.itemsAvailable !== false"
3+
datatable="ng" dt-options="$ctrl.dtOptions" dt-column-defs="$ctrl.dtColumnDefs" dt-instance="$ctrl.dtInstanceCallback"
4+
class="table-view-container table table-striped table-bordered table-hover dataTable">
5+
<thead>
6+
<tr role="row">
7+
<th class="table-view-pf-select"><input type="checkbox" value="$ctrl.selectAll" ng-model="$ctrl.selectAll" ng-change="$ctrl.toggleAll()"/></th>
8+
<th ng-repeat="col in $ctrl.colummns">{{col.header}}</th>
9+
<th ng-if="$ctrl.areActions()" colspan="{{$ctrl.calcActionsColspan()}}">Actions</th>
10+
</tr>
11+
</thead>
12+
<tbody>
13+
<tr role="row" ng-repeat="item in $ctrl.items track by $index">
14+
<td class="table-view-pf-select">
15+
<input type="checkbox" value="item.selected" ng-model="item.selected" ng-change="$ctrl.toggleOne(item)"/>
16+
</td>
17+
<td ng-repeat="(key, value) in item" ng-if="$ctrl.isColItemFld(key)">{{ value }}</td>
18+
<td ng-if="$ctrl.actionButtons && $ctrl.actionButtons.length > 0" class="table-view-pf-actions" ng-repeat="actionButton in $ctrl.actionButtons">
19+
<div class="table-view-pf-btn">
20+
<button class="btn btn-default" title="{{actionButton.title}}"
21+
ng-click="$ctrl.handleButtonAction(actionButton, item)">
22+
<span ng-if="!actionButton.include">{{actionButton.name}}</span>
23+
</button>
24+
</div>
25+
</td>
26+
<td ng-if="$ctrl.menuActions && $ctrl.menuActions.length > 0" class="table-view-pf-actions list-group-item-header">
27+
<div uib-dropdown class="{{$ctrl.dropdownClass}} dropdown-kebab-pf"
28+
id="kebab_{{$index}}"
29+
ng-if="$ctrl.menuActions && $ctrl.menuActions.length > 0">
30+
<button uib-dropdown-toggle class="btn btn-default dropdown-toggle" type="button"
31+
id="dropdownKebabRight_{{$index}}"
32+
ng-click="$ctrl.setupActions(item, $event)">
33+
<span class="fa fa-ellipsis-v"></span>
34+
</button>
35+
<ul uib-dropdown-menu class="dropdown-menu dropdown-menu-right {{$index}}" aria-labelledby="dropdownKebabRight_{{$index}}" >
36+
<li ng-repeat="menuAction in $ctrl.menuActions"
37+
ng-if="menuAction.isVisible !== false"
38+
role="{{menuAction.isSeparator === true ? 'separator' : 'menuitem'}}"
39+
ng-class="{'divider': (menuAction.isSeparator === true), 'disabled': (menuAction.isDisabled === true)}">
40+
<a ng-if="menuAction.isSeparator !== true" title="{{menuAction.title}}" ng-click="$ctrl.handleMenuAction(menuAction, item)">
41+
{{menuAction.name}}
42+
</a>
43+
</li>
44+
</ul>
45+
</div>
46+
</td>
847
</tr>
9-
</thead>
10-
<tbody>
11-
<tr role="row" ng-repeat="item in $ctrl.items track by $index">
12-
<td class="table-view-pf-select">
13-
<input type="checkbox" value="item.selected" ng-model="item.selected" ng-change="$ctrl.toggleOne(item)"/>
14-
</td>
15-
<td ng-repeat="(key, value) in item" ng-if="$ctrl.isColItemFld(key)">{{ value }}</td>
16-
<td ng-if="$ctrl.actionButtons && $ctrl.actionButtons.length > 0" class="table-view-pf-actions" ng-repeat="actionButton in $ctrl.actionButtons">
17-
<div class="table-view-pf-btn">
18-
<button class="btn btn-default" title="{{actionButton.title}}"
19-
ng-click="$ctrl.handleButtonAction(actionButton, item)">
20-
<span ng-if="!actionButton.include">{{actionButton.name}}</span>
21-
</button>
22-
</div>
23-
</td>
24-
<td ng-if="$ctrl.menuActions && $ctrl.menuActions.length > 0" class="table-view-pf-actions list-group-item-header">
25-
<div uib-dropdown class="{{$ctrl.dropdownClass}} dropdown-kebab-pf"
26-
id="kebab_{{$index}}"
27-
ng-if="$ctrl.menuActions && $ctrl.menuActions.length > 0">
28-
<button uib-dropdown-toggle class="btn btn-link" type="button"
29-
id="dropdownKebabRight_{{$index}}"
30-
ng-click="$ctrl.setupActions(item, $event)">
31-
<span class="fa fa-ellipsis-v"></span>
32-
</button>
33-
<ul uib-dropdown-menu class="dropdown-menu dropdown-menu-right {{$index}}" aria-labelledby="dropdownKebabRight_{{$index}}" >
34-
<li ng-repeat="menuAction in $ctrl.menuActions"
35-
ng-if="menuAction.isVisible !== false"
36-
role="{{menuAction.isSeparator === true ? 'separator' : 'menuitem'}}"
37-
ng-class="{'divider': (menuAction.isSeparator === true), 'disabled': (menuAction.isDisabled === true)}">
38-
<a ng-if="menuAction.isSeparator !== true" title="{{menuAction.title}}" ng-click="$ctrl.handleMenuAction(menuAction, item)">
39-
{{menuAction.name}}
40-
</a>
41-
</li>
42-
</ul>
43-
</div>
44-
</td>
45-
</tr>
46-
</tbody>
47-
</table>
48+
</tbody>
49+
</table>
50+
<pf-empty-state ng-if="$ctrl.config.itemsAvailable === false" config="$ctrl.emptyStateConfig"></pf-empty-state>
51+
</span>

src/toolbars/examples/toolbar.js

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@
8080
</pf-toolbar>
8181
</div>
8282
<div class="col-md-12" ng-if="viewType == 'listView'">
83-
<pf-list-view config="listConfig" items="items">
83+
<pf-list-view config="listConfig"
84+
items="items"
85+
empty-state-config="emptyStateConfig">
8486
<div class="list-view-pf-description">
8587
<div class="list-group-item-heading">
8688
{{item.name}}
@@ -100,7 +102,9 @@
100102
</pf-list-view>
101103
</div>
102104
<div class="col-md-12" ng-if="viewType == 'cardView'">
103-
<pf-card-view config="listConfig" items="items">
105+
<pf-card-view config="listConfig"
106+
items="items"
107+
empty-state-config="emptyStateConfig">
104108
<div class="col-md-12">
105109
<span>{{item.name}}</span>
106110
</div>
@@ -115,9 +119,17 @@
115119
<div class="col-md-12" ng-show="viewType == 'tableView'">
116120
<pf-table-view config="tableConfig"
117121
colummns="colummns"
118-
items="items">
122+
items="items"
123+
empty-state-config="emptyStateConfig">
119124
</pf-table-view>
120125
</div>
126+
<div class="col-md-12" style="padding-top: 12px;">
127+
<div class="form-group">
128+
<label class="checkbox-inline">
129+
<input type="checkbox" ng-model="listConfig.itemsAvailable" ng-change="updateItemsAvailable()">Items Available</input>
130+
</label>
131+
</div>
132+
</div>
121133
<hr class="col-md-12">
122134
<div class="col-md-12">
123135
<label class="events-label">Current Filters: </label>
@@ -446,12 +458,25 @@
446458
$scope.listConfig = {
447459
selectionMatchProp: 'name',
448460
checkDisabled: false,
461+
itemsAvailable: true,
449462
onCheckBoxChange: handleCheckBoxChange
450463
};
451464
465+
$scope.emptyStateConfig = {
466+
icon: 'pficon-warning-triangle-o',
467+
title: 'No Items Available',
468+
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.",
469+
helpLink: {
470+
label: 'For more information please see',
471+
urlLabel: 'pfExample',
472+
url : '#/api/patternfly.views.component:pfEmptyState'
473+
}
474+
};
475+
452476
$scope.tableConfig = {
453477
onCheckBoxChange: handleCheckBoxChange,
454-
selectionMatchProp: "name"
478+
selectionMatchProp: "name",
479+
itemsAvailable: true,
455480
};
456481
457482
$scope.doAdd = function () {
@@ -462,6 +487,19 @@
462487
$scope.actionsText = "Option " + option + " selected\n" + $scope.actionsText;
463488
};
464489
490+
$scope.updateItemsAvailable = function () {
491+
$scope.tableConfig.itemsAvailable = $scope.listConfig.itemsAvailable;
492+
if(!$scope.listConfig.itemsAvailable) {
493+
$scope.toolbarConfig.filterConfig.resultsCount = 0;
494+
$scope.toolbarConfig.filterConfig.totalCount = 0;
495+
$scope.toolbarConfig.filterConfig.selectedCount = 0;
496+
} else {
497+
$scope.toolbarConfig.filterConfig.resultsCount = $scope.items.length;
498+
$scope.toolbarConfig.filterConfig.totalCount = $scope.allItems.length;
499+
handleCheckBoxChange();
500+
}
501+
};
502+
465503
function handleCheckBoxChange (item) {
466504
var selectedItems = $filter('filter')($scope.allItems, {selected: true});
467505
if (selectedItems) {

0 commit comments

Comments
 (0)