Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into feat/sub-categories
Browse files Browse the repository at this point in the history
# Conflicts:
#	packages/desktop-client/src/components/budget/BudgetCategories.jsx
#	packages/desktop-client/src/components/budget/SidebarGroup.tsx
#	packages/desktop-client/src/components/settings/Experimental.tsx
#	packages/desktop-client/src/hooks/useFeatureFlag.ts
#	packages/loot-core/src/types/prefs.d.ts
UnderKoen committed Nov 5, 2024
2 parents 6a7ef6f + c0f9073 commit 9988c6e
Showing 186 changed files with 2,572 additions and 2,885 deletions.
55 changes: 55 additions & 0 deletions .github/workflows/update-vrt.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: /update-vrt
on:
issue_comment:
types: [ created ]

permissions:
pull-requests: write
contents: write

concurrency:
group: ${{ github.workflow }}-${{ github.event.issue.number }}
cancel-in-progress: true

jobs:
update-vrt:
name: Update VRT
runs-on: ubuntu-latest
if: |
github.event.issue.pull_request &&
contains(github.event.comment.body, '/update-vrt')
container:
image: mcr.microsoft.com/playwright:v1.41.1-jammy
steps:
- name: Get PR branch
# Until https://github.com/xt0rted/pull-request-comment-branch/issues/322 is resolved we use the forked version
uses: gotson/pull-request-comment-branch@head-repo-owner-dist
id: comment-branch
- uses: actions/checkout@v4
with:
repository: ${{ steps.comment-branch.outputs.head_owner }}/${{ steps.comment-branch.outputs.head_repo }}
ref: ${{ steps.comment-branch.outputs.head_ref }}
- name: Set up environment
uses: ./.github/actions/setup
- name: Wait for Netlify build to finish
id: netlify
env:
COMMIT_SHA: ${{ steps.comment-branch.outputs.head_sha }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./.github/actions/netlify-wait-for-build
- name: Run VRT Tests on Netlify URL
run: yarn vrt --update-snapshots
env:
E2E_START_URL: ${{ steps.netlify.outputs.url }}
- name: Commit and push changes
run: |
git config --system --add safe.directory "*"
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git add "**/*.png"
if git diff --staged --quiet; then
echo "No changes to commit"
exit 0
fi
git commit -m "Update VRT"
git push origin HEAD:${{ steps.comment-branch.outputs.head_ref }}
2 changes: 1 addition & 1 deletion packages/api/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@actual-app/api",
"version": "24.10.1",
"version": "24.11.0",
"license": "MIT",
"description": "An API for Actual",
"engines": {
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion packages/desktop-client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@actual-app/web",
"version": "24.10.1",
"version": "24.11.0",
"license": "MIT",
"files": [
"build"
23 changes: 22 additions & 1 deletion packages/desktop-client/src/browser-preload.browser.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { initBackend as initSQLBackend } from 'absurd-sql/dist/indexeddb-main-thread';
import { registerSW } from 'virtual:pwa-register';

import * as Platform from 'loot-core/src/client/platform';

@@ -39,6 +40,19 @@ function createBackendWorker() {

createBackendWorker();

let isUpdateReadyForDownload = false;
let markUpdateReadyForDownload;
const isUpdateReadyForDownloadPromise = new Promise(resolve => {
markUpdateReadyForDownload = () => {
isUpdateReadyForDownload = true;
resolve(true);
};
});
const updateSW = registerSW({
immediate: true,
onNeedRefresh: markUpdateReadyForDownload,
});

global.Actual = {
IS_DEV,
ACTUAL_VERSION,
@@ -140,7 +154,14 @@ global.Actual = {
window.open(url, '_blank');
},
onEventFromMain: () => {},
applyAppUpdate: () => {},
isUpdateReadyForDownload: () => isUpdateReadyForDownload,
waitForUpdateReadyForDownload: () => isUpdateReadyForDownloadPromise,
applyAppUpdate: async () => {
updateSW();

// Wait for the app to reload
await new Promise(() => {});
},
updateAppMenu: () => {},

ipcConnect: () => {},
30 changes: 22 additions & 8 deletions packages/desktop-client/src/components/App.tsx
Original file line number Diff line number Diff line change
@@ -51,8 +51,20 @@ function AppInner() {
const { showBoundary: showErrorBoundary } = useErrorBoundary();
const dispatch = useDispatch();

const maybeUpdate = async <T,>(cb?: () => T): Promise<T> => {
if (global.Actual.isUpdateReadyForDownload()) {
dispatch(
setAppState({
loadingText: t('Downloading and applying update...'),
}),
);
await global.Actual.applyAppUpdate();
}
return cb?.();
};

async function init() {
const socketName = await global.Actual.getServerSocket();
const socketName = await maybeUpdate(() => global.Actual.getServerSocket());

dispatch(
setAppState({
@@ -86,14 +98,16 @@ function AppInner() {
loadingText: t('Retrieving remote files...'),
}),
);
send('get-remote-files').then(files => {
if (files) {
const remoteFile = files.find(f => f.fileId === cloudFileId);
if (remoteFile && remoteFile.deleted) {
dispatch(closeBudget());
}

const files = await send('get-remote-files');
if (files) {
const remoteFile = files.find(f => f.fileId === cloudFileId);
if (remoteFile && remoteFile.deleted) {
dispatch(closeBudget());
}
});
}

await maybeUpdate();
}
}

23 changes: 23 additions & 0 deletions packages/desktop-client/src/components/FinancesApp.tsx
Original file line number Diff line number Diff line change
@@ -100,6 +100,29 @@ export function FinancesApp() {
}, 100);
}, []);

useEffect(() => {
async function run() {
await global.Actual.waitForUpdateReadyForDownload();
dispatch(
addNotification({
type: 'message',
title: t('A new version of Actual is available!'),
message: t('Click the button below to reload and apply the update.'),
sticky: true,
id: 'update-reload-notification',
button: {
title: t('Update now'),
action: async () => {
await global.Actual.applyAppUpdate();
},
},
}),
);
}

run();
}, []);

useEffect(() => {
async function run() {
const latestVersion = await getLatestVersion();
8 changes: 8 additions & 0 deletions packages/desktop-client/src/components/ManageRules.tsx
Original file line number Diff line number Diff line change
@@ -204,6 +204,13 @@ export function ManageRules({
setLoading(false);
}

async function onDeleteRule(id: string) {
setLoading(true);
await send('rule-delete', id);
await loadRules();
setLoading(false);
}

const onEditRule = useCallback(rule => {
dispatch(
pushModal('edit-rule', {
@@ -306,6 +313,7 @@ export function ManageRules({
hoveredRule={hoveredRule}
onHover={onHover}
onEditRule={onEditRule}
onDeleteRule={rule => onDeleteRule(rule.id)}
/>
)}
</SimpleTable>
9 changes: 9 additions & 0 deletions packages/desktop-client/src/components/accounts/Account.tsx
Original file line number Diff line number Diff line change
@@ -1803,6 +1803,15 @@ class AccountInternal extends PureComponent<
sortField={this.state.sort?.field}
ascDesc={this.state.sort?.ascDesc}
onChange={this.onTransactionsChange}
onBatchDelete={this.onBatchDelete}
onBatchDuplicate={this.onBatchDuplicate}
onBatchLinkSchedule={this.onBatchLinkSchedule}
onBatchUnlinkSchedule={this.onBatchUnlinkSchedule}
onCreateRule={this.onCreateRule}
onScheduleAction={this.onScheduleAction}
onMakeAsNonSplitTransactions={
this.onMakeAsNonSplitTransactions
}
onRefetch={this.refetchTransactions}
onCloseAddTransaction={() =>
this.setState({ isAdding: false })
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React, { useRef, useState } from 'react';
import React, { useCallback, useRef, useState } from 'react';
import { Trans } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
import { useParams } from 'react-router-dom';

import { t } from 'i18next';

import { unlinkAccount } from 'loot-core/client/actions';
import { type AccountEntity } from 'loot-core/types/models';

import { authorizeBank } from '../../gocardless';
import { useAccounts } from '../../hooks/useAccounts';
@@ -16,7 +17,7 @@ import { Link } from '../common/Link';
import { Popover } from '../common/Popover';
import { View } from '../common/View';

function getErrorMessage(type, code) {
function getErrorMessage(type: string, code: string) {
switch (type.toUpperCase()) {
case 'ITEM_ERROR':
switch (code.toUpperCase()) {
@@ -81,7 +82,29 @@ export function AccountSyncCheck() {
const [open, setOpen] = useState(false);
const triggerRef = useRef(null);

if (!failedAccounts) {
const reauth = useCallback(
(acc: AccountEntity) => {
setOpen(false);

if (acc.account_id) {
authorizeBank(dispatch, { upgradingAccountId: acc.account_id });
}
},
[dispatch],
);

const unlink = useCallback(
(acc: AccountEntity) => {
if (acc.id) {
dispatch(unlinkAccount(acc.id));
}

setOpen(false);
},
[dispatch],
);

if (!failedAccounts || !id) {
return null;
}

@@ -91,22 +114,15 @@ export function AccountSyncCheck() {
}

const account = accounts.find(account => account.id === id);
if (!account) {
return null;
}

const { type, code } = error;
const showAuth =
(type === 'ITEM_ERROR' && code === 'ITEM_LOGIN_REQUIRED') ||
(type === 'INVALID_INPUT' && code === 'INVALID_ACCESS_TOKEN');

function reauth() {
setOpen(false);

authorizeBank(dispatch, { upgradingAccountId: account.account_id });
}

async function unlink() {
dispatch(unlinkAccount(account.id));
setOpen(false);
}

return (
<View>
<Button
@@ -148,20 +164,20 @@ export function AccountSyncCheck() {
<View style={{ justifyContent: 'flex-end', flexDirection: 'row' }}>
{showAuth ? (
<>
<Button onPress={unlink}>
<Button onPress={() => unlink(account)}>
<Trans>Unlink</Trans>
</Button>
<Button
variant="primary"
autoFocus
onPress={reauth}
onPress={() => reauth(account)}
style={{ marginLeft: 5 }}
>
<Trans>Reauthorize</Trans>
</Button>
</>
) : (
<Button onPress={unlink}>
<Button onPress={() => unlink(account)}>
<Trans>Unlink account</Trans>
</Button>
)}
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ export const BudgetCategories = memo(
onSaveGroup,
onDeleteCategory,
onDeleteGroup,
onApplyBudgetTemplatesInGroup,
onReorderCategory,
onReorderGroup,
}) => {
@@ -251,6 +252,7 @@ export const BudgetCategories = memo(
onShowNewCategory={onShowNewCategory}
onShowNewGroup={onShowNewGroup}
depth={item.depth}
onApplyBudgetTemplatesInGroup={onApplyBudgetTemplatesInGroup}
/>
);
break;
2 changes: 2 additions & 0 deletions packages/desktop-client/src/components/budget/BudgetTable.jsx
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ export function BudgetTable(props) {
onDeleteCategory,
onSaveGroup,
onDeleteGroup,
onApplyBudgetTemplatesInGroup,
onReorderCategory,
onReorderGroup,
onShowActivity,
@@ -235,6 +236,7 @@ export function BudgetTable(props) {
onReorderGroup={_onReorderGroup}
onBudgetAction={onBudgetAction}
onShowActivity={onShowActivity}
onApplyBudgetTemplatesInGroup={onApplyBudgetTemplatesInGroup}
/>
</View>
</View>
Original file line number Diff line number Diff line change
@@ -26,6 +26,9 @@ type ExpenseGroupProps = {
onEditName?: ComponentProps<typeof SidebarGroup>['onEdit'];
onSave?: ComponentProps<typeof SidebarGroup>['onSave'];
onDelete?: ComponentProps<typeof SidebarGroup>['onDelete'];
onApplyBudgetTemplatesInGroup?: ComponentProps<
typeof SidebarGroup
>['onApplyBudgetTemplatesInGroup'];
onDragChange: OnDragChangeCallback<
ComponentProps<typeof SidebarGroup>['group']
>;
@@ -46,6 +49,7 @@ export function ExpenseGroup({
onEditName,
onSave,
onDelete,
onApplyBudgetTemplatesInGroup,
onDragChange,
onReorderGroup,
onReorderCategory,
@@ -131,6 +135,7 @@ export function ExpenseGroup({
onEdit={onEditName}
onSave={onSave}
onDelete={onDelete}
onApplyBudgetTemplatesInGroup={onApplyBudgetTemplatesInGroup}
onShowNewCategory={onShowNewCategory}
onShowNewGroup={onShowNewGroup}
depth={depth}
Loading

0 comments on commit 9988c6e

Please sign in to comment.