Skip to content

Commit 761b539

Browse files
Add pfDataToolbar directive with ngDocs/Example and Unit Tests
1 parent 0a27a70 commit 761b539

File tree

8 files changed

+887
-4
lines changed

8 files changed

+887
-4
lines changed

dist/angular-patternfly.js

Lines changed: 295 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ angular.module( 'patternfly.utils', [] );
5757
* Views module for patternfly.
5858
*
5959
*/
60-
angular.module('patternfly.views', ['patternfly.utils']);
60+
angular.module('patternfly.views', ['patternfly.utils', 'patternfly.filters']);
6161
;/**
6262
* @ngdoc directive
6363
* @name patternfly.autofocus:pfFocused
@@ -3429,6 +3429,295 @@ angular.module('patternfly.views').directive('pfDataTiles', [
34293429
};
34303430
}
34313431
]);
3432+
;/**
3433+
* @ngdoc directive
3434+
* @name patternfly.views.directive:pfDataToolbar
3435+
*
3436+
* @description
3437+
* Directive for standard data toolbar. Includes filtering and view selection capabilities
3438+
* <br><br>
3439+
*
3440+
* @param {object} config configuration settings for the toolbar:<br/>
3441+
* <ul style='list-style-type: none'>
3442+
* <li>.filterConfig - (Object) Optional filter config. If undefined, no filtering capabilities are shown.
3443+
* See pfSimpleFilter for filter config options.
3444+
* <li>.viewsConfig - (Object) Optional configuration settings for view type selection
3445+
* <ul style='list-style-type: none'>
3446+
* <li>.views - (Array) List of available views for selection. See pfViewUtils for standard available views
3447+
* <ul style='list-style-type: none'>
3448+
* <li>.id - (String) Unique id for the view, used for comparisons
3449+
* <li>.title - (String) Optional title, uses as a tooltip for the view selector
3450+
* <li>.iconClass - (String) Icon class to use for the view selector
3451+
* </ul>
3452+
* <li>.onViewSelect - ( function(view) ) Function to call when a view is selected
3453+
* <li>.currentView - the id of the currently selected view
3454+
* </ul>
3455+
* </ul>
3456+
*
3457+
* @example
3458+
<example module="patternfly.views" deps="patternfly.filters">
3459+
<file name="index.html">
3460+
<div ng-controller="ViewCtrl" class="row example-container">
3461+
<div class="col-md-12">
3462+
<div pf-data-toolbar id="exampleDataToolbar" config="toolbarConfig"></div>
3463+
</div>
3464+
<hr class="col-md-12">
3465+
<div class="col-md-12">
3466+
<label class="events-label">Valid Items: </label>
3467+
</div>
3468+
<div class="col-md-12 list-view-container" ng-if="viewType == 'listView'">
3469+
<div pf-data-list class="row" config="listConfig" items="items">
3470+
<div class="row list-row">
3471+
<div class="col-md-3">
3472+
<span>{{item.name}}</span>
3473+
</div>
3474+
<div class="col-md-7">
3475+
<span>{{item.address}}</span>
3476+
</div>
3477+
<div class="col-md-2">
3478+
<span>{{item.birthMonth}}</span>
3479+
</div>
3480+
</div>
3481+
</div>
3482+
</div>
3483+
<div class="col-md-12 tiles-view-container" ng-if="viewType == 'tilesView'">
3484+
<div pf-data-tiles config="vm.listConfig" items="items">
3485+
<div class="col-md-12">
3486+
<span>{{item.name}}</span>
3487+
</div>
3488+
<div class="col-md-12">
3489+
<span>{{item.address}}</span>
3490+
</div>
3491+
<div class="col-md-12">
3492+
<span>{{item.birthMonth}}</span>
3493+
</div>
3494+
</div>
3495+
</div>
3496+
</br></br>
3497+
<div class="col-md-12">
3498+
<label class="events-label">Current Filters: </label>
3499+
</div>
3500+
<div class="col-md-12">
3501+
<textarea rows="5" class="col-md-12">{{filtersText}}</textarea>
3502+
</div>
3503+
</div>
3504+
</file>
3505+
3506+
<file name="script.js">
3507+
angular.module('patternfly.views').controller('ViewCtrl', ['$scope', 'pfViewUtils',
3508+
function ($scope, pfViewUtils) {
3509+
$scope.filtersText = '';
3510+
3511+
$scope.allItems = [
3512+
{
3513+
name: "Fred Flintstone",
3514+
address: "20 Dinosaur Way, Bedrock, Washingstone",
3515+
birthMonth: 'February'
3516+
},
3517+
{
3518+
name: "John Smith",
3519+
address: "415 East Main Street, Norfolk, Virginia",
3520+
birthMonth: 'October'
3521+
},
3522+
{
3523+
name: "Frank Livingston",
3524+
address: "234 Elm Street, Pittsburgh, Pennsylvania",
3525+
birthMonth: 'March'
3526+
},
3527+
{
3528+
name: "Judy Green",
3529+
address: "2 Apple Boulevard, Cincinatti, Ohio",
3530+
birthMonth: 'December'
3531+
},
3532+
{
3533+
name: "Pat Thomas",
3534+
address: "50 Second Street, New York, New York",
3535+
birthMonth: 'February'
3536+
}
3537+
];
3538+
$scope.items = $scope.allItems;
3539+
3540+
var matchesFilter = function (item, filter) {
3541+
var match = true;
3542+
3543+
if (filter.id === 'name') {
3544+
match = item.name.match(filter.value) !== null;
3545+
} else if (filter.id === 'address') {
3546+
match = item.address.match(filter.value) !== null;
3547+
} else if (filter.id === 'birthMonth') {
3548+
match = item.birthMonth === filter.value;
3549+
}
3550+
return match;
3551+
};
3552+
3553+
var matchesFilters = function (item, filters) {
3554+
var matches = true;
3555+
3556+
filters.forEach(function(filter) {
3557+
if (!matchesFilter(item, filter)) {
3558+
matches = false;
3559+
return false;
3560+
}
3561+
});
3562+
return matches;
3563+
};
3564+
3565+
var applyFilters = function (filters) {
3566+
$scope.items = [];
3567+
if (filters && filters.length > 0) {
3568+
$scope.allItems.forEach(function (item) {
3569+
if (matchesFilters(item, filters)) {
3570+
$scope.items.push(item);
3571+
}
3572+
});
3573+
} else {
3574+
$scope.items = $scope.allItems;
3575+
}
3576+
};
3577+
3578+
var filterChange = function (filters) {
3579+
$scope.filtersText = "";
3580+
filters.forEach(function (filter) {
3581+
$scope.filtersText += filter.title + " : " + filter.value + "\n";
3582+
});
3583+
applyFilters(filters);
3584+
$scope.toolbarConfig.filterConfig.resultsCount = $scope.items.length;
3585+
};
3586+
3587+
$scope.filterConfig = {
3588+
fields: [
3589+
{
3590+
id: 'name',
3591+
title: 'Name',
3592+
placeholder: 'Filter by Name',
3593+
filterType: 'text'
3594+
},
3595+
{
3596+
id: 'address',
3597+
title: 'Address',
3598+
placeholder: 'Filter by Address',
3599+
filterType: 'text'
3600+
},
3601+
{
3602+
id: 'birthMonth',
3603+
title: 'Birth Month',
3604+
placeholder: 'Filter by Birth Month',
3605+
filterType: 'select',
3606+
filterValues: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
3607+
}
3608+
],
3609+
resultsCount: $scope.items.length,
3610+
appliedFilters: [],
3611+
onFilterChange: filterChange
3612+
};
3613+
3614+
var viewSelected = function(viewId) {
3615+
$scope.viewType = viewId
3616+
};
3617+
3618+
$scope.viewsConfig = {
3619+
views: [pfViewUtils.getListView(), pfViewUtils.getTilesView()],
3620+
onViewSelect: viewSelected
3621+
};
3622+
$scope.viewsConfig.currentView = $scope.viewsConfig.views[0].id;
3623+
$scope.viewType = $scope.viewsConfig.currentView;
3624+
3625+
$scope.toolbarConfig = {
3626+
viewsConfig: $scope.viewsConfig,
3627+
filterConfig: $scope.filterConfig
3628+
};
3629+
3630+
$scope.listConfig = {
3631+
selectionMatchProp: 'name',
3632+
checkDisabled: false
3633+
};
3634+
}
3635+
]);
3636+
</file>
3637+
</example>
3638+
*/
3639+
angular.module('patternfly.views').directive('pfDataToolbar',
3640+
function () {
3641+
'use strict';
3642+
return {
3643+
restrict: 'A',
3644+
scope: {
3645+
config: '='
3646+
},
3647+
replace: true,
3648+
transclude: false,
3649+
templateUrl: 'views/toolbar/data-toolbar.html',
3650+
controller: ["$scope", function ($scope) {
3651+
$scope.viewSelected = function (viewId) {
3652+
$scope.config.viewsConfig.currentView = viewId;
3653+
if ($scope.config.viewsConfig.onViewSelect && !$scope.checkViewDisabled(viewId)) {
3654+
$scope.config.viewsConfig.onViewSelect(viewId);
3655+
}
3656+
};
3657+
3658+
$scope.isViewSelected = function (viewId) {
3659+
return $scope.config.viewsConfig && ($scope.config.viewsConfig.currentView === viewId);
3660+
};
3661+
3662+
$scope.checkViewDisabled = function (view) {
3663+
return $scope.config.viewsConfig.checkViewDisabled && $scope.config.viewsConfig.checkViewDisabled(view);
3664+
};
3665+
}],
3666+
link: function (scope, element, attrs) {
3667+
scope.$watch('config', function () {
3668+
if (scope.config && scope.config.viewsConfig && scope.config.viewsConfig.views) {
3669+
scope.config.viewsConfig.viewsList = angular.copy(scope.config.viewsConfig.views);
3670+
3671+
if (!scope.config.viewsConfig.currentView) {
3672+
scope.config.viewsConfig.currentView = scope.config.viewsConfig.viewsList[0];
3673+
}
3674+
}
3675+
}, true);
3676+
}
3677+
};
3678+
}
3679+
);
3680+
;(function () {
3681+
'use strict';
3682+
3683+
angular.module('patternfly.views').constant('pfViewUtils', {
3684+
getDashboardView: function (title) {
3685+
return {
3686+
id: 'dashboardView',
3687+
title: title || 'Dashboard View',
3688+
iconClass: 'fa fa-dashboard'
3689+
};
3690+
},
3691+
getTilesView: function (title) {
3692+
return {
3693+
id: 'tilesView',
3694+
title: title || 'Tiles View',
3695+
iconClass: 'fa fa-th'
3696+
};
3697+
},
3698+
getListView: function (title) {
3699+
return {
3700+
id: 'listView',
3701+
title: title || 'List View',
3702+
iconClass: 'fa fa-th-list'
3703+
};
3704+
},
3705+
getTableView: function (title) {
3706+
return {
3707+
id: 'tableView',
3708+
title: title || 'Table View',
3709+
iconClass: 'fa fa-table'
3710+
};
3711+
},
3712+
getTopologyView: function (title) {
3713+
return {
3714+
id: 'topologyView',
3715+
title: title || 'Topology View',
3716+
iconClass: 'fa fa-sitemap'
3717+
};
3718+
}
3719+
});
3720+
})();
34323721
;angular.module('patternfly.card').run(['$templateCache', function($templateCache) {
34333722
'use strict';
34343723

@@ -3516,4 +3805,9 @@ angular.module('patternfly.views').directive('pfDataTiles', [
35163805
"<div class=tiles-view-pf><div class=tile ng-repeat=\"item in items\" ng-class=\"{'pf-selectable': selectItems, 'active': isSelected(item), 'disabled': checkDisabled(item)}\"><div class=tile-content ng-click=\"itemClick($event, item)\" ng-dblclick=\"dblClick($event, item)\"><div pf-transclude=parent></div></div><div class=tile-check-box ng-if=config.showSelectBox><input type=checkbox value=item.selected ng-model=item.selected ng-disabled=checkDisabled(item) ng-change=\"checkBoxChange(item)\"></div></div></div>"
35173806
);
35183807

3808+
3809+
$templateCache.put('views/toolbar/data-toolbar.html',
3810+
"<div class=\"row toolbar-pf\"><div class=col-sm-12><div class=\"toolbar-pf-view-selector pull-right\" ng-if=\"config.viewsConfig && config.viewsConfig.views\"><ul class=list-inline><li ng-repeat=\"view in config.viewsConfig.viewsList\" ng-class=\"{'active': isViewSelected(view.id), 'disabled': checkViewDisabled(view)}\" title={{view.title}}><a><i class=\"view-selector {{view.iconClass}}\" ng-click=viewSelected(view.id)></i></a></li></ul></div><div pf-simple-filter id={{filterDomId}} config=config.filterConfig ng-if=config.filterConfig></div></div></div>"
3811+
);
3812+
35193813
}]);

dist/angular-patternfly.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

misc/demo.css

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,29 @@ hr {
4040
display:inline-block;
4141
width: 100%;
4242
}
43+
44+
.list-view-container {
45+
border: 1px solid #000000;
46+
min-height: 25px;
47+
margin: 10px;
48+
}
49+
50+
.list-view-container .list-row {
51+
padding-top: 2px;
52+
}
53+
54+
.list-view-container span {
55+
padding-left: 5px;
56+
}
57+
58+
.tiles-view-container {
59+
border: 1px solid #000000;
60+
margin: 10px;
61+
min-height: 25px;
62+
padding: 5px;
63+
}
64+
65+
.tiles-view-container .tiles-view-pf .tile {
66+
height: 90px;
67+
width: 300px;
68+
}

0 commit comments

Comments
 (0)