Skip to content

Commit edcec39

Browse files
Add Expand Capability to pfNotificationDrawer
1 parent 32cd804 commit edcec39

File tree

4 files changed

+164
-22
lines changed

4 files changed

+164
-22
lines changed

src/notification/notification-drawer.directive.js

Lines changed: 88 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
* <br><br>
1515
*
1616
* @param {boolean} drawerHidden Flag if the drawer is currently hidden
17-
* @param {string} drawerTitle Title to display for the drawer
17+
* @param {boolean} allowExpand Flag if the drawer can be expanded. Optional, default: false
18+
* @param {boolean} drawExpanded Flag if the drawer is expanded (only valid if allowExpand is true). Optional, default: false
19+
* @param {string} drawerTitle Title to display for the drawer (leaving this blank will remove the provided expand capability)
1820
* @param {object} notificationGroups Array of notification groups to add to the drawer
1921
* @param {string} actionButtonTitle Text for the lower action button of the drawer (optional, if not specified there will be no action button)
2022
* @param {function} actionButtonCallback function(notificationGroup) Callback method for action button for each group, the notificationGroup is passed (Optional)
@@ -45,7 +47,7 @@
4547
</div>
4648
<div class="layout-pf-fixed">
4749
<div class="navbar-pf-vertical">
48-
<div pf-notification-drawer drawer-hidden="hideDrawer" drawer-title="Notifications Drawer"
50+
<div pf-notification-drawer drawer-hidden="hideDrawer" drawer-title="Notifications Drawer" allow-expand="true"
4951
action-button-title="Mark All Read" action-button-callback="actionButtonCB" notification-groups="groups"
5052
heading-include="heading.html" subheading-include="subheading.html" notification-body-include="notification-body.html"
5153
notification-footer-include="notification-footer.html" custom-scope="customScope">
@@ -73,25 +75,58 @@
7375
</a>
7476
</file>
7577
<file name="notification-body.html">
76-
<div class="dropdown pull-right dropdown-kebab-pf" ng-if="notification.actions && notification.actions.length > 0">
77-
<button class="btn btn-link dropdown-toggle" type="button" id="dropdownKebabRight" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
78-
<span class="fa fa-ellipsis-v"></span>
79-
</button>
80-
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownKebabRight">
81-
<li ng-repeat="action in notification.actions"
82-
role="{{action.isSeparator === true ? 'separator' : 'menuitem'}}"
83-
ng-class="{'divider': action.isSeparator === true, 'disabled': action.isDisabled === true}">
84-
<a ng-if="action.isSeparator !== true" class="secondary-action" title="{{action.title}}" ng-click="customScope.handleAction(notification, action)">
85-
{{action.name}}
86-
</a>
87-
</li>
88-
</ul>
78+
<div ng-if="!drawerExpanded">
79+
<div class="dropdown pull-right dropdown-kebab-pf" ng-if="notification.actions && notification.actions.length > 0">
80+
<button class="btn btn-link dropdown-toggle" type="button" id="dropdownKebabRight" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
81+
<span class="fa fa-ellipsis-v"></span>
82+
</button>
83+
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownKebabRight">
84+
<li ng-repeat="action in notification.actions"
85+
role="{{action.isSeparator === true ? 'separator' : 'menuitem'}}"
86+
ng-class="{'divider': action.isSeparator === true, 'disabled': action.isDisabled === true}">
87+
<a ng-if="action.isSeparator !== true" class="secondary-action" title="{{action.title}}" ng-click="customScope.handleAction(notification, action)">
88+
{{action.name}}
89+
</a>
90+
</li>
91+
</ul>
92+
</div>
93+
<span ng-if="notification.status" class="{{'pull-left ' + customScope.getNotficationStatusIconClass(notification)}}" ng-click="customScope.markRead(notification)"></span>
94+
<span class="drawer-pf-notification-message" ng-click="customScope.markRead(notification)">{{notification.message}}</span>
95+
<div class="drawer-pf-notification-info" ng-click="customScope.markRead(notification)">
96+
<span class="date">{{notification.timeStamp | date:'MM/dd/yyyy'}}</span>
97+
<span class="time">{{notification.timeStamp | date:'h:mm:ss a'}}</span>
98+
</div>
8999
</div>
90-
<span ng-if="notification.status" class="{{'pull-left ' + customScope.getNotficationStatusIconClass(notification)}}"></span>
91-
<span class="drawer-pf-notification-message">{{notification.message}}</span>
92-
<div class="drawer-pf-notification-info">
93-
<span class="date">{{notification.timeStamp | date:'MM/dd/yyyy'}}</span>
94-
<span class="time">{{notification.timeStamp | date:'h:mm:ss a'}}</span>
100+
<div ng-if="drawerExpanded" class="container-fluid expanded-notification">
101+
<div class="row">
102+
<div class="col-sm-6">
103+
<span class="pull-left {{customScope.getNotficationStatusIconClass(notification)}}"></span>
104+
<span class="drawer-pf-notification-message notification-message"
105+
tooltip-append-to-body="true" tooltip-popup-delay="500" tooltip-placement="bottom" tooltip="{{notification.message}}">
106+
{{notification.message}}
107+
</span>
108+
</div>
109+
<div class="col-sm-6">
110+
<div class="drawer-pf-notification-info">
111+
<span class="date">{{notification.timeStamp | date:'MM/dd/yyyy'}}</span>
112+
<span class="time">{{notification.timeStamp | date:'h:mm:ss a'}}</span>
113+
</div>
114+
<div class="dropdown pull-right dropdown-kebab-pf" ng-if="notification.actions && notification.actions.length > 0">
115+
<button class="btn btn-link dropdown-toggle" type="button" id="dropdownKebabRight" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
116+
<span class="fa fa-ellipsis-v"></span>
117+
</button>
118+
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownKebabRight">
119+
<li ng-repeat="action in notification.actions"
120+
role="{{action.isSeparator === true ? 'separator' : 'menuitem'}}"
121+
ng-class="{'divider': action.isSeparator === true, 'disabled': action.isDisabled === true}">
122+
<a ng-if="action.isSeparator !== true" class="secondary-action" title="{{action.title}}" ng-click="customScope.handleAction(notification, action)">
123+
{{action.name}}
124+
</a>
125+
</li>
126+
</ul>
127+
</div>
128+
</div>
129+
</div>
95130
</div>
96131
</file>
97132
<file name="script.js">
@@ -375,6 +410,10 @@
375410
$scope.actionsText = "";
376411
$scope.actionButtonCB = function (group) {
377412
$scope.actionsText = "Action Button clicked: " + group.heading + "\n" + $scope.actionsText;
413+
group.notifications.forEach(function(nextNotification) {
414+
nextNotification.unread = false;
415+
});
416+
group.subHeading = "0 New Events";
378417
};
379418
380419
//
@@ -408,19 +447,38 @@
408447
$scope.customScope.clearAll = function (group) {
409448
var newText = group.heading + " - Clear All";
410449
$scope.actionsText = newText + "\n" + $scope.actionsText;
450+
group.notifications = [];
451+
group.subHeading = "0 New Events";
411452
};
412453
454+
$scope.customScope.markRead = function (notification) {
455+
if (notification.unread) {
456+
notification.unread = false;
457+
$scope.actionsText = "Mark notification read" + "\n" + $scope.actionsText;
458+
var notificationGroup = $scope.groups.find(function(group) {
459+
return group.notifications.find(function(nextNotification) {
460+
return notification == nextNotification;
461+
});
462+
});
463+
var unread = notificationGroup.notifications.filter(function(nextNotification) {
464+
return nextNotification.unread;
465+
});
466+
notificationGroup.subHeading = unread.length + " New Events";
467+
}
468+
};
413469
}
414470
]);
415471
</file>
416472
</example>
417473
*/
418-
angular.module('patternfly.notification').directive('pfNotificationDrawer', function ($window, $timeout, $document) {
474+
angular.module('patternfly.notification').directive('pfNotificationDrawer', function ($window, $timeout) {
419475
'use strict';
420476
return {
421477
restrict: 'A',
422478
scope: {
423479
drawerHidden: '=?',
480+
allowExpand: '=?',
481+
drawerExpanded: '=?',
424482
drawerTitle: '@',
425483
notificationGroups: '=',
426484
actionButtonTitle: '@',
@@ -433,6 +491,11 @@ angular.module('patternfly.notification').directive('pfNotificationDrawer', func
433491
customScope: '=?'
434492
},
435493
templateUrl: 'notification/notification-drawer.html',
494+
controller: function ($scope) {
495+
if (!$scope.allowExpand || angular.isUndefined($scope.drawerExpanded)) {
496+
$scope.drawerExpanded = false;
497+
}
498+
},
436499
link: function (scope, element) {
437500

438501
scope.$watch('notificationGroups', function () {
@@ -465,6 +528,10 @@ angular.module('patternfly.notification').directive('pfNotificationDrawer', func
465528
}
466529
};
467530

531+
scope.toggleExpandDrawer = function () {
532+
scope.drawerExpanded = !scope.drawerExpanded;
533+
};
534+
468535
if (scope.groupHeight) {
469536
element.find('.panel-group').css("height", scope.groupHeight);
470537
}

src/notification/notification-drawer.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
<div class="drawer-pf" ng-class="{'hide': drawerHidden}">
1+
<div class="drawer-pf" ng-class="{'hide': drawerHidden, 'drawer-pf-expanded': drawerExpanded}">
22
<div ng-if="drawerTitle" class="drawer-pf-title">
3+
<a ng-if="allowExpand" class="drawer-pf-toggle-expand" ng-click="toggleExpandDrawer()"></a>
34
<h3 class="text-center">{{drawerTitle}}</h3>
45
</div>
56
<div ng-if="titleInclude" class="drawer-pf-title" ng-include src="titleInclude"></div>

styles/angular-patternfly.css

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,3 +419,37 @@ accordion > .panel-group .panel-open .panel-title > a:before {
419419
.navbar-brand-txt {
420420
line-height: 34px;
421421
}
422+
423+
.drawer-pf-toggle-expand {
424+
color: inherit;
425+
cursor: pointer;
426+
left: 0;
427+
padding: 2px 5px;
428+
position: absolute;
429+
}
430+
.drawer-pf-toggle-expand:before {
431+
content: "\f100";
432+
font-family: "FontAwesome";
433+
}
434+
.drawer-pf-toggle-expand:hover, .drawer-pf-toggle-expand:focus {
435+
text-decoration: none;
436+
outline: none;
437+
}
438+
439+
.drawer-pf.drawer-pf-expanded {
440+
left: 270px;
441+
width: inherit;
442+
}
443+
.drawer-pf.drawer-pf-expanded .drawer-pf-title a.drawer-pf-toggle-expand:before {
444+
content: "\f101";
445+
}
446+
.drawer-pf-notification .expanded-notification .date {
447+
border-right: none;
448+
padding-right: 0;
449+
}
450+
.drawer-pf-notification .expanded-notification .drawer-pf-notification-info {
451+
display: inline-block;
452+
}
453+
.drawer-pf-notification .expanded-notification .drawer-pf-notification-message {
454+
display: inline-block;
455+
}

test/notification/notification-drawer.spec.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,4 +442,44 @@ describe('Directive: pfNotificationDrawer', function () {
442442

443443
expect($scope.actionPerformed.name).toBe('Action1');
444444
});
445+
446+
it ('should show the expand toggle when allow expand is set to true', function () {
447+
var expandToggle = element.find('.drawer-pf-toggle-expand');
448+
expect(expandToggle.length).toBe(0);
449+
450+
var htmlTmp = '<div pf-notification-drawer allow-expand="true" drawer-hidden="hideDrawer" drawer-title="Notifications Drawer" title-include="test/notification/title.html" ' +
451+
' action-button-title="Mark All Read" action-button-callback="actionButtonCB" notification-groups="groups"' +
452+
' heading-include="test/notification/heading.html" subheading-include="test/notification/subheading.html" notification-body-include="test/notification/notification-body.html"' +
453+
' notification-footer-include="test/notification/notification-footer.html" custom-scope="customScope">' +
454+
'</div>';
455+
456+
compileHTML(htmlTmp, $scope);
457+
458+
expandToggle = element.find('.drawer-pf-toggle-expand');
459+
expect(expandToggle.length).toBe(1);
460+
});
461+
462+
it ('should expand the drawer when the expand toggle is clicked', function () {
463+
var expandedDrawer = element.find('.drawer-pf.drawer-pf-expanded');
464+
expect(expandedDrawer.length).toBe(0);
465+
466+
var htmlTmp = '<div pf-notification-drawer allow-expand="true" drawer-hidden="hideDrawer" drawer-title="Notifications Drawer" title-include="test/notification/title.html" ' +
467+
' action-button-title="Mark All Read" action-button-callback="actionButtonCB" notification-groups="groups"' +
468+
' heading-include="test/notification/heading.html" subheading-include="test/notification/subheading.html" notification-body-include="test/notification/notification-body.html"' +
469+
' notification-footer-include="test/notification/notification-footer.html" custom-scope="customScope">' +
470+
'</div>';
471+
472+
compileHTML(htmlTmp, $scope);
473+
474+
expandedDrawer = element.find('.drawer-pf.drawer-pf-expanded');
475+
expect(expandedDrawer.length).toBe(0);
476+
var expandToggle = element.find('.drawer-pf-toggle-expand');
477+
expect(expandToggle.length).toBe(1);
478+
479+
eventFire(expandToggle[0], 'click');
480+
$scope.$digest();
481+
482+
expandedDrawer = element.find('.drawer-pf.drawer-pf-expanded');
483+
expect(expandedDrawer.length).toBe(1);
484+
});
445485
});

0 commit comments

Comments
 (0)