-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Notification box for card limit (#3074)
* Notification box for card limit * Updating snapshots * adding notification box tests * Fix linter errors * Working on limits store * Implemeting the redux integration with the new limits * Refining store * Simplifying cards hidding/showing * Adding the secondary warning about hidding cards in other boards * Fixing tests * Fixed isLimited to limited * Fixing snooze of other boards hidden warning * Fixing linter error * Removing some unneeded coode * Moving limit logic to the cards selector * Changing the approach to limit cards * Fixing eslint errors Co-authored-by: Scott Bishel <scott.bishel@mattermost.com>
- Loading branch information
Showing
22 changed files
with
643 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||
// See LICENSE.txt for license information. | ||
import React, {useCallback, useEffect, useState} from 'react' | ||
import {useIntl, FormattedMessage} from 'react-intl' | ||
|
||
import AlertIcon from '../widgets/icons/alert' | ||
|
||
import {useAppSelector, useAppDispatch} from '../store/hooks' | ||
import {IUser, UserConfigPatch} from '../user' | ||
import {getMe, patchProps, getCardLimitSnoozeUntil, getCardHiddenWarningSnoozeUntil} from '../store/users' | ||
import {getHiddenByLimitCards, getCardHiddenWarning} from '../store/cards' | ||
import TelemetryClient, {TelemetryActions, TelemetryCategory} from '../telemetry/telemetryClient' | ||
import octoClient from '../octoClient' | ||
|
||
import NotificationBox from '../widgets/notification-box' | ||
import './cardLimitNotification.scss' | ||
|
||
const snoozeTime = 1000 * 60 * 60 * 24 * 10 | ||
const checkSnoozeInterval = 1000 * 60 * 5 | ||
|
||
const CardLimitNotification = () => { | ||
const intl = useIntl() | ||
const [time, setTime] = useState(Date.now()) | ||
|
||
const hiddenCards = useAppSelector<number>(getHiddenByLimitCards) | ||
const cardHiddenWarning = useAppSelector<boolean>(getCardHiddenWarning) | ||
const me = useAppSelector<IUser|null>(getMe) | ||
const snoozedUntil = useAppSelector<number>(getCardLimitSnoozeUntil) | ||
const snoozedCardHiddenWarningUntil = useAppSelector<number>(getCardHiddenWarningSnoozeUntil) | ||
const dispatch = useAppDispatch() | ||
|
||
const onCloseHidden = useCallback(async () => { | ||
if (me) { | ||
const patch: UserConfigPatch = { | ||
updatedFields: { | ||
focalboard_cardLimitSnoozeUntil: `${Date.now() + snoozeTime}`, | ||
}, | ||
} | ||
|
||
const patchedProps = await octoClient.patchUserConfig(me.id, patch) | ||
if (patchedProps) { | ||
dispatch(patchProps(patchedProps)) | ||
} | ||
} | ||
}, [me]) | ||
|
||
const onCloseWarning = useCallback(async () => { | ||
if (me) { | ||
const patch: UserConfigPatch = { | ||
updatedFields: { | ||
focalboard_cardHiddenWarningSnoozeUntil: `${Date.now() + snoozeTime}`, | ||
}, | ||
} | ||
|
||
const patchedProps = await octoClient.patchUserConfig(me.id, patch) | ||
if (patchedProps) { | ||
dispatch(patchProps(patchedProps)) | ||
} | ||
} | ||
}, [me]) | ||
|
||
let show = false | ||
let onClose = onCloseHidden | ||
let title = intl.formatMessage( | ||
{ | ||
id: 'notification-box-card-limit-reached.title', | ||
defaultMessage: '{cards} cards hidden from board', | ||
}, | ||
{cards: hiddenCards}, | ||
) | ||
|
||
if (hiddenCards > 0 && time > snoozedUntil) { | ||
show = true | ||
} | ||
|
||
if (!show && cardHiddenWarning) { | ||
show = time > snoozedCardHiddenWarningUntil | ||
onClose = onCloseWarning | ||
title = intl.formatMessage( | ||
{ | ||
id: 'notification-box-cards-hidden.title', | ||
defaultMessage: 'Your action hidden another card', | ||
}, | ||
) | ||
} | ||
|
||
useEffect(() => { | ||
if (!show) { | ||
const interval = setInterval(() => setTime(Date.now()), checkSnoozeInterval) | ||
return () => { | ||
clearInterval(interval) | ||
} | ||
} | ||
return () => null | ||
}, [show]) | ||
|
||
useEffect(() => { | ||
if (show) { | ||
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.LimitCardLimitReached, {}) | ||
} | ||
}, [show]) | ||
|
||
const onClick = useCallback(() => { | ||
// TODO: Show the modal to upgrade | ||
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.LimitCardLimitLinkOpen, {}) | ||
}, []) | ||
|
||
const hasPermissionToUpgrade = me?.roles?.split(' ').indexOf('system_admin') !== -1 | ||
|
||
if (!show) { | ||
return null | ||
} | ||
|
||
return ( | ||
<NotificationBox | ||
icon={<AlertIcon/>} | ||
title={title} | ||
onClose={onClose} | ||
closeTooltip={intl.formatMessage({ | ||
id: 'notification-box-card-limit-reached.close-tooltip', | ||
defaultMessage: 'Snooze for 10 days', | ||
})} | ||
> | ||
{hasPermissionToUpgrade && | ||
<FormattedMessage | ||
id='notification-box.card-limit-reached.text' | ||
defaultMessage='Card limit reached, to view older cards, {link}' | ||
values={{ | ||
link: ( | ||
<a | ||
onClick={onClick} | ||
> | ||
<FormattedMessage | ||
id='notification-box-card-limit-reached.link' | ||
defaultMessage='upgrade to a paid plan' | ||
/> | ||
</a>), | ||
}} | ||
/>} | ||
{!hasPermissionToUpgrade && | ||
<FormattedMessage | ||
id='notification-box.card-limit-reached.not-admin.text' | ||
defaultMessage='To access archived cards, contact your admin to upgrade to a paid plan.' | ||
/>} | ||
</NotificationBox> | ||
) | ||
} | ||
|
||
export default React.memo(CardLimitNotification) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,4 +74,11 @@ | |
position: relative; | ||
flex: 0 0 auto; | ||
} | ||
|
||
.NotificationBox { | ||
.AlertIcon { | ||
color: #ffbc1f; | ||
font-size: 24px; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.