-
Notifications
You must be signed in to change notification settings - Fork 356
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Notification drawer #6644
Notification drawer #6644
Conversation
@fhlavac Cannot add the following reviewer because they are not recognized: skateman Hyperkid123 martinpovolny |
@miq-bot add_reviewer @Hyperkid123 |
@miq-bot add_reviewer @martinpovolny |
@fhlavac to fix the Travis issues. You will have to delete tests for the old angular controllers. Also, there is a problem with dates in your snapshots. I think an update should be good enough. If it won't help just remove the snapshot. |
I like it even without looking at the code, my only concern is if the kebab context menu things are working as they used to work in the old implemenation. |
@skateman do we know how they suppose to work? Can the session thing be deleted? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this is what I have found so far.
const [isPanelExpanded, setPanelExpanded] = useState(true); | ||
const unreadCount = useSelector(({ notificationReducer: { unreadCount } }) => unreadCount); | ||
const notifications = useSelector(({ notificationReducer: { notifications } }) => notifications); | ||
const totalNotificationsCount = useSelector(({ notificationReducer: { totalNotificationsCount } }) => totalNotificationsCount); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
useSelector
can be used for multiple values. You don't need to call the hook each time you need something from the state.
const { isDrawerVisible, unreadCount } = useSelector(({ notificationReducer: { isDrawerVisible, unreadCount } }) => ({ isDrawerVisible, unreadCount )});
All state variables should probably use only one useSelector if possible.
const ToastList = () => { | ||
const dispatch = useDispatch(); | ||
const toastNotifications = useSelector(({ notificationReducer: { toastNotifications } }) => toastNotifications); | ||
const notificationTimerDelay = 8000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would define this constant outside of the component. If you leave it is at is, it will create a new variable for each notification which uses slightly more memory. It's not a big deal but its a good practice.
className="nav-item-iconic drawer-pf-trigger-icon" | ||
title={`${unreadCount} ${__('unread notifications')}`} | ||
onClick={() => { | ||
dispatch({ type: '@@notifications/toggleDrawerVisibility' }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should move this string to a constant somewhere.
"type": "success", | ||
"unread": true | ||
} | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing newline at the end of the file
"seen": false, | ||
"href": "http://localhost:3000/api/notifications/10000000017255" | ||
}] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^^
package.json
Outdated
@@ -63,7 +63,7 @@ | |||
"moment-strftime": "~0.5.0", | |||
"moment-timezone": "~0.5.21", | |||
"numeral": "~2.0.6", | |||
"patternfly": "~3.59.1", | |||
"patternfly": "~3.59.4", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you revert it back to the original version? I think this upgrade did not help anything.
What do you mean? |
const { | ||
isDrawerVisible, unreadCount, notifications, totalNotificationsCount, maxNotifications, | ||
} = useSelector(({ | ||
notificationReducer: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a lot of extra code duplications. If you have a use case like this, when you are basically consuming the whole state, you can just return the whole object and destruct it only in one place:
const {
isDrawerVisible, unreadCount, notifications, totalNotificationsCount, maxNotifications,
} = useSelector(({ notificationReducer }) => notificationReducer)
dispatch(toggleMaxNotifications()) | ||
} | ||
> | ||
{ maxNotifications ? __('Show all (may take a while)') : __(`Show only the first ${maxNotificationsConstant}`)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not going to work. Get text translation (the __() function) does not work with es6 template strings. You should use sprintf
if you want to use variables in translations.
__(`Show only the first ${maxNotificationsConstant}`) => sprintf(__(Show only the first %s'), maxNotificationsConstant)
const Notifications = () => { | ||
const dispatch = useDispatch(); | ||
const isDrawerVisible = useSelector(({ notificationReducer: { isDrawerVisible } }) => isDrawerVisible); | ||
const unreadCount = useSelector(({ notificationReducer: { unreadCount } }) => unreadCount); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^^ use only one useSelector
}; | ||
|
||
export default connect(mapStateToProps)(Notifications); | ||
export default (Notifications); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for extra brackets
maxNotifications, | ||
}; | ||
|
||
beforeEach(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
empty setup and clean callbacks
b2e5c95
to
f0101d0
Compare
f0101d0
to
64426f5
Compare
@skateman Displaying both doesn't make sense but in the angular implementation drawer and toast notifications were displayed at the same time as well... maybe it is a bug... |
<Drawer.Title | ||
title={drawerTitle} | ||
onCloseClick={() => dispatch(toggleDrawerVisibility())} | ||
onExpandClick={() => { setDrawerExpanded(!isDrawerExpanded); }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need for extra block around one-line function.
onExpandClick={() => setDrawerExpanded(!isDrawerExpanded)}
<a | ||
id="eventsExpander" | ||
className={classnames({ collapsed: !isPanelExpanded })} | ||
onClick={() => { setPanelExpanded(!isPanelExpanded); }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^^
64426f5
to
8f5f961
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@skateman is the functionality OK?
Yeah, except of the toasts, but we can address that in a future PR. There are multiple possible refactoring points in the area. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
8f5f961
to
88664a3
Compare
Checked commits fhlavac/manageiq-ui-classic@4f6059b~...88664a3 with ruby 2.5.5, rubocop 0.69.0, haml-lint 0.20.0, and yamllint 1.10.0 |
@@ -64,3 +65,5 @@ miqOptimizationInit(); | |||
|
|||
import * as move from '../helpers/move.js'; | |||
ManageIQ.move = move; | |||
|
|||
ManageIQ.redux.store.dispatch(initNotifications(true)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is causing an API request on the login screen, causing a browser login popup.
EDIT: fixing in #6689
Notification drawer → React
A number of all user's notifications is now fetched using a separate API request since data GET request returns a wrong COUNT - it should be fixed after ManageIQ/manageiq-api#726
I'm not sure about displaying all the necessary attributes in toast notifications (especially the link).
@skateman, could you please check it?