mirror of
https://github.com/actualbudget/actual.git
synced 2026-03-09 11:42:54 -05:00
Compare commits
7 Commits
v25.5.0
...
UnderKoen/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
326e632e11 | ||
|
|
a55c21db27 | ||
|
|
4a4b512935 | ||
|
|
f2e8c40535 | ||
|
|
478840b34a | ||
|
|
8c158bcd63 | ||
|
|
ca9f62ac29 |
@@ -308,6 +308,7 @@ type AccountInternalProps = {
|
||||
hideFraction: boolean;
|
||||
accountsSyncing: string[];
|
||||
dispatch: AppDispatch;
|
||||
reconcileAmount: number | null;
|
||||
};
|
||||
type AccountInternalState = {
|
||||
search: string;
|
||||
@@ -369,12 +370,13 @@ class AccountInternal extends PureComponent<
|
||||
filterConditionsOp: 'and',
|
||||
loading: true,
|
||||
workingHard: false,
|
||||
reconcileAmount: null,
|
||||
reconcileAmount: props.reconcileAmount,
|
||||
transactions: [],
|
||||
transactionCount: 0,
|
||||
showBalances: props.showBalances,
|
||||
balances: null,
|
||||
showCleared: props.showCleared,
|
||||
showCleared: props.reconcileAmount == null ? props.showCleared : true,
|
||||
prevShowCleared: props.showCleared,
|
||||
showReconciled: props.showReconciled,
|
||||
editingName: false,
|
||||
nameError: '',
|
||||
@@ -474,6 +476,15 @@ class AccountInternal extends PureComponent<
|
||||
if (this.props.accountId !== prevProps.accountId) {
|
||||
this.setState({ sort: null, search: '', filterConditions: [] });
|
||||
}
|
||||
|
||||
if (this.props.reconcileAmount !== prevProps.reconcileAmount) {
|
||||
this.setState({
|
||||
reconcileAmount: this.props.reconcileAmount,
|
||||
showCleared:
|
||||
this.props.reconcileAmount == null ? this.props.showCleared : true,
|
||||
prevShowCleared: this.props.showCleared,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
@@ -2022,6 +2033,7 @@ export function Account() {
|
||||
categoryId={location?.state?.categoryId}
|
||||
location={location}
|
||||
savedFilters={savedFiters}
|
||||
reconcileAmount={location?.state?.reconcileAmount ?? null}
|
||||
/>
|
||||
</SplitsExpandedProvider>
|
||||
</SchedulesProvider>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// @ts-strict-ignore
|
||||
import React, { type CSSProperties, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { AlignedText } from '@actual-app/components/aligned-text';
|
||||
import { InitialFocus } from '@actual-app/components/initial-focus';
|
||||
@@ -12,15 +13,20 @@ import { Tooltip } from '@actual-app/components/tooltip';
|
||||
import { View } from '@actual-app/components/view';
|
||||
import { css, cx } from '@emotion/css';
|
||||
|
||||
import { openAccountCloseModal } from 'loot-core/client/actions';
|
||||
import {
|
||||
addNotification,
|
||||
openAccountCloseModal,
|
||||
} from 'loot-core/client/actions';
|
||||
import * as Platform from 'loot-core/client/platform';
|
||||
import {
|
||||
reopenAccount,
|
||||
updateAccount,
|
||||
} from 'loot-core/client/queries/queriesSlice';
|
||||
import { currencyToInteger } from 'loot-core/shared/util';
|
||||
import { type AccountEntity } from 'loot-core/types/models';
|
||||
|
||||
import { useContextMenu } from '../../hooks/useContextMenu';
|
||||
import { useNavigate } from '../../hooks/useNavigate';
|
||||
import { useNotes } from '../../hooks/useNotes';
|
||||
import { useDispatch } from '../../redux';
|
||||
import { Input } from '../common/Input';
|
||||
@@ -35,6 +41,8 @@ import {
|
||||
} from '../sort';
|
||||
import { type SheetFields, type Binding } from '../spreadsheet';
|
||||
import { CellValue } from '../spreadsheet/CellValue';
|
||||
import { useFormat } from '../spreadsheet/useFormat';
|
||||
import { useSheetValue } from '../spreadsheet/useSheetValue';
|
||||
|
||||
export const accountNameStyle: CSSProperties = {
|
||||
marginTop: -2,
|
||||
@@ -78,6 +86,8 @@ export function Account<FieldName extends SheetFields<'account'>>({
|
||||
onDragChange,
|
||||
onDrop,
|
||||
}: AccountProps<FieldName>) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const type = account
|
||||
? account.closed
|
||||
? 'account-closed'
|
||||
@@ -105,11 +115,16 @@ export function Account<FieldName extends SheetFields<'account'>>({
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
const [isEditingName, setIsEditingName] = useState(false);
|
||||
const [isEditingBalance, setIsEditingBalance] = useState(false);
|
||||
|
||||
const accountNote = useNotes(`account-${account?.id}`);
|
||||
const needsTooltip = !!account?.id;
|
||||
|
||||
const accountValue = useSheetValue(query);
|
||||
const navigate = useNavigate();
|
||||
const format = useFormat();
|
||||
|
||||
const accountRow = (
|
||||
<View
|
||||
innerRef={dropRef}
|
||||
@@ -122,7 +137,7 @@ export function Account<FieldName extends SheetFields<'account'>>({
|
||||
<Link
|
||||
variant="internal"
|
||||
to={to}
|
||||
isDisabled={isEditing}
|
||||
isDisabled={isEditingName}
|
||||
style={{
|
||||
...accountNameStyle,
|
||||
...style,
|
||||
@@ -184,14 +199,13 @@ export function Account<FieldName extends SheetFields<'account'>>({
|
||||
}
|
||||
}
|
||||
left={
|
||||
isEditing ? (
|
||||
isEditingName ? (
|
||||
<InitialFocus>
|
||||
<Input
|
||||
style={{
|
||||
padding: 0,
|
||||
width: '100%',
|
||||
}}
|
||||
onBlur={() => setIsEditing(false)}
|
||||
onBlur={() => setIsEditingName(false)}
|
||||
onEnter={e => {
|
||||
const inputEl = e.target as HTMLInputElement;
|
||||
const newAccountName = inputEl.value;
|
||||
@@ -205,9 +219,9 @@ export function Account<FieldName extends SheetFields<'account'>>({
|
||||
}),
|
||||
);
|
||||
}
|
||||
setIsEditing(false);
|
||||
setIsEditingName(false);
|
||||
}}
|
||||
onEscape={() => setIsEditing(false)}
|
||||
onEscape={() => setIsEditingName(false)}
|
||||
defaultValue={name}
|
||||
/>
|
||||
</InitialFocus>
|
||||
@@ -215,7 +229,44 @@ export function Account<FieldName extends SheetFields<'account'>>({
|
||||
name
|
||||
)
|
||||
}
|
||||
right={<CellValue binding={query} type="financial" />}
|
||||
right={
|
||||
isEditingBalance ? (
|
||||
<InitialFocus>
|
||||
<Input
|
||||
style={{
|
||||
width: '100%',
|
||||
textAlign: 'right',
|
||||
...styles.tnum,
|
||||
}}
|
||||
onBlur={() => setIsEditingBalance(false)}
|
||||
onEnter={e => {
|
||||
const inputEl = e.target as HTMLInputElement;
|
||||
const newValue = inputEl.value;
|
||||
if (newValue.trim() !== '') {
|
||||
const v = currencyToInteger(newValue);
|
||||
|
||||
if (v === accountValue) {
|
||||
dispatch(
|
||||
addNotification({
|
||||
type: 'message',
|
||||
message:
|
||||
'The new balance is the same as the current balance.',
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
navigate(to, { state: { reconcileAmount: v } });
|
||||
}
|
||||
}
|
||||
setIsEditingBalance(false);
|
||||
}}
|
||||
onEscape={() => setIsEditingBalance(false)}
|
||||
defaultValue={format(accountValue, 'financial')}
|
||||
/>
|
||||
</InitialFocus>
|
||||
) : (
|
||||
<CellValue binding={query} type="financial" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Link>
|
||||
{account && (
|
||||
@@ -240,17 +291,22 @@ export function Account<FieldName extends SheetFields<'account'>>({
|
||||
break;
|
||||
}
|
||||
case 'rename': {
|
||||
setIsEditing(true);
|
||||
setIsEditingName(true);
|
||||
break;
|
||||
}
|
||||
case 'reconcile': {
|
||||
setIsEditingBalance(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
setMenuOpen(false);
|
||||
}}
|
||||
items={[
|
||||
{ name: 'rename', text: 'Rename' },
|
||||
{ name: 'rename', text: t('Rename') },
|
||||
{ name: 'reconcile', text: t('Reconcile') },
|
||||
account.closed
|
||||
? { name: 'reopen', text: 'Reopen' }
|
||||
: { name: 'close', text: 'Close' },
|
||||
? { name: 'reopen', text: t('Reopen') }
|
||||
: { name: 'close', text: t('Close') },
|
||||
]}
|
||||
/>
|
||||
</Popover>
|
||||
|
||||
6
upcoming-release-notes/4252.md
Normal file
6
upcoming-release-notes/4252.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: Enhancements
|
||||
authors: [UnderKoen]
|
||||
---
|
||||
|
||||
Reconcile account on sidebar context menu
|
||||
Reference in New Issue
Block a user