Commit ba048498 by Samuel Padgett

Add NotificationService.hideNotification

Also truncate long text in toast notifications (with a "See All" link).
parent eb8c2167
...@@ -383,7 +383,15 @@ hawtioPluginLoader.addModule('openshiftCommonUI'); ...@@ -383,7 +383,15 @@ hawtioPluginLoader.addModule('openshiftCommonUI');
" <span class=\"{{notification.type | alertIcon}}\" aria-hidden=\"true\"></span>\n" + " <span class=\"{{notification.type | alertIcon}}\" aria-hidden=\"true\"></span>\n" +
" <span class=\"sr-only\">{{notification.type}}</span>\n" + " <span class=\"sr-only\">{{notification.type}}</span>\n" +
" <span class=\"toast-notification-message\" ng-if=\"notification.message\">{{notification.message}}</span>\n" + " <span class=\"toast-notification-message\" ng-if=\"notification.message\">{{notification.message}}</span>\n" +
" <span ng-if=\"notification.details\">{{notification.details}}</span>\n" + " <span ng-if=\"notification.details\">\n" +
" <truncate-long-text\n" +
" limit=\"200\"\n" +
" content=\"notification.details\"\n" +
" use-word-boundary=\"true\"\n" +
" expandable=\"true\"\n" +
" hide-collapse=\"true\">\n" +
" </truncate-long-text>\n" +
" </span>\n" +
" <span ng-repeat=\"link in notification.links\">\n" + " <span ng-repeat=\"link in notification.links\">\n" +
" <a ng-if=\"!link.href\" href=\"\" ng-click=\"onClick(notification, link)\" role=\"button\">{{link.label}}</a>\n" + " <a ng-if=\"!link.href\" href=\"\" ng-click=\"onClick(notification, link)\" role=\"button\">{{link.label}}</a>\n" +
" <a ng-if=\"link.href\" ng-href=\"{{link.href}}\" ng-attr-target=\"{{link.target}}\">{{link.label}}</a>\n" + " <a ng-if=\"link.href\" ng-href=\"{{link.href}}\" ng-attr-target=\"{{link.target}}\">{{link.label}}</a>\n" +
...@@ -411,11 +419,11 @@ hawtioPluginLoader.addModule('openshiftCommonUI'); ...@@ -411,11 +419,11 @@ hawtioPluginLoader.addModule('openshiftCommonUI');
" </span>\n" + " </span>\n" +
" <span ng-if=\"toggles.expanded\">\n" + " <span ng-if=\"toggles.expanded\">\n" +
" <div ng-if=\"prettifyJson\" class=\"well\">\n" + " <div ng-if=\"prettifyJson\" class=\"well\">\n" +
" <span class=\"pull-right\" style=\"margin-top: -10px;\"><a href=\"\" ng-click=\"toggles.expanded = false\" class=\"truncation-collapse-link\">Collapse</a></span>\n" + " <span ng-if=\"!hideCollapse\" class=\"pull-right\" style=\"margin-top: -10px;\"><a href=\"\" ng-click=\"toggles.expanded = false\" class=\"truncation-collapse-link\">Collapse</a></span>\n" +
" <span ng-bind-html=\"content | prettifyJSON | highlightKeywords : keywords\" class=\"pretty-json truncated-content\"></span>\n" + " <span ng-bind-html=\"content | prettifyJSON | highlightKeywords : keywords\" class=\"pretty-json truncated-content\"></span>\n" +
" </div>\n" + " </div>\n" +
" <span ng-if=\"!prettifyJson\">\n" + " <span ng-if=\"!prettifyJson\">\n" +
" <span class=\"pull-right\"><a href=\"\" ng-click=\"toggles.expanded = false\" class=\"truncation-collapse-link\">Collapse</a></span>\n" + " <span ng-if=\"!hideCollapse\" class=\"pull-right\"><a href=\"\" ng-click=\"toggles.expanded = false\" class=\"truncation-collapse-link\">Collapse</a></span>\n" +
" <span ng-bind-html=\"content | highlightKeywords : keywords\" class=\"truncated-content\"></span>\n" + " <span ng-bind-html=\"content | highlightKeywords : keywords\" class=\"truncated-content\"></span>\n" +
" </span>\n" + " </span>\n" +
" </span>\n" + " </span>\n" +
...@@ -932,6 +940,8 @@ angular.module('openshiftCommonUI') ...@@ -932,6 +940,8 @@ angular.module('openshiftCommonUI')
newlineLimit: '=', newlineLimit: '=',
useWordBoundary: '=', useWordBoundary: '=',
expandable: '=', expandable: '=',
// When expandable is on, optionally hide the collapse link so text can only be expanded. (Used for toast notifications.)
hideCollapse: '=',
keywords: '=highlightKeywords', // optional keywords to highlight using the `highlightKeywords` filter keywords: '=highlightKeywords', // optional keywords to highlight using the `highlightKeywords` filter
prettifyJson: '=' // prettifies JSON blobs when expanded, only used if expandable is true prettifyJson: '=' // prettifies JSON blobs when expanded, only used if expandable is true
}, },
...@@ -1712,6 +1722,18 @@ angular.module('openshiftCommonUI').provider('NotificationsService', function() ...@@ -1712,6 +1722,18 @@ angular.module('openshiftCommonUI').provider('NotificationsService', function()
notifications.push(notification); notifications.push(notification);
}; };
var hideNotification = function (notificationID) {
if (!notificationID) {
return;
}
_.each(notifications, function(notification) {
if (notification.id === notificationID) {
notification.hidden = true;
}
});
};
var getNotifications = function () { var getNotifications = function () {
return notifications; return notifications;
}; };
...@@ -1746,9 +1768,7 @@ angular.module('openshiftCommonUI').provider('NotificationsService', function() ...@@ -1746,9 +1768,7 @@ angular.module('openshiftCommonUI').provider('NotificationsService', function()
}; };
var isAutoDismiss = function(notification) { var isAutoDismiss = function(notification) {
return _.find(autoDismissTypes, function(type) { return _.includes(autoDismissTypes, notification.type);
return type === notification.type;
});
}; };
// Also handle `addNotification` events on $rootScope, which is used by DataService. // Also handle `addNotification` events on $rootScope, which is used by DataService.
...@@ -1758,6 +1778,7 @@ angular.module('openshiftCommonUI').provider('NotificationsService', function() ...@@ -1758,6 +1778,7 @@ angular.module('openshiftCommonUI').provider('NotificationsService', function()
return { return {
addNotification: addNotification, addNotification: addNotification,
hideNotification: hideNotification,
getNotifications: getNotifications, getNotifications: getNotifications,
clearNotifications: clearNotifications, clearNotifications: clearNotifications,
isNotificationPermanentlyHidden: isNotificationPermanentlyHidden, isNotificationPermanentlyHidden: isNotificationPermanentlyHidden,
......
...@@ -554,7 +554,15 @@ hawtioPluginLoader.addModule('openshiftCommonUI'); ...@@ -554,7 +554,15 @@ hawtioPluginLoader.addModule('openshiftCommonUI');
" <span class=\"{{notification.type | alertIcon}}\" aria-hidden=\"true\"></span>\n" + " <span class=\"{{notification.type | alertIcon}}\" aria-hidden=\"true\"></span>\n" +
" <span class=\"sr-only\">{{notification.type}}</span>\n" + " <span class=\"sr-only\">{{notification.type}}</span>\n" +
" <span class=\"toast-notification-message\" ng-if=\"notification.message\">{{notification.message}}</span>\n" + " <span class=\"toast-notification-message\" ng-if=\"notification.message\">{{notification.message}}</span>\n" +
" <span ng-if=\"notification.details\">{{notification.details}}</span>\n" + " <span ng-if=\"notification.details\">\n" +
" <truncate-long-text\n" +
" limit=\"200\"\n" +
" content=\"notification.details\"\n" +
" use-word-boundary=\"true\"\n" +
" expandable=\"true\"\n" +
" hide-collapse=\"true\">\n" +
" </truncate-long-text>\n" +
" </span>\n" +
" <span ng-repeat=\"link in notification.links\">\n" + " <span ng-repeat=\"link in notification.links\">\n" +
" <a ng-if=\"!link.href\" href=\"\" ng-click=\"onClick(notification, link)\" role=\"button\">{{link.label}}</a>\n" + " <a ng-if=\"!link.href\" href=\"\" ng-click=\"onClick(notification, link)\" role=\"button\">{{link.label}}</a>\n" +
" <a ng-if=\"link.href\" ng-href=\"{{link.href}}\" ng-attr-target=\"{{link.target}}\">{{link.label}}</a>\n" + " <a ng-if=\"link.href\" ng-href=\"{{link.href}}\" ng-attr-target=\"{{link.target}}\">{{link.label}}</a>\n" +
...@@ -582,11 +590,11 @@ hawtioPluginLoader.addModule('openshiftCommonUI'); ...@@ -582,11 +590,11 @@ hawtioPluginLoader.addModule('openshiftCommonUI');
" </span>\n" + " </span>\n" +
" <span ng-if=\"toggles.expanded\">\n" + " <span ng-if=\"toggles.expanded\">\n" +
" <div ng-if=\"prettifyJson\" class=\"well\">\n" + " <div ng-if=\"prettifyJson\" class=\"well\">\n" +
" <span class=\"pull-right\" style=\"margin-top: -10px;\"><a href=\"\" ng-click=\"toggles.expanded = false\" class=\"truncation-collapse-link\">Collapse</a></span>\n" + " <span ng-if=\"!hideCollapse\" class=\"pull-right\" style=\"margin-top: -10px;\"><a href=\"\" ng-click=\"toggles.expanded = false\" class=\"truncation-collapse-link\">Collapse</a></span>\n" +
" <span ng-bind-html=\"content | prettifyJSON | highlightKeywords : keywords\" class=\"pretty-json truncated-content\"></span>\n" + " <span ng-bind-html=\"content | prettifyJSON | highlightKeywords : keywords\" class=\"pretty-json truncated-content\"></span>\n" +
" </div>\n" + " </div>\n" +
" <span ng-if=\"!prettifyJson\">\n" + " <span ng-if=\"!prettifyJson\">\n" +
" <span class=\"pull-right\"><a href=\"\" ng-click=\"toggles.expanded = false\" class=\"truncation-collapse-link\">Collapse</a></span>\n" + " <span ng-if=\"!hideCollapse\" class=\"pull-right\"><a href=\"\" ng-click=\"toggles.expanded = false\" class=\"truncation-collapse-link\">Collapse</a></span>\n" +
" <span ng-bind-html=\"content | highlightKeywords : keywords\" class=\"truncated-content\"></span>\n" + " <span ng-bind-html=\"content | highlightKeywords : keywords\" class=\"truncated-content\"></span>\n" +
" </span>\n" + " </span>\n" +
" </span>\n" + " </span>\n" +
...@@ -1103,6 +1111,8 @@ angular.module('openshiftCommonUI') ...@@ -1103,6 +1111,8 @@ angular.module('openshiftCommonUI')
newlineLimit: '=', newlineLimit: '=',
useWordBoundary: '=', useWordBoundary: '=',
expandable: '=', expandable: '=',
// When expandable is on, optionally hide the collapse link so text can only be expanded. (Used for toast notifications.)
hideCollapse: '=',
keywords: '=highlightKeywords', // optional keywords to highlight using the `highlightKeywords` filter keywords: '=highlightKeywords', // optional keywords to highlight using the `highlightKeywords` filter
prettifyJson: '=' // prettifies JSON blobs when expanded, only used if expandable is true prettifyJson: '=' // prettifies JSON blobs when expanded, only used if expandable is true
}, },
...@@ -4807,6 +4817,18 @@ angular.module('openshiftCommonUI').provider('NotificationsService', function() ...@@ -4807,6 +4817,18 @@ angular.module('openshiftCommonUI').provider('NotificationsService', function()
notifications.push(notification); notifications.push(notification);
}; };
var hideNotification = function (notificationID) {
if (!notificationID) {
return;
}
_.each(notifications, function(notification) {
if (notification.id === notificationID) {
notification.hidden = true;
}
});
};
var getNotifications = function () { var getNotifications = function () {
return notifications; return notifications;
}; };
...@@ -4841,9 +4863,7 @@ angular.module('openshiftCommonUI').provider('NotificationsService', function() ...@@ -4841,9 +4863,7 @@ angular.module('openshiftCommonUI').provider('NotificationsService', function()
}; };
var isAutoDismiss = function(notification) { var isAutoDismiss = function(notification) {
return _.find(autoDismissTypes, function(type) { return _.includes(autoDismissTypes, notification.type);
return type === notification.type;
});
}; };
// Also handle `addNotification` events on $rootScope, which is used by DataService. // Also handle `addNotification` events on $rootScope, which is used by DataService.
...@@ -4853,6 +4873,7 @@ angular.module('openshiftCommonUI').provider('NotificationsService', function() ...@@ -4853,6 +4873,7 @@ angular.module('openshiftCommonUI').provider('NotificationsService', function()
return { return {
addNotification: addNotification, addNotification: addNotification,
hideNotification: hideNotification,
getNotifications: getNotifications, getNotifications: getNotifications,
clearNotifications: clearNotifications, clearNotifications: clearNotifications,
isNotificationPermanentlyHidden: isNotificationPermanentlyHidden, isNotificationPermanentlyHidden: isNotificationPermanentlyHidden,
......
...@@ -85,8 +85,8 @@ $templateCache.put("src/components/binding/bindServiceForm.html", '<div class="b ...@@ -85,8 +85,8 @@ $templateCache.put("src/components/binding/bindServiceForm.html", '<div class="b
$templateCache.put("src/components/create-project/createProject.html", '<form name="createProjectForm" novalidate>\n <fieldset ng-disabled="disableInputs">\n <div class="form-group">\n <label for="name" class="required">Name</label>\n <span ng-class="{\'has-error\': (createProjectForm.name.$error.pattern && createProjectForm.name.$touched) || nameTaken}">\n <input class="form-control input-lg"\n name="name"\n id="name"\n placeholder="my-project"\n type="text"\n required\n take-focus\n minlength="2"\n maxlength="63"\n pattern="[a-z0-9]([-a-z0-9]*[a-z0-9])?"\n aria-describedby="nameHelp"\n ng-model="name"\n ng-model-options="{ updateOn: \'default blur\' }"\n ng-change="nameTaken = false"\n autocorrect="off"\n autocapitalize="off"\n spellcheck="false">\n </span>\n <div>\n <span class="help-block">A unique name for the project.</span>\n </div>\n <div class="has-error">\n <span id="nameHelp" class="help-block" ng-if="createProjectForm.name.$error.required && createProjectForm.name.$dirty">\n Name is required.\n </span>\n </div>\n <div class="has-error">\n <span id="nameHelp" class="help-block" ng-if="createProjectForm.name.$error.minlength && createProjectForm.name.$touched">\n Name must have at least two characters.\n </span>\n </div>\n <div class="has-error">\n <span id="nameHelp" class="help-block" ng-if="createProjectForm.name.$error.pattern && createProjectForm.name.$touched">\n Project names may only contain lower-case letters, numbers, and dashes.\n They may not start or end with a dash.\n </span>\n </div>\n <div class="has-error">\n <span class="help-block" ng-if="nameTaken">\n This name is already in use. Please choose a different name.\n </span>\n </div>\n </div>\n\n <div class="form-group">\n <label for="displayName">Display Name</label>\n <input class="form-control input-lg"\n name="displayName"\n id="displayName"\n placeholder="My Project"\n type="text"\n ng-model="displayName">\n </div>\n\n <div class="form-group">\n <label for="description">Description</label>\n <textarea class="form-control input-lg"\n name="description"\n id="description"\n placeholder="A short description."\n ng-model="description"></textarea>\n </div>\n\n <div class="button-group">\n <button type="submit"\n class="btn btn-primary btn-lg"\n ng-class="{\'dialog-btn\': isDialog}"\n ng-click="createProject()"\n ng-disabled="createProjectForm.$invalid || nameTaken || disableInputs"\n value="">\n Create\n </button>\n <button\n class="btn btn-default btn-lg"\n ng-class="{\'dialog-btn\': isDialog}"\n ng-click="cancelCreateProject()">\n Cancel\n </button>\n </div>\n </fieldset>\n</form>\n'), $templateCache.put("src/components/create-project/createProject.html", '<form name="createProjectForm" novalidate>\n <fieldset ng-disabled="disableInputs">\n <div class="form-group">\n <label for="name" class="required">Name</label>\n <span ng-class="{\'has-error\': (createProjectForm.name.$error.pattern && createProjectForm.name.$touched) || nameTaken}">\n <input class="form-control input-lg"\n name="name"\n id="name"\n placeholder="my-project"\n type="text"\n required\n take-focus\n minlength="2"\n maxlength="63"\n pattern="[a-z0-9]([-a-z0-9]*[a-z0-9])?"\n aria-describedby="nameHelp"\n ng-model="name"\n ng-model-options="{ updateOn: \'default blur\' }"\n ng-change="nameTaken = false"\n autocorrect="off"\n autocapitalize="off"\n spellcheck="false">\n </span>\n <div>\n <span class="help-block">A unique name for the project.</span>\n </div>\n <div class="has-error">\n <span id="nameHelp" class="help-block" ng-if="createProjectForm.name.$error.required && createProjectForm.name.$dirty">\n Name is required.\n </span>\n </div>\n <div class="has-error">\n <span id="nameHelp" class="help-block" ng-if="createProjectForm.name.$error.minlength && createProjectForm.name.$touched">\n Name must have at least two characters.\n </span>\n </div>\n <div class="has-error">\n <span id="nameHelp" class="help-block" ng-if="createProjectForm.name.$error.pattern && createProjectForm.name.$touched">\n Project names may only contain lower-case letters, numbers, and dashes.\n They may not start or end with a dash.\n </span>\n </div>\n <div class="has-error">\n <span class="help-block" ng-if="nameTaken">\n This name is already in use. Please choose a different name.\n </span>\n </div>\n </div>\n\n <div class="form-group">\n <label for="displayName">Display Name</label>\n <input class="form-control input-lg"\n name="displayName"\n id="displayName"\n placeholder="My Project"\n type="text"\n ng-model="displayName">\n </div>\n\n <div class="form-group">\n <label for="description">Description</label>\n <textarea class="form-control input-lg"\n name="description"\n id="description"\n placeholder="A short description."\n ng-model="description"></textarea>\n </div>\n\n <div class="button-group">\n <button type="submit"\n class="btn btn-primary btn-lg"\n ng-class="{\'dialog-btn\': isDialog}"\n ng-click="createProject()"\n ng-disabled="createProjectForm.$invalid || nameTaken || disableInputs"\n value="">\n Create\n </button>\n <button\n class="btn btn-default btn-lg"\n ng-class="{\'dialog-btn\': isDialog}"\n ng-click="cancelCreateProject()">\n Cancel\n </button>\n </div>\n </fieldset>\n</form>\n'),
$templateCache.put("src/components/delete-project/delete-project-button.html", '<div class="actions">\n <!-- Avoid whitespace inside the link -->\n <a href=""\n ng-click="$event.stopPropagation(); openDeleteModal()"\n role="button"\n class="action-button"\n ng-attr-aria-disabled="{{disableDelete ? \'true\' : undefined}}"\n ng-class="{ \'disabled-link\': disableDelete }"\n ><i class="fa fa-trash-o" aria-hidden="true"\n ></i><span class="sr-only">Delete Project {{projectName}}</span></a>\n</div>\n'), $templateCache.put("src/components/delete-project/delete-project-modal.html", '<div class="delete-resource-modal">\n <!-- Use a form so that the enter key submits when typing a project name to confirm. -->\n <form>\n <div class="modal-body">\n <h1>Are you sure you want to delete the project\n \'<strong>{{displayName ? displayName : projectName}}</strong>\'?</h1>\n <p>\n This will <strong>delete all resources</strong> associated with\n the project {{displayName ? displayName : projectName}} and <strong>cannot be\n undone</strong>. Make sure this is something you really want to do!\n </p>\n <div ng-show="typeNameToConfirm">\n <p>Type the name of the project to confirm.</p>\n <p>\n <label class="sr-only" for="resource-to-delete">project to delete</label>\n <input\n ng-model="confirmName"\n id="resource-to-delete"\n type="text"\n class="form-control input-lg"\n autocorrect="off"\n autocapitalize="off"\n spellcheck="false"\n autofocus>\n </p>\n </div>\n </div>\n <div class="modal-footer">\n <button ng-disabled="typeNameToConfirm && confirmName !== projectName && confirmName !== displayName" class="btn btn-lg btn-danger" type="submit" ng-click="delete();">Delete</button>\n <button class="btn btn-lg btn-default" type="button" ng-click="cancel();">Cancel</button>\n </div>\n </form>\n</div>\n'), $templateCache.put("src/components/delete-project/delete-project-button.html", '<div class="actions">\n <!-- Avoid whitespace inside the link -->\n <a href=""\n ng-click="$event.stopPropagation(); openDeleteModal()"\n role="button"\n class="action-button"\n ng-attr-aria-disabled="{{disableDelete ? \'true\' : undefined}}"\n ng-class="{ \'disabled-link\': disableDelete }"\n ><i class="fa fa-trash-o" aria-hidden="true"\n ></i><span class="sr-only">Delete Project {{projectName}}</span></a>\n</div>\n'), $templateCache.put("src/components/delete-project/delete-project-modal.html", '<div class="delete-resource-modal">\n <!-- Use a form so that the enter key submits when typing a project name to confirm. -->\n <form>\n <div class="modal-body">\n <h1>Are you sure you want to delete the project\n \'<strong>{{displayName ? displayName : projectName}}</strong>\'?</h1>\n <p>\n This will <strong>delete all resources</strong> associated with\n the project {{displayName ? displayName : projectName}} and <strong>cannot be\n undone</strong>. Make sure this is something you really want to do!\n </p>\n <div ng-show="typeNameToConfirm">\n <p>Type the name of the project to confirm.</p>\n <p>\n <label class="sr-only" for="resource-to-delete">project to delete</label>\n <input\n ng-model="confirmName"\n id="resource-to-delete"\n type="text"\n class="form-control input-lg"\n autocorrect="off"\n autocapitalize="off"\n spellcheck="false"\n autofocus>\n </p>\n </div>\n </div>\n <div class="modal-footer">\n <button ng-disabled="typeNameToConfirm && confirmName !== projectName && confirmName !== displayName" class="btn btn-lg btn-danger" type="submit" ng-click="delete();">Delete</button>\n <button class="btn btn-lg btn-default" type="button" ng-click="cancel();">Cancel</button>\n </div>\n </form>\n</div>\n'),
$templateCache.put("src/components/delete-project/delete-project.html", '<a href="javascript:void(0)"\n ng-click="openDeleteModal()"\n role="button"\n ng-attr-aria-disabled="{{disableDelete ? \'true\' : undefined}}"\n ng-class="{ \'disabled-link\': disableDelete }"\n>{{label || \'Delete\'}}</a>\n'), $templateCache.put("src/components/edit-project/editProject.html", '<form name="editProjectForm">\n <fieldset ng-disabled="disableInputs">\n <div class="form-group">\n <label for="displayName">Display Name</label>\n <input class="form-control input-lg"\n name="displayName"\n id="displayName"\n placeholder="My Project"\n type="text"\n ng-model="editableFields.displayName">\n </div>\n\n <div class="form-group">\n <label for="description">Description</label>\n <textarea class="form-control input-lg"\n name="description"\n id="description"\n placeholder="A short description."\n ng-model="editableFields.description"></textarea>\n </div>\n\n <div class="button-group">\n <button type="submit"\n class="btn btn-primary btn-lg"\n ng-class="{\'dialog-btn\': isDialog}"\n ng-click="update()"\n ng-disabled="editProjectForm.$invalid || disableInputs"\n value="">{{submitButtonLabel}}</button>\n <button\n class="btn btn-default btn-lg"\n ng-class="{\'dialog-btn\': isDialog}"\n ng-click="cancelEditProject()">\n Cancel\n </button>\n </div>\n </fieldset>\n</form>\n'), $templateCache.put("src/components/delete-project/delete-project.html", '<a href="javascript:void(0)"\n ng-click="openDeleteModal()"\n role="button"\n ng-attr-aria-disabled="{{disableDelete ? \'true\' : undefined}}"\n ng-class="{ \'disabled-link\': disableDelete }"\n>{{label || \'Delete\'}}</a>\n'), $templateCache.put("src/components/edit-project/editProject.html", '<form name="editProjectForm">\n <fieldset ng-disabled="disableInputs">\n <div class="form-group">\n <label for="displayName">Display Name</label>\n <input class="form-control input-lg"\n name="displayName"\n id="displayName"\n placeholder="My Project"\n type="text"\n ng-model="editableFields.displayName">\n </div>\n\n <div class="form-group">\n <label for="description">Description</label>\n <textarea class="form-control input-lg"\n name="description"\n id="description"\n placeholder="A short description."\n ng-model="editableFields.description"></textarea>\n </div>\n\n <div class="button-group">\n <button type="submit"\n class="btn btn-primary btn-lg"\n ng-class="{\'dialog-btn\': isDialog}"\n ng-click="update()"\n ng-disabled="editProjectForm.$invalid || disableInputs"\n value="">{{submitButtonLabel}}</button>\n <button\n class="btn btn-default btn-lg"\n ng-class="{\'dialog-btn\': isDialog}"\n ng-click="cancelEditProject()">\n Cancel\n </button>\n </div>\n </fieldset>\n</form>\n'),
$templateCache.put("src/components/toast-notifications/toast-notifications.html", '<div class="toast-notifications-list-pf">\n <div ng-repeat="(notificationID, notification) in notifications track by (notificationID + (notification.message || notification.details))" ng-if="!notification.hidden"\n ng-mouseenter="setHover(notification, true)" ng-mouseleave="setHover(notification, false)">\n <div class="toast-pf alert {{notification.type | alertStatus}}" ng-class="{\'alert-dismissable\': !hideCloseButton}">\n <button ng-if="!hideCloseButton" type="button" class="close" ng-click="close(notification)">\n <span class="pficon pficon-close" aria-hidden="true"></span>\n <span class="sr-only">Close</span>\n </button>\n <span class="{{notification.type | alertIcon}}" aria-hidden="true"></span>\n <span class="sr-only">{{notification.type}}</span>\n <span class="toast-notification-message" ng-if="notification.message">{{notification.message}}</span>\n <span ng-if="notification.details">{{notification.details}}</span>\n <span ng-repeat="link in notification.links">\n <a ng-if="!link.href" href="" ng-click="onClick(notification, link)" role="button">{{link.label}}</a>\n <a ng-if="link.href" ng-href="{{link.href}}" ng-attr-target="{{link.target}}">{{link.label}}</a>\n <span ng-if="!$last" class="toast-action-divider">|</span>\n </span>\n </div>\n </div>\n</div>\n'), $templateCache.put("src/components/toast-notifications/toast-notifications.html", '<div class="toast-notifications-list-pf">\n <div ng-repeat="(notificationID, notification) in notifications track by (notificationID + (notification.message || notification.details))" ng-if="!notification.hidden"\n ng-mouseenter="setHover(notification, true)" ng-mouseleave="setHover(notification, false)">\n <div class="toast-pf alert {{notification.type | alertStatus}}" ng-class="{\'alert-dismissable\': !hideCloseButton}">\n <button ng-if="!hideCloseButton" type="button" class="close" ng-click="close(notification)">\n <span class="pficon pficon-close" aria-hidden="true"></span>\n <span class="sr-only">Close</span>\n </button>\n <span class="{{notification.type | alertIcon}}" aria-hidden="true"></span>\n <span class="sr-only">{{notification.type}}</span>\n <span class="toast-notification-message" ng-if="notification.message">{{notification.message}}</span>\n <span ng-if="notification.details">\n <truncate-long-text\n limit="200"\n content="notification.details"\n use-word-boundary="true"\n expandable="true"\n hide-collapse="true">\n </truncate-long-text>\n </span>\n <span ng-repeat="link in notification.links">\n <a ng-if="!link.href" href="" ng-click="onClick(notification, link)" role="button">{{link.label}}</a>\n <a ng-if="link.href" ng-href="{{link.href}}" ng-attr-target="{{link.target}}">{{link.label}}</a>\n <span ng-if="!$last" class="toast-action-divider">|</span>\n </span>\n </div>\n </div>\n</div>\n'),
$templateCache.put("src/components/truncate-long-text/truncateLongText.html", '<!--\n Do not remove class `truncated-content` (here or below) even though it\'s not\n styled directly in origin-web-common. `truncated-content` is used by\n origin-web-console in certain contexts.\n-->\n<span ng-if="!truncated" ng-bind-html="content | highlightKeywords : keywords" class="truncated-content"></span>\n<span ng-if="truncated">\n <span ng-if="!toggles.expanded">\n <span ng-attr-title="{{content}}" class="truncation-block">\n <span ng-bind-html="truncatedContent | highlightKeywords : keywords" class="truncated-content"></span>&hellip;\n </span>\n <a ng-if="expandable" href="" ng-click="toggles.expanded = true" class="nowrap">See All</a>\n </span>\n <span ng-if="toggles.expanded">\n <div ng-if="prettifyJson" class="well">\n <span class="pull-right" style="margin-top: -10px;"><a href="" ng-click="toggles.expanded = false" class="truncation-collapse-link">Collapse</a></span>\n <span ng-bind-html="content | prettifyJSON | highlightKeywords : keywords" class="pretty-json truncated-content"></span>\n </div>\n <span ng-if="!prettifyJson">\n <span class="pull-right"><a href="" ng-click="toggles.expanded = false" class="truncation-collapse-link">Collapse</a></span>\n <span ng-bind-html="content | highlightKeywords : keywords" class="truncated-content"></span>\n </span>\n </span>\n</span>\n'); $templateCache.put("src/components/truncate-long-text/truncateLongText.html", '<!--\n Do not remove class `truncated-content` (here or below) even though it\'s not\n styled directly in origin-web-common. `truncated-content` is used by\n origin-web-console in certain contexts.\n-->\n<span ng-if="!truncated" ng-bind-html="content | highlightKeywords : keywords" class="truncated-content"></span>\n<span ng-if="truncated">\n <span ng-if="!toggles.expanded">\n <span ng-attr-title="{{content}}" class="truncation-block">\n <span ng-bind-html="truncatedContent | highlightKeywords : keywords" class="truncated-content"></span>&hellip;\n </span>\n <a ng-if="expandable" href="" ng-click="toggles.expanded = true" class="nowrap">See All</a>\n </span>\n <span ng-if="toggles.expanded">\n <div ng-if="prettifyJson" class="well">\n <span ng-if="!hideCollapse" class="pull-right" style="margin-top: -10px;"><a href="" ng-click="toggles.expanded = false" class="truncation-collapse-link">Collapse</a></span>\n <span ng-bind-html="content | prettifyJSON | highlightKeywords : keywords" class="pretty-json truncated-content"></span>\n </div>\n <span ng-if="!prettifyJson">\n <span ng-if="!hideCollapse" class="pull-right"><a href="" ng-click="toggles.expanded = false" class="truncation-collapse-link">Collapse</a></span>\n <span ng-bind-html="content | highlightKeywords : keywords" class="truncated-content"></span>\n </span>\n </span>\n</span>\n');
} ]), angular.module("openshiftCommonUI").component("bindApplicationForm", { } ]), angular.module("openshiftCommonUI").component("bindApplicationForm", {
controllerAs:"ctrl", controllerAs:"ctrl",
bindings:{ bindings:{
...@@ -366,6 +366,7 @@ limit:"=", ...@@ -366,6 +366,7 @@ limit:"=",
newlineLimit:"=", newlineLimit:"=",
useWordBoundary:"=", useWordBoundary:"=",
expandable:"=", expandable:"=",
hideCollapse:"=",
keywords:"=highlightKeywords", keywords:"=highlightKeywords",
prettifyJson:"=" prettifyJson:"="
}, },
...@@ -2053,6 +2054,10 @@ var notifications = [], dismissDelay = this.dismissDelay, autoDismissTypes = thi ...@@ -2053,6 +2054,10 @@ var notifications = [], dismissDelay = this.dismissDelay, autoDismissTypes = thi
return namespace ? "hide/notification/" + namespace + "/" + notificationID :"hide/notification/" + notificationID; return namespace ? "hide/notification/" + namespace + "/" + notificationID :"hide/notification/" + notificationID;
}, addNotification = function(notification) { }, addNotification = function(notification) {
isNotificationPermanentlyHidden(notification) || isNotificationVisible(notification) || notifications.push(notification); isNotificationPermanentlyHidden(notification) || isNotificationVisible(notification) || notifications.push(notification);
}, hideNotification = function(notificationID) {
notificationID && _.each(notifications, function(notification) {
notification.id === notificationID && (notification.hidden = !0);
});
}, getNotifications = function() { }, getNotifications = function() {
return notifications; return notifications;
}, clearNotifications = function() { }, clearNotifications = function() {
...@@ -2069,14 +2074,13 @@ return notification.id ? _.some(notifications, function(next) { ...@@ -2069,14 +2074,13 @@ return notification.id ? _.some(notifications, function(next) {
return !next.hidden && notification.id === next.id; return !next.hidden && notification.id === next.id;
}) :!1; }) :!1;
}, isAutoDismiss = function(notification) { }, isAutoDismiss = function(notification) {
return _.find(autoDismissTypes, function(type) { return _.includes(autoDismissTypes, notification.type);
return type === notification.type;
});
}; };
return $rootScope.$on("addNotification", function(event, data) { return $rootScope.$on("addNotification", function(event, data) {
addNotification(data); addNotification(data);
}), { }), {
addNotification:addNotification, addNotification:addNotification,
hideNotification:hideNotification,
getNotifications:getNotifications, getNotifications:getNotifications,
clearNotifications:clearNotifications, clearNotifications:clearNotifications,
isNotificationPermanentlyHidden:isNotificationPermanentlyHidden, isNotificationPermanentlyHidden:isNotificationPermanentlyHidden,
......
...@@ -365,7 +365,15 @@ angular.module('openshiftCommonUI').run(['$templateCache', function($templateCac ...@@ -365,7 +365,15 @@ angular.module('openshiftCommonUI').run(['$templateCache', function($templateCac
" <span class=\"{{notification.type | alertIcon}}\" aria-hidden=\"true\"></span>\n" + " <span class=\"{{notification.type | alertIcon}}\" aria-hidden=\"true\"></span>\n" +
" <span class=\"sr-only\">{{notification.type}}</span>\n" + " <span class=\"sr-only\">{{notification.type}}</span>\n" +
" <span class=\"toast-notification-message\" ng-if=\"notification.message\">{{notification.message}}</span>\n" + " <span class=\"toast-notification-message\" ng-if=\"notification.message\">{{notification.message}}</span>\n" +
" <span ng-if=\"notification.details\">{{notification.details}}</span>\n" + " <span ng-if=\"notification.details\">\n" +
" <truncate-long-text\n" +
" limit=\"200\"\n" +
" content=\"notification.details\"\n" +
" use-word-boundary=\"true\"\n" +
" expandable=\"true\"\n" +
" hide-collapse=\"true\">\n" +
" </truncate-long-text>\n" +
" </span>\n" +
" <span ng-repeat=\"link in notification.links\">\n" + " <span ng-repeat=\"link in notification.links\">\n" +
" <a ng-if=\"!link.href\" href=\"\" ng-click=\"onClick(notification, link)\" role=\"button\">{{link.label}}</a>\n" + " <a ng-if=\"!link.href\" href=\"\" ng-click=\"onClick(notification, link)\" role=\"button\">{{link.label}}</a>\n" +
" <a ng-if=\"link.href\" ng-href=\"{{link.href}}\" ng-attr-target=\"{{link.target}}\">{{link.label}}</a>\n" + " <a ng-if=\"link.href\" ng-href=\"{{link.href}}\" ng-attr-target=\"{{link.target}}\">{{link.label}}</a>\n" +
...@@ -393,11 +401,11 @@ angular.module('openshiftCommonUI').run(['$templateCache', function($templateCac ...@@ -393,11 +401,11 @@ angular.module('openshiftCommonUI').run(['$templateCache', function($templateCac
" </span>\n" + " </span>\n" +
" <span ng-if=\"toggles.expanded\">\n" + " <span ng-if=\"toggles.expanded\">\n" +
" <div ng-if=\"prettifyJson\" class=\"well\">\n" + " <div ng-if=\"prettifyJson\" class=\"well\">\n" +
" <span class=\"pull-right\" style=\"margin-top: -10px;\"><a href=\"\" ng-click=\"toggles.expanded = false\" class=\"truncation-collapse-link\">Collapse</a></span>\n" + " <span ng-if=\"!hideCollapse\" class=\"pull-right\" style=\"margin-top: -10px;\"><a href=\"\" ng-click=\"toggles.expanded = false\" class=\"truncation-collapse-link\">Collapse</a></span>\n" +
" <span ng-bind-html=\"content | prettifyJSON | highlightKeywords : keywords\" class=\"pretty-json truncated-content\"></span>\n" + " <span ng-bind-html=\"content | prettifyJSON | highlightKeywords : keywords\" class=\"pretty-json truncated-content\"></span>\n" +
" </div>\n" + " </div>\n" +
" <span ng-if=\"!prettifyJson\">\n" + " <span ng-if=\"!prettifyJson\">\n" +
" <span class=\"pull-right\"><a href=\"\" ng-click=\"toggles.expanded = false\" class=\"truncation-collapse-link\">Collapse</a></span>\n" + " <span ng-if=\"!hideCollapse\" class=\"pull-right\"><a href=\"\" ng-click=\"toggles.expanded = false\" class=\"truncation-collapse-link\">Collapse</a></span>\n" +
" <span ng-bind-html=\"content | highlightKeywords : keywords\" class=\"truncated-content\"></span>\n" + " <span ng-bind-html=\"content | highlightKeywords : keywords\" class=\"truncated-content\"></span>\n" +
" </span>\n" + " </span>\n" +
" </span>\n" + " </span>\n" +
......
...@@ -9,7 +9,15 @@ ...@@ -9,7 +9,15 @@
<span class="{{notification.type | alertIcon}}" aria-hidden="true"></span> <span class="{{notification.type | alertIcon}}" aria-hidden="true"></span>
<span class="sr-only">{{notification.type}}</span> <span class="sr-only">{{notification.type}}</span>
<span class="toast-notification-message" ng-if="notification.message">{{notification.message}}</span> <span class="toast-notification-message" ng-if="notification.message">{{notification.message}}</span>
<span ng-if="notification.details">{{notification.details}}</span> <span ng-if="notification.details">
<truncate-long-text
limit="200"
content="notification.details"
use-word-boundary="true"
expandable="true"
hide-collapse="true">
</truncate-long-text>
</span>
<span ng-repeat="link in notification.links"> <span ng-repeat="link in notification.links">
<a ng-if="!link.href" href="" ng-click="onClick(notification, link)" role="button">{{link.label}}</a> <a ng-if="!link.href" href="" ng-click="onClick(notification, link)" role="button">{{link.label}}</a>
<a ng-if="link.href" ng-href="{{link.href}}" ng-attr-target="{{link.target}}">{{link.label}}</a> <a ng-if="link.href" ng-href="{{link.href}}" ng-attr-target="{{link.target}}">{{link.label}}</a>
......
...@@ -13,11 +13,11 @@ ...@@ -13,11 +13,11 @@
</span> </span>
<span ng-if="toggles.expanded"> <span ng-if="toggles.expanded">
<div ng-if="prettifyJson" class="well"> <div ng-if="prettifyJson" class="well">
<span class="pull-right" style="margin-top: -10px;"><a href="" ng-click="toggles.expanded = false" class="truncation-collapse-link">Collapse</a></span> <span ng-if="!hideCollapse" class="pull-right" style="margin-top: -10px;"><a href="" ng-click="toggles.expanded = false" class="truncation-collapse-link">Collapse</a></span>
<span ng-bind-html="content | prettifyJSON | highlightKeywords : keywords" class="pretty-json truncated-content"></span> <span ng-bind-html="content | prettifyJSON | highlightKeywords : keywords" class="pretty-json truncated-content"></span>
</div> </div>
<span ng-if="!prettifyJson"> <span ng-if="!prettifyJson">
<span class="pull-right"><a href="" ng-click="toggles.expanded = false" class="truncation-collapse-link">Collapse</a></span> <span ng-if="!hideCollapse" class="pull-right"><a href="" ng-click="toggles.expanded = false" class="truncation-collapse-link">Collapse</a></span>
<span ng-bind-html="content | highlightKeywords : keywords" class="truncated-content"></span> <span ng-bind-html="content | highlightKeywords : keywords" class="truncated-content"></span>
</span> </span>
</span> </span>
......
...@@ -12,6 +12,8 @@ angular.module('openshiftCommonUI') ...@@ -12,6 +12,8 @@ angular.module('openshiftCommonUI')
newlineLimit: '=', newlineLimit: '=',
useWordBoundary: '=', useWordBoundary: '=',
expandable: '=', expandable: '=',
// When expandable is on, optionally hide the collapse link so text can only be expanded. (Used for toast notifications.)
hideCollapse: '=',
keywords: '=highlightKeywords', // optional keywords to highlight using the `highlightKeywords` filter keywords: '=highlightKeywords', // optional keywords to highlight using the `highlightKeywords` filter
prettifyJson: '=' // prettifies JSON blobs when expanded, only used if expandable is true prettifyJson: '=' // prettifies JSON blobs when expanded, only used if expandable is true
}, },
......
...@@ -25,6 +25,18 @@ angular.module('openshiftCommonUI').provider('NotificationsService', function() ...@@ -25,6 +25,18 @@ angular.module('openshiftCommonUI').provider('NotificationsService', function()
notifications.push(notification); notifications.push(notification);
}; };
var hideNotification = function (notificationID) {
if (!notificationID) {
return;
}
_.each(notifications, function(notification) {
if (notification.id === notificationID) {
notification.hidden = true;
}
});
};
var getNotifications = function () { var getNotifications = function () {
return notifications; return notifications;
}; };
...@@ -59,9 +71,7 @@ angular.module('openshiftCommonUI').provider('NotificationsService', function() ...@@ -59,9 +71,7 @@ angular.module('openshiftCommonUI').provider('NotificationsService', function()
}; };
var isAutoDismiss = function(notification) { var isAutoDismiss = function(notification) {
return _.find(autoDismissTypes, function(type) { return _.includes(autoDismissTypes, notification.type);
return type === notification.type;
});
}; };
// Also handle `addNotification` events on $rootScope, which is used by DataService. // Also handle `addNotification` events on $rootScope, which is used by DataService.
...@@ -71,6 +81,7 @@ angular.module('openshiftCommonUI').provider('NotificationsService', function() ...@@ -71,6 +81,7 @@ angular.module('openshiftCommonUI').provider('NotificationsService', function()
return { return {
addNotification: addNotification, addNotification: addNotification,
hideNotification: hideNotification,
getNotifications: getNotifications, getNotifications: getNotifications,
clearNotifications: clearNotifications, clearNotifications: clearNotifications,
isNotificationPermanentlyHidden: isNotificationPermanentlyHidden, isNotificationPermanentlyHidden: isNotificationPermanentlyHidden,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment