diff --git a/pkg/webui/console/containers/notifications/index.js b/pkg/webui/console/containers/notifications/index.js index c6f773666e7..4de613aa71f 100644 --- a/pkg/webui/console/containers/notifications/index.js +++ b/pkg/webui/console/containers/notifications/index.js @@ -73,16 +73,16 @@ const Notifications = () => { const [fetching, setFetching] = useState(false) const loadNextPage = useCallback( - async (startIndex, stopIndex) => { + async (startIndex, stopIndex, archived) => { if (fetching) return setFetching(true) + const composedArchived = + archived === undefined ? showArchived === 'true' : archived === 'true' // Determine filters based on whether archived notifications should be shown. - const filters = - showArchived === 'true' - ? ['NOTIFICATION_STATUS_ARCHIVED'] - : ['NOTIFICATION_STATUS_UNSEEN', 'NOTIFICATION_STATUS_SEEN'] - + const filters = composedArchived + ? ['NOTIFICATION_STATUS_ARCHIVED'] + : ['NOTIFICATION_STATUS_UNSEEN', 'NOTIFICATION_STATUS_SEEN'] // Calculate the number of items to fetch. const limit = Math.max(BATCH_SIZE, stopIndex - startIndex + 1) const [startPage, stopPage] = indicesToPage(startIndex, stopIndex, limit) @@ -121,16 +121,20 @@ const Notifications = () => { [fetching, showArchived, dispatch, userId, items, selectedNotification], ) - const handleShowArchived = useCallback(() => { + const handleShowArchived = useCallback(async () => { // Toggle the showArchived state. - setShowArchived(showArchived === 'false' ? 'true' : 'false') - + const newShowArchivedValue = showArchived === 'false' ? 'true' : 'false' + await setShowArchived(newShowArchivedValue) // Reset items and selected notification. setItems([]) setSelectedNotification(undefined) // Load the first page of archived notifications. - loadNextPage(0, BATCH_SIZE) + // When handleShowArchived is defined, it captures the current value of showArchived. + // Even though showArchived is updated later, the captured value inside handleShowArchived remains the same. + // So loadNextPage() is called with the old value of showArchived, showing the same notifications again. + // To avoid this, we pass the new value of showArchived to loadNextPage() as an argument. + loadNextPage(0, BATCH_SIZE, newShowArchivedValue) }, [loadNextPage, setShowArchived, showArchived]) const handleArchive = useCallback( diff --git a/pkg/webui/console/containers/notifications/notification-list/index.js b/pkg/webui/console/containers/notifications/notification-list/index.js index 6d89fa43926..c078007babe 100644 --- a/pkg/webui/console/containers/notifications/notification-list/index.js +++ b/pkg/webui/console/containers/notifications/notification-list/index.js @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React, { useCallback, useEffect, useRef } from 'react' +import React, { useCallback } from 'react' import { useDispatch, useSelector } from 'react-redux' import classNames from 'classnames' import { defineMessages } from 'react-intl' @@ -28,7 +28,6 @@ import Message from '@ttn-lw/lib/components/message' import attachPromise from '@ttn-lw/lib/store/actions/attach-promise' import PropTypes from '@ttn-lw/lib/prop-types' import sharedMessages from '@ttn-lw/lib/shared-messages' -import combineRefs from '@ttn-lw/lib/combine-refs' import { updateNotificationStatus } from '@console/store/actions/notifications' @@ -59,7 +58,7 @@ const NotificationList = ({ const totalUnseenCount = useSelector(selectTotalUnseenCount) const dispatch = useDispatch() const isItemLoaded = useCallback( - index => !hasNextPage || index < items.length, + index => (items.length > 0 ? !hasNextPage || index < items.length : false), [hasNextPage, items], ) const itemCount = totalCount || 100 @@ -145,7 +144,7 @@ const NotificationList = ({ { const unseenIds = useSelector(selectUnseenIds) const showSelected = selectedNotification?.id === notification.id - const classes = classNames(style.notificationPreview, 'm-0', { + const showUnseenStatus = unseenIds.includes(notification.id) + const classes = classNames(style.notificationPreview, 'm-0 d-flex', { [style.notificationSelected]: showSelected, }) const titleClasses = classNames(style.notificationPreviewTitle, { + [style.notificationRead]: !showUnseenStatus, [style.notificationSelected]: showSelected, }) const previewClasses = classNames(style.notificationPreviewContent, { + [style.notificationRead]: !showUnseenStatus, [style.notificationSelected]: showSelected, }) - const showUnseenStatus = unseenIds.includes(notification.id) return ( ) } diff --git a/pkg/webui/console/containers/notifications/notifications.styl b/pkg/webui/console/containers/notifications/notifications.styl index 869da044b3b..c7423abf621 100644 --- a/pkg/webui/console/containers/notifications/notifications.styl +++ b/pkg/webui/console/containers/notifications/notifications.styl @@ -16,15 +16,14 @@ display: flex flex-direction: column border-right: 1px solid rgba(0, 0, 0, 0.09) - min-width: 10rem - max-width: 30rem width: 33% &-change-button display: flex align-self: center width: fit-content - margin-top $cs.m + margin-top: $cs.m + margin-bottom: $cs.m color: $c.tts-primary !important &.notification-selected @@ -37,7 +36,7 @@ justify-content: space-between align-items: center border-bottom: 1px solid rgba(0, 0, 0, 0.09) - padding: $cs.m + padding: $cs.m $cs.s &-date color: $c.grey-700 @@ -88,7 +87,7 @@ font-size: 3rem .notification-preview - height: 6.286rem + height: 7rem width: 100% border-bottom: 1px solid rgba(0, 0, 0, 0.09) padding: $cs.m @@ -104,6 +103,9 @@ margin-bottom: $cs.xs font-weight: 600 + &.notification-read + margin-left: 0.857rem + &.notification-selected color: $c.white +media-query($bp.s) @@ -122,7 +124,6 @@ text-overflow: ellipsis &-content - width: 100% color: $c.grey-700 overflow: hidden display: -webkit-box @@ -131,6 +132,9 @@ white-space: pre-wrap font-size: $fs.s + &.notification-read + margin-left: 0.857rem + &.notification-selected color: white +media-query($bp.s)