From d7b4da96a70eeffcf47f87caa3d960e9bc80f9db Mon Sep 17 00:00:00 2001 From: UnderKoen Date: Wed, 30 Oct 2024 22:14:49 +0100 Subject: [PATCH 1/8] enhance: context menu on sidebar account --- .../src/components/sidebar/Account.tsx | 118 +++++++++++++++++- 1 file changed, 114 insertions(+), 4 deletions(-) diff --git a/packages/desktop-client/src/components/sidebar/Account.tsx b/packages/desktop-client/src/components/sidebar/Account.tsx index 62985660a4f..60de74603de 100644 --- a/packages/desktop-client/src/components/sidebar/Account.tsx +++ b/packages/desktop-client/src/components/sidebar/Account.tsx @@ -1,8 +1,14 @@ // @ts-strict-ignore -import React, { type CSSProperties } from 'react'; +import React, { type CSSProperties, useEffect, useRef, useState } from 'react'; +import { useDispatch } from 'react-redux'; import { css, cx } from '@emotion/css'; +import { + openAccountCloseModal, + reopenAccount, + updateAccount, +} from 'loot-core/client/actions'; import * as Platform from 'loot-core/client/platform'; import { type AccountEntity } from 'loot-core/src/types/models'; @@ -10,6 +16,8 @@ import { useNotes } from '../../hooks/useNotes'; import { styles, theme } from '../../style'; import { AlignedText } from '../common/AlignedText'; import { Link } from '../common/Link'; +import { Menu } from '../common/Menu'; +import { Popover } from '../common/Popover'; import { Text } from '../common/Text'; import { Tooltip } from '../common/Tooltip'; import { View } from '../common/View'; @@ -23,6 +31,7 @@ import { } from '../sort'; import { type SheetFields, type Binding } from '../spreadsheet'; import { CellValue } from '../spreadsheet/CellValue'; +import { useFeatureFlag } from '../../hooks/useFeatureFlag'; export const accountNameStyle: CSSProperties = { marginTop: -2, @@ -74,6 +83,12 @@ export function Account>({ : 'account-onbudget' : 'title'; + const triggerRef = useRef(null); + const [menuOpen, setMenuOpen] = useState(false); + const contextMenusEnabled = useFeatureFlag('contextMenus'); + const [crossOffset, setCrossOffset] = useState(0); + const [offset, setOffset] = useState(0); + const { dragRef } = useDraggable({ type, onDragChange, @@ -87,12 +102,52 @@ export function Account>({ onDrop, }); + const dispatch = useDispatch(); + + const editingRef = useRef(null); + const [isEditing, setIsEditing] = useState(false); + useEffect(() => { + if (!editingRef.current) return; + if (isEditing) { + editingRef.current.focus(); + window.getSelection().selectAllChildren(editingRef.current); + } else { + editingRef.current.textContent = name; + } + }, [name, isEditing]); + + const updateName = () => { + if (account && isEditing) { + setIsEditing(false); + const newName = editingRef.current.textContent; + if (newName !== account.name && newName.trim()) { + dispatch( + updateAccount({ + ...account, + name: newName, + }), + ); + } + } + }; + const accountNote = useNotes(`account-${account?.id}`); const needsTooltip = !!account?.id; const accountRow = ( - - + { + if (!needsTooltip || !contextMenusEnabled) return; + e.preventDefault(); + const rect = e.currentTarget.getBoundingClientRect(); + setCrossOffset(e.clientX - rect.left); + setOffset(e.clientY - rect.bottom); + setMenuOpen(true); + }} + > + >({ paddingBottom: '3px', } } - left={name} + left={ + { + if (e.key === 'Enter') { + e.preventDefault(); + updateName(); + } else if (e.key === 'Escape') { + setIsEditing(false); + } + }} + > + {name} + + } right={} /> + {account && ( + setMenuOpen(false)} + style={{ width: 200, margin: 1 }} + isNonModal + crossOffset={crossOffset} + offset={offset} + > + { + switch (type) { + case 'close': { + dispatch(openAccountCloseModal(account.id)); + break; + } + case 'reopen': { + dispatch(reopenAccount(account.id)); + break; + } + case 'rename': { + setIsEditing(true); + break; + } + } + setMenuOpen(false); + }} + items={[ + { name: 'rename', text: 'Rename' }, + account.closed + ? { name: 'reopen', text: 'Reopen' } + : { name: 'close', text: 'Close' }, + ]} + /> + + )} From a3b24dabe3027d2417537fd845c59253529659cb Mon Sep 17 00:00:00 2001 From: UnderKoen Date: Wed, 30 Oct 2024 22:25:48 +0100 Subject: [PATCH 2/8] enhance: context menu on EditableBudgetName --- .../src/components/sidebar/Sidebar.tsx | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/packages/desktop-client/src/components/sidebar/Sidebar.tsx b/packages/desktop-client/src/components/sidebar/Sidebar.tsx index a70840622d0..e3fcfc29589 100644 --- a/packages/desktop-client/src/components/sidebar/Sidebar.tsx +++ b/packages/desktop-client/src/components/sidebar/Sidebar.tsx @@ -8,6 +8,7 @@ import { Resizable } from 're-resizable'; import { closeBudget, replaceModal } from 'loot-core/src/client/actions'; import * as Platform from 'loot-core/src/client/platform'; +import { useFeatureFlag } from '../../hooks/useFeatureFlag'; import { useGlobalPref } from '../../hooks/useGlobalPref'; import { useLocalPref } from '../../hooks/useLocalPref'; import { useMetadataPref } from '../../hooks/useMetadataPref'; @@ -166,6 +167,9 @@ function EditableBudgetName() { const [editing, setEditing] = useState(false); const [menuOpen, setMenuOpen] = useState(false); const triggerRef = useRef(null); + const contextMenusEnabled = useFeatureFlag('contextMenus'); + const [crossOffset, setCrossOffset] = useState(0); + const [offset, setOffset] = useState(0); function onMenuSelect(type: string) { setMenuOpen(false); @@ -218,7 +222,16 @@ function EditableBudgetName() { } return ( - <> + { + if (!contextMenusEnabled) return; + e.preventDefault(); + const rect = e.currentTarget.getBoundingClientRect(); + setCrossOffset(e.clientX - rect.left); + setOffset(e.clientY - rect.bottom); + setMenuOpen(true); + }} + >