Notifications fixes

* move NotificationsToaster into App.js to use it only ince in the app
* remove visual properties (dismissable, timeoutable) from notification record
* don't auto hide 'error' type notifications, so they don't vanish before
  user reads them
* render NotificationsToaster above modals
* use up to date patternfly class for NotificationsToaster so the messages
  don't disappear when view is scrolled (position fixed vs absolute)

Closes-Bug: 1674361
Closes-Bug: 1647705
Change-Id: I9fce702fd104aa31daf5991e6683fde586b3f0cb
This commit is contained in:
Jiri Tomasek 2017-07-26 23:11:11 +02:00 committed by Honza Pokorny
parent 0b5a88a348
commit 66776fd1af
8 changed files with 36 additions and 34 deletions

View File

@ -18,15 +18,19 @@ import React from 'react';
import { Route, Switch } from 'react-router-dom';
import Login from './login/Login';
import NotificationsToaster from './notifications/NotificationsToaster';
import UserAuthenticator from './UserAuthenticator';
export default class App extends React.Component {
render() {
return (
<Switch>
<Route path="/login" component={Login} />
<Route path="/" component={UserAuthenticator} />
</Switch>
<div>
<NotificationsToaster />
<Switch>
<Route path="/login" component={Login} />
<Route path="/" component={UserAuthenticator} />
</Switch>
</div>
);
}
}

View File

@ -23,7 +23,6 @@ import { Redirect } from 'react-router-dom';
import AuthenticatedContent from './AuthenticatedContent';
import Loader from './ui/Loader';
import LoginActions from '../actions/LoginActions';
import NotificationsToaster from './notifications/NotificationsToaster';
const messages = defineMessages({
authenticating: {
@ -71,7 +70,6 @@ class UserAuthenticator extends React.Component {
>
<AuthenticatedContent />
</Loader>
<NotificationsToaster />
</div>
);
} else {

View File

@ -29,7 +29,6 @@ import Loader from '../ui/Loader';
import LoginInput from '../ui/forms/LoginInput';
import LanguageInput from './LanguageInput';
import LoginActions from '../../actions/LoginActions';
import NotificationsToaster from '../notifications/NotificationsToaster';
import LogoSvg from '../../../img/logo.svg';
import TripleoOwlSvg from '../../../img/tripleo-owl.svg';
@ -190,7 +189,6 @@ class Login extends React.Component {
</div>
</div>
</div>
<NotificationsToaster />
</div>
);
} else {

View File

@ -83,7 +83,7 @@ export default class Notification extends React.Component {
type="button"
className="close"
aria-label="Close"
onClick={this._hideNotification.bind(this)}
onClick={this.props.removeNotification}
>
<span className="pficon pficon-close" aria-hidden="true" />
</button>
@ -107,7 +107,9 @@ Notification.propTypes = {
};
Notification.defaultProps = {
dismissable: true,
message: '',
title: '',
timeoutable: true,
type: 'error'
};

View File

@ -49,13 +49,10 @@ class NotificationsToaster extends React.Component {
title={notification.title}
message={notification.message}
type={notification.type}
dismissable={notification.dismissable}
timeoutable={notification.timeoutable}
timeoutable={notification.type !== 'error'}
timerPaused={this.state.isHovered}
removeNotification={this.props.removeNotification.bind(
this,
notification.id
)}
removeNotification={() =>
this.props.removeNotification(notification.id)}
/>
);
});
@ -64,7 +61,7 @@ class NotificationsToaster extends React.Component {
render() {
return (
<div
className="toast-pf-max-width toast-pf-top-right"
className="toast-notifications-list-pf"
onMouseEnter={this._handleMouseEnter.bind(this)}
onMouseLeave={this._handleMouseLeave.bind(this)}
>

View File

@ -20,9 +20,7 @@ export const Notification = Record({
id: undefined,
title: '',
message: '',
type: 'error',
viewed: false,
dismissable: true,
timeoutable: true,
type: 'error',
timestamp: undefined
});

View File

@ -21,6 +21,6 @@ const notifications = state => state.notifications.get('all');
export const getNonViewedNotifications = createSelector(
notifications,
notifications => {
return notifications.filterNot(notification => notification.get('viewed'));
return notifications.filterNot(notification => notification.viewed);
}
);

View File

@ -19,7 +19,7 @@
// --------------------------------------------------
.login-pf {
background-color: @login-bg-color;
background-color: @login-bg-color;
@media (min-width: @screen-sm-min) {
background-image: url("../../img/bg-login-2.png");
background-position: 100% 100%;
@ -71,31 +71,33 @@
}
// this seems to work better than 'middle'
.badge { vertical-align: baseline; }
.badge {
vertical-align: baseline;
}
// Additional treeview styles not included in patternfly but included in patternfly's treeview example ?!?
.treeview {
.list-group-item {
cursor:pointer;
cursor: pointer;
}
span.indent {
margin-left:10px;
margin-right:10px;
margin-left: 10px;
margin-right: 10px;
}
span.icon {
width:12px;
margin-right:5px;
width: 12px;
margin-right: 5px;
}
.node-disabled {
color:silver;
cursor:not-allowed;
color: silver;
cursor: not-allowed;
}
}
.node-treeview1 {
border:none;
border: none;
}
.node-treeview1:not(.node-disabled):hover {
background-color:#F5F5F5;
background-color: #f5f5f5;
}
// Custom styles
@ -144,7 +146,7 @@
}
}
.navbar-pf .navbar-utility > li > a {
padding: 14px 10px;
padding: 14px 10px;
}
// blank slate doesn't have margin-top to match bottom for some reason
@ -152,7 +154,6 @@
margin-top: 20px;
}
// ListView
// remove those 2 when this issue is resolved https://github.com/patternfly/patternfly/issues/324
.list-view-pf-main-info {
@ -167,8 +168,12 @@
// white-space: normal;
// }
// Remove top margin from page-header if there are breadcrumbs above it
.breadcrumb + .page-header {
margin-top: 0;
}
// Notifications Toaster needs to lie over modals which are 1050
.toast-notifications-list-pf {
z-index: 1060;
}