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

Web port of the react native edit transaction view #1340

Merged
merged 42 commits into from
Aug 8, 2023
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
32e8f95
Add non-functional port of the RN edit transaction component
Cldfire Jul 6, 2023
86dd5a6
Working buttons and functional input fields
Cldfire Jul 6, 2023
9c8cea9
Stop using location state to pass transactions to edit component
Cldfire Jul 6, 2023
0dfd392
Remove add transaction from toolbar
Cldfire Jul 6, 2023
000dbc4
Start using edit field modal
Cldfire Jul 7, 2023
2484281
Lots of UI improvements
Cldfire Jul 7, 2023
60578a2
Implement adding transactions from transactions list
Cldfire Jul 7, 2023
ba9df74
Stop edit field modal from closing on blur
Cldfire Jul 8, 2023
df94fa0
Set `role="button"` on downshift autocomplete items
Cldfire Jul 9, 2023
1263062
userSelect: none some things
Cldfire Jul 10, 2023
2d5b293
Fix amount input styling
Cldfire Jul 10, 2023
de9436a
Fix cleared checkbox
Cldfire Jul 10, 2023
f28d2a6
Improve autocomplete styling
Cldfire Jul 12, 2023
3541eba
Improve modal layout
Cldfire Jul 12, 2023
37569fd
Fix routing when loading URLs directly
Cldfire Jul 12, 2023
1df5448
Add button for changing sign of transaction
Cldfire Jul 15, 2023
e3d2205
Disable split transaction editing for now
Cldfire Jul 15, 2023
12de3a0
Fix focus bug when adding transaction
Cldfire Jul 15, 2023
e79bc89
Add changelog entry
Cldfire Jul 15, 2023
ab31f7a
Fix lint error
Cldfire Jul 15, 2023
5e96cc2
Fix typecheck errors
Cldfire Jul 15, 2023
c3a7a63
Merge branch 'master' into jarek/port-rn-edit-transaction
Cldfire Jul 15, 2023
d795e8c
Address some feedback
Cldfire Jul 15, 2023
1e72984
Remove math support from MobileAmountInput
Cldfire Jul 15, 2023
754c574
Add back button to edit transaction card
Cldfire Jul 15, 2023
71c29a0
Remove mobile amount input context
Cldfire Jul 16, 2023
01d491c
Get rid of CSSStyleSheet usage
Cldfire Jul 16, 2023
2b5f390
Use actual minus symbol
Cldfire Jul 16, 2023
827802d
Address remaining review comments
Cldfire Jul 16, 2023
0c7a57e
Remove FocusableAmountInput wrapper
Cldfire Jul 16, 2023
f63fe97
Fix transaction table tests
Cldfire Jul 16, 2023
9c5d56e
Fix split transactions on desktop
Cldfire Jul 16, 2023
f430014
Fix layout when edit transaction view is vertically challenged
Cldfire Jul 31, 2023
3bc55d6
Change transaction edit / new routes
Cldfire Jul 31, 2023
b556ae1
Merge branch 'master' into jarek/port-rn-edit-transaction
Cldfire Jul 31, 2023
9077c18
Un-fix transaction table tests
Cldfire Jul 31, 2023
4ab9175
Fix bare buttons
Cldfire Jul 31, 2023
f92ef44
Fix navigation after transaction save / delete
Cldfire Jul 31, 2023
e6fc12a
Use native date picker for transaction editing on mobile devices
Cldfire Aug 3, 2023
81c511b
Merge branch 'master' into jarek/port-rn-edit-transaction
Cldfire Aug 7, 2023
2c84f76
Fix mobile account view
Cldfire Aug 7, 2023
5cfa762
Fix build after merging master
Cldfire Aug 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions packages/desktop-client/src/components/FinancesApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import LinkSchedule from './schedules/LinkSchedule';
import PostsOfflineNotification from './schedules/PostsOfflineNotification';
import Settings from './settings';
import Titlebar, { TitlebarProvider } from './Titlebar';
import { TransactionEdit } from './transactions/MobileTransaction';

