diff --git a/src/2-pages/Budgets/EnvelopeTable/Row/AvailableCell.tsx b/src/2-pages/Budgets/EnvelopeTable/Row/AvailableCell.tsx index 84330e93..98bbc86f 100644 --- a/src/2-pages/Budgets/EnvelopeTable/Row/AvailableCell.tsx +++ b/src/2-pages/Budgets/EnvelopeTable/Row/AvailableCell.tsx @@ -1,25 +1,45 @@ -import React, { FC } from 'react' +import React, { FC, useCallback, useState } from 'react' import { useDraggable } from '@dnd-kit/core' -import { Typography, Box } from '@mui/material' +import { Typography, Box, Popover, Stack, IconButton } from '@mui/material' import { useTranslation } from 'react-i18next' import { Tooltip } from '6-shared/ui/Tooltip' import { formatMoney } from '6-shared/helpers/money' -import { WarningIcon } from '6-shared/ui/Icons' +import { WarningIcon, MoreHorizIcon } from '6-shared/ui/Icons' import { Amount } from '6-shared/ui/Amount' +import { userSettingsModel } from '5-entities/userSettings' import { DragTypes } from '2-pages/Budgets/DnD' +import { useIsSmall } from '../shared/shared' type AvailableCellProps = { id: string hiddenOverspend?: number available: number budgeted: number + activity: number isChild?: boolean isSelf?: boolean + onBudgetClick: (e: React.MouseEvent) => void + onActivityClick: (e: React.MouseEvent) => void } export const AvailableCell: FC = props => { - const { hiddenOverspend, id, available, isChild, budgeted, isSelf } = props - const { t } = useTranslation('budgets') + const { + hiddenOverspend, + id, + available, + isChild, + budgeted, + activity, + isSelf, + onBudgetClick, + onActivityClick, + } = props + const { t } = useTranslation(['budgets', 'common']) + const isSmall = useIsSmall() + const { showExtraCellMenu } = userSettingsModel.useUserSettings() + const [popoverAnchor, setPopoverAnchor] = useState(null) + const showPopoverIcon = isSmall && showExtraCellMenu + const availableColor = getAvailableColor( available, isChild, @@ -27,8 +47,35 @@ export const AvailableCell: FC = props => { isSelf ) + const handleOpenPopover = useCallback( + (e: React.MouseEvent) => { + e.stopPropagation() + setPopoverAnchor(e.currentTarget) + }, + [] + ) + + const handleClosePopover = useCallback(() => { + setPopoverAnchor(null) + }, []) + return ( - + + {showPopoverIcon && ( + + + + )} + {!!hiddenOverspend && ( = props => { mx: -2, py: 0.5, my: -0.5, - component: 'span', display: 'inline-block', color: availableColor, }} @@ -66,6 +112,86 @@ export const AvailableCell: FC = props => { + + + + { + handleClosePopover() + onBudgetClick(e) + }} + sx={{ + display: 'flex', + justifyContent: 'space-between', + gap: 2, + px: 1, + py: 0.5, + borderRadius: 1, + cursor: 'pointer', + '&:hover': { bgcolor: 'action.hover' }, + '&:active': { bgcolor: 'action.focus' }, + }} + > + + {t('budget', { ns: 'common' })} + + + + + + { + handleClosePopover() + onActivityClick(e) + }} + sx={{ + display: 'flex', + justifyContent: 'space-between', + gap: 2, + px: 1, + py: 0.5, + borderRadius: 1, + cursor: 'pointer', + '&:hover': { bgcolor: 'action.hover' }, + '&:active': { bgcolor: 'action.focus' }, + }} + > + + {t('activity', { ns: 'common' })} + + + + + + + ) } diff --git a/src/2-pages/Budgets/EnvelopeTable/Row/Row.tsx b/src/2-pages/Budgets/EnvelopeTable/Row/Row.tsx index be067f97..b79475de 100644 --- a/src/2-pages/Budgets/EnvelopeTable/Row/Row.tsx +++ b/src/2-pages/Budgets/EnvelopeTable/Row/Row.tsx @@ -130,7 +130,10 @@ export const Row: FC = props => { available={available} isChild={isChild} budgeted={budgeted} + activity={activity} isSelf={isSelf} + onBudgetClick={e => openBudgetPopover(id, e.currentTarget)} + onActivityClick={() => openTransactionsPopover(id)} /> } goal={ diff --git a/src/3-widgets/Navigation/SettingsMenu.tsx b/src/3-widgets/Navigation/SettingsMenu.tsx index def053fa..608cd5e7 100644 --- a/src/3-widgets/Navigation/SettingsMenu.tsx +++ b/src/3-widgets/Navigation/SettingsMenu.tsx @@ -87,6 +87,7 @@ const Settings = (props: { onClose: () => void; showLinks?: boolean }) => { {isExpanded ? ( <> + ) : ( @@ -290,6 +291,31 @@ function IconModeItem() { ) } +function ExtraCellMenuItem() { + const { t } = useTranslation('settings') + const dispatch = useAppDispatch() + const { showExtraCellMenu } = userSettingsModel.useUserSettings() + const handleClick = () => { + sendEvent( + `Settings: showExtraCellMenu ${showExtraCellMenu ? 'off' : 'on'}` + ) + dispatch( + userSettingsModel.patch({ + showExtraCellMenu: !showExtraCellMenu, + }) + ) + } + return ( + + + + + {t('extraCellMenu')} + + + ) +} + function BudgetSettingsItem() { const { t } = useTranslation('settings') const dispatch = useAppDispatch() diff --git a/src/5-entities/userSettings/userSettings.ts b/src/5-entities/userSettings/userSettings.ts index 06009e49..f101e6f0 100644 --- a/src/5-entities/userSettings/userSettings.ts +++ b/src/5-entities/userSettings/userSettings.ts @@ -15,6 +15,9 @@ export type TUserSettings = { /** Use SVG icons instead of emoji for tags/categories */ emojiIcons: boolean + + /** Shows a popover icon on mobile to access hidden budget/activity columns */ + showExtraCellMenu: boolean } export type TUserSettingsPatch = Partial export type TStoredUserSettings = Partial @@ -30,6 +33,7 @@ export const getUserSettings: TSelector = createSelector( sawMigrationAlert: raw.sawMigrationAlert ?? false, preferZmBudgets: raw.preferZmBudgets ?? false, emojiIcons: raw.emojiIcons ?? false, + showExtraCellMenu: raw.showExtraCellMenu ?? false, }) ) diff --git a/src/6-shared/localization/translations/en.ts b/src/6-shared/localization/translations/en.ts index 2c98bd4b..c2c5d9ef 100644 --- a/src/6-shared/localization/translations/en.ts +++ b/src/6-shared/localization/translations/en.ts @@ -452,6 +452,7 @@ export const en: typeof ru = { regularSync: 'Auto-sync', useIcons: 'Use icons', useEmojis: 'Use emojis', + extraCellMenu: 'Сell menu for small screens', useZmBudgets: 'Zenmoney budgets', useZmBudgetsDescription: 'Use the same budgets as Zenmoney', convertBudgetsFromZm: 'Convert budgets from Zenmoney', diff --git a/src/6-shared/localization/translations/ru.json b/src/6-shared/localization/translations/ru.json index 7eb070ae..6e5775dd 100644 --- a/src/6-shared/localization/translations/ru.json +++ b/src/6-shared/localization/translations/ru.json @@ -432,6 +432,7 @@ "regularSync": "Автосинхронизация", "useIcons": "Использовать иконки", "useEmojis": "Использовать эмодзи", + "extraCellMenu": "Mеню ячеек для маленьких экранов", "useZmBudgets": "Бюджеты Дзен-мани", "useZmBudgetsDescription": "Использовать те же бюджеты что и ДМ", "convertBudgetsFromZm": "Конвертировать бюджеты из Дзен-мани",