Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhance: context menu on sidebar elements #3777

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
109 changes: 105 additions & 4 deletions packages/desktop-client/src/components/sidebar/Account.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
// @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';

import { useContextMenu } from '../../hooks/useContextMenu';
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';
Expand Down Expand Up @@ -74,6 +83,10 @@ export function Account<FieldName extends SheetFields<'account'>>({
: 'account-onbudget'
: 'title';

const triggerRef = useRef(null);
const { setMenuOpen, menuOpen, handleContextMenu, position } =
useContextMenu();

const { dragRef } = useDraggable({
type,
onDragChange,
Expand All @@ -87,12 +100,45 @@ export function Account<FieldName extends SheetFields<'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 = (
<View innerRef={dropRef} style={{ flexShrink: 0, ...outerStyle }}>
<View>
<View
innerRef={dropRef}
style={{ flexShrink: 0, ...outerStyle }}
onContextMenu={needsTooltip ? handleContextMenu : undefined}
>
<View innerRef={triggerRef}>
<DropHighlight pos={dropPos} />
<View innerRef={dragRef}>
<Link
Expand Down Expand Up @@ -158,10 +204,64 @@ export function Account<FieldName extends SheetFields<'account'>>({
paddingBottom: '3px',
}
}
left={name}
left={
<span
contentEditable={isEditing}
ref={editingRef}
suppressContentEditableWarning={true}
onBlur={updateName}
onKeyDown={e => {
if (e.key === 'Enter') {
e.preventDefault();
updateName();
} else if (e.key === 'Escape') {
setIsEditing(false);
}
}}
>
{name}
</span>
}
UnderKoen marked this conversation as resolved.
Show resolved Hide resolved
right={<CellValue binding={query} type="financial" />}
/>
</Link>
{account && (
<Popover
triggerRef={triggerRef}
placement="bottom start"
isOpen={menuOpen}
onOpenChange={() => setMenuOpen(false)}
style={{ width: 200, margin: 1 }}
isNonModal
{...position}
>
<Menu
onMenuSelect={type => {
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' },
]}
/>
</Popover>
)}
</View>
</View>
</View>
Expand Down Expand Up @@ -202,6 +302,7 @@ export function Account<FieldName extends SheetFields<'account'>>({
placement="right top"
triggerProps={{
delay: 1000,
isDisabled: menuOpen,
}}
>
{accountRow}
Expand Down
15 changes: 11 additions & 4 deletions packages/desktop-client/src/components/sidebar/BudgetName.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useDispatch } from 'react-redux';
import { closeBudget } from 'loot-core/src/client/actions';
import * as Platform from 'loot-core/src/client/platform';

import { useContextMenu } from '../../hooks/useContextMenu';
import { useMetadataPref } from '../../hooks/useMetadataPref';
import { useNavigate } from '../../hooks/useNavigate';
import { SvgExpandArrow } from '../../icons/v0';
Expand Down Expand Up @@ -54,9 +55,10 @@ function EditableBudgetName() {
const [budgetName, setBudgetNamePref] = useMetadataPref('budgetName');
const dispatch = useDispatch();
const navigate = useNavigate();
const [menuOpen, setMenuOpen] = useState(false);
const triggerRef = useRef<HTMLButtonElement>(null);
const [editing, setEditing] = useState(false);
const { setMenuOpen, menuOpen, handleContextMenu, resetPosition, position } =
useContextMenu();

function onMenuSelect(type: string) {
setMenuOpen(false);
Expand Down Expand Up @@ -106,7 +108,7 @@ function EditableBudgetName() {
}

return (
<>
<View onContextMenu={handleContextMenu}>
<Button
ref={triggerRef}
variant="bare"
Expand All @@ -117,7 +119,10 @@ function EditableBudgetName() {
marginLeft: -5,
flex: '0 auto',
}}
onPress={() => setMenuOpen(true)}
onPress={() => {
resetPosition();
setMenuOpen(true);
}}
>
<Text style={{ whiteSpace: 'nowrap', overflow: 'hidden' }}>
{budgetName || t('A budget has no name')}
Expand All @@ -134,9 +139,11 @@ function EditableBudgetName() {
placement="bottom start"
isOpen={menuOpen}
onOpenChange={() => setMenuOpen(false)}
style={{ margin: 1 }}
{...position}
>
<Menu onMenuSelect={onMenuSelect} items={items} />
</Popover>
</>
</View>
);
}
6 changes: 6 additions & 0 deletions upcoming-release-notes/3777.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
category: Enhancements
authors: [UnderKoen]
---

Add context menu's on the sidebar account names and the budget name at the top left.
Loading