function NarrowNotSupported({ children, redirectTo = '/budget' }) {
const { isNarrowWidth } = useResponsive();
Expand All @@ -65,6 +66,17 @@ function NarrowNotSupported({ children, redirectTo = '/budget' }) {
return isNarrowWidth ? null : children;
}

function WideNotSupported({ children, redirectTo = '/budget' }) {
trevdor marked this conversation as resolved.
Show resolved Hide resolved
const { isNarrowWidth } = useResponsive();
const navigate = useNavigate();
useEffect(() => {
if (!isNarrowWidth) {
navigate(redirectTo);
}
}, [isNarrowWidth, navigate, redirectTo]);
return isNarrowWidth ? children : null;
}

function StackedRoutesInner({ location }) {
const { isNarrowWidth } = useResponsive();
return (
Expand Down Expand Up @@ -149,6 +161,24 @@ function StackedRoutesInner({ location }) {
element={isNarrowWidth ? <MobileAccount /> : <Account />}
/>

<Route
path="/accounts/:id/:transactionId"
Cldfire marked this conversation as resolved.
Show resolved Hide resolved
element={
<WideNotSupported>
<TransactionEdit />
</WideNotSupported>
}
/>

<Route
path="/accounts/:id/new-transaction"
element={
<WideNotSupported>
<TransactionEdit />
</WideNotSupported>
}
/>

<Route
path="/accounts"
element={isNarrowWidth ? <MobileAccounts /> : <Account />}
Expand Down
16 changes: 2 additions & 14 deletions packages/desktop-client/src/components/accounts/MobileAccount.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import * as queries from 'loot-core/src/client/queries';
import { pagedQuery } from 'loot-core/src/client/query-helpers';
import { send, listen } from 'loot-core/src/platform/client/fetch';
import {
getSplit,
isPreviewId,
ungroupTransactions,
} from 'loot-core/src/shared/transactions';
Expand Down Expand Up @@ -179,7 +178,6 @@ function Account(props) {
setSearchText(text);
};

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const onSelectTransaction = transaction => {
if (isPreviewId(transaction.id)) {
let parts = transaction.id.split('/');
Expand Down Expand Up @@ -208,17 +206,7 @@ function Account(props) {
},
);
} else {
let trans = [transaction];
if (transaction.parent_id || transaction.is_parent) {
let index = transactions.findIndex(
t => t.id === (transaction.parent_id || transaction.id),
);
trans = getSplit(transactions, index);
}

navigate('Transaction', {
transactions: trans,
});
navigate(`${transaction.id}`);
}
};

Expand Down Expand Up @@ -263,7 +251,7 @@ function Account(props) {
paged && paged.fetchNext();
}}
onSearch={onSearch}
onSelectTransaction={() => {}} // onSelectTransaction}
onSelectTransaction={onSelectTransaction}
/>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export default function AccountDetails({
TODO: connect to an add transaction modal
Only left here but hidden for flex centering of the account name.
*/}
<Link to="transaction/new" style={{ visibility: 'hidden' }}>
<Link to="new-transaction">
<Button
bare
style={{ justifyContent: 'center', width: LEFT_RIGHT_FLEX_WIDTH }}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
import React from 'react';

import { css } from 'glamor';

import { useCachedAccounts } from 'loot-core/src/client/data-hooks/accounts';

import { useResponsive } from '../../ResponsiveProvider';
import { colors } from '../../style';
import { View } from '../common';

import Autocomplete from './Autocomplete';

function AccountList({ items, getItemProps, highlightedIndex, embedded }) {
function AccountList({
items,
getItemProps,
highlightedIndex,
embedded,
groupHeaderStyle,
}) {
let lastItem = null;
const { isNarrowWidth } = useResponsive();
const highlightedIndexColor = isNarrowWidth
? 'rgba(100, 100, 100, .15)'
: colors.n4;

return (
<View>
Expand Down Expand Up @@ -41,6 +54,7 @@ function AccountList({ items, getItemProps, highlightedIndex, embedded }) {
style={{
color: colors.y9,
padding: '4px 9px',
...groupHeaderStyle,
}}
data-testid="account-item-group"
>
Expand All @@ -49,14 +63,43 @@ function AccountList({ items, getItemProps, highlightedIndex, embedded }) {
) : null,
<div
{...(getItemProps ? getItemProps({ item }) : null)}
// Downshift calls `setTimeout(..., 250)` in the `onMouseMove`
// event handler they set on this element. When this code runs
// in WebKit on touch-enabled devices, taps on this element end
// up not triggering the `onClick` event (and therefore delaying
// response to user input) until after the `setTimeout` callback
// finishes executing. This is caused by content observation code
// that implements various strategies to prevent the user from
// accidentally clicking content that changed as a result of code
// run in the `onMouseMove` event.
//
// Long story short, we don't want any delay here between the user
// tapping and the resulting action being performed. It turns out
// there's some "fast path" logic that can be triggered in various
// ways to force WebKit to bail on the content observation process.
// One of those ways is setting `role="button"` (or a number of
// other aria roles) on the element, which is what we're doing here.
Cldfire marked this conversation as resolved.
Show resolved Hide resolved
//
// ref:
// * https://github.com/WebKit/WebKit/blob/447d90b0c52b2951a69df78f06bb5e6b10262f4b/LayoutTests/fast/events/touch/ios/content-observation/400ms-hover-intent.html
// * https://github.com/WebKit/WebKit/blob/58956cf59ba01267644b5e8fe766efa7aa6f0c5c/Source/WebCore/page/ios/ContentChangeObserver.cpp
// * https://github.com/WebKit/WebKit/blob/58956cf59ba01267644b5e8fe766efa7aa6f0c5c/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm#L783
role="button"
key={item.id}
style={{
backgroundColor:
highlightedIndex === idx ? colors.n4 : 'transparent',
padding: 4,
paddingLeft: 20,
borderRadius: embedded ? 4 : 0,
}}
className={`${css([
{
backgroundColor:
highlightedIndex === idx
? highlightedIndexColor
: 'transparent',
padding: 4,
paddingLeft: 20,
borderRadius: embedded ? 4 : 0,
':active': {
backgroundColor: 'rgba(100, 100, 100, .25)',
},
},
])}`}
data-testid={
'account-item' +
(highlightedIndex === idx ? '-highlighted' : '')
Expand All @@ -74,6 +117,8 @@ function AccountList({ items, getItemProps, highlightedIndex, embedded }) {
export default function AccountAutocomplete({
embedded,
includeClosedAccounts = true,
groupHeaderStyle,
closeOnBlur,
...props
}) {
let accounts = useCachedAccounts() || [];
Expand All @@ -97,13 +142,15 @@ export default function AccountAutocomplete({
strict={true}
highlightFirst={true}
embedded={embedded}
closeOnBlur={closeOnBlur}
suggestions={accounts}
renderItems={(items, getItemProps, highlightedIndex) => (
<AccountList
items={items}
getItemProps={getItemProps}
highlightedIndex={highlightedIndex}
embedded={embedded}
groupHeaderStyle={groupHeaderStyle}
/>
)}
{...props}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,28 @@ function defaultRenderItems(items, getItemProps, highlightedIndex) {
return (
<div
{...getItemProps({ item })}
// Downshift calls `setTimeout(..., 250)` in the `onMouseMove`
// event handler they set on this element. When this code runs
// in WebKit on touch-enabled devices, taps on this element end
// up not triggering the `onClick` event (and therefore delaying
// response to user input) until after the `setTimeout` callback
// finishes executing. This is caused by content observation code
// that implements various strategies to prevent the user from
// accidentally clicking content that changed as a result of code
// run in the `onMouseMove` event.
//
// Long story short, we don't want any delay here between the user
// tapping and the resulting action being performed. It turns out
// there's some "fast path" logic that can be triggered in various
// ways to force WebKit to bail on the content observation process.
// One of those ways is setting `role="button"` (or a number of
// other aria roles) on the element, which is what we're doing here.
//
// ref:
// * https://github.com/WebKit/WebKit/blob/447d90b0c52b2951a69df78f06bb5e6b10262f4b/LayoutTests/fast/events/touch/ios/content-observation/400ms-hover-intent.html
// * https://github.com/WebKit/WebKit/blob/58956cf59ba01267644b5e8fe766efa7aa6f0c5c/Source/WebCore/page/ios/ContentChangeObserver.cpp
// * https://github.com/WebKit/WebKit/blob/58956cf59ba01267644b5e8fe766efa7aa6f0c5c/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm#L783
role="button"
key={name}
{...css({
padding: 5,
Expand Down Expand Up @@ -140,6 +162,7 @@ type SingleAutocompleteProps = {
strict?: boolean;
onSelect: (id: unknown, value: string) => void;
tableBehavior?: boolean;
closeOnBlur?: boolean;
value: unknown[];
isMulti?: boolean;
};
Expand All @@ -164,6 +187,7 @@ function SingleAutocomplete({
strict,
onSelect,
tableBehavior,
closeOnBlur = true,
value: initialValue,
isMulti = false,
}: SingleAutocompleteProps) {
Expand Down Expand Up @@ -374,6 +398,8 @@ function SingleAutocomplete({
e.preventDownshiftDefault = true;
inputProps.onBlur && inputProps.onBlur(e);

if (!closeOnBlur) return;

if (!tableBehavior) {
if (e.target.value === '') {
onSelect && onSelect(null, e.target.value);
Expand Down
Loading
Loading