From 5686009ceecaec60e65bee4c764d618c7599b5ac Mon Sep 17 00:00:00 2001 From: SamBobBarnes Date: Mon, 20 Jan 2025 10:32:32 -0600 Subject: [PATCH 01/11] save button --- .../components/schedules/UpcomingLength.tsx | 43 +++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/packages/desktop-client/src/components/schedules/UpcomingLength.tsx b/packages/desktop-client/src/components/schedules/UpcomingLength.tsx index 5195110eee3..57cb90569c7 100644 --- a/packages/desktop-client/src/components/schedules/UpcomingLength.tsx +++ b/packages/desktop-client/src/components/schedules/UpcomingLength.tsx @@ -1,9 +1,10 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { type SyncedPrefs } from 'loot-core/types/prefs'; import { useSyncedPref } from '../../hooks/useSyncedPref'; +import { Button } from '../common/Button2'; import { Modal, ModalCloseButton, ModalHeader } from '../common/Modal'; import { Paragraph } from '../common/Paragraph'; import { Select } from '../common/Select'; @@ -20,7 +21,7 @@ function useUpcomingLengthOptions() { { value: '7', label: t('1 week') }, { value: '14', label: t('2 weeks') }, { value: 'oneMonth', label: t('1 month') }, - { value: 'currentMonth', label: t('end of the current month') }, + { value: 'currentMonth', label: t('End of the current month') }, ]; return { upcomingLengthOptions }; @@ -32,10 +33,25 @@ export function UpcomingLength() { 'upcomingScheduledTransactionLength', ); + const saveUpcomingLength = () => { + setUpcomingLength(tempUpcomingLength); + }; + const { upcomingLengthOptions } = useUpcomingLengthOptions(); const upcomingLength = _upcomingLength || '7'; + const [tempUpcomingLength, setTempUpcomingLength] = useState(upcomingLength); + const [saveActive, setSaveActive] = useState(false); + + useEffect(() => { + if (tempUpcomingLength !== upcomingLength) { + setSaveActive(true); + } else { + setSaveActive(false); + } + }, [tempUpcomingLength, upcomingLength]); + return ( setUpcomingLength(newValue)} + value={tempUpcomingLength} + onChange={newValue => { + setTempUpcomingLength(newValue); + }} /> +
+ +
)}
From 97e6c5dc3e7d3ad95642019a526c1a7ffa22a9de Mon Sep 17 00:00:00 2001 From: SamBobBarnes Date: Mon, 20 Jan 2025 10:37:10 -0600 Subject: [PATCH 02/11] release notes --- upcoming-release-notes/4206.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 upcoming-release-notes/4206.md diff --git a/upcoming-release-notes/4206.md b/upcoming-release-notes/4206.md new file mode 100644 index 00000000000..e9b1929f737 --- /dev/null +++ b/upcoming-release-notes/4206.md @@ -0,0 +1,6 @@ +--- +category: Features +authors: [ SamBobBarnes ] +--- + +Add option for custom upcoming length From d21444a1bf13963ecb6efb2878dbb581e02e3e3c Mon Sep 17 00:00:00 2001 From: SamBobBarnes Date: Mon, 20 Jan 2025 10:45:07 -0600 Subject: [PATCH 03/11] custom component shows --- .../schedules/CustomUpcomingLength.tsx | 18 ++++++++++++++++++ .../components/schedules/UpcomingLength.tsx | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 packages/desktop-client/src/components/schedules/CustomUpcomingLength.tsx diff --git a/packages/desktop-client/src/components/schedules/CustomUpcomingLength.tsx b/packages/desktop-client/src/components/schedules/CustomUpcomingLength.tsx new file mode 100644 index 00000000000..506ab526d73 --- /dev/null +++ b/packages/desktop-client/src/components/schedules/CustomUpcomingLength.tsx @@ -0,0 +1,18 @@ +import { Paragraph } from '../common/Paragraph'; +import { View } from '../common/View'; + +type CustomUpcomingLengthProps = { + onChange: (value: string) => void; + tempValue: string; +}; + +export function CustomUpcomingLength({ + onChange, + tempValue, +}: CustomUpcomingLengthProps) { + return ( + + Temp:{tempValue} + + ); +} diff --git a/packages/desktop-client/src/components/schedules/UpcomingLength.tsx b/packages/desktop-client/src/components/schedules/UpcomingLength.tsx index 57cb90569c7..b7d579623c0 100644 --- a/packages/desktop-client/src/components/schedules/UpcomingLength.tsx +++ b/packages/desktop-client/src/components/schedules/UpcomingLength.tsx @@ -10,6 +10,8 @@ import { Paragraph } from '../common/Paragraph'; import { Select } from '../common/Select'; import { View } from '../common/View'; +import { CustomUpcomingLength } from './CustomUpcomingLength'; + function useUpcomingLengthOptions() { const { t } = useTranslation(); @@ -22,11 +24,16 @@ function useUpcomingLengthOptions() { { value: '14', label: t('2 weeks') }, { value: 'oneMonth', label: t('1 month') }, { value: 'currentMonth', label: t('End of the current month') }, + { value: 'custom', label: t('Custom length') }, ]; return { upcomingLengthOptions }; } +function nonCustomUpcomingLengthValues() { + return ['1', '7', '14', 'oneMonth', 'currentMonth']; +} + export function UpcomingLength() { const { t } = useTranslation(); const [_upcomingLength, setUpcomingLength] = useSyncedPref( @@ -42,6 +49,10 @@ export function UpcomingLength() { const upcomingLength = _upcomingLength || '7'; const [tempUpcomingLength, setTempUpcomingLength] = useState(upcomingLength); + const [useCustomLength, setUseCustomLength] = useState( + nonCustomUpcomingLengthValues().findIndex(x => x === tempUpcomingLength) === + -1, + ); const [saveActive, setSaveActive] = useState(false); useEffect(() => { @@ -83,9 +94,16 @@ export function UpcomingLength() { ])} value={tempUpcomingLength} onChange={newValue => { + setUseCustomLength(newValue === 'custom'); setTempUpcomingLength(newValue); }} /> + {useCustomLength && ( + + )}
Date: Mon, 20 Jan 2025 11:06:52 -0600 Subject: [PATCH 04/11] custom input and saving working --- .../schedules/CustomUpcomingLength.tsx | 50 +++++++++++++++++-- .../components/schedules/UpcomingLength.tsx | 16 ++++-- 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/packages/desktop-client/src/components/schedules/CustomUpcomingLength.tsx b/packages/desktop-client/src/components/schedules/CustomUpcomingLength.tsx index 506ab526d73..3b03d69ec70 100644 --- a/packages/desktop-client/src/components/schedules/CustomUpcomingLength.tsx +++ b/packages/desktop-client/src/components/schedules/CustomUpcomingLength.tsx @@ -1,5 +1,8 @@ -import { Paragraph } from '../common/Paragraph'; -import { View } from '../common/View'; +import React, { useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; + +import { Input } from '../common/Input'; +import { Select } from '../common/Select'; type CustomUpcomingLengthProps = { onChange: (value: string) => void; @@ -10,9 +13,46 @@ export function CustomUpcomingLength({ onChange, tempValue, }: CustomUpcomingLengthProps) { + const { t } = useTranslation(); + + const options = [ + { value: 'day', label: t('Days') }, + { value: 'week', label: t('Weeks') }, + { value: 'month', label: t('Months') }, + { value: 'year', label: t('Years') }, + ]; + + let timePeriod = []; + if (tempValue === 'custom') { + timePeriod = ['1', 'day']; + } else { + timePeriod = tempValue.split('-'); + } + + const [numValue, setNumValue] = useState(parseInt(timePeriod[0])); + const [unit, setUnit] = useState(timePeriod[1]); + + useEffect(() => { + onChange(`${numValue}-${unit}`); + }, [numValue, onChange, unit]); + return ( - - Temp:{tempValue} - +
+ setNumValue(parseInt(e.target.value))} + defaultValue={numValue} + /> + [x.value, x.label])}