mirror of
https://github.com/actualbudget/actual.git
synced 2026-03-11 20:44:32 -05:00
🐛 Schedule table in Link Schedule modal is collapsed (#1501)
Co-authored-by: kyrias <johannes@kyriasis.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import { send } from 'loot-core/src/platform/client/fetch';
|
||||
|
||||
import { useActions } from '../hooks/useActions';
|
||||
import useSyncServerStatus from '../hooks/useSyncServerStatus';
|
||||
import { type CommonModalProps } from '../types/modals';
|
||||
|
||||
import BudgetSummary from './modals/BudgetSummary';
|
||||
import CloseAccount from './modals/CloseAccount';
|
||||
@@ -43,7 +44,7 @@ export default function Modals() {
|
||||
|
||||
let modals = modalStack
|
||||
.map(({ name, options }, idx) => {
|
||||
const modalProps = {
|
||||
const modalProps: CommonModalProps = {
|
||||
onClose: actions.popModal,
|
||||
onBack: actions.popModal,
|
||||
showBack: idx > 0,
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
|
||||
import { useSchedules } from 'loot-core/src/client/data-hooks/schedules';
|
||||
import { send } from 'loot-core/src/platform/client/fetch';
|
||||
|
||||
import Modal from '../common/Modal';
|
||||
import Search from '../common/Search';
|
||||
import Text from '../common/Text';
|
||||
import View from '../common/View';
|
||||
|
||||
import { SchedulesTable } from './SchedulesTable';
|
||||
|
||||
export default function ScheduleLink({
|
||||
modalProps,
|
||||
actions,
|
||||
transactionIds: ids,
|
||||
}) {
|
||||
let scheduleData = useSchedules(
|
||||
useCallback(query => query.filter({ completed: false }), []),
|
||||
);
|
||||
|
||||
let [filter, setFilter] = useState('');
|
||||
|
||||
if (scheduleData == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let { schedules, statuses } = scheduleData;
|
||||
|
||||
async function onSelect(scheduleId) {
|
||||
if (ids && ids.length > 0) {
|
||||
await send('transactions-batch-update', {
|
||||
updated: ids.map(id => ({ id, schedule: scheduleId })),
|
||||
});
|
||||
}
|
||||
actions.popModal();
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal title="Link Schedule" size="medium" {...modalProps}>
|
||||
<View
|
||||
style={{ flexDirection: 'row', marginBottom: 20, alignItems: 'center' }}
|
||||
>
|
||||
<Text>Choose a schedule to link these transactions to:</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
<Search
|
||||
isInModal
|
||||
width={300}
|
||||
placeholder="Filter schedules…"
|
||||
value={filter}
|
||||
onChange={setFilter}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<SchedulesTable
|
||||
schedules={schedules}
|
||||
filter={filter}
|
||||
statuses={statuses}
|
||||
minimal={true}
|
||||
onSelect={onSelect}
|
||||
tableStyle={{ marginInline: -20 }}
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
import React, { useCallback, useRef, useState } from 'react';
|
||||
|
||||
import { useSchedules } from 'loot-core/src/client/data-hooks/schedules';
|
||||
import { send } from 'loot-core/src/platform/client/fetch';
|
||||
import { type Query } from 'loot-core/src/shared/query';
|
||||
|
||||
import { type BoundActions } from '../../hooks/useActions';
|
||||
import { type CommonModalProps } from '../../types/modals';
|
||||
import Modal from '../common/Modal';
|
||||
import Search from '../common/Search';
|
||||
import Text from '../common/Text';
|
||||
import View from '../common/View';
|
||||
|
||||
import { ROW_HEIGHT, SchedulesTable } from './SchedulesTable';
|
||||
|
||||
export default function ScheduleLink({
|
||||
modalProps,
|
||||
actions,
|
||||
transactionIds: ids,
|
||||
}: {
|
||||
actions: BoundActions;
|
||||
modalProps?: CommonModalProps;
|
||||
transactionIds: string[];
|
||||
}) {
|
||||
let [filter, setFilter] = useState('');
|
||||
|
||||
let scheduleData = useSchedules({
|
||||
transform: useCallback((q: Query) => q.filter({ completed: false }), []),
|
||||
});
|
||||
|
||||
let searchInput = useRef(null);
|
||||
if (scheduleData == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let { schedules, statuses } = scheduleData;
|
||||
|
||||
async function onSelect(scheduleId: string) {
|
||||
if (ids?.length > 0) {
|
||||
await send('transactions-batch-update', {
|
||||
updated: ids.map(id => ({ id, schedule: scheduleId })),
|
||||
});
|
||||
}
|
||||
actions.popModal();
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal title="Link Schedule" size={{ width: 600 }} {...modalProps}>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
gap: 4,
|
||||
marginBottom: 20,
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<Text>
|
||||
Choose the schedule{' '}
|
||||
{ids?.length > 1
|
||||
? `these ${ids.length} transactions belong`
|
||||
: `this transaction belongs`}{' '}
|
||||
to:
|
||||
</Text>
|
||||
<Search
|
||||
inputRef={searchInput}
|
||||
isInModal
|
||||
width={300}
|
||||
placeholder="Filter schedules…"
|
||||
value={filter}
|
||||
onChange={setFilter}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View
|
||||
style={{
|
||||
marginTop: 15,
|
||||
flexBasis: (ROW_HEIGHT - 1) * (Math.max(schedules.length, 1) + 1),
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<SchedulesTable
|
||||
allowCompleted={false}
|
||||
filter={filter}
|
||||
minimal={true}
|
||||
onAction={() => {}}
|
||||
onSelect={onSelect}
|
||||
schedules={schedules}
|
||||
statuses={statuses}
|
||||
style={null}
|
||||
tableStyle={{ marginInline: -20 }}
|
||||
/>
|
||||
</View>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
@@ -12,7 +12,7 @@ type ActionReturnType<T extends (...args: unknown[]) => unknown> =
|
||||
? ReturnType
|
||||
: ReturnType<T>;
|
||||
|
||||
type BoundActions = {
|
||||
export type BoundActions = {
|
||||
[Key in keyof typeof actions]: (
|
||||
...args: Parameters<(typeof actions)[Key]>
|
||||
) => ActionReturnType<(typeof actions)[Key]>;
|
||||
|
||||
10
packages/desktop-client/src/types/modals.d.ts
vendored
Normal file
10
packages/desktop-client/src/types/modals.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import { type PopModalAction } from 'loot-core/src/client/state-types/modals';
|
||||
|
||||
export type CommonModalProps = {
|
||||
onClose: () => PopModalAction;
|
||||
onBack: () => PopModalAction;
|
||||
showBack: boolean;
|
||||
isCurrent: boolean;
|
||||
isHidden: boolean;
|
||||
stackIndex: number;
|
||||
};
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { createContext, useEffect, useState, useContext } from 'react';
|
||||
|
||||
import { type Query } from '../../shared/query';
|
||||
import { getStatus, getHasTransactionsQuery } from '../../shared/schedules';
|
||||
import q, { liveQuery } from '../query-helpers';
|
||||
|
||||
@@ -18,7 +19,7 @@ function loadStatuses(schedules, onData) {
|
||||
});
|
||||
}
|
||||
|
||||
type UseSchedulesArgs = { transform?: <T>(v: T) => T };
|
||||
type UseSchedulesArgs = { transform?: (q: Query) => Query };
|
||||
export function useSchedules({ transform }: UseSchedulesArgs = {}) {
|
||||
let [data, setData] = useState(null);
|
||||
|
||||
|
||||
6
upcoming-release-notes/1501.md
Normal file
6
upcoming-release-notes/1501.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: Bugfix
|
||||
authors: [trevdor]
|
||||
---
|
||||
|
||||
Fix collapsed schedules table in Link Schedule modal
|
||||
Reference in New Issue
Block a user