diff --git a/packages/api/package.json b/packages/api/package.json index 5873f406805..c8623304f39 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -1,6 +1,6 @@ { "name": "@actual-app/api", - "version": "6.10.0", + "version": "24.10.0", "license": "MIT", "description": "An API for Actual", "engines": { diff --git a/packages/desktop-client/e2e/accounts.mobile.test.js b/packages/desktop-client/e2e/accounts.mobile.test.js new file mode 100644 index 00000000000..90cf4814f1d --- /dev/null +++ b/packages/desktop-client/e2e/accounts.mobile.test.js @@ -0,0 +1,57 @@ +import { test, expect } from '@playwright/test'; + +import { ConfigurationPage } from './page-models/configuration-page'; +import { MobileNavigation } from './page-models/mobile-navigation'; + +test.describe('Mobile Accounts', () => { + let page; + let navigation; + let configurationPage; + + test.beforeEach(async ({ browser }) => { + page = await browser.newPage(); + navigation = new MobileNavigation(page); + configurationPage = new ConfigurationPage(page); + + await page.setViewportSize({ + width: 350, + height: 600, + }); + await page.goto('/'); + await configurationPage.createTestFile(); + }); + + test.afterEach(async () => { + await page.close(); + }); + + test('opens the accounts page and asserts on balances', async () => { + const accountsPage = await navigation.goToAccountsPage(); + + const account = await accountsPage.getNthAccount(1); + + await expect(account.name).toHaveText('Ally Savings'); + await expect(account.balance).toHaveText('7,653.00'); + await expect(page).toMatchThemeScreenshots(); + }); + + test('opens individual account page and checks that filtering is working', async () => { + const accountsPage = await navigation.goToAccountsPage(); + const accountPage = await accountsPage.openNthAccount(0); + + await expect(accountPage.heading).toHaveText('Bank of America'); + await expect(accountPage.transactionList).toBeVisible(); + await expect(await accountPage.getBalance()).toBeGreaterThan(0); + await expect(accountPage.noTransactionsMessage).not.toBeVisible(); + await expect(page).toMatchThemeScreenshots(); + + await accountPage.searchByText('nothing should be found'); + await expect(accountPage.noTransactionsMessage).toBeVisible(); + await expect(accountPage.transactions).toHaveCount(0); + await expect(page).toMatchThemeScreenshots(); + + await accountPage.searchByText('Kroger'); + await expect(accountPage.transactions).not.toHaveCount(0); + await expect(page).toMatchThemeScreenshots(); + }); +}); diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-individual-account-page-and-checks-that-filtering-is-working-1-chromium-linux.png b/packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-1-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-individual-account-page-and-checks-that-filtering-is-working-1-chromium-linux.png rename to packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-1-chromium-linux.png diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-individual-account-page-and-checks-that-filtering-is-working-2-chromium-linux.png b/packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-2-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-individual-account-page-and-checks-that-filtering-is-working-2-chromium-linux.png rename to packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-2-chromium-linux.png diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-individual-account-page-and-checks-that-filtering-is-working-3-chromium-linux.png b/packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-3-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-individual-account-page-and-checks-that-filtering-is-working-3-chromium-linux.png rename to packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-3-chromium-linux.png diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-individual-account-page-and-checks-that-filtering-is-working-4-chromium-linux.png b/packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-4-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-individual-account-page-and-checks-that-filtering-is-working-4-chromium-linux.png rename to packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-4-chromium-linux.png diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-individual-account-page-and-checks-that-filtering-is-working-5-chromium-linux.png b/packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-5-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-individual-account-page-and-checks-that-filtering-is-working-5-chromium-linux.png rename to packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-5-chromium-linux.png diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-individual-account-page-and-checks-that-filtering-is-working-6-chromium-linux.png b/packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-6-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-individual-account-page-and-checks-that-filtering-is-working-6-chromium-linux.png rename to packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-6-chromium-linux.png diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-individual-account-page-and-checks-that-filtering-is-working-7-chromium-linux.png b/packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-7-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-individual-account-page-and-checks-that-filtering-is-working-7-chromium-linux.png rename to packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-7-chromium-linux.png diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-individual-account-page-and-checks-that-filtering-is-working-8-chromium-linux.png b/packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-8-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-individual-account-page-and-checks-that-filtering-is-working-8-chromium-linux.png rename to packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-8-chromium-linux.png diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-individual-account-page-and-checks-that-filtering-is-working-9-chromium-linux.png b/packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-9-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-individual-account-page-and-checks-that-filtering-is-working-9-chromium-linux.png rename to packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-9-chromium-linux.png diff --git a/packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-the-accounts-page-and-asserts-on-balances-1-chromium-linux.png b/packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-the-accounts-page-and-asserts-on-balances-1-chromium-linux.png new file mode 100644 index 00000000000..568ed03a9dd Binary files /dev/null and b/packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-the-accounts-page-and-asserts-on-balances-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-the-accounts-page-and-asserts-on-balances-2-chromium-linux.png b/packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-the-accounts-page-and-asserts-on-balances-2-chromium-linux.png new file mode 100644 index 00000000000..51bb6f2433d Binary files /dev/null and b/packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-the-accounts-page-and-asserts-on-balances-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-the-accounts-page-and-asserts-on-balances-3-chromium-linux.png b/packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-the-accounts-page-and-asserts-on-balances-3-chromium-linux.png new file mode 100644 index 00000000000..7577f513fc6 Binary files /dev/null and b/packages/desktop-client/e2e/accounts.mobile.test.js-snapshots/Mobile-Accounts-opens-the-accounts-page-and-asserts-on-balances-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-1-chromium-linux.png b/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-1-chromium-linux.png index b356e0c8add..ff035988802 100644 Binary files a/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-1-chromium-linux.png and b/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-2-chromium-linux.png b/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-2-chromium-linux.png index 91901ad8901..8a51b293a72 100644 Binary files a/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-2-chromium-linux.png and b/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-3-chromium-linux.png b/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-3-chromium-linux.png index d0fe328145e..d5b4b30c7f1 100644 Binary files a/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-3-chromium-linux.png and b/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-4-chromium-linux.png b/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-4-chromium-linux.png index bc60bfc408a..8b0146d47af 100644 Binary files a/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-4-chromium-linux.png and b/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-4-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js b/packages/desktop-client/e2e/budget.mobile.test.js new file mode 100644 index 00000000000..c098c8652b5 --- /dev/null +++ b/packages/desktop-client/e2e/budget.mobile.test.js @@ -0,0 +1,281 @@ +import { test, expect } from '@playwright/test'; + +import * as monthUtils from 'loot-core/src/shared/months'; + +import { ConfigurationPage } from './page-models/configuration-page'; +import { MobileNavigation } from './page-models/mobile-navigation'; + +const budgetTypes = ['Envelope', 'Tracking']; + +budgetTypes.forEach(budgetType => { + test.describe(`Mobile Budget [${budgetType}]`, () => { + let page; + let navigation; + let configurationPage; + let previousGlobalIsTesting; + + test.beforeAll(() => { + // TODO: Hack, properly mock the currentMonth function + previousGlobalIsTesting = global.IS_TESTING; + global.IS_TESTING = true; + }); + + test.afterAll(() => { + // TODO: Hack, properly mock the currentMonth function + global.IS_TESTING = previousGlobalIsTesting; + }); + + test.beforeEach(async ({ browser }) => { + page = await browser.newPage(); + navigation = new MobileNavigation(page); + configurationPage = new ConfigurationPage(page); + + await page.setViewportSize({ + width: 350, + height: 600, + }); + await page.goto('/'); + await configurationPage.createTestFile(); + + if (budgetType === 'Tracking') { + // Set budget type to tracking + const settingsPage = await navigation.goToSettingsPage(); + await settingsPage.useBudgetType('tracking'); + } + }); + + test.afterEach(async () => { + await page.close(); + }); + + test('loads the budget page with budgeted amounts', async () => { + const budgetPage = await navigation.goToBudgetPage(); + await budgetPage.waitForBudgetTable(); + + await expect(budgetPage.categoryNames).toHaveText([ + 'Food', + 'Restaurants', + 'Entertainment', + 'Clothing', + 'General', + 'Gift', + 'Medical', + 'Savings', + 'Cell', + 'Internet', + 'Mortgage', + 'Water', + 'Power', + 'Starting Balances', + 'Misc', + 'Income', + ]); + await expect(page).toMatchThemeScreenshots(); + }); + + // Page Header Tests + + test('checks that clicking the Actual logo in the page header opens the budget page menu', async () => { + const budgetPage = await navigation.goToBudgetPage(); + await budgetPage.waitForBudgetTable(); + + await budgetPage.openBudgetPageMenu(); + + const budgetPageMenuModal = page.getByRole('dialog'); + + await expect(budgetPageMenuModal).toBeVisible(); + await expect(page).toMatchThemeScreenshots(); + }); + + test("checks that clicking the left arrow in the page header shows the previous month's budget", async () => { + const budgetPage = await navigation.goToBudgetPage(); + await budgetPage.waitForBudgetTable(); + + const selectedMonth = await budgetPage.getSelectedMonth(); + const displayMonth = monthUtils.format( + selectedMonth, + budgetPage.MONTH_HEADER_DATE_FORMAT, + ); + + await expect(budgetPage.heading).toHaveText(displayMonth); + + const previousMonth = await budgetPage.goToPreviousMonth(); + const previousDisplayMonth = monthUtils.format( + previousMonth, + budgetPage.MONTH_HEADER_DATE_FORMAT, + ); + + await expect(budgetPage.heading).toHaveText(previousDisplayMonth); + await expect(page).toMatchThemeScreenshots(); + }); + + test('checks that clicking the month in the page header opens the month menu modal', async () => { + const budgetPage = await navigation.goToBudgetPage(); + await budgetPage.waitForBudgetTable(); + + const selectedMonth = await budgetPage.getSelectedMonth(); + + await budgetPage.openMonthMenu(); + + const monthMenuModal = page.getByRole('dialog'); + const monthMenuModalHeading = monthMenuModal.getByRole('heading'); + + const displayMonth = monthUtils.format( + selectedMonth, + budgetPage.MONTH_HEADER_DATE_FORMAT, + ); + await expect(monthMenuModalHeading).toHaveText(displayMonth); + await expect(page).toMatchThemeScreenshots(); + }); + + test("checks that clicking the right arrow in the page header shows the next month's budget", async () => { + const budgetPage = await navigation.goToBudgetPage(); + await budgetPage.waitForBudgetTable(); + + const selectedMonth = await budgetPage.getSelectedMonth(); + const displayMonth = monthUtils.format( + selectedMonth, + budgetPage.MONTH_HEADER_DATE_FORMAT, + ); + + await expect(budgetPage.heading).toHaveText(displayMonth); + + const nextMonth = await budgetPage.goToNextMonth(); + const nextDisplayMonth = monthUtils.format( + nextMonth, + budgetPage.MONTH_HEADER_DATE_FORMAT, + ); + + await expect(budgetPage.heading).toHaveText(nextDisplayMonth); + await expect(page).toMatchThemeScreenshots(); + }); + + // Category / Category Group Menu Tests + + test('checks that clicking the category group name opens the category group menu modal', async () => { + const budgetPage = await navigation.goToBudgetPage(); + await budgetPage.waitForBudgetTable(); + + const categoryGroupName = await budgetPage.getCategoryGroupNameForRow(0); + await budgetPage.openCategoryGroupMenu(categoryGroupName); + + const categoryMenuModalHeading = page + .getByRole('dialog') + .getByRole('heading'); + + await expect(categoryMenuModalHeading).toHaveText(categoryGroupName); + await expect(page).toMatchThemeScreenshots(); + }); + + test('checks that clicking the category name opens the category menu modal', async () => { + const budgetPage = await navigation.goToBudgetPage(); + await budgetPage.waitForBudgetTable(); + + const categoryName = await budgetPage.getCategoryNameForRow(0); + await budgetPage.openCategoryMenu(categoryName); + + const categoryMenuModalHeading = page + .getByRole('dialog') + .getByRole('heading'); + + await expect(categoryMenuModalHeading).toHaveText(categoryName); + await expect(page).toMatchThemeScreenshots(); + }); + + // Budgeted Cell Tests + + test('checks that clicking the budgeted cell opens the budget menu modal', async () => { + const budgetPage = await navigation.goToBudgetPage(); + await budgetPage.waitForBudgetTable(); + + const categoryName = await budgetPage.getCategoryNameForRow(0); + await budgetPage.openBudgetMenu(categoryName); + + const budgetMenuModalHeading = page + .getByRole('dialog') + .getByRole('heading'); + + await expect(budgetMenuModalHeading).toHaveText(categoryName); + await expect(page).toMatchThemeScreenshots(); + }); + + test('updates the budgeted amount', async () => { + const budgetPage = await navigation.goToBudgetPage(); + await budgetPage.waitForBudgetTable(); + + const categoryName = await budgetPage.getCategoryNameForRow(0); + + // Set to 100.00 + await budgetPage.setBudget(categoryName, 10000); + + const budgetedButton = + await budgetPage.getButtonForBudgeted(categoryName); + + await expect(budgetedButton).toHaveText('100.00'); + await expect(page).toMatchThemeScreenshots(); + }); + + // Spent Cell Tests + + test('checks that clicking spent cell redirects to the category transactions page', async () => { + const budgetPage = await navigation.goToBudgetPage(); + await budgetPage.waitForBudgetTable(); + + const categoryName = await budgetPage.getCategoryNameForRow(0); + const accountPage = await budgetPage.openSpentPage(categoryName); + + await expect(accountPage.heading).toContainText(categoryName); + await expect(accountPage.transactionList).toBeVisible(); + await expect(page).toMatchThemeScreenshots(); + }); + + // Balance Cell Tests + + test('checks that clicking the balance cell opens the balance menu modal', async () => { + const budgetPage = await navigation.goToBudgetPage(); + await budgetPage.waitForBudgetTable(); + + const categoryName = await budgetPage.getCategoryNameForRow(0); + await budgetPage.openBalanceMenu(categoryName); + + const balanceMenuModalHeading = page + .getByRole('dialog') + .getByRole('heading'); + + await expect(balanceMenuModalHeading).toHaveText(categoryName); + await expect(page).toMatchThemeScreenshots(); + }); + + if (budgetType === 'Envelope') { + test('checks that clicking the To Budget/Overbudgeted amount opens the budget summary menu modal', async () => { + const budgetPage = await navigation.goToBudgetPage(); + await budgetPage.waitForBudgetTable(); + + await budgetPage.openEnvelopeBudgetSummaryMenu(); + + const summaryModalHeading = page + .getByRole('dialog') + .getByRole('heading'); + + await expect(summaryModalHeading).toHaveText('Budget Summary'); + await expect(page).toMatchThemeScreenshots(); + }); + } + + if (budgetType === 'Tracking') { + test('checks that clicking the Saved/Projected Savings/Overspent amount opens the budget summary menu modal', async () => { + const budgetPage = await navigation.goToBudgetPage(); + await budgetPage.waitForBudgetTable(); + + await budgetPage.openTrackingBudgetSummaryMenu(); + + const summaryModalHeading = page + .getByRole('dialog') + .getByRole('heading'); + + await expect(summaryModalHeading).toHaveText('Budget Summary'); + await expect(page).toMatchThemeScreenshots(); + }); + } + }); +}); diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--14404-in-the-page-header-opens-the-month-menu-modal-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--14404-in-the-page-header-opens-the-month-menu-modal-3-chromium-linux.png new file mode 100644 index 00000000000..d0e4358f008 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--14404-in-the-page-header-opens-the-month-menu-modal-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--321fd-ed-amount-opens-the-budget-summary-menu-modal-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--321fd-ed-amount-opens-the-budget-summary-menu-modal-2-chromium-linux.png new file mode 100644 index 00000000000..76654922336 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--321fd-ed-amount-opens-the-budget-summary-menu-modal-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--4bb70-ed-amount-opens-the-budget-summary-menu-modal-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--4bb70-ed-amount-opens-the-budget-summary-menu-modal-1-chromium-linux.png new file mode 100644 index 00000000000..fd33f815ca6 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--4bb70-ed-amount-opens-the-budget-summary-menu-modal-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--589a6-the-page-header-shows-the-next-month-s-budget-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--589a6-the-page-header-shows-the-next-month-s-budget-2-chromium-linux.png new file mode 100644 index 00000000000..058a5667394 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--589a6-the-page-header-shows-the-next-month-s-budget-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--6ab37-roup-name-opens-the-category-group-menu-modal-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--6ab37-roup-name-opens-the-category-group-menu-modal-1-chromium-linux.png new file mode 100644 index 00000000000..1bcf9bf9faa Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--6ab37-roup-name-opens-the-category-group-menu-modal-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--6dbdb-page-header-shows-the-previous-month-s-budget-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--6dbdb-page-header-shows-the-previous-month-s-budget-1-chromium-linux.png new file mode 100644 index 00000000000..d37b4a2d7d4 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--6dbdb-page-header-shows-the-previous-month-s-budget-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--7bd8f-the-page-header-shows-the-next-month-s-budget-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--7bd8f-the-page-header-shows-the-next-month-s-budget-3-chromium-linux.png new file mode 100644 index 00000000000..988870579d7 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--7bd8f-the-page-header-shows-the-next-month-s-budget-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--884ac-the-page-header-shows-the-next-month-s-budget-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--884ac-the-page-header-shows-the-next-month-s-budget-1-chromium-linux.png new file mode 100644 index 00000000000..460e95731b2 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--884ac-the-page-header-shows-the-next-month-s-budget-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--94a79-roup-name-opens-the-category-group-menu-modal-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--94a79-roup-name-opens-the-category-group-menu-modal-2-chromium-linux.png new file mode 100644 index 00000000000..8d67f0370be Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--94a79-roup-name-opens-the-category-group-menu-modal-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--94a85-ed-amount-opens-the-budget-summary-menu-modal-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--94a85-ed-amount-opens-the-budget-summary-menu-modal-3-chromium-linux.png new file mode 100644 index 00000000000..71f459b3765 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--94a85-ed-amount-opens-the-budget-summary-menu-modal-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--96ebb-page-header-shows-the-previous-month-s-budget-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--96ebb-page-header-shows-the-previous-month-s-budget-3-chromium-linux.png new file mode 100644 index 00000000000..3c7e86938d5 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--96ebb-page-header-shows-the-previous-month-s-budget-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--9e6aa-in-the-page-header-opens-the-budget-page-menu-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--9e6aa-in-the-page-header-opens-the-budget-page-menu-1-chromium-linux.png new file mode 100644 index 00000000000..5e2cf02ad51 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--9e6aa-in-the-page-header-opens-the-budget-page-menu-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--bbde3-roup-name-opens-the-category-group-menu-modal-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--bbde3-roup-name-opens-the-category-group-menu-modal-3-chromium-linux.png new file mode 100644 index 00000000000..fdd6356d63b Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--bbde3-roup-name-opens-the-category-group-menu-modal-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--bed18-in-the-page-header-opens-the-month-menu-modal-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--bed18-in-the-page-header-opens-the-month-menu-modal-1-chromium-linux.png new file mode 100644 index 00000000000..5dc3d48b6b0 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--bed18-in-the-page-header-opens-the-month-menu-modal-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--c18ad-l-redirects-to-the-category-transactions-page-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--c18ad-l-redirects-to-the-category-transactions-page-1-chromium-linux.png new file mode 100644 index 00000000000..bc0d475808a Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--c18ad-l-redirects-to-the-category-transactions-page-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--ceb3a-in-the-page-header-opens-the-month-menu-modal-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--ceb3a-in-the-page-header-opens-the-month-menu-modal-2-chromium-linux.png new file mode 100644 index 00000000000..a63219d6de3 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--ceb3a-in-the-page-header-opens-the-month-menu-modal-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--d270d-in-the-page-header-opens-the-budget-page-menu-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--d270d-in-the-page-header-opens-the-budget-page-menu-2-chromium-linux.png new file mode 100644 index 00000000000..b9ba2b27d1e Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--d270d-in-the-page-header-opens-the-budget-page-menu-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--d7184-page-header-shows-the-previous-month-s-budget-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--d7184-page-header-shows-the-previous-month-s-budget-2-chromium-linux.png new file mode 100644 index 00000000000..4f90b89186a Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--d7184-page-header-shows-the-previous-month-s-budget-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--e995e-l-redirects-to-the-category-transactions-page-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--e995e-l-redirects-to-the-category-transactions-page-3-chromium-linux.png new file mode 100644 index 00000000000..f0279600ae4 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--e995e-l-redirects-to-the-category-transactions-page-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--fdd57-in-the-page-header-opens-the-budget-page-menu-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--fdd57-in-the-page-header-opens-the-budget-page-menu-3-chromium-linux.png new file mode 100644 index 00000000000..618bf0641ff Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--fdd57-in-the-page-header-opens-the-budget-page-menu-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--ff568-l-redirects-to-the-category-transactions-page-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--ff568-l-redirects-to-the-category-transactions-page-2-chromium-linux.png new file mode 100644 index 00000000000..a6fb65dbbbf Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking--ff568-l-redirects-to-the-category-transactions-page-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-button-opens-the-balance-menu-modal-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-button-opens-the-balance-menu-modal-1-chromium-linux.png new file mode 100644 index 00000000000..5869adc1b5e Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-button-opens-the-balance-menu-modal-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-button-opens-the-balance-menu-modal-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-button-opens-the-balance-menu-modal-2-chromium-linux.png new file mode 100644 index 00000000000..034d3082d75 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-button-opens-the-balance-menu-modal-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-button-opens-the-balance-menu-modal-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-button-opens-the-balance-menu-modal-3-chromium-linux.png new file mode 100644 index 00000000000..ac062843aa8 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-button-opens-the-balance-menu-modal-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-1-chromium-linux.png new file mode 100644 index 00000000000..5869adc1b5e Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-2-chromium-linux.png new file mode 100644 index 00000000000..034d3082d75 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-3-chromium-linux.png new file mode 100644 index 00000000000..ac062843aa8 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-1-chromium-linux.png new file mode 100644 index 00000000000..984b80b5728 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-2-chromium-linux.png new file mode 100644 index 00000000000..06005e54628 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-3-chromium-linux.png new file mode 100644 index 00000000000..dd02417d9b9 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-category-name-opens-the-category-menu-modal-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-category-name-opens-the-category-menu-modal-1-chromium-linux.png new file mode 100644 index 00000000000..d5f2ffa90f9 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-category-name-opens-the-category-menu-modal-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-category-name-opens-the-category-menu-modal-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-category-name-opens-the-category-menu-modal-2-chromium-linux.png new file mode 100644 index 00000000000..3e85352b87b Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-category-name-opens-the-category-menu-modal-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-category-name-opens-the-category-menu-modal-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-category-name-opens-the-category-menu-modal-3-chromium-linux.png new file mode 100644 index 00000000000..c590bd3bef0 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-category-name-opens-the-category-menu-modal-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png new file mode 100644 index 00000000000..9da21147232 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.png new file mode 100644 index 00000000000..410c42e23b6 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-loads-the-budget-page-with-budgeted-amounts-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-loads-the-budget-page-with-budgeted-amounts-3-chromium-linux.png new file mode 100644 index 00000000000..4cb3721acf5 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-loads-the-budget-page-with-budgeted-amounts-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-updates-the-budgeted-amount-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-updates-the-budgeted-amount-1-chromium-linux.png new file mode 100644 index 00000000000..4f68721b84d Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-updates-the-budgeted-amount-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-updates-the-budgeted-amount-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-updates-the-budgeted-amount-2-chromium-linux.png new file mode 100644 index 00000000000..a19cedda1d0 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-updates-the-budgeted-amount-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-updates-the-budgeted-amount-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-updates-the-budgeted-amount-3-chromium-linux.png new file mode 100644 index 00000000000..745a08af1c9 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Envelope-updates-the-budgeted-amount-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--0ba04-nt-amount-opens-the-budget-summary-menu-modal-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--0ba04-nt-amount-opens-the-budget-summary-menu-modal-1-chromium-linux.png new file mode 100644 index 00000000000..5dc07de4460 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--0ba04-nt-amount-opens-the-budget-summary-menu-modal-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--0dfe7-page-header-shows-the-previous-month-s-budget-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--0dfe7-page-header-shows-the-previous-month-s-budget-1-chromium-linux.png new file mode 100644 index 00000000000..73e12fc76ea Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--0dfe7-page-header-shows-the-previous-month-s-budget-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--11290-l-redirects-to-the-category-transactions-page-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--11290-l-redirects-to-the-category-transactions-page-3-chromium-linux.png new file mode 100644 index 00000000000..f0279600ae4 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--11290-l-redirects-to-the-category-transactions-page-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--1ce6d-nt-amount-opens-the-budget-summary-menu-modal-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--1ce6d-nt-amount-opens-the-budget-summary-menu-modal-2-chromium-linux.png new file mode 100644 index 00000000000..548b0a3d9a8 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--1ce6d-nt-amount-opens-the-budget-summary-menu-modal-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--42062-in-the-page-header-opens-the-month-menu-modal-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--42062-in-the-page-header-opens-the-month-menu-modal-2-chromium-linux.png new file mode 100644 index 00000000000..75a2f7234cc Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--42062-in-the-page-header-opens-the-month-menu-modal-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--49fb6-in-the-page-header-opens-the-month-menu-modal-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--49fb6-in-the-page-header-opens-the-month-menu-modal-3-chromium-linux.png new file mode 100644 index 00000000000..0a6d217ad52 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--49fb6-in-the-page-header-opens-the-month-menu-modal-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--57d88-l-redirects-to-the-category-transactions-page-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--57d88-l-redirects-to-the-category-transactions-page-2-chromium-linux.png new file mode 100644 index 00000000000..a6fb65dbbbf Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--57d88-l-redirects-to-the-category-transactions-page-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--5d90c-l-redirects-to-the-category-transactions-page-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--5d90c-l-redirects-to-the-category-transactions-page-1-chromium-linux.png new file mode 100644 index 00000000000..bc0d475808a Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--5d90c-l-redirects-to-the-category-transactions-page-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--5f098-roup-name-opens-the-category-group-menu-modal-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--5f098-roup-name-opens-the-category-group-menu-modal-1-chromium-linux.png new file mode 100644 index 00000000000..c599478f424 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--5f098-roup-name-opens-the-category-group-menu-modal-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--7c353-the-page-header-shows-the-next-month-s-budget-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--7c353-the-page-header-shows-the-next-month-s-budget-3-chromium-linux.png new file mode 100644 index 00000000000..64ccf3b3e34 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--7c353-the-page-header-shows-the-next-month-s-budget-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--929be-roup-name-opens-the-category-group-menu-modal-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--929be-roup-name-opens-the-category-group-menu-modal-3-chromium-linux.png new file mode 100644 index 00000000000..95f3f10b042 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--929be-roup-name-opens-the-category-group-menu-modal-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--a3783-in-the-page-header-opens-the-budget-page-menu-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--a3783-in-the-page-header-opens-the-budget-page-menu-1-chromium-linux.png new file mode 100644 index 00000000000..6484a50e024 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--a3783-in-the-page-header-opens-the-budget-page-menu-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--a8b5e-in-the-page-header-opens-the-budget-page-menu-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--a8b5e-in-the-page-header-opens-the-budget-page-menu-3-chromium-linux.png new file mode 100644 index 00000000000..f7136804f45 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--a8b5e-in-the-page-header-opens-the-budget-page-menu-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--b1562-in-the-page-header-opens-the-month-menu-modal-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--b1562-in-the-page-header-opens-the-month-menu-modal-1-chromium-linux.png new file mode 100644 index 00000000000..d89bd29270b Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--b1562-in-the-page-header-opens-the-month-menu-modal-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--cfb69-page-header-shows-the-previous-month-s-budget-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--cfb69-page-header-shows-the-previous-month-s-budget-2-chromium-linux.png new file mode 100644 index 00000000000..a7fc68c3c29 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--cfb69-page-header-shows-the-previous-month-s-budget-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--d5af6-the-page-header-shows-the-next-month-s-budget-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--d5af6-the-page-header-shows-the-next-month-s-budget-1-chromium-linux.png new file mode 100644 index 00000000000..b044c08e50b Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--d5af6-the-page-header-shows-the-next-month-s-budget-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--dc927-roup-name-opens-the-category-group-menu-modal-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--dc927-roup-name-opens-the-category-group-menu-modal-2-chromium-linux.png new file mode 100644 index 00000000000..f9556fe46c0 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--dc927-roup-name-opens-the-category-group-menu-modal-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f2198-the-page-header-shows-the-next-month-s-budget-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f2198-the-page-header-shows-the-next-month-s-budget-2-chromium-linux.png new file mode 100644 index 00000000000..3f2e3397c1a Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f2198-the-page-header-shows-the-next-month-s-budget-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f224f-nt-amount-opens-the-budget-summary-menu-modal-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f224f-nt-amount-opens-the-budget-summary-menu-modal-3-chromium-linux.png new file mode 100644 index 00000000000..28ffda6ae88 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f224f-nt-amount-opens-the-budget-summary-menu-modal-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f7fa3-page-header-shows-the-previous-month-s-budget-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f7fa3-page-header-shows-the-previous-month-s-budget-3-chromium-linux.png new file mode 100644 index 00000000000..bce1db2c68e Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f7fa3-page-header-shows-the-previous-month-s-budget-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f8a19-in-the-page-header-opens-the-budget-page-menu-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f8a19-in-the-page-header-opens-the-budget-page-menu-2-chromium-linux.png new file mode 100644 index 00000000000..73cd3660794 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f8a19-in-the-page-header-opens-the-budget-page-menu-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-button-opens-the-balance-menu-modal-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-button-opens-the-balance-menu-modal-1-chromium-linux.png new file mode 100644 index 00000000000..91e45c2a9ee Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-button-opens-the-balance-menu-modal-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-button-opens-the-balance-menu-modal-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-button-opens-the-balance-menu-modal-2-chromium-linux.png new file mode 100644 index 00000000000..e43057e5fb1 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-button-opens-the-balance-menu-modal-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-button-opens-the-balance-menu-modal-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-button-opens-the-balance-menu-modal-3-chromium-linux.png new file mode 100644 index 00000000000..65aab550f2c Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-button-opens-the-balance-menu-modal-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-1-chromium-linux.png new file mode 100644 index 00000000000..91e45c2a9ee Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-2-chromium-linux.png new file mode 100644 index 00000000000..e43057e5fb1 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-3-chromium-linux.png new file mode 100644 index 00000000000..65aab550f2c Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-1-chromium-linux.png new file mode 100644 index 00000000000..bdb7e1a9fc7 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-2-chromium-linux.png new file mode 100644 index 00000000000..55c39e9fc41 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-3-chromium-linux.png new file mode 100644 index 00000000000..23d1ea1afd3 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-category-name-opens-the-category-menu-modal-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-category-name-opens-the-category-menu-modal-1-chromium-linux.png new file mode 100644 index 00000000000..75f8db9c1ce Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-category-name-opens-the-category-menu-modal-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-category-name-opens-the-category-menu-modal-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-category-name-opens-the-category-menu-modal-2-chromium-linux.png new file mode 100644 index 00000000000..66c1f799be3 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-category-name-opens-the-category-menu-modal-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-category-name-opens-the-category-menu-modal-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-category-name-opens-the-category-menu-modal-3-chromium-linux.png new file mode 100644 index 00000000000..0ab29fefb78 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-category-name-opens-the-category-menu-modal-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png new file mode 100644 index 00000000000..bb0ac8bbf88 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.png new file mode 100644 index 00000000000..631e8256296 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-loads-the-budget-page-with-budgeted-amounts-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-loads-the-budget-page-with-budgeted-amounts-3-chromium-linux.png new file mode 100644 index 00000000000..b662506066c Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-loads-the-budget-page-with-budgeted-amounts-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-updates-the-budgeted-amount-1-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-updates-the-budgeted-amount-1-chromium-linux.png new file mode 100644 index 00000000000..a6c178b7a6c Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-updates-the-budgeted-amount-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-updates-the-budgeted-amount-2-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-updates-the-budgeted-amount-2-chromium-linux.png new file mode 100644 index 00000000000..38c4c7b2b1e Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-updates-the-budgeted-amount-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-updates-the-budgeted-amount-3-chromium-linux.png b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-updates-the-budgeted-amount-3-chromium-linux.png new file mode 100644 index 00000000000..7fc874ece94 Binary files /dev/null and b/packages/desktop-client/e2e/budget.mobile.test.js-snapshots/Mobile-Budget-Tracking-updates-the-budgeted-amount-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.test.js-snapshots/Budget-renders-the-summary-information-available-funds-overspent-budgeted-and-for-next-month-1-chromium-linux.png b/packages/desktop-client/e2e/budget.test.js-snapshots/Budget-renders-the-summary-information-available-funds-overspent-budgeted-and-for-next-month-1-chromium-linux.png index 896da24b7f0..8fba61126ec 100644 Binary files a/packages/desktop-client/e2e/budget.test.js-snapshots/Budget-renders-the-summary-information-available-funds-overspent-budgeted-and-for-next-month-1-chromium-linux.png and b/packages/desktop-client/e2e/budget.test.js-snapshots/Budget-renders-the-summary-information-available-funds-overspent-budgeted-and-for-next-month-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/budget.test.js-snapshots/Budget-renders-the-summary-information-available-funds-overspent-budgeted-and-for-next-month-3-chromium-linux.png b/packages/desktop-client/e2e/budget.test.js-snapshots/Budget-renders-the-summary-information-available-funds-overspent-budgeted-and-for-next-month-3-chromium-linux.png index 9b39108c6c8..eaffb35c1a5 100644 Binary files a/packages/desktop-client/e2e/budget.test.js-snapshots/Budget-renders-the-summary-information-available-funds-overspent-budgeted-and-for-next-month-3-chromium-linux.png and b/packages/desktop-client/e2e/budget.test.js-snapshots/Budget-renders-the-summary-information-available-funds-overspent-budgeted-and-for-next-month-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-checks-that-settings-page-can-be-opened-2-chromium-linux.png b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-checks-that-settings-page-can-be-opened-2-chromium-linux.png deleted file mode 100644 index 456d02f3632..00000000000 Binary files a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-checks-that-settings-page-can-be-opened-2-chromium-linux.png and /dev/null differ diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-from-accounts-id-page-1-chromium-linux.png b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-from-accounts-id-page-1-chromium-linux.png deleted file mode 100644 index a46b5dc8c62..00000000000 Binary files a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-from-accounts-id-page-1-chromium-linux.png and /dev/null differ diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-4-chromium-linux.png b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-4-chromium-linux.png deleted file mode 100644 index 0a7f75a1db9..00000000000 Binary files a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-4-chromium-linux.png and /dev/null differ diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png deleted file mode 100644 index db0ea1066d0..00000000000 Binary files a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png and /dev/null differ diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.png b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.png deleted file mode 100644 index 52423795d8b..00000000000 Binary files a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.png and /dev/null differ diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-3-chromium-linux.png b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-3-chromium-linux.png deleted file mode 100644 index fadeb6b4274..00000000000 Binary files a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-3-chromium-linux.png and /dev/null differ diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-the-accounts-page-and-asserts-on-balances-1-chromium-linux.png b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-the-accounts-page-and-asserts-on-balances-1-chromium-linux.png deleted file mode 100644 index 9f22f964fe9..00000000000 Binary files a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-the-accounts-page-and-asserts-on-balances-1-chromium-linux.png and /dev/null differ diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-the-accounts-page-and-asserts-on-balances-2-chromium-linux.png b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-the-accounts-page-and-asserts-on-balances-2-chromium-linux.png deleted file mode 100644 index f11e904a0f6..00000000000 Binary files a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-the-accounts-page-and-asserts-on-balances-2-chromium-linux.png and /dev/null differ diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-the-accounts-page-and-asserts-on-balances-3-chromium-linux.png b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-the-accounts-page-and-asserts-on-balances-3-chromium-linux.png deleted file mode 100644 index 38af663c40e..00000000000 Binary files a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-opens-the-accounts-page-and-asserts-on-balances-3-chromium-linux.png and /dev/null differ diff --git a/packages/desktop-client/e2e/page-models/mobile-account-page.js b/packages/desktop-client/e2e/page-models/mobile-account-page.js index 0d831015c3b..34a572206bb 100644 --- a/packages/desktop-client/e2e/page-models/mobile-account-page.js +++ b/packages/desktop-client/e2e/page-models/mobile-account-page.js @@ -6,9 +6,9 @@ export class MobileAccountPage { this.heading = page.getByRole('heading'); this.balance = page.getByTestId('transactions-balance'); - this.noTransactionsFoundError = page.getByText('No transactions'); + this.noTransactionsMessage = page.getByText('No transactions'); this.searchBox = page.getByPlaceholder(/^Search/); - this.transactionList = page.getByLabel('transaction list'); + this.transactionList = page.getByLabel('Transaction list'); this.transactions = this.transactionList.getByRole('button'); this.createTransactionButton = page.getByRole('button', { name: 'Add Transaction', diff --git a/packages/desktop-client/e2e/page-models/mobile-budget-page.js b/packages/desktop-client/e2e/page-models/mobile-budget-page.js index c5d843fd220..7a3a63c0520 100644 --- a/packages/desktop-client/e2e/page-models/mobile-budget-page.js +++ b/packages/desktop-client/e2e/page-models/mobile-budget-page.js @@ -1,9 +1,305 @@ +import { MobileAccountPage } from './mobile-account-page'; + export class MobileBudgetPage { + MONTH_HEADER_DATE_FORMAT = 'MMMM ‘yy'; + constructor(page) { this.page = page; - this.categoryNames = page + this.#initializePageHeaderLocators(page); + this.#initializeBudgetTableLocators(page); + } + + async determineBudgetType() { + return (await this.#getButtonForEnvelopeBudgetSummary({ + throwIfNotFound: false, + })) !== null + ? 'Envelope' + : 'Tracking'; + } + + #initializeBudgetTableLocators(page) { + this.budgetTableHeader = page.getByTestId('budget-table-header'); + + // Envelope budget summary buttons + this.toBudgetButton = this.budgetTableHeader.getByRole('button', { + name: 'To Budget', + }); + this.overbudgetedButton = this.budgetTableHeader.getByRole('button', { + name: 'Overbudgeted', + }); + + // Tracking budget summary buttons + this.savedButton = this.budgetTableHeader.getByRole('button', { + name: 'Saved', + }); + this.projectedSavingsButton = this.budgetTableHeader.getByRole('button', { + name: 'Projected Savings', + }); + this.overspentButton = this.budgetTableHeader.getByRole('button', { + name: 'Overspent', + }); + + this.budgetedHeaderButton = this.budgetTableHeader.getByRole('button', { + name: 'Budgeted', + }); + this.spentHeaderButton = this.budgetTableHeader.getByRole('button', { + name: 'Spent', + }); + + this.budgetTable = page.getByTestId('budget-table'); + + this.categoryRows = this.budgetTable .getByTestId('budget-groups') - .getByTestId('category-name'); + .getByTestId('category-row'); + + this.categoryNames = this.categoryRows.getByTestId('category-name'); + + this.categoryGroupRows = this.budgetTable + .getByTestId('budget-groups') + .getByTestId('category-group-row'); + + this.categoryGroupNames = this.categoryGroupRows.getByTestId( + 'category-group-name', + ); + } + + #initializePageHeaderLocators(page) { + this.heading = page.getByRole('heading'); + this.previousMonthButton = this.heading.getByRole('button', { + name: 'Previous month', + }); + this.selectedBudgetMonthButton = this.heading.locator('button[data-month]'); + this.nextMonthButton = this.heading.getByRole('button', { + name: 'Next month', + }); + this.budgetPageMenuButton = page.getByRole('button', { + name: 'Budget page menu', + }); + } + + async waitForBudgetTable() { + await this.budgetTable.waitFor(); + } + + async toggleVisibleColumns(maxAttempts = 3) { + for (let i = 0; i < maxAttempts; i++) { + if (await this.budgetedHeaderButton.isVisible()) { + await this.budgetedHeaderButton.click(); + return; + } + if (await this.spentHeaderButton.isVisible()) { + await this.spentHeaderButton.click(); + return; + } + await this.page.waitForTimeout(1000); + } + + throw new Error('Budgeted/Spent columns could not be located on the page'); + } + + async getSelectedMonth() { + return await this.heading + .locator('[data-month]') + .getAttribute('data-month'); + } + + async openBudgetPageMenu() { + await this.budgetPageMenuButton.click(); + } + + async getCategoryGroupNameForRow(idx) { + return this.categoryGroupNames.nth(idx).textContent(); + } + + #getButtonForCategoryGroup(categoryGroupName) { + return this.categoryGroupRows.getByRole('button', { + name: categoryGroupName, + exact: true, + }); + } + + async openCategoryGroupMenu(categoryGroupName) { + const categoryGroupButton = + await this.#getButtonForCategoryGroup(categoryGroupName); + await categoryGroupButton.click(); + } + + async getCategoryNameForRow(idx) { + return this.categoryNames.nth(idx).textContent(); + } + + #getButtonForCategory(categoryName) { + return this.categoryRows.getByRole('button', { + name: categoryName, + exact: true, + }); + } + + async openCategoryMenu(categoryName) { + const categoryButton = await this.#getButtonForCategory(categoryName); + await categoryButton.click(); + } + + async #getButtonForCell(buttonType, categoryName) { + const buttonSelector = + buttonType === 'Budgeted' + ? `Open budget menu for ${categoryName} category` + : `Show transactions for ${categoryName} category`; + + let button = this.budgetTable.getByRole('button', { name: buttonSelector }); + + if (await button.isVisible()) { + return button; + } + + await this.toggleVisibleColumns(); + button = this.budgetTable.getByRole('button', { name: buttonSelector }); + + if (await button.isVisible()) { + return button; + } + + throw new Error( + `${buttonType} button for category ${categoryName} could not be located on the page`, + ); + } + + async getButtonForBudgeted(categoryName) { + return await this.#getButtonForCell('Budgeted', categoryName); + } + + async getButtonForSpent(categoryName) { + return await this.#getButtonForCell('Spent', categoryName); + } + + async openBudgetMenu(categoryName) { + const budgetedButton = await this.getButtonForBudgeted(categoryName); + await budgetedButton.click(); + } + + async setBudget(categoryName, newAmount) { + const budgetedButton = await this.getButtonForBudgeted(categoryName); + await budgetedButton.click(); + + await this.page.keyboard.type(String(newAmount)); + await this.page.keyboard.press('Enter'); + } + + async openSpentPage(categoryName) { + const spentButton = await this.getButtonForSpent(categoryName); + await spentButton.click(); + + return new MobileAccountPage(this.page); + } + + async openBalanceMenu(categoryName) { + const balanceButton = this.budgetTable.getByRole('button', { + name: `Open balance menu for ${categoryName} category`, + }); + + if (await balanceButton.isVisible()) { + await balanceButton.click(); + } else { + throw new Error( + `Balance button for category ${categoryName} not found or not visible`, + ); + } + } + + async #waitForNewMonthToLoad({ + currentMonth, + errorMessage, + maxAttempts = 3, + } = {}) { + for (let attempt = 0; attempt < maxAttempts; attempt++) { + const newMonth = await this.getSelectedMonth(); + if (newMonth !== currentMonth) { + return newMonth; + } + await this.page.waitForTimeout(500); + } + + throw new Error(errorMessage); + } + + async goToPreviousMonth({ maxAttempts = 3 } = {}) { + const currentMonth = await this.getSelectedMonth(); + + await this.previousMonthButton.click(); + + return await this.#waitForNewMonthToLoad({ + currentMonth, + maxAttempts, + errorMessage: + 'Failed to navigate to the previous month after maximum attempts', + }); + } + + async openMonthMenu() { + await this.selectedBudgetMonthButton.click(); + } + + async goToNextMonth({ maxAttempts = 3 } = {}) { + const currentMonth = await this.getSelectedMonth(); + + await this.nextMonthButton.click(); + + return await this.#waitForNewMonthToLoad({ + currentMonth, + maxAttempts, + errorMessage: + 'Failed to navigate to the next month after maximum attempts', + }); + } + + async #getButtonForEnvelopeBudgetSummary({ throwIfNotFound = true } = {}) { + if (await this.toBudgetButton.isVisible()) { + return this.toBudgetButton; + } + + if (await this.overbudgetedButton.isVisible()) { + return this.overbudgetedButton; + } + + if (!throwIfNotFound) { + return null; + } + + throw new Error( + 'Neither “To Budget” nor “Overbudgeted” button could be located on the page', + ); + } + + async openEnvelopeBudgetSummaryMenu() { + const budgetSummaryButton = await this.#getButtonForEnvelopeBudgetSummary(); + await budgetSummaryButton.click(); + } + + async #getButtonForTrackingBudgetSummary({ throwIfNotFound = true } = {}) { + if (await this.savedButton.isVisible()) { + return this.savedButton; + } + + if (await this.projectedSavingsButton.isVisible()) { + return this.projectedSavingsButton; + } + + if (await this.overspentButton.isVisible()) { + return this.overspentButton; + } + + if (!throwIfNotFound) { + return null; + } + + throw new Error( + 'None of “Saved”, “Projected Savings”, or “Overspent” buttons could be located on the page', + ); + } + + async openTrackingBudgetSummaryMenu() { + const budgetSummaryButton = await this.#getButtonForTrackingBudgetSummary(); + await budgetSummaryButton.click(); } } diff --git a/packages/desktop-client/e2e/page-models/settings-page.js b/packages/desktop-client/e2e/page-models/settings-page.js index 3b42dabbd31..dcf838cea5b 100644 --- a/packages/desktop-client/e2e/page-models/settings-page.js +++ b/packages/desktop-client/e2e/page-models/settings-page.js @@ -7,9 +7,28 @@ export class SettingsPage { await this.page.getByRole('button', { name: 'Export data' }).click(); } + async useBudgetType(budgetType) { + await this.enableExperimentalFeature('Budget mode toggle'); + + const switchBudgetTypeButton = this.page.getByRole('button', { + name: `Switch to ${budgetType} budgeting`, + }); + + await switchBudgetTypeButton.click(); + } + async enableExperimentalFeature(featureName) { - await this.page.getByTestId('advanced-settings').click(); - await this.page.getByTestId('experimental-settings').click(); - await this.page.getByLabel(featureName).check(); + const advancedSettingsButton = this.page.getByTestId('advanced-settings'); + await advancedSettingsButton.click(); + + const experimentalSettingsButton = this.page.getByTestId( + 'experimental-settings', + ); + await experimentalSettingsButton.click(); + + const featureCheckbox = this.page.getByRole('checkbox', { + name: featureName, + }); + await featureCheckbox.click(); } } diff --git a/packages/desktop-client/e2e/reports.test.js-snapshots/Reports-custom-reports-Validates-that-show-summary-button-shows-the-summary-1-chromium-linux.png b/packages/desktop-client/e2e/reports.test.js-snapshots/Reports-custom-reports-Validates-that-show-summary-button-shows-the-summary-1-chromium-linux.png index 4e1278d1d5f..92e54bb9ed5 100644 Binary files a/packages/desktop-client/e2e/reports.test.js-snapshots/Reports-custom-reports-Validates-that-show-summary-button-shows-the-summary-1-chromium-linux.png and b/packages/desktop-client/e2e/reports.test.js-snapshots/Reports-custom-reports-Validates-that-show-summary-button-shows-the-summary-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-checks-the-page-visuals-1-chromium-linux.png b/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-checks-the-page-visuals-1-chromium-linux.png index e8ed70e8979..c4ef30851c9 100644 Binary files a/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-checks-the-page-visuals-1-chromium-linux.png and b/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-checks-the-page-visuals-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-4-chromium-linux.png b/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-4-chromium-linux.png index d4b7313b410..4a395ced02d 100644 Binary files a/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-4-chromium-linux.png and b/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-4-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-split-transaction-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-1-chromium-linux.png b/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-split-transaction-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-1-chromium-linux.png index 0e7fdf49c01..385ffe558f1 100644 Binary files a/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-split-transaction-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-1-chromium-linux.png and b/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-split-transaction-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/schedules.test.js-snapshots/Schedules-creates-a-new-schedule-posts-the-transaction-and-later-completes-it-7-chromium-linux.png b/packages/desktop-client/e2e/schedules.test.js-snapshots/Schedules-creates-a-new-schedule-posts-the-transaction-and-later-completes-it-7-chromium-linux.png index 460687d313d..82f7f27da36 100644 Binary files a/packages/desktop-client/e2e/schedules.test.js-snapshots/Schedules-creates-a-new-schedule-posts-the-transaction-and-later-completes-it-7-chromium-linux.png and b/packages/desktop-client/e2e/schedules.test.js-snapshots/Schedules-creates-a-new-schedule-posts-the-transaction-and-later-completes-it-7-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/schedules.test.js-snapshots/Schedules-creates-a-new-schedule-posts-the-transaction-and-later-completes-it-8-chromium-linux.png b/packages/desktop-client/e2e/schedules.test.js-snapshots/Schedules-creates-a-new-schedule-posts-the-transaction-and-later-completes-it-8-chromium-linux.png index d5fa8b02dcf..865ede80633 100644 Binary files a/packages/desktop-client/e2e/schedules.test.js-snapshots/Schedules-creates-a-new-schedule-posts-the-transaction-and-later-completes-it-8-chromium-linux.png and b/packages/desktop-client/e2e/schedules.test.js-snapshots/Schedules-creates-a-new-schedule-posts-the-transaction-and-later-completes-it-8-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/settings.mobile.test.js b/packages/desktop-client/e2e/settings.mobile.test.js new file mode 100644 index 00000000000..89e291ee693 --- /dev/null +++ b/packages/desktop-client/e2e/settings.mobile.test.js @@ -0,0 +1,43 @@ +import { test, expect } from '@playwright/test'; + +import { ConfigurationPage } from './page-models/configuration-page'; +import { MobileNavigation } from './page-models/mobile-navigation'; + +test.describe('Mobile Settings', () => { + let page; + let navigation; + let configurationPage; + + test.beforeEach(async ({ browser }) => { + page = await browser.newPage(); + navigation = new MobileNavigation(page); + configurationPage = new ConfigurationPage(page); + + await page.setViewportSize({ + width: 350, + height: 600, + }); + await page.goto('/'); + await configurationPage.createTestFile(); + }); + + test.afterEach(async () => { + await page.close(); + }); + + test('checks that settings page can be opened', async () => { + const settingsPage = await navigation.goToSettingsPage(); + await expect(page).toMatchThemeScreenshots(); + + const downloadPromise = page.waitForEvent('download'); + + await settingsPage.exportData(); + + const download = await downloadPromise; + + expect(await download.suggestedFilename()).toMatch( + /^\d{4}-\d{2}-\d{2}-.*.zip$/, + ); + await expect(page).toMatchThemeScreenshots(); + }); +}); diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-checks-that-settings-page-can-be-opened-1-chromium-linux.png b/packages/desktop-client/e2e/settings.mobile.test.js-snapshots/Mobile-Settings-checks-that-settings-page-can-be-opened-1-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-checks-that-settings-page-can-be-opened-1-chromium-linux.png rename to packages/desktop-client/e2e/settings.mobile.test.js-snapshots/Mobile-Settings-checks-that-settings-page-can-be-opened-1-chromium-linux.png diff --git a/packages/desktop-client/e2e/settings.mobile.test.js-snapshots/Mobile-Settings-checks-that-settings-page-can-be-opened-2-chromium-linux.png b/packages/desktop-client/e2e/settings.mobile.test.js-snapshots/Mobile-Settings-checks-that-settings-page-can-be-opened-2-chromium-linux.png new file mode 100644 index 00000000000..cd4126a2cbd Binary files /dev/null and b/packages/desktop-client/e2e/settings.mobile.test.js-snapshots/Mobile-Settings-checks-that-settings-page-can-be-opened-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-checks-that-settings-page-can-be-opened-3-chromium-linux.png b/packages/desktop-client/e2e/settings.mobile.test.js-snapshots/Mobile-Settings-checks-that-settings-page-can-be-opened-3-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-checks-that-settings-page-can-be-opened-3-chromium-linux.png rename to packages/desktop-client/e2e/settings.mobile.test.js-snapshots/Mobile-Settings-checks-that-settings-page-can-be-opened-3-chromium-linux.png diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-checks-that-settings-page-can-be-opened-4-chromium-linux.png b/packages/desktop-client/e2e/settings.mobile.test.js-snapshots/Mobile-Settings-checks-that-settings-page-can-be-opened-4-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-checks-that-settings-page-can-be-opened-4-chromium-linux.png rename to packages/desktop-client/e2e/settings.mobile.test.js-snapshots/Mobile-Settings-checks-that-settings-page-can-be-opened-4-chromium-linux.png diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-checks-that-settings-page-can-be-opened-5-chromium-linux.png b/packages/desktop-client/e2e/settings.mobile.test.js-snapshots/Mobile-Settings-checks-that-settings-page-can-be-opened-5-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-checks-that-settings-page-can-be-opened-5-chromium-linux.png rename to packages/desktop-client/e2e/settings.mobile.test.js-snapshots/Mobile-Settings-checks-that-settings-page-can-be-opened-5-chromium-linux.png diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-checks-that-settings-page-can-be-opened-6-chromium-linux.png b/packages/desktop-client/e2e/settings.mobile.test.js-snapshots/Mobile-Settings-checks-that-settings-page-can-be-opened-6-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-checks-that-settings-page-can-be-opened-6-chromium-linux.png rename to packages/desktop-client/e2e/settings.mobile.test.js-snapshots/Mobile-Settings-checks-that-settings-page-can-be-opened-6-chromium-linux.png diff --git a/packages/desktop-client/e2e/mobile.test.js b/packages/desktop-client/e2e/transactions.mobile.test.js similarity index 53% rename from packages/desktop-client/e2e/mobile.test.js rename to packages/desktop-client/e2e/transactions.mobile.test.js index 665b17e3f31..0327dc2b585 100644 --- a/packages/desktop-client/e2e/mobile.test.js +++ b/packages/desktop-client/e2e/transactions.mobile.test.js @@ -3,7 +3,7 @@ import { test, expect } from '@playwright/test'; import { ConfigurationPage } from './page-models/configuration-page'; import { MobileNavigation } from './page-models/mobile-navigation'; -test.describe('Mobile', () => { +test.describe('Mobile Transactions', () => { let page; let navigation; let configurationPage; @@ -25,60 +25,6 @@ test.describe('Mobile', () => { await page.close(); }); - test('loads the budget page with budgeted amounts', async () => { - const budgetPage = await navigation.goToBudgetPage(); - - await expect(budgetPage.categoryNames).toHaveText([ - 'Food', - 'Restaurants', - 'Entertainment', - 'Clothing', - 'General', - 'Gift', - 'Medical', - 'Savings', - 'Cell', - 'Internet', - 'Mortgage', - 'Water', - 'Power', - 'Starting Balances', - 'Misc', - 'Income', - ]); - await expect(page).toMatchThemeScreenshots(); - }); - - test('opens the accounts page and asserts on balances', async () => { - const accountsPage = await navigation.goToAccountsPage(); - - const account = await accountsPage.getNthAccount(1); - - await expect(account.name).toHaveText('Ally Savings'); - await expect(account.balance).toHaveText('7,653.00'); - await expect(page).toMatchThemeScreenshots(); - }); - - test('opens individual account page and checks that filtering is working', async () => { - const accountsPage = await navigation.goToAccountsPage(); - const accountPage = await accountsPage.openNthAccount(0); - - await expect(accountPage.heading).toHaveText('Bank of America'); - expect(await accountPage.getBalance()).toBeGreaterThan(0); - - await expect(accountPage.noTransactionsFoundError).not.toBeVisible(); - await expect(page).toMatchThemeScreenshots(); - - await accountPage.searchByText('nothing should be found'); - await expect(accountPage.noTransactionsFoundError).toBeVisible(); - await expect(accountPage.transactions).toHaveCount(0); - await expect(page).toMatchThemeScreenshots(); - - await accountPage.searchByText('Kroger'); - await expect(accountPage.transactions).not.toHaveCount(0); - await expect(page).toMatchThemeScreenshots(); - }); - test('creates a transaction via footer button', async () => { const transactionEntryPage = await navigation.goToTransactionEntryPage(); await expect(page).toMatchThemeScreenshots(); @@ -136,20 +82,4 @@ test.describe('Mobile', () => { 'KrogerClothing-12.34', ); }); - - test('checks that settings page can be opened', async () => { - const settingsPage = await navigation.goToSettingsPage(); - await expect(page).toMatchThemeScreenshots(); - - const downloadPromise = page.waitForEvent('download'); - - await settingsPage.exportData(); - - const download = await downloadPromise; - - expect(await download.suggestedFilename()).toMatch( - /^\d{4}-\d{2}-\d{2}-.*.zip$/, - ); - await expect(page).toMatchThemeScreenshots(); - }); }); diff --git a/packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-from-accounts-id-page-1-chromium-linux.png b/packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-from-accounts-id-page-1-chromium-linux.png new file mode 100644 index 00000000000..2e18a7006d6 Binary files /dev/null and b/packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-from-accounts-id-page-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-from-accounts-id-page-2-chromium-linux.png b/packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-from-accounts-id-page-2-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-from-accounts-id-page-2-chromium-linux.png rename to packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-from-accounts-id-page-2-chromium-linux.png diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-from-accounts-id-page-3-chromium-linux.png b/packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-from-accounts-id-page-3-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-from-accounts-id-page-3-chromium-linux.png rename to packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-from-accounts-id-page-3-chromium-linux.png diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-1-chromium-linux.png b/packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-1-chromium-linux.png similarity index 52% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-1-chromium-linux.png rename to packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-1-chromium-linux.png index 0520ca7e91b..62d41df64aa 100644 Binary files a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-1-chromium-linux.png and b/packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-2-chromium-linux.png b/packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-2-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-2-chromium-linux.png rename to packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-2-chromium-linux.png diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-3-chromium-linux.png b/packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-3-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-3-chromium-linux.png rename to packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-3-chromium-linux.png diff --git a/packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-4-chromium-linux.png b/packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-4-chromium-linux.png new file mode 100644 index 00000000000..ad745da2d72 Binary files /dev/null and b/packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-4-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-5-chromium-linux.png b/packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-5-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-5-chromium-linux.png rename to packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-5-chromium-linux.png diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-6-chromium-linux.png b/packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-6-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-6-chromium-linux.png rename to packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-6-chromium-linux.png diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-7-chromium-linux.png b/packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-7-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-7-chromium-linux.png rename to packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-7-chromium-linux.png diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-8-chromium-linux.png b/packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-8-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-8-chromium-linux.png rename to packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-8-chromium-linux.png diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-9-chromium-linux.png b/packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-9-chromium-linux.png similarity index 100% rename from packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-9-chromium-linux.png rename to packages/desktop-client/e2e/transactions.mobile.test.js-snapshots/Mobile-Transactions-creates-a-transaction-via-footer-button-9-chromium-linux.png diff --git a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-test-transaction-1-chromium-linux.png b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-test-transaction-1-chromium-linux.png index 545c17ea0bf..9cf0dd26ef4 100644 Binary files a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-test-transaction-1-chromium-linux.png and b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-test-transaction-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-1-chromium-linux.png b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-1-chromium-linux.png index 2a6dceb5475..9c733307f86 100644 Binary files a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-1-chromium-linux.png and b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-1-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-2-chromium-linux.png b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-2-chromium-linux.png index fe93911f83a..fd36fa1e44a 100644 Binary files a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-2-chromium-linux.png and b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-2-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-3-chromium-linux.png b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-3-chromium-linux.png index fb92925b5e3..c82912ea59f 100644 Binary files a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-3-chromium-linux.png and b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-3-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-4-chromium-linux.png b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-4-chromium-linux.png index ebe54fd9660..90b8efa764e 100644 Binary files a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-4-chromium-linux.png and b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-4-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-5-chromium-linux.png b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-5-chromium-linux.png index 9a48e369fe8..e16e5ff345c 100644 Binary files a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-5-chromium-linux.png and b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-5-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-6-chromium-linux.png b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-6-chromium-linux.png index 8555e68f86f..cf954a39813 100644 Binary files a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-6-chromium-linux.png and b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-creates-a-transfer-test-transaction-6-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-filters-transactions-by-date-4-chromium-linux.png b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-filters-transactions-by-date-4-chromium-linux.png index b84e109ad7d..3bc25010868 100644 Binary files a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-filters-transactions-by-date-4-chromium-linux.png and b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-filters-transactions-by-date-4-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-filters-transactions-by-date-5-chromium-linux.png b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-filters-transactions-by-date-5-chromium-linux.png index 61dab14eb01..4885ea64abf 100644 Binary files a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-filters-transactions-by-date-5-chromium-linux.png and b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-filters-transactions-by-date-5-chromium-linux.png differ diff --git a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-filters-transactions-by-date-6-chromium-linux.png b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-filters-transactions-by-date-6-chromium-linux.png index 781841d1522..3accde6d973 100644 Binary files a/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-filters-transactions-by-date-6-chromium-linux.png and b/packages/desktop-client/e2e/transactions.test.js-snapshots/Transactions-filters-transactions-by-date-6-chromium-linux.png differ diff --git a/packages/desktop-client/package.json b/packages/desktop-client/package.json index b160ffc21a3..4194efdd612 100644 --- a/packages/desktop-client/package.json +++ b/packages/desktop-client/package.json @@ -1,6 +1,6 @@ { "name": "@actual-app/web", - "version": "24.9.0", + "version": "24.10.0", "license": "MIT", "files": [ "build" diff --git a/packages/desktop-client/playwright.config.js b/packages/desktop-client/playwright.config.js index ad5b4896c57..1d3f481fb5a 100644 --- a/packages/desktop-client/playwright.config.js +++ b/packages/desktop-client/playwright.config.js @@ -65,7 +65,7 @@ expect.extend({ // eslint-disable-next-line import/no-unused-modules, import/no-default-export export default defineConfig({ - timeout: 20000, // 20 seconds + timeout: 30000, // 30 seconds retries: 1, testDir: 'e2e/', reporter: !process.env.CI ? [['html', { open: 'never' }]] : undefined, diff --git a/packages/desktop-client/src/components/BankSyncStatus.tsx b/packages/desktop-client/src/components/BankSyncStatus.tsx index 77ae6457d1f..52130e0c198 100644 --- a/packages/desktop-client/src/components/BankSyncStatus.tsx +++ b/packages/desktop-client/src/components/BankSyncStatus.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { Trans } from 'react-i18next'; import { useSelector } from 'react-redux'; import { useTransition, animated } from 'react-spring'; @@ -15,6 +16,7 @@ export function BankSyncStatus() { (state: State) => state.account.accountsSyncing, ); const accountsSyncingCount = accountsSyncing.length; + const count = accountsSyncingCount; const transitions = useTransition( accountsSyncingCount > 0 ? 'syncing' : null, @@ -58,8 +60,9 @@ export function BankSyncStatus() { iconStyle={{ color: theme.pillTextSelected }} /> - Syncing... {accountsSyncingCount} account - {accountsSyncingCount > 1 && 's'} remaining + + Syncing... {{ count }} accounts remaining + diff --git a/packages/desktop-client/src/components/budget/envelope/CoverMenu.tsx b/packages/desktop-client/src/components/budget/envelope/CoverMenu.tsx index 6a126b389d5..5c810c17cd9 100644 --- a/packages/desktop-client/src/components/budget/envelope/CoverMenu.tsx +++ b/packages/desktop-client/src/components/budget/envelope/CoverMenu.tsx @@ -1,4 +1,5 @@ import React, { useMemo, useState } from 'react'; +import { Trans, useTranslation } from 'react-i18next'; import { type CategoryEntity } from 'loot-core/src/types/models'; @@ -22,6 +23,8 @@ export function CoverMenu({ onSubmit, onClose, }: CoverMenuProps) { + const { t } = useTranslation(); + const { grouped: originalCategoryGroups } = useCategories(); const [fromCategoryId, setFromCategoryId] = useState(null); @@ -44,7 +47,9 @@ export function CoverMenu({ } return ( - Cover from category: + + Cover from category: + {node => ( @@ -56,7 +61,7 @@ export function CoverMenu({ inputProps={{ inputRef: node, onEnter: event => !event.defaultPrevented && submit(), - placeholder: '(none)', + placeholder: t('(none)'), }} showHiddenCategories={false} /> @@ -77,7 +82,7 @@ export function CoverMenu({ }} onPress={submit} > - Transfer + Transfer diff --git a/packages/desktop-client/src/components/budget/envelope/EnvelopeBudgetComponents.tsx b/packages/desktop-client/src/components/budget/envelope/EnvelopeBudgetComponents.tsx index 449c13a4a3c..86f005dc5ba 100644 --- a/packages/desktop-client/src/components/budget/envelope/EnvelopeBudgetComponents.tsx +++ b/packages/desktop-client/src/components/budget/envelope/EnvelopeBudgetComponents.tsx @@ -1,4 +1,5 @@ import React, { type ComponentProps, memo, useRef, useState } from 'react'; +import { useTranslation, Trans } from 'react-i18next'; import { css } from 'glamor'; @@ -74,7 +75,9 @@ export const BudgetTotalsMonth = memo(function BudgetTotalsMonth() { }} > - Budgeted + + Budgeted + - Received + + Received + ); } @@ -191,6 +196,8 @@ export const ExpenseCategoryMonth = memo(function ExpenseCategoryMonth({ onBudgetAction, onShowActivity, }: ExpenseCategoryMonthProps) { + const { t } = useTranslation(); + const budgetMenuTriggerRef = useRef(null); const balanceMenuTriggerRef = useRef(null); const [budgetMenuOpen, setBudgetMenuOpen] = useState(false); @@ -268,7 +275,7 @@ export const ExpenseCategoryMonth = memo(function ExpenseCategoryMonth({ category: category.id, }); showUndoNotification({ - message: `Budget set to last month’s budget.`, + message: t(`Budget set to last month’s budget.`), }); }} onSetMonthsAverage={numberOfMonths => { @@ -284,7 +291,10 @@ export const ExpenseCategoryMonth = memo(function ExpenseCategoryMonth({ category: category.id, }); showUndoNotification({ - message: `Budget set to ${numberOfMonths}-month average.`, + message: t( + 'Budget set to {{numberOfMonths}}-month average.', + { numberOfMonths }, + ), }); }} onApplyBudgetTemplate={() => { @@ -292,7 +302,7 @@ export const ExpenseCategoryMonth = memo(function ExpenseCategoryMonth({ category: category.id, }); showUndoNotification({ - message: `Budget template applied.`, + message: t(`Budget template applied.`), }); }} /> diff --git a/packages/desktop-client/src/components/budget/envelope/HoldMenu.tsx b/packages/desktop-client/src/components/budget/envelope/HoldMenu.tsx index 3bf1a79df80..296d8a7cd99 100644 --- a/packages/desktop-client/src/components/budget/envelope/HoldMenu.tsx +++ b/packages/desktop-client/src/components/budget/envelope/HoldMenu.tsx @@ -4,6 +4,7 @@ import React, { useEffect, type ChangeEvent, } from 'react'; +import { Trans } from 'react-i18next'; import { useSpreadsheet } from 'loot-core/src/client/SpreadsheetProvider'; import { evalArithmetic } from 'loot-core/src/shared/arithmetic'; @@ -47,7 +48,9 @@ export function HoldMenu({ onSubmit, onClose }: HoldMenuProps) { return ( - Hold this amount: + + Hold this amount: + submit(amount)} > - Hold + Hold diff --git a/packages/desktop-client/src/components/budget/envelope/TransferMenu.tsx b/packages/desktop-client/src/components/budget/envelope/TransferMenu.tsx index f304eab3d46..d6bb64b7728 100644 --- a/packages/desktop-client/src/components/budget/envelope/TransferMenu.tsx +++ b/packages/desktop-client/src/components/budget/envelope/TransferMenu.tsx @@ -1,4 +1,5 @@ import React, { useMemo, useState } from 'react'; +import { Trans } from 'react-i18next'; import { evalArithmetic } from 'loot-core/src/shared/arithmetic'; import { integerToCurrency, amountToInteger } from 'loot-core/src/shared/util'; @@ -55,7 +56,9 @@ export function TransferMenu({ return ( - Transfer this amount: + + Transfer this amount: + _onSubmit(amount, toCategoryId)} > - Transfer + Transfer diff --git a/packages/desktop-client/src/components/budget/envelope/budgetsummary/BudgetMonthMenu.tsx b/packages/desktop-client/src/components/budget/envelope/budgetsummary/BudgetMonthMenu.tsx index 3f4c97da904..29723a12302 100644 --- a/packages/desktop-client/src/components/budget/envelope/budgetsummary/BudgetMonthMenu.tsx +++ b/packages/desktop-client/src/components/budget/envelope/budgetsummary/BudgetMonthMenu.tsx @@ -1,4 +1,5 @@ import React, { type ComponentPropsWithoutRef } from 'react'; +import { useTranslation } from 'react-i18next'; import { useFeatureFlag } from '../../../../hooks/useFeatureFlag'; import { Menu } from '../../../common/Menu'; @@ -25,6 +26,8 @@ export function BudgetMonthMenu({ onEndOfMonthCleanup, ...props }: BudgetMonthMenuProps) { + const { t } = useTranslation(); + const isGoalTemplatesEnabled = useFeatureFlag('goalTemplatesEnabled'); return ( {showLogo && ( {url ? ( - <> + Using server: {url} - > + ) : ( - No server configured + + No server configured + )} - Change + Change ); diff --git a/packages/desktop-client/src/components/manager/subscribe/ChangePassword.tsx b/packages/desktop-client/src/components/manager/subscribe/ChangePassword.tsx index 0894061e6a0..a058630b087 100644 --- a/packages/desktop-client/src/components/manager/subscribe/ChangePassword.tsx +++ b/packages/desktop-client/src/components/manager/subscribe/ChangePassword.tsx @@ -1,5 +1,6 @@ // @ts-strict-ignore import React, { useState } from 'react'; +import { Trans, useTranslation } from 'react-i18next'; import { send } from 'loot-core/src/platform/client/fetch'; @@ -13,6 +14,8 @@ import { Title } from './common'; import { ConfirmPasswordForm } from './ConfirmPasswordForm'; export function ChangePassword() { + const { t } = useTranslation(); + const navigate = useNavigate(); const [error, setError] = useState(null); const [msg, setMessage] = useState(null); @@ -37,7 +40,7 @@ export function ChangePassword() { if (error) { setError(error); } else { - setMessage('Password successfully changed'); + setMessage(t('Password successfully changed')); await send('subscribe-sign-in', { password }); navigate('/'); } @@ -45,7 +48,7 @@ export function ChangePassword() { return ( - + - This will change the password for this server instance. All existing - sessions will stay logged in. + + This will change the password for this server instance. All existing + sessions will stay logged in. + {error && ( @@ -90,7 +95,7 @@ export function ChangePassword() { style={{ fontSize: 15, marginRight: 10 }} onPress={() => navigate('/')} > - Cancel + Cancel } onSetPassword={onSetPassword} diff --git a/packages/desktop-client/src/components/manager/subscribe/ConfirmPasswordForm.tsx b/packages/desktop-client/src/components/manager/subscribe/ConfirmPasswordForm.tsx index 97f40aefc1d..ae6c4db017e 100644 --- a/packages/desktop-client/src/components/manager/subscribe/ConfirmPasswordForm.tsx +++ b/packages/desktop-client/src/components/manager/subscribe/ConfirmPasswordForm.tsx @@ -1,11 +1,14 @@ // @ts-strict-ignore import React, { useState } from 'react'; +import { Trans, useTranslation } from 'react-i18next'; import { ButtonWithLoading } from '../../common/Button2'; import { BigInput } from '../../common/Input'; import { View } from '../../common/View'; export function ConfirmPasswordForm({ buttons, onSetPassword, onError }) { + const { t } = useTranslation(); + const [password1, setPassword1] = useState(''); const [password2, setPassword2] = useState(''); const [showPassword, setShowPassword] = useState(false); @@ -40,14 +43,14 @@ export function ConfirmPasswordForm({ buttons, onSetPassword, onError }) { > - Show password + {' '} + Show password {buttons} @@ -73,7 +77,7 @@ export function ConfirmPasswordForm({ buttons, onSetPassword, onError }) { isLoading={loading} onPress={onSubmit} > - OK + OK diff --git a/packages/desktop-client/src/components/manager/subscribe/Error.tsx b/packages/desktop-client/src/components/manager/subscribe/Error.tsx index c1328d43f9a..9168d9fbe02 100644 --- a/packages/desktop-client/src/components/manager/subscribe/Error.tsx +++ b/packages/desktop-client/src/components/manager/subscribe/Error.tsx @@ -1,5 +1,6 @@ // @ts-strict-ignore import React from 'react'; +import { Trans } from 'react-i18next'; import { useLocation } from 'react-router-dom'; import { useNavigate } from '../../../hooks/useNavigate'; @@ -38,7 +39,7 @@ export function Error() { {getErrorMessage(error)} - Try again + Try again ); diff --git a/packages/desktop-client/src/components/manager/subscribe/Login.tsx b/packages/desktop-client/src/components/manager/subscribe/Login.tsx index d81f9a52a85..bbc2c4f99b1 100644 --- a/packages/desktop-client/src/components/manager/subscribe/Login.tsx +++ b/packages/desktop-client/src/components/manager/subscribe/Login.tsx @@ -1,5 +1,6 @@ // @ts-strict-ignore import React, { useState, useEffect } from 'react'; +import { Trans, useTranslation } from 'react-i18next'; import { useDispatch } from 'react-redux'; import { useParams, useSearchParams } from 'react-router-dom'; @@ -18,6 +19,8 @@ import { View } from '../../common/View'; import { useBootstrapped, Title } from './common'; export function Login() { + const { t } = useTranslation(); + const dispatch = useDispatch(); const { method = 'password' } = useParams(); const [searchParams, _setSearchParams] = useSearchParams(); @@ -93,7 +96,7 @@ export function Login() { return ( - + - If you lost your password, you likely still have access to your server - to manually reset it. + + If you lost your password, you likely still have access to your server + to manually reset it. + {error && ( @@ -122,7 +127,7 @@ export function Login() { - Sign in + Sign in )} @@ -153,12 +158,12 @@ export function Login() { style={{ fontSize: 15 }} to={'/login/password?error=' + error} > - Login with Password + Login with Password )} {!error && ( - Checking Header Token Login ...{' '} + Checking Header Token Login ...{' '} )} @@ -176,7 +181,7 @@ export function Login() { style={{ fontSize: 15, color: theme.pageTextLink, marginLeft: 10 }} onPress={onDemo} > - Try Demo → + Try Demo → diff --git a/packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx b/packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx index abd5438d356..a6db405777f 100644 --- a/packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx +++ b/packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx @@ -284,7 +284,12 @@ function BudgetCell({ }; return ( - + {({ type, name, value }) => children?.({ type, @@ -300,6 +305,7 @@ function BudgetCell({ ...makeAmountGrey(value), }} onPress={onOpenCategoryBudgetMenu} + aria-label={`Open budget menu for ${category.name} category`} > @@ -524,7 +530,7 @@ const ExpenseCategory = memo(function ExpenseCategory({ opacity: isHidden ? 0.5 : undefined, ...style, }} - data-testid="row" + data-testid="category-row" innerRef={listItemRef} > - + {({ type, value }) => ( {group.name} @@ -972,7 +984,7 @@ const IncomeGroupHeader = memo(function IncomeGroupHeader({ paddingLeft: 0, }} innerRef={listItemRef} - data-testid={`income-group-header-${group.name}`} + data-testid="category-group-row" > {group.name} @@ -1132,7 +1144,7 @@ const IncomeCategory = memo(function IncomeCategory({ opacity: !!category.hidden ? 0.5 : undefined, ...style, }} - data-testid="row" + data-testid="category-row" innerRef={listItemRef} > )} - + {({ type, value }) => ( @@ -1641,6 +1656,7 @@ export function BudgetTable({ variant="bare" style={{ margin: 10 }} onPress={onOpenBudgetPageMenu} + aria-label="Budget page menu" > { if (prevEnabled) { @@ -1968,12 +1986,14 @@ function MonthSelector({ onPress={() => { onOpenMonthMenu?.(month); }} + data-month={month} > {monthUtils.format(month, 'MMMM ‘yy')} { if (nextEnabled) { diff --git a/packages/desktop-client/src/components/mobile/transactions/TransactionList.jsx b/packages/desktop-client/src/components/mobile/transactions/TransactionList.jsx index 67cdfc68e77..195fa4cb32c 100644 --- a/packages/desktop-client/src/components/mobile/transactions/TransactionList.jsx +++ b/packages/desktop-client/src/components/mobile/transactions/TransactionList.jsx @@ -91,6 +91,7 @@ export function TransactionList({ if (isLoading) { return ( { const expenseGroups = originalCategoryGroups.filter(g => !g.is_income); @@ -77,7 +80,7 @@ export function CoverModal({ rightContent={} /> - + @@ -100,7 +103,7 @@ export function CoverModal({ close(); }} > - Transfer + Transfer > diff --git a/packages/desktop-client/src/components/modals/EnvelopeBudgetMenuModal.tsx b/packages/desktop-client/src/components/modals/EnvelopeBudgetMenuModal.tsx index f450a6f6bd0..44e9de784fe 100644 --- a/packages/desktop-client/src/components/modals/EnvelopeBudgetMenuModal.tsx +++ b/packages/desktop-client/src/components/modals/EnvelopeBudgetMenuModal.tsx @@ -99,6 +99,7 @@ export function EnvelopeBudgetMenuModal({ }} textStyle={{ ...styles.veryLargeText, textAlign: 'center' }} onUpdateAmount={_onUpdateBudget} + data-testid="budget-amount" /> + + + {children} + + + ); +} diff --git a/packages/desktop-client/src/components/modals/ImportTransactionsModal/DateFormatSelect.jsx b/packages/desktop-client/src/components/modals/ImportTransactionsModal/DateFormatSelect.jsx new file mode 100644 index 00000000000..c911ea36c66 --- /dev/null +++ b/packages/desktop-client/src/components/modals/ImportTransactionsModal/DateFormatSelect.jsx @@ -0,0 +1,39 @@ +import React from 'react'; + +import { Select } from '../../common/Select'; +import { View } from '../../common/View'; +import { SectionLabel } from '../../forms'; + +import { dateFormats } from './utils'; + +export function DateFormatSelect({ + transactions, + fieldMappings, + parseDateFormat, + onChange, +}) { + // We don't actually care about the delimiter, but we try to render + // it based on the data we have so far. Look in a transaction and + // try to figure out what delimiter the date is using, and default + // to space if we can't figure it out. + let delimiter = '-'; + if (transactions.length > 0 && fieldMappings && fieldMappings.date != null) { + const date = transactions[0][fieldMappings.date]; + const m = date && date.match(/[/.,-/\\]/); + delimiter = m ? m[0] : ' '; + } + + return ( + + + [ + f.format, + f.label.replace(/ /g, delimiter), + ])} + value={parseDateFormat || ''} + onChange={onChange} + /> + + ); +} diff --git a/packages/desktop-client/src/components/modals/ImportTransactionsModal/FieldMappings.jsx b/packages/desktop-client/src/components/modals/ImportTransactionsModal/FieldMappings.jsx new file mode 100644 index 00000000000..b4de3f32617 --- /dev/null +++ b/packages/desktop-client/src/components/modals/ImportTransactionsModal/FieldMappings.jsx @@ -0,0 +1,132 @@ +import React from 'react'; + +import { Stack } from '../../common/Stack'; +import { View } from '../../common/View'; +import { SectionLabel } from '../../forms'; + +import { SelectField } from './SelectField'; +import { SubLabel } from './SubLabel'; + +export function FieldMappings({ + transactions, + mappings, + onChange, + splitMode, + inOutMode, + hasHeaderRow, +}) { + if (transactions.length === 0) { + return null; + } + + const { existing, ignored, selected, selected_merge, trx_id, ...trans } = + transactions[0]; + const options = Object.keys(trans); + mappings = mappings || {}; + + return ( + + + + + + onChange('date', name)} + hasHeaderRow={hasHeaderRow} + firstTransaction={transactions[0]} + /> + + + + onChange('payee', name)} + hasHeaderRow={hasHeaderRow} + firstTransaction={transactions[0]} + /> + + + + onChange('notes', name)} + hasHeaderRow={hasHeaderRow} + firstTransaction={transactions[0]} + /> + + + + onChange('category', name)} + hasHeaderRow={hasHeaderRow} + firstTransaction={transactions[0]} + /> + + {splitMode ? ( + <> + + + onChange('outflow', name)} + hasHeaderRow={hasHeaderRow} + firstTransaction={transactions[0]} + /> + + + + onChange('inflow', name)} + hasHeaderRow={hasHeaderRow} + firstTransaction={transactions[0]} + /> + + > + ) : ( + <> + {inOutMode && ( + + + onChange('inOut', name)} + hasHeaderRow={hasHeaderRow} + firstTransaction={transactions[0]} + /> + + )} + + + onChange('amount', name)} + hasHeaderRow={hasHeaderRow} + firstTransaction={transactions[0]} + /> + + > + )} + + + ); +} diff --git a/packages/desktop-client/src/components/modals/ImportTransactionsModal.jsx b/packages/desktop-client/src/components/modals/ImportTransactionsModal/ImportTransactionsModal.jsx similarity index 59% rename from packages/desktop-client/src/components/modals/ImportTransactionsModal.jsx rename to packages/desktop-client/src/components/modals/ImportTransactionsModal/ImportTransactionsModal.jsx index 4a74a10b70f..903957ed4e8 100644 --- a/packages/desktop-client/src/components/modals/ImportTransactionsModal.jsx +++ b/packages/desktop-client/src/components/modals/ImportTransactionsModal/ImportTransactionsModal.jsx @@ -1,132 +1,35 @@ -import React, { useState, useEffect, useMemo, useCallback } from 'react'; +import React, { useState, useEffect, useCallback } from 'react'; -import * as d from 'date-fns'; import deepEqual from 'deep-equal'; -import { format as formatDate_ } from 'loot-core/src/shared/months'; +import { amountToInteger } from 'loot-core/src/shared/util'; + +import { useActions } from '../../../hooks/useActions'; +import { useDateFormat } from '../../../hooks/useDateFormat'; +import { useSyncedPrefs } from '../../../hooks/useSyncedPrefs'; +import { theme } from '../../../style'; +import { Button, ButtonWithLoading } from '../../common/Button2'; +import { Input } from '../../common/Input'; +import { Modal, ModalCloseButton, ModalHeader } from '../../common/Modal'; +import { Select } from '../../common/Select'; +import { Stack } from '../../common/Stack'; +import { Text } from '../../common/Text'; +import { View } from '../../common/View'; +import { SectionLabel } from '../../forms'; +import { TableHeader, TableWithNavigator } from '../../table'; + +import { CheckboxOption } from './CheckboxOption'; +import { DateFormatSelect } from './DateFormatSelect'; +import { FieldMappings } from './FieldMappings'; +import { InOutOption } from './InOutOption'; +import { MultiplierOption } from './MultiplierOption'; +import { Transaction } from './Transaction'; import { - amountToCurrency, - amountToInteger, - looselyParseAmount, -} from 'loot-core/src/shared/util'; - -import { useActions } from '../../hooks/useActions'; -import { useDateFormat } from '../../hooks/useDateFormat'; -import { useSyncedPrefs } from '../../hooks/useSyncedPrefs'; -import { SvgDownAndRightArrow } from '../../icons/v2'; -import { theme, styles } from '../../style'; -import { Button, ButtonWithLoading } from '../common/Button2'; -import { Input } from '../common/Input'; -import { Modal, ModalCloseButton, ModalHeader } from '../common/Modal'; -import { Select } from '../common/Select'; -import { Stack } from '../common/Stack'; -import { Text } from '../common/Text'; -import { Tooltip } from '../common/Tooltip'; -import { View } from '../common/View'; -import { Checkbox, SectionLabel } from '../forms'; -import { TableHeader, TableWithNavigator, Row, Field } from '../table'; - -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' }, - { format: 'mm dd yy', label: 'MM DD YY' }, - { format: 'dd mm yyyy', label: 'DD MM YYYY' }, - { format: 'dd mm yy', label: 'DD MM YY' }, -]; - -export function parseDate(str, order) { - if (typeof str !== 'string') { - return null; - } - - function pad(v) { - return v && v.length === 1 ? '0' + v : v; - } - - const dateGroups = (a, b) => str => { - const parts = str - .replace(/\bjan(\.|uary)?\b/i, '01') - .replace(/\bfeb(\.|ruary)?\b/i, '02') - .replace(/\bmar(\.|ch)?\b/i, '03') - .replace(/\bapr(\.|il)?\b/i, '04') - .replace(/\bmay\.?\b/i, '05') - .replace(/\bjun(\.|e)?\b/i, '06') - .replace(/\bjul(\.|y)?\b/i, '07') - .replace(/\baug(\.|ust)?\b/i, '08') - .replace(/\bsep(\.|tember)?\b/i, '09') - .replace(/\boct(\.|ober)?\b/i, '10') - .replace(/\bnov(\.|ember)?\b/i, '11') - .replace(/\bdec(\.|ember)?\b/i, '12') - .replace(/^[^\d]+/, '') - .replace(/[^\d]+$/, '') - .split(/[^\d]+/); - if (parts.length >= 3) { - return parts.slice(0, 3); - } - - const digits = str.replace(/[^\d]/g, ''); - return [digits.slice(0, a), digits.slice(a, a + b), digits.slice(a + b)]; - }; - const yearFirst = dateGroups(4, 2); - const twoDig = dateGroups(2, 2); - - let parts, year, month, day; - switch (order) { - case 'dd mm yyyy': - parts = twoDig(str); - year = parts[2]; - month = parts[1]; - day = parts[0]; - break; - case 'dd mm yy': - parts = twoDig(str); - year = `20${parts[2]}`; - month = parts[1]; - day = parts[0]; - break; - case 'yyyy mm dd': - parts = yearFirst(str); - year = parts[0]; - month = parts[1]; - day = parts[2]; - break; - case 'yy mm dd': - parts = twoDig(str); - year = `20${parts[0]}`; - month = parts[1]; - day = parts[2]; - break; - case 'mm dd yy': - parts = twoDig(str); - year = `20${parts[2]}`; - month = parts[0]; - day = parts[1]; - break; - default: - case 'mm dd yyyy': - parts = twoDig(str); - year = parts[2]; - month = parts[0]; - day = parts[1]; - } - - const parsed = `${year}-${pad(month)}-${pad(day)}`; - if (!d.isValid(d.parseISO(parsed))) { - return null; - } - return parsed; -} - -function formatDate(date, format) { - if (!date) { - return null; - } - try { - return formatDate_(date, format); - } catch (e) {} - return null; -} + applyFieldMappings, + dateFormats, + parseAmountFields, + parseDate, +} from './utils'; function getFileType(filepath) { const m = filepath.match(/\.([^.]*)$/); @@ -136,30 +39,6 @@ function getFileType(filepath) { return rawType; } -function ParsedDate({ parseDateFormat, dateFormat, date }) { - const parsed = - date && - formatDate( - parseDateFormat ? parseDate(date, parseDateFormat) : date, - dateFormat, - ); - return ( - - - {date || ( - - Empty - - )}{' '} - →{' '} - - - {parsed || 'Invalid'} - - - ); -} - function getInitialDateFormat(transactions, mappings) { if (transactions.length === 0 || mappings.date == null) { return 'yyyy mm dd'; @@ -240,87 +119,6 @@ function getInitialMappings(transactions) { }; } -function applyFieldMappings(transaction, mappings) { - const result = {}; - for (const [originalField, target] of Object.entries(mappings)) { - let field = originalField; - if (field === 'payee') { - field = 'payee_name'; - } - - result[field] = transaction[target || field]; - } - // Keep preview fields on the mapped transactions - result.trx_id = transaction.trx_id; - result.existing = transaction.existing; - result.ignored = transaction.ignored; - result.selected = transaction.selected; - result.selected_merge = transaction.selected_merge; - return result; -} - -function parseAmount(amount, mapper, multiplier) { - if (amount == null) { - return null; - } - - const parsed = - typeof amount === 'string' ? looselyParseAmount(amount) : amount; - - if (parsed === null) { - return null; - } - - return mapper(parsed) * multiplier; -} - -function parseAmountFields( - trans, - splitMode, - inOutMode, - outValue, - flipAmount, - multiplierAmount, -) { - const multiplier = parseFloat(multiplierAmount) || 1.0; - - if (splitMode) { - // 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 - const outflow = parseAmount(trans.outflow, n => -Math.abs(n), multiplier); - const inflow = outflow - ? 0 - : parseAmount(trans.inflow, n => Math.abs(n), multiplier); - - return { - amount: outflow || inflow, - outflow, - inflow, - }; - } - if (inOutMode) { - return { - amount: parseAmount( - trans.amount, - n => (trans.inOut === outValue ? Math.abs(n) * -1 : Math.abs(n)), - multiplier, - ), - outflow: null, - inflow: null, - }; - } - return { - amount: parseAmount( - trans.amount, - n => (flipAmount ? n * -1 : n), - multiplier, - ), - outflow: null, - inflow: null, - }; -} - function parseCategoryFields(trans, categories) { let match = null; categories.forEach(category => { @@ -334,511 +132,6 @@ function parseCategoryFields(trans, categories) { return match; } -function Transaction({ - transaction: rawTransaction, - fieldMappings, - showParsed, - parseDateFormat, - dateFormat, - splitMode, - inOutMode, - outValue, - flipAmount, - multiplierAmount, - categories, - onCheckTransaction, - reconcile, -}) { - const categoryList = categories.map(category => category.name); - const transaction = useMemo( - () => - fieldMappings && !rawTransaction.isMatchedTransaction - ? applyFieldMappings(rawTransaction, fieldMappings) - : rawTransaction, - [rawTransaction, fieldMappings], - ); - - let amount, outflow, inflow; - if (rawTransaction.isMatchedTransaction) { - amount = rawTransaction.amount; - if (splitMode) { - outflow = amount < 0 ? -amount : 0; - inflow = amount > 0 ? amount : 0; - } - } else { - ({ amount, outflow, inflow } = parseAmountFields( - transaction, - splitMode, - inOutMode, - outValue, - flipAmount, - multiplierAmount, - )); - } - - return ( - - {reconcile && ( - - {!transaction.isMatchedTransaction && ( - - onCheckTransaction(transaction.trx_id)} - style={ - transaction.selected_merge - ? { - ':checked': { - '::after': { - background: - theme.checkboxBackgroundSelected + - // update sign from packages/desktop-client/src/icons/v1/layer.svg - // eslint-disable-next-line rulesdir/typography - ' url(\'data:image/svg+xml; utf8,\') 9px 9px', - }, - }, - } - : { - '&': { - border: - '1px solid ' + theme.buttonNormalDisabledBorder, - backgroundColor: theme.buttonNormalDisabledBorder, - '::after': { - display: 'block', - background: - theme.buttonNormalDisabledBorder + - // minus sign adapted from packages/desktop-client/src/icons/v1/add.svg - // eslint-disable-next-line rulesdir/typography - ' url(\'data:image/svg+xml; utf8,\') 9px 9px', - width: 9, - height: 9, - content: ' ', - }, - }, - ':checked': { - border: '1px solid ' + theme.checkboxBorderSelected, - backgroundColor: theme.checkboxBackgroundSelected, - '::after': { - background: - theme.checkboxBackgroundSelected + - // plus sign from packages/desktop-client/src/icons/v1/add.svg - // eslint-disable-next-line rulesdir/typography - ' url(\'data:image/svg+xml; utf8,\') 9px 9px', - }, - }, - } - } - /> - - )} - - )} - - {transaction.isMatchedTransaction ? ( - - - - - - {formatDate(transaction.date, dateFormat)} - - - ) : showParsed ? ( - - ) : ( - formatDate(transaction.date, dateFormat) - )} - - - {transaction.payee_name} - - - {transaction.notes} - - - {categoryList.includes(transaction.category) && transaction.category} - - {splitMode ? ( - <> - - {amountToCurrency(outflow)} - - - {amountToCurrency(inflow)} - - > - ) : ( - <> - {inOutMode && ( - - {transaction.inOut} - - )} - - {amountToCurrency(amount)} - - > - )} - - ); -} - -function SubLabel({ title }) { - return ( - - {title} - - ); -} - -function SelectField({ - style, - options, - value, - onChange, - hasHeaderRow, - firstTransaction, -}) { - return ( - [ - option, - hasHeaderRow - ? option - : `Column ${parseInt(option) + 1} (${firstTransaction[option]})`, - ]), - ]} - value={value === null ? 'choose-field' : value} - onChange={onChange} - style={style} - /> - ); -} - -function DateFormatSelect({ - transactions, - fieldMappings, - parseDateFormat, - onChange, -}) { - // We don't actually care about the delimiter, but we try to render - // it based on the data we have so far. Look in a transaction and - // try to figure out what delimiter the date is using, and default - // to space if we can't figure it out. - let delimiter = '-'; - if (transactions.length > 0 && fieldMappings && fieldMappings.date != null) { - const date = transactions[0][fieldMappings.date]; - const m = date && date.match(/[/.,-/\\]/); - delimiter = m ? m[0] : ' '; - } - - return ( - - - [ - f.format, - f.label.replace(/ /g, delimiter), - ])} - value={parseDateFormat || ''} - onChange={onChange} - /> - - ); -} - -function CheckboxOption({ id, checked, disabled, onChange, children, style }) { - return ( - - - - {children} - - - ); -} - -function MultiplierOption({ - multiplierEnabled, - multiplierAmount, - onToggle, - onChangeAmount, -}) { - return ( - - - Add multiplier - - - - ); -} - -function InOutOption({ - inOutMode, - outValue, - disabled, - onToggle, - onChangeText, -}) { - return ( - - - {inOutMode - ? 'in/out identifier' - : 'Select column to specify if amount goes in/out'} - - {inOutMode && ( - - )} - - ); -} - -function FieldMappings({ - transactions, - mappings, - onChange, - splitMode, - inOutMode, - hasHeaderRow, -}) { - if (transactions.length === 0) { - return null; - } - - const { existing, ignored, selected, selected_merge, trx_id, ...trans } = - transactions[0]; - const options = Object.keys(trans); - mappings = mappings || {}; - - return ( - - - - - - onChange('date', name)} - hasHeaderRow={hasHeaderRow} - firstTransaction={transactions[0]} - /> - - - - onChange('payee', name)} - hasHeaderRow={hasHeaderRow} - firstTransaction={transactions[0]} - /> - - - - onChange('notes', name)} - hasHeaderRow={hasHeaderRow} - firstTransaction={transactions[0]} - /> - - - - onChange('category', name)} - hasHeaderRow={hasHeaderRow} - firstTransaction={transactions[0]} - /> - - {splitMode ? ( - <> - - - onChange('outflow', name)} - hasHeaderRow={hasHeaderRow} - firstTransaction={transactions[0]} - /> - - - - onChange('inflow', name)} - hasHeaderRow={hasHeaderRow} - firstTransaction={transactions[0]} - /> - - > - ) : ( - <> - {inOutMode && ( - - - onChange('inOut', name)} - hasHeaderRow={hasHeaderRow} - firstTransaction={transactions[0]} - /> - - )} - - - onChange('amount', name)} - hasHeaderRow={hasHeaderRow} - firstTransaction={transactions[0]} - /> - - > - )} - - - ); -} - export function ImportTransactionsModal({ options }) { const dateFormat = useDateFormat() || 'MM/dd/yyyy'; const [prefs, savePrefs] = useSyncedPrefs(); diff --git a/packages/desktop-client/src/components/modals/ImportTransactionsModal/InOutOption.jsx b/packages/desktop-client/src/components/modals/ImportTransactionsModal/InOutOption.jsx new file mode 100644 index 00000000000..5bd36a8f42e --- /dev/null +++ b/packages/desktop-client/src/components/modals/ImportTransactionsModal/InOutOption.jsx @@ -0,0 +1,37 @@ +import React from 'react'; + +import { Input } from '../../common/Input'; +import { View } from '../../common/View'; + +import { CheckboxOption } from './CheckboxOption'; + +export function InOutOption({ + inOutMode, + outValue, + disabled, + onToggle, + onChangeText, +}) { + return ( + + + {inOutMode + ? 'in/out identifier' + : 'Select column to specify if amount goes in/out'} + + {inOutMode && ( + + )} + + ); +} diff --git a/packages/desktop-client/src/components/modals/ImportTransactionsModal/MultiplierOption.jsx b/packages/desktop-client/src/components/modals/ImportTransactionsModal/MultiplierOption.jsx new file mode 100644 index 00000000000..f5d922cf513 --- /dev/null +++ b/packages/desktop-client/src/components/modals/ImportTransactionsModal/MultiplierOption.jsx @@ -0,0 +1,32 @@ +import React from 'react'; + +import { Input } from '../../common/Input'; +import { View } from '../../common/View'; + +import { CheckboxOption } from './CheckboxOption'; + +export function MultiplierOption({ + multiplierEnabled, + multiplierAmount, + onToggle, + onChangeAmount, +}) { + return ( + + + Add multiplier + + + + ); +} diff --git a/packages/desktop-client/src/components/modals/ImportTransactionsModal/ParsedDate.jsx b/packages/desktop-client/src/components/modals/ImportTransactionsModal/ParsedDate.jsx new file mode 100644 index 00000000000..9abf5e340c0 --- /dev/null +++ b/packages/desktop-client/src/components/modals/ImportTransactionsModal/ParsedDate.jsx @@ -0,0 +1,30 @@ +import React from 'react'; + +import { theme } from '../../../style'; +import { Text } from '../../common/Text'; + +import { formatDate, parseDate } from './utils'; + +export function ParsedDate({ parseDateFormat, dateFormat, date }) { + const parsed = + date && + formatDate( + parseDateFormat ? parseDate(date, parseDateFormat) : date, + dateFormat, + ); + return ( + + + {date || ( + + Empty + + )}{' '} + →{' '} + + + {parsed || 'Invalid'} + + + ); +} diff --git a/packages/desktop-client/src/components/modals/ImportTransactionsModal/SelectField.jsx b/packages/desktop-client/src/components/modals/ImportTransactionsModal/SelectField.jsx new file mode 100644 index 00000000000..0626b8e6393 --- /dev/null +++ b/packages/desktop-client/src/components/modals/ImportTransactionsModal/SelectField.jsx @@ -0,0 +1,29 @@ +import React from 'react'; + +import { Select } from '../../common/Select'; + +export function SelectField({ + style, + options, + value, + onChange, + hasHeaderRow, + firstTransaction, +}) { + return ( + [ + option, + hasHeaderRow + ? option + : `Column ${parseInt(option) + 1} (${firstTransaction[option]})`, + ]), + ]} + value={value === null ? 'choose-field' : value} + onChange={onChange} + style={style} + /> + ); +} diff --git a/packages/desktop-client/src/components/modals/ImportTransactionsModal/SubLabel.jsx b/packages/desktop-client/src/components/modals/ImportTransactionsModal/SubLabel.jsx new file mode 100644 index 00000000000..0d1d64de243 --- /dev/null +++ b/packages/desktop-client/src/components/modals/ImportTransactionsModal/SubLabel.jsx @@ -0,0 +1,12 @@ +import React from 'react'; + +import { theme } from '../../../style'; +import { Text } from '../../common/Text'; + +export function SubLabel({ title }) { + return ( + + {title} + + ); +} diff --git a/packages/desktop-client/src/components/modals/ImportTransactionsModal/Transaction.jsx b/packages/desktop-client/src/components/modals/ImportTransactionsModal/Transaction.jsx new file mode 100644 index 00000000000..0a861eb02ad --- /dev/null +++ b/packages/desktop-client/src/components/modals/ImportTransactionsModal/Transaction.jsx @@ -0,0 +1,241 @@ +import React, { useMemo } from 'react'; + +import { amountToCurrency } from 'loot-core/src/shared/util'; + +import { SvgDownAndRightArrow } from '../../../icons/v2'; +import { theme, styles } from '../../../style'; +import { Stack } from '../../common/Stack'; +import { Tooltip } from '../../common/Tooltip'; +import { View } from '../../common/View'; +import { Checkbox } from '../../forms'; +import { Row, Field } from '../../table'; + +import { ParsedDate } from './ParsedDate'; +import { applyFieldMappings, formatDate, parseAmountFields } from './utils'; + +export function Transaction({ + transaction: rawTransaction, + fieldMappings, + showParsed, + parseDateFormat, + dateFormat, + splitMode, + inOutMode, + outValue, + flipAmount, + multiplierAmount, + categories, + onCheckTransaction, + reconcile, +}) { + const categoryList = categories.map(category => category.name); + const transaction = useMemo( + () => + fieldMappings && !rawTransaction.isMatchedTransaction + ? applyFieldMappings(rawTransaction, fieldMappings) + : rawTransaction, + [rawTransaction, fieldMappings], + ); + + let amount, outflow, inflow; + if (rawTransaction.isMatchedTransaction) { + amount = rawTransaction.amount; + if (splitMode) { + outflow = amount < 0 ? -amount : 0; + inflow = amount > 0 ? amount : 0; + } + } else { + ({ amount, outflow, inflow } = parseAmountFields( + transaction, + splitMode, + inOutMode, + outValue, + flipAmount, + multiplierAmount, + )); + } + + return ( + + {reconcile && ( + + {!transaction.isMatchedTransaction && ( + + onCheckTransaction(transaction.trx_id)} + style={ + transaction.selected_merge + ? { + ':checked': { + '::after': { + background: + theme.checkboxBackgroundSelected + + // update sign from packages/desktop-client/src/icons/v1/layer.svg + // eslint-disable-next-line rulesdir/typography + ' url(\'data:image/svg+xml; utf8,\') 9px 9px', + }, + }, + } + : { + '&': { + border: + '1px solid ' + theme.buttonNormalDisabledBorder, + backgroundColor: theme.buttonNormalDisabledBorder, + '::after': { + display: 'block', + background: + theme.buttonNormalDisabledBorder + + // minus sign adapted from packages/desktop-client/src/icons/v1/add.svg + // eslint-disable-next-line rulesdir/typography + ' url(\'data:image/svg+xml; utf8,\') 9px 9px', + width: 9, + height: 9, + content: ' ', + }, + }, + ':checked': { + border: '1px solid ' + theme.checkboxBorderSelected, + backgroundColor: theme.checkboxBackgroundSelected, + '::after': { + background: + theme.checkboxBackgroundSelected + + // plus sign from packages/desktop-client/src/icons/v1/add.svg + // eslint-disable-next-line rulesdir/typography + ' url(\'data:image/svg+xml; utf8,\') 9px 9px', + }, + }, + } + } + /> + + )} + + )} + + {transaction.isMatchedTransaction ? ( + + + + + + {formatDate(transaction.date, dateFormat)} + + + ) : showParsed ? ( + + ) : ( + formatDate(transaction.date, dateFormat) + )} + + + {transaction.payee_name} + + + {transaction.notes} + + + {categoryList.includes(transaction.category) && transaction.category} + + {splitMode ? ( + <> + + {amountToCurrency(outflow)} + + + {amountToCurrency(inflow)} + + > + ) : ( + <> + {inOutMode && ( + + {transaction.inOut} + + )} + + {amountToCurrency(amount)} + + > + )} + + ); +} diff --git a/packages/desktop-client/src/components/modals/ImportTransactionsModal/index.ts b/packages/desktop-client/src/components/modals/ImportTransactionsModal/index.ts new file mode 100644 index 00000000000..5bb6235f451 --- /dev/null +++ b/packages/desktop-client/src/components/modals/ImportTransactionsModal/index.ts @@ -0,0 +1 @@ +export { ImportTransactionsModal } from './ImportTransactionsModal'; diff --git a/packages/desktop-client/src/components/modals/ImportTransactionsModal/utils.js b/packages/desktop-client/src/components/modals/ImportTransactionsModal/utils.js new file mode 100644 index 00000000000..094f862e5b2 --- /dev/null +++ b/packages/desktop-client/src/components/modals/ImportTransactionsModal/utils.js @@ -0,0 +1,187 @@ +import * as d from 'date-fns'; + +import { format as formatDate_ } from 'loot-core/src/shared/months'; +import { looselyParseAmount } from 'loot-core/src/shared/util'; + +export 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' }, + { format: 'mm dd yy', label: 'MM DD YY' }, + { format: 'dd mm yyyy', label: 'DD MM YYYY' }, + { format: 'dd mm yy', label: 'DD MM YY' }, +]; + +export function parseDate(str, order) { + if (typeof str !== 'string') { + return null; + } + + function pad(v) { + return v && v.length === 1 ? '0' + v : v; + } + + const dateGroups = (a, b) => str => { + const parts = str + .replace(/\bjan(\.|uary)?\b/i, '01') + .replace(/\bfeb(\.|ruary)?\b/i, '02') + .replace(/\bmar(\.|ch)?\b/i, '03') + .replace(/\bapr(\.|il)?\b/i, '04') + .replace(/\bmay\.?\b/i, '05') + .replace(/\bjun(\.|e)?\b/i, '06') + .replace(/\bjul(\.|y)?\b/i, '07') + .replace(/\baug(\.|ust)?\b/i, '08') + .replace(/\bsep(\.|tember)?\b/i, '09') + .replace(/\boct(\.|ober)?\b/i, '10') + .replace(/\bnov(\.|ember)?\b/i, '11') + .replace(/\bdec(\.|ember)?\b/i, '12') + .replace(/^[^\d]+/, '') + .replace(/[^\d]+$/, '') + .split(/[^\d]+/); + if (parts.length >= 3) { + return parts.slice(0, 3); + } + + const digits = str.replace(/[^\d]/g, ''); + return [digits.slice(0, a), digits.slice(a, a + b), digits.slice(a + b)]; + }; + const yearFirst = dateGroups(4, 2); + const twoDig = dateGroups(2, 2); + + let parts, year, month, day; + switch (order) { + case 'dd mm yyyy': + parts = twoDig(str); + year = parts[2]; + month = parts[1]; + day = parts[0]; + break; + case 'dd mm yy': + parts = twoDig(str); + year = `20${parts[2]}`; + month = parts[1]; + day = parts[0]; + break; + case 'yyyy mm dd': + parts = yearFirst(str); + year = parts[0]; + month = parts[1]; + day = parts[2]; + break; + case 'yy mm dd': + parts = twoDig(str); + year = `20${parts[0]}`; + month = parts[1]; + day = parts[2]; + break; + case 'mm dd yy': + parts = twoDig(str); + year = `20${parts[2]}`; + month = parts[0]; + day = parts[1]; + break; + default: + case 'mm dd yyyy': + parts = twoDig(str); + year = parts[2]; + month = parts[0]; + day = parts[1]; + } + + const parsed = `${year}-${pad(month)}-${pad(day)}`; + if (!d.isValid(d.parseISO(parsed))) { + return null; + } + return parsed; +} + +export function formatDate(date, format) { + if (!date) { + return null; + } + try { + return formatDate_(date, format); + } catch (e) {} + return null; +} + +export function applyFieldMappings(transaction, mappings) { + const result = {}; + for (const [originalField, target] of Object.entries(mappings)) { + let field = originalField; + if (field === 'payee') { + field = 'payee_name'; + } + + result[field] = transaction[target || field]; + } + // Keep preview fields on the mapped transactions + result.trx_id = transaction.trx_id; + result.existing = transaction.existing; + result.ignored = transaction.ignored; + result.selected = transaction.selected; + result.selected_merge = transaction.selected_merge; + return result; +} + +function parseAmount(amount, mapper, multiplier) { + if (amount == null) { + return null; + } + + const parsed = + typeof amount === 'string' ? looselyParseAmount(amount) : amount; + + if (parsed === null) { + return null; + } + + return mapper(parsed) * multiplier; +} + +export function parseAmountFields( + trans, + splitMode, + inOutMode, + outValue, + flipAmount, + multiplierAmount, +) { + const multiplier = parseFloat(multiplierAmount) || 1.0; + + if (splitMode) { + // 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 + const outflow = parseAmount(trans.outflow, n => -Math.abs(n), multiplier); + const inflow = outflow + ? 0 + : parseAmount(trans.inflow, n => Math.abs(n), multiplier); + + return { + amount: outflow || inflow, + outflow, + inflow, + }; + } + if (inOutMode) { + return { + amount: parseAmount( + trans.amount, + n => (trans.inOut === outValue ? Math.abs(n) * -1 : Math.abs(n)), + multiplier, + ), + outflow: null, + inflow: null, + }; + } + return { + amount: parseAmount( + trans.amount, + n => (flipAmount ? n * -1 : n), + multiplier, + ), + outflow: null, + inflow: null, + }; +} diff --git a/packages/desktop-client/src/components/modals/ImportTransactionsModal.test.js b/packages/desktop-client/src/components/modals/ImportTransactionsModal/utils.test.js similarity index 98% rename from packages/desktop-client/src/components/modals/ImportTransactionsModal.test.js rename to packages/desktop-client/src/components/modals/ImportTransactionsModal/utils.test.js index 742868e29b6..f4bfa6841cb 100644 --- a/packages/desktop-client/src/components/modals/ImportTransactionsModal.test.js +++ b/packages/desktop-client/src/components/modals/ImportTransactionsModal/utils.test.js @@ -1,4 +1,4 @@ -import { parseDate } from './ImportTransactionsModal'; +import { parseDate } from './utils'; describe('Import transactions', function () { describe('date parsing', function () { diff --git a/packages/desktop-client/src/components/modals/TrackingBudgetMenuModal.tsx b/packages/desktop-client/src/components/modals/TrackingBudgetMenuModal.tsx index 3f899c9ed21..47b6e4796fc 100644 --- a/packages/desktop-client/src/components/modals/TrackingBudgetMenuModal.tsx +++ b/packages/desktop-client/src/components/modals/TrackingBudgetMenuModal.tsx @@ -99,6 +99,7 @@ export function TrackingBudgetMenuModal({ }} textStyle={{ ...styles.veryLargeText, textAlign: 'center' }} onUpdateAmount={_onUpdateBudget} + data-testid="budget-amount" /> { const expenseGroups = originalCategoryGroups.filter(g => !g.is_income); @@ -85,7 +88,7 @@ export function TransferModal({ /> - + - Transfer + Transfer diff --git a/packages/desktop-client/src/components/modals/manager/DeleteFileModal.tsx b/packages/desktop-client/src/components/modals/manager/DeleteFileModal.tsx index 98e6efdb162..3b93804fb86 100644 --- a/packages/desktop-client/src/components/modals/manager/DeleteFileModal.tsx +++ b/packages/desktop-client/src/components/modals/manager/DeleteFileModal.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react'; +import { Trans, useTranslation } from 'react-i18next'; import { useDispatch } from 'react-redux'; import { deleteBudget } from 'loot-core/client/actions'; @@ -15,6 +16,8 @@ type DeleteFileProps = { }; export function DeleteFileModal({ file }: DeleteFileProps) { + const { t } = useTranslation(); + // 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 @@ -30,7 +33,7 @@ export function DeleteFileModal({ file }: DeleteFileProps) { {({ state: { close } }) => ( <> } /> - This is a hosted file which means it is - stored on your server to make it available for download on any - device. You can delete it from the server, which will also - remove it from all of your devices. + + This is a hosted file which means it is + stored on your server to make it available for download on + any device. You can delete it from the server, which will + also remove it from all of your devices. + - Delete file from all devices + Delete file from all devices > )} @@ -84,26 +89,30 @@ export function DeleteFileModal({ file }: DeleteFileProps) { <> {isCloudFile ? ( - You can also delete just the local copy. This will remove - all local data and the file will be listed as available for - download. + + You can also delete just the local copy. This will remove + all local data and the file will be listed as available + for download. + ) : ( {file.state === 'broken' ? ( - <> + This is a hosted file but it was created by another user. You can only delete the local copy. - > + ) : ( - <> + This a local file which is not stored on a server. - > + )}{' '} - Deleting it will remove it and all of its backups - permanently. + + Deleting it will remove it and all of its backups + permanently. + )} @@ -133,7 +142,7 @@ export function DeleteFileModal({ file }: DeleteFileProps) { close(); }} > - Delete file locally + Delete file locally > )} diff --git a/packages/desktop-client/src/components/modals/manager/ImportActualModal.tsx b/packages/desktop-client/src/components/modals/manager/ImportActualModal.tsx index 659792e7afc..d1041250caf 100644 --- a/packages/desktop-client/src/components/modals/manager/ImportActualModal.tsx +++ b/packages/desktop-client/src/components/modals/manager/ImportActualModal.tsx @@ -1,5 +1,6 @@ // @ts-strict-ignore import React, { useState } from 'react'; +import { Trans, useTranslation } from 'react-i18next'; import { useDispatch } from 'react-redux'; import { importBudget } from 'loot-core/src/client/actions/budgets'; @@ -29,6 +30,8 @@ function getErrorMessage(error: string): string { } export function ImportActualModal() { + const { t } = useTranslation(); + const dispatch = useDispatch(); const [error, setError] = useState(null); const [importing, setImporting] = useState(false); @@ -56,7 +59,7 @@ export function ImportActualModal() { {({ state: { close } }) => ( <> } /> @@ -68,15 +71,19 @@ export function ImportActualModal() { div': { lineHeight: '1.7em' } }}> - You can import data from another Actual account or instance. - First export your data from a different account, and it will - give you a compressed file. This file is a simple zip file that - contains the db.sqlite and{' '} - metadata.json files. + + You can import data from another Actual account or instance. + First export your data from a different account, and it will + give you a compressed file. This file is a simple zip file + that contains the db.sqlite and{' '} + metadata.json files. + - Select one of these compressed files and import it here. + + Select one of these compressed files and import it here. + @@ -86,7 +93,7 @@ export function ImportActualModal() { isLoading={importing} onPress={onImport} > - Select file... + Select file... diff --git a/packages/desktop-client/src/components/modals/manager/ImportModal.tsx b/packages/desktop-client/src/components/modals/manager/ImportModal.tsx index c1572539d8c..3ced17d7093 100644 --- a/packages/desktop-client/src/components/modals/manager/ImportModal.tsx +++ b/packages/desktop-client/src/components/modals/manager/ImportModal.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react'; +import { Trans, useTranslation } from 'react-i18next'; import { useDispatch } from 'react-redux'; import { pushModal } from 'loot-core/client/actions'; @@ -20,6 +21,8 @@ function getErrorMessage(error: 'not-ynab4' | boolean) { } export function ImportModal() { + const { t } = useTranslation(); + const dispatch = useDispatch(); const [error] = useState(false); @@ -51,7 +54,7 @@ export function ImportModal() { {({ state: { close } }) => ( <> } /> @@ -69,19 +72,23 @@ export function ImportModal() { onSelectType('ynab4')}> YNAB4 - The old unsupported desktop app + The old unsupported desktop app onSelectType('ynab5')}> nYNAB - The newer web app + + The newer web app + onSelectType('actual')}> Actual - Import a file exported from Actual + + Import a file exported from Actual + diff --git a/packages/desktop-client/src/components/modals/manager/ImportYNAB4Modal.tsx b/packages/desktop-client/src/components/modals/manager/ImportYNAB4Modal.tsx index 361ac5d46c4..3d02baa794a 100644 --- a/packages/desktop-client/src/components/modals/manager/ImportYNAB4Modal.tsx +++ b/packages/desktop-client/src/components/modals/manager/ImportYNAB4Modal.tsx @@ -1,5 +1,6 @@ // @ts-strict-ignore import React, { useState } from 'react'; +import { Trans, useTranslation } from 'react-i18next'; import { useDispatch } from 'react-redux'; import { importBudget } from 'loot-core/src/client/actions/budgets'; @@ -21,6 +22,8 @@ function getErrorMessage(error: string): string { } export function ImportYNAB4Modal() { + const { t } = useTranslation(); + const dispatch = useDispatch(); const [error, setError] = useState(null); const [importing, setImporting] = useState(false); @@ -48,7 +51,7 @@ export function ImportYNAB4Modal() { {({ state: { close } }) => ( <> } /> @@ -60,17 +63,21 @@ export function ImportYNAB4Modal() { - To import data from YNAB4, locate where your YNAB4 data is - stored. It is usually in your Documents folder under YNAB. Your - data is a directory inside that with the .ynab4{' '} - suffix. + + To import data from YNAB4, locate where your YNAB4 data is + stored. It is usually in your Documents folder under YNAB. + Your data is a directory inside that with the + .ynab4 suffix. + - When you’ve located your data,{' '} - compress it into a zip file. On macOS, - right-click the folder and select “Compress”. On Windows, - right-click and select “Send to → Compressed (zipped) - folder”. Upload the zipped folder for importing. + + When you’ve located your data,{' '} + compress it into a zip file. On macOS, + right-click the folder and select “Compress”. On Windows, + right-click and select “Send to → Compressed (zipped) + folder”. Upload the zipped folder for importing. + - Select zip file... + Select zip file... diff --git a/packages/desktop-client/src/components/modals/manager/ImportYNAB5Modal.tsx b/packages/desktop-client/src/components/modals/manager/ImportYNAB5Modal.tsx index e05303b6359..a17d9ab74b5 100644 --- a/packages/desktop-client/src/components/modals/manager/ImportYNAB5Modal.tsx +++ b/packages/desktop-client/src/components/modals/manager/ImportYNAB5Modal.tsx @@ -1,5 +1,6 @@ // @ts-strict-ignore import React, { useState } from 'react'; +import { Trans, useTranslation } from 'react-i18next'; import { useDispatch } from 'react-redux'; import { importBudget } from 'loot-core/src/client/actions/budgets'; @@ -24,6 +25,8 @@ function getErrorMessage(error: string): string { } export function ImportYNAB5Modal() { + const { t } = useTranslation(); + const dispatch = useDispatch(); const [error, setError] = useState(null); const [importing, setImporting] = useState(false); @@ -51,7 +54,7 @@ export function ImportYNAB5Modal() { {({ state: { close } }) => ( <> } /> @@ -68,21 +71,25 @@ export function ImportYNAB5Modal() { }} > - - Read here - {' '} - for instructions on how to migrate your data from YNAB. You need - to export your data as JSON, and that page explains how to do - that. + + + Read here + {' '} + for instructions on how to migrate your data from YNAB. You + need to export your data as JSON, and that page explains how + to do that. + - Once you have exported your data, select the file and Actual - will import it. Budgets may not match up exactly because things - work slightly differently, but you should be able to fix up any - problems. + + Once you have exported your data, select the file and Actual + will import it. Budgets may not match up exactly because + things work slightly differently, but you should be able to + fix up any problems. + - Select file... + Select file... diff --git a/packages/desktop-client/src/components/payees/PayeeTableRow.tsx b/packages/desktop-client/src/components/payees/PayeeTableRow.tsx index 637a63da76b..cd6fe5aeb2e 100644 --- a/packages/desktop-client/src/components/payees/PayeeTableRow.tsx +++ b/packages/desktop-client/src/components/payees/PayeeTableRow.tsx @@ -1,5 +1,6 @@ // @ts-strict-ignore import { memo } from 'react'; +import { Trans, useTranslation } from 'react-i18next'; import { type PayeeEntity } from 'loot-core/src/types/models'; @@ -24,6 +25,8 @@ type RuleButtonProps = { }; function RuleButton({ ruleCount, focused, onEdit, onClick }: RuleButtonProps) { + const count = ruleCount; + return ( {ruleCount > 0 ? ( - <> - {ruleCount} associated {ruleCount === 1 ? 'rule' : 'rules'} - > + {{ count }} associated rules ) : ( - <>Create rule> + Create rule )} @@ -95,6 +96,8 @@ export const PayeeTableRow = memo( onUpdate, style, }: PayeeTableRowProps) => { + const { t } = useTranslation(); + const { id } = payee; const dispatchSelected = useSelectedDispatch(); const borderColor = selected @@ -153,7 +156,7 @@ export const PayeeTableRow = memo( }} void; - const lib: { getDataDir: () => string }; -} diff --git a/packages/desktop-electron/package.json b/packages/desktop-electron/package.json index 960b789e90c..ad6d9e6cd00 100644 --- a/packages/desktop-electron/package.json +++ b/packages/desktop-electron/package.json @@ -3,7 +3,7 @@ "author": "Actual", "productName": "Actual", "description": "A simple and powerful personal finance system", - "version": "24.9.0", + "version": "24.10.0", "scripts": { "clean": "rm -rf dist", "update-client": "bin/update-client", @@ -17,14 +17,11 @@ "appId": "com.actualbudget.actual", "files": [ "build", - "!node_modules/loot-core/src{,/**/*}", - "!node_modules/loot-core/lib-dist/{browser,bundle.mobile*}", - "!node_modules/absurd-sql", "!node_modules/better-sqlite3/{benchmark,src,bin,docs,deps,build/Release/obj,build/Release/sqlite3.a,build/Release/test_extension.node}", "!**/*.js.map", "!**/stats.json", - "!node_modules/@jlongster/sql.js/**/*", - "!build/client-build/sql-wasm.wasm" + "!build/client-build/sql-wasm.wasm", + "!build/loot-core/lib-dist/{browser,bundle.mobile*}" ], "beforePack": "./build/beforePackHook.js", "mac": { @@ -88,9 +85,9 @@ "npmRebuild": false }, "dependencies": { + "better-sqlite3": "^9.6.0", "electron-is-dev": "2.0.0", "electron-log": "4.4.8", - "loot-core": "*", "node-fetch": "^2.7.0", "promise-retry": "^2.0.1" }, diff --git a/packages/desktop-electron/server.ts b/packages/desktop-electron/server.ts index a49e14d4095..1e6f8366787 100644 --- a/packages/desktop-electron/server.ts +++ b/packages/desktop-electron/server.ts @@ -1,15 +1,16 @@ -import Module from 'module'; - // @ts-strict-ignore import fetch from 'node-fetch'; -Module.globalPaths.push(__dirname + '/..'); global.fetch = fetch; const lazyLoadBackend = async (isDev: boolean) => { - // eslint-disable-next-line import/extensions - const bundle = await import('loot-core/lib-dist/bundle.desktop.js'); - bundle.initApp(isDev); + try { + const bundle = await import(process.env.lootCoreScript); + bundle.initApp(isDev); + } catch (error) { + console.error('Failed to init the server bundle:', error); + throw new Error(`Failed to init the server bundle: ${error.message}`); + } }; const isDev = false; diff --git a/packages/desktop-electron/window-state.ts b/packages/desktop-electron/window-state.ts index 46b1a077129..cbcb365ef12 100644 --- a/packages/desktop-electron/window-state.ts +++ b/packages/desktop-electron/window-state.ts @@ -3,26 +3,25 @@ import path from 'path'; import electron, { BrowserWindow } from 'electron'; -const backend = undefined; -const getBackend = async () => - // eslint-disable-next-line import/extensions - backend || (await import('loot-core/lib-dist/bundle.desktop.js')); - type WindowState = Electron.Rectangle & { isMaximized?: boolean; isFullScreen?: boolean; displayBounds?: Electron.Rectangle; }; +const getDataDir = () => { + if (!process.env.ACTUAL_DATA_DIR) { + throw new Error('ACTUAL_DATA_DIR is not set'); + } + + return process.env.ACTUAL_DATA_DIR; +}; + async function loadState() { let state: WindowState | undefined = undefined; - const backend = await getBackend(); try { state = JSON.parse( - fs.readFileSync( - path.join(backend.lib.getDataDir(), 'window.json'), - 'utf8', - ), + fs.readFileSync(path.join(getDataDir(), 'window.json'), 'utf8'), ); } catch (e) { console.log('Could not load window state'); @@ -47,10 +46,9 @@ function updateState(win: BrowserWindow, state: WindowState) { } async function saveState(win: BrowserWindow, state: WindowState) { - const backend = await getBackend(); updateState(win, state); fs.writeFileSync( - path.join(backend.lib.getDataDir(), 'window.json'), + path.join(getDataDir(), 'window.json'), JSON.stringify(state), 'utf8', ); diff --git a/packages/loot-core/src/server/budget/goals/goalsSchedule.test.ts b/packages/loot-core/src/server/budget/goals/goalsSchedule.test.ts index abfa9c035d8..29eefba3895 100644 --- a/packages/loot-core/src/server/budget/goals/goalsSchedule.test.ts +++ b/packages/loot-core/src/server/budget/goals/goalsSchedule.test.ts @@ -82,4 +82,68 @@ describe('goalsSchedule', () => { expect(result.remainder).toBe(0); expect(result.scheduleFlag).toBe(true); }); + + it('should return correct budget when yearly recurring schedule set and balance is greater than target', async () => { + // Given + const scheduleFlag = false; + const template_lines = [{ type: 'schedule', name: 'Test Schedule' }]; + const current_month = '2024-09-01'; + const balance = 12000; + const remainder = 0; + const last_month_balance = 12000; + const to_budget = 0; + const errors: string[] = []; + const category = { id: 1, name: 'Test Category' }; + + (db.first as jest.Mock).mockResolvedValue({ id: 1, completed: 0 }); + (getRuleForSchedule as jest.Mock).mockResolvedValue({ + serialize: () => ({ + conditions: [ + { + op: 'is', + field: 'date', + value: { + start: '2024-08-01', + interval: 1, + frequency: 'yearly', + patterns: [], + skipWeekend: false, + weekendSolveMode: 'before', + endMode: 'never', + endOccurrences: 1, + endDate: '2024-08-04', + }, + type: 'date', + }, + { + op: 'is', + field: 'amount', + value: -12000, + type: 'number', + }, + ], + }), + execActions: () => ({ amount: -12000, subtransactions: [] }), + }); + (isReflectBudget as jest.Mock).mockReturnValue(false); + + // When + const result = await goalsSchedule( + scheduleFlag, + template_lines, + current_month, + balance, + remainder, + last_month_balance, + to_budget, + errors, + category, + ); + + // Then + expect(result.to_budget).toBe(1000); + expect(result.errors).toHaveLength(0); + expect(result.remainder).toBe(0); + expect(result.scheduleFlag).toBe(true); + }); }); diff --git a/packages/loot-core/src/server/budget/goals/goalsSchedule.ts b/packages/loot-core/src/server/budget/goals/goalsSchedule.ts index 8b2162845cc..6abeec39b94 100644 --- a/packages/loot-core/src/server/budget/goals/goalsSchedule.ts +++ b/packages/loot-core/src/server/budget/goals/goalsSchedule.ts @@ -166,7 +166,11 @@ async function getSinkingBaseContributionTotal(t) { //return only the base contribution of each schedule let total = 0; for (let ll = 0; ll < t.length; ll++) { - total += t[ll].target / t[ll].target_interval; + let monthlyAmount = t[ll].target / t[ll].target_interval; + if (t[ll].target_frequency === 'yearly') { + monthlyAmount /= 12; + } + total += monthlyAmount; } return total; } diff --git a/upcoming-release-notes/3085.md b/upcoming-release-notes/3085.md deleted file mode 100644 index 48aa868428d..00000000000 --- a/upcoming-release-notes/3085.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Enhancements -authors: [joel-jeremy] ---- - -Show undo notifications when applying goal templates / budget actions in mobile. diff --git a/upcoming-release-notes/3119.md b/upcoming-release-notes/3119.md deleted file mode 100644 index 72945925ce6..00000000000 --- a/upcoming-release-notes/3119.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Enhancements -authors: [joel-jeremy] ---- - -Auto notes in month notes when reassigning budgets. diff --git a/upcoming-release-notes/3163.md b/upcoming-release-notes/3163.md deleted file mode 100644 index f6c8d75db23..00000000000 --- a/upcoming-release-notes/3163.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [joel-jeremy] ---- - -Use new react-aria-components in common and mobile components. diff --git a/upcoming-release-notes/3277.md b/upcoming-release-notes/3277.md deleted file mode 100644 index 201f78a71f7..00000000000 --- a/upcoming-release-notes/3277.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [matt-fidd] ---- - -Support translations in desktop-client/components/accounts. diff --git a/upcoming-release-notes/3286.md b/upcoming-release-notes/3286.md deleted file mode 100644 index d055ab0de8c..00000000000 --- a/upcoming-release-notes/3286.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [TimQuelch] ---- - -Forcibly reload app when API request is redirected. This fixes issue #2793 diff --git a/upcoming-release-notes/3288.md b/upcoming-release-notes/3288.md deleted file mode 100644 index 5444e81af19..00000000000 --- a/upcoming-release-notes/3288.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Enhancements -authors: [Matissjanis] ---- - -Dashboards: text widget support. diff --git a/upcoming-release-notes/3298.md b/upcoming-release-notes/3298.md deleted file mode 100644 index ead0ec5d874..00000000000 --- a/upcoming-release-notes/3298.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Enhancements -authors: [VoltaicGRiD, psybers] ---- - -Implement greater visibility and accessibility on popover menus and tooltips. \ No newline at end of file diff --git a/upcoming-release-notes/3311.md b/upcoming-release-notes/3311.md deleted file mode 100644 index c7eabab267a..00000000000 --- a/upcoming-release-notes/3311.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MatissJanis] ---- - -TypeScript: migrate Account component. diff --git a/upcoming-release-notes/3313.md b/upcoming-release-notes/3313.md deleted file mode 100644 index 555b2ab24d2..00000000000 --- a/upcoming-release-notes/3313.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Enhancements -authors: [psybers] ---- - -Support translations in desktop-client/components/schedules. diff --git a/upcoming-release-notes/3325.md b/upcoming-release-notes/3325.md deleted file mode 100644 index a926a724208..00000000000 --- a/upcoming-release-notes/3325.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Features -authors: [tim-smart] ---- - -Add setting to set preferred dark theme for "System default" mode diff --git a/upcoming-release-notes/3326.md b/upcoming-release-notes/3326.md deleted file mode 100644 index 196c56cf2bc..00000000000 --- a/upcoming-release-notes/3326.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Features -authors: [tim-smart] ---- - -Add an uncategorized transaction button to the mobile app. diff --git a/upcoming-release-notes/3332.md b/upcoming-release-notes/3332.md deleted file mode 100644 index 2de2dd0e8f0..00000000000 --- a/upcoming-release-notes/3332.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Enhancements -authors: [tim-smart] ---- - -Set html theme-color meta tag to match the webmanifest theme_color. diff --git a/upcoming-release-notes/3344.md b/upcoming-release-notes/3344.md deleted file mode 100644 index 3ce054286c3..00000000000 --- a/upcoming-release-notes/3344.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Enhancements -authors: [tim-smart] ---- - -Adjust mobile header link style diff --git a/upcoming-release-notes/3352.md b/upcoming-release-notes/3352.md deleted file mode 100644 index c99e63939d2..00000000000 --- a/upcoming-release-notes/3352.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [nmathey] ---- - -Support translations in Translation support for desktop-client/src/components/budget/BalanceWithCarryover.tsx diff --git a/upcoming-release-notes/3355.md b/upcoming-release-notes/3355.md deleted file mode 100644 index d74e4039f1d..00000000000 --- a/upcoming-release-notes/3355.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MatissJanis] ---- - -TypeScript: migrate Reconcile file. diff --git a/upcoming-release-notes/3356.md b/upcoming-release-notes/3356.md deleted file mode 100644 index f8accb98a21..00000000000 --- a/upcoming-release-notes/3356.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [matt-fidd] ---- - -Fix incorrect hook usage in #3277 diff --git a/upcoming-release-notes/3361.md b/upcoming-release-notes/3361.md deleted file mode 100644 index 7b9dd21635c..00000000000 --- a/upcoming-release-notes/3361.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [UnderKoen] ---- - -TypeScript: RSchedule types fixed diff --git a/upcoming-release-notes/3363.md b/upcoming-release-notes/3363.md deleted file mode 100644 index 4506ff225c9..00000000000 --- a/upcoming-release-notes/3363.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [agradina] ---- - -Support translations in desktop-client/components/budget. diff --git a/upcoming-release-notes/3364.md b/upcoming-release-notes/3364.md deleted file mode 100644 index 4eed1fc45c0..00000000000 --- a/upcoming-release-notes/3364.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Enhancements -authors: [MatissJanis, carkom] ---- - -Dashboards: ability to save filters & time-range on net-worth widgets. diff --git a/upcoming-release-notes/3367.md b/upcoming-release-notes/3367.md deleted file mode 100644 index 4e17cc73221..00000000000 --- a/upcoming-release-notes/3367.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [nmathey] ---- - -Support translations in Translation support for desktop-client/src/components/budget/BudgetTotals.tsx diff --git a/upcoming-release-notes/3374.md b/upcoming-release-notes/3374.md deleted file mode 100644 index 3f05cf826af..00000000000 --- a/upcoming-release-notes/3374.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [joel-jeremy] ---- - -Mobile - Fix budget cells being triggered when pulling down to refresh on budget table. diff --git a/upcoming-release-notes/3377.md b/upcoming-release-notes/3377.md deleted file mode 100644 index 2ebd4574f94..00000000000 --- a/upcoming-release-notes/3377.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Enhancements -authors: [olets] ---- - -Privacy mode: instead of blurring, use an illegible font (#3376) diff --git a/upcoming-release-notes/3379.md b/upcoming-release-notes/3379.md deleted file mode 100644 index 6e2677bb8db..00000000000 --- a/upcoming-release-notes/3379.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [carkom] ---- - -Fix report header validateStart bug. diff --git a/upcoming-release-notes/3380.md b/upcoming-release-notes/3380.md deleted file mode 100644 index d1d25f0e928..00000000000 --- a/upcoming-release-notes/3380.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Enhancements -authors: [carkom] ---- - -Fixing spending report header so that any month can be compared to any other month. Also adds budget as an optional comparison. diff --git a/upcoming-release-notes/3389.md b/upcoming-release-notes/3389.md deleted file mode 100644 index 93fff21f0f6..00000000000 --- a/upcoming-release-notes/3389.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [MikesGlitch] ---- - -Prevent keyboard shortcuts modal launching when entering shortcut into editable field. diff --git a/upcoming-release-notes/3391.md b/upcoming-release-notes/3391.md deleted file mode 100644 index a09102eacbd..00000000000 --- a/upcoming-release-notes/3391.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [jfdoming] ---- - -Refine Menu/Select types to allow broader types for the value/name attribute diff --git a/upcoming-release-notes/3393.md b/upcoming-release-notes/3393.md deleted file mode 100644 index b060f56b5de..00000000000 --- a/upcoming-release-notes/3393.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MikesGlitch] ---- - -Prevent sidebar from saving to metadata.json unnecessarily diff --git a/upcoming-release-notes/3394.md b/upcoming-release-notes/3394.md deleted file mode 100644 index cb3015aae73..00000000000 --- a/upcoming-release-notes/3394.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MikesGlitch] ---- - -Remove unneded Payee typeahead console log diff --git a/upcoming-release-notes/3395.md b/upcoming-release-notes/3395.md deleted file mode 100644 index 99f2245c913..00000000000 --- a/upcoming-release-notes/3395.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MatissJanis] ---- - -SyncedPrefs: refactor pref values from explicit types to `string`. diff --git a/upcoming-release-notes/3396.md b/upcoming-release-notes/3396.md deleted file mode 100644 index 4f04cb9c560..00000000000 --- a/upcoming-release-notes/3396.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [jfdoming] ---- - -Convert `RecurringSchedulePicker.jsx` -> `RecurringSchedulePicker.tsx` diff --git a/upcoming-release-notes/3397.md b/upcoming-release-notes/3397.md deleted file mode 100644 index eb5ceb11f2e..00000000000 --- a/upcoming-release-notes/3397.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MatissJanis] ---- - -SyncedPrefs: refactor usages of number formatter away from redux. diff --git a/upcoming-release-notes/3398.md b/upcoming-release-notes/3398.md deleted file mode 100644 index 77d83012409..00000000000 --- a/upcoming-release-notes/3398.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MikesGlitch] ---- - -Prevent sync from saving to metadata.json unnecessarily diff --git a/upcoming-release-notes/3399.md b/upcoming-release-notes/3399.md deleted file mode 100644 index 8f49154a008..00000000000 --- a/upcoming-release-notes/3399.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [jfdoming] ---- - -Fix regression in case sensitivity for `is`/`matches` operator diff --git a/upcoming-release-notes/3400.md b/upcoming-release-notes/3400.md deleted file mode 100644 index afe6f4d4874..00000000000 --- a/upcoming-release-notes/3400.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Enhancements -authors: [jfdoming] ---- - -Update splash background to match theming diff --git a/upcoming-release-notes/3401.md b/upcoming-release-notes/3401.md deleted file mode 100644 index 748b194dc50..00000000000 --- a/upcoming-release-notes/3401.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [joel-jeremy] ---- - -Use react-aria-components' Button in filters. diff --git a/upcoming-release-notes/3406.md b/upcoming-release-notes/3406.md deleted file mode 100644 index fbde65543bf..00000000000 --- a/upcoming-release-notes/3406.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MikesGlitch] ---- - -Adding retries into filesystem calls to mitigate locking issues caused by virus scanners. diff --git a/upcoming-release-notes/3408.md b/upcoming-release-notes/3408.md deleted file mode 100644 index 6334f66c26e..00000000000 --- a/upcoming-release-notes/3408.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MatissJanis] ---- - -SyncedPrefs: refactor `ImportTransactions` usage of prefs to use a common hook. diff --git a/upcoming-release-notes/3410.md b/upcoming-release-notes/3410.md deleted file mode 100644 index aff78c9812b..00000000000 --- a/upcoming-release-notes/3410.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MatissJanis] ---- - -SyncedPrefs: move `budgetType` back to metadata prefs. diff --git a/upcoming-release-notes/3411.md b/upcoming-release-notes/3411.md deleted file mode 100644 index ca639b898d5..00000000000 --- a/upcoming-release-notes/3411.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Enhancements -authors: [joel-jeremy] ---- - -Undoable auto tranfer notes + auto notes for cover diff --git a/upcoming-release-notes/3412.md b/upcoming-release-notes/3412.md deleted file mode 100644 index 7647c9a523c..00000000000 --- a/upcoming-release-notes/3412.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [qedi-r] ---- - -Sort suggested payee popup section by favorite status first, then alphabetically. diff --git a/upcoming-release-notes/3413.md b/upcoming-release-notes/3413.md deleted file mode 100644 index bd51d52fe81..00000000000 --- a/upcoming-release-notes/3413.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [joel-jeremy] ---- - -Complete migration of all modals to react-aria-components Modal component. diff --git a/upcoming-release-notes/3417.md b/upcoming-release-notes/3417.md deleted file mode 100644 index 72abdd69eef..00000000000 --- a/upcoming-release-notes/3417.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Enhancements -authors: [MatissJanis] ---- - -Dashboards: ability to save filters & time-range on cash-flow widgets. diff --git a/upcoming-release-notes/3423.md b/upcoming-release-notes/3423.md deleted file mode 100644 index 366c1281f3e..00000000000 --- a/upcoming-release-notes/3423.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MatissJanis] ---- - -SyncedPrefs: move synced-preferences from metadata.json to the database. diff --git a/upcoming-release-notes/3426.md b/upcoming-release-notes/3426.md deleted file mode 100644 index fc71ed4eba7..00000000000 --- a/upcoming-release-notes/3426.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [a-gradina] ---- - -Support translations in desktop-client/components/budget. diff --git a/upcoming-release-notes/3427.md b/upcoming-release-notes/3427.md deleted file mode 100644 index 9624e7a039d..00000000000 --- a/upcoming-release-notes/3427.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MatissJanis] ---- - -SyncedPrefs: move budget type to synced preferences. diff --git a/upcoming-release-notes/3431.md b/upcoming-release-notes/3431.md deleted file mode 100644 index a323e31a3c3..00000000000 --- a/upcoming-release-notes/3431.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MikesGlitch] ---- - -Restart server silently when adding self signed cert and add some logs diff --git a/upcoming-release-notes/3432.md b/upcoming-release-notes/3432.md deleted file mode 100644 index afdbed30aed..00000000000 --- a/upcoming-release-notes/3432.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Enhancements -authors: [MatissJanis] ---- - -Dashboards: ability to save filters & time-range on spending widgets. diff --git a/upcoming-release-notes/3441.md b/upcoming-release-notes/3441.md deleted file mode 100644 index fbcac7b5a06..00000000000 --- a/upcoming-release-notes/3441.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [MatisJanis] ---- - -Fix account filters being overridden. diff --git a/upcoming-release-notes/3430.md b/upcoming-release-notes/3444.md similarity index 55% rename from upcoming-release-notes/3430.md rename to upcoming-release-notes/3444.md index 94128819536..55f83991cbd 100644 --- a/upcoming-release-notes/3430.md +++ b/upcoming-release-notes/3444.md @@ -3,4 +3,4 @@ category: Maintenance authors: [a-gradina] --- -Support translations for component files +Support translations in various files. diff --git a/upcoming-release-notes/3450.md b/upcoming-release-notes/3450.md deleted file mode 100644 index 806d0a413ef..00000000000 --- a/upcoming-release-notes/3450.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [joel-jeremy] ---- - -Cleanup react-aria packages and dedupe packages. diff --git a/upcoming-release-notes/3451.md b/upcoming-release-notes/3451.md deleted file mode 100644 index 9539cc6d7ce..00000000000 --- a/upcoming-release-notes/3451.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Enhancements -authors: [carkom] ---- - -Fixing display issues in spending report and adding a legend. diff --git a/upcoming-release-notes/3452.md b/upcoming-release-notes/3452.md deleted file mode 100644 index d1de146fdaa..00000000000 --- a/upcoming-release-notes/3452.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [matt-fidd] ---- - -Update synced account balance in db if available diff --git a/upcoming-release-notes/3453.md b/upcoming-release-notes/3453.md deleted file mode 100644 index 42a848f2a4a..00000000000 --- a/upcoming-release-notes/3453.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [joel-jeremy] ---- - -Fix react-aria-components Button hover styles diff --git a/upcoming-release-notes/3456.md b/upcoming-release-notes/3456.md deleted file mode 100644 index c3ebd318f61..00000000000 --- a/upcoming-release-notes/3456.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [UnderKoen] ---- - -Fix csv import deduplication #3416 diff --git a/upcoming-release-notes/3458.md b/upcoming-release-notes/3458.md deleted file mode 100644 index a13767e96a6..00000000000 --- a/upcoming-release-notes/3458.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MatissJanis] ---- - -SyncedPrefs: separate out MetadataPrefs and LocalPrefs in different storage locations. diff --git a/upcoming-release-notes/3459.md b/upcoming-release-notes/3459.md deleted file mode 100644 index 98ad9dad226..00000000000 --- a/upcoming-release-notes/3459.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Features -authors: [MatissJanis] ---- - -SimpleFIN is officially released as a first-party feature of Actual. diff --git a/upcoming-release-notes/3460.md b/upcoming-release-notes/3460.md deleted file mode 100644 index b39dfcb9c9a..00000000000 --- a/upcoming-release-notes/3460.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [MatisJanis] ---- - -SyncedPrefs: fix import prefs not reading correctly. diff --git a/upcoming-release-notes/3462.md b/upcoming-release-notes/3462.md deleted file mode 100644 index 541a072ce91..00000000000 --- a/upcoming-release-notes/3462.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [joel-jeremy] ---- - -Fix save report forms submit handler so that it doesn't trigger a reload of an entire page on submit. diff --git a/upcoming-release-notes/3463.md b/upcoming-release-notes/3463.md deleted file mode 100644 index e0b7480280b..00000000000 --- a/upcoming-release-notes/3463.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [joel-jeremy] ---- - -Mobile - Do not allow renaming category or group to an empty name. diff --git a/upcoming-release-notes/3468.md b/upcoming-release-notes/3468.md deleted file mode 100644 index abb00dd5270..00000000000 --- a/upcoming-release-notes/3468.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MikesGlitch] ---- - -Remove old updater logic diff --git a/upcoming-release-notes/3469.md b/upcoming-release-notes/3469.md deleted file mode 100644 index a5ff4ae73ea..00000000000 --- a/upcoming-release-notes/3469.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [MatissJanis] ---- - -Reports - deleting custom reports should remove the widget from the dashboard. diff --git a/upcoming-release-notes/3472.md b/upcoming-release-notes/3472.md deleted file mode 100644 index 6aa81cf1542..00000000000 --- a/upcoming-release-notes/3472.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [joel-jeremy] ---- - -Fix privacy filters not activating diff --git a/upcoming-release-notes/3475.md b/upcoming-release-notes/3475.md deleted file mode 100644 index 49af54b1cb1..00000000000 --- a/upcoming-release-notes/3475.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MikesGlitch] ---- - -Replacing the deprecated Electron file handler protocol with the new version diff --git a/upcoming-release-notes/3478.md b/upcoming-release-notes/3478.md deleted file mode 100644 index fb85dc1d51e..00000000000 --- a/upcoming-release-notes/3478.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [MatissJanis] ---- - -CSV import - fix checkboxes not working. diff --git a/upcoming-release-notes/3480.md b/upcoming-release-notes/3480.md deleted file mode 100644 index 212a4574679..00000000000 --- a/upcoming-release-notes/3480.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [qedi-r] ---- - -Fix 'matches' operator incorrectly matching empty strings. diff --git a/upcoming-release-notes/3483.md b/upcoming-release-notes/3483.md deleted file mode 100644 index b373bc07a9f..00000000000 --- a/upcoming-release-notes/3483.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MatissJanis] ---- - -File/variable renames: rollover budget -> envelope budget; report budget -> tracking budget. diff --git a/upcoming-release-notes/3484.md b/upcoming-release-notes/3484.md deleted file mode 100644 index fd0f8fa1a6a..00000000000 --- a/upcoming-release-notes/3484.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [MatissJanis] ---- - -Custom reports - fix opening table reports crashing the page. diff --git a/upcoming-release-notes/3487.md b/upcoming-release-notes/3487.md deleted file mode 100644 index 081fe893bef..00000000000 --- a/upcoming-release-notes/3487.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [tim-smart] ---- - -Fix modals not opening on mobile budget view diff --git a/upcoming-release-notes/3491.md b/upcoming-release-notes/3491.md deleted file mode 100644 index bdd9b38b7ee..00000000000 --- a/upcoming-release-notes/3491.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [joel-jeremy] ---- - -Fix mobile page header button styles. diff --git a/upcoming-release-notes/3492.md b/upcoming-release-notes/3492.md deleted file mode 100644 index cd068c750b9..00000000000 --- a/upcoming-release-notes/3492.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [joel-jeremy] ---- - -Fix mobile balance modal not properly coloring balance. diff --git a/upcoming-release-notes/3493.md b/upcoming-release-notes/3493.md deleted file mode 100644 index d8686ab1bd7..00000000000 --- a/upcoming-release-notes/3493.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MatissJanis] ---- - -Custom reports: added e2e tests to improve stability. diff --git a/upcoming-release-notes/3495.md b/upcoming-release-notes/3495.md deleted file mode 100644 index b4ddc5cd82d..00000000000 --- a/upcoming-release-notes/3495.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [junyuanz1] ---- - -Removes whitespace from both ends of the category name diff --git a/upcoming-release-notes/3497.md b/upcoming-release-notes/3497.md deleted file mode 100644 index 4c0922a5500..00000000000 --- a/upcoming-release-notes/3497.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [UnderKoen] ---- - -Fix running `yarn vrt:docker` on windows with git bash diff --git a/upcoming-release-notes/3498.md b/upcoming-release-notes/3498.md deleted file mode 100644 index e14d239550f..00000000000 --- a/upcoming-release-notes/3498.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MatissJanis] ---- - -e2e: improve rules test stability. diff --git a/upcoming-release-notes/3501.md b/upcoming-release-notes/3501.md deleted file mode 100644 index 40f592e670b..00000000000 --- a/upcoming-release-notes/3501.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [Jonathan-Fang] ---- - -Fix typo in README for Actual Budget Github homepage diff --git a/upcoming-release-notes/3503.md b/upcoming-release-notes/3503.md deleted file mode 100644 index 4ae2f6204ac..00000000000 --- a/upcoming-release-notes/3503.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MatissJanis] ---- - -e2e: improve onboarding test stability. diff --git a/upcoming-release-notes/3448.md b/upcoming-release-notes/3506.md similarity index 54% rename from upcoming-release-notes/3448.md rename to upcoming-release-notes/3506.md index e475df111df..8bc03a154ee 100644 --- a/upcoming-release-notes/3448.md +++ b/upcoming-release-notes/3506.md @@ -3,4 +3,4 @@ category: Maintenance authors: [joel-jeremy] --- -Reduce budget table re-renders +e2e: Add some mobile visual regression tests diff --git a/upcoming-release-notes/3509.md b/upcoming-release-notes/3509.md deleted file mode 100644 index 932a22fccd7..00000000000 --- a/upcoming-release-notes/3509.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [qedi-r] ---- - -Fix desktop popover showing in mobile To Budget options. diff --git a/upcoming-release-notes/3510.md b/upcoming-release-notes/3510.md deleted file mode 100644 index 9e060c92db7..00000000000 --- a/upcoming-release-notes/3510.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [youngcw] ---- - -Fix templates and syntax check running on deleted categories diff --git a/upcoming-release-notes/3511.md b/upcoming-release-notes/3511.md new file mode 100644 index 00000000000..9cdd896d030 --- /dev/null +++ b/upcoming-release-notes/3511.md @@ -0,0 +1,6 @@ +--- +category: Bugfix +authors: [JukeboxRhino] +--- + +Fix yearly schedule templates not behaving correctly when budgeting ahead of the transaction date diff --git a/upcoming-release-notes/3512.md b/upcoming-release-notes/3512.md deleted file mode 100644 index e14d239550f..00000000000 --- a/upcoming-release-notes/3512.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MatissJanis] ---- - -e2e: improve rules test stability. diff --git a/upcoming-release-notes/3513.md b/upcoming-release-notes/3513.md deleted file mode 100644 index 588f052d13b..00000000000 --- a/upcoming-release-notes/3513.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [MatissJanis] ---- - -e2e: improve settings test stability. diff --git a/upcoming-release-notes/3514.md b/upcoming-release-notes/3514.md deleted file mode 100644 index 23e3c759f5e..00000000000 --- a/upcoming-release-notes/3514.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [youngcw] ---- - -Add category goal info to the budget prewarm list for faster loading of indicator colors. diff --git a/upcoming-release-notes/3515.md b/upcoming-release-notes/3515.md deleted file mode 100644 index 3200097e69e..00000000000 --- a/upcoming-release-notes/3515.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [EtaoinWu] ---- - -Fix GoCardless linking (account selection window not appearing) diff --git a/upcoming-release-notes/3521.md b/upcoming-release-notes/3521.md deleted file mode 100644 index d309047ee2f..00000000000 --- a/upcoming-release-notes/3521.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [joel-jeremy] ---- - -Cleanup: Set theme-color at App level instead of per page diff --git a/upcoming-release-notes/3523.md b/upcoming-release-notes/3523.md deleted file mode 100644 index 5dc8ddbaf3e..00000000000 --- a/upcoming-release-notes/3523.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [joel-jeremy] ---- - -e2e stability: wait for data-theme to switch before taking a screenshot diff --git a/upcoming-release-notes/3525.md b/upcoming-release-notes/3525.md deleted file mode 100644 index 06481bc3e07..00000000000 --- a/upcoming-release-notes/3525.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [qedi-r] ---- - -Expose underlying exception source when a module fails to load. diff --git a/upcoming-release-notes/3526.md b/upcoming-release-notes/3526.md deleted file mode 100644 index 08c90d6f349..00000000000 --- a/upcoming-release-notes/3526.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [matt-fidd] ---- - -Fix electron build workflow for ubuntu-latest diff --git a/upcoming-release-notes/3530.md b/upcoming-release-notes/3530.md deleted file mode 100644 index 523cde14cda..00000000000 --- a/upcoming-release-notes/3530.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Maintenance -authors: [joel-jeremy] ---- - -[e2e] Fix the flaky "navigates back to start page by clicking on “no server” in an empty budget file test" from onboarding.test.js diff --git a/upcoming-release-notes/3535.md b/upcoming-release-notes/3535.md deleted file mode 100644 index 3fa0f6137bf..00000000000 --- a/upcoming-release-notes/3535.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [MikesGlitch] ---- - -Fix balance carryover arrow on Firefox diff --git a/upcoming-release-notes/3539.md b/upcoming-release-notes/3539.md deleted file mode 100644 index 63655637501..00000000000 --- a/upcoming-release-notes/3539.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [matt-fidd] ---- - -Fix error when creating a rule from an existing transaction diff --git a/upcoming-release-notes/3540.md b/upcoming-release-notes/3540.md deleted file mode 100644 index 5225ba04520..00000000000 --- a/upcoming-release-notes/3540.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [MatissJanis] ---- - -BankSync: fix showing sync status after linking and close all modal stack. diff --git a/upcoming-release-notes/3541.md b/upcoming-release-notes/3541.md deleted file mode 100644 index bd1a1ea86ef..00000000000 --- a/upcoming-release-notes/3541.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: Bugfix -authors: [MatissJanis] ---- - -Fix import crashing if the QFX file is malformed. diff --git a/upcoming-release-notes/3552.md b/upcoming-release-notes/3552.md new file mode 100644 index 00000000000..f5819b02b9f --- /dev/null +++ b/upcoming-release-notes/3552.md @@ -0,0 +1,6 @@ +--- +category: Maintenance +authors: [MatissJanis] +--- + +Split `ImportTransactionsModal` file in multiple smaller component files. diff --git a/upcoming-release-notes/3443.md b/upcoming-release-notes/3553.md similarity index 61% rename from upcoming-release-notes/3443.md rename to upcoming-release-notes/3553.md index 4c1fbda3611..61e5497c345 100644 --- a/upcoming-release-notes/3443.md +++ b/upcoming-release-notes/3553.md @@ -3,4 +3,4 @@ category: Maintenance authors: [MikesGlitch] --- -Reduce size of desktop packages +Reducing Desktop app package size diff --git a/yarn.lock b/yarn.lock index 05741033463..bd042b82d52 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7129,9 +7129,9 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.30001587": - version: 1.0.30001587 - resolution: "caniuse-lite@npm:1.0.30001587" - checksum: 10/960e26927ad876971021186337df1df2d37d7ed4fc7907098c060f56ae8de737d471791e51387ca55bea07f56b0a76553a90125f88a2f958ca1f4f715013cf71 + version: 1.0.30001663 + resolution: "caniuse-lite@npm:1.0.30001663" + checksum: 10/a67aba45e10bf56f584f82ab414ff21f5d23ddbd71936839b79c305710b332d8b91df37948a525fe1c9cede81ab56a3d831ee6e3f1fa11c4f299651ea49a8067 languageName: node linkType: hard @@ -8412,13 +8412,13 @@ __metadata: "@electron/notarize": "npm:2.4.0" "@electron/rebuild": "npm:3.6.0" "@types/copyfiles": "npm:^2" + better-sqlite3: "npm:^9.6.0" copyfiles: "npm:^2.4.1" cross-env: "npm:^7.0.3" electron: "npm:30.0.6" electron-builder: "npm:24.13.3" electron-is-dev: "npm:2.0.0" electron-log: "npm:4.4.8" - loot-core: "npm:*" node-fetch: "npm:^2.7.0" promise-retry: "npm:^2.0.1" typescript: "npm:^5.5.4" @@ -13129,7 +13129,7 @@ __metadata: languageName: node linkType: hard -"loot-core@npm:*, loot-core@workspace:packages/loot-core": +"loot-core@workspace:packages/loot-core": version: 0.0.0-use.local resolution: "loot-core@workspace:packages/loot-core" dependencies:
db.sqlite
metadata.json
.ynab4