diff --git a/.eslintrc.js b/.eslintrc.js index d0eadff98ccc0cc50e6effa0df36827a2b4eafaa..1c9425aa7a9f4b2757af57fe78070cfb3ed9910d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -239,7 +239,27 @@ module.exports = { './packages/api/app/**/*', './packages/crdt/**/*', './packages/desktop-client/src/*', - // './packages/desktop-client/src/components/**/*', + // './packages/desktop-client/src/components/*', + './packages/desktop-client/src/components/accounts/**/*', + './packages/desktop-client/src/components/autocomplete/**/*', + './packages/desktop-client/src/components/budget/**/*', + './packages/desktop-client/src/components/common/**/*', + './packages/desktop-client/src/components/filters/**/*', + './packages/desktop-client/src/components/gocardless/**/*', + './packages/desktop-client/src/components/manager/**/*', + './packages/desktop-client/src/components/mobile/**/*', + './packages/desktop-client/src/components/modals/**/*', + // './packages/desktop-client/src/components/payees/**/*', + // './packages/desktop-client/src/components/reports/**/*', + // './packages/desktop-client/src/components/responsive/**/*', + // './packages/desktop-client/src/components/rules/**/*', + // './packages/desktop-client/src/components/schedules/**/*', + // './packages/desktop-client/src/components/select/**/*', + // './packages/desktop-client/src/components/settings/**/*', + // './packages/desktop-client/src/components/sidebar/**/*', + // './packages/desktop-client/src/components/spreadsheet/**/*', + // './packages/desktop-client/src/components/transactions/**/*', + // './packages/desktop-client/src/components/util/**/*', './packages/desktop-client/src/hooks/**/*', './packages/desktop-client/src/icons/**/*', './packages/desktop-client/src/style/**/*', diff --git a/packages/desktop-client/src/components/accounts/Account.js b/packages/desktop-client/src/components/accounts/Account.js index 8e047c7abb45c622daf1db884d780c4923b56c6d..37871916290bf0265a8e2829883c9247962bc02f 100644 --- a/packages/desktop-client/src/components/accounts/Account.js +++ b/packages/desktop-client/src/components/accounts/Account.js @@ -89,11 +89,11 @@ function AllTransactions({ children, }) { const { id: accountId } = account; - let scheduleData = useCachedSchedules(); + const scheduleData = useCachedSchedules(); transactions ??= []; - let schedules = useMemo( + const schedules = useMemo( () => scheduleData ? scheduleData.schedules.filter( @@ -107,7 +107,7 @@ function AllTransactions({ [scheduleData], ); - let prependTransactions = useMemo(() => { + const prependTransactions = useMemo(() => { return schedules.map(schedule => ({ id: `preview/${schedule.id}`, payee: schedule._payee, @@ -130,16 +130,16 @@ function AllTransactions({ : 0; }, [showBalances, balances, transactions]); - let prependBalances = useMemo(() => { + const prependBalances = useMemo(() => { if (!showBalances) { return null; } // Reverse so we can calculate from earliest upcoming schedule. - let scheduledBalances = [...prependTransactions] + const scheduledBalances = [...prependTransactions] .reverse() .map(scheduledTransaction => { - let amount = + const amount = (scheduledTransaction._inverse ? -1 : 1) * getScheduledAmount(scheduledTransaction.amount); return { @@ -150,7 +150,7 @@ function AllTransactions({ return groupById(scheduledBalances); }, [showBalances, prependTransactions, runningBalance]); - let allTransactions = useMemo(() => { + const allTransactions = useMemo(() => { // Don't prepend scheduled transactions if we are filtering if (!filtered && prependTransactions.length > 0) { return prependTransactions.concat(transactions); @@ -158,7 +158,7 @@ function AllTransactions({ return transactions; }, [filtered, prependTransactions, transactions]); - let allBalances = useMemo(() => { + const allBalances = useMemo(() => { // Don't prepend scheduled transactions if we are filtering if (!filtered && prependBalances && balances) { return { ...prependBalances, ...balances }; @@ -217,7 +217,7 @@ class AccountInternal extends PureComponent { } async componentDidMount() { - let maybeRefetch = tables => { + const maybeRefetch = tables => { if ( tables.includes('transactions') || tables.includes('category_mapping') || @@ -227,7 +227,7 @@ class AccountInternal extends PureComponent { } }; - let onUndo = async ({ tables, messages, undoTag }) => { + const onUndo = async ({ tables, messages, undoTag }) => { await maybeRefetch(tables); // If all the messages are dealing with transactions, find the @@ -239,7 +239,7 @@ class AccountInternal extends PureComponent { messages.every(msg => msg.dataset === 'transactions') && !messages.find(msg => msg.column === 'tombstone') ) { - let focusableMsgs = messages.filter( + const focusableMsgs = messages.filter( msg => msg.dataset === 'transactions' && !(msg.column === 'tombstone'), ); @@ -265,7 +265,7 @@ class AccountInternal extends PureComponent { this.props.setLastUndoState(null); }; - let unlistens = [listen('undo-event', onUndo)]; + const unlistens = [listen('undo-event', onUndo)]; this.unlisten = () => { unlistens.forEach(unlisten => unlisten()); @@ -317,7 +317,7 @@ class AccountInternal extends PureComponent { } fetchAllIds = async () => { - let { data } = await runQuery(this.paged.getQuery().select('id')); + const { data } = await runQuery(this.paged.getQuery().select('id')); // Remember, this is the `grouped` split type so we need to deal // with the `subtransactions` property return data.reduce((arr, t) => { @@ -332,7 +332,7 @@ class AccountInternal extends PureComponent { }; fetchTransactions = () => { - let query = this.makeRootQuery(); + const query = this.makeRootQuery(); this.rootQuery = this.currentQuery = query; this.updateQuery(query); @@ -342,8 +342,8 @@ class AccountInternal extends PureComponent { }; makeRootQuery = () => { - let locationState = this.props.location.state; - let accountId = this.props.accountId; + const locationState = this.props.location.state; + const accountId = this.props.accountId; if (locationState && locationState.filter) { return q('transactions') @@ -488,12 +488,12 @@ class AccountInternal extends PureComponent { }; onExport = async accountName => { - let exportedTransactions = await send('transactions-export-query', { + const exportedTransactions = await send('transactions-export-query', { query: this.currentQuery.serialize(), }); - let normalizedName = + const normalizedName = accountName && accountName.replace(/[()]/g, '').replace(/\s+/g, '-'); - let filename = `${normalizedName || 'transactions'}.csv`; + const filename = `${normalizedName || 'transactions'}.csv`; window.Actual.saveFile( exportedTransactions, @@ -523,8 +523,10 @@ class AccountInternal extends PureComponent { }; canCalculateBalance = () => { - let accountId = this.props.accountId; - let account = this.props.accounts.find(account => account.id === accountId); + const accountId = this.props.accountId; + const account = this.props.accounts.find( + account => account.id === accountId, + ); return ( account && this.state.search === '' && @@ -540,7 +542,7 @@ class AccountInternal extends PureComponent { return null; } - let { data } = await runQuery( + const { data } = await runQuery( this.paged .getQuery() .options({ splits: 'none' }) @@ -570,8 +572,8 @@ class AccountInternal extends PureComponent { }; onToggleExtraBalances = () => { - let { accountId, showExtraBalances } = this.props; - let key = 'show-extra-balances-' + accountId || 'all-accounts'; + const { accountId, showExtraBalances } = this.props; + const key = 'show-extra-balances-' + accountId || 'all-accounts'; this.props.savePrefs({ [key]: !showExtraBalances }); }; @@ -622,7 +624,7 @@ class AccountInternal extends PureComponent { break; case 'remove-sorting': { this.setState({ sort: [] }, () => { - let filters = this.state.filters; + const filters = this.state.filters; if (filters.length > 0) { this.applyFilters([...filters]); } else { @@ -648,7 +650,7 @@ class AccountInternal extends PureComponent { }; getAccountTitle(account, id) { - let { filterName } = this.props.location.state || {}; + const { filterName } = this.props.location.state || {}; if (filterName) { return filterName; @@ -686,7 +688,7 @@ class AccountInternal extends PureComponent { }; onCreatePayee = name => { - let trimmed = name.trim(); + const trimmed = name.trim(); if (trimmed !== '') { return this.props.createPayee(name); } @@ -696,9 +698,9 @@ class AccountInternal extends PureComponent { lockTransactions = async () => { this.setState({ workingHard: true }); - let { accountId } = this.props; + const { accountId } = this.props; - let { data } = await runQuery( + const { data } = await runQuery( q('transactions') .filter({ cleared: true, reconciled: false, account: accountId }) .select('*') @@ -706,10 +708,10 @@ class AccountInternal extends PureComponent { ); let transactions = ungroupTransactions(data); - let changes = { updated: [] }; + const changes = { updated: [] }; transactions.forEach(trans => { - let { diff } = updateTransaction(transactions, { + const { diff } = updateTransaction(transactions, { ...trans, reconciled: true, }); @@ -730,16 +732,16 @@ class AccountInternal extends PureComponent { }; onDoneReconciling = async () => { - let { accountId } = this.props; - let { reconcileAmount } = this.state; + const { accountId } = this.props; + const { reconcileAmount } = this.state; - let { data } = await runQuery( + const { data } = await runQuery( q('transactions') .filter({ cleared: true, account: accountId }) .select('*') .options({ splits: 'grouped' }), ); - let transactions = ungroupTransactions(data); + const transactions = ungroupTransactions(data); let cleared = 0; @@ -749,7 +751,7 @@ class AccountInternal extends PureComponent { } }); - let targetDiff = reconcileAmount - cleared; + const targetDiff = reconcileAmount - cleared; if (targetDiff === 0) { await this.lockTransactions(); @@ -792,10 +794,10 @@ class AccountInternal extends PureComponent { }; onBatchEdit = async (name, ids) => { - let onChange = async (name, value) => { + const onChange = async (name, value) => { this.setState({ workingHard: true }); - let { data } = await runQuery( + const { data } = await runQuery( q('transactions') .filter({ id: { $oneof: ids } }) .select('*') @@ -803,7 +805,7 @@ class AccountInternal extends PureComponent { ); let transactions = ungroupTransactions(data); - let changes = { deleted: [], updated: [] }; + const changes = { deleted: [], updated: [] }; // Cleared is a special case right now if (name === 'cleared') { @@ -826,7 +828,7 @@ class AccountInternal extends PureComponent { return; } - let transaction = { + const transaction = { ...trans, [name]: value, }; @@ -835,7 +837,7 @@ class AccountInternal extends PureComponent { transaction.reconciled = false; } - let { diff } = updateTransaction(transactions, transaction); + const { diff } = updateTransaction(transactions, transaction); // TODO: We need to keep an updated list of transactions so // the logic in `updateTransaction`, particularly about @@ -863,13 +865,13 @@ class AccountInternal extends PureComponent { }; if (name === 'amount' || name === 'payee' || name === 'account') { - let { data } = await runQuery( + const { data } = await runQuery( q('transactions') .filter({ id: { $oneof: ids }, reconciled: true }) .select('*') .options({ splits: 'grouped' }), ); - let transactions = ungroupTransactions(data); + const transactions = ungroupTransactions(data); if (transactions.length > 0) { this.props.pushModal('confirm-transaction-edit', { @@ -892,17 +894,17 @@ class AccountInternal extends PureComponent { }; onBatchDuplicate = async ids => { - let onConfirmDuplicate = async ids => { + const onConfirmDuplicate = async ids => { this.setState({ workingHard: true }); - let { data } = await runQuery( + const { data } = await runQuery( q('transactions') .filter({ id: { $oneof: ids } }) .select('*') .options({ splits: 'grouped' }), ); - let changes = { + const changes = { added: data .reduce((newTransactions, trans) => { return newTransactions.concat( @@ -925,10 +927,10 @@ class AccountInternal extends PureComponent { }; onBatchDelete = async ids => { - let onConfirmDelete = async ids => { + const onConfirmDelete = async ids => { this.setState({ workingHard: true }); - let { data } = await runQuery( + const { data } = await runQuery( q('transactions') .filter({ id: { $oneof: ids } }) .select('*') @@ -936,11 +938,11 @@ class AccountInternal extends PureComponent { ); let transactions = ungroupTransactions(data); - let idSet = new Set(ids); - let changes = { deleted: [], updated: [] }; + const idSet = new Set(ids); + const changes = { deleted: [], updated: [] }; transactions.forEach(trans => { - let parentId = trans.parent_id; + const parentId = trans.parent_id; // First, check if we're actually deleting this transaction by // checking `idSet`. Then, we don't need to do anything if it's @@ -949,7 +951,7 @@ class AccountInternal extends PureComponent { return; } - let { diff } = deleteTransaction(transactions, trans.id); + const { diff } = deleteTransaction(transactions, trans.id); // TODO: We need to keep an updated list of transactions so // the logic in `updateTransaction`, particularly about @@ -977,13 +979,13 @@ class AccountInternal extends PureComponent { }; checkForReconciledTransactions = async (ids, confirmReason, onConfirm) => { - let { data } = await runQuery( + const { data } = await runQuery( q('transactions') .filter({ id: { $oneof: ids }, reconciled: true }) .select('*') .options({ splits: 'grouped' }), ); - let transactions = ungroupTransactions(data); + const transactions = ungroupTransactions(data); if (transactions.length > 0) { this.props.pushModal('confirm-transaction-edit', { onConfirm: () => { @@ -1005,14 +1007,14 @@ class AccountInternal extends PureComponent { }; onCreateRule = async ids => { - let { data } = await runQuery( + const { data } = await runQuery( q('transactions') .filter({ id: { $oneof: ids } }) .select('*') .options({ splits: 'grouped' }), ); - let transactions = ungroupTransactions(data); - let payeeCondition = transactions[0].imported_payee + const transactions = ungroupTransactions(data); + const payeeCondition = transactions[0].imported_payee ? { field: 'imported_payee', op: 'is', @@ -1026,7 +1028,7 @@ class AccountInternal extends PureComponent { type: 'id', }; - let rule = { + const rule = { stage: null, conditionsOp: 'and', conditions: [payeeCondition], @@ -1054,7 +1056,7 @@ class AccountInternal extends PureComponent { onReloadSavedFilter = (savedFilter, item) => { if (item === 'reload') { - let [getFilter] = this.props.filtersList.filter( + const [getFilter] = this.props.filtersList.filter( f => f.id === this.state.filterId.id, ); this.setState({ conditionsOp: getFilter.conditionsOp }); @@ -1136,15 +1138,15 @@ class AccountInternal extends PureComponent { onScheduleAction = async (name, ids) => { switch (name) { case 'post-transaction': - for (let id of ids) { - let parts = id.split('/'); + for (const id of ids) { + const parts = id.split('/'); await send('schedule/post-transaction', { id: parts[1] }); } this.refetchTransactions(); break; case 'skip': - for (let id of ids) { - let parts = id.split('/'); + for (const id of ids) { + const parts = id.split('/'); await send('schedule/skip-next-date', { id: parts[1] }); } break; @@ -1154,10 +1156,10 @@ class AccountInternal extends PureComponent { applyFilters = async conditions => { if (conditions.length > 0) { - let customFilters = conditions + const customFilters = conditions .filter(cond => !!cond.customName) .map(f => f.filter); - let { filters } = await send('make-filters-from-conditions', { + const { filters } = await send('make-filters-from-conditions', { conditions: conditions.filter(cond => !cond.customName), }); const conditionsOpKey = this.state.conditionsOp === 'or' ? '$or' : '$and'; @@ -1187,13 +1189,13 @@ class AccountInternal extends PureComponent { }; applySort = (field, ascDesc, prevField, prevAscDesc) => { - let filters = this.state.filters; - let sortField = getField(!field ? this.state.sort.field : field); - let sortAscDesc = !ascDesc ? this.state.sort.ascDesc : ascDesc; - let sortPrevField = getField( + const filters = this.state.filters; + const sortField = getField(!field ? this.state.sort.field : field); + const sortAscDesc = !ascDesc ? this.state.sort.ascDesc : ascDesc; + const sortPrevField = getField( !prevField ? this.state.sort.prevField : prevField, ); - let sortPrevAscDesc = !prevField + const sortPrevAscDesc = !prevField ? this.state.sort.prevAscDesc : prevAscDesc; @@ -1263,7 +1265,7 @@ class AccountInternal extends PureComponent { }; render() { - let { + const { accounts, categoryGroups, payees, @@ -1277,7 +1279,7 @@ class AccountInternal extends PureComponent { accountId, categoryId, } = this.props; - let { + const { transactions, loading, workingHard, @@ -1290,7 +1292,7 @@ class AccountInternal extends PureComponent { showCleared, } = this.state; - let account = accounts.find(account => account.id === accountId); + const account = accounts.find(account => account.id === accountId); const accountName = this.getAccountTitle(account, accountId); if (!accountName && !loading) { @@ -1299,19 +1301,19 @@ class AccountInternal extends PureComponent { return <Navigate to="/accounts" replace />; } - let category = categoryGroups + const category = categoryGroups .flatMap(g => g.categories) .find(category => category.id === categoryId); - let showEmptyMessage = !loading && !accountId && accounts.length === 0; + const showEmptyMessage = !loading && !accountId && accounts.length === 0; - let isNameEditable = + const isNameEditable = accountId && accountId !== 'budgeted' && accountId !== 'offbudget' && accountId !== 'uncategorized'; - let balanceQuery = this.getBalanceQuery(account, accountId); + const balanceQuery = this.getBalanceQuery(account, accountId); return ( <AllTransactions @@ -1459,8 +1461,8 @@ class AccountInternal extends PureComponent { } function AccountHack(props) { - let { dispatch: splitsExpandedDispatch } = useSplitsExpanded(); - let match = useMatch(props.location.pathname); + const { dispatch: splitsExpandedDispatch } = useSplitsExpanded(); + const match = useMatch(props.location.pathname); return ( <AccountInternal @@ -1472,11 +1474,11 @@ function AccountHack(props) { } export default function Account() { - let params = useParams(); - let location = useLocation(); + const params = useParams(); + const location = useLocation(); - let { grouped: categoryGroups } = useCategories(); - let state = useSelector(state => ({ + const { grouped: categoryGroups } = useCategories(); + const state = useSelector(state => ({ newTransactions: state.queries.newTransactions, matchedTransactions: state.queries.matchedTransactions, accounts: state.queries.accounts, @@ -1494,14 +1496,14 @@ export default function Account() { lastUndoState: state.app.lastUndoState, })); - let dispatch = useDispatch(); - let filtersList = useFilters(); - let actionCreators = useMemo( + const dispatch = useDispatch(); + const filtersList = useFilters(); + const actionCreators = useMemo( () => bindActionCreators(actions, dispatch), [dispatch], ); - let transform = useMemo(() => { + const transform = useMemo(() => { let filterByAccount = queries.getAccountFilter(params.id, '_account'); let filterByPayee = queries.getAccountFilter( params.id, diff --git a/packages/desktop-client/src/components/accounts/AccountSyncCheck.js b/packages/desktop-client/src/components/accounts/AccountSyncCheck.js index c6e2e4e440b31233947c6bb0906d9acb24708531..d7d3597b71db3b600f99dcdaf7c9c1c6544b32d9 100644 --- a/packages/desktop-client/src/components/accounts/AccountSyncCheck.js +++ b/packages/desktop-client/src/components/accounts/AccountSyncCheck.js @@ -49,24 +49,24 @@ function getErrorMessage(type, code) { } export default function AccountSyncCheck() { - let accounts = useSelector(state => state.queries.accounts); - let failedAccounts = useSelector(state => state.account.failedAccounts); - let { unlinkAccount, pushModal } = useActions(); + const accounts = useSelector(state => state.queries.accounts); + const failedAccounts = useSelector(state => state.account.failedAccounts); + const { unlinkAccount, pushModal } = useActions(); - let { id } = useParams(); - let [open, setOpen] = useState(false); + const { id } = useParams(); + const [open, setOpen] = useState(false); if (!failedAccounts) { return null; } - let error = failedAccounts.get(id); + const error = failedAccounts.get(id); if (!error) { return null; } - let account = accounts.find(account => account.id === id); - let { type, code } = error; - let showAuth = + const account = accounts.find(account => account.id === id); + const { type, code } = error; + const showAuth = (type === 'ITEM_ERROR' && code === 'ITEM_LOGIN_REQUIRED') || (type === 'INVALID_INPUT' && code === 'INVALID_ACCESS_TOKEN'); diff --git a/packages/desktop-client/src/components/accounts/Balance.js b/packages/desktop-client/src/components/accounts/Balance.js index c3710c2c9a3f83158c0f89685c3b83f0f988868e..8383b055c3960c5fedb5baea07993a5db76c88b8 100644 --- a/packages/desktop-client/src/components/accounts/Balance.js +++ b/packages/desktop-client/src/components/accounts/Balance.js @@ -40,9 +40,9 @@ function DetailedBalance({ name, balance, isExactBalance = true }) { } function SelectedBalance({ selectedItems, account }) { - let name = `selected-balance-${[...selectedItems].join('-')}`; + const name = `selected-balance-${[...selectedItems].join('-')}`; - let rows = useSheetValue({ + const rows = useSheetValue({ name, query: q('transactions') .filter({ @@ -51,9 +51,9 @@ function SelectedBalance({ selectedItems, account }) { }) .select('id'), }); - let ids = new Set((rows || []).map(r => r.id)); + const ids = new Set((rows || []).map(r => r.id)); - let finalIds = [...selectedItems].filter(id => !ids.has(id)); + const finalIds = [...selectedItems].filter(id => !ids.has(id)); let balance = useSheetValue({ name: name + '-sum', query: q('transactions') @@ -63,14 +63,14 @@ function SelectedBalance({ selectedItems, account }) { }); let scheduleBalance = null; - let scheduleData = useCachedSchedules(); - let schedules = scheduleData ? scheduleData.schedules : []; - let previewIds = [...selectedItems] + const scheduleData = useCachedSchedules(); + const schedules = scheduleData ? scheduleData.schedules : []; + const previewIds = [...selectedItems] .filter(id => isPreviewId(id)) .map(id => id.slice(8)); let isExactBalance = true; - for (let s of schedules) { + for (const s of schedules) { if (previewIds.includes(s.id)) { // If a schedule is `between X and Y` then we calculate the average if (s._amountOp === 'isbetween') { @@ -105,11 +105,11 @@ function SelectedBalance({ selectedItems, account }) { } function MoreBalances({ balanceQuery }) { - let cleared = useSheetValue({ + const cleared = useSheetValue({ name: balanceQuery.name + '-cleared', query: balanceQuery.query.filter({ cleared: true }), }); - let uncleared = useSheetValue({ + const uncleared = useSheetValue({ name: balanceQuery.name + '-uncleared', query: balanceQuery.query.filter({ cleared: false }), }); @@ -128,7 +128,7 @@ export function Balances({ onToggleExtraBalances, account, }) { - let selectedItems = useSelectedItems(); + const selectedItems = useSelectedItems(); return ( <View diff --git a/packages/desktop-client/src/components/accounts/Header.js b/packages/desktop-client/src/components/accounts/Header.js index ab40a636894f96cd0179a82138a764d42bfbc873..6e3992583e910d7f4de3526059d8c38978f0a1fe 100644 --- a/packages/desktop-client/src/components/accounts/Header.js +++ b/packages/desktop-client/src/components/accounts/Header.js @@ -78,9 +78,9 @@ export function AccountHeader({ onDeleteFilter, onScheduleAction, }) { - let [menuOpen, setMenuOpen] = useState(false); - let searchInput = useRef(null); - let splitsExpanded = useSplitsExpanded(); + const [menuOpen, setMenuOpen] = useState(false); + const searchInput = useRef(null); + const splitsExpanded = useSplitsExpanded(); let canSync = account && account.account_id; if (!account) { @@ -359,7 +359,7 @@ function AccountMenu({ onReconcile, onMenuSelect, }) { - let [tooltip, setTooltip] = useState('default'); + const [tooltip, setTooltip] = useState('default'); const syncServerStatus = useSyncServerStatus(); return tooltip === 'reconcile' ? ( diff --git a/packages/desktop-client/src/components/accounts/MobileAccount.js b/packages/desktop-client/src/components/accounts/MobileAccount.js index 794c59a4c0cce0c21a37512ca4b413e30ee0d45e..837764310ba71cae908705375a90f5a35a4aa073 100644 --- a/packages/desktop-client/src/components/accounts/MobileAccount.js +++ b/packages/desktop-client/src/components/accounts/MobileAccount.js @@ -41,13 +41,13 @@ const getSchedulesTransform = memoizeOne((id, hasSearch) => { }); function PreviewTransactions({ accountId, children }) { - let scheduleData = useCachedSchedules(); + const scheduleData = useCachedSchedules(); if (scheduleData == null) { return children(null); } - let schedules = scheduleData.schedules.filter( + const schedules = scheduleData.schedules.filter( s => !s.completed && ['due', 'upcoming', 'missed'].includes(scheduleData.statuses.get(s.id)), @@ -76,15 +76,15 @@ export default function Account(props) { const [searchText, setSearchText] = useState(''); const [currentQuery, setCurrentQuery] = useState(); - let state = useSelector(state => ({ + const state = useSelector(state => ({ payees: state.queries.payees, newTransactions: state.queries.newTransactions, prefs: state.prefs.local, dateFormat: state.prefs.local.dateFormat || 'MM/dd/yyyy', })); - let dispatch = useDispatch(); - let actionCreators = useMemo( + const dispatch = useDispatch(); + const actionCreators = useMemo( () => bindActionCreators(actions, dispatch), [dispatch], ); @@ -106,7 +106,7 @@ export default function Account(props) { }; const fetchTransactions = async () => { - let query = makeRootQuery(); + const query = makeRootQuery(); setCurrentQuery(query); updateQuery(query); }; @@ -189,9 +189,9 @@ export default function Account(props) { } }; - let balance = queries.accountBalance(account); - let numberFormat = state.prefs.numberFormat || 'comma-dot'; - let hideFraction = state.prefs.hideFraction || false; + const balance = queries.accountBalance(account); + const numberFormat = state.prefs.numberFormat || 'comma-dot'; + const hideFraction = state.prefs.hideFraction || false; return ( <SchedulesProvider diff --git a/packages/desktop-client/src/components/accounts/MobileAccountDetails.js b/packages/desktop-client/src/components/accounts/MobileAccountDetails.js index b20832df9fda9153e0197bfe4a71bd3a67a7045d..c2a250d2b1220800581d305ab6646e01c16c2a7c 100644 --- a/packages/desktop-client/src/components/accounts/MobileAccountDetails.js +++ b/packages/desktop-client/src/components/accounts/MobileAccountDetails.js @@ -75,7 +75,7 @@ export default function AccountDetails({ onSelectTransaction, pushModal, }) { - let allTransactions = useMemo(() => { + const allTransactions = useMemo(() => { return prependTransactions.concat(transactions); }, [prependTransactions, transactions]); diff --git a/packages/desktop-client/src/components/accounts/MobileAccounts.js b/packages/desktop-client/src/components/accounts/MobileAccounts.js index 2df04b5ac84a135ba812de2aeef1d8e9ff062b3a..ac71f9231e08295d72f3c81f95fc103ac24b60fe 100644 --- a/packages/desktop-client/src/components/accounts/MobileAccounts.js +++ b/packages/desktop-client/src/components/accounts/MobileAccounts.js @@ -216,18 +216,18 @@ function AccountList({ } export default function Accounts() { - let accounts = useSelector(state => state.queries.accounts); - let newTransactions = useSelector(state => state.queries.newTransactions); - let updatedAccounts = useSelector(state => state.queries.updatedAccounts); - let numberFormat = useSelector( + const accounts = useSelector(state => state.queries.accounts); + const newTransactions = useSelector(state => state.queries.newTransactions); + const updatedAccounts = useSelector(state => state.queries.updatedAccounts); + const numberFormat = useSelector( state => state.prefs.local.numberFormat || 'comma-dot', ); - let hideFraction = useSelector( + const hideFraction = useSelector( state => state.prefs.local.hideFraction || false, ); const { list: categories } = useCategories(); - let { getAccounts, replaceModal, syncAndDownload } = useActions(); + const { getAccounts, replaceModal, syncAndDownload } = useActions(); const transactions = useState({}); const navigate = useNavigate(); diff --git a/packages/desktop-client/src/components/accounts/Reconcile.js b/packages/desktop-client/src/components/accounts/Reconcile.js index 762a728f884b1bff44cb52f6ce86d762a9a4c6d5..d01ad8ef3f24f1eecb5b354ebe7e59c3b48e21ec 100644 --- a/packages/desktop-client/src/components/accounts/Reconcile.js +++ b/packages/desktop-client/src/components/accounts/Reconcile.js @@ -20,13 +20,13 @@ export function ReconcilingMessage({ onDone, onCreateTransaction, }) { - let cleared = useSheetValue({ + const cleared = useSheetValue({ name: balanceQuery.name + '-cleared', value: 0, query: balanceQuery.query.filter({ cleared: true }), }); - let format = useFormat(); - let targetDiff = targetBalance - cleared; + const format = useFormat(); + const targetDiff = targetBalance - cleared; return ( <View @@ -96,18 +96,18 @@ export function ReconcilingMessage({ } export function ReconcileTooltip({ account, onReconcile, onClose }) { - let balanceQuery = queries.accountBalance(account); - let clearedBalance = useSheetValue({ + const balanceQuery = queries.accountBalance(account); + const clearedBalance = useSheetValue({ name: balanceQuery.name + '-cleared', value: null, query: balanceQuery.query.filter({ cleared: true }), }); - let format = useFormat(); + const format = useFormat(); function onSubmit(e) { e.preventDefault(); - let input = e.target.elements[0]; - let amount = currencyToInteger(input.value); + const input = e.target.elements[0]; + const amount = currencyToInteger(input.value); if (amount != null) { onReconcile(amount == null ? clearedBalance : amount); onClose(); diff --git a/packages/desktop-client/src/components/autocomplete/Autocomplete.tsx b/packages/desktop-client/src/components/autocomplete/Autocomplete.tsx index 16491a6fd2c1a24a33f93aee1c9d60f02bb8ff95..5c413b01d55a0d0c83b7df7d0d4df6fc75b617ad 100644 --- a/packages/desktop-client/src/components/autocomplete/Autocomplete.tsx +++ b/packages/desktop-client/src/components/autocomplete/Autocomplete.tsx @@ -24,7 +24,7 @@ const inst: { lastChangeType? } = {}; function findItem(strict, suggestions, value) { if (strict) { - let idx = suggestions.findIndex(item => item.id === value); + const idx = suggestions.findIndex(item => item.id === value); return idx === -1 ? null : suggestions[idx]; } @@ -70,7 +70,7 @@ function fireUpdate(onUpdate, strict, suggestions, index, value) { } else { if (index == null) { // If passing in a value directly, validate the id - let sug = suggestions.find(sug => sug.id === value); + const sug = suggestions.find(sug => sug.id === value); if (sug) { selected = sug.id; } @@ -90,7 +90,7 @@ function defaultRenderItems(items, getItemProps, highlightedIndex) { return ( <div> {items.map((item, index) => { - let name = getItemName(item); + const name = getItemName(item); return ( <div {...getItemProps({ item })} @@ -222,7 +222,7 @@ function SingleAutocomplete({ function resetState(newValue) { const val = newValue === undefined ? initialValue : newValue; - let selectedItem = findItem(strict, suggestions, val); + const selectedItem = findItem(strict, suggestions, val); setSelectedItem(selectedItem); setValue(selectedItem ? getItemName(selectedItem) : ''); @@ -311,10 +311,10 @@ function SingleAutocomplete({ setHighlightedIndex(null); } else { - let defaultGetHighlightedIndex = filteredSuggestions => { + const defaultGetHighlightedIndex = filteredSuggestions => { return highlightFirst && filteredSuggestions.length ? 0 : null; }; - let highlightedIndex = ( + const highlightedIndex = ( getHighlightedIndex || defaultGetHighlightedIndex )(filteredSuggestions); // @ts-expect-error Types say there is no type @@ -415,7 +415,7 @@ function SingleAutocomplete({ // If not using table behavior, reset the input on blur. Tables // handle saving the value on blur. - let value = selectedItem ? getItemId(selectedItem) : null; + const value = selectedItem ? getItemId(selectedItem) : null; resetState(value); } else { @@ -423,7 +423,7 @@ function SingleAutocomplete({ } }, onKeyDown: (e: KeyboardEvent<HTMLInputElement>) => { - let { onKeyDown } = inputProps || {}; + const { onKeyDown } = inputProps || {}; // If the dropdown is open, an item is highlighted, and the user // pressed enter, always capture that and handle it ourselves @@ -561,15 +561,15 @@ function MultiAutocomplete({ strict, ...props }: MultiAutocompleteProps) { - let [focused, setFocused] = useState(false); - let lastSelectedItems = useRef<unknown[]>(); + const [focused, setFocused] = useState(false); + const lastSelectedItems = useRef<unknown[]>(); useEffect(() => { lastSelectedItems.current = selectedItems; }); function onRemoveItem(id) { - let items = selectedItems.filter(i => i !== id); + const items = selectedItems.filter(i => i !== id); onSelect(items); } diff --git a/packages/desktop-client/src/components/autocomplete/CategoryAutocomplete.tsx b/packages/desktop-client/src/components/autocomplete/CategoryAutocomplete.tsx index 59c71f81c17530ca9c902632c9ba83fdd764a010..b8c07ba36dbf1c8038418d4f2563814524ffc3ec 100644 --- a/packages/desktop-client/src/components/autocomplete/CategoryAutocomplete.tsx +++ b/packages/desktop-client/src/components/autocomplete/CategoryAutocomplete.tsx @@ -117,7 +117,7 @@ export default function CategoryAutocomplete({ renderCategoryItem, ...props }: CategoryAutocompleteProps) { - let categorySuggestions: Array< + const categorySuggestions: Array< CategoryEntity & { group?: CategoryGroupEntity } > = useMemo( () => diff --git a/packages/desktop-client/src/components/autocomplete/PayeeAutocomplete.tsx b/packages/desktop-client/src/components/autocomplete/PayeeAutocomplete.tsx index 740cd93eb435401e74cb873ae6a9b5f5609c87c2..6ed812c7b02b4280294fd25390c690f1ba186eba 100644 --- a/packages/desktop-client/src/components/autocomplete/PayeeAutocomplete.tsx +++ b/packages/desktop-client/src/components/autocomplete/PayeeAutocomplete.tsx @@ -68,7 +68,7 @@ function PayeeList({ renderPayeeItem = defaultRenderPayeeItem, footer, }) { - let isFiltered = items.filtered; + const isFiltered = items.filtered; let createNew = null; items = [...items]; @@ -76,12 +76,12 @@ function PayeeList({ // with the value of the input so it always shows whatever the user // entered if (items[0].id === 'new') { - let [first, ...rest] = items; + const [first, ...rest] = items; createNew = first; items = rest; } - let offset = createNew ? 1 : 0; + const offset = createNew ? 1 : 0; let lastType = null; return ( @@ -102,14 +102,14 @@ function PayeeList({ })} {items.map((item, idx) => { - let type = item.transfer_acct ? 'account' : 'payee'; + const type = item.transfer_acct ? 'account' : 'payee'; let title; if (type === 'payee' && lastType !== type) { title = 'Payees'; } else if (type === 'account' && lastType !== type) { title = 'Transfer To/From'; } - let showMoreMessage = idx === items.length - 1 && isFiltered; + const showMoreMessage = idx === items.length - 1 && isFiltered; lastType = type; return ( @@ -185,20 +185,20 @@ export default function PayeeAutocomplete({ payees, ...props }: PayeeAutocompleteProps) { - let cachedPayees = useCachedPayees(); + const cachedPayees = useCachedPayees(); if (!payees) { payees = cachedPayees; } - let cachedAccounts = useCachedAccounts(); + const cachedAccounts = useCachedAccounts(); if (!accounts) { accounts = cachedAccounts; } - let [focusTransferPayees, setFocusTransferPayees] = useState(false); - let [rawPayee, setRawPayee] = useState(''); - let hasPayeeInput = !!rawPayee; - let payeeSuggestions = useMemo(() => { + const [focusTransferPayees, setFocusTransferPayees] = useState(false); + const [rawPayee, setRawPayee] = useState(''); + const hasPayeeInput = !!rawPayee; + const payeeSuggestions = useMemo(() => { const suggestions = getPayeeSuggestions( payees, focusTransferPayees, @@ -211,13 +211,13 @@ export default function PayeeAutocomplete({ return [{ id: 'new', name: '' }, ...suggestions]; }, [payees, focusTransferPayees, accounts, hasPayeeInput]); - let dispatch = useDispatch(); + const dispatch = useDispatch(); async function handleSelect(value, rawInputValue) { if (tableBehavior) { onSelect?.(makeNew(value, rawInputValue)); } else { - let create = () => dispatch(createPayee(rawInputValue)); + const create = () => dispatch(createPayee(rawInputValue)); if (Array.isArray(value)) { value = await Promise.all(value.map(v => (v === 'new' ? create() : v))); @@ -279,10 +279,10 @@ export default function PayeeAutocomplete({ }); filtered.sort((p1, p2) => { - let r1 = p1.name.toLowerCase().startsWith(value.toLowerCase()); - let r2 = p2.name.toLowerCase().startsWith(value.toLowerCase()); - let r1exact = p1.name.toLowerCase() === value.toLowerCase(); - let r2exact = p2.name.toLowerCase() === value.toLowerCase(); + const r1 = p1.name.toLowerCase().startsWith(value.toLowerCase()); + const r2 = p2.name.toLowerCase().startsWith(value.toLowerCase()); + const r1exact = p1.name.toLowerCase() === value.toLowerCase(); + const r2exact = p2.name.toLowerCase() === value.toLowerCase(); // (maniacal laughter) mwahaHAHAHAHAH if (p1.id === 'new') { @@ -306,7 +306,7 @@ export default function PayeeAutocomplete({ } }); - let isf = filtered.length > 100; + const isf = filtered.length > 100; filtered = filtered.slice(0, 100); filtered.filtered = isf; diff --git a/packages/desktop-client/src/components/autocomplete/SavedFilterAutocomplete.tsx b/packages/desktop-client/src/components/autocomplete/SavedFilterAutocomplete.tsx index 347db0826391fdccce284fbf9fe709e6039d2875..a2800b8564609ec7c2460201f7cf777ca355f635 100644 --- a/packages/desktop-client/src/components/autocomplete/SavedFilterAutocomplete.tsx +++ b/packages/desktop-client/src/components/autocomplete/SavedFilterAutocomplete.tsx @@ -63,7 +63,7 @@ export default function SavedFilterAutocomplete({ embedded, ...props }: SavedFilterAutocompleteProps) { - let filters = useFilters() || []; + const filters = useFilters() || []; return ( <Autocomplete diff --git a/packages/desktop-client/src/components/budget/BalanceWithCarryover.tsx b/packages/desktop-client/src/components/budget/BalanceWithCarryover.tsx index f0c29ee5283295541b9da738e21a786a062dd7a5..7b09d547d9a5dcf7c05801fe2293d65aa2c0d621 100644 --- a/packages/desktop-client/src/components/budget/BalanceWithCarryover.tsx +++ b/packages/desktop-client/src/components/budget/BalanceWithCarryover.tsx @@ -29,11 +29,11 @@ export default function BalanceWithCarryover({ balanceStyle, carryoverStyle, }: BalanceWithCarryoverProps) { - let carryoverValue = useSheetValue(carryover); - let balanceValue = useSheetValue(balance); - let goalValue = useSheetValue(goal); - let budgetedValue = useSheetValue(budgeted); - let isGoalTemplatesEnabled = useFeatureFlag('goalTemplatesEnabled'); + const carryoverValue = useSheetValue(carryover); + const balanceValue = useSheetValue(balance); + const goalValue = useSheetValue(goal); + const budgetedValue = useSheetValue(budgeted); + const isGoalTemplatesEnabled = useFeatureFlag('goalTemplatesEnabled'); return ( <View style={style}> <CellValue diff --git a/packages/desktop-client/src/components/budget/BudgetCategories.js b/packages/desktop-client/src/components/budget/BudgetCategories.js index 9f6d2286f5d9c46614e6d8394d51b3cf593ca8d4..e4788008c161499e93963211903c5935da832776 100644 --- a/packages/desktop-client/src/components/budget/BudgetCategories.js +++ b/packages/desktop-client/src/components/budget/BudgetCategories.js @@ -39,8 +39,8 @@ const BudgetCategories = memo( onShowNewGroup, onHideNewGroup, }) => { - let items = useMemo(() => { - let [expenseGroups, incomeGroup] = separateGroups(categoryGroups); + const items = useMemo(() => { + const [expenseGroups, incomeGroup] = separateGroups(categoryGroups); let items = Array.prototype.concat.apply( [], @@ -53,7 +53,7 @@ const BudgetCategories = memo( cat => showHiddenCategories || !cat.hidden, ); - let items = [{ type: 'expense-group', value: { ...group } }]; + const items = [{ type: 'expense-group', value: { ...group } }]; if (newCategoryForGroup === group.id) { items.push({ type: 'new-category' }); @@ -103,13 +103,13 @@ const BudgetCategories = memo( showHiddenCategories, ]); - let [dragState, setDragState] = useState(null); - let [savedCollapsed, setSavedCollapsed] = useState(null); + const [dragState, setDragState] = useState(null); + const [savedCollapsed, setSavedCollapsed] = useState(null); // TODO: If we turn this into a reducer, we could probably memoize // each item in the list for better perf function onDragChange(newDragState) { - let { state } = newDragState; + const { state } = newDragState; if (state === 'start-preview') { setDragState({ @@ -283,7 +283,7 @@ const BudgetCategories = memo( throw new Error('Unknown item type: ' + item.type); } - let pos = + const pos = idx === 0 ? 'first' : idx === items.length - 1 ? 'last' : null; return ( diff --git a/packages/desktop-client/src/components/budget/BudgetMonthCountContext.tsx b/packages/desktop-client/src/components/budget/BudgetMonthCountContext.tsx index 4a825f4ec20eee4932bd2a5c4b785a60ae2b57ed..a69e40fb69f9b619275dc3b256550277e054bb88 100644 --- a/packages/desktop-client/src/components/budget/BudgetMonthCountContext.tsx +++ b/packages/desktop-client/src/components/budget/BudgetMonthCountContext.tsx @@ -12,7 +12,8 @@ type BudgetMonthCountContextValue = { setDisplayMax: Dispatch<SetStateAction<number>>; }; -let BudgetMonthCountContext = createContext<BudgetMonthCountContextValue>(null); +const BudgetMonthCountContext = + createContext<BudgetMonthCountContextValue>(null); type BudgetMonthCountProviderProps = { children: ReactNode; @@ -21,7 +22,7 @@ type BudgetMonthCountProviderProps = { export function BudgetMonthCountProvider({ children, }: BudgetMonthCountProviderProps) { - let [displayMax, setDisplayMax] = useState(1); + const [displayMax, setDisplayMax] = useState(1); return ( <BudgetMonthCountContext.Provider value={{ displayMax, setDisplayMax }}> diff --git a/packages/desktop-client/src/components/budget/BudgetPageHeader.tsx b/packages/desktop-client/src/components/budget/BudgetPageHeader.tsx index c5f3576c70bc2e84f65d69b9db962a47d98171d2..919793bc3f6bc8e98a56bec19114c6cf1e6aabb3 100644 --- a/packages/desktop-client/src/components/budget/BudgetPageHeader.tsx +++ b/packages/desktop-client/src/components/budget/BudgetPageHeader.tsx @@ -17,8 +17,8 @@ type BudgetPageHeaderProps = { const BudgetPageHeader = memo<BudgetPageHeaderProps>( ({ startMonth, onMonthSelect, numMonths, monthBounds }) => { function getValidMonth(month) { - let start = monthBounds.start; - let end = monthUtils.subMonths(monthBounds.end, numMonths - 1); + const start = monthBounds.start; + const end = monthUtils.subMonths(monthBounds.end, numMonths - 1); if (month < start) { return start; diff --git a/packages/desktop-client/src/components/budget/BudgetSummaries.tsx b/packages/desktop-client/src/components/budget/BudgetSummaries.tsx index 11dc77f5bc2f3cbbb6d21918f7773c321554d083..1367005cc11accf736f6c759c0d2bbc047afc5fe 100644 --- a/packages/desktop-client/src/components/budget/BudgetSummaries.tsx +++ b/packages/desktop-client/src/components/budget/BudgetSummaries.tsx @@ -25,37 +25,37 @@ type BudgetSummariesProps = { export default function BudgetSummaries({ SummaryComponent, }: BudgetSummariesProps) { - let { months } = useContext(MonthsContext); + const { months } = useContext(MonthsContext); - let [widthState, setWidthState] = useState(0); - let [styles, spring] = useSpring(() => ({ + const [widthState, setWidthState] = useState(0); + const [styles, spring] = useSpring(() => ({ x: 0, config: { mass: 3, tension: 600, friction: 80 }, })); - let containerRef = useResizeObserver( + const containerRef = useResizeObserver( useCallback(rect => { setWidthState(rect.width); }, []), ); - let prevMonth0 = useRef(months[0]); - let allMonths = [...months]; + const prevMonth0 = useRef(months[0]); + const allMonths = [...months]; allMonths.unshift(subMonths(months[0], 1)); allMonths.push(addMonths(months[months.length - 1], 1)); - let monthWidth = widthState / months.length; + const monthWidth = widthState / months.length; useLayoutEffect(() => { - let prevMonth = prevMonth0.current; - let reversed = prevMonth > months[0]; - let offsetX = monthWidth; + const prevMonth = prevMonth0.current; + const reversed = prevMonth > months[0]; + const offsetX = monthWidth; let from = reversed ? -offsetX * 2 : 0; if (prevMonth !== allMonths[0] && prevMonth !== allMonths[2]) { from = -offsetX; } - let to = -offsetX; + const to = -offsetX; spring.start({ from: { x: from }, x: to }); }, [months[0]]); diff --git a/packages/desktop-client/src/components/budget/BudgetTable.js b/packages/desktop-client/src/components/budget/BudgetTable.js index 46568a288471ee67f4c1051fcb7626d9d0cf2361..1059c0633fd91b88e9cc47a3998e7b627dfeb902 100644 --- a/packages/desktop-client/src/components/budget/BudgetTable.js +++ b/packages/desktop-client/src/components/budget/BudgetTable.js @@ -33,16 +33,20 @@ class BudgetTable extends Component { }; onReorderCategory = (id, dropPos, targetId) => { - let { categoryGroups } = this.props; + const { categoryGroups } = this.props; - let isGroup = !!categoryGroups.find(g => g.id === targetId); + const isGroup = !!categoryGroups.find(g => g.id === targetId); if (isGroup) { - let { targetId: groupId } = findSortUp(categoryGroups, dropPos, targetId); - let group = categoryGroups.find(g => g.id === groupId); + const { targetId: groupId } = findSortUp( + categoryGroups, + dropPos, + targetId, + ); + const group = categoryGroups.find(g => g.id === groupId); if (group) { - let { categories } = group; + const { categories } = group; this.props.onReorderCategory({ id, groupId: group.id, @@ -55,7 +59,7 @@ class BudgetTable extends Component { } else { let targetGroup; - for (let group of categoryGroups) { + for (const group of categoryGroups) { if (group.categories.find(cat => cat.id === targetId)) { targetGroup = group; break; @@ -71,7 +75,7 @@ class BudgetTable extends Component { }; onReorderGroup = (id, dropPos, targetId) => { - let { categoryGroups } = this.props; + const { categoryGroups } = this.props; this.props.onReorderGroup({ id, @@ -80,8 +84,8 @@ class BudgetTable extends Component { }; moveVertically = dir => { - let { editing } = this.state; - let { type, categoryGroups, collapsed } = this.props; + const { editing } = this.state; + const { type, categoryGroups, collapsed } = this.props; const flattened = categoryGroups.reduce((all, group) => { if (collapsed.includes(group.id)) { @@ -151,12 +155,12 @@ class BudgetTable extends Component { }; collapseAllCategories = () => { - let { setCollapsed, categoryGroups } = this.props; + const { setCollapsed, categoryGroups } = this.props; setCollapsed(categoryGroups.map(g => g.id)); }; render() { - let { + const { type, categoryGroups, prewarmStartMonth, @@ -177,7 +181,7 @@ class BudgetTable extends Component { onShowNewGroup, onHideNewGroup, } = this.props; - let { editing, draggingState, showHiddenCategories } = this.state; + const { editing, draggingState, showHiddenCategories } = this.state; return ( <View diff --git a/packages/desktop-client/src/components/budget/DynamicBudgetTable.tsx b/packages/desktop-client/src/components/budget/DynamicBudgetTable.tsx index 51ab9df276161b04bbba6ef545d3ca2cf95ef245..961f2ee146bab47ea8392f922e97b8b1bdfa13d2 100644 --- a/packages/desktop-client/src/components/budget/DynamicBudgetTable.tsx +++ b/packages/desktop-client/src/components/budget/DynamicBudgetTable.tsx @@ -10,7 +10,7 @@ import BudgetPageHeader from './BudgetPageHeader'; import BudgetTable from './BudgetTable'; function getNumPossibleMonths(width: number) { - let estimatedTableWidth = width - 200; + const estimatedTableWidth = width - 200; if (estimatedTableWidth < 500) { return 1; @@ -51,13 +51,13 @@ const DynamicBudgetTableInner = forwardRef< }, ref, ) => { - let prefs = useSelector(state => state.prefs.local); - let { setDisplayMax } = useBudgetMonthCount(); - let actions = useActions(); + const prefs = useSelector(state => state.prefs.local); + const { setDisplayMax } = useBudgetMonthCount(); + const actions = useActions(); - let numPossible = getNumPossibleMonths(width); - let numMonths = Math.min(numPossible, maxMonths); - let maxWidth = 200 + 500 * numMonths; + const numPossible = getNumPossibleMonths(width); + const numMonths = Math.min(numPossible, maxMonths); + const maxWidth = 200 + 500 * numMonths; useEffect(() => { setDisplayMax(numPossible); diff --git a/packages/desktop-client/src/components/budget/ExpenseCategory.tsx b/packages/desktop-client/src/components/budget/ExpenseCategory.tsx index af20de7e5418ffd69df4292a77672f0f91d5387a..cc1313966870b8ac437a22f5be55b3ad4d225a86 100644 --- a/packages/desktop-client/src/components/budget/ExpenseCategory.tsx +++ b/packages/desktop-client/src/components/budget/ExpenseCategory.tsx @@ -52,14 +52,14 @@ function ExpenseCategory({ dragging = true; } - let { dragRef } = useDraggable({ + const { dragRef } = useDraggable({ type: 'category', onDragChange, item: cat, canDrag: editingCell === null, }); - let { dropRef, dropPos } = useDroppable({ + const { dropRef, dropPos } = useDroppable({ types: 'category', id: cat.id, onDrop: onReorder, diff --git a/packages/desktop-client/src/components/budget/ExpenseGroup.tsx b/packages/desktop-client/src/components/budget/ExpenseGroup.tsx index 6104e012545305bf4cf070fcd8c0bb75efa351bd..7c1bfd8983f6d601e246de455aedd0e475ea3193 100644 --- a/packages/desktop-client/src/components/budget/ExpenseGroup.tsx +++ b/packages/desktop-client/src/components/budget/ExpenseGroup.tsx @@ -48,22 +48,22 @@ function ExpenseGroup({ onToggleCollapse, onShowNewCategory, }: ExpenseGroupProps) { - let dragging = dragState && dragState.item === group; + const dragging = dragState && dragState.item === group; - let { dragRef } = useDraggable({ + const { dragRef } = useDraggable({ type: 'group', onDragChange, item: group, canDrag: editingCell === null, }); - let { dropRef, dropPos } = useDroppable({ + const { dropRef, dropPos } = useDroppable({ types: 'group', id: group.id, onDrop: onReorderGroup, }); - let { dropRef: catDropRef, dropPos: catDropPos } = useDroppable({ + const { dropRef: catDropRef, dropPos: catDropPos } = useDroppable({ types: 'category', id: group.id, onDrop: onReorderCategory, diff --git a/packages/desktop-client/src/components/budget/IncomeCategory.tsx b/packages/desktop-client/src/components/budget/IncomeCategory.tsx index 110da55231e56d6a2ca57e7a90858cd874411954..0d5625186da77a50cc60a493767d1db7b2da95c0 100644 --- a/packages/desktop-client/src/components/budget/IncomeCategory.tsx +++ b/packages/desktop-client/src/components/budget/IncomeCategory.tsx @@ -43,14 +43,14 @@ function IncomeCategory({ onReorder, onShowActivity, }: IncomeCategoryProps) { - let { dragRef } = useDraggable({ + const { dragRef } = useDraggable({ type: 'income-category', onDragChange, item: cat, canDrag: editingCell === null, }); - let { dropRef, dropPos } = useDroppable({ + const { dropRef, dropPos } = useDroppable({ types: 'income-category', id: cat.id, onDrop: onReorder, diff --git a/packages/desktop-client/src/components/budget/MobileBudget.js b/packages/desktop-client/src/components/budget/MobileBudget.js index 4f9e1601c18eb62310b2c539f0232059e8cc5067..8c3e7327c65db14682d8dbb9fd47739ff7656d7c 100644 --- a/packages/desktop-client/src/components/budget/MobileBudget.js +++ b/packages/desktop-client/src/components/budget/MobileBudget.js @@ -41,7 +41,7 @@ class Budget extends Component { } async loadCategories() { - let result = await this.props.getCategories(); + const result = await this.props.getCategories(); this.setState({ categoryGroups: result.grouped }); } @@ -63,7 +63,7 @@ class Budget extends Component { this.setState({ initialized: true }); - let unlisten = listen('sync-event', ({ type, tables }) => { + const unlisten = listen('sync-event', ({ type, tables }) => { if ( type === 'success' && (tables.includes('categories') || @@ -145,14 +145,14 @@ class Budget extends Component { }; onDeleteGroup = async groupId => { - let group = this.state.categoryGroups?.find(g => g.id === groupId); + const group = this.state.categoryGroups?.find(g => g.id === groupId); if (!group) { return; } let mustTransfer = false; - for (let category of group.categories) { + for (const category of group.categories) { if (await send('must-category-transfer', { id: category.id })) { mustTransfer = true; break; @@ -210,21 +210,22 @@ class Budget extends Component { }; onReorderCategory = (id, { inGroup, aroundCategory }) => { - let { categoryGroups } = this.state; + const { categoryGroups } = this.state; let groupId, targetId; if (inGroup) { groupId = inGroup; } else if (aroundCategory) { - let { id: catId, position } = aroundCategory; + const { id: originalCatId, position } = aroundCategory; - let group = categoryGroups.find(group => + let catId = originalCatId; + const group = categoryGroups.find(group => group.categories.find(cat => cat.id === catId), ); if (position === 'bottom') { - let { categories } = group; - let idx = categories.findIndex(cat => cat.id === catId); + const { categories } = group; + const idx = categories.findIndex(cat => cat.id === catId); catId = idx < categories.length - 1 ? categories[idx + 1].id : null; } @@ -240,10 +241,10 @@ class Budget extends Component { }; onReorderGroup = (id, targetId, position) => { - let { categoryGroups } = this.state; + const { categoryGroups } = this.state; if (position === 'bottom') { - let idx = categoryGroups.findIndex(group => group.id === targetId); + const idx = categoryGroups.findIndex(group => group.id === targetId); targetId = idx < categoryGroups.length - 1 ? categoryGroups[idx + 1].id : null; } @@ -266,23 +267,23 @@ class Budget extends Component { }; onPrevMonth = async () => { - let { spreadsheet, budgetType } = this.props; - let month = monthUtils.subMonths(this.state.currentMonth, 1); + const { spreadsheet, budgetType } = this.props; + const month = monthUtils.subMonths(this.state.currentMonth, 1); await prewarmMonth(budgetType, spreadsheet, month); this.setState({ currentMonth: month, initialized: true }); }; onNextMonth = async () => { - let { spreadsheet, budgetType } = this.props; - let month = monthUtils.addMonths(this.state.currentMonth, 1); + const { spreadsheet, budgetType } = this.props; + const month = monthUtils.addMonths(this.state.currentMonth, 1); await prewarmMonth(budgetType, spreadsheet, month); this.setState({ currentMonth: month, initialized: true }); }; onOpenActionSheet = () => { - let { budgetType } = this.props; + const { budgetType } = this.props; - let options = [ + const options = [ 'Edit Categories', 'Copy last month’s budget', 'Set budgets to zero', @@ -352,8 +353,8 @@ class Budget extends Component { applyBudgetAction, pushModal, } = this.props; - let numberFormat = prefs.numberFormat || 'comma-dot'; - let hideFraction = prefs.hideFraction || false; + const numberFormat = prefs.numberFormat || 'comma-dot'; + const hideFraction = prefs.hideFraction || false; if (!categoryGroups || !initialized) { return ( @@ -414,14 +415,14 @@ class Budget extends Component { } export default function BudgetWrapper() { - let { list: categories, grouped: categoryGroups } = useCategories(); - let budgetType = useSelector( + const { list: categories, grouped: categoryGroups } = useCategories(); + const budgetType = useSelector( state => state.prefs.local.budgetType || 'rollover', ); - let prefs = useSelector(state => state.prefs.local); + const prefs = useSelector(state => state.prefs.local); - let actions = useActions(); - let spreadsheet = useSpreadsheet(); + const actions = useActions(); + const spreadsheet = useSpreadsheet(); useSetThemeColor(theme.mobileViewTheme); return ( <Budget diff --git a/packages/desktop-client/src/components/budget/MobileBudgetTable.js b/packages/desktop-client/src/components/budget/MobileBudgetTable.js index 0190840d57839279ade9fc5bd00649909c58b059..4f8e81107c107377589bf384108759ae42632065 100644 --- a/packages/desktop-client/src/components/budget/MobileBudgetTable.js +++ b/packages/desktop-client/src/components/budget/MobileBudgetTable.js @@ -40,7 +40,7 @@ import RolloverBudgetBalanceTooltip from './rollover/BalanceTooltip'; import { makeAmountGrey } from './util'; function ToBudget({ toBudget, onClick }) { - let amount = useSheetValue(toBudget); + const amount = useSheetValue(toBudget); return ( <Button type="bare" @@ -70,12 +70,12 @@ function ToBudget({ toBudget, onClick }) { } function Saved({ projected, onClick }) { - let binding = projected + const binding = projected ? reportBudget.totalBudgetedSaved : reportBudget.totalSaved; - let saved = useSheetValue(binding) || 0; - let isNegative = saved < 0; + const saved = useSheetValue(binding) || 0; + const isNegative = saved < 0; return ( <Button @@ -135,7 +135,7 @@ function BudgetCell({ onEdit, isEditing, }) { - let sheetValue = useSheetValue(binding); + const sheetValue = useSheetValue(binding); function updateBudgetAmount(amount) { onBudgetAction?.(month, 'budget-amount', { @@ -255,14 +255,14 @@ const ExpenseCategory = memo(function ExpenseCategory({ show3Cols, showBudgetedCol, }) { - let opacity = blank ? 0 : 1; - let showEditables = editMode || isEditing; + const opacity = blank ? 0 : 1; + const showEditables = editMode || isEditing; - let [categoryName, setCategoryName] = useState(category.name); - let [isHidden, setIsHidden] = useState(category.hidden); + const [categoryName, setCategoryName] = useState(category.name); + const [isHidden, setIsHidden] = useState(category.hidden); - let tooltip = useTooltip(); - let balanceTooltip = useTooltip(); + const tooltip = useTooltip(); + const balanceTooltip = useTooltip(); useEffect(() => { if (isBudgetActionMenuOpen) { @@ -276,7 +276,7 @@ const ExpenseCategory = memo(function ExpenseCategory({ } }, [isEditing, tooltip]); - let onSubmit = () => { + const onSubmit = () => { if (categoryName) { onSave?.({ ...category, @@ -288,7 +288,7 @@ const ExpenseCategory = memo(function ExpenseCategory({ onEdit?.(null); }; - let onMenuSelect = type => { + const onMenuSelect = type => { onEdit?.(null); switch (type) { case 'toggle-visibility': @@ -306,10 +306,10 @@ const ExpenseCategory = memo(function ExpenseCategory({ } }; - let listItemRef = useRef(); - let inputRef = useRef(); + const listItemRef = useRef(); + const inputRef = useRef(); - let _onBudgetAction = (monthIndex, action, arg) => { + const _onBudgetAction = (monthIndex, action, arg) => { onBudgetAction?.( monthUtils.getMonthFromIndex(monthUtils.getYear(month), monthIndex), action, @@ -317,7 +317,7 @@ const ExpenseCategory = memo(function ExpenseCategory({ ); }; - let content = ( + const content = ( <ListItem style={{ backgroundColor: isEditingBudget @@ -555,13 +555,13 @@ const ExpenseGroupTotals = memo(function ExpenseGroupTotals({ show3Cols, showBudgetedCol, }) { - let opacity = blank ? 0 : 1; - let showEditables = editMode || isEditing; + const opacity = blank ? 0 : 1; + const showEditables = editMode || isEditing; - let [groupName, setGroupName] = useState(group.name); - let [isHidden, setIsHidden] = useState(group.hidden); + const [groupName, setGroupName] = useState(group.name); + const [isHidden, setIsHidden] = useState(group.hidden); - let tooltip = useTooltip(); + const tooltip = useTooltip(); useEffect(() => { if (!isEditing && tooltip.isOpen) { @@ -569,7 +569,7 @@ const ExpenseGroupTotals = memo(function ExpenseGroupTotals({ } }, [isEditing]); - let onSubmit = () => { + const onSubmit = () => { if (groupName) { onSave?.({ ...group, @@ -581,7 +581,7 @@ const ExpenseGroupTotals = memo(function ExpenseGroupTotals({ onEdit?.(null); }; - let onMenuSelect = type => { + const onMenuSelect = type => { onEdit?.(null); switch (type) { case 'add-category': @@ -602,10 +602,10 @@ const ExpenseGroupTotals = memo(function ExpenseGroupTotals({ } }; - let listItemRef = useRef(); - let inputRef = useRef(); + const listItemRef = useRef(); + const inputRef = useRef(); - let content = ( + const content = ( <ListItem style={{ flexDirection: 'row', @@ -811,11 +811,11 @@ const IncomeGroupTotals = memo(function IncomeGroupTotals({ isEditing, onEdit, }) { - let [groupName, setGroupName] = useState(group.name); - let [isHidden, setIsHidden] = useState(group.hidden); - let showEditables = editMode || isEditing; + const [groupName, setGroupName] = useState(group.name); + const [isHidden, setIsHidden] = useState(group.hidden); + const showEditables = editMode || isEditing; - let tooltip = useTooltip(); + const tooltip = useTooltip(); useEffect(() => { if (!isEditing && tooltip.isOpen) { @@ -823,7 +823,7 @@ const IncomeGroupTotals = memo(function IncomeGroupTotals({ } }, [isEditing]); - let onSubmit = () => { + const onSubmit = () => { if (groupName) { onSave?.({ ...group, @@ -835,7 +835,7 @@ const IncomeGroupTotals = memo(function IncomeGroupTotals({ onEdit?.(null); }; - let onMenuSelect = type => { + const onMenuSelect = type => { onEdit?.(null); switch (type) { case 'add-category': @@ -856,8 +856,8 @@ const IncomeGroupTotals = memo(function IncomeGroupTotals({ } }; - let listItemRef = useRef(); - let inputRef = useRef(); + const listItemRef = useRef(); + const inputRef = useRef(); return ( <ListItem @@ -1019,11 +1019,11 @@ const IncomeCategory = memo(function IncomeCategory({ isEditingBudget, onEditBudget, }) { - let [categoryName, setCategoryName] = useState(category.name); - let [isHidden, setIsHidden] = useState(category.hidden); - let showEditables = editMode || isEditing; + const [categoryName, setCategoryName] = useState(category.name); + const [isHidden, setIsHidden] = useState(category.hidden); + const showEditables = editMode || isEditing; - let tooltip = useTooltip(); + const tooltip = useTooltip(); useEffect(() => { if (!isEditing && tooltip.isOpen) { @@ -1031,7 +1031,7 @@ const IncomeCategory = memo(function IncomeCategory({ } }, [isEditing]); - let onSubmit = () => { + const onSubmit = () => { if (categoryName) { onSave?.({ ...category, @@ -1043,7 +1043,7 @@ const IncomeCategory = memo(function IncomeCategory({ onEdit?.(null); }; - let onMenuSelect = type => { + const onMenuSelect = type => { onEdit?.(null); switch (type) { case 'toggle-visibility': @@ -1061,8 +1061,8 @@ const IncomeCategory = memo(function IncomeCategory({ } }; - let listItemRef = useRef(); - let inputRef = useRef(); + const listItemRef = useRef(); + const inputRef = useRef(); return ( <ListItem @@ -1694,7 +1694,7 @@ export function BudgetTable(props) { const show3Cols = width >= 360; // let editMode = false; // neuter editMode -- sorry, not rewriting drag-n-drop right now - let format = useFormat(); + const format = useFormat(); const mobileShowBudgetedColPref = useSelector(state => { return state.prefs?.local?.toggleMobileDisplayPref || true; @@ -1704,7 +1704,7 @@ export function BudgetTable(props) { return state.prefs?.local?.['budget.showHiddenCategories'] || false; }); - let [showBudgetedCol, setShowBudgetedCol] = useState( + const [showBudgetedCol, setShowBudgetedCol] = useState( !mobileShowBudgetedColPref && !document.cookie.match(/mobileShowBudgetedColPref=true/), ); @@ -1716,7 +1716,7 @@ export function BudgetTable(props) { } } - let buttonStyle = { + const buttonStyle = { padding: 0, backgroundColor: 'transparent', borderRadius: 'unset', @@ -1995,10 +1995,10 @@ function BudgetMenu({ onToggleHiddenCategories, onSwitchBudgetType, }) { - let tooltip = useTooltip(); - let isReportBudgetEnabled = useFeatureFlag('reportBudget'); + const tooltip = useTooltip(); + const isReportBudgetEnabled = useFeatureFlag('reportBudget'); - let onMenuSelect = name => { + const onMenuSelect = name => { tooltip.close(); switch (name) { case 'edit-mode': @@ -2062,10 +2062,10 @@ function BudgetMenu({ } function MonthSelector({ month, monthBounds, onPrevMonth, onNextMonth }) { - let prevEnabled = month > monthBounds.start; - let nextEnabled = month < monthUtils.subMonths(monthBounds.end, 1); + const prevEnabled = month > monthBounds.start; + const nextEnabled = month < monthUtils.subMonths(monthBounds.end, 1); - let arrowButtonStyle = { + const arrowButtonStyle = { padding: 10, margin: 2, }; diff --git a/packages/desktop-client/src/components/budget/MonthCountSelector.tsx b/packages/desktop-client/src/components/budget/MonthCountSelector.tsx index 8a325e18f23ded9d3883de6db5641ff6d2224592..c3509bc20bca535a1e5d35aaa2e6f2bb0d67b3d8 100644 --- a/packages/desktop-client/src/components/budget/MonthCountSelector.tsx +++ b/packages/desktop-client/src/components/budget/MonthCountSelector.tsx @@ -29,7 +29,7 @@ export function MonthCountSelector({ maxMonths, onChange, }: MonthCountSelectorProps) { - let { displayMax } = useBudgetMonthCount(); + const { displayMax } = useBudgetMonthCount(); // It doesn't make sense to show anything if we can only fit one // month @@ -37,7 +37,7 @@ export function MonthCountSelector({ return null; } - let calendars = []; + const calendars = []; for (let i = 1; i <= displayMax; i++) { calendars.push( <Calendar diff --git a/packages/desktop-client/src/components/budget/MonthPicker.tsx b/packages/desktop-client/src/components/budget/MonthPicker.tsx index 7ee9c2206c1864fbc52ac63cee0fe09f4b18c202..b80e8e740eeb3f1e4ec2ab22ebd91fde25856f43 100644 --- a/packages/desktop-client/src/components/budget/MonthPicker.tsx +++ b/packages/desktop-client/src/components/budget/MonthPicker.tsx @@ -57,7 +57,7 @@ export const MonthPicker = ({ ); }); - let yearHeadersShown = []; + const yearHeadersShown = []; return ( <View diff --git a/packages/desktop-client/src/components/budget/MonthsContext.tsx b/packages/desktop-client/src/components/budget/MonthsContext.tsx index 3292929dfdfc7025459033f2dd9704b319d80688..bca1acfe315c3f75a78f1102532d8f1533b4b747 100644 --- a/packages/desktop-client/src/components/budget/MonthsContext.tsx +++ b/packages/desktop-client/src/components/budget/MonthsContext.tsx @@ -23,7 +23,7 @@ type MonthsContextProps = { type: string; }; -export let MonthsContext = createContext<MonthsContextProps>(null); +export const MonthsContext = createContext<MonthsContextProps>(null); type MonthsProviderProps = { startMonth: string | undefined; @@ -40,9 +40,9 @@ export function MonthsProvider({ type, children, }: MonthsProviderProps) { - let endMonth = monthUtils.addMonths(startMonth, numMonths - 1); - let bounds = getValidMonthBounds(monthBounds, startMonth, endMonth); - let months = monthUtils.rangeInclusive(bounds.start, bounds.end); + const endMonth = monthUtils.addMonths(startMonth, numMonths - 1); + const bounds = getValidMonthBounds(monthBounds, startMonth, endMonth); + const months = monthUtils.rangeInclusive(bounds.start, bounds.end); return ( <MonthsContext.Provider value={{ months, type }}> diff --git a/packages/desktop-client/src/components/budget/RenderMonths.tsx b/packages/desktop-client/src/components/budget/RenderMonths.tsx index 362ebafcec4946cb66e312c4288eb4349e58b1c3..649734d97550cd75dc256b2b6f83011642b2e285 100644 --- a/packages/desktop-client/src/components/budget/RenderMonths.tsx +++ b/packages/desktop-client/src/components/budget/RenderMonths.tsx @@ -25,10 +25,10 @@ function RenderMonths({ args, style, }: RenderMonthsProps) { - let { months } = useContext(MonthsContext); + const { months } = useContext(MonthsContext); return months.map((month, index) => { - let editing = editingIndex === index; + const editing = editingIndex === index; return ( <NamespaceContext.Provider diff --git a/packages/desktop-client/src/components/budget/index.tsx b/packages/desktop-client/src/components/budget/index.tsx index d72b15de959b8a205e75e5d883e40ea69efb1d3f..db90edc081706b31a876dbec7059798050d5be41 100644 --- a/packages/desktop-client/src/components/budget/index.tsx +++ b/packages/desktop-client/src/components/budget/index.tsx @@ -122,17 +122,17 @@ function Budget(props: BudgetProps) { ); async function loadCategories() { - let result = await props.getCategories(); + const result = await props.getCategories(); setCategoryGroups(result.grouped); } useEffect(() => { - let { titlebar, budgetType } = props; + const { titlebar, budgetType } = props; async function run() { loadCategories(); - let { start, end } = await send('get-budget-bounds'); + const { start, end } = await send('get-budget-bounds'); setBounds({ start, end }); await prewarmAllMonths( @@ -147,7 +147,7 @@ function Budget(props: BudgetProps) { run(); - let unlistens = [ + const unlistens = [ listen('sync-event', ({ type, tables }) => { if ( type === 'success' && @@ -255,7 +255,7 @@ function Budget(props: BudgetProps) { }; const onSaveCategory = async category => { - let exists = + const exists = (await props.getCategories()).grouped .filter(g => g.id === category.cat_group)[0] .categories.filter( @@ -270,7 +270,7 @@ function Budget(props: BudgetProps) { } if (category.id === 'new') { - let id = await props.createCategory( + const id = await props.createCategory( category.name, category.cat_group, category.is_income, @@ -313,7 +313,7 @@ function Budget(props: BudgetProps) { const onSaveGroup = async group => { if (group.id === 'new') { - let id = await props.createGroup(group.name); + const id = await props.createGroup(group.name); setIsAddingGroup(false); setCategoryGroups(state => addGroup(state, { @@ -330,10 +330,10 @@ function Budget(props: BudgetProps) { }; const onDeleteGroup = async id => { - let group = categoryGroups.find(g => g.id === id); + const group = categoryGroups.find(g => g.id === id); let mustTransfer = false; - for (let category of group.categories) { + for (const category of group.categories) { if (await send('must-category-transfer', { id: category.id })) { mustTransfer = true; break; @@ -377,9 +377,9 @@ function Budget(props: BudgetProps) { }; const onReorderCategory = async sortInfo => { - let cats = await props.getCategories(); - let moveCandidate = cats.list.filter(c => c.id === sortInfo.id)[0]; - let exists = + const cats = await props.getCategories(); + const moveCandidate = cats.list.filter(c => c.id === sortInfo.id)[0]; + const exists = cats.grouped .filter(g => g.id === sortInfo.groupId)[0] .categories.filter( @@ -406,7 +406,7 @@ function Budget(props: BudgetProps) { }; const onToggleCollapse = () => { - let collapsed = !summaryCollapsed; + const collapsed = !summaryCollapsed; setSummaryCollapsed(collapsed); props.savePrefs({ 'budget.summaryCollapsed': collapsed }); }; @@ -427,14 +427,14 @@ function Budget(props: BudgetProps) { } }; - let { - maxMonths, + const { + maxMonths: originalMaxMonths, budgetType: type, reportComponents, rolloverComponents, } = props; - maxMonths = maxMonths || 1; + const maxMonths = originalMaxMonths || 1; if (!initialized || !categoryGroups) { return null; @@ -532,27 +532,29 @@ const RolloverBudgetSummary = memo<{ month: string }>(props => { }); export default function BudgetWrapper(props) { - let startMonth = useSelector(state => state.prefs.local['budget.startMonth']); - let collapsedPrefs = useSelector( + const startMonth = useSelector( + state => state.prefs.local['budget.startMonth'], + ); + const collapsedPrefs = useSelector( state => state.prefs.local['budget.collapsed'], ); - let summaryCollapsed = useSelector( + const summaryCollapsed = useSelector( state => state.prefs.local['budget.summaryCollapsed'], ); - let budgetType = useSelector( + const budgetType = useSelector( state => state.prefs.local.budgetType || 'rollover', ); - let maxMonths = useSelector(state => state.prefs.global.maxMonths); - let { grouped: categoryGroups } = useCategories(); + const maxMonths = useSelector(state => state.prefs.global.maxMonths); + const { grouped: categoryGroups } = useCategories(); - let actions = useActions(); - let spreadsheet = useSpreadsheet(); - let titlebar = useContext(TitlebarContext); - let location = useLocation(); - let match = useMatch(location.pathname); - let navigate = useNavigate(); + const actions = useActions(); + const spreadsheet = useSpreadsheet(); + const titlebar = useContext(TitlebarContext); + const location = useLocation(); + const match = useMatch(location.pathname); + const navigate = useNavigate(); - let reportComponents = useMemo<ReportComponents>( + const reportComponents = useMemo<ReportComponents>( () => ({ SummaryComponent: report.BudgetSummary, ExpenseCategoryComponent: report.ExpenseCategoryMonth, @@ -565,7 +567,7 @@ export default function BudgetWrapper(props) { [report], ); - let rolloverComponents = useMemo<RolloverComponents>( + const rolloverComponents = useMemo<RolloverComponents>( () => ({ SummaryComponent: RolloverBudgetSummary, ExpenseCategoryComponent: rollover.ExpenseCategoryMonth, diff --git a/packages/desktop-client/src/components/budget/report/BalanceTooltip.tsx b/packages/desktop-client/src/components/budget/report/BalanceTooltip.tsx index 4d34915a5e39adfcf7a0ccae58e181a18784f16d..c1c297518a821cec0b8ab7f448a02351788f705a 100644 --- a/packages/desktop-client/src/components/budget/report/BalanceTooltip.tsx +++ b/packages/desktop-client/src/components/budget/report/BalanceTooltip.tsx @@ -22,9 +22,9 @@ export default function BalanceTooltip({ onClose, ...tooltipProps }: BalanceTooltipProps) { - let carryover = useSheetValue(reportBudget.catCarryover(categoryId)); + const carryover = useSheetValue(reportBudget.catCarryover(categoryId)); - let _onClose = () => { + const _onClose = () => { tooltip.close(); onClose?.(); }; diff --git a/packages/desktop-client/src/components/budget/report/ReportComponents.tsx b/packages/desktop-client/src/components/budget/report/ReportComponents.tsx index 1d3d03bb8d36852be59295736b06adda39f0db68..ed38d3bab9d7aae8a0624f6aa9d4e07d7ed4d896 100644 --- a/packages/desktop-client/src/components/budget/report/ReportComponents.tsx +++ b/packages/desktop-client/src/components/budget/report/ReportComponents.tsx @@ -20,7 +20,7 @@ import { makeAmountGrey } from '../util'; import BalanceTooltip from './BalanceTooltip'; -let headerLabelStyle: CSSProperties = { +const headerLabelStyle: CSSProperties = { flex: 1, padding: '0 5px', textAlign: 'right', @@ -91,7 +91,7 @@ type GroupMonthProps = { group: { id: string; is_income: boolean }; }; export const GroupMonth = memo(function GroupMonth({ group }: GroupMonthProps) { - let { id } = group; + const { id } = group; return ( <View style={{ flex: 1, flexDirection: 'row' }}> @@ -156,7 +156,7 @@ export const CategoryMonth = memo(function CategoryMonth({ onBudgetAction, onShowActivity, }: CategoryMonthProps) { - let balanceTooltip = useTooltip(); + const balanceTooltip = useTooltip(); const [menuOpen, setMenuOpen] = useState(false); const [hover, setHover] = useState(false); const isGoalTemplatesEnabled = useFeatureFlag('goalTemplatesEnabled'); diff --git a/packages/desktop-client/src/components/budget/report/ReportContext.tsx b/packages/desktop-client/src/components/budget/report/ReportContext.tsx index 3f746cfd5b0a0d0b48b782c96139b0247b3d0b1f..e38b4da869fbf76bcabe887e994bc87d3a2c55f6 100644 --- a/packages/desktop-client/src/components/budget/report/ReportContext.tsx +++ b/packages/desktop-client/src/components/budget/report/ReportContext.tsx @@ -2,7 +2,7 @@ import React, { type ReactNode, createContext, useContext } from 'react'; import * as monthUtils from 'loot-core/src/shared/months'; -let Context = createContext(null); +const Context = createContext(null); type ReportProviderProps = { summaryCollapsed: boolean; @@ -16,7 +16,7 @@ export function ReportProvider({ onToggleSummaryCollapse, children, }: ReportProviderProps) { - let currentMonth = monthUtils.currentMonth(); + const currentMonth = monthUtils.currentMonth(); return ( <Context.Provider diff --git a/packages/desktop-client/src/components/budget/report/budgetsummary/BudgetSummary.tsx b/packages/desktop-client/src/components/budget/report/budgetsummary/BudgetSummary.tsx index d1f726a7ed5e1caf478fe9cca8629895ce5fb133..58e18d32a0a8441416b9b3af4fd600ccae436079 100644 --- a/packages/desktop-client/src/components/budget/report/budgetsummary/BudgetSummary.tsx +++ b/packages/desktop-client/src/components/budget/report/budgetsummary/BudgetSummary.tsx @@ -26,7 +26,7 @@ type BudgetSummaryProps = { month?: string; }; export default function BudgetSummary({ month }: BudgetSummaryProps) { - let { + const { currentMonth, summaryCollapsed: collapsed, onBudgetAction, @@ -35,7 +35,7 @@ export default function BudgetSummary({ month }: BudgetSummaryProps) { const isGoalTemplatesEnabled = useFeatureFlag('goalTemplatesEnabled'); - let [menuOpen, setMenuOpen] = useState(false); + const [menuOpen, setMenuOpen] = useState(false); function onMenuOpen() { setMenuOpen(true); } @@ -44,7 +44,7 @@ export default function BudgetSummary({ month }: BudgetSummaryProps) { setMenuOpen(false); } - let ExpandOrCollapseIcon = collapsed ? ArrowButtonDown1 : ArrowButtonUp1; + const ExpandOrCollapseIcon = collapsed ? ArrowButtonDown1 : ArrowButtonUp1; return ( <View diff --git a/packages/desktop-client/src/components/budget/report/budgetsummary/ExpenseProgress.tsx b/packages/desktop-client/src/components/budget/report/budgetsummary/ExpenseProgress.tsx index 5f5120cdeb0e5ecbbf655aac307a5bef24c85b11..4613c95760681d240c4a93d4362badc8fa2ff60a 100644 --- a/packages/desktop-client/src/components/budget/report/budgetsummary/ExpenseProgress.tsx +++ b/packages/desktop-client/src/components/budget/report/budgetsummary/ExpenseProgress.tsx @@ -13,7 +13,7 @@ type ExpenseProgressProps = { }; export function ExpenseProgress({ current, target }: ExpenseProgressProps) { let totalSpent = useSheetValue(current) || 0; - let totalBudgeted = useSheetValue(target) || 0; + const totalBudgeted = useSheetValue(target) || 0; // Reverse total spent, and also set a bottom boundary of 0 (in case // income goes into an expense category and it's "positive", don't diff --git a/packages/desktop-client/src/components/budget/report/budgetsummary/IncomeProgress.tsx b/packages/desktop-client/src/components/budget/report/budgetsummary/IncomeProgress.tsx index 7a13d213d5a25aeb8e752ea30718fc1e63a8efc8..33f731711e70936a45156570ee9831ac5a06dad8 100644 --- a/packages/desktop-client/src/components/budget/report/budgetsummary/IncomeProgress.tsx +++ b/packages/desktop-client/src/components/budget/report/budgetsummary/IncomeProgress.tsx @@ -16,7 +16,7 @@ export default function IncomeProgress({ target, }: IncomeProgressProps) { let totalIncome = useSheetValue(current) || 0; - let totalBudgeted = useSheetValue(target) || 0; + const totalBudgeted = useSheetValue(target) || 0; let over = false; @@ -25,7 +25,7 @@ export default function IncomeProgress({ totalIncome = -totalIncome; } - let frac = fraction(totalIncome, totalBudgeted); + const frac = fraction(totalIncome, totalBudgeted); return ( <PieProgress diff --git a/packages/desktop-client/src/components/budget/report/budgetsummary/PieProgress.tsx b/packages/desktop-client/src/components/budget/report/budgetsummary/PieProgress.tsx index 32cba3df5cbfb35ddc7dcd440c09bf1d4c85d1a8..7f655168f0e7225da4f9dcd32e597c8cd05b9fac 100644 --- a/packages/desktop-client/src/components/budget/report/budgetsummary/PieProgress.tsx +++ b/packages/desktop-client/src/components/budget/report/budgetsummary/PieProgress.tsx @@ -12,10 +12,10 @@ export default function PieProgress({ color, backgroundColor, }: PieProgressProps) { - let radius = 4; - let circum = 2 * Math.PI * radius; - let dash = progress * circum; - let gap = circum; + const radius = 4; + const circum = 2 * Math.PI * radius; + const dash = progress * circum; + const gap = circum; return ( <svg viewBox="0 0 20 20" style={style}> diff --git a/packages/desktop-client/src/components/budget/report/budgetsummary/Saved.tsx b/packages/desktop-client/src/components/budget/report/budgetsummary/Saved.tsx index 8c8768e3e729a374a7eac7d3808e5bb396615529..80fbf1b74ace6a95a1a219925d426aa3501dc270 100644 --- a/packages/desktop-client/src/components/budget/report/budgetsummary/Saved.tsx +++ b/packages/desktop-client/src/components/budget/report/budgetsummary/Saved.tsx @@ -20,11 +20,11 @@ type SavedProps = { style?: CSSProperties; }; export default function Saved({ projected, style }: SavedProps) { - let budgetedSaved = useSheetValue(reportBudget.totalBudgetedSaved) || 0; - let totalSaved = useSheetValue(reportBudget.totalSaved) || 0; - let format = useFormat(); - let saved = projected ? budgetedSaved : totalSaved; - let isNegative = saved < 0; + const budgetedSaved = useSheetValue(reportBudget.totalBudgetedSaved) || 0; + const totalSaved = useSheetValue(reportBudget.totalSaved) || 0; + const format = useFormat(); + const saved = projected ? budgetedSaved : totalSaved; + const isNegative = saved < 0; return ( <View style={{ alignItems: 'center', fontSize: 14, ...style }}> @@ -39,7 +39,7 @@ export default function Saved({ projected, style }: SavedProps) { <HoverTarget renderContent={() => { if (!projected) { - let diff = totalSaved - budgetedSaved; + const diff = totalSaved - budgetedSaved; return ( <Tooltip position="bottom-center" diff --git a/packages/desktop-client/src/components/budget/rollover/BalanceTooltip.tsx b/packages/desktop-client/src/components/budget/rollover/BalanceTooltip.tsx index cf959c9a9459b9ee166bd5f9a5a3a49d62922e36..6df17d977bc25ef2749b299c4da668a90ee27815 100644 --- a/packages/desktop-client/src/components/budget/rollover/BalanceTooltip.tsx +++ b/packages/desktop-client/src/components/budget/rollover/BalanceTooltip.tsx @@ -24,11 +24,11 @@ export default function BalanceTooltip({ onClose, ...tooltipProps }: BalanceTooltipProps) { - let carryover = useSheetValue(rolloverBudget.catCarryover(categoryId)); - let balance = useSheetValue(rolloverBudget.catBalance(categoryId)); - let [menu, setMenu] = useState('menu'); + const carryover = useSheetValue(rolloverBudget.catCarryover(categoryId)); + const balance = useSheetValue(rolloverBudget.catBalance(categoryId)); + const [menu, setMenu] = useState('menu'); - let _onClose = () => { + const _onClose = () => { tooltip.close(); onClose?.(); }; diff --git a/packages/desktop-client/src/components/budget/rollover/CoverTooltip.tsx b/packages/desktop-client/src/components/budget/rollover/CoverTooltip.tsx index 9e24fcaf6828d43119fa079fc9d9f15305c62c5d..2605e5df23b460f49f8a3f4bb1a02be59751be76 100644 --- a/packages/desktop-client/src/components/budget/rollover/CoverTooltip.tsx +++ b/packages/desktop-client/src/components/budget/rollover/CoverTooltip.tsx @@ -22,7 +22,7 @@ export default function CoverTooltip({ categoryGroups = addToBeBudgetedGroup( categoryGroups.filter(g => !g.is_income), ); - let [category, setCategory] = useState(null); + const [category, setCategory] = useState(null); function submit() { if (category) { diff --git a/packages/desktop-client/src/components/budget/rollover/RolloverComponents.tsx b/packages/desktop-client/src/components/budget/rollover/RolloverComponents.tsx index 747770a7d869756ade95d099386e117666e2d35f..e34a1322d2f6875dc6abaf4013a4edb07ea780f8 100644 --- a/packages/desktop-client/src/components/budget/rollover/RolloverComponents.tsx +++ b/packages/desktop-client/src/components/budget/rollover/RolloverComponents.tsx @@ -20,7 +20,7 @@ import { makeAmountGrey } from '../util'; import BalanceTooltip from './BalanceTooltip'; -let headerLabelStyle: CSSProperties = { +const headerLabelStyle: CSSProperties = { flex: 1, padding: '0 5px', textAlign: 'right', @@ -89,7 +89,7 @@ type ExpenseGroupMonthProps = { export const ExpenseGroupMonth = memo(function ExpenseGroupMonth({ group, }: ExpenseGroupMonthProps) { - let { id } = group; + const { id } = group; return ( <View style={{ flex: 1, flexDirection: 'row' }}> @@ -152,7 +152,7 @@ export const ExpenseCategoryMonth = memo(function ExpenseCategoryMonth({ onBudgetAction, onShowActivity, }: ExpenseCategoryMonthProps) { - let balanceTooltip = useTooltip(); + const balanceTooltip = useTooltip(); const [menuOpen, setMenuOpen] = useState(false); const [hover, setHover] = useState(false); const isGoalTemplatesEnabled = useFeatureFlag('goalTemplatesEnabled'); diff --git a/packages/desktop-client/src/components/budget/rollover/RolloverContext.tsx b/packages/desktop-client/src/components/budget/rollover/RolloverContext.tsx index 7006ae78ee8498d939d9703df2376b4448a1e899..3d825c834e251a7fef00e07f7dc70f22e7d8b3ac 100644 --- a/packages/desktop-client/src/components/budget/rollover/RolloverContext.tsx +++ b/packages/desktop-client/src/components/budget/rollover/RolloverContext.tsx @@ -2,7 +2,7 @@ import React, { type ReactNode, createContext, useContext } from 'react'; import * as monthUtils from 'loot-core/src/shared/months'; -let Context = createContext(null); +const Context = createContext(null); type RolloverContextProps = { categoryGroups: unknown[]; @@ -18,7 +18,7 @@ export function RolloverContext({ onToggleSummaryCollapse, children, }: RolloverContextProps) { - let currentMonth = monthUtils.currentMonth(); + const currentMonth = monthUtils.currentMonth(); return ( <Context.Provider diff --git a/packages/desktop-client/src/components/budget/rollover/TransferTooltip.tsx b/packages/desktop-client/src/components/budget/rollover/TransferTooltip.tsx index 4aa10527c9e90831158afa8b11b441decb7ac80d..5e7c382165bfc71156dde24f5bb84fb6aa88f17e 100644 --- a/packages/desktop-client/src/components/budget/rollover/TransferTooltip.tsx +++ b/packages/desktop-client/src/components/budget/rollover/TransferTooltip.tsx @@ -34,8 +34,8 @@ export default function TransferTooltip({ position = 'bottom-right', ...props }: TransferTooltipProps) { - let spreadsheet = useSpreadsheet(); - let sheetName = useContext(NamespaceContext); + const spreadsheet = useSpreadsheet(); + const sheetName = useContext(NamespaceContext); let { grouped: categoryGroups } = useCategories(); categoryGroups = categoryGroups.filter(g => !g.is_income); @@ -43,8 +43,8 @@ export default function TransferTooltip({ categoryGroups = addToBeBudgetedGroup(categoryGroups); } - let [amount, setAmount] = useState(null); - let [category, setCategory] = useState(null); + const [amount, setAmount] = useState(null); + const [category, setCategory] = useState(null); useEffect(() => { (async () => { @@ -58,7 +58,7 @@ export default function TransferTooltip({ }, []); function submit() { - let parsedAmount = evalArithmetic(amount, null); + const parsedAmount = evalArithmetic(amount, null); if (parsedAmount && category) { onSubmit(amountToInteger(parsedAmount), category); onClose(); diff --git a/packages/desktop-client/src/components/budget/rollover/budgetsummary/BudgetSummary.tsx b/packages/desktop-client/src/components/budget/rollover/budgetsummary/BudgetSummary.tsx index 5cbf8f573430560bcde050b888d4d761f871314a..0a5c73b9c7afdb15af4cd8ac980f9acde1bb1441 100644 --- a/packages/desktop-client/src/components/budget/rollover/budgetsummary/BudgetSummary.tsx +++ b/packages/desktop-client/src/components/budget/rollover/budgetsummary/BudgetSummary.tsx @@ -27,14 +27,14 @@ export default function BudgetSummary({ month, isGoalTemplatesEnabled, }: BudgetSummaryProps) { - let { + const { currentMonth, summaryCollapsed: collapsed, onBudgetAction, onToggleSummaryCollapse, } = useRollover(); - let [menuOpen, setMenuOpen] = useState(false); + const [menuOpen, setMenuOpen] = useState(false); function onMenuOpen(e) { setMenuOpen(true); } @@ -43,9 +43,9 @@ export default function BudgetSummary({ setMenuOpen(false); } - let prevMonthName = monthUtils.format(monthUtils.prevMonth(month), 'MMM'); + const prevMonthName = monthUtils.format(monthUtils.prevMonth(month), 'MMM'); - let ExpandOrCollapseIcon = collapsed ? ArrowButtonDown1 : ArrowButtonUp1; + const ExpandOrCollapseIcon = collapsed ? ArrowButtonDown1 : ArrowButtonUp1; return ( <View diff --git a/packages/desktop-client/src/components/budget/rollover/budgetsummary/ToBudget.tsx b/packages/desktop-client/src/components/budget/rollover/budgetsummary/ToBudget.tsx index e024e322d928c0bc80a5ae64b52604bb89b18f82..184456c76936b26a76b3c0c293d52676ffdfe882 100644 --- a/packages/desktop-client/src/components/budget/rollover/budgetsummary/ToBudget.tsx +++ b/packages/desktop-client/src/components/budget/rollover/budgetsummary/ToBudget.tsx @@ -43,16 +43,16 @@ export default function ToBudget({ holdTooltipProps, transferTooltipProps, }: ToBudgetProps) { - let [menuOpen, setMenuOpen] = useState(null); - let sheetName = useSheetName(rolloverBudget.toBudget); - let sheetValue = useSheetValue({ + const [menuOpen, setMenuOpen] = useState(null); + const sheetName = useSheetName(rolloverBudget.toBudget); + const sheetValue = useSheetValue({ name: rolloverBudget.toBudget, value: 0, }); - let format = useFormat(); - let availableValue = parseInt(sheetValue); - let num = isNaN(availableValue) ? 0 : availableValue; - let isNegative = num < 0; + const format = useFormat(); + const availableValue = parseInt(sheetValue); + const num = isNaN(availableValue) ? 0 : availableValue; + const isNegative = num < 0; return ( <View style={{ alignItems: 'center', ...style }}> diff --git a/packages/desktop-client/src/components/budget/rollover/budgetsummary/TotalsList.tsx b/packages/desktop-client/src/components/budget/rollover/budgetsummary/TotalsList.tsx index 0805b8bacf020db7e8894aa39b8a3d1d79af070a..20a5fd4b9cfa07b80af169ce5825012d6b5d6e8c 100644 --- a/packages/desktop-client/src/components/budget/rollover/budgetsummary/TotalsList.tsx +++ b/packages/desktop-client/src/components/budget/rollover/budgetsummary/TotalsList.tsx @@ -75,7 +75,7 @@ export default function TotalsList({ prevMonthName, style }: TotalsListProps) { binding={rolloverBudget.lastMonthOverspent} type="financial" formatter={value => { - let v = format(value, 'financial'); + const v = format(value, 'financial'); return value > 0 ? '+' + v : value === 0 ? '-' + v : v; }} style={{ fontWeight: 600, ...styles.tnum }} @@ -85,7 +85,7 @@ export default function TotalsList({ prevMonthName, style }: TotalsListProps) { binding={rolloverBudget.totalBudgeted} type="financial" formatter={value => { - let v = format(value, 'financial'); + const v = format(value, 'financial'); return value > 0 ? '+' + v : value === 0 ? '-' + v : v; }} style={{ fontWeight: 600, ...styles.tnum }} @@ -95,8 +95,8 @@ export default function TotalsList({ prevMonthName, style }: TotalsListProps) { binding={rolloverBudget.forNextMonth} type="financial" formatter={value => { - let n = parseInt(value) || 0; - let v = format(Math.abs(n), 'financial'); + const n = parseInt(value) || 0; + const v = format(Math.abs(n), 'financial'); return n >= 0 ? '-' + v : '+' + v; }} style={{ fontWeight: 600, ...styles.tnum }} diff --git a/packages/desktop-client/src/components/budget/util.ts b/packages/desktop-client/src/components/budget/util.ts index 6e9f7dd1427d70f757885e9435256f4291c821e6..b1e7d7d5c2496169d8597b5b77032aff3ec6fc93 100644 --- a/packages/desktop-client/src/components/budget/util.ts +++ b/packages/desktop-client/src/components/budget/util.ts @@ -85,13 +85,13 @@ export function findSortDown( if (pos === 'top') { return { targetId }; } else { - let idx = arr.findIndex(item => item.id === targetId); + const idx = arr.findIndex(item => item.id === targetId); if (idx === -1) { throw new Error('findSort: item not found: ' + targetId); } - let newIdx = idx + 1; + const newIdx = idx + 1; if (newIdx < arr.length - 1) { return { targetId: arr[newIdx].id }; } else { @@ -109,13 +109,13 @@ export function findSortUp( if (pos === 'bottom') { return { targetId }; } else { - let idx = arr.findIndex(item => item.id === targetId); + const idx = arr.findIndex(item => item.id === targetId); if (idx === -1) { throw new Error('findSort: item not found: ' + targetId); } - let newIdx = idx - 1; + const newIdx = idx - 1; if (newIdx >= 0) { return { targetId: arr[newIdx].id }; } else { @@ -134,12 +134,12 @@ export async function prewarmMonth( spreadsheet: ReturnType<typeof useSpreadsheet>, month: string, ) { - let method: keyof Handlers = + const method: keyof Handlers = budgetType === 'report' ? 'report-budget-month' : 'rollover-budget-month'; - let values = await send(method, { month }); + const values = await send(method, { month }); - for (let value of values) { + for (const value of values) { spreadsheet.prewarmCache(value.name, value); } } @@ -150,14 +150,14 @@ export async function prewarmAllMonths( bounds: { start: string; end: string }, startMonth: string, ) { - let numMonths = 3; + const numMonths = 3; bounds = getValidMonthBounds( bounds, monthUtils.subMonths(startMonth, 1), monthUtils.addMonths(startMonth, numMonths + 1), ); - let months = monthUtils.rangeInclusive(bounds.start, bounds.end); + const months = monthUtils.rangeInclusive(bounds.start, bounds.end); await Promise.all( months.map(month => prewarmMonth(budgetType, spreadsheet, month)), diff --git a/packages/desktop-client/src/components/common/AnchorLink.tsx b/packages/desktop-client/src/components/common/AnchorLink.tsx index c1ea47493855dc828a1350cd0aaa7749bd0aeca2..2cc6ba3fd013e2538a100f43e32aa19e2ccec5f6 100644 --- a/packages/desktop-client/src/components/common/AnchorLink.tsx +++ b/packages/desktop-client/src/components/common/AnchorLink.tsx @@ -18,7 +18,7 @@ export default function AnchorLink({ activeStyle, children, }: AnchorLinkProps) { - let match = useMatch({ path: to }); + const match = useMatch({ path: to }); return ( <NavLink diff --git a/packages/desktop-client/src/components/common/Button.tsx b/packages/desktop-client/src/components/common/Button.tsx index a421059aed94ca0f5c8b61e4af046888f45465c0..f99e0adec7efde55c7975ad831a1f5b3f9c136ef 100644 --- a/packages/desktop-client/src/components/common/Button.tsx +++ b/packages/desktop-client/src/components/common/Button.tsx @@ -149,7 +149,7 @@ const Button = forwardRef<HTMLButtonElement, ButtonProps>( }, ref, ) => { - let typeWithDisabled = disabled ? type + 'Disabled' : type; + const typeWithDisabled = disabled ? type + 'Disabled' : type; hoveredStyle = { ...(type !== 'bare' && styles.shadow), @@ -163,8 +163,8 @@ const Button = forwardRef<HTMLButtonElement, ButtonProps>( ...activeStyle, }; - let Component = as; - let buttonStyle = { + const Component = as; + const buttonStyle = { alignItems: 'center', justifyContent: 'center', flexShrink: 0, @@ -211,7 +211,7 @@ export const ButtonWithLoading = forwardRef< HTMLButtonElement, ButtonWithLoadingProps >((props, ref) => { - let { loading, children, ...buttonProps } = props; + const { loading, children, ...buttonProps } = props; return ( <Button {...buttonProps} diff --git a/packages/desktop-client/src/components/common/ExternalLink.tsx b/packages/desktop-client/src/components/common/ExternalLink.tsx index 6c37ea5825a06a5f06556fad36fc0bf05b3db217..f31d240c9b540386cc0716d6888f8921f7612ca7 100644 --- a/packages/desktop-client/src/components/common/ExternalLink.tsx +++ b/packages/desktop-client/src/components/common/ExternalLink.tsx @@ -2,7 +2,7 @@ import React, { type ReactNode, forwardRef } from 'react'; import { theme } from '../../style'; -let externalLinkColors = { +const externalLinkColors = { purple: theme.pageTextPositive, blue: theme.pageTextLink, muted: 'inherit', diff --git a/packages/desktop-client/src/components/common/HoverTarget.tsx b/packages/desktop-client/src/components/common/HoverTarget.tsx index bbaa27b87d45cd5564e353f5561a198e671c6b7d..097ad9c013da88a58a776801239f477675d7b78e 100644 --- a/packages/desktop-client/src/components/common/HoverTarget.tsx +++ b/packages/desktop-client/src/components/common/HoverTarget.tsx @@ -19,7 +19,7 @@ export default function HoverTarget({ renderContent, disabled, }: HoverTargetProps) { - let [hovered, setHovered] = useState(false); + const [hovered, setHovered] = useState(false); const onPointerEnter = useCallback(() => { if (!disabled) { diff --git a/packages/desktop-client/src/components/common/InitialFocus.tsx b/packages/desktop-client/src/components/common/InitialFocus.tsx index 7c6ad0a651ecee514a4bfe08dfdfb9da1ee53c00..6f88cbb60f0a8cef7bf7decd0635590214b553a2 100644 --- a/packages/desktop-client/src/components/common/InitialFocus.tsx +++ b/packages/desktop-client/src/components/common/InitialFocus.tsx @@ -11,7 +11,7 @@ type InitialFocusProps = { }; export default function InitialFocus({ children }: InitialFocusProps) { - let node = useRef(null); + const node = useRef(null); useEffect(() => { if (node.current && !global.IS_DESIGN_MODE) { diff --git a/packages/desktop-client/src/components/common/Input.tsx b/packages/desktop-client/src/components/common/Input.tsx index d5284251426266b3118ffded1a80f53705055e30..6a4e6eaf96596ab705e29c0c003f012235eb54d7 100644 --- a/packages/desktop-client/src/components/common/Input.tsx +++ b/packages/desktop-client/src/components/common/Input.tsx @@ -37,7 +37,7 @@ export default function Input({ focused, ...nativeProps }: InputProps) { - let ref = useRef(); + const ref = useRef(); useProperFocus(ref, focused); return ( diff --git a/packages/desktop-client/src/components/common/InputWithContent.tsx b/packages/desktop-client/src/components/common/InputWithContent.tsx index 6321a7d857ce098521c0bf44a09bdf012ae5fc85..24b357342a8272b8c2182543e5dd8ed693e3e858 100644 --- a/packages/desktop-client/src/components/common/InputWithContent.tsx +++ b/packages/desktop-client/src/components/common/InputWithContent.tsx @@ -22,7 +22,7 @@ export default function InputWithContent({ getStyle, ...props }: InputWithContentProps) { - let [focused, setFocused] = useState(props.focused); + const [focused, setFocused] = useState(props.focused); return ( <View diff --git a/packages/desktop-client/src/components/common/Menu.tsx b/packages/desktop-client/src/components/common/Menu.tsx index be4382405f3ac76196eef93bcc9671d067025f19..1d0258cd77e7e294700571aa34e657bae252cff5 100644 --- a/packages/desktop-client/src/components/common/Menu.tsx +++ b/packages/desktop-client/src/components/common/Menu.tsx @@ -46,21 +46,21 @@ export default function Menu({ items: allItems, onMenuSelect, }: MenuProps) { - let elRef = useRef(null); - let items = allItems.filter(x => x); - let [hoveredIndex, setHoveredIndex] = useState(null); + const elRef = useRef(null); + const items = allItems.filter(x => x); + const [hoveredIndex, setHoveredIndex] = useState(null); useEffect(() => { const el = elRef.current; el.focus(); - let onKeyDown = e => { - let filteredItems = items.filter( + const onKeyDown = e => { + const filteredItems = items.filter( item => item && item !== Menu.line && item.type !== Menu.label, ); - let currentIndex = filteredItems.indexOf(items[hoveredIndex]); + const currentIndex = filteredItems.indexOf(items[hoveredIndex]); - let transformIndex = idx => items.indexOf(filteredItems[idx]); + const transformIndex = idx => items.indexOf(filteredItems[idx]); switch (e.key) { case 'ArrowUp': @@ -131,7 +131,7 @@ export default function Menu({ ); } - let lastItem = items[idx - 1]; + const lastItem = items[idx - 1]; return ( <View diff --git a/packages/desktop-client/src/components/common/Modal.tsx b/packages/desktop-client/src/components/common/Modal.tsx index a03bdd004b35176fd5c2e174a70c1c8c33121ff4..3eac7bf303b9a90598562bff9e4f8907b84458d4 100644 --- a/packages/desktop-client/src/components/common/Modal.tsx +++ b/packages/desktop-client/src/components/common/Modal.tsx @@ -64,7 +64,7 @@ const Modal = ({ // This deactivates any key handlers in the "app" scope. Ideally // each modal would have a name so they could each have their own // key handlers, but we'll do that later - let prevScope = hotkeys.getScope(); + const prevScope = hotkeys.getScope(); hotkeys.setScope('modal'); return () => hotkeys.setScope(prevScope); }, []); @@ -243,9 +243,9 @@ const ModalContent = ({ stackIndex, children, }: ModalContentProps) => { - let contentRef = useRef(null); - let mounted = useRef(false); - let rotateFactor = useRef(Math.random() * 10 - 5); + const contentRef = useRef(null); + const mounted = useRef(false); + const rotateFactor = useRef(Math.random() * 10 - 5); useLayoutEffect(() => { if (contentRef.current == null) { @@ -319,11 +319,11 @@ export const ModalButtons = ({ focusButton = false, children, }: ModalButtonsProps) => { - let containerRef = useRef(null); + const containerRef = useRef(null); useEffect(() => { if (focusButton && containerRef.current) { - let button = containerRef.current.querySelector( + const button = containerRef.current.querySelector( 'button:not([data-hidden])', ); diff --git a/packages/desktop-client/src/components/common/Stack.tsx b/packages/desktop-client/src/components/common/Stack.tsx index a59cf5a9fc374894e1ecec3a9493fc56da855e53..1a3df4f0f1daea5358af4e43f763758c940ede37 100644 --- a/packages/desktop-client/src/components/common/Stack.tsx +++ b/packages/desktop-client/src/components/common/Stack.tsx @@ -66,7 +66,7 @@ const Stack = forwardRef<HTMLDivElement, StackProps>( {...props} > {validChildren.map(({ key, child }, index) => { - let isLastChild = validChildren.length === index + 1; + const isLastChild = validChildren.length === index + 1; let marginProp; if (isHorizontal) { diff --git a/packages/desktop-client/src/components/filters/FiltersMenu.js b/packages/desktop-client/src/components/filters/FiltersMenu.js index 2c1b6d58e637a3fa90f31f0645113ab0e739fea6..16034382cca23eb8ca7ffb5fae76ed6dbcc91812 100644 --- a/packages/desktop-client/src/components/filters/FiltersMenu.js +++ b/packages/desktop-client/src/components/filters/FiltersMenu.js @@ -40,7 +40,7 @@ import CompactFiltersButton from './CompactFiltersButton'; import FiltersButton from './FiltersButton'; import { CondOpMenu } from './SavedFilters'; -let filterFields = [ +const filterFields = [ 'date', 'account', 'payee', @@ -119,7 +119,7 @@ function OpButton({ op, selected, style, onClick }) { function updateFilterReducer(state, action) { switch (action.type) { case 'set-op': { - let type = FIELD_TYPES.get(state.field); + const type = FIELD_TYPES.get(state.field); let value = state.value; if ( (type === 'id' || type === 'string') && @@ -135,7 +135,7 @@ function updateFilterReducer(state, action) { return { ...state, op: action.op, value }; } case 'set-value': { - let { value } = makeValue(action.value, { + const { value } = makeValue(action.value, { type: FIELD_TYPES.get(state.field), }); return { ...state, value }; @@ -153,9 +153,10 @@ function ConfigureField({ dispatch, onApply, }) { - let [subfield, setSubfield] = useState(initialSubfield); - let inputRef = useRef(); - let prevOp = useRef(null); + const [subfield, setSubfield] = useState(initialSubfield); + const inputRef = useRef(); + const prevOp = useRef(null); + useEffect(() => { if (prevOp.current !== op && inputRef.current) { inputRef.current.focus(); @@ -163,7 +164,7 @@ function ConfigureField({ prevOp.current = op; }, [op]); - let type = FIELD_TYPES.get(field); + const type = FIELD_TYPES.get(field); let ops = TYPE_INFO[type].ops.filter(op => op !== 'isbetween'); // Month and year fields are quite hacky right now! Figure out how @@ -337,23 +338,23 @@ function ConfigureField({ } export function FilterButton({ onApply, compact, hover }) { - let filters = useFilters(); + const filters = useFilters(); - let { dateFormat } = useSelector(state => { + const { dateFormat } = useSelector(state => { return { dateFormat: state.prefs.local.dateFormat || 'MM/dd/yyyy', }; }); - let [state, dispatch] = useReducer( + const [state, dispatch] = useReducer( (state, action) => { switch (action.type) { case 'select-field': return { ...state, fieldsOpen: true, condOpen: false }; case 'configure': { - let { field } = deserializeField(action.field); - let type = FIELD_TYPES.get(field); - let ops = TYPE_INFO[type].ops; + const { field } = deserializeField(action.field); + const type = FIELD_TYPES.get(field); + const ops = TYPE_INFO[type].ops; return { ...state, fieldsOpen: false, @@ -377,7 +378,7 @@ export function FilterButton({ onApply, compact, hover }) { if (cond.type === 'date' && cond.options) { if (cond.options.month) { - let date = parseDate( + const date = parseDate( cond.value, getMonthYearFormat(dateFormat), new Date(), @@ -389,7 +390,7 @@ export function FilterButton({ onApply, compact, hover }) { return; } } else if (cond.options.year) { - let date = parseDate(cond.value, 'yyyy', new Date()); + const date = parseDate(cond.value, 'yyyy', new Date()); if (isDateValid(date)) { cond.value = formatDate(date, 'yyyy'); } else { @@ -399,17 +400,17 @@ export function FilterButton({ onApply, compact, hover }) { } } - let { error } = + const { error } = cond.field !== 'saved' && (await send('rule-validate', { conditions: [cond], actions: [], })); - let saved = filters.find(f => cond.value === f.id); + const saved = filters.find(f => cond.value === f.id); if (error && error.conditionErrors.length > 0) { - let field = titleFirst(mapField(cond.field)); + const field = titleFirst(mapField(cond.field)); alert(field + ': ' + getFieldError(error.conditionErrors[0])); } else { onApply(saved ? saved : cond); @@ -477,7 +478,7 @@ export function FilterButton({ onApply, compact, hover }) { } function FilterEditor({ field, op, value, options, onSave, onClose }) { - let [state, dispatch] = useReducer( + const [state, dispatch] = useReducer( (state, action) => { switch (action.type) { case 'close': @@ -518,9 +519,10 @@ function FilterExpression({ onChange, onDelete, }) { - let [editing, setEditing] = useState(false); + const [editing, setEditing] = useState(false); + + const field = subfieldFromFilter({ field: originalField, value }); - let field = subfieldFromFilter({ field: originalField, value }); return ( <View style={{ diff --git a/packages/desktop-client/src/components/filters/SavedFilters.js b/packages/desktop-client/src/components/filters/SavedFilters.js index 31f88898f25fb11cd7f9b2454c735d8844245613..fce9af440cdcb6f316da7bcb9fe46606f48f51ce 100644 --- a/packages/desktop-client/src/components/filters/SavedFilters.js +++ b/packages/desktop-client/src/components/filters/SavedFilters.js @@ -67,7 +67,7 @@ function NameFilter({ onAddUpdate, err, }) { - let inputRef = useRef(); + const inputRef = useRef(); useEffect(() => { if (inputRef.current) { @@ -130,13 +130,13 @@ function SavedFilterMenuButton({ onReloadSavedFilter, filtersList, }) { - let [nameOpen, setNameOpen] = useState(false); - let [adding, setAdding] = useState(false); - let [menuOpen, setMenuOpen] = useState(false); - let [err, setErr] = useState(null); - let [menuItem, setMenuItem] = useState(null); - let [name, setName] = useState(filterId.name); - let id = filterId.id; + const [nameOpen, setNameOpen] = useState(false); + const [adding, setAdding] = useState(false); + const [menuOpen, setMenuOpen] = useState(false); + const [err, setErr] = useState(null); + const [menuItem, setMenuItem] = useState(null); + const [name, setName] = useState(filterId.name); + const id = filterId.id; let res; let savedFilter; diff --git a/packages/desktop-client/src/components/manager/BudgetList.js b/packages/desktop-client/src/components/manager/BudgetList.js index 0f57c29f954266d28fac6acae4e86af69b96eced..0d702504f3816d5e069355d81e33bb2d2eed9d48 100644 --- a/packages/desktop-client/src/components/manager/BudgetList.js +++ b/packages/desktop-client/src/components/manager/BudgetList.js @@ -51,13 +51,13 @@ function FileMenu({ onDelete, onClose }) { } } - let items = [{ name: 'delete', text: 'Delete' }]; + const items = [{ name: 'delete', text: 'Delete' }]; return <Menu onMenuSelect={onMenuSelect} items={items} />; } function DetailButton({ state, onDelete }) { - let [menuOpen, setMenuOpen] = useState(false); + const [menuOpen, setMenuOpen] = useState(false); return ( <View> @@ -137,7 +137,7 @@ function FileState({ file }) { } function File({ file, onSelect, onDelete }) { - let selecting = useRef(false); + const selecting = useRef(false); async function _onSelect(file) { // Never allow selecting the file while uploading/downloading, and @@ -223,7 +223,7 @@ function BudgetTable({ files, onSelect, onDelete }) { } function RefreshButton({ onRefresh }) { - let [loading, setLoading] = useState(false); + const [loading, setLoading] = useState(false); async function _onRefresh() { setLoading(true); @@ -231,7 +231,7 @@ function RefreshButton({ onRefresh }) { setLoading(false); } - let Icon = loading ? Loading : RefreshArrow; + const Icon = loading ? Loading : RefreshArrow; return ( <Button @@ -246,9 +246,9 @@ function RefreshButton({ onRefresh }) { } export default function BudgetList() { - let files = useSelector(state => state.budgets.allFiles || []); + const files = useSelector(state => state.budgets.allFiles || []); - let { + const { getUserData, loadAllFiles, pushModal, diff --git a/packages/desktop-client/src/components/manager/ConfigServer.tsx b/packages/desktop-client/src/components/manager/ConfigServer.tsx index cda664eb51aa85228679e1678cc29c7232bb001d..20cf42356f7ac6e677070540da8cdfaeae390891 100644 --- a/packages/desktop-client/src/components/manager/ConfigServer.tsx +++ b/packages/desktop-client/src/components/manager/ConfigServer.tsx @@ -19,16 +19,16 @@ import { Title } from './subscribe/common'; export default function ConfigServer() { useSetThemeColor(theme.mobileConfigServerViewTheme); - let { createBudget, signOut, loggedIn } = useActions(); - let navigate = useNavigate(); - let [url, setUrl] = useState(''); - let currentUrl = useServerURL(); - let setServerUrl = useSetServerURL(); + const { createBudget, signOut, loggedIn } = useActions(); + const navigate = useNavigate(); + const [url, setUrl] = useState(''); + const currentUrl = useServerURL(); + const setServerUrl = useSetServerURL(); useEffect(() => { setUrl(currentUrl); }, [currentUrl]); - let [loading, setLoading] = useState(false); - let [error, setError] = useState<string | null>(null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState<string | null>(null); function getErrorMessage(error: string) { switch (error) { @@ -46,14 +46,14 @@ export default function ConfigServer() { setError(null); setLoading(true); - let { error } = await setServerUrl(url); + const { error } = await setServerUrl(url); if ( ['network-failure', 'get-server-failure'].includes(error) && !url.startsWith('http://') && !url.startsWith('https://') ) { - let { error } = await setServerUrl('https://' + url); + const { error } = await setServerUrl('https://' + url); if (error) { setUrl('https://' + url); setError(error); diff --git a/packages/desktop-client/src/components/manager/DeleteFile.js b/packages/desktop-client/src/components/manager/DeleteFile.js index 28eb1dc3fa5c432e1fa253828a297555bdee5e78..a801fa346afad02637c9d9211b1b3fcaec98edd5 100644 --- a/packages/desktop-client/src/components/manager/DeleteFile.js +++ b/packages/desktop-client/src/components/manager/DeleteFile.js @@ -7,7 +7,7 @@ import Text from '../common/Text'; import View from '../common/View'; export default function DeleteMenu({ modalProps, actions, file }) { - let [loadingState, setLoadingState] = useState(null); + const [loadingState, setLoadingState] = useState(null); async function onDeleteCloud() { setLoadingState('cloud'); @@ -28,7 +28,7 @@ export default function DeleteMenu({ modalProps, actions, file }) { // If the state is "broken" that means it was created by another // user. The current user should be able to delete the local file, // but not the remote one - let isRemote = file.cloudFileId && file.state !== 'broken'; + const isRemote = file.cloudFileId && file.state !== 'broken'; return ( <Modal diff --git a/packages/desktop-client/src/components/manager/Import.tsx b/packages/desktop-client/src/components/manager/Import.tsx index 23854fe2c1783e7beabf9efbe75a3c86be4470d3..823a565cdf094afcc7b1654410e5d631f1a69deb 100644 --- a/packages/desktop-client/src/components/manager/Import.tsx +++ b/packages/desktop-client/src/components/manager/Import.tsx @@ -41,7 +41,7 @@ function Import({ modalProps, actions }: ImportProps) { } } - let itemStyle = { + const itemStyle = { padding: 10, border: '1px solid ' + theme.tableBorder, borderRadius: 6, diff --git a/packages/desktop-client/src/components/manager/ManagementApp.js b/packages/desktop-client/src/components/manager/ManagementApp.js index 3e61c09b76042ff8e5219e69c58b15a9cf3e612e..d72cf414103a299796b920891bf2c8931b143f5c 100644 --- a/packages/desktop-client/src/components/manager/ManagementApp.js +++ b/packages/desktop-client/src/components/manager/ManagementApp.js @@ -48,13 +48,13 @@ function Version() { } export default function ManagementApp({ isLoading }) { - let files = useSelector(state => state.budgets.allFiles); - let userData = useSelector(state => state.user.data); - let managerHasInitialized = useSelector( + const files = useSelector(state => state.budgets.allFiles); + const userData = useSelector(state => state.user.data); + const managerHasInitialized = useSelector( state => state.app.managerHasInitialized, ); - let { setAppState, getUserData, loadAllFiles } = useActions(); + const { setAppState, getUserData, loadAllFiles } = useActions(); // runs on mount only useEffect(() => { @@ -74,7 +74,7 @@ export default function ManagementApp({ isLoading }) { } async function fetchData() { - let userData = await getUserData(); + const userData = await getUserData(); if (userData) { await loadAllFiles(); } diff --git a/packages/desktop-client/src/components/manager/Modals.js b/packages/desktop-client/src/components/manager/Modals.js index fa6451658677fe85eb610eaad6f42c3c4b29792f..cc7637a332cfcd8e3f73d83fc55367a44d3a0797 100644 --- a/packages/desktop-client/src/components/manager/Modals.js +++ b/packages/desktop-client/src/components/manager/Modals.js @@ -14,11 +14,11 @@ import ImportYNAB4 from './ImportYNAB4'; import ImportYNAB5 from './ImportYNAB5'; export default function Modals() { - let modalStack = useSelector(state => state.modals.modalStack); - let isHidden = useSelector(state => state.modals.isHidden); - let actions = useActions(); + const modalStack = useSelector(state => state.modals.modalStack); + const isHidden = useSelector(state => state.modals.isHidden); + const actions = useActions(); - let stack = modalStack.map(({ name, options = {} }, idx) => { + const stack = modalStack.map(({ name, options = {} }, idx) => { const modalProps = { onClose: actions.popModal, onPush: actions.pushModal, diff --git a/packages/desktop-client/src/components/manager/WelcomeScreen.tsx b/packages/desktop-client/src/components/manager/WelcomeScreen.tsx index 5f05c5cf5d179628a0fe0fabccf48259733e3c52..89f45cf1074285c13bb2a26447614a74314f1350 100644 --- a/packages/desktop-client/src/components/manager/WelcomeScreen.tsx +++ b/packages/desktop-client/src/components/manager/WelcomeScreen.tsx @@ -9,7 +9,7 @@ import Text from '../common/Text'; import View from '../common/View'; export default function WelcomeScreen() { - let { createBudget, pushModal } = useActions(); + const { createBudget, pushModal } = useActions(); return ( <View diff --git a/packages/desktop-client/src/components/manager/subscribe/Bootstrap.tsx b/packages/desktop-client/src/components/manager/subscribe/Bootstrap.tsx index 0de5a81dfe849e5c2900afb14a8834d2525cefcf..479833542a39f69da8b352c6f3c9875e8c51c023 100644 --- a/packages/desktop-client/src/components/manager/subscribe/Bootstrap.tsx +++ b/packages/desktop-client/src/components/manager/subscribe/Bootstrap.tsx @@ -16,10 +16,10 @@ import { useBootstrapped, Title } from './common'; import { ConfirmPasswordForm } from './ConfirmPasswordForm'; export default function Bootstrap() { - let dispatch = useDispatch(); - let [error, setError] = useState(null); + const dispatch = useDispatch(); + const [error, setError] = useState(null); - let { checked } = useBootstrapped(); + const { checked } = useBootstrapped(); function getErrorMessage(error) { switch (error) { @@ -36,7 +36,7 @@ export default function Bootstrap() { async function onSetPassword(password) { setError(null); - let { error } = await send('subscribe-bootstrap', { password }); + const { error } = await send('subscribe-bootstrap', { password }); if (error) { setError(error); diff --git a/packages/desktop-client/src/components/manager/subscribe/ChangePassword.tsx b/packages/desktop-client/src/components/manager/subscribe/ChangePassword.tsx index 68adb49b8d4f7121e988d1e187e0d0b82bc6105c..3988553ad6cfcb3728e7ca1502d10ba4e4c493fc 100644 --- a/packages/desktop-client/src/components/manager/subscribe/ChangePassword.tsx +++ b/packages/desktop-client/src/components/manager/subscribe/ChangePassword.tsx @@ -12,9 +12,9 @@ import { Title } from './common'; import { ConfirmPasswordForm } from './ConfirmPasswordForm'; export default function ChangePassword() { - let navigate = useNavigate(); - let [error, setError] = useState(null); - let [msg, setMessage] = useState(null); + const navigate = useNavigate(); + const [error, setError] = useState(null); + const [msg, setMessage] = useState(null); function getErrorMessage(error) { switch (error) { @@ -31,7 +31,7 @@ export default function ChangePassword() { async function onSetPassword(password) { setError(null); - let { error } = await send('subscribe-change-password', { password }); + const { error } = await send('subscribe-change-password', { password }); if (error) { setError(error); diff --git a/packages/desktop-client/src/components/manager/subscribe/ConfirmPasswordForm.tsx b/packages/desktop-client/src/components/manager/subscribe/ConfirmPasswordForm.tsx index b0d5b3622ffd09742adcf51a8d0b94d2421eb527..32ab5ca8a1256b9830ccbe1f694cde84665f1065 100644 --- a/packages/desktop-client/src/components/manager/subscribe/ConfirmPasswordForm.tsx +++ b/packages/desktop-client/src/components/manager/subscribe/ConfirmPasswordForm.tsx @@ -5,10 +5,10 @@ import { BigInput } from '../../common/Input'; import View from '../../common/View'; export function ConfirmPasswordForm({ buttons, onSetPassword, onError }) { - let [password1, setPassword1] = useState(''); - let [password2, setPassword2] = useState(''); - let [showPassword, setShowPassword] = useState(false); - let [loading, setLoading] = useState(false); + const [password1, setPassword1] = useState(''); + const [password2, setPassword2] = useState(''); + const [showPassword, setShowPassword] = useState(false); + const [loading, setLoading] = useState(false); async function onSubmit(e) { e.preventDefault(); diff --git a/packages/desktop-client/src/components/manager/subscribe/Error.tsx b/packages/desktop-client/src/components/manager/subscribe/Error.tsx index 30429f89fd2f448f6841e7d7f7065b48d8590af1..a26ff87c66bfb134301dffff638ce3eb1b55e363 100644 --- a/packages/desktop-client/src/components/manager/subscribe/Error.tsx +++ b/packages/desktop-client/src/components/manager/subscribe/Error.tsx @@ -17,9 +17,9 @@ function getErrorMessage(reason) { } export default function Error() { - let navigate = useNavigate(); - let location = useLocation(); - let { error } = (location.state || {}) as { error? }; + const navigate = useNavigate(); + const location = useLocation(); + const { error } = (location.state || {}) as { error? }; function onTryAgain() { navigate('/'); diff --git a/packages/desktop-client/src/components/manager/subscribe/Login.tsx b/packages/desktop-client/src/components/manager/subscribe/Login.tsx index 600c809661cc646bd508d72e9c7a94878635e8c9..3ed5cef99a53b0195d9f379aeb227a322e022c3b 100644 --- a/packages/desktop-client/src/components/manager/subscribe/Login.tsx +++ b/packages/desktop-client/src/components/manager/subscribe/Login.tsx @@ -14,12 +14,12 @@ import View from '../../common/View'; import { useBootstrapped, Title } from './common'; export default function Login() { - let dispatch = useDispatch(); - let [password, setPassword] = useState(''); - let [loading, setLoading] = useState(false); - let [error, setError] = useState(null); + const dispatch = useDispatch(); + const [password, setPassword] = useState(''); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); - let { checked } = useBootstrapped(); + const { checked } = useBootstrapped(); function getErrorMessage(error) { switch (error) { @@ -40,7 +40,7 @@ export default function Login() { setError(null); setLoading(true); - let { error } = await send('subscribe-sign-in', { password }); + const { error } = await send('subscribe-sign-in', { password }); setLoading(false); if (error) { diff --git a/packages/desktop-client/src/components/manager/subscribe/common.tsx b/packages/desktop-client/src/components/manager/subscribe/common.tsx index 9cc46ca8a6673bb357c613b6ce4599bae7b963bd..cb328c9608bb748ba0ac13a275a232bdf6980ab2 100644 --- a/packages/desktop-client/src/components/manager/subscribe/common.tsx +++ b/packages/desktop-client/src/components/manager/subscribe/common.tsx @@ -17,14 +17,14 @@ import { useSetServerURL } from '../../ServerContext'; // they will also potentially redirect to other pages which do *not* // do any checks. export function useBootstrapped() { - let [checked, setChecked] = useState(false); - let navigate = useNavigate(); - let location = useLocation(); - let setServerURL = useSetServerURL(); + const [checked, setChecked] = useState(false); + const navigate = useNavigate(); + const location = useLocation(); + const setServerURL = useSetServerURL(); useEffect(() => { async function run() { - let ensure = url => { + const ensure = url => { if (location.pathname !== url) { navigate(url); } else { @@ -32,12 +32,12 @@ export function useBootstrapped() { } }; - let url = await send('get-server-url'); - let bootstrapped = await send('get-did-bootstrap'); + const url = await send('get-server-url'); + const bootstrapped = await send('get-did-bootstrap'); if (url == null && !bootstrapped) { // A server hasn't been specified yet - let serverURL = window.location.origin; - let result = await send('subscribe-needs-bootstrap', { + const serverURL = window.location.origin; + const result = await send('subscribe-needs-bootstrap', { url: serverURL, }); if ('error' in result || !result.hasServer) { @@ -54,7 +54,7 @@ export function useBootstrapped() { ensure('/bootstrap'); } } else { - let result = await send('subscribe-needs-bootstrap'); + const result = await send('subscribe-needs-bootstrap'); if ('error' in result) { navigate('/error', { state: { error: result.error } }); } else if (result.bootstrapped) { diff --git a/packages/desktop-client/src/components/mobile/MobileAmountInput.js b/packages/desktop-client/src/components/mobile/MobileAmountInput.js index a1c6895a5f88e73b481a39d6bd0d64624f5ef04d..4155bffab6afd235df165f144c9e4af1b20e680f 100644 --- a/packages/desktop-client/src/components/mobile/MobileAmountInput.js +++ b/packages/desktop-client/src/components/mobile/MobileAmountInput.js @@ -132,7 +132,7 @@ class AmountInput extends PureComponent { }; onChangeText = text => { - let { onChange } = this.props; + const { onChange } = this.props; this.setState({ text }); onChange(text); @@ -142,7 +142,7 @@ class AmountInput extends PureComponent { const { style, textStyle } = this.props; const { editing, value, text } = this.state; - let input = ( + const input = ( <input type="text" ref={el => (this.input = el)} diff --git a/packages/desktop-client/src/components/modals/CloseAccount.tsx b/packages/desktop-client/src/components/modals/CloseAccount.tsx index 48f63a61ff7cb5968180c2e122eb926e52e72ffe..2b58b0852d3fa00b18cede442c5d73a5c4bd9e28 100644 --- a/packages/desktop-client/src/components/modals/CloseAccount.tsx +++ b/packages/desktop-client/src/components/modals/CloseAccount.tsx @@ -51,12 +51,12 @@ function CloseAccount({ actions, modalProps, }: CloseAccountProps) { - let [loading, setLoading] = useState(false); - let [transfer, setTransfer] = useState(''); - let [category, setCategory] = useState(''); + const [loading, setLoading] = useState(false); + const [transfer, setTransfer] = useState(''); + const [category, setCategory] = useState(''); - let [transferError, setTransferError] = useState(false); - let [categoryError, setCategoryError] = useState(false); + const [transferError, setTransferError] = useState(false); + const [categoryError, setCategoryError] = useState(false); return ( <Modal @@ -84,10 +84,10 @@ function CloseAccount({ onSubmit={event => { event.preventDefault(); - let transferError = balance !== 0 && transfer === ''; + const transferError = balance !== 0 && transfer === ''; setTransferError(transferError); - let categoryError = + const categoryError = needsCategory(account, transfer, accounts) && category === ''; setCategoryError(categoryError); diff --git a/packages/desktop-client/src/components/modals/CreateEncryptionKey.tsx b/packages/desktop-client/src/components/modals/CreateEncryptionKey.tsx index 33c8f94f07884262e4842e3ce5b73183b6e95fc2..8a18eff5f7a279c7fa5763fe9e81592a85ddbd6a 100644 --- a/packages/desktop-client/src/components/modals/CreateEncryptionKey.tsx +++ b/packages/desktop-client/src/components/modals/CreateEncryptionKey.tsx @@ -30,19 +30,19 @@ export default function CreateEncryptionKey({ actions, options = {}, }: CreateEncryptionKeyProps) { - let [password, setPassword] = useState(''); - let [loading, setLoading] = useState(false); - let [error, setError] = useState(''); - let [showPassword, setShowPassword] = useState(false); + const [password, setPassword] = useState(''); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(''); + const [showPassword, setShowPassword] = useState(false); - let isRecreating = options.recreate; + const isRecreating = options.recreate; async function onCreateKey() { if (password !== '' && !loading) { setLoading(true); setError(null); - let res = await send('key-make', { password }); + const res = await send('key-make', { password }); if (res.error) { setLoading(null); setError(getCreateKeyError(res.error)); diff --git a/packages/desktop-client/src/components/modals/CreateLocalAccount.tsx b/packages/desktop-client/src/components/modals/CreateLocalAccount.tsx index 62d208cb39c175d807909ae04a7a23210620ade6..5f5cc59e6ff0680e860684c2eab4ad494d66d4b1 100644 --- a/packages/desktop-client/src/components/modals/CreateLocalAccount.tsx +++ b/packages/desktop-client/src/components/modals/CreateLocalAccount.tsx @@ -23,15 +23,15 @@ type CreateLocalAccountProps = { }; function CreateLocalAccount({ modalProps, actions }: CreateLocalAccountProps) { - let navigate = useNavigate(); - let [name, setName] = useState(''); - let [offbudget, setOffbudget] = useState(false); - let [balance, setBalance] = useState('0'); + const navigate = useNavigate(); + const [name, setName] = useState(''); + const [offbudget, setOffbudget] = useState(false); + const [balance, setBalance] = useState('0'); - let [nameError, setNameError] = useState(false); - let [balanceError, setBalanceError] = useState(false); + const [nameError, setNameError] = useState(false); + const [balanceError, setBalanceError] = useState(false); - let validateBalance = balance => !isNaN(parseFloat(balance)); + const validateBalance = balance => !isNaN(parseFloat(balance)); return ( <Modal title="Create Local Account" {...modalProps}> @@ -41,15 +41,15 @@ function CreateLocalAccount({ modalProps, actions }: CreateLocalAccountProps) { onSubmit={async event => { event.preventDefault(); - let nameError = !name; + const nameError = !name; setNameError(nameError); - let balanceError = !validateBalance(balance); + const balanceError = !validateBalance(balance); setBalanceError(balanceError); if (!nameError && !balanceError) { actions.closeModal(); - let id = await actions.createAccount( + const id = await actions.createAccount( name, toRelaxedNumber(balance), offbudget, @@ -65,7 +65,7 @@ function CreateLocalAccount({ modalProps, actions }: CreateLocalAccountProps) { value={name} onChange={event => setName(event.target.value)} onBlur={event => { - let name = event.target.value.trim(); + const name = event.target.value.trim(); setName(name); if (name && nameError) { setNameError(false); @@ -139,7 +139,7 @@ function CreateLocalAccount({ modalProps, actions }: CreateLocalAccountProps) { value={balance} onChange={event => setBalance(event.target.value)} onBlur={event => { - let balance = event.target.value.trim(); + const balance = event.target.value.trim(); setBalance(balance); if (validateBalance(balance) && balanceError) { setBalanceError(false); diff --git a/packages/desktop-client/src/components/modals/EditField.js b/packages/desktop-client/src/components/modals/EditField.js index e5a3dd365b96dbcec9dd95a68a6def078e993a1b..853c85534be0d036401939dd6dc36c63ba7c8b5b 100644 --- a/packages/desktop-client/src/components/modals/EditField.js +++ b/packages/desktop-client/src/components/modals/EditField.js @@ -35,14 +35,14 @@ function CreatePayeeIcon(props) { } export default function EditField({ modalProps, name, onSubmit }) { - let dateFormat = useSelector( + const dateFormat = useSelector( state => state.prefs.local.dateFormat || 'MM/dd/yyyy', ); - let { grouped: categoryGroups } = useCategories(); - let accounts = useSelector(state => state.queries.accounts); - let payees = useSelector(state => state.queries.payees); + const { grouped: categoryGroups } = useCategories(); + const accounts = useSelector(state => state.queries.accounts); + const payees = useSelector(state => state.queries.payees); - let { createPayee } = useActions(); + const { createPayee } = useActions(); function onSelect(value) { if (value != null) { @@ -65,18 +65,18 @@ export default function EditField({ modalProps, name, onSubmit }) { const { isNarrowWidth } = useResponsive(); let label, editor, minWidth; - let inputStyle = { + const inputStyle = { ':focus': { boxShadow: 0 }, ...(isNarrowWidth && itemStyle), }; - let autocompleteProps = { + const autocompleteProps = { inputProps: { style: inputStyle }, containerProps: { style: { height: isNarrowWidth ? '90vh' : 275 } }, }; switch (name) { case 'date': { - let today = currentDay(); + const today = currentDay(); label = 'Date'; minWidth = 350; editor = ( diff --git a/packages/desktop-client/src/components/modals/EditRule.js b/packages/desktop-client/src/components/modals/EditRule.js index 1af0c6e29c7b093ceecc14fa5911cfe09a78f373..9893fa71f433c9d1c78caae3b850a3d6192ec688 100644 --- a/packages/desktop-client/src/components/modals/EditRule.js +++ b/packages/desktop-client/src/components/modals/EditRule.js @@ -54,7 +54,7 @@ function applyErrors(array, errorsArray) { } function getTransactionFields(conditions, actions) { - let fields = ['date']; + const fields = ['date']; if (conditions.find(c => c.field === 'imported_payee')) { fields.push('imported_payee'); @@ -191,8 +191,9 @@ function ConditionEditor({ onDelete, onAdd, }) { - let { field, op, value, type, options, error } = condition; + const { field: originalField, op, value, type, options, error } = condition; + let field = originalField; if (field === 'amount' && options) { if (options.inflow) { field = 'amount-inflow'; @@ -251,10 +252,10 @@ function formatAmount(amount) { } function ScheduleDescription({ id }) { - let dateFormat = useSelector(state => { + const dateFormat = useSelector(state => { return state.prefs.local.dateFormat || 'MM/dd/yyyy'; }); - let scheduleData = useSchedules({ + const scheduleData = useSchedules({ transform: useCallback(q => q.filter({ id }), []), }); @@ -266,8 +267,8 @@ function ScheduleDescription({ id }) { return <View style={{ flex: 1 }}>{id}</View>; } - let [schedule] = scheduleData.schedules; - let status = schedule && scheduleData.statuses.get(schedule.id); + const [schedule] = scheduleData.schedules; + const status = schedule && scheduleData.statuses.get(schedule.id); return ( <View style={{ flex: 1, flexDirection: 'row', alignItems: 'center' }}> @@ -300,7 +301,7 @@ function ScheduleDescription({ id }) { ); } -let actionFields = [ +const actionFields = [ 'category', 'payee', 'notes', @@ -310,7 +311,7 @@ let actionFields = [ 'amount', ].map(field => [field, mapField(field)]); function ActionEditor({ ops, action, editorStyle, onChange, onDelete, onAdd }) { - let { field, op, value, type, error, inputKey = 'initial' } = action; + const { field, op, value, type, error, inputKey = 'initial' } = action; return ( <Editor style={editorStyle} error={error}> @@ -364,7 +365,7 @@ function ActionEditor({ ops, action, editorStyle, onChange, onDelete, onAdd }) { } function StageInfo() { - let [open, setOpen] = useState(); + const [open, setOpen] = useState(); return ( <View style={{ position: 'relative', marginLeft: 5 }}> @@ -439,9 +440,9 @@ function ConditionsList({ f => !conditions.some(c => c.field.includes(f) || f.includes(c.field)), ); } - let field = fields[0] || 'payee'; + const field = fields[0] || 'payee'; - let copy = [...conditions]; + const copy = [...conditions]; copy.splice(index + 1, 0, { type: FIELD_TYPES.get(field), field, @@ -463,7 +464,7 @@ function ConditionsList({ onChangeConditions( updateValue(conditions, cond, () => { if (field === 'field') { - let newCond = { field: value }; + const newCond = { field: value }; if (value === 'amount-inflow') { newCond.field = 'amount'; @@ -475,7 +476,7 @@ function ConditionsList({ newCond.type = FIELD_TYPES.get(newCond.field); - let prevType = FIELD_TYPES.get(cond.field); + const prevType = FIELD_TYPES.get(cond.field); if ( (prevType === 'string' || prevType === 'number') && prevType === newCond.type && @@ -490,7 +491,7 @@ function ConditionsList({ return newInput(makeValue(null, newCond)); } } else if (field === 'op') { - let op = value; + const op = value; // Switching between oneOf and other operators is a // special-case. It changes the input type, so we need to @@ -589,7 +590,7 @@ function ConditionsList({ // TODO: // * Dont touch child transactions? -let conditionFields = [ +const conditionFields = [ 'imported_payee', 'account', 'category', @@ -609,15 +610,17 @@ export default function EditRule({ defaultRule, onSave: originalOnSave, }) { - let [conditions, setConditions] = useState(defaultRule.conditions.map(parse)); - let [actions, setActions] = useState(defaultRule.actions.map(parse)); - let [stage, setStage] = useState(defaultRule.stage); - let [conditionsOp, setConditionsOp] = useState(defaultRule.conditionsOp); - let [transactions, setTransactions] = useState([]); - let dispatch = useDispatch(); - let scrollableEl = useRef(); + const [conditions, setConditions] = useState( + defaultRule.conditions.map(parse), + ); + const [actions, setActions] = useState(defaultRule.actions.map(parse)); + const [stage, setStage] = useState(defaultRule.stage); + const [conditionsOp, setConditionsOp] = useState(defaultRule.conditionsOp); + const [transactions, setTransactions] = useState([]); + const dispatch = useDispatch(); + const scrollableEl = useRef(); - let isSchedule = actions.some(action => action.op === 'link-schedule'); + const isSchedule = actions.some(action => action.op === 'link-schedule'); useEffect(() => { dispatch(initiallyLoadPayees()); @@ -630,21 +633,21 @@ export default function EditRule({ useEffect(() => { // Flash the scrollbar if (scrollableEl.current) { - let el = scrollableEl.current; - let top = el.scrollTop; + const el = scrollableEl.current; + const top = el.scrollTop; el.scrollTop = top + 1; el.scrollTop = top; } // Run it here async function run() { - let { filters } = await send('make-filters-from-conditions', { + const { filters } = await send('make-filters-from-conditions', { conditions: conditions.map(unparse), }); if (filters.length > 0) { const conditionsOpKey = conditionsOp === 'or' ? '$or' : '$and'; - let { data: transactions } = await runQuery( + const { data: transactions } = await runQuery( q('transactions') .filter({ [conditionsOpKey]: filters }) .select('*'), @@ -657,7 +660,7 @@ export default function EditRule({ run(); }, [actions, conditions, conditionsOp]); - let selectedInst = useSelected('transactions', transactions, []); + const selectedInst = useSelected('transactions', transactions, []); function addInitialAction() { addAction(-1); @@ -665,12 +668,12 @@ export default function EditRule({ function addAction(index) { let fields = actionFields.map(f => f[0]); - for (let action of actions) { + for (const action of actions) { fields = fields.filter(f => f !== action.field); } - let field = fields[0] || 'category'; + const field = fields[0] || 'category'; - let copy = [...actions]; + const copy = [...actions]; copy.splice(index + 1, 0, { type: FIELD_TYPES.get(field), field, @@ -683,7 +686,7 @@ export default function EditRule({ function onChangeAction(action, field, value) { setActions( updateValue(actions, action, () => { - let a = { ...action }; + const a = { ...action }; a[field] = value; if (field === 'field') { @@ -724,7 +727,7 @@ export default function EditRule({ } async function onSave() { - let rule = { + const rule = { ...defaultRule, stage, conditionsOp, @@ -732,8 +735,8 @@ export default function EditRule({ actions: actions.map(unparse), }; - let method = rule.id ? 'rule-update' : 'rule-add'; - let { error, id: newId } = await send(method, rule); + const method = rule.id ? 'rule-update' : 'rule-add'; + const { error, id: newId } = await send(method, rule); if (error) { if (error.conditionErrors) { @@ -754,7 +757,7 @@ export default function EditRule({ } } - let editorStyle = { + const editorStyle = { color: theme.pillText, backgroundColor: theme.pillBackground, borderRadius: 4, diff --git a/packages/desktop-client/src/components/modals/FixEncryptionKey.tsx b/packages/desktop-client/src/components/modals/FixEncryptionKey.tsx index d327898f9281a6ffdd596ff578678d94c454ec5d..c7e0d96365a551b630c78906577a1681adc63f5a 100644 --- a/packages/desktop-client/src/components/modals/FixEncryptionKey.tsx +++ b/packages/desktop-client/src/components/modals/FixEncryptionKey.tsx @@ -27,19 +27,19 @@ export default function FixEncryptionKey({ actions, options = {}, }: FixEncryptionKeyProps) { - let { hasExistingKey, cloudFileId, onSuccess } = options; + const { hasExistingKey, cloudFileId, onSuccess } = options; - let [password, setPassword] = useState(''); - let [error, setError] = useState(''); - let [loading, setLoading] = useState(false); - let [showPassword, setShowPassword] = useState(false); + const [password, setPassword] = useState(''); + const [error, setError] = useState(''); + const [loading, setLoading] = useState(false); + const [showPassword, setShowPassword] = useState(false); async function onUpdateKey() { if (password !== '' && !loading) { setLoading(true); setError(null); - let { error } = await send('key-test', { + const { error } = await send('key-test', { password, fileId: cloudFileId, }); diff --git a/packages/desktop-client/src/components/modals/GoCardlessExternalMsg.tsx b/packages/desktop-client/src/components/modals/GoCardlessExternalMsg.tsx index 53355f336423ca1b824f289c00aa9ad9b3df1ef9..ccdcad5a0a577946a535324e477dbcd6d135b340 100644 --- a/packages/desktop-client/src/components/modals/GoCardlessExternalMsg.tsx +++ b/packages/desktop-client/src/components/modals/GoCardlessExternalMsg.tsx @@ -93,16 +93,16 @@ export default function GoCardlessExternalMsg({ }: GoCardlessExternalMsgProps) { const dispatch = useDispatch(); - let [waiting, setWaiting] = useState<string | null>(null); - let [success, setSuccess] = useState<boolean>(false); - let [institutionId, setInstitutionId] = useState<string>(); - let [country, setCountry] = useState<string>(); - let [error, setError] = useState<'unknown' | 'timeout' | null>(null); - let [isGoCardlessSetupComplete, setIsGoCardlessSetupComplete] = useState< + const [waiting, setWaiting] = useState<string | null>(null); + const [success, setSuccess] = useState<boolean>(false); + const [institutionId, setInstitutionId] = useState<string>(); + const [country, setCountry] = useState<string>(); + const [error, setError] = useState<'unknown' | 'timeout' | null>(null); + const [isGoCardlessSetupComplete, setIsGoCardlessSetupComplete] = useState< boolean | null >(null); - let [menuOpen, setMenuOpen] = useState<boolean>(false); - let data = useRef<GoCardlessToken | null>(null); + const [menuOpen, setMenuOpen] = useState<boolean>(false); + const data = useRef<GoCardlessToken | null>(null); const { data: bankOptions, @@ -116,7 +116,7 @@ export default function GoCardlessExternalMsg({ setError(null); setWaiting('browser'); - let res = await onMoveExternal({ institutionId }); + const res = await onMoveExternal({ institutionId }); if (res.error) { setError(res.error); setWaiting(null); diff --git a/packages/desktop-client/src/components/modals/ImportTransactions.js b/packages/desktop-client/src/components/modals/ImportTransactions.js index 11665ea71e8df96603a1bbf1ca3a4dae919422d1..b66597e11251b8ff564992f12906435f283dac5b 100644 --- a/packages/desktop-client/src/components/modals/ImportTransactions.js +++ b/packages/desktop-client/src/components/modals/ImportTransactions.js @@ -23,7 +23,7 @@ import View from '../common/View'; import { Checkbox, SectionLabel } from '../forms'; import { TableHeader, TableWithNavigator, Row, Field } from '../table'; -let dateFormats = [ +const dateFormats = [ { format: 'yyyy mm dd', label: 'YYYY MM DD' }, { format: 'yy mm dd', label: 'YY MM DD' }, { format: 'mm dd yyyy', label: 'MM DD YYYY' }, @@ -108,7 +108,7 @@ export function parseDate(str, order) { day = parts[1]; } - let parsed = `${year}-${pad(month)}-${pad(day)}`; + const parsed = `${year}-${pad(month)}-${pad(day)}`; if (!d.isValid(d.parseISO(parsed))) { return null; } @@ -126,15 +126,15 @@ function formatDate(date, format) { } function getFileType(filepath) { - let m = filepath.match(/\.([^.]*)$/); + const m = filepath.match(/\.([^.]*)$/); if (!m) return 'ofx'; - let rawType = m[1].toLowerCase(); + const rawType = m[1].toLowerCase(); if (rawType === 'tsv') return 'csv'; return rawType; } function ParsedDate({ parseDateFormat, showParsed, dateFormat, date }) { - let parsed = + const parsed = date && formatDate( parseDateFormat ? parseDate(date, parseDateFormat) : date, @@ -162,10 +162,10 @@ function getInitialDateFormat(transactions, mappings) { return 'yyyy mm dd'; } - let transaction = transactions[0]; - let date = transaction[mappings.date]; + const transaction = transactions[0]; + const date = transaction[mappings.date]; - let found = + const found = date == null ? null : dateFormats.find(f => parseDate(date, f.format) != null); @@ -177,35 +177,35 @@ function getInitialMappings(transactions) { return {}; } - let transaction = transactions[0]; - let fields = Object.entries(transaction); + const transaction = transactions[0]; + const fields = Object.entries(transaction); function key(entry) { return entry ? entry[0] : null; } - let dateField = key( + const dateField = key( fields.find(([name, value]) => name.toLowerCase().includes('date')) || fields.find(([name, value]) => value.match(/^\d+[-/]\d+[-/]\d+$/)), ); - let amountField = key( + const amountField = key( fields.find(([name, value]) => name.toLowerCase().includes('amount')) || fields.find(([name, value]) => value.match(/^-?[.,\d]+$/)), ); - let payeeField = key( + const payeeField = key( fields.find(([name, value]) => name !== dateField && name !== amountField), ); - let notesField = key( + const notesField = key( fields.find( ([name, value]) => name !== dateField && name !== amountField && name !== payeeField, ), ); - let inOutField = key( + const inOutField = key( fields.find( ([name, value]) => name !== dateField && @@ -225,8 +225,9 @@ function getInitialMappings(transactions) { } function applyFieldMappings(transaction, mappings) { - let result = {}; - for (let [field, target] of Object.entries(mappings)) { + const result = {}; + for (const [originalField, target] of Object.entries(mappings)) { + let field = originalField; if (field === 'payee') { field = 'payee_name'; } @@ -240,8 +241,9 @@ function parseAmount(amount, mapper) { if (amount == null) { return null; } - let parsed = typeof amount === 'string' ? looselyParseAmount(amount) : amount; - let value = mapper(parsed); + const parsed = + typeof amount === 'string' ? looselyParseAmount(amount) : amount; + const value = mapper(parsed); return value; } @@ -259,8 +261,8 @@ function parseAmountFields( // Split mode is a little weird; first we look for an outflow and // if that has a value, we never want to show a number in the // inflow. Same for `amount`; we choose outflow first and then inflow - let outflow = parseAmount(trans.outflow, n => -Math.abs(n)) * multiplier; - let inflow = outflow + const outflow = parseAmount(trans.outflow, n => -Math.abs(n)) * multiplier; + const inflow = outflow ? 0 : parseAmount(trans.inflow, n => Math.abs(n)) * multiplier; @@ -300,7 +302,7 @@ function Transaction({ flipAmount, multiplierAmount, }) { - let transaction = useMemo( + const transaction = useMemo( () => fieldMappings ? applyFieldMappings(rawTransaction, fieldMappings) @@ -434,8 +436,8 @@ function DateFormatSelect({ // to space if we can't figure it out. let delimiter = '-'; if (transactions.length > 0 && fieldMappings && fieldMappings.date != null) { - let date = transactions[0][fieldMappings.date]; - let m = date && date.match(/[/.,-/\\]/); + const date = transactions[0][fieldMappings.date]; + const m = date && date.match(/[/.,-/\\]/); delimiter = m ? m[0] : ' '; } @@ -555,7 +557,7 @@ function FieldMappings({ return null; } - let options = Object.keys(transactions[0]); + const options = Object.keys(transactions[0]); mappings = mappings || {}; return ( @@ -655,53 +657,53 @@ function FieldMappings({ } export default function ImportTransactions({ modalProps, options }) { - let dateFormat = useSelector( + const dateFormat = useSelector( state => state.prefs.local.dateFormat || 'MM/dd/yyyy', ); - let prefs = useSelector(state => state.prefs.local); - let { parseTransactions, importTransactions, getPayees, savePrefs } = + const prefs = useSelector(state => state.prefs.local); + const { parseTransactions, importTransactions, getPayees, savePrefs } = useActions(); - let [multiplierAmount, setMultiplierAmount] = useState(''); - let [loadingState, setLoadingState] = useState('parsing'); - let [error, setError] = useState(null); - let [filename, setFilename] = useState(options.filename); - let [transactions, setTransactions] = useState([]); - let [filetype, setFileType] = useState(null); - let [fieldMappings, setFieldMappings] = useState(null); - let [splitMode, setSplitMode] = useState(false); - let [inOutMode, setInOutMode] = useState(false); - let [outValue, setOutValue] = useState(''); - let [flipAmount, setFlipAmount] = useState(false); - let [multiplierEnabled, setMultiplierEnabled] = useState(false); - let { accountId, onImported } = options; + const [multiplierAmount, setMultiplierAmount] = useState(''); + const [loadingState, setLoadingState] = useState('parsing'); + const [error, setError] = useState(null); + const [filename, setFilename] = useState(options.filename); + const [transactions, setTransactions] = useState([]); + const [filetype, setFileType] = useState(null); + const [fieldMappings, setFieldMappings] = useState(null); + const [splitMode, setSplitMode] = useState(false); + const [inOutMode, setInOutMode] = useState(false); + const [outValue, setOutValue] = useState(''); + const [flipAmount, setFlipAmount] = useState(false); + const [multiplierEnabled, setMultiplierEnabled] = useState(false); + const { accountId, onImported } = options; // This cannot be set after parsing the file, because changing it // requires re-parsing the file. This is different from the other // options which are simple post-processing. That means if you // parsed different files without closing the modal, it wouldn't // re-read this. - let [delimiter, setDelimiter] = useState( + const [delimiter, setDelimiter] = useState( prefs[`csv-delimiter-${accountId}`] || (filename.endsWith('.tsv') ? '\t' : ','), ); - let [hasHeaderRow, setHasHeaderRow] = useState( + const [hasHeaderRow, setHasHeaderRow] = useState( prefs[`csv-has-header-${accountId}`] ?? true, ); - let [fallbackMissingPayeeToMemo, setFallbackMissingPayeeToMemo] = useState( + const [fallbackMissingPayeeToMemo, setFallbackMissingPayeeToMemo] = useState( prefs[`ofx-fallback-missing-payee-${accountId}`] ?? true, ); - let [parseDateFormat, setParseDateFormat] = useState(null); + const [parseDateFormat, setParseDateFormat] = useState(null); - let [clearOnImport, setClearOnImport] = useState(true); + const [clearOnImport, setClearOnImport] = useState(true); const enableExperimentalOfxParser = useFeatureFlag('experimentalOfxParser'); async function parse(filename, options) { setLoadingState('parsing'); - let filetype = getFileType(filename); + const filetype = getFileType(filename); setFilename(filename); setFileType(filetype); @@ -710,7 +712,7 @@ export default function ImportTransactions({ modalProps, options }) { enableExperimentalOfxParser, }; - let { errors, transactions } = await parseTransactions(filename, options); + const { errors, transactions } = await parseTransactions(filename, options); setLoadingState(null); setError(null); @@ -734,7 +736,7 @@ export default function ImportTransactions({ modalProps, options }) { setFieldMappings(mappings); // Set initial split mode based on any saved mapping - let initialSplitMode = !!(mappings.outflow || mappings.inflow); + const initialSplitMode = !!(mappings.outflow || mappings.inflow); setSplitMode(initialSplitMode); setParseDateFormat( @@ -785,16 +787,16 @@ export default function ImportTransactions({ modalProps, options }) { setFlipAmount(!flipAmount); } - let isSplit = !splitMode; + const isSplit = !splitMode; setSplitMode(isSplit); setInOutMode(false); setFlipAmount(false); // Run auto-detection on the fields to try to detect the fields // automatically - let mappings = getInitialMappings(transactions); + const mappings = getInitialMappings(transactions); - let newFieldMappings = isSplit + const newFieldMappings = isSplit ? { amount: null, outflow: mappings.amount, @@ -835,13 +837,13 @@ export default function ImportTransactions({ modalProps, options }) { async function onImport() { setLoadingState('importing'); - let finalTransactions = []; + const finalTransactions = []; let errorMessage; for (let trans of transactions) { trans = fieldMappings ? applyFieldMappings(trans, fieldMappings) : trans; - let date = isOfxFile(filetype) + const date = isOfxFile(filetype) ? trans.date : parseDate(trans.date, parseDateFormat); if (date == null) { @@ -851,7 +853,7 @@ export default function ImportTransactions({ modalProps, options }) { break; } - let { amount } = parseAmountFields( + const { amount } = parseAmountFields( trans, splitMode, inOutMode, @@ -864,7 +866,7 @@ export default function ImportTransactions({ modalProps, options }) { break; } - let { inflow, outflow, inOut, ...finalTransaction } = trans; + const { inflow, outflow, inOut, ...finalTransaction } = trans; finalTransactions.push({ ...finalTransaction, date, @@ -880,7 +882,7 @@ export default function ImportTransactions({ modalProps, options }) { } if (!isOfxFile(filetype)) { - let key = `parse-date-${accountId}-${filetype}`; + const key = `parse-date-${accountId}-${filetype}`; savePrefs({ [key]: parseDateFormat }); } @@ -901,7 +903,7 @@ export default function ImportTransactions({ modalProps, options }) { savePrefs({ [`flip-amount-${accountId}-${filetype}`]: flipAmount }); } - let didChange = await importTransactions(accountId, finalTransactions); + const didChange = await importTransactions(accountId, finalTransactions); if (didChange) { await getPayees(); } @@ -913,7 +915,7 @@ export default function ImportTransactions({ modalProps, options }) { modalProps.onClose(); } - let headers = [ + const headers = [ { name: 'Date', width: 200 }, { name: 'Payee', width: 'flex' }, { name: 'Notes', width: 'flex' }, diff --git a/packages/desktop-client/src/components/modals/LoadBackup.js b/packages/desktop-client/src/components/modals/LoadBackup.js index 6e0f3d98e6642334142b32977748c94696ff5c2a..64786e72407bf73b36ac88c31147fc7656056fce 100644 --- a/packages/desktop-client/src/components/modals/LoadBackup.js +++ b/packages/desktop-client/src/components/modals/LoadBackup.js @@ -54,7 +54,7 @@ function LoadBackup({ actions, modalProps, }) { - let [backups, setBackups] = useState([]); + const [backups, setBackups] = useState([]); useEffect(() => { send('backups-get', { id: budgetId }).then(setBackups); diff --git a/packages/desktop-client/src/components/modals/ManageRulesModal.tsx b/packages/desktop-client/src/components/modals/ManageRulesModal.tsx index 72a7d202ac094f25cb64882e738ea8bc0dcd1b2e..59dccf84a5a0bfdae593c639cffa2cf87219b312 100644 --- a/packages/desktop-client/src/components/modals/ManageRulesModal.tsx +++ b/packages/desktop-client/src/components/modals/ManageRulesModal.tsx @@ -16,8 +16,8 @@ export default function ManageRulesModal({ modalProps, payeeId, }: ManageRulesModalProps) { - let [loading, setLoading] = useState(true); - let location = useLocation(); + const [loading, setLoading] = useState(true); + const location = useLocation(); if (isNonProductionEnvironment()) { if (location.pathname !== '/payees') { throw new Error( diff --git a/packages/desktop-client/src/components/modals/MergeUnusedPayees.js b/packages/desktop-client/src/components/modals/MergeUnusedPayees.js index 50d3f36ec9e85beeedbee1a0d11e42f20543db15..d857cdd6a90c78c6684da1b6e849be25c94bcb56 100644 --- a/packages/desktop-client/src/components/modals/MergeUnusedPayees.js +++ b/packages/desktop-client/src/components/modals/MergeUnusedPayees.js @@ -12,27 +12,27 @@ import Paragraph from '../common/Paragraph'; import Text from '../common/Text'; import View from '../common/View'; -let highlightStyle = { color: theme.pageTextPositive }; +const highlightStyle = { color: theme.pageTextPositive }; export default function MergeUnusedPayees({ modalProps, payeeIds, targetPayeeId, }) { - let { payees: allPayees, modalStack } = useSelector(state => ({ + const { payees: allPayees, modalStack } = useSelector(state => ({ payees: state.queries.payees, modalStack: state.modals.modalStack, })); - let isEditingRule = !!modalStack.find(m => m.name === 'edit-rule'); - let dispatch = useDispatch(); - let [shouldCreateRule, setShouldCreateRule] = useState(true); - let flashRef = useRef(null); + const isEditingRule = !!modalStack.find(m => m.name === 'edit-rule'); + const dispatch = useDispatch(); + const [shouldCreateRule, setShouldCreateRule] = useState(true); + const flashRef = useRef(null); useEffect(() => { // Flash the scrollbar if (flashRef.current) { - let el = flashRef.current; - let top = el.scrollTop; + const el = flashRef.current; + const top = el.scrollTop; el.scrollTop = top + 1; el.scrollTop = top; } @@ -44,10 +44,10 @@ export default function MergeUnusedPayees({ // // TODO: I think a custom `useSelector` hook that doesn't bind would // be nice - let [payees] = useState(() => + const [payees] = useState(() => payeeIds.map(id => allPayees.find(p => p.id === id)), ); - let targetPayee = allPayees.find(p => p.id === targetPayeeId); + const targetPayee = allPayees.find(p => p.id === targetPayeeId); if (!targetPayee) { return null; @@ -61,7 +61,7 @@ export default function MergeUnusedPayees({ let ruleId; if (shouldCreateRule && !isEditingRule) { - let id = await send('rule-add-payee-rename', { + const id = await send('rule-add-payee-rename', { fromNames: payees.map(p => p.name), to: targetPayee.id, }); @@ -74,10 +74,10 @@ export default function MergeUnusedPayees({ } async function onMergeAndCreateRule() { - let ruleId = await onMerge(); + const ruleId = await onMerge(); if (ruleId) { - let rule = await send('rule-get', { id: ruleId }); + const rule = await send('rule-get', { id: ruleId }); dispatch(replaceModal('edit-rule', { rule })); } } diff --git a/packages/desktop-client/src/components/modals/PlaidExternalMsg.tsx b/packages/desktop-client/src/components/modals/PlaidExternalMsg.tsx index 1b19f09c3b8915cdb0a5e0de36c08347e9134706..e9146a7e0393ec8d4dde4d1eeba0417b57f20570 100644 --- a/packages/desktop-client/src/components/modals/PlaidExternalMsg.tsx +++ b/packages/desktop-client/src/components/modals/PlaidExternalMsg.tsx @@ -33,16 +33,16 @@ export default function PlaidExternalMsg({ onSuccess, onClose: originalOnClose, }: PlainExternalMsgProps) { - let [waiting, setWaiting] = useState(null); - let [success, setSuccess] = useState(false); - let [error, setError] = useState(null); - let data = useRef(null); + const [waiting, setWaiting] = useState(null); + const [success, setSuccess] = useState(false); + const [error, setError] = useState(null); + const data = useRef(null); async function onJump() { setError(null); setWaiting('browser'); - let res = await onMoveExternal(); + const res = await onMoveExternal(); if (res.error) { setError(res.error); setWaiting(null); diff --git a/upcoming-release-notes/2033.md b/upcoming-release-notes/2033.md new file mode 100644 index 0000000000000000000000000000000000000000..afd0770965a91bdb6f8a9e25b375f1c38d4f2fef --- /dev/null +++ b/upcoming-release-notes/2033.md @@ -0,0 +1,6 @@ +--- +category: Maintenance +authors: [joel-jeremy] +--- + +Apply ESLint prefer-const on components folder part 1