Compare commits
1 commit
master
...
jlongster-
Author | SHA1 | Date | |
---|---|---|---|
|
c4d1303691 |
13 changed files with 66511 additions and 50 deletions
1
packages/api/.gitignore
vendored
1
packages/api/.gitignore
vendored
|
@ -1 +0,0 @@
|
||||||
app/bundle.api.js*
|
|
66420
packages/api/app/bundle.api.js
Normal file
66420
packages/api/app/bundle.api.js
Normal file
File diff suppressed because one or more lines are too long
1
packages/api/app/bundle.api.js.map
Normal file
1
packages/api/app/bundle.api.js.map
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,18 +1,9 @@
|
||||||
{
|
{
|
||||||
"name": "@actual-app/api",
|
"name": "@actual-app/api",
|
||||||
"version": "4.1.5",
|
"version": "4.0.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"description": "An API for Actual",
|
"description": "An API for Actual",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"files": [
|
|
||||||
"app",
|
|
||||||
"default-db.sqlite",
|
|
||||||
"index.js",
|
|
||||||
"injected.js",
|
|
||||||
"methods.js",
|
|
||||||
"migrations",
|
|
||||||
"utils.js"
|
|
||||||
],
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"better-sqlite3": "^7.5.0",
|
"better-sqlite3": "^7.5.0",
|
||||||
"node-fetch": "^1.6.3",
|
"node-fetch": "^1.6.3",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@actual-app/web",
|
"name": "@actual-app/web",
|
||||||
"version": "22.12.03",
|
"version": "22.10.25",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"files": [
|
"files": [
|
||||||
"build"
|
"build"
|
||||||
|
|
|
@ -35,7 +35,6 @@ import {
|
||||||
Stack
|
Stack
|
||||||
} from 'loot-design/src/components/common';
|
} from 'loot-design/src/components/common';
|
||||||
import { KeyHandlers } from 'loot-design/src/components/KeyHandlers';
|
import { KeyHandlers } from 'loot-design/src/components/KeyHandlers';
|
||||||
import NotesButton from 'loot-design/src/components/NotesButton';
|
|
||||||
import CellValue from 'loot-design/src/components/spreadsheet/CellValue';
|
import CellValue from 'loot-design/src/components/spreadsheet/CellValue';
|
||||||
import format from 'loot-design/src/components/spreadsheet/format';
|
import format from 'loot-design/src/components/spreadsheet/format';
|
||||||
import useSheetValue from 'loot-design/src/components/spreadsheet/useSheetValue';
|
import useSheetValue from 'loot-design/src/components/spreadsheet/useSheetValue';
|
||||||
|
@ -671,46 +670,30 @@ const AccountHeader = React.memo(
|
||||||
/>
|
/>
|
||||||
</InitialFocus>
|
</InitialFocus>
|
||||||
) : isNameEditable ? (
|
) : isNameEditable ? (
|
||||||
<View
|
<Button
|
||||||
style={{
|
bare
|
||||||
flexDirection: 'row',
|
|
||||||
alignItems: 'center',
|
|
||||||
gap: 3,
|
|
||||||
'& .hover-visible': {
|
|
||||||
opacity: 0,
|
|
||||||
transition: 'opacity .25s'
|
|
||||||
},
|
|
||||||
'&:hover .hover-visible': {
|
|
||||||
opacity: 1
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={{
|
style={{
|
||||||
fontSize: 25,
|
fontSize: 25,
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
marginRight: 5,
|
marginLeft: -5,
|
||||||
marginBottom: 5
|
marginTop: -5,
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
'& svg': { display: 'none' },
|
||||||
|
'&:hover svg': { display: 'unset' }
|
||||||
}}
|
}}
|
||||||
>
|
|
||||||
{accountName}
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<NotesButton id={`account-${account.id}`} />
|
|
||||||
<Button
|
|
||||||
bare
|
|
||||||
className="hover-visible"
|
|
||||||
onClick={() => onExposeName(true)}
|
onClick={() => onExposeName(true)}
|
||||||
>
|
>
|
||||||
|
{accountName}
|
||||||
|
|
||||||
<Pencil1
|
<Pencil1
|
||||||
style={{
|
style={{
|
||||||
width: 11,
|
width: 11,
|
||||||
height: 11,
|
height: 11,
|
||||||
color: colors.n8
|
marginLeft: 5,
|
||||||
|
color: colors.n4
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
</View>
|
|
||||||
) : (
|
) : (
|
||||||
<View
|
<View
|
||||||
style={{ fontSize: 25, fontWeight: 500, marginBottom: 5 }}
|
style={{ fontSize: 25, fontWeight: 500, marginBottom: 5 }}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"productName": "Actual",
|
"productName": "Actual",
|
||||||
"author": "Shift Reset LLC",
|
"author": "Shift Reset LLC",
|
||||||
"description": "A simple and powerful personal finance system",
|
"description": "A simple and powerful personal finance system",
|
||||||
"version": "22.12.03",
|
"version": "22.10.25",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"clean": "rm -rf dist",
|
"clean": "rm -rf dist",
|
||||||
"build": "electron-builder",
|
"build": "electron-builder",
|
||||||
|
|
|
@ -24,12 +24,21 @@ export function applyBudgetAction(month, type, args) {
|
||||||
case 'set-3-avg':
|
case 'set-3-avg':
|
||||||
await send('budget/set-3month-avg', { month });
|
await send('budget/set-3month-avg', { month });
|
||||||
break;
|
break;
|
||||||
|
case 'set-all-future':
|
||||||
|
await send('budget/set-all-future', { startMonth: month });
|
||||||
|
break;
|
||||||
case 'hold':
|
case 'hold':
|
||||||
await send('budget/hold-for-next-month', {
|
await send('budget/hold-for-next-month', {
|
||||||
month,
|
month,
|
||||||
amount: args.amount
|
amount: args.amount
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case 'hold-all-future':
|
||||||
|
await send('budget/hold-for-future-months', {
|
||||||
|
startMonth: month,
|
||||||
|
amount: args.amount
|
||||||
|
});
|
||||||
|
break;
|
||||||
case 'reset-hold':
|
case 'reset-hold':
|
||||||
await send('budget/reset-hold', { month });
|
await send('budget/reset-hold', { month });
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -190,6 +190,26 @@ export async function set3MonthAvg({ month }) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function setAllFuture({ startMonth }) {
|
||||||
|
if (!isReflectBudget()) {
|
||||||
|
throw new Error('setAllFuture only applies to report budget type');
|
||||||
|
}
|
||||||
|
let table = getBudgetTable();
|
||||||
|
let budgetData = await getBudgetData(table, dbMonth(startMonth));
|
||||||
|
let months = getAllMonths(monthUtils.addMonths(startMonth, 1));
|
||||||
|
|
||||||
|
batchMessages(() => {
|
||||||
|
for (let month of months) {
|
||||||
|
budgetData.forEach(budget => {
|
||||||
|
if (budget.is_income === 1 && !isReflectBudget()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setBudget({ category: budget.category, month, amount: budget.amount });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export async function holdForNextMonth({ month, amount }) {
|
export async function holdForNextMonth({ month, amount }) {
|
||||||
let row = await db.first(
|
let row = await db.first(
|
||||||
'SELECT buffered FROM zero_budget_months WHERE id = ?',
|
'SELECT buffered FROM zero_budget_months WHERE id = ?',
|
||||||
|
@ -212,6 +232,18 @@ export async function holdForNextMonth({ month, amount }) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function holdForFutureMonths({ startMonth, amount }) {
|
||||||
|
let months = getAllMonths(startMonth);
|
||||||
|
|
||||||
|
await batchMessages(async () => {
|
||||||
|
for (let month of months) {
|
||||||
|
if (!(await holdForNextMonth({ month, amount }))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export async function resetHold({ month }) {
|
export async function resetHold({ month }) {
|
||||||
await setBuffer(month, 0);
|
await setBuffer(month, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,15 @@ app.method(
|
||||||
);
|
);
|
||||||
app.method('budget/set-zero', mutator(undoable(actions.setZero)));
|
app.method('budget/set-zero', mutator(undoable(actions.setZero)));
|
||||||
app.method('budget/set-3month-avg', mutator(undoable(actions.set3MonthAvg)));
|
app.method('budget/set-3month-avg', mutator(undoable(actions.set3MonthAvg)));
|
||||||
|
app.method('budget/set-all-future', mutator(undoable(actions.setAllFuture)));
|
||||||
app.method(
|
app.method(
|
||||||
'budget/hold-for-next-month',
|
'budget/hold-for-next-month',
|
||||||
mutator(undoable(actions.holdForNextMonth))
|
mutator(undoable(actions.holdForNextMonth))
|
||||||
);
|
);
|
||||||
|
app.method(
|
||||||
|
'budget/hold-for-future-months',
|
||||||
|
mutator(undoable(actions.holdForFutureMonths))
|
||||||
|
);
|
||||||
app.method('budget/reset-hold', mutator(undoable(actions.resetHold)));
|
app.method('budget/reset-hold', mutator(undoable(actions.resetHold)));
|
||||||
app.method(
|
app.method(
|
||||||
'budget/cover-overspending',
|
'budget/cover-overspending',
|
||||||
|
|
|
@ -368,6 +368,10 @@ export default React.memo(function BudgetSummary({ month }) {
|
||||||
{
|
{
|
||||||
name: 'set-3-avg',
|
name: 'set-3-avg',
|
||||||
text: 'Set budgets to 3 month avg'
|
text: 'Set budgets to 3 month avg'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'set-all-future',
|
||||||
|
text: 'Apply to all future budgets'
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -204,6 +204,10 @@ function ToBudget({ month, prevMonthName, collapsed, onBudgetAction }) {
|
||||||
name: 'buffer',
|
name: 'buffer',
|
||||||
text: 'Hold for next month'
|
text: 'Hold for next month'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'buffer-future',
|
||||||
|
text: 'Hold for all future months'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'reset-buffer',
|
name: 'reset-buffer',
|
||||||
text: "Reset next month's buffer"
|
text: "Reset next month's buffer"
|
||||||
|
@ -220,6 +224,14 @@ function ToBudget({ month, prevMonthName, collapsed, onBudgetAction }) {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{state.menuOpen === 'buffer-future' && (
|
||||||
|
<HoldTooltip
|
||||||
|
onClose={() => setState({ menuOpen: null })}
|
||||||
|
onSubmit={amount => {
|
||||||
|
onBudgetAction(month, 'hold-all-future', { amount });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{state.menuOpen === 'transfer' && (
|
{state.menuOpen === 'transfer' && (
|
||||||
<TransferTooltip
|
<TransferTooltip
|
||||||
initialAmountName="leftover"
|
initialAmountName="leftover"
|
||||||
|
|
|
@ -330,6 +330,11 @@ class Budget extends React.Component {
|
||||||
case 3:
|
case 3:
|
||||||
this.onBudgetAction('set-3-avg');
|
this.onBudgetAction('set-3-avg');
|
||||||
break;
|
break;
|
||||||
|
case 4:
|
||||||
|
if (budgetType === 'report') {
|
||||||
|
this.onBudgetAction('set-all-future');
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue