diff --git a/src/assets/icons/icon-check-light.svg b/src/assets/icons/icon-check-light.svg
deleted file mode 100644
index 0c9a0f387..000000000
--- a/src/assets/icons/icon-check-light.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
diff --git a/src/components/ActionCard/CommentMobile.jsx b/src/components/ActionCard/CommentMobile.jsx
index dea0c764d..6a5104192 100644
--- a/src/components/ActionCard/CommentMobile.jsx
+++ b/src/components/ActionCard/CommentMobile.jsx
@@ -16,7 +16,7 @@ const CommentMobile = ({ messageId, author, date, children }) => {
const messageLink = window.location.pathname.substr(0, window.location.pathname.indexOf('#')) + `#comment-${messageId}`
return (
-
diff --git a/src/components/NotificationsDropdown/NotificationsDropdown.scss b/src/components/NotificationsDropdown/NotificationsDropdown.scss
index bbaaeb407..e8dab7488 100644
--- a/src/components/NotificationsDropdown/NotificationsDropdown.scss
+++ b/src/components/NotificationsDropdown/NotificationsDropdown.scss
@@ -56,24 +56,16 @@
width: 480px;
}
- .notifications-read-all {
- @include roboto;
- background-color: $tc-gray-neutral-light;
- border-top: 1px solid $tc-gray-10;
- color: $tc-gray-50;
- display: block;
- font-size: 12px;
- line-height: 40px;
- letter-spacing: 0;
- text-align: center;
- }
-
.notifications-empty {
- padding: 50px 0 60px;
+ justify-content: center;
+ display: flex;
+ height: 100%;
+ flex-direction: column;
+ padding: 0;
+ }
- .notification-settings {
- margin-top: 30px;
- }
+ .notifications-empty-note {
+ max-width: 270px;
}
}
}
diff --git a/src/components/NotificationsDropdown/NotificationsDropdownContainer.jsx b/src/components/NotificationsDropdown/NotificationsDropdownContainer.jsx
index e74a28ca1..bcf40caf9 100644
--- a/src/components/NotificationsDropdown/NotificationsDropdownContainer.jsx
+++ b/src/components/NotificationsDropdown/NotificationsDropdownContainer.jsx
@@ -7,20 +7,32 @@ import React from 'react'
import { Link } from 'react-router-dom'
import { connect } from 'react-redux'
import _ from 'lodash'
-import { getNotifications, visitNotifications, toggleNotificationSeen, markAllNotificationsRead, toggleNotificationRead, toggleBundledNotificationRead } from '../../routes/notifications/actions'
-import { splitNotificationsBySources, filterReadNotifications, limitQuantityInSources } from '../../routes/notifications/helpers/notifications'
+import { getNotifications, visitNotifications, toggleNotificationSeen, markAllNotificationsRead,
+ toggleNotificationRead, toggleBundledNotificationRead, viewOlderNotifications, toggleNotificationsDropdownMobile } from '../../routes/notifications/actions'
+import { splitNotificationsBySources, filterReadNotifications, limitQuantityInSources, filterOldNotifications } from '../../routes/notifications/helpers/notifications'
import NotificationsSection from '../NotificationsSection/NotificationsSection'
import NotificationsEmpty from '../NotificationsEmpty/NotificationsEmpty'
import NotificationsDropdownHeader from '../NotificationsDropdownHeader/NotificationsDropdownHeader'
import NotificationsDropdown from './NotificationsDropdown'
import NotificationsMobilePage from './NotificationsMobilePage'
+import NotificationsReadAll from './NotificationsReadAll'
import ScrollLock from 'react-scroll-lock-component'
import MediaQuery from 'react-responsive'
-import { NOTIFCATIONS_DROPDOWN_PER_SOURCE, NOTIFCATIONS_DROPDOWN_MAX_TOTAL, REFRESH_NOTIFICATIONS_INTERVAL } from '../../config/constants'
+import { NOTIFICATIONS_DROPDOWN_PER_SOURCE, NOTIFICATIONS_DROPDOWN_MAX_TOTAL, REFRESH_NOTIFICATIONS_INTERVAL, SCREEN_BREAKPOINT_MD } from '../../config/constants'
import './NotificationsDropdown.scss'
class NotificationsDropdownContainer extends React.Component {
+ constructor(props) {
+ super(props)
+
+ this.state = {
+ isViewAll: false
+ }
+
+ this.viewAll = this.viewAll.bind(this)
+ }
+
componentDidMount() {
this.props.getNotifications()
this.autoRefreshNotifications = setInterval(() => this.props.getNotifications(), REFRESH_NOTIFICATIONS_INTERVAL)
@@ -28,6 +40,23 @@ class NotificationsDropdownContainer extends React.Component {
componentWillUnmount() {
clearInterval(this.autoRefreshNotifications)
+ // hide notifications dropdown for mobile, when this component is unmounted
+ this.props.toggleNotificationsDropdownMobile(false)
+ }
+
+ componentWillReceiveProps(nextProps) {
+ const currentPathname = this.props.location.pathname
+ const nextPathname = nextProps.location.pathname
+
+ if (currentPathname !== nextPathname) {
+ // hide notifications dropdown for mobile,
+ // when this component persist but URL changed
+ this.props.toggleNotificationsDropdownMobile(false)
+ }
+ }
+
+ viewAll() {
+ this.setState({isViewAll: true})
}
render() {
@@ -35,7 +64,10 @@ class NotificationsDropdownContainer extends React.Component {
return
}
- const {lastVisited, sources, notifications, markAllNotificationsRead, toggleNotificationRead, toggleNotificationSeen, pending, toggleBundledNotificationRead, visitNotifications } = this.props
+ const {lastVisited, sources, notifications, markAllNotificationsRead, toggleNotificationRead, toggleNotificationSeen,
+ pending, toggleBundledNotificationRead, visitNotifications, oldSourceIds, viewOlderNotifications, isDropdownMobileOpen,
+ toggleNotificationsDropdownMobile } = this.props
+ const {isViewAll} = this.state
const getPathname = link => link.split(/[?#]/)[0].replace(/\/?$/, '')
// mark notifications with url mathc current page's url as seen
@@ -48,15 +80,26 @@ class NotificationsDropdownContainer extends React.Component {
}
const notReadNotifications = filterReadNotifications(notifications)
- const notificationsBySources = limitQuantityInSources(
- splitNotificationsBySources(sources, notReadNotifications),
- NOTIFCATIONS_DROPDOWN_PER_SOURCE,
- NOTIFCATIONS_DROPDOWN_MAX_TOTAL
- )
+ const notOldNotifications = filterOldNotifications(notReadNotifications, oldSourceIds)
+ const allNotificationsBySources = splitNotificationsBySources(sources, notOldNotifications)
+ let notificationsBySources
+
+ if (!isViewAll) {
+ notificationsBySources = limitQuantityInSources(
+ allNotificationsBySources,
+ NOTIFICATIONS_DROPDOWN_PER_SOURCE,
+ NOTIFICATIONS_DROPDOWN_MAX_TOTAL
+ )
+ } else {
+ notificationsBySources = allNotificationsBySources
+ }
+
+ const hiddenByLimitCount = _.sumBy(allNotificationsBySources, 'notifications.length') - _.sumBy(notificationsBySources, 'notifications.length')
+
const globalSource = notificationsBySources.length > 0 && notificationsBySources[0].id === 'global' ? notificationsBySources[0] : null
const projectSources = notificationsBySources.length > 1 && globalSource ? notificationsBySources.slice(1) : notificationsBySources
const hasUnread = notReadNotifications.length > 0
- const olderNotificationsCount = _.sumBy(projectSources, 'total') - _.sumBy(projectSources, 'notifications.length')
+ const olderNotificationsCount = notReadNotifications.length - notOldNotifications.length
// we have to give Dropdown component some time
// before removing notification item node from the list
// otherwise dropdown thinks we clicked outside and closes dropdown
@@ -75,18 +118,36 @@ class NotificationsDropdownContainer extends React.Component {
}
const hasNew = hasUnread && lastVisited < _.maxBy(_.map(notifications, n => new Date(n.date)))
+ const notificationsEmpty = (
+
+
+ Maybe you need to check your notification settings to
+ get up to date with the latest activity from your projects?
+
+
+ Notification Settings
+
+
+ )
+
+ // this function checks that notification is not seen yet,
+ // before marking it as seen
+ const markNotificationSeen = (notificationId) => {
+ const notification = _.find(notifications, { id: notificationId })
+
+ if (notification && !notification.seen) {
+ toggleNotificationSeen(notificationId)
+ }
+ }
+
return (
-
+
{(matches) => (matches ? (
!pending && markAllNotificationsRead()} hasUnread={hasUnread}/>
{!hasUnread ? (
-
-
- Notification Settings
-
-
+ {notificationsEmpty}
) : ([
@@ -96,8 +157,8 @@ class NotificationsDropdownContainer extends React.Component {
{...globalSource}
isGlobal
isSimple
- onReadToggleClick={document.body.classList.remove('noScroll'), toggleNotificationReadWithDelay}
- onLinkClick={toggleNotificationSeen}
+ onReadToggleClick={toggleNotificationReadWithDelay}
+ onLinkClick={markNotificationSeen}
/>
}
{projectSources.filter(source => source.notifications.length > 0).map(source => (
@@ -105,44 +166,64 @@ class NotificationsDropdownContainer extends React.Component {
{...source}
key={source.id}
isSimple
- onReadToggleClick={document.body.classList.remove('noScroll'), toggleNotificationReadWithDelay}
- onLinkClick={toggleNotificationSeen}
+ onReadToggleClick={toggleNotificationReadWithDelay}
+ onLinkClick={markNotificationSeen}
/>
))}
,
-