Compare commits
147 commits
fix-aggreg
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
3edf947145 | ||
|
b34dfb15b2 | ||
|
8b1c5777ad | ||
|
94c195abb9 | ||
|
7c1c9bf03a | ||
|
8f7625831f | ||
|
15e2f2dce7 | ||
|
29fb2cc641 | ||
|
2566b950c2 | ||
|
ba71c1ba05 | ||
|
fcde52a9c7 | ||
|
94dbbbc68b | ||
|
16e01a8f58 | ||
|
a9218e1625 | ||
|
0a61acdf8f | ||
|
157b58a2dd | ||
|
7b6909eaa6 | ||
|
3133ddcda3 | ||
|
4904da5006 | ||
|
a72ee51e1a | ||
|
bf03dfc1cc | ||
|
a157679906 | ||
|
a4a7803407 | ||
|
2d9b319e45 | ||
|
4b83552ddf | ||
|
5f0da9deb8 | ||
|
e903f5c20d | ||
|
04aa1731b5 | ||
|
bb9c9927db | ||
|
696a094303 | ||
|
4421f2a173 | ||
|
f1b61cf6f1 | ||
|
6075e846d3 | ||
|
2857e65ccd | ||
|
29124f624b | ||
|
aa97994ad2 | ||
|
be3dc26166 | ||
|
9ce6f9564c | ||
|
12289792da | ||
|
c8e759fd49 | ||
|
2256653c16 | ||
|
182c77a8e3 | ||
|
de232b3ff0 | ||
|
a582975d71 | ||
|
93f0093c1d | ||
|
0e441eeed2 | ||
|
f190443272 | ||
|
603179dda1 | ||
|
fd3c0f9b18 | ||
|
d98b8c1d73 | ||
|
c9a543310d | ||
|
5a00bf6b43 | ||
|
9c0df36e16 | ||
|
dc53a74459 | ||
|
ecd91b8f8e | ||
|
4c0bd80f24 | ||
|
01d0eb2f0a | ||
|
0fcfffea57 | ||
|
4be86c3d42 | ||
|
9e7f94a237 | ||
|
f09f2dfe7b | ||
|
89128faf3f | ||
|
ea2ab1428d | ||
|
e638cdf467 | ||
|
d293613645 | ||
|
18e6eac116 | ||
|
ae8ef2674f | ||
|
b0ed8d5149 | ||
|
fecca411b0 | ||
|
5505a1439a | ||
|
55b9a0e7ef | ||
|
b552929b29 | ||
|
887df1e388 | ||
|
8e41d8d2dd | ||
|
3773ab9892 | ||
|
be6780f90b | ||
|
1d0b2721db | ||
|
677faa611d | ||
|
4f0bfe4a1f | ||
|
3ee7ae16cc | ||
|
01be80d562 | ||
|
d61457716e | ||
|
6f86bd77e8 | ||
|
d83c75d1ae | ||
|
40dbab3732 | ||
|
203ab791f2 | ||
|
c77273742b | ||
|
0e0b46ed5e | ||
|
3118cf26e3 | ||
|
2cedd68e69 | ||
|
b73ef9153f | ||
|
102d92048b | ||
|
9be15eaee1 | ||
|
e3ee0c61a6 | ||
|
c7a32ec8d0 | ||
|
a94def9c55 | ||
|
6d31a1cda9 | ||
|
31e2b01df3 | ||
|
7fa62b431c | ||
|
f7c977dc12 | ||
|
fc125712dd | ||
|
5a49d65b72 | ||
|
c40b5e4d5d | ||
|
973868c654 | ||
|
3f0addc78e | ||
|
16daa294b5 | ||
|
26ff01f4c9 | ||
|
e54b762e31 | ||
|
8f3e9d4b37 | ||
|
b230c52f92 | ||
|
db818f78fa | ||
|
57e0d713da | ||
|
8d0872c7a4 | ||
|
0c6304572c | ||
|
93a3543464 | ||
|
8a91006c7b | ||
|
0dcff8e671 | ||
|
6967698d32 | ||
|
fc4f120487 | ||
|
88590dccaa | ||
|
d705cd351b | ||
|
3e9cfece83 | ||
|
1fb6e193f0 | ||
|
2d9091f179 | ||
|
58a0910996 | ||
|
aa4d05ece6 | ||
|
2eb4408872 | ||
|
5c96635d79 | ||
|
5dad1070b6 | ||
|
b41ee56c81 | ||
|
ce5ee1b877 | ||
|
969901103f | ||
|
399aac7c91 | ||
|
2358c0875d | ||
|
90f7a205a6 | ||
|
a92e740c88 | ||
|
ac1e2b3c79 | ||
|
d30067b5b9 | ||
|
5977e020f0 | ||
|
a44834c0d3 | ||
|
55870be101 | ||
|
c1761b9302 | ||
|
91967ef920 | ||
|
c6335b4f57 | ||
|
2846166a8e | ||
|
a2b67cb153 | ||
|
c94749aace |
446 changed files with 27756 additions and 87525 deletions
|
@ -1,121 +0,0 @@
|
||||||
default_config: &default_config
|
|
||||||
environment:
|
|
||||||
SENTRY_ORG: shift-reset-llc
|
|
||||||
SENTRY_PROJECT: actual
|
|
||||||
YARN_CACHE_FOLDER: ~/.cache/yarn
|
|
||||||
CSC_LINK: ~/windows-shift-reset-llc.p12
|
|
||||||
|
|
||||||
cached_files: &cached_files
|
|
||||||
paths:
|
|
||||||
- ~/.cache/yarn
|
|
||||||
- node_modules
|
|
||||||
- ./packages/desktop-electron/node_modules
|
|
||||||
- ./packages/loot-core/node_modules
|
|
||||||
- ./mobile/node_modules
|
|
||||||
- ./import-ynab4/node_modules
|
|
||||||
- ./api/node_modules
|
|
||||||
- ./node-libofx/node_modules
|
|
||||||
- ./loot-design/node_modules
|
|
||||||
- ./desktop-client/node_modules
|
|
||||||
key: v3-dependencies-{{ checksum "yarn.lock" }}
|
|
||||||
|
|
||||||
version_tag_only: &version_tag_only
|
|
||||||
filters:
|
|
||||||
branches:
|
|
||||||
ignore: /.*/
|
|
||||||
tags:
|
|
||||||
only: /^\d+\.\d+\.\d+$/
|
|
||||||
|
|
||||||
version: 2.1
|
|
||||||
|
|
||||||
orbs:
|
|
||||||
win: circleci/windows@2.2.0
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
<<: *default_config
|
|
||||||
|
|
||||||
docker:
|
|
||||||
- image: circleci/node:16.15.0
|
|
||||||
|
|
||||||
working_directory: ~/repo
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
|
|
||||||
- restore_cache:
|
|
||||||
keys:
|
|
||||||
- v3-dependencies-{{ checksum "yarn.lock" }}
|
|
||||||
|
|
||||||
- run: yarn install --pure-lockfile
|
|
||||||
|
|
||||||
- save_cache:
|
|
||||||
<<: *cached_files
|
|
||||||
|
|
||||||
- run: yarn test
|
|
||||||
|
|
||||||
build_windows:
|
|
||||||
<<: *default_config
|
|
||||||
|
|
||||||
executor:
|
|
||||||
name: win/default
|
|
||||||
|
|
||||||
working_directory: ~/repo
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
|
|
||||||
- run:
|
|
||||||
command: npm install -g @sentry/cli --unsafe-perm
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- run:
|
|
||||||
command: echo $WINDOWS_CERT | base64 --decode >> ${HOME}/windows-shift-reset-llc.p12
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- run:
|
|
||||||
command: yarn install --pure-lockfile
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- run:
|
|
||||||
command: ./bin/package --release --version ${CIRCLE_TAG}
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
build_linux:
|
|
||||||
<<: *default_config
|
|
||||||
|
|
||||||
docker:
|
|
||||||
- image: circleci/node:16.15.0
|
|
||||||
|
|
||||||
working_directory: ~/repo
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
|
|
||||||
- restore_cache:
|
|
||||||
keys:
|
|
||||||
- v3-dependencies-{{ checksum "yarn.lock" }}
|
|
||||||
|
|
||||||
- run: yarn install --pure-lockfile
|
|
||||||
|
|
||||||
- run: sudo npm install -g @sentry/cli --unsafe-perm
|
|
||||||
|
|
||||||
- run: ./bin/package --release --version ${CIRCLE_TAG}
|
|
||||||
|
|
||||||
workflows:
|
|
||||||
version: 2
|
|
||||||
test:
|
|
||||||
jobs:
|
|
||||||
- test
|
|
||||||
build_version:
|
|
||||||
jobs:
|
|
||||||
- test:
|
|
||||||
<<: *version_tag_only
|
|
||||||
- build_windows:
|
|
||||||
<<: *version_tag_only
|
|
||||||
requires:
|
|
||||||
- test
|
|
||||||
- build_linux:
|
|
||||||
<<: *version_tag_only
|
|
||||||
requires:
|
|
||||||
- test
|
|
39
.eslintrc.js
Normal file
39
.eslintrc.js
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
module.exports = {
|
||||||
|
plugins: ['prettier', 'import'],
|
||||||
|
extends: ['react-app'],
|
||||||
|
rules: {
|
||||||
|
'prettier/prettier': 'error',
|
||||||
|
'no-unused-vars': 'off',
|
||||||
|
'no-loop-func': 'off',
|
||||||
|
'no-restricted-globals': 'off',
|
||||||
|
|
||||||
|
'import/no-useless-path-segments': 'error',
|
||||||
|
'import/order': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
alphabetize: {
|
||||||
|
caseInsensitive: true,
|
||||||
|
order: 'asc'
|
||||||
|
},
|
||||||
|
groups: [
|
||||||
|
'builtin', // Built-in types are first
|
||||||
|
'external',
|
||||||
|
['sibling', 'parent'], // Then sibling and parent types. They can be mingled together
|
||||||
|
'index' // Then the index file
|
||||||
|
],
|
||||||
|
'newlines-between': 'always',
|
||||||
|
pathGroups: [
|
||||||
|
// Enforce that React (and react-related packages) is the first import
|
||||||
|
{ group: 'builtin', pattern: 'react?(-*)', position: 'before' },
|
||||||
|
// Separate imports from Actual from "real" external imports
|
||||||
|
{
|
||||||
|
group: 'external',
|
||||||
|
pattern: 'loot-{core,design}/**/*',
|
||||||
|
position: 'after'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
pathGroupsExcludedImportTypes: ['react']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
77
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
77
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
name: Bug Report
|
||||||
|
description: File a bug report also known as an issue or problem.
|
||||||
|
title: '[Bug]: '
|
||||||
|
labels: ['bug', 'needs triage']
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
id: intro-md
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for taking the time to fill out this bug report! Please ensure you provide as much information as asked to better assist in confirming and identifying a fix for the bug report.
|
||||||
|
- type: dropdown
|
||||||
|
id: existing-issue
|
||||||
|
attributes:
|
||||||
|
label: 'Verified issue does not already exist?'
|
||||||
|
description: 'Please search to see if an issue already exists for the issue you encountered.'
|
||||||
|
options:
|
||||||
|
- 'I have searched and found no existing issue'
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: what-happened
|
||||||
|
attributes:
|
||||||
|
label: What happened?
|
||||||
|
description: Also tell us, what did you expect to happen?
|
||||||
|
placeholder: Tell us what you see!
|
||||||
|
value: 'A bug happened!'
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: errors-received
|
||||||
|
attributes:
|
||||||
|
label: 'What error did you receive?'
|
||||||
|
description: 'If you received an error or a message on the screen, please provide that here.'
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: markdown
|
||||||
|
id: env-info
|
||||||
|
attributes:
|
||||||
|
value: '## Environment Details'
|
||||||
|
- type: dropdown
|
||||||
|
id: hosting
|
||||||
|
attributes:
|
||||||
|
label: Where are you hosting Actual?
|
||||||
|
description: Where are you running your instance of Actual from?
|
||||||
|
options:
|
||||||
|
- Locally via Yarn
|
||||||
|
- Docker
|
||||||
|
- Fly.io
|
||||||
|
- NAS
|
||||||
|
- Other
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: dropdown
|
||||||
|
id: browsers
|
||||||
|
attributes:
|
||||||
|
label: What browsers are you seeing the problem on?
|
||||||
|
multiple: true
|
||||||
|
options:
|
||||||
|
- Firefox
|
||||||
|
- Chrome
|
||||||
|
- Safari
|
||||||
|
- Microsoft Edge
|
||||||
|
- Other
|
||||||
|
- type: dropdown
|
||||||
|
id: operating-system
|
||||||
|
attributes:
|
||||||
|
label: Operating System
|
||||||
|
description: What operating system are you using?
|
||||||
|
options:
|
||||||
|
- Windows 11
|
||||||
|
- Windows 10
|
||||||
|
- Mac OSX
|
||||||
|
- Linux
|
||||||
|
- Mobile Device
|
||||||
|
- Other
|
||||||
|
validations:
|
||||||
|
required: false
|
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: Feature Request?
|
||||||
|
url: https://github.com/actualbudget/actual/discussions/new?category=ideas
|
||||||
|
about: Website is hosted via GitHub Discussions under actualbudget/actual
|
2
.github/actions/setup/action.yml
vendored
2
.github/actions/setup/action.yml
vendored
|
@ -6,7 +6,7 @@ runs:
|
||||||
- name: Install node
|
- name: Install node
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 16.15.0
|
||||||
- name: Cache
|
- name: Cache
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
id: cache
|
id: cache
|
||||||
|
|
14
.github/workflows/opened-issues-triage.yml
vendored
Normal file
14
.github/workflows/opened-issues-triage.yml
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
name: Mark new issue for triage
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [opened]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
needs-triage:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions-ecosystem/action-add-labels@v1
|
||||||
|
with:
|
||||||
|
labels: needs triage
|
22
.github/workflows/stale.yml
vendored
Normal file
22
.github/workflows/stale.yml
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
name: Close inactive issues
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "30 1 * * *"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
close-issues:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v5
|
||||||
|
with:
|
||||||
|
days-before-issue-stale: 90
|
||||||
|
days-before-issue-close: -1
|
||||||
|
stale-issue-label: "stale"
|
||||||
|
stale-issue-message: "🚧🚨 This issue is being marked as stale due to 90 days of inactivity. 🚧🚨"
|
||||||
|
days-before-pr-stale: -1
|
||||||
|
days-before-pr-close: -1
|
||||||
|
only-labels: 'needs triage'
|
||||||
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
18
.github/workflows/test.yml
vendored
Normal file
18
.github/workflows/test.yml
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
name: Test
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request:
|
||||||
|
branches: '*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up environment
|
||||||
|
uses: ./.github/actions/setup
|
||||||
|
- name: Test
|
||||||
|
run: yarn test
|
9
.gitignore
vendored
9
.gitignore
vendored
|
@ -20,3 +20,12 @@ bundle.mobile.js.map
|
||||||
export-2020-01-10.csv
|
export-2020-01-10.csv
|
||||||
|
|
||||||
**/*.log
|
**/*.log
|
||||||
|
|
||||||
|
# Yarn
|
||||||
|
.pnp.*
|
||||||
|
.yarn/*
|
||||||
|
!.yarn/patches
|
||||||
|
!.yarn/plugins
|
||||||
|
!.yarn/releases
|
||||||
|
!.yarn/sdks
|
||||||
|
!.yarn/versions
|
||||||
|
|
4
.prettierrc.json
Normal file
4
.prettierrc.json
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "none"
|
||||||
|
}
|
28
.yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
vendored
Normal file
28
.yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
vendored
Normal file
File diff suppressed because one or more lines are too long
785
.yarn/releases/yarn-3.2.0.cjs
vendored
Executable file
785
.yarn/releases/yarn-3.2.0.cjs
vendored
Executable file
File diff suppressed because one or more lines are too long
7
.yarnrc.yml
Normal file
7
.yarnrc.yml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
nodeLinker: node-modules
|
||||||
|
|
||||||
|
plugins:
|
||||||
|
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
|
||||||
|
spec: "@yarnpkg/plugin-workspace-tools"
|
||||||
|
|
||||||
|
yarnPath: .yarn/releases/yarn-3.2.0.cjs
|
67
README.md
67
README.md
|
@ -1,72 +1,39 @@
|
||||||
This is the source code for [Actual](https://actualbudget.com), a local-first personal finance tool. It is 100% free and open-source.
|
## Getting Started
|
||||||
|
|
||||||
If you are only interested in running the latest version, you don't need this repo. You can get the latest version through npm.
|
Actual is a local-first personal finance tool. It is 100% free and open-source, written in NodeJS, it has a synchronization element so that all your changes can move between devices without any heavy lifting.
|
||||||
|
|
||||||
More docs are available in the [docs](https://github.com/actualbudget/actual/tree/master/docs) folder.
|
If you are interested in contributing, or want to know how development works, see [CONTRIBUTING.md](https://github.com/actualbudget/actual/blob/master/CONTRIBUTING.md) we would love to have you.
|
||||||
|
|
||||||
If you are interested in contributing, or want to know how development works, see [CONTRIBUTING.md](https://github.com/actualbudget/actual/blob/master/CONTRIBUTING.md)
|
Want to say thanks? Click the ⭐ at the top of the page.
|
||||||
|
|
||||||
Join the [discord](https://discord.gg/pRYNYr4W5A)!
|
## Key Links
|
||||||
|
|
||||||
|
* Actual [discord](https://discord.gg/pRYNYr4W5A) community.
|
||||||
|
* Actual [Community Documentation](https://actualbudget.github.io/docs)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
If you are only interested in running the latest version and not contributing to the source code, you don't need to clone this repo. You can get the latest version through npm.
|
||||||
|
|
||||||
|
**Please Note:** While the Actual repository holds source code for the mobile applications that were supported when Actual was closed source, these are no longer supported on the Open Source version of Actual.
|
||||||
|
|
||||||
### The easy way: using a server (recommended)
|
### The easy way: using a server (recommended)
|
||||||
|
|
||||||
The easiest way to get Actual running is to use the [actual-server](https://github.com/actualbudget/actual-server) project. That is the server for syncing changes across devices, and it comes with the latest version of Actual. The server will provide both the web project and a server for syncing.
|
The easiest way to get Actual running is to use the [actual-server](https://github.com/actualbudget/actual-server) project. That is the server for syncing changes across devices, and it comes with the latest version of Actual. The server will provide both the web project and a server for syncing.
|
||||||
|
|
||||||
```
|
You can get up and running quickly and easily by following our [Running Actual Locally Guide](https://actualbudget.github.io/docs/Installing/Local/your-own-machine)
|
||||||
git clone https://github.com/actualbudget/actual-server.git
|
|
||||||
cd actual-server
|
|
||||||
yarn install
|
|
||||||
yarn start
|
|
||||||
```
|
|
||||||
|
|
||||||
Navigate to https://localhost:5006 in your browser and you will see Actual.
|
## Documentation
|
||||||
|
|
||||||
You should deploy the server somewhere so you can access your data from anywhere. See instructions on the [actual-server](https://github.com/actualbudget/actual-server) repo.
|
We have a wide range of documentation on how to use Actual, this is all available in our [Community Documentation](https://actualbudget.github.io/docs), this includes topics on Budgeting, Account Management, Tips & Tricks and some documentation for developers.
|
||||||
|
|
||||||
### Without a server
|
|
||||||
|
|
||||||
This will give you a fully local web app without a server. This npm package is the `packages/desktop-client` package in this repo built for production:
|
|
||||||
|
|
||||||
```
|
|
||||||
yarn add @actual-app/web
|
|
||||||
```
|
|
||||||
|
|
||||||
Now you need to serve the files in `node_modules/@actual-app/web/build`. One way to do it:
|
|
||||||
|
|
||||||
```
|
|
||||||
cd node_modules/@actual-app/web/build
|
|
||||||
npx http-server .
|
|
||||||
```
|
|
||||||
|
|
||||||
Navigate to http://localhost:8080 and you should see Actual.
|
|
||||||
|
|
||||||
## Building
|
|
||||||
|
|
||||||
If you want to build the latest version, see [releasing.md](https://github.com/actualbudget/actual/blob/master/docs/releasing.md). It provides instructions for building this code into the same artifacts that come from npm.
|
|
||||||
|
|
||||||
## Run locally
|
|
||||||
|
|
||||||
Both the electron and web app can started with a single command. When running in development, it will store data in a `data` directory in the root of the `actual` directory.
|
|
||||||
|
|
||||||
First, make sure to run `yarn install` to install all dependencies.
|
|
||||||
|
|
||||||
In the root of the project:
|
|
||||||
|
|
||||||
```
|
|
||||||
yarn start # Run the electron app
|
|
||||||
yarn start:browser # Run the web app
|
|
||||||
```
|
|
||||||
|
|
||||||
## Code structure
|
## Code structure
|
||||||
|
|
||||||
The app is split up into a few packages:
|
The Actual app is split up into a few packages:
|
||||||
|
|
||||||
* loot-core - The core application that runs on any platform
|
* loot-core - The core application that runs on any platform
|
||||||
* loot-design - The generic design components that make up the UI
|
* loot-design - The generic design components that make up the UI
|
||||||
* desktop-client - The desktop UI
|
* desktop-client - The desktop UI
|
||||||
* desktop-electron - The desktop app
|
* desktop-electron - The desktop app
|
||||||
* mobile - The mobile app
|
|
||||||
|
|
||||||
More docs are available in the [docs](https://github.com/actualbudget/actual/tree/master/docs) folder.
|
More information on the project structure is available in our [community documentation](https://actualbudget.github.io/docs/Developers/project-layout).
|
||||||
|
|
21
bin/package
21
bin/package
|
@ -80,27 +80,14 @@ if [[ $CI != true && "$OSTYPE" == "darwin"* ]]; then
|
||||||
yarn lint
|
yarn lint
|
||||||
fi
|
fi
|
||||||
|
|
||||||
./node_modules/.bin/patch-package
|
yarn patch-package
|
||||||
|
|
||||||
(
|
yarn workspace mobile patch-package
|
||||||
cd packages/loot-design;
|
|
||||||
../../node_modules/.bin/patch-package
|
|
||||||
)
|
|
||||||
|
|
||||||
(
|
yarn workspace loot-core build:node
|
||||||
cd packages/mobile;
|
|
||||||
../../node_modules/.bin/patch-package
|
|
||||||
)
|
|
||||||
|
|
||||||
(
|
yarn workspace @actual-app/web build
|
||||||
cd packages/loot-core;
|
|
||||||
NODE_ENV=production yarn build:node
|
|
||||||
)
|
|
||||||
|
|
||||||
(
|
|
||||||
cd packages/desktop-client;
|
|
||||||
yarn build
|
|
||||||
)
|
|
||||||
|
|
||||||
rm -fr packages/desktop-electron/client-build
|
rm -fr packages/desktop-electron/client-build
|
||||||
cp -r packages/desktop-client/build packages/desktop-electron/client-build
|
cp -r packages/desktop-client/build packages/desktop-electron/client-build
|
||||||
|
|
|
@ -56,19 +56,8 @@ if [ $CI != true ]; then
|
||||||
yarn lint
|
yarn lint
|
||||||
fi
|
fi
|
||||||
|
|
||||||
(
|
ACTUAL_RELEASE_TYPE=$RELEASE yarn workspace loot-core build:browser
|
||||||
cd packages/loot-design;
|
|
||||||
../../node_modules/.bin/patch-package
|
|
||||||
)
|
|
||||||
|
|
||||||
(
|
REACT_APP_RELEASE_TYPE=$RELEASE yarn workspace @actual-app/web build:browser
|
||||||
cd packages/loot-core;
|
|
||||||
ACTUAL_RELEASE_TYPE=$RELEASE yarn build:browser
|
|
||||||
)
|
|
||||||
|
|
||||||
(
|
|
||||||
cd packages/desktop-client;
|
|
||||||
REACT_APP_RELEASE_TYPE=$RELEASE yarn build:browser
|
|
||||||
)
|
|
||||||
|
|
||||||
echo "packages/desktop-client/build"
|
echo "packages/desktop-client/build"
|
||||||
|
|
20
docs/API.md
20
docs/API.md
|
@ -1,20 +0,0 @@
|
||||||
|
|
||||||
Previous docs for the API are [here](https://actualbudget.com/docs/developers/using-the-API/). The API is currently being improved. Previously, the API connected to an existing running instance of Actual. Now the API is bundled and fully isolated, capable of running all of Actual itself. Setting up the API is different because of this.
|
|
||||||
|
|
||||||
You need to call `init` and pass it the directory where your files live. Call `load-budget` to load the file you want to work on. After that, you can use the same API as before.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```js
|
|
||||||
let actual = require('@actual-app/api');
|
|
||||||
|
|
||||||
await actual.init({
|
|
||||||
config: {
|
|
||||||
dataDir: join(__dirname, 'user-files')
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
await actual.internal.send('load-budget', { id: 'My-Finances' });
|
|
||||||
|
|
||||||
await actual.getAccounts();
|
|
||||||
```
|
|
|
@ -1,44 +0,0 @@
|
||||||
# How to cut a release
|
|
||||||
|
|
||||||
In the open-source version of Actual, all updates go through npm. There are two libraries:
|
|
||||||
|
|
||||||
* `@actual-app/api`: The API for the underlying functionality. This includes the entire backend of Actual, meant to be used with node.
|
|
||||||
* `@actual-app/web`: A web build that will serve the app with a web frontend. This includes both the frontend and backend of Actual. It includes the backend as well because it's built to be used as a Web Worker.
|
|
||||||
|
|
||||||
Both the API and web libraries are versioned together. This may change in the future, but because the web library also brings along its own backend it's easier to maintain a single version for now. That makes it clear which version the backend is regardless of library.
|
|
||||||
|
|
||||||
## Releasing `@actual-app/api`
|
|
||||||
|
|
||||||
This generates a bundle for the API:
|
|
||||||
|
|
||||||
```
|
|
||||||
cd packages/loot-core
|
|
||||||
yarn build:api
|
|
||||||
```
|
|
||||||
|
|
||||||
The built files live in `lib-dist`, so we need to copy them to the API package:
|
|
||||||
|
|
||||||
```
|
|
||||||
cp lib-dist/bundle.api* ../api/app
|
|
||||||
```
|
|
||||||
|
|
||||||
Next, bump the version on package.json. Finally, publish it:
|
|
||||||
|
|
||||||
```
|
|
||||||
npm publish
|
|
||||||
```
|
|
||||||
|
|
||||||
## Releasing `@actual-app/web`
|
|
||||||
|
|
||||||
In the root of `actual` (not just `desktop-client`), run this:
|
|
||||||
|
|
||||||
```
|
|
||||||
./bin/package-browser
|
|
||||||
```
|
|
||||||
|
|
||||||
This will compile both the backend and the frontend into a single directory in `packages/desktop-client/build`. This directory is all the files that need to be published. After bumping the version, publish `desktop-client`:
|
|
||||||
|
|
||||||
```
|
|
||||||
cd packages/desktop-client
|
|
||||||
npm publish
|
|
||||||
```
|
|
|
@ -1,24 +0,0 @@
|
||||||
const { join, resolve } = require('path');
|
|
||||||
const { createTransformer } = require('babel-jest');
|
|
||||||
const packagePath = resolve('./');
|
|
||||||
|
|
||||||
const packageGlob = join(packagePath, 'packages/*');
|
|
||||||
|
|
||||||
module.exports = createTransformer({
|
|
||||||
babelrcRoots: packageGlob,
|
|
||||||
|
|
||||||
// TODO: This is awful and a mess and we should fix it.
|
|
||||||
//
|
|
||||||
// Forcing this on allows certain packages in node_modules to be
|
|
||||||
// exported as ESM, which jest usually errors on. node_modules are
|
|
||||||
// usually not transformed, but you can allowlist one in the
|
|
||||||
// `jest.config.js` for your project like this:
|
|
||||||
//
|
|
||||||
// transformIgnorePatterns: [
|
|
||||||
// '/node_modules/(?!absurd-sql)'
|
|
||||||
// ],
|
|
||||||
//
|
|
||||||
// Without this explicit plugin, even though Jest transforms the
|
|
||||||
// module it won't recognize ESM
|
|
||||||
plugins: ['@babel/plugin-transform-modules-commonjs']
|
|
||||||
});
|
|
|
@ -1,9 +0,0 @@
|
||||||
const { join, resolve } = require('path');
|
|
||||||
const { createTransformer } = require('babel-jest');
|
|
||||||
const packagePath = resolve('./');
|
|
||||||
|
|
||||||
const packageGlob = join(packagePath, 'packages/*');
|
|
||||||
|
|
||||||
module.exports = createTransformer({
|
|
||||||
babelrcRoots: packageGlob
|
|
||||||
});
|
|
|
@ -1,8 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
projects: [
|
|
||||||
'<rootDir>/packages/loot-core',
|
|
||||||
'<rootDir>/packages/loot-core/jest.web.config.js',
|
|
||||||
'<rootDir>/packages/loot-design',
|
|
||||||
'<rootDir>/packages/loot-design/jest.rn.config.js'
|
|
||||||
]
|
|
||||||
};
|
|
67
package.json
67
package.json
|
@ -15,74 +15,39 @@
|
||||||
"workspaces": {
|
"workspaces": {
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
],
|
|
||||||
"nohoist": [
|
|
||||||
"**/better-sqlite3",
|
|
||||||
"**/better-sqlite3/**",
|
|
||||||
"mobile/react-native",
|
|
||||||
"mobile/react-native-*",
|
|
||||||
"mobile/rn-fetch-blob",
|
|
||||||
"mobile/**/event-target-shim",
|
|
||||||
"mobile/@sentry/react-native",
|
|
||||||
"mobile/nodejs-mobile-react-native",
|
|
||||||
"**/mobile/nodejs-mobile-react-native/**",
|
|
||||||
"**/@react-native-community/**",
|
|
||||||
"**/@react-navigation/**",
|
|
||||||
"mobile/react-navigation",
|
|
||||||
"mobile/react-navigation-tabs",
|
|
||||||
"mobile/rn-snoopy",
|
|
||||||
"mobile/rn-snoopy/**",
|
|
||||||
"mobile/detox",
|
|
||||||
"mobile/detox/**",
|
|
||||||
"mobile/jsc-android",
|
|
||||||
"mobile/jsc-android/**",
|
|
||||||
"**/react-native-web",
|
|
||||||
"**/react-native-web/**",
|
|
||||||
"**/@sentry/cli"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "npm-run-all --parallel start:desktop-*",
|
"start": "npm-run-all --parallel 'start:desktop-*'",
|
||||||
"start:desktop-node": "cd packages/loot-core && yarn watch:node",
|
"start:desktop-node": "yarn workspace loot-core watch:node",
|
||||||
"start:desktop-client": "cd packages/desktop-client && yarn watch",
|
"start:desktop-client": "yarn workspace @actual-app/web watch",
|
||||||
"start:desktop-electron": "cd packages/desktop-electron && yarn watch",
|
"start:desktop-electron": "yarn workspace Actual watch",
|
||||||
"start:browser": "npm-run-all --parallel start:browser-*",
|
"start:browser": "npm-run-all --parallel 'start:browser-*'",
|
||||||
"start:browser-backend": "cd packages/loot-core && yarn watch:browser",
|
"start:browser-backend": "yarn workspace loot-core watch:browser",
|
||||||
"start:browser-frontend": "cd packages/desktop-client && yarn start:browser",
|
"start:browser-frontend": "yarn workspace @actual-app/web start:browser",
|
||||||
"test": "./node_modules/.bin/jest --maxWorkers=4",
|
"test": "yarn workspaces foreach --parallel --verbose run test",
|
||||||
"test:debug": "node ./node_modules/.bin/jest --runInBand --useStderr",
|
"test:debug": "yarn workspaces foreach --verbose run test",
|
||||||
"test:debug-brk": "node --inspect-brk ./node_modules/.bin/jest --runInBand",
|
|
||||||
"rebuild-electron": "./node_modules/.bin/electron-rebuild -f -m ./packages/loot-core",
|
"rebuild-electron": "./node_modules/.bin/electron-rebuild -f -m ./packages/loot-core",
|
||||||
"rebuild-node": "cd packages/loot-core && npm rebuild",
|
"rebuild-node": "yarn workspace loot-core rebuild",
|
||||||
"lint": "cd packages/loot-core && yarn lint",
|
"lint": "yarn workspaces foreach --verbose run lint",
|
||||||
"postinstall": "rm -rf ./packages/loot-design/node_modules/react && rm -rf ./packages/mobile/node_modules/react && rm -rf ./node_modules/react-native && patch-package"
|
"postinstall": "rm -rf ./packages/loot-design/node_modules/react && rm -rf ./packages/mobile/node_modules/react && rm -rf ./node_modules/react-native && patch-package"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/plugin-transform-modules-commonjs": "^7.18.2",
|
|
||||||
"cross-env": "^5.1.5",
|
"cross-env": "^5.1.5",
|
||||||
"husky": "^3.0.4",
|
"husky": "^3.0.4",
|
||||||
"npm-run-all": "^4.1.3",
|
"npm-run-all": "^4.1.3",
|
||||||
|
"patch-package": "^6.1.2",
|
||||||
"prettier": "^1.18.1",
|
"prettier": "^1.18.1",
|
||||||
"pretty-quick": "^1.11.1",
|
"pretty-quick": "^1.11.1",
|
||||||
"shelljs": "^0.8.2",
|
"shelljs": "^0.8.2",
|
||||||
"source-map-support": "^0.5.21"
|
"source-map-support": "^0.5.21"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
|
||||||
"extends": "react-app",
|
|
||||||
"rules": {
|
|
||||||
"no-unused-vars": "off",
|
|
||||||
"no-loop-func": "off",
|
|
||||||
"no-restricted-globals": "off"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"prettier": {
|
|
||||||
"singleQuote": true,
|
|
||||||
"trailingComma": "none"
|
|
||||||
},
|
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"@babel/preset-env": "^7.15.1",
|
"@babel/preset-env": "^7.15.1",
|
||||||
"@babel/core": "^7.15.1",
|
"@babel/core": "^7.15.1",
|
||||||
"@babel/runtime": "^7.15.1",
|
"@babel/runtime": "^7.15.1",
|
||||||
"@babel/helper-plugin-utils": "^7.14.5"
|
"@babel/helper-plugin-utils": "^7.14.5",
|
||||||
}
|
"react-error-overlay": "6.0.9"
|
||||||
|
},
|
||||||
|
"packageManager": "yarn@3.2.0"
|
||||||
}
|
}
|
||||||
|
|
1
packages/api/.gitignore
vendored
Normal file
1
packages/api/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
app/bundle.api.js*
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,8 +1,7 @@
|
||||||
let bundle = require('./app/bundle.api.js');
|
let bundle = require('./app/bundle.api.js');
|
||||||
|
let injected = require('./injected');
|
||||||
let methods = require('./methods');
|
let methods = require('./methods');
|
||||||
let utils = require('./utils');
|
let utils = require('./utils');
|
||||||
|
|
||||||
let injected = require('./injected');
|
|
||||||
let actualApp;
|
let actualApp;
|
||||||
|
|
||||||
async function init({ budgetId, config } = {}) {
|
async function init({ budgetId, config } = {}) {
|
||||||
|
|
|
@ -1,9 +1,18 @@
|
||||||
{
|
{
|
||||||
"name": "@actual-app/api",
|
"name": "@actual-app/api",
|
||||||
"version": "4.0.2",
|
"version": "4.1.5",
|
||||||
"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,5 +1,5 @@
|
||||||
function amountToInteger(n) {
|
function amountToInteger(n) {
|
||||||
return Math.round(n * 100) | 0;
|
return Math.round(n * 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
function integerToAmount(n) {
|
function integerToAmount(n) {
|
||||||
|
|
|
@ -518,6 +518,10 @@ module.exports = function(webpackEnv) {
|
||||||
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
|
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
|
||||||
// You can remove this if you don't use Moment.js:
|
// You can remove this if you don't use Moment.js:
|
||||||
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
|
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
|
||||||
|
// Pikaday throws a warning if Moment.js is not installed however it doesn't
|
||||||
|
// actually require it to be installed. As we don't use Moment.js ourselves
|
||||||
|
// then we can just silence this warning.
|
||||||
|
new webpack.IgnorePlugin(/moment$/, /pikaday$/),
|
||||||
!(isEnvDevelopment || process.env.PERF_BUILD) &&
|
!(isEnvDevelopment || process.env.PERF_BUILD) &&
|
||||||
new webpack.IgnorePlugin(/perf-deets\/frontend/),
|
new webpack.IgnorePlugin(/perf-deets\/frontend/),
|
||||||
// Generate a service worker script that will precache, and keep up to date,
|
// Generate a service worker script that will precache, and keep up to date,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@actual-app/web",
|
"name": "@actual-app/web",
|
||||||
"version": "4.0.2",
|
"version": "22.12.03",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"files": [
|
"files": [
|
||||||
"build"
|
"build"
|
||||||
|
@ -14,7 +14,6 @@
|
||||||
"@reactions/component": "^2.0.2",
|
"@reactions/component": "^2.0.2",
|
||||||
"@sentry/browser": "6.12.0",
|
"@sentry/browser": "6.12.0",
|
||||||
"@svgr/webpack": "2.4.1",
|
"@svgr/webpack": "2.4.1",
|
||||||
"add": "^2.0.6",
|
|
||||||
"babel-eslint": "9.0.0",
|
"babel-eslint": "9.0.0",
|
||||||
"babel-loader": "8.0.4",
|
"babel-loader": "8.0.4",
|
||||||
"babel-preset-jwl-app": "6.1.12",
|
"babel-preset-jwl-app": "6.1.12",
|
||||||
|
@ -23,6 +22,7 @@
|
||||||
"case-sensitive-paths-webpack-plugin": "2.1.2",
|
"case-sensitive-paths-webpack-plugin": "2.1.2",
|
||||||
"chalk": "2.4.1",
|
"chalk": "2.4.1",
|
||||||
"codemirror": "^5.37.0",
|
"codemirror": "^5.37.0",
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
"css-loader": "1.0.0",
|
"css-loader": "1.0.0",
|
||||||
"date-fns": "2.0.0-alpha.27",
|
"date-fns": "2.0.0-alpha.27",
|
||||||
"debounce": "^1.2.0",
|
"debounce": "^1.2.0",
|
||||||
|
@ -32,8 +32,9 @@
|
||||||
"eslint-config-react-app": "3.0.5",
|
"eslint-config-react-app": "3.0.5",
|
||||||
"eslint-loader": "2.1.1",
|
"eslint-loader": "2.1.1",
|
||||||
"eslint-plugin-flowtype": "2.50.1",
|
"eslint-plugin-flowtype": "2.50.1",
|
||||||
"eslint-plugin-import": "2.14.0",
|
"eslint-plugin-import": "^2.26.0",
|
||||||
"eslint-plugin-jsx-a11y": "6.1.2",
|
"eslint-plugin-jsx-a11y": "6.1.2",
|
||||||
|
"eslint-plugin-prettier": "^3.1.4",
|
||||||
"eslint-plugin-react": "7.11.1",
|
"eslint-plugin-react": "7.11.1",
|
||||||
"file-loader": "2.0.0",
|
"file-loader": "2.0.0",
|
||||||
"focus-visible": "^4.1.1",
|
"focus-visible": "^4.1.1",
|
||||||
|
@ -41,10 +42,8 @@
|
||||||
"fs-extra": "7.0.0",
|
"fs-extra": "7.0.0",
|
||||||
"glamor": "^2.20.40",
|
"glamor": "^2.20.40",
|
||||||
"html-webpack-plugin": "4.0.0-alpha.2",
|
"html-webpack-plugin": "4.0.0-alpha.2",
|
||||||
"http-client": "^4.3.1",
|
|
||||||
"identity-obj-proxy": "3.0.0",
|
"identity-obj-proxy": "3.0.0",
|
||||||
"load-js": "^3.0.3",
|
"load-js": "^3.0.3",
|
||||||
"lodash.memoize": "^4.1.2",
|
|
||||||
"mini-css-extract-plugin": "0.4.3",
|
"mini-css-extract-plugin": "0.4.3",
|
||||||
"mitt": "^1.1.2",
|
"mitt": "^1.1.2",
|
||||||
"optimize-css-assets-webpack-plugin": "5.0.1",
|
"optimize-css-assets-webpack-plugin": "5.0.1",
|
||||||
|
@ -55,7 +54,6 @@
|
||||||
"postcss-preset-env": "6.3.1",
|
"postcss-preset-env": "6.3.1",
|
||||||
"postcss-safe-parser": "4.0.1",
|
"postcss-safe-parser": "4.0.1",
|
||||||
"prop-types": "15.6.0",
|
"prop-types": "15.6.0",
|
||||||
"raven-js": "^3.21.0",
|
|
||||||
"react": "16.13.1",
|
"react": "16.13.1",
|
||||||
"react-addons-shallow-compare": "^15.6.0",
|
"react-addons-shallow-compare": "^15.6.0",
|
||||||
"react-app-polyfill": "^0.1.3",
|
"react-app-polyfill": "^0.1.3",
|
||||||
|
@ -75,7 +73,6 @@
|
||||||
"sass-loader": "7.1.0",
|
"sass-loader": "7.1.0",
|
||||||
"style-loader": "0.23.0",
|
"style-loader": "0.23.0",
|
||||||
"terser-webpack-plugin": "1.1.0",
|
"terser-webpack-plugin": "1.1.0",
|
||||||
"url-loader": "1.1.1",
|
|
||||||
"victory": "^0.26.1",
|
"victory": "^0.26.1",
|
||||||
"webpack": "4.19.1",
|
"webpack": "4.19.1",
|
||||||
"webpack-dev-server": "3.11.0",
|
"webpack-dev-server": "3.11.0",
|
||||||
|
@ -85,10 +82,11 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "cross-env PORT=3001 node scripts/start.js",
|
"start": "cross-env PORT=3001 node scripts/start.js",
|
||||||
"start:browser": "./bin/watch-browser",
|
"start:browser": "cross-env ./bin/watch-browser",
|
||||||
"watch": "cross-env PORT=3001 node scripts/start.js",
|
"watch": "cross-env PORT=3001 node scripts/start.js",
|
||||||
"build": "cross-env INLINE_RUNTIME_CHUNK=false node scripts/build.js",
|
"build": "cross-env INLINE_RUNTIME_CHUNK=false node scripts/build.js",
|
||||||
"build:browser": "./bin/build-browser"
|
"build:browser": "cross-env ./bin/build-browser",
|
||||||
|
"lint": "eslint src"
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"electron 3.0"
|
"electron 3.0"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
default-db.sqlite
|
default-db.sqlite
|
||||||
|
migrations/.force-copy-windows
|
||||||
migrations/1548957970627_remove-db-version.sql
|
migrations/1548957970627_remove-db-version.sql
|
||||||
migrations/1550601598648_payees.sql
|
migrations/1550601598648_payees.sql
|
||||||
migrations/1555786194328_remove_category_group_unique.sql
|
migrations/1555786194328_remove_category_group_unique.sql
|
||||||
|
@ -14,4 +15,3 @@ migrations/1615745967948_meta.sql
|
||||||
migrations/1616167010796_accounts_order.sql
|
migrations/1616167010796_accounts_order.sql
|
||||||
migrations/1618975177358_schedules.sql
|
migrations/1618975177358_schedules.sql
|
||||||
migrations/1632571489012_remove_cache.js
|
migrations/1632571489012_remove_cache.js
|
||||||
migrations/.force-copy-windows
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { css } from 'glamor';
|
import { css } from 'glamor';
|
||||||
|
|
||||||
import { View } from 'loot-design/src/components/common';
|
import { View } from 'loot-design/src/components/common';
|
||||||
import Refresh from 'loot-design/src/svg/v1/Refresh';
|
import Refresh from 'loot-design/src/svg/v1/Refresh';
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,22 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { css } from 'glamor';
|
import { css } from 'glamor';
|
||||||
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
import {
|
import {
|
||||||
init as initConnection,
|
init as initConnection,
|
||||||
send
|
send
|
||||||
} from 'loot-core/src/platform/client/fetch';
|
} from 'loot-core/src/platform/client/fetch';
|
||||||
import installPolyfills from '../polyfills';
|
|
||||||
import { styles, hasHiddenScrollbars } from 'loot-design/src/style';
|
import { styles, hasHiddenScrollbars } from 'loot-design/src/style';
|
||||||
import FatalError from './FatalError';
|
|
||||||
import ManagementApp from './manager/ManagementApp';
|
import installPolyfills from '../polyfills';
|
||||||
import FinancesApp from './FinancesApp';
|
|
||||||
import AppBackground from './AppBackground';
|
import AppBackground from './AppBackground';
|
||||||
import UpdateNotification from './UpdateNotification';
|
import FatalError from './FatalError';
|
||||||
|
import FinancesApp from './FinancesApp';
|
||||||
|
import ManagementApp from './manager/ManagementApp';
|
||||||
import MobileWebMessage from './MobileWebMessage';
|
import MobileWebMessage from './MobileWebMessage';
|
||||||
|
import UpdateNotification from './UpdateNotification';
|
||||||
|
|
||||||
class App extends React.Component {
|
class App extends React.Component {
|
||||||
state = {
|
state = {
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import React, { useState } from 'react';
|
import React from 'react';
|
||||||
import { View, Block } from 'loot-design/src/components/common';
|
|
||||||
import { css } from 'glamor';
|
import { css } from 'glamor';
|
||||||
import Background from './Background';
|
|
||||||
import AnimatedLoading from 'loot-design/src/svg/v1/AnimatedLoading';
|
import { View, Block } from 'loot-design/src/components/common';
|
||||||
import { colors } from 'loot-design/src/style';
|
import { colors } from 'loot-design/src/style';
|
||||||
|
import AnimatedLoading from 'loot-design/src/svg/v1/AnimatedLoading';
|
||||||
|
|
||||||
|
import Background from './Background';
|
||||||
|
|
||||||
function AppBackground({ initializing, loadingText }) {
|
function AppBackground({ initializing, loadingText }) {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { css } from 'glamor';
|
import { css } from 'glamor';
|
||||||
|
|
||||||
import BG from './manager/bg.svg';
|
import BG from './manager/bg.svg';
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import React, { useState } from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { useTransition, animated } from 'react-spring';
|
import { useTransition, animated } from 'react-spring';
|
||||||
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
import { View, Text } from 'loot-design/src/components/common';
|
import { View, Text } from 'loot-design/src/components/common';
|
||||||
import { colors, styles } from 'loot-design/src/style';
|
import { colors, styles } from 'loot-design/src/style';
|
||||||
|
|
||||||
import AnimatedRefresh from './AnimatedRefresh';
|
import AnimatedRefresh from './AnimatedRefresh';
|
||||||
|
|
||||||
function BankSyncStatus({ accountsSyncing }) {
|
function BankSyncStatus({ accountsSyncing }) {
|
||||||
|
|
|
@ -9,14 +9,18 @@ function getFlex(flex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function Box({ flex, children, direction, style }) {
|
function Box({ flex, children, direction, style }) {
|
||||||
return <div
|
return (
|
||||||
|
<div
|
||||||
style={{
|
style={{
|
||||||
...style,
|
...style,
|
||||||
flex: getFlex(flex),
|
flex: getFlex(flex),
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: direction || 'column'
|
flexDirection: direction || 'column'
|
||||||
}}
|
}}
|
||||||
>{children}</div>;
|
>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Box;
|
export default Box;
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
import CodeMirror from 'codemirror';
|
||||||
|
|
||||||
|
import * as spreadsheet from 'loot-core/src/client/sheetql/spreadsheet';
|
||||||
import {
|
import {
|
||||||
send,
|
send,
|
||||||
init as initConnection
|
init as initConnection
|
||||||
} from 'loot-core/src/platform/client/fetch';
|
} from 'loot-core/src/platform/client/fetch';
|
||||||
import * as spreadsheet from 'loot-core/src/client/sheetql/spreadsheet';
|
|
||||||
import CodeMirror from 'codemirror';
|
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Button,
|
Button,
|
||||||
Input,
|
Input,
|
||||||
InlineField
|
InlineField
|
||||||
} from 'loot-design/src/components/common';
|
} from 'loot-design/src/components/common';
|
||||||
import { styles, colors } from 'loot-design/src/style';
|
import { colors } from 'loot-design/src/style';
|
||||||
|
|
||||||
require('codemirror/lib/codemirror.css');
|
require('codemirror/lib/codemirror.css');
|
||||||
require('codemirror/theme/monokai.css');
|
require('codemirror/theme/monokai.css');
|
||||||
|
@ -206,7 +207,7 @@ class Debugger extends React.Component {
|
||||||
height: 10,
|
height: 10,
|
||||||
backgroundColor: '#303030',
|
backgroundColor: '#303030',
|
||||||
marginRight: 10,
|
marginRight: 10,
|
||||||
borderRadius: 10,
|
borderRadius: 10
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Button onClick={this.toggleRecord} style={{ marginRight: 10 }}>
|
<Button onClick={this.toggleRecord} style={{ marginRight: 10 }}>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Stack,
|
Stack,
|
||||||
|
@ -99,7 +100,9 @@ class FatalError extends React.Component {
|
||||||
.
|
.
|
||||||
</P>
|
</P>
|
||||||
<P>
|
<P>
|
||||||
<Button onClick={() => window.Actual.relaunch()}>{buttonText}</Button>
|
<Button onClick={() => window.Actual.relaunch()}>
|
||||||
|
{buttonText}
|
||||||
|
</Button>
|
||||||
</P>
|
</P>
|
||||||
<P isLast={true} style={{ fontSize: 11 }}>
|
<P isLast={true} style={{ fontSize: 11 }}>
|
||||||
<Link
|
<Link
|
||||||
|
|
|
@ -1,40 +1,41 @@
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { Router, Route, Redirect, Switch, useLocation } from 'react-router-dom';
|
|
||||||
import { createBrowserHistory } from 'history';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { DndProvider } from 'react-dnd';
|
import { DndProvider } from 'react-dnd';
|
||||||
import Backend from 'react-dnd-html5-backend';
|
import Backend from 'react-dnd-html5-backend';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { Router, Route, Redirect, Switch, useLocation } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { createBrowserHistory } from 'history';
|
||||||
import hotkeys from 'hotkeys-js';
|
import hotkeys from 'hotkeys-js';
|
||||||
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
|
import { AccountsProvider } from 'loot-core/src/client/data-hooks/accounts';
|
||||||
|
import { PayeesProvider } from 'loot-core/src/client/data-hooks/payees';
|
||||||
import { SpreadsheetProvider } from 'loot-core/src/client/SpreadsheetProvider';
|
import { SpreadsheetProvider } from 'loot-core/src/client/SpreadsheetProvider';
|
||||||
import checkForUpgradeNotifications from 'loot-core/src/client/upgrade-notifications';
|
import checkForUpgradeNotifications from 'loot-core/src/client/upgrade-notifications';
|
||||||
import { colors } from 'loot-design/src/style';
|
|
||||||
import { View } from 'loot-design/src/components/common';
|
|
||||||
import BankSyncStatus from './BankSyncStatus';
|
|
||||||
import { BudgetMonthCountProvider } from 'loot-design/src/components/budget/BudgetMonthCountContext';
|
|
||||||
import * as undo from 'loot-core/src/platform/client/undo';
|
import * as undo from 'loot-core/src/platform/client/undo';
|
||||||
import { PageTypeProvider } from './Page';
|
import { BudgetMonthCountProvider } from 'loot-design/src/components/budget/BudgetMonthCountContext';
|
||||||
import { getLocationState } from '../util/location-state';
|
import { View } from 'loot-design/src/components/common';
|
||||||
import { ActiveLocationProvider } from './ActiveLocation';
|
import { colors } from 'loot-design/src/style';
|
||||||
import { makeLocationState } from '../util/location-state';
|
|
||||||
import { PayeesProvider } from 'loot-core/src/client/data-hooks/payees';
|
|
||||||
import { AccountsProvider } from 'loot-core/src/client/data-hooks/accounts';
|
|
||||||
|
|
||||||
import Titlebar, { TitlebarProvider } from './Titlebar';
|
import { getLocationState, makeLocationState } from '../util/location-state';
|
||||||
import FloatableSidebar, { SidebarProvider } from './FloatableSidebar';
|
|
||||||
import Account from './accounts/Account';
|
import Account from './accounts/Account';
|
||||||
|
import { ActiveLocationProvider } from './ActiveLocation';
|
||||||
|
import BankSyncStatus from './BankSyncStatus';
|
||||||
import Budget from './budget';
|
import Budget from './budget';
|
||||||
import Reports from './reports';
|
import FloatableSidebar, { SidebarProvider } from './FloatableSidebar';
|
||||||
import Schedules from './schedules';
|
import GlobalKeys from './GlobalKeys';
|
||||||
import EditSchedule from './schedules/EditSchedule';
|
|
||||||
import LinkSchedule from './schedules/LinkSchedule';
|
|
||||||
import DiscoverSchedules from './schedules/DiscoverSchedules';
|
|
||||||
import PostsOfflineNotification from './schedules/PostsOfflineNotification';
|
|
||||||
import FixSplitsTool from './tools/FixSplitsTool';
|
|
||||||
import Settings from './Settings';
|
|
||||||
import Modals from './Modals';
|
import Modals from './Modals';
|
||||||
import Notifications from './Notifications';
|
import Notifications from './Notifications';
|
||||||
import GlobalKeys from './GlobalKeys';
|
import { PageTypeProvider } from './Page';
|
||||||
|
import Reports from './reports';
|
||||||
|
import Schedules from './schedules';
|
||||||
|
import DiscoverSchedules from './schedules/DiscoverSchedules';
|
||||||
|
import EditSchedule from './schedules/EditSchedule';
|
||||||
|
import LinkSchedule from './schedules/LinkSchedule';
|
||||||
|
import PostsOfflineNotification from './schedules/PostsOfflineNotification';
|
||||||
|
import Settings from './Settings';
|
||||||
|
import Titlebar, { TitlebarProvider } from './Titlebar';
|
||||||
|
import FixSplitsTool from './tools/FixSplitsTool';
|
||||||
// import Debugger from './Debugger';
|
// import Debugger from './Debugger';
|
||||||
|
|
||||||
function URLBar() {
|
function URLBar() {
|
||||||
|
@ -277,7 +278,4 @@ function FinancesAppWithContext(props) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(
|
export default connect(null, actions)(FinancesAppWithContext);
|
||||||
null,
|
|
||||||
actions
|
|
||||||
)(FinancesAppWithContext);
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import React, { useState, useEffect, useContext } from 'react';
|
import React, { useState, useEffect, useContext } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { withRouter } from 'react-router-dom';
|
import { withRouter } from 'react-router-dom';
|
||||||
|
|
||||||
import mitt from 'mitt';
|
import mitt from 'mitt';
|
||||||
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
import { View } from 'loot-design/src/components/common';
|
import { View } from 'loot-design/src/components/common';
|
||||||
import { SIDEBAR_WIDTH } from 'loot-design/src/components/sidebar';
|
import { SIDEBAR_WIDTH } from 'loot-design/src/components/sidebar';
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { withRouter } from 'react-router-dom';
|
import { withRouter } from 'react-router-dom';
|
||||||
|
|
||||||
import Platform from 'loot-core/src/client/platform';
|
import Platform from 'loot-core/src/client/platform';
|
||||||
|
|
||||||
class GlobalKeys extends React.Component {
|
class GlobalKeys extends React.Component {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { withRouter } from 'react-router';
|
import { withRouter } from 'react-router';
|
||||||
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Text,
|
Text,
|
||||||
|
@ -11,7 +11,6 @@ import {
|
||||||
Menu
|
Menu
|
||||||
} from 'loot-design/src/components/common';
|
} from 'loot-design/src/components/common';
|
||||||
import { colors } from 'loot-design/src/style';
|
import { colors } from 'loot-design/src/style';
|
||||||
import ExclamationSolid from 'loot-design/src/svg/v1/ExclamationSolid';
|
|
||||||
|
|
||||||
function LoggedInUser({
|
function LoggedInUser({
|
||||||
history,
|
history,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Text,
|
Text,
|
||||||
|
|
|
@ -1,30 +1,31 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { bindActionCreators } from 'redux';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { Route, Switch } from 'react-router-dom';
|
import { Route, Switch } from 'react-router-dom';
|
||||||
import { createLocation } from 'history';
|
|
||||||
import Component from '@reactions/component';
|
import Component from '@reactions/component';
|
||||||
|
import { createLocation } from 'history';
|
||||||
|
import { bindActionCreators } from 'redux';
|
||||||
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
import { send, listen, unlisten } from 'loot-core/src/platform/client/fetch';
|
import { send, listen, unlisten } from 'loot-core/src/platform/client/fetch';
|
||||||
import { getModalRoute } from '../util';
|
|
||||||
|
|
||||||
import CreateAccount from './modals/CreateAccount';
|
|
||||||
import CreateLocalAccount from 'loot-design/src/components/modals/CreateLocalAccount';
|
|
||||||
import CloseAccount from 'loot-design/src/components/modals/CloseAccount';
|
import CloseAccount from 'loot-design/src/components/modals/CloseAccount';
|
||||||
import SelectLinkedAccounts from 'loot-design/src/components/modals/SelectLinkedAccounts';
|
|
||||||
import ConfigureLinkedAccounts from 'loot-design/src/components/modals/ConfigureLinkedAccounts';
|
import ConfigureLinkedAccounts from 'loot-design/src/components/modals/ConfigureLinkedAccounts';
|
||||||
import LoadBackup from 'loot-design/src/components/modals/LoadBackup';
|
import CreateLocalAccount from 'loot-design/src/components/modals/CreateLocalAccount';
|
||||||
import ManagePayeesWithData from './payees/ManagePayeesWithData';
|
|
||||||
import ManageRules from './modals/ManageRules';
|
|
||||||
import EditRule from './modals/EditRule';
|
|
||||||
import MergeUnusedPayees from './modals/MergeUnusedPayees';
|
|
||||||
import PlaidExternalMsg from 'loot-design/src/components/modals/PlaidExternalMsg';
|
|
||||||
import ConfirmCategoryDelete from './modals/ConfirmCategoryDelete';
|
|
||||||
import WelcomeScreen from './modals/WelcomeScreen';
|
|
||||||
import ImportTransactions from 'loot-design/src/components/modals/ImportTransactions';
|
|
||||||
import CreateEncryptionKey from './modals/CreateEncryptionKey';
|
|
||||||
import FixEncryptionKey from './modals/FixEncryptionKey';
|
|
||||||
import EditField from 'loot-design/src/components/modals/EditField';
|
import EditField from 'loot-design/src/components/modals/EditField';
|
||||||
|
import ImportTransactions from 'loot-design/src/components/modals/ImportTransactions';
|
||||||
|
import LoadBackup from 'loot-design/src/components/modals/LoadBackup';
|
||||||
|
import PlaidExternalMsg from 'loot-design/src/components/modals/PlaidExternalMsg';
|
||||||
|
import SelectLinkedAccounts from 'loot-design/src/components/modals/SelectLinkedAccounts';
|
||||||
|
|
||||||
|
import ConfirmCategoryDelete from './modals/ConfirmCategoryDelete';
|
||||||
|
import CreateAccount from './modals/CreateAccount';
|
||||||
|
import CreateEncryptionKey from './modals/CreateEncryptionKey';
|
||||||
|
import EditRule from './modals/EditRule';
|
||||||
|
import FixEncryptionKey from './modals/FixEncryptionKey';
|
||||||
|
import ManageRules from './modals/ManageRules';
|
||||||
|
import MergeUnusedPayees from './modals/MergeUnusedPayees';
|
||||||
|
import WelcomeScreen from './modals/WelcomeScreen';
|
||||||
|
import ManagePayeesWithData from './payees/ManagePayeesWithData';
|
||||||
|
|
||||||
function Modals({
|
function Modals({
|
||||||
history,
|
history,
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import React, { useState, useEffect, useMemo } from 'react';
|
import React, { useState, useEffect, useMemo } from 'react';
|
||||||
import { bindActionCreators } from 'redux';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { bindActionCreators } from 'redux';
|
||||||
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
|
@ -10,9 +12,9 @@ import {
|
||||||
Stack,
|
Stack,
|
||||||
ExternalLink
|
ExternalLink
|
||||||
} from 'loot-design/src/components/common';
|
} from 'loot-design/src/components/common';
|
||||||
|
import { styles, colors } from 'loot-design/src/style';
|
||||||
import Delete from 'loot-design/src/svg/Delete';
|
import Delete from 'loot-design/src/svg/Delete';
|
||||||
import Loading from 'loot-design/src/svg/v1/AnimatedLoading';
|
import Loading from 'loot-design/src/svg/v1/AnimatedLoading';
|
||||||
import { styles, colors } from 'loot-design/src/style';
|
|
||||||
|
|
||||||
function compileMessage(message, actions, setLoading, onRemove) {
|
function compileMessage(message, actions, setLoading, onRemove) {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
import { Modal, View, Text } from 'loot-design/src/components/common';
|
import { Modal, View, Text } from 'loot-design/src/components/common';
|
||||||
import { colors, styles } from 'loot-design/src/style';
|
import { styles } from 'loot-design/src/style';
|
||||||
|
|
||||||
let PageTypeContext = React.createContext({ type: 'page' });
|
let PageTypeContext = React.createContext({ type: 'page' });
|
||||||
|
|
||||||
|
|
|
@ -1,28 +1,23 @@
|
||||||
import React, { useState, useEffect, useRef } from 'react';
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
import { bindActionCreators } from 'redux';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { css } from 'glamor';
|
|
||||||
import { Route, Switch, Redirect } from 'react-router-dom';
|
import { Route, Switch, Redirect } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { css } from 'glamor';
|
||||||
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
|
import Platform from 'loot-core/src/client/platform';
|
||||||
|
import { send, listen } from 'loot-core/src/platform/client/fetch';
|
||||||
|
import { numberFormats } from 'loot-core/src/shared/util';
|
||||||
|
import { Information } from 'loot-design/src/components/alerts';
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Text,
|
Text,
|
||||||
Button,
|
Button,
|
||||||
ButtonLink,
|
|
||||||
ButtonWithLoading,
|
ButtonWithLoading,
|
||||||
AnchorLink,
|
AnchorLink
|
||||||
Link,
|
|
||||||
Input
|
|
||||||
} from 'loot-design/src/components/common';
|
} from 'loot-design/src/components/common';
|
||||||
import { send, listen } from 'loot-core/src/platform/client/fetch';
|
|
||||||
import { numberFormats } from 'loot-core/src/shared/util';
|
|
||||||
import { styles, colors } from 'loot-design/src/style';
|
import { styles, colors } from 'loot-design/src/style';
|
||||||
import { Information, Warning, Error } from 'loot-design/src/components/alerts';
|
|
||||||
import Checkmark from 'loot-design/src/svg/v1/Checkmark';
|
|
||||||
import CheveronDown from 'loot-design/src/svg/v1/CheveronDown';
|
|
||||||
import ExpandArrow from 'loot-design/src/svg/ExpandArrow';
|
import ExpandArrow from 'loot-design/src/svg/ExpandArrow';
|
||||||
import ExclamationSolid from 'loot-design/src/svg/v1/ExclamationSolid';
|
|
||||||
import Platform from 'loot-core/src/client/platform';
|
|
||||||
|
|
||||||
import useServerVersion from '../hooks/useServerVersion';
|
import useServerVersion from '../hooks/useServerVersion';
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,20 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { bindActionCreators } from 'redux';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { withRouter } from 'react-router-dom';
|
import { withRouter } from 'react-router-dom';
|
||||||
import { select } from 'glamor';
|
|
||||||
import lively from '@jlongster/lively';
|
import { bindActionCreators } from 'redux';
|
||||||
|
|
||||||
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
|
import * as queries from 'loot-core/src/client/queries';
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
import { send } from 'loot-core/src/platform/client/fetch';
|
||||||
import { styles, colors } from 'loot-design/src/style';
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Input,
|
Input,
|
||||||
InitialFocus,
|
InitialFocus,
|
||||||
View,
|
|
||||||
Text
|
Text
|
||||||
} from 'loot-design/src/components/common';
|
} from 'loot-design/src/components/common';
|
||||||
import { Sidebar } from 'loot-design/src/components/sidebar';
|
import { Sidebar } from 'loot-design/src/components/sidebar';
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import { styles, colors } from 'loot-design/src/style';
|
||||||
import * as queries from 'loot-core/src/client/queries';
|
|
||||||
|
|
||||||
function EditableBudgetName({ prefs, savePrefs }) {
|
function EditableBudgetName({ prefs, savePrefs }) {
|
||||||
const [editing, setEditing] = useState(false);
|
const [editing, setEditing] = useState(false);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React, { Component } from 'react';
|
import React from 'react';
|
||||||
import Cell from 'loot-design/src/components/spreadsheet/Cell';
|
|
||||||
import { View } from 'loot-design/src/components/common';
|
import { View } from 'loot-design/src/components/common';
|
||||||
|
import Cell from 'loot-design/src/components/spreadsheet/Cell';
|
||||||
|
|
||||||
function SpreadsheetInterface() {
|
function SpreadsheetInterface() {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,13 +1,3 @@
|
||||||
import React, { useState } from 'react';
|
|
||||||
import {
|
|
||||||
View,
|
|
||||||
Text,
|
|
||||||
Stack,
|
|
||||||
Button,
|
|
||||||
ButtonWithLoading
|
|
||||||
} from 'loot-design/src/components/common';
|
|
||||||
import { colors } from 'loot-design/src/style';
|
|
||||||
|
|
||||||
export function RepairSyncNotification() {}
|
export function RepairSyncNotification() {}
|
||||||
|
|
||||||
// TODO: sync button shouldn't show error status if it's a local file
|
// TODO: sync button shouldn't show error status if it's a local file
|
||||||
|
|
|
@ -1,17 +1,11 @@
|
||||||
import React, {
|
import React, { useState, useEffect, useRef, useContext } from 'react';
|
||||||
useState,
|
|
||||||
useEffect,
|
|
||||||
useRef,
|
|
||||||
useCallback,
|
|
||||||
useContext
|
|
||||||
} from 'react';
|
|
||||||
import { Switch, Route, withRouter } from 'react-router-dom';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import { Switch, Route, withRouter } from 'react-router-dom';
|
||||||
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
|
import Platform from 'loot-core/src/client/platform';
|
||||||
import * as queries from 'loot-core/src/client/queries';
|
import * as queries from 'loot-core/src/client/queries';
|
||||||
import { listen } from 'loot-core/src/platform/client/fetch';
|
import { listen } from 'loot-core/src/platform/client/fetch';
|
||||||
import Platform from 'loot-core/src/client/platform';
|
|
||||||
import { colors } from 'loot-design/src/style';
|
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Text,
|
Text,
|
||||||
|
@ -22,15 +16,17 @@ import {
|
||||||
P
|
P
|
||||||
} from 'loot-design/src/components/common';
|
} from 'loot-design/src/components/common';
|
||||||
import SheetValue from 'loot-design/src/components/spreadsheet/SheetValue';
|
import SheetValue from 'loot-design/src/components/spreadsheet/SheetValue';
|
||||||
import { MonthCountSelector } from './budget/MonthCountSelector';
|
import { colors } from 'loot-design/src/style';
|
||||||
import ArrowButtonRight1 from 'loot-design/src/svg/v2/ArrowButtonRight1';
|
|
||||||
import NavigationMenu from 'loot-design/src/svg/v2/NavigationMenu';
|
|
||||||
import ArrowLeft from 'loot-design/src/svg/v1/ArrowLeft';
|
import ArrowLeft from 'loot-design/src/svg/v1/ArrowLeft';
|
||||||
import AlertTriangle from 'loot-design/src/svg/v2/AlertTriangle';
|
import AlertTriangle from 'loot-design/src/svg/v2/AlertTriangle';
|
||||||
|
import ArrowButtonRight1 from 'loot-design/src/svg/v2/ArrowButtonRight1';
|
||||||
|
import NavigationMenu from 'loot-design/src/svg/v2/NavigationMenu';
|
||||||
|
|
||||||
import AccountSyncCheck from './accounts/AccountSyncCheck';
|
import AccountSyncCheck from './accounts/AccountSyncCheck';
|
||||||
import LoggedInUser from './LoggedInUser';
|
|
||||||
import AnimatedRefresh from './AnimatedRefresh';
|
import AnimatedRefresh from './AnimatedRefresh';
|
||||||
|
import { MonthCountSelector } from './budget/MonthCountSelector';
|
||||||
import { useSidebar } from './FloatableSidebar';
|
import { useSidebar } from './FloatableSidebar';
|
||||||
|
import LoggedInUser from './LoggedInUser';
|
||||||
|
|
||||||
export let TitlebarContext = React.createContext();
|
export let TitlebarContext = React.createContext();
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,23 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { bindActionCreators } from 'redux';
|
import { bindActionCreators } from 'redux';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
import { View } from 'loot-design/src/components/common';
|
|
||||||
import { colors } from 'loot-design/src/style';
|
|
||||||
import Intro from './tutorial/Intro';
|
|
||||||
import BudgetSummary from './tutorial/BudgetSummary';
|
|
||||||
import BudgetCategories from './tutorial/BudgetCategories';
|
import BudgetCategories from './tutorial/BudgetCategories';
|
||||||
import BudgetInitial from './tutorial/BudgetInitial';
|
import BudgetInitial from './tutorial/BudgetInitial';
|
||||||
|
import BudgetNewIncome from './tutorial/BudgetNewIncome';
|
||||||
|
import BudgetNextMonth from './tutorial/BudgetNextMonth';
|
||||||
|
import BudgetSummary from './tutorial/BudgetSummary';
|
||||||
|
import CategoryBalance from './tutorial/CategoryBalance';
|
||||||
|
import Final from './tutorial/Final';
|
||||||
|
import Intro from './tutorial/Intro';
|
||||||
|
import Overspending from './tutorial/Overspending';
|
||||||
import TransactionAdd from './tutorial/TransactionAdd';
|
import TransactionAdd from './tutorial/TransactionAdd';
|
||||||
import TransactionEnter from './tutorial/TransactionEnter';
|
import TransactionEnter from './tutorial/TransactionEnter';
|
||||||
import TransactionFinalize from './tutorial/TransactionFinalize';
|
|
||||||
import BudgetNewIncome from './tutorial/BudgetNewIncome';
|
|
||||||
import CategoryBalance from './tutorial/CategoryBalance';
|
|
||||||
import Overspending from './tutorial/Overspending';
|
|
||||||
import BudgetNextMonth from './tutorial/BudgetNextMonth';
|
|
||||||
import DeleteTransactions from './tutorial/DeleteTransactions';
|
|
||||||
import Final from './tutorial/Final';
|
|
||||||
|
|
||||||
function generatePath(innerRect, outerRect) {
|
function generatePath(innerRect, outerRect) {
|
||||||
const i = innerRect;
|
const i = innerRect;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import lively from '@jlongster/lively';
|
|
||||||
|
|
||||||
class Tutorial extends React.Component {
|
class Tutorial extends React.Component {
|
||||||
static childContextTypes = {
|
static childContextTypes = {
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { bindActionCreators } from 'redux';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { bindActionCreators } from 'redux';
|
||||||
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
import {
|
import { View, Text, Link, Button } from 'loot-design/src/components/common';
|
||||||
View,
|
|
||||||
Text,
|
|
||||||
Block,
|
|
||||||
Link,
|
|
||||||
Button
|
|
||||||
} from 'loot-design/src/components/common';
|
|
||||||
import { colors } from 'loot-design/src/style';
|
import { colors } from 'loot-design/src/style';
|
||||||
import Close from 'loot-design/src/svg/v1/Close';
|
import Close from 'loot-design/src/svg/v1/Close';
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,28 @@
|
||||||
import React, {
|
import React, { useState, useEffect, useRef, useMemo } from 'react';
|
||||||
useState,
|
|
||||||
useLayoutEffect,
|
|
||||||
useEffect,
|
|
||||||
useRef,
|
|
||||||
useMemo,
|
|
||||||
useReducer,
|
|
||||||
useCallback
|
|
||||||
} from 'react';
|
|
||||||
import { bindActionCreators } from 'redux';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { useSelector, useDispatch } from 'react-redux';
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
import {
|
import { Redirect, useParams, useHistory, useLocation } from 'react-router-dom';
|
||||||
Redirect,
|
|
||||||
withRouter,
|
|
||||||
useParams,
|
|
||||||
useHistory,
|
|
||||||
useLocation
|
|
||||||
} from 'react-router-dom';
|
|
||||||
import { css } from 'glamor';
|
|
||||||
import Modal from 'react-modal';
|
|
||||||
import Component from '@reactions/component';
|
|
||||||
import { debounce } from 'debounce';
|
import { debounce } from 'debounce';
|
||||||
import SpreadsheetContext from 'loot-design/src/components/spreadsheet/SpreadsheetContext';
|
import { bindActionCreators } from 'redux';
|
||||||
import { send, listen } from 'loot-core/src/platform/client/fetch';
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
|
import {
|
||||||
|
SchedulesProvider,
|
||||||
|
useCachedSchedules
|
||||||
|
} from 'loot-core/src/client/data-hooks/schedules';
|
||||||
|
import * as queries from 'loot-core/src/client/queries';
|
||||||
|
import q, { runQuery, pagedQuery } from 'loot-core/src/client/query-helpers';
|
||||||
|
import { send, listen } from 'loot-core/src/platform/client/fetch';
|
||||||
|
import {
|
||||||
|
deleteTransaction,
|
||||||
|
updateTransaction,
|
||||||
|
ungroupTransactions
|
||||||
|
} from 'loot-core/src/shared/transactions';
|
||||||
|
import {
|
||||||
|
currencyToInteger,
|
||||||
|
applyChanges,
|
||||||
|
groupById
|
||||||
|
} from 'loot-core/src/shared/util';
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Text,
|
Text,
|
||||||
|
@ -33,63 +32,40 @@ import {
|
||||||
InitialFocus,
|
InitialFocus,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Menu,
|
Menu,
|
||||||
Block,
|
|
||||||
Stack
|
Stack
|
||||||
} from 'loot-design/src/components/common';
|
} from 'loot-design/src/components/common';
|
||||||
import {
|
import { KeyHandlers } from 'loot-design/src/components/KeyHandlers';
|
||||||
currencyToInteger,
|
import NotesButton from 'loot-design/src/components/NotesButton';
|
||||||
applyChanges,
|
import CellValue from 'loot-design/src/components/spreadsheet/CellValue';
|
||||||
groupById
|
|
||||||
} from 'loot-core/src/shared/util';
|
|
||||||
import * as monthUtils from 'loot-core/src/shared/months';
|
|
||||||
import TutorialPoint from 'loot-design/src/components/TutorialPoint';
|
|
||||||
import DotsHorizontalTriple from 'loot-design/src/svg/v1/DotsHorizontalTriple';
|
|
||||||
import Pencil1 from 'loot-design/src/svg/v2/Pencil1';
|
|
||||||
import SearchAlternate from 'loot-design/src/svg/v2/SearchAlternate';
|
|
||||||
import DownloadThickBottom from 'loot-design/src/svg/v2/DownloadThickBottom';
|
|
||||||
import AnimatedRefresh from '../AnimatedRefresh';
|
|
||||||
import Add from 'loot-design/src/svg/v1/Add';
|
|
||||||
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';
|
||||||
import CellValue from 'loot-design/src/components/spreadsheet/CellValue';
|
import { SelectedItemsButton } from 'loot-design/src/components/table';
|
||||||
import ArrowButtonRight1 from 'loot-design/src/svg/v2/ArrowButtonRight1';
|
import {
|
||||||
import CheveronDown from 'loot-design/src/svg/v1/CheveronDown';
|
SelectedProviderWithItems,
|
||||||
import CheckCircle1 from 'loot-design/src/svg/v2/CheckCircle1';
|
useSelectedItems
|
||||||
|
} from 'loot-design/src/components/useSelected';
|
||||||
|
import { styles, colors } from 'loot-design/src/style';
|
||||||
|
import Add from 'loot-design/src/svg/v1/Add';
|
||||||
import Loading from 'loot-design/src/svg/v1/AnimatedLoading';
|
import Loading from 'loot-design/src/svg/v1/AnimatedLoading';
|
||||||
|
import DotsHorizontalTriple from 'loot-design/src/svg/v1/DotsHorizontalTriple';
|
||||||
|
import ArrowButtonRight1 from 'loot-design/src/svg/v2/ArrowButtonRight1';
|
||||||
import ArrowsExpand3 from 'loot-design/src/svg/v2/ArrowsExpand3';
|
import ArrowsExpand3 from 'loot-design/src/svg/v2/ArrowsExpand3';
|
||||||
import ArrowsShrink3 from 'loot-design/src/svg/v2/ArrowsShrink3';
|
import ArrowsShrink3 from 'loot-design/src/svg/v2/ArrowsShrink3';
|
||||||
import * as queries from 'loot-core/src/client/queries';
|
import CheckCircle1 from 'loot-design/src/svg/v2/CheckCircle1';
|
||||||
import q, { runQuery, pagedQuery } from 'loot-core/src/client/query-helpers';
|
import DownloadThickBottom from 'loot-design/src/svg/v2/DownloadThickBottom';
|
||||||
import { queryContext } from 'loot-core/src/client/query-hooks';
|
import Pencil1 from 'loot-design/src/svg/v2/Pencil1';
|
||||||
import { SelectedItemsButton } from 'loot-design/src/components/table';
|
import SearchAlternate from 'loot-design/src/svg/v2/SearchAlternate';
|
||||||
import { Query } from 'loot-core/src/shared/query';
|
|
||||||
import * as aql from 'loot-core/src/client/query-helpers';
|
import { authorizeBank } from '../../plaid';
|
||||||
import {
|
import { useActiveLocation } from '../ActiveLocation';
|
||||||
deleteTransaction,
|
import AnimatedRefresh from '../AnimatedRefresh';
|
||||||
updateTransaction,
|
import { FilterButton, AppliedFilters } from './Filters';
|
||||||
ungroupTransactions
|
import TransactionList from './TransactionList';
|
||||||
} from 'loot-core/src/shared/transactions';
|
|
||||||
import {
|
import {
|
||||||
SplitsExpandedProvider,
|
SplitsExpandedProvider,
|
||||||
useSplitsExpanded,
|
useSplitsExpanded,
|
||||||
isPreviewId
|
isPreviewId
|
||||||
} from './TransactionsTable';
|
} from './TransactionsTable';
|
||||||
import { styles, colors } from 'loot-design/src/style';
|
|
||||||
import TransactionList from './TransactionList';
|
|
||||||
import { authorizeBank } from '../../plaid';
|
|
||||||
import {
|
|
||||||
SelectedProviderWithItems,
|
|
||||||
useSelectedItems
|
|
||||||
} from 'loot-design/src/components/useSelected';
|
|
||||||
import { keys } from 'loot-design/src/util/keys';
|
|
||||||
import { KeyHandlers } from 'loot-design/src/components/KeyHandlers';
|
|
||||||
import { FilterButton, AppliedFilters } from './Filters';
|
|
||||||
import {
|
|
||||||
SchedulesProvider,
|
|
||||||
useCachedSchedules
|
|
||||||
} from 'loot-core/src/client/data-hooks/schedules';
|
|
||||||
import { getPayeesById } from 'loot-core/src/client/reducers/queries';
|
|
||||||
import { useActiveLocation } from '../ActiveLocation';
|
|
||||||
|
|
||||||
function EmptyMessage({ onAdd }) {
|
function EmptyMessage({ onAdd }) {
|
||||||
return (
|
return (
|
||||||
|
@ -131,6 +107,7 @@ function EmptyMessage({ onAdd }) {
|
||||||
function ReconcilingMessage({ balanceQuery, targetBalance, onDone }) {
|
function ReconcilingMessage({ balanceQuery, targetBalance, onDone }) {
|
||||||
let cleared = useSheetValue({
|
let cleared = useSheetValue({
|
||||||
name: balanceQuery.name + '-cleared',
|
name: balanceQuery.name + '-cleared',
|
||||||
|
value: 0,
|
||||||
query: balanceQuery.query.filter({ cleared: true })
|
query: balanceQuery.query.filter({ cleared: true })
|
||||||
});
|
});
|
||||||
let targetDiff = targetBalance - cleared;
|
let targetDiff = targetBalance - cleared;
|
||||||
|
@ -642,7 +619,7 @@ const AccountHeader = React.memo(
|
||||||
let searchInput = useRef(null);
|
let searchInput = useRef(null);
|
||||||
let splitsExpanded = useSplitsExpanded();
|
let splitsExpanded = useSplitsExpanded();
|
||||||
|
|
||||||
let canSync = syncEnabled && (account && account.account_id);
|
let canSync = syncEnabled && account && account.account_id;
|
||||||
if (!account) {
|
if (!account) {
|
||||||
// All accounts - check for any syncable account
|
// All accounts - check for any syncable account
|
||||||
canSync = !!accounts.find(account => !!account.account_id);
|
canSync = !!accounts.find(account => !!account.account_id);
|
||||||
|
@ -694,30 +671,46 @@ const AccountHeader = React.memo(
|
||||||
/>
|
/>
|
||||||
</InitialFocus>
|
</InitialFocus>
|
||||||
) : isNameEditable ? (
|
) : isNameEditable ? (
|
||||||
<Button
|
<View
|
||||||
bare
|
style={{
|
||||||
|
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,
|
||||||
marginLeft: -5,
|
marginRight: 5,
|
||||||
marginTop: -5,
|
marginBottom: 5
|
||||||
backgroundColor: 'transparent',
|
|
||||||
'& svg': { display: 'none' },
|
|
||||||
'&:hover svg': { display: 'unset' }
|
|
||||||
}}
|
}}
|
||||||
onClick={() => onExposeName(true)}
|
|
||||||
>
|
>
|
||||||
{accountName}
|
{accountName}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<NotesButton id={`account-${account.id}`} />
|
||||||
|
<Button
|
||||||
|
bare
|
||||||
|
className="hover-visible"
|
||||||
|
onClick={() => onExposeName(true)}
|
||||||
|
>
|
||||||
<Pencil1
|
<Pencil1
|
||||||
style={{
|
style={{
|
||||||
width: 11,
|
width: 11,
|
||||||
height: 11,
|
height: 11,
|
||||||
marginLeft: 5,
|
color: colors.n8
|
||||||
color: colors.n4
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
|
</View>
|
||||||
) : (
|
) : (
|
||||||
<View
|
<View
|
||||||
style={{ fontSize: 25, fontWeight: 500, marginBottom: 5 }}
|
style={{ fontSize: 25, fontWeight: 500, marginBottom: 5 }}
|
||||||
|
@ -1701,9 +1694,9 @@ class AccountInternal extends React.PureComponent {
|
||||||
}
|
}
|
||||||
showAccount={
|
showAccount={
|
||||||
!accountId ||
|
!accountId ||
|
||||||
(accountId === 'offbudget' ||
|
accountId === 'offbudget' ||
|
||||||
accountId === 'budgeted' ||
|
accountId === 'budgeted' ||
|
||||||
accountId === 'uncategorized')
|
accountId === 'uncategorized'
|
||||||
}
|
}
|
||||||
isAdding={this.state.isAdding}
|
isAdding={this.state.isAdding}
|
||||||
isNew={this.isNew}
|
isNew={this.isNew}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Route, withRouter } from 'react-router-dom';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
import { View, Text, Button, Tooltip } from 'loot-design/src/components/common';
|
import { View, Button, Tooltip } from 'loot-design/src/components/common';
|
||||||
import ExclamationOutline from 'loot-design/src/svg/v1/ExclamationOutline';
|
|
||||||
import { colors } from 'loot-design/src/style';
|
import { colors } from 'loot-design/src/style';
|
||||||
|
import ExclamationOutline from 'loot-design/src/svg/v1/ExclamationOutline';
|
||||||
|
|
||||||
import { reauthorizeBank } from '../../plaid';
|
import { reauthorizeBank } from '../../plaid';
|
||||||
|
|
||||||
function getErrorMessage(type, code) {
|
function getErrorMessage(type, code) {
|
||||||
|
|
|
@ -1,24 +1,15 @@
|
||||||
import React, { useState, useRef, useEffect, useReducer } from 'react';
|
import React, { useState, useRef, useEffect, useReducer } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import scopeTab from 'react-modal/lib/helpers/scopeTab';
|
|
||||||
import {
|
import {
|
||||||
parse as parseDate,
|
parse as parseDate,
|
||||||
format as formatDate,
|
format as formatDate,
|
||||||
isValid as isDateValid
|
isValid as isDateValid
|
||||||
} from 'date-fns';
|
} from 'date-fns';
|
||||||
|
import scopeTab from 'react-modal/lib/helpers/scopeTab';
|
||||||
|
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
import { send } from 'loot-core/src/platform/client/fetch';
|
||||||
import { getMonthYearFormat } from 'loot-core/src/shared/months';
|
import { getMonthYearFormat } from 'loot-core/src/shared/months';
|
||||||
import { titleFirst } from 'loot-core/src/shared/util';
|
|
||||||
import {
|
|
||||||
View,
|
|
||||||
Text,
|
|
||||||
Tooltip,
|
|
||||||
Stack,
|
|
||||||
Button,
|
|
||||||
InitialFocus,
|
|
||||||
Menu,
|
|
||||||
CustomSelect
|
|
||||||
} from 'loot-design/src/components/common';
|
|
||||||
import {
|
import {
|
||||||
mapField,
|
mapField,
|
||||||
friendlyOp,
|
friendlyOp,
|
||||||
|
@ -29,11 +20,22 @@ import {
|
||||||
FIELD_TYPES,
|
FIELD_TYPES,
|
||||||
TYPE_INFO
|
TYPE_INFO
|
||||||
} from 'loot-core/src/shared/rules';
|
} from 'loot-core/src/shared/rules';
|
||||||
|
import { titleFirst } from 'loot-core/src/shared/util';
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
Tooltip,
|
||||||
|
Stack,
|
||||||
|
Button,
|
||||||
|
Menu,
|
||||||
|
CustomSelect
|
||||||
|
} from 'loot-design/src/components/common';
|
||||||
|
import { colors } from 'loot-design/src/style';
|
||||||
import DeleteIcon from 'loot-design/src/svg/Delete';
|
import DeleteIcon from 'loot-design/src/svg/Delete';
|
||||||
import SettingsSliderAlternate from 'loot-design/src/svg/v2/SettingsSliderAlternate';
|
import SettingsSliderAlternate from 'loot-design/src/svg/v2/SettingsSliderAlternate';
|
||||||
import GenericInput from '../util/GenericInput';
|
|
||||||
import { Value } from '../modals/ManageRules';
|
import { Value } from '../modals/ManageRules';
|
||||||
import { styles, colors } from 'loot-design/src/style';
|
import GenericInput from '../util/GenericInput';
|
||||||
|
|
||||||
let filterFields = [
|
let filterFields = [
|
||||||
'date',
|
'date',
|
||||||
|
@ -149,7 +151,11 @@ function ConfigureField({ field, op, value, dispatch, onApply }) {
|
||||||
['amount-outflow', 'Amount (outflow)']
|
['amount-outflow', 'Amount (outflow)']
|
||||||
]
|
]
|
||||||
: field === 'date'
|
: field === 'date'
|
||||||
? [['date', 'Date'], ['month', 'Month'], ['year', 'Year']]
|
? [
|
||||||
|
['date', 'Date'],
|
||||||
|
['month', 'Month'],
|
||||||
|
['year', 'Year']
|
||||||
|
]
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
value={subfield}
|
value={subfield}
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
import React, { useMemo, useCallback } from 'react';
|
import React, { useMemo, useCallback } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
format as formatDate,
|
format as formatDate,
|
||||||
parse as parseDate,
|
|
||||||
parseISO,
|
parseISO,
|
||||||
isValid as isDateValid
|
isValid as isDateValid
|
||||||
} from 'date-fns';
|
} from 'date-fns';
|
||||||
|
|
||||||
|
import {
|
||||||
|
getAccountsById,
|
||||||
|
getCategoriesById
|
||||||
|
} from 'loot-core/src/client/reducers/queries';
|
||||||
|
import { integerToCurrency } from 'loot-core/src/shared/util';
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
Row,
|
Row,
|
||||||
|
@ -17,18 +23,9 @@ import {
|
||||||
useSelectedItems,
|
useSelectedItems,
|
||||||
useSelectedDispatch
|
useSelectedDispatch
|
||||||
} from 'loot-design/src/components/useSelected';
|
} from 'loot-design/src/components/useSelected';
|
||||||
import {
|
|
||||||
integerToAmount,
|
|
||||||
amountToInteger,
|
|
||||||
integerToCurrency
|
|
||||||
} from 'loot-core/src/shared/util';
|
|
||||||
import {
|
|
||||||
getAccountsById,
|
|
||||||
getPayeesById,
|
|
||||||
getCategoriesById
|
|
||||||
} from 'loot-core/src/client/reducers/queries';
|
|
||||||
import ArrowsSynchronize from 'loot-design/src/svg/v2/ArrowsSynchronize';
|
|
||||||
import { styles } from 'loot-design/src/style';
|
import { styles } from 'loot-design/src/style';
|
||||||
|
import ArrowsSynchronize from 'loot-design/src/svg/v2/ArrowsSynchronize';
|
||||||
|
|
||||||
import DisplayId from '../util/DisplayId';
|
import DisplayId from '../util/DisplayId';
|
||||||
|
|
||||||
function serializeTransaction(transaction, dateFormat) {
|
function serializeTransaction(transaction, dateFormat) {
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
import React, {
|
import React, { useRef, useEffect, useCallback, useLayoutEffect } from 'react';
|
||||||
useRef,
|
|
||||||
useEffect,
|
|
||||||
useCallback,
|
|
||||||
useLayoutEffect,
|
|
||||||
useMemo
|
|
||||||
} from 'react';
|
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { TransactionTable } from './TransactionsTable';
|
|
||||||
import lively from '@jlongster/lively';
|
import { send } from 'loot-core/src/platform/client/fetch';
|
||||||
import {
|
import {
|
||||||
splitTransaction,
|
splitTransaction,
|
||||||
updateTransaction,
|
updateTransaction,
|
||||||
|
@ -15,9 +9,10 @@ import {
|
||||||
realizeTempTransactions,
|
realizeTempTransactions,
|
||||||
applyTransactionDiff
|
applyTransactionDiff
|
||||||
} from 'loot-core/src/shared/transactions';
|
} from 'loot-core/src/shared/transactions';
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
|
||||||
import { pushModal } from 'loot-core/src/client/actions/modals';
|
|
||||||
import { getChangedValues, applyChanges } from 'loot-core/src/shared/util';
|
import { getChangedValues, applyChanges } from 'loot-core/src/shared/util';
|
||||||
|
|
||||||
|
import { TransactionTable } from './TransactionsTable';
|
||||||
|
|
||||||
const uuid = require('loot-core/src/platform/uuid');
|
const uuid = require('loot-core/src/platform/uuid');
|
||||||
|
|
||||||
// When data changes, there are two ways to update the UI:
|
// When data changes, there are two ways to update the UI:
|
||||||
|
|
|
@ -5,58 +5,42 @@ import React, {
|
||||||
useCallback,
|
useCallback,
|
||||||
useLayoutEffect,
|
useLayoutEffect,
|
||||||
useEffect,
|
useEffect,
|
||||||
useImperativeHandle,
|
|
||||||
useContext,
|
useContext,
|
||||||
useReducer
|
useReducer
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { useSelector, useDispatch } from 'react-redux';
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
format as formatDate,
|
format as formatDate,
|
||||||
parse as parseDate,
|
|
||||||
parseISO,
|
parseISO,
|
||||||
isValid as isDateValid
|
isValid as isDateValid
|
||||||
} from 'date-fns';
|
} from 'date-fns';
|
||||||
import q, { runQuery } from 'loot-core/src/client/query-helpers';
|
|
||||||
import {
|
import { useCachedSchedules } from 'loot-core/src/client/data-hooks/schedules';
|
||||||
View,
|
|
||||||
Text,
|
|
||||||
Stack,
|
|
||||||
Tooltip,
|
|
||||||
Button
|
|
||||||
} from 'loot-design/src/components/common';
|
|
||||||
import CategoryAutocomplete from 'loot-design/src/components/CategorySelect';
|
|
||||||
import PayeeAutocomplete from 'loot-design/src/components/PayeeAutocomplete';
|
|
||||||
import AccountAutocomplete from 'loot-design/src/components/AccountAutocomplete';
|
|
||||||
import DateSelect from 'loot-design/src/components/DateSelect';
|
|
||||||
import RightArrow2 from 'loot-design/src/svg/RightArrow2';
|
|
||||||
import LeftArrow2 from 'loot-design/src/svg/LeftArrow2';
|
|
||||||
import Hyperlink2 from 'loot-design/src/svg/v2/Hyperlink2';
|
|
||||||
import DeleteIcon from 'loot-design/src/svg/Delete';
|
|
||||||
import CheveronDown from 'loot-design/src/svg/v1/CheveronDown';
|
|
||||||
import CalendarIcon from 'loot-design/src/svg/v2/Calendar';
|
|
||||||
import ArrowsSynchronize from 'loot-design/src/svg/v2/ArrowsSynchronize';
|
|
||||||
import {
|
|
||||||
integerToCurrency,
|
|
||||||
amountToInteger,
|
|
||||||
applyChanges,
|
|
||||||
debugMemoFailure,
|
|
||||||
titleFirst
|
|
||||||
} from 'loot-core/src/shared/util';
|
|
||||||
import evalArithmetic from 'loot-core/src/shared/arithmetic';
|
|
||||||
import {
|
import {
|
||||||
getAccountsById,
|
getAccountsById,
|
||||||
getPayeesById,
|
getPayeesById,
|
||||||
getCategoriesById
|
getCategoriesById
|
||||||
} from 'loot-core/src/client/reducers/queries';
|
} from 'loot-core/src/client/reducers/queries';
|
||||||
import { currentDay, dayFromDate, addDays } from 'loot-core/src/shared/months';
|
import evalArithmetic from 'loot-core/src/shared/arithmetic';
|
||||||
|
import { currentDay } from 'loot-core/src/shared/months';
|
||||||
|
import { getScheduledAmount } from 'loot-core/src/shared/schedules';
|
||||||
import {
|
import {
|
||||||
splitTransaction,
|
splitTransaction,
|
||||||
updateTransaction,
|
updateTransaction,
|
||||||
deleteTransaction,
|
deleteTransaction,
|
||||||
addSplitTransaction,
|
addSplitTransaction
|
||||||
ungroupTransaction
|
|
||||||
} from 'loot-core/src/shared/transactions';
|
} from 'loot-core/src/shared/transactions';
|
||||||
import { styles, colors } from 'loot-design/src/style';
|
import {
|
||||||
|
integerToCurrency,
|
||||||
|
amountToInteger,
|
||||||
|
titleFirst
|
||||||
|
} from 'loot-core/src/shared/util';
|
||||||
|
import AccountAutocomplete from 'loot-design/src/components/AccountAutocomplete';
|
||||||
|
import CategoryAutocomplete from 'loot-design/src/components/CategorySelect';
|
||||||
|
import { View, Text, Tooltip, Button } from 'loot-design/src/components/common';
|
||||||
|
import DateSelect from 'loot-design/src/components/DateSelect';
|
||||||
|
import PayeeAutocomplete from 'loot-design/src/components/PayeeAutocomplete';
|
||||||
import {
|
import {
|
||||||
Cell,
|
Cell,
|
||||||
Field,
|
Field,
|
||||||
|
@ -67,18 +51,22 @@ import {
|
||||||
CustomCell,
|
CustomCell,
|
||||||
CellButton,
|
CellButton,
|
||||||
useTableNavigator,
|
useTableNavigator,
|
||||||
Table,
|
Table
|
||||||
ROW_HEIGHT
|
|
||||||
} from 'loot-design/src/components/table';
|
} from 'loot-design/src/components/table';
|
||||||
|
import { useMergedRefs } from 'loot-design/src/components/useMergedRefs';
|
||||||
import {
|
import {
|
||||||
useSelectedDispatch,
|
useSelectedDispatch,
|
||||||
useSelectedItems
|
useSelectedItems
|
||||||
} from 'loot-design/src/components/useSelected';
|
} from 'loot-design/src/components/useSelected';
|
||||||
import { keys } from 'loot-design/src/util/keys';
|
import { styles, colors } from 'loot-design/src/style';
|
||||||
import { useMergedRefs } from 'loot-design/src/components/useMergedRefs';
|
import LeftArrow2 from 'loot-design/src/svg/LeftArrow2';
|
||||||
|
import RightArrow2 from 'loot-design/src/svg/RightArrow2';
|
||||||
|
import CheveronDown from 'loot-design/src/svg/v1/CheveronDown';
|
||||||
|
import ArrowsSynchronize from 'loot-design/src/svg/v2/ArrowsSynchronize';
|
||||||
|
import CalendarIcon from 'loot-design/src/svg/v2/Calendar';
|
||||||
|
import Hyperlink2 from 'loot-design/src/svg/v2/Hyperlink2';
|
||||||
|
|
||||||
import { getStatusProps } from '../schedules/StatusBadge';
|
import { getStatusProps } from '../schedules/StatusBadge';
|
||||||
import { useCachedSchedules } from 'loot-core/src/client/data-hooks/schedules';
|
|
||||||
import { getScheduledAmount } from 'loot-core/src/shared/schedules';
|
|
||||||
|
|
||||||
let TABLE_BACKGROUND_COLOR = colors.n11;
|
let TABLE_BACKGROUND_COLOR = colors.n11;
|
||||||
|
|
||||||
|
@ -348,7 +336,7 @@ function StatusCell({
|
||||||
? colors.y5
|
? colors.y5
|
||||||
: selected
|
: selected
|
||||||
? colors.b7
|
? colors.b7
|
||||||
: colors.n6
|
: colors.n7
|
||||||
};
|
};
|
||||||
|
|
||||||
function onSelect() {
|
function onSelect() {
|
||||||
|
@ -374,7 +362,8 @@ function StatusCell({
|
||||||
':focus': {
|
':focus': {
|
||||||
border: '1px solid ' + props.color,
|
border: '1px solid ' + props.color,
|
||||||
boxShadow: `0 1px 2px ${props.color}`
|
boxShadow: `0 1px 2px ${props.color}`
|
||||||
}
|
},
|
||||||
|
cursor: isClearedField ? 'pointer' : 'default'
|
||||||
},
|
},
|
||||||
|
|
||||||
isChild && { visibility: 'hidden' }
|
isChild && { visibility: 'hidden' }
|
||||||
|
@ -1649,7 +1638,8 @@ export let TransactionTable = React.forwardRef((props, ref) => {
|
||||||
onAddSplit(lastTransaction.id);
|
onAddSplit(lastTransaction.id);
|
||||||
} else if (
|
} else if (
|
||||||
(newNavigator.focusedField === 'debit' ||
|
(newNavigator.focusedField === 'debit' ||
|
||||||
newNavigator.focusedField === 'credit') &&
|
newNavigator.focusedField === 'credit' ||
|
||||||
|
newNavigator.focusedField === 'cleared') &&
|
||||||
newNavigator.editingId === lastTransaction.id &&
|
newNavigator.editingId === lastTransaction.id &&
|
||||||
(!isSplit || !lastTransaction.error)
|
(!isSplit || !lastTransaction.error)
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -1,15 +1,27 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act } from 'react-dom/test-utils';
|
|
||||||
import { render, fireEvent } from '@testing-library/react';
|
import { render, fireEvent } from '@testing-library/react';
|
||||||
import { debugDOM } from 'loot-core/src/mocks/util';
|
|
||||||
import { format as formatDate, parse as parseDate } from 'date-fns';
|
import { format as formatDate, parse as parseDate } from 'date-fns';
|
||||||
import { integerToCurrency } from 'loot-core/src/shared/util';
|
import { act } from 'react-dom/test-utils';
|
||||||
import { initServer } from 'loot-core/src/platform/client/fetch';
|
|
||||||
import {
|
import {
|
||||||
generateTransaction,
|
generateTransaction,
|
||||||
generateAccount,
|
generateAccount,
|
||||||
generateCategoryGroups
|
generateCategoryGroups,
|
||||||
|
TestProvider
|
||||||
} from 'loot-core/src/mocks';
|
} from 'loot-core/src/mocks';
|
||||||
|
import { initServer } from 'loot-core/src/platform/client/fetch';
|
||||||
|
import {
|
||||||
|
addSplitTransaction,
|
||||||
|
realizeTempTransactions,
|
||||||
|
splitTransaction,
|
||||||
|
updateTransaction
|
||||||
|
} from 'loot-core/src/shared';
|
||||||
|
import { integerToCurrency } from 'loot-core/src/shared/util';
|
||||||
|
import { SelectedProviderWithItems } from 'loot-design/src/components';
|
||||||
|
|
||||||
|
import { SplitsExpandedProvider, TransactionTable } from './TransactionsTable';
|
||||||
|
|
||||||
const uuid = require('loot-core/src/platform/uuid');
|
const uuid = require('loot-core/src/platform/uuid');
|
||||||
|
|
||||||
const accounts = [generateAccount('Bank of America')];
|
const accounts = [generateAccount('Bank of America')];
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import React, { useState, useLayoutEffect } from 'react';
|
import React from 'react';
|
||||||
import { styles, colors } from 'loot-design/src/style';
|
|
||||||
import { View, Text } from 'loot-design/src/components/common';
|
|
||||||
import { useBudgetMonthCount } from 'loot-design/src/components/budget/BudgetMonthCountContext';
|
import { useBudgetMonthCount } from 'loot-design/src/components/budget/BudgetMonthCountContext';
|
||||||
|
import { View } from 'loot-design/src/components/common';
|
||||||
|
import { colors } from 'loot-design/src/style';
|
||||||
import CalendarIcon from 'loot-design/src/svg/v2/Calendar';
|
import CalendarIcon from 'loot-design/src/svg/v2/Calendar';
|
||||||
|
|
||||||
function Calendar({ color, onClick }) {
|
function Calendar({ color, onClick }) {
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
function BudgetSheetHeader({ row }) {
|
function BudgetSheetHeader({ row }) {
|
||||||
return (
|
return (
|
||||||
<Row style={{ zIndex: 200, backgroundColor: colors.grey1, marginLeft: 20 }}>
|
<Row style={{ zIndex: 200, backgroundColor: colors.grey1, marginLeft: 20 }}>
|
||||||
|
|
|
@ -1,25 +1,8 @@
|
||||||
import React, { useEffect, useContext, useMemo } from 'react';
|
import React, { useContext, useMemo } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { withRouter } from 'react-router-dom';
|
|
||||||
import { bindActionCreators } from 'redux';
|
|
||||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
|
||||||
import memoizeOne from 'memoize-one';
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
import { send, listen } from 'loot-core/src/platform/client/fetch';
|
import { send, listen } from 'loot-core/src/platform/client/fetch';
|
||||||
import * as monthUtils from 'loot-core/src/shared/months';
|
|
||||||
import { getValidMonthBounds } from 'loot-design/src/components/budget/MonthsContext';
|
|
||||||
import { TitlebarContext } from '../Titlebar';
|
|
||||||
|
|
||||||
import * as rollover from 'loot-design/src/components/budget/rollover/rollover-components';
|
|
||||||
import { RolloverContext } from 'loot-design/src/components/budget/rollover/RolloverContext';
|
|
||||||
|
|
||||||
import * as report from 'loot-design/src/components/budget/report/components';
|
|
||||||
import { ReportProvider } from 'loot-design/src/components/budget/report/ReportContext';
|
|
||||||
|
|
||||||
import DynamicBudgetTable from 'loot-design/src/components/budget/DynamicBudgetTable';
|
|
||||||
import SpreadsheetContext from 'loot-design/src/components/spreadsheet/SpreadsheetContext';
|
|
||||||
import { View } from 'loot-design/src/components/common';
|
|
||||||
import { styles, colors } from 'loot-design/src/style';
|
|
||||||
import {
|
import {
|
||||||
addCategory,
|
addCategory,
|
||||||
updateCategory,
|
updateCategory,
|
||||||
|
@ -30,6 +13,18 @@ import {
|
||||||
updateGroup,
|
updateGroup,
|
||||||
deleteGroup
|
deleteGroup
|
||||||
} from 'loot-core/src/shared/categories.js';
|
} from 'loot-core/src/shared/categories.js';
|
||||||
|
import * as monthUtils from 'loot-core/src/shared/months';
|
||||||
|
import DynamicBudgetTable from 'loot-design/src/components/budget/DynamicBudgetTable';
|
||||||
|
import { getValidMonthBounds } from 'loot-design/src/components/budget/MonthsContext';
|
||||||
|
import * as report from 'loot-design/src/components/budget/report/components';
|
||||||
|
import { ReportProvider } from 'loot-design/src/components/budget/report/ReportContext';
|
||||||
|
import * as rollover from 'loot-design/src/components/budget/rollover/rollover-components';
|
||||||
|
import { RolloverContext } from 'loot-design/src/components/budget/rollover/RolloverContext';
|
||||||
|
import { View } from 'loot-design/src/components/common';
|
||||||
|
import SpreadsheetContext from 'loot-design/src/components/spreadsheet/SpreadsheetContext';
|
||||||
|
import { styles } from 'loot-design/src/style';
|
||||||
|
|
||||||
|
import { TitlebarContext } from '../Titlebar';
|
||||||
|
|
||||||
let _initialBudgetMonth = null;
|
let _initialBudgetMonth = null;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
import { send } from 'loot-core/src/platform/client/fetch';
|
||||||
|
|
||||||
const Container = styled.div`
|
const Container = styled.div`
|
||||||
|
|
|
@ -1,23 +1,18 @@
|
||||||
import React, { useState, useEffect, useCallback } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
|
||||||
|
import { signOut, loggedIn } from 'loot-core/src/client/actions/user';
|
||||||
|
import { send } from 'loot-core/src/platform/client/fetch';
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Text,
|
Text,
|
||||||
Button,
|
Button,
|
||||||
ButtonWithLoading
|
ButtonWithLoading
|
||||||
} from 'loot-design/src/components/common';
|
} from 'loot-design/src/components/common';
|
||||||
import { colors, styles } from 'loot-design/src/style';
|
import { colors } from 'loot-design/src/style';
|
||||||
import { signOut, loggedIn } from 'loot-core/src/client/actions/user';
|
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
import { Title, Input } from './subscribe/common';
|
||||||
import {
|
|
||||||
useBootstrapped,
|
|
||||||
Title,
|
|
||||||
Input,
|
|
||||||
Link,
|
|
||||||
ExternalLink
|
|
||||||
} from './subscribe/common';
|
|
||||||
|
|
||||||
export default function ConfigServer() {
|
export default function ConfigServer() {
|
||||||
let dispatch = useDispatch();
|
let dispatch = useDispatch();
|
||||||
|
|
|
@ -1,22 +1,23 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { createBrowserHistory } from 'history';
|
|
||||||
import { Switch, Redirect, Router, Route } from 'react-router-dom';
|
import { Switch, Redirect, Router, Route } from 'react-router-dom';
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
|
||||||
|
import { createBrowserHistory } from 'history';
|
||||||
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
import { View, Text } from 'loot-design/src/components/common';
|
import { View, Text } from 'loot-design/src/components/common';
|
||||||
import { colors } from 'loot-design/src/style';
|
import { colors } from 'loot-design/src/style';
|
||||||
import ServerURL from './ServerURL';
|
|
||||||
|
import useServerVersion from '../../hooks/useServerVersion';
|
||||||
import LoggedInUser from '../LoggedInUser';
|
import LoggedInUser from '../LoggedInUser';
|
||||||
import Notifications from '../Notifications';
|
import Notifications from '../Notifications';
|
||||||
|
|
||||||
import Modals from './Modals';
|
|
||||||
import Login from './subscribe/Login';
|
|
||||||
import Bootstrap from './subscribe/Bootstrap';
|
|
||||||
import Error from './subscribe/Error';
|
|
||||||
import ChangePassword from './subscribe/ChangePassword';
|
|
||||||
import ConfigServer from './ConfigServer';
|
import ConfigServer from './ConfigServer';
|
||||||
import useServerVersion from '../../hooks/useServerVersion';
|
import Modals from './Modals';
|
||||||
|
import ServerURL from './ServerURL';
|
||||||
|
import Bootstrap from './subscribe/Bootstrap';
|
||||||
|
import ChangePassword from './subscribe/ChangePassword';
|
||||||
|
import Error from './subscribe/Error';
|
||||||
|
import Login from './subscribe/Login';
|
||||||
|
|
||||||
function Version() {
|
function Version() {
|
||||||
const version = useServerVersion();
|
const version = useServerVersion();
|
||||||
|
@ -230,8 +231,7 @@ class ManagementApp extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(
|
export default connect(state => {
|
||||||
state => {
|
|
||||||
let { modalStack } = state.modals;
|
let { modalStack } = state.modals;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -241,6 +241,4 @@ export default connect(
|
||||||
loadingText: state.app.loadingText,
|
loadingText: state.app.loadingText,
|
||||||
currentModals: modalStack.map(modal => modal.name)
|
currentModals: modalStack.map(modal => modal.name)
|
||||||
};
|
};
|
||||||
},
|
}, actions)(ManagementApp);
|
||||||
actions
|
|
||||||
)(ManagementApp);
|
|
||||||
|
|
|
@ -1,20 +1,22 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { bindActionCreators } from 'redux';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import Component from '@reactions/component';
|
import Component from '@reactions/component';
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
import { bindActionCreators } from 'redux';
|
||||||
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
|
import { send } from 'loot-core/src/platform/client/fetch';
|
||||||
import { View } from 'loot-design/src/components/common';
|
import { View } from 'loot-design/src/components/common';
|
||||||
import BudgetList from 'loot-design/src/components/manager/BudgetList';
|
import BudgetList from 'loot-design/src/components/manager/BudgetList';
|
||||||
import LoadBackup from 'loot-design/src/components/modals/LoadBackup';
|
import DeleteFile from 'loot-design/src/components/manager/DeleteFile';
|
||||||
import Import from 'loot-design/src/components/manager/Import';
|
import Import from 'loot-design/src/components/manager/Import';
|
||||||
|
import ImportActual from 'loot-design/src/components/manager/ImportActual';
|
||||||
import ImportYNAB4 from 'loot-design/src/components/manager/ImportYNAB4';
|
import ImportYNAB4 from 'loot-design/src/components/manager/ImportYNAB4';
|
||||||
import ImportYNAB5 from 'loot-design/src/components/manager/ImportYNAB5';
|
import ImportYNAB5 from 'loot-design/src/components/manager/ImportYNAB5';
|
||||||
import ImportActual from 'loot-design/src/components/manager/ImportActual';
|
import LoadBackup from 'loot-design/src/components/modals/LoadBackup';
|
||||||
import DeleteFile from 'loot-design/src/components/manager/DeleteFile';
|
|
||||||
import CreateEncryptionKey from '../modals/CreateEncryptionKey';
|
import CreateEncryptionKey from '../modals/CreateEncryptionKey';
|
||||||
import FixEncryptionKey from '../modals/FixEncryptionKey';
|
import FixEncryptionKey from '../modals/FixEncryptionKey';
|
||||||
import { colors } from 'loot-design/src/style';
|
|
||||||
|
|
||||||
function Modals({
|
function Modals({
|
||||||
modalStack,
|
modalStack,
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import {
|
|
||||||
View,
|
|
||||||
Text,
|
|
||||||
AnchorLink,
|
|
||||||
Button
|
|
||||||
} from 'loot-design/src/components/common';
|
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
import { send } from 'loot-core/src/platform/client/fetch';
|
||||||
|
import { View, Text, AnchorLink } from 'loot-design/src/components/common';
|
||||||
|
|
||||||
export default function ServerURL() {
|
export default function ServerURL() {
|
||||||
let [url, setUrl] = useState(null);
|
let [url, setUrl] = useState(null);
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
import React, { useState, useEffect, useCallback } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
|
||||||
import { View, Text, Button } from 'loot-design/src/components/common';
|
|
||||||
import { colors, styles } from 'loot-design/src/style';
|
|
||||||
import { loggedIn } from 'loot-core/src/client/actions/user';
|
|
||||||
import { createBudget } from 'loot-core/src/client/actions/budgets';
|
import { createBudget } from 'loot-core/src/client/actions/budgets';
|
||||||
|
import { loggedIn } from 'loot-core/src/client/actions/user';
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
import { send } from 'loot-core/src/platform/client/fetch';
|
||||||
|
import { View, Text, Button } from 'loot-design/src/components/common';
|
||||||
|
import { colors } from 'loot-design/src/style';
|
||||||
|
|
||||||
|
import { useBootstrapped, Title } from './common';
|
||||||
import { ConfirmPasswordForm } from './ConfirmPasswordForm';
|
import { ConfirmPasswordForm } from './ConfirmPasswordForm';
|
||||||
import { useBootstrapped, Title, Input, Link, ExternalLink } from './common';
|
|
||||||
|
|
||||||
export default function Bootstrap() {
|
export default function Bootstrap() {
|
||||||
let dispatch = useDispatch();
|
let dispatch = useDispatch();
|
||||||
|
|
|
@ -1,19 +1,13 @@
|
||||||
import React, { useState, useCallback } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
|
||||||
import {
|
|
||||||
View,
|
|
||||||
Text,
|
|
||||||
Button,
|
|
||||||
ButtonWithLoading
|
|
||||||
} from 'loot-design/src/components/common';
|
|
||||||
import { colors, styles } from 'loot-design/src/style';
|
|
||||||
import { loggedIn } from 'loot-core/src/client/actions/user';
|
|
||||||
import { createBudget } from 'loot-core/src/client/actions/budgets';
|
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
import { send } from 'loot-core/src/platform/client/fetch';
|
||||||
|
import { View, Text, Button } from 'loot-design/src/components/common';
|
||||||
|
import { colors } from 'loot-design/src/style';
|
||||||
|
|
||||||
|
import { Title } from './common';
|
||||||
import { ConfirmPasswordForm } from './ConfirmPasswordForm';
|
import { ConfirmPasswordForm } from './ConfirmPasswordForm';
|
||||||
import { useBootstrapped, Title, Input, Link, ExternalLink } from './common';
|
|
||||||
|
|
||||||
export default function ChangePassword() {
|
export default function ChangePassword() {
|
||||||
let dispatch = useDispatch();
|
let dispatch = useDispatch();
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import {
|
|
||||||
View,
|
import { View, ButtonWithLoading } from 'loot-design/src/components/common';
|
||||||
Button,
|
|
||||||
ButtonWithLoading
|
|
||||||
} from 'loot-design/src/components/common';
|
|
||||||
import { Input } from './common';
|
import { Input } from './common';
|
||||||
|
|
||||||
export function ConfirmPasswordForm({ buttons, onSetPassword, onError }) {
|
export function ConfirmPasswordForm({ buttons, onSetPassword, onError }) {
|
||||||
|
@ -47,6 +45,7 @@ export function ConfirmPasswordForm({ buttons, onSetPassword, onError }) {
|
||||||
type={showPassword ? 'text' : 'password'}
|
type={showPassword ? 'text' : 'password'}
|
||||||
value={password1}
|
value={password1}
|
||||||
onChange={e => setPassword1(e.target.value)}
|
onChange={e => setPassword1(e.target.value)}
|
||||||
|
onEnter={onSubmit}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
placeholder="Confirm password"
|
placeholder="Confirm password"
|
||||||
|
@ -54,6 +53,7 @@ export function ConfirmPasswordForm({ buttons, onSetPassword, onError }) {
|
||||||
value={password2}
|
value={password2}
|
||||||
onChange={e => setPassword2(e.target.value)}
|
onChange={e => setPassword2(e.target.value)}
|
||||||
style={{ marginTop: 10 }}
|
style={{ marginTop: 10 }}
|
||||||
|
onEnter={onSubmit}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
|
@ -69,10 +69,7 @@ export function ConfirmPasswordForm({ buttons, onSetPassword, onError }) {
|
||||||
</label>
|
</label>
|
||||||
<View style={{ flex: 1 }} />
|
<View style={{ flex: 1 }} />
|
||||||
{buttons}
|
{buttons}
|
||||||
<ButtonWithLoading
|
<ButtonWithLoading primary loading={loading}>
|
||||||
primary
|
|
||||||
loading={loading}
|
|
||||||
>
|
|
||||||
OK
|
OK
|
||||||
</ButtonWithLoading>
|
</ButtonWithLoading>
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React from 'react';
|
||||||
import { useHistory, useLocation } from 'react-router-dom';
|
import { useHistory, useLocation } from 'react-router-dom';
|
||||||
import {
|
|
||||||
View,
|
import { View, Text, Button } from 'loot-design/src/components/common';
|
||||||
Text,
|
import { colors } from 'loot-design/src/style';
|
||||||
Button,
|
|
||||||
ButtonWithLoading
|
|
||||||
} from 'loot-design/src/components/common';
|
|
||||||
import { colors, styles } from 'loot-design/src/style';
|
|
||||||
|
|
||||||
function getErrorMessage(reason) {
|
function getErrorMessage(reason) {
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
import React, { useState, useCallback } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
|
||||||
|
import { createBudget } from 'loot-core/src/client/actions/budgets';
|
||||||
|
import { loggedIn } from 'loot-core/src/client/actions/user';
|
||||||
|
import { send } from 'loot-core/src/platform/client/fetch';
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Text,
|
Text,
|
||||||
Button,
|
Button,
|
||||||
ButtonWithLoading
|
ButtonWithLoading
|
||||||
} from 'loot-design/src/components/common';
|
} from 'loot-design/src/components/common';
|
||||||
import { colors, styles } from 'loot-design/src/style';
|
import { colors } from 'loot-design/src/style';
|
||||||
import { loggedIn } from 'loot-core/src/client/actions/user';
|
|
||||||
import { createBudget } from 'loot-core/src/client/actions/budgets';
|
import { useBootstrapped, Title, Input } from './common';
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
|
||||||
import { useBootstrapped, Title, Input, Link, ExternalLink } from './common';
|
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
let dispatch = useDispatch();
|
let dispatch = useDispatch();
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useHistory, useLocation } from 'react-router-dom';
|
import { useHistory, useLocation } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { send } from 'loot-core/src/platform/client/fetch';
|
||||||
import {
|
import {
|
||||||
AnchorLink,
|
|
||||||
Text,
|
Text,
|
||||||
Button,
|
Button,
|
||||||
ButtonLink,
|
|
||||||
Input as BaseInput
|
Input as BaseInput
|
||||||
} from 'loot-design/src/components/common';
|
} from 'loot-design/src/components/common';
|
||||||
import { colors, styles } from 'loot-design/src/style';
|
import { colors, styles } from 'loot-design/src/style';
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
|
||||||
|
|
||||||
// There are two URLs that dance with each other: `/login` and
|
// There are two URLs that dance with each other: `/login` and
|
||||||
// `/bootstrap`. Both of these URLs check the state of the the server
|
// `/bootstrap`. Both of these URLs check the state of the the server
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import { NativeCategorySelect } from 'loot-design/src/components/CategorySelect';
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Text,
|
Text,
|
||||||
Block,
|
Block,
|
||||||
Modal,
|
Modal,
|
||||||
Button,
|
Button
|
||||||
Select
|
|
||||||
} from 'loot-design/src/components/common';
|
} from 'loot-design/src/components/common';
|
||||||
import { colors } from 'loot-design/src/style';
|
import { colors } from 'loot-design/src/style';
|
||||||
import { NativeCategorySelect } from 'loot-design/src/components/CategorySelect';
|
|
||||||
|
|
||||||
class ConfirmCategoryDelete extends React.Component {
|
class ConfirmCategoryDelete extends React.Component {
|
||||||
state = { transferCategory: null, error: null };
|
state = { transferCategory: null, error: null };
|
||||||
|
|
|
@ -1,17 +1,12 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { bindActionCreators } from 'redux';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { bindActionCreators } from 'redux';
|
||||||
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
import { View, Text, Modal, Button } from 'loot-design/src/components/common';
|
||||||
import {
|
|
||||||
View,
|
|
||||||
Text,
|
|
||||||
Modal,
|
|
||||||
Button,
|
|
||||||
Strong,
|
|
||||||
P
|
|
||||||
} from 'loot-design/src/components/common';
|
|
||||||
import { colors } from 'loot-design/src/style';
|
import { colors } from 'loot-design/src/style';
|
||||||
|
|
||||||
import { authorizeBank } from '../../plaid';
|
import { authorizeBank } from '../../plaid';
|
||||||
|
|
||||||
class CreateAccount extends React.Component {
|
class CreateAccount extends React.Component {
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
import { css } from 'glamor';
|
import { css } from 'glamor';
|
||||||
|
|
||||||
|
import { send } from 'loot-core/src/platform/client/fetch';
|
||||||
|
import { getCreateKeyError } from 'loot-core/src/shared/errors';
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Text,
|
Text,
|
||||||
Stack,
|
|
||||||
Modal,
|
Modal,
|
||||||
Button,
|
|
||||||
ButtonWithLoading,
|
ButtonWithLoading,
|
||||||
ExternalLink,
|
ExternalLink,
|
||||||
P,
|
P,
|
||||||
|
@ -13,9 +15,7 @@ import {
|
||||||
Input,
|
Input,
|
||||||
InitialFocus
|
InitialFocus
|
||||||
} from 'loot-design/src/components/common';
|
} from 'loot-design/src/components/common';
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
import { colors } from 'loot-design/src/style';
|
||||||
import { styles, colors } from 'loot-design/src/style';
|
|
||||||
import { getCreateKeyError } from 'loot-core/src/shared/errors';
|
|
||||||
|
|
||||||
export default function CreateEncryptionKey({
|
export default function CreateEncryptionKey({
|
||||||
modalProps,
|
modalProps,
|
||||||
|
|
|
@ -1,31 +1,14 @@
|
||||||
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
||||||
import { bindActionCreators } from 'redux';
|
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
initiallyLoadPayees,
|
initiallyLoadPayees,
|
||||||
setUndoEnabled
|
setUndoEnabled
|
||||||
} from 'loot-core/src/client/actions/queries';
|
} from 'loot-core/src/client/actions/queries';
|
||||||
import * as undo from 'loot-core/src/platform/client/undo';
|
import { useSchedules } from 'loot-core/src/client/data-hooks/schedules';
|
||||||
import q, { runQuery } from 'loot-core/src/client/query-helpers';
|
import q, { runQuery } from 'loot-core/src/client/query-helpers';
|
||||||
import {
|
import { send } from 'loot-core/src/platform/client/fetch';
|
||||||
View,
|
import * as monthUtils from 'loot-core/src/shared/months';
|
||||||
Text,
|
|
||||||
Modal,
|
|
||||||
Button,
|
|
||||||
Select,
|
|
||||||
Stack,
|
|
||||||
Input,
|
|
||||||
CustomSelect,
|
|
||||||
Tooltip
|
|
||||||
} from 'loot-design/src/components/common';
|
|
||||||
import GenericInput from '../util/GenericInput';
|
|
||||||
import { keys } from 'loot-design/src/util/keys';
|
|
||||||
import { send, listen, unlisten } from 'loot-core/src/platform/client/fetch';
|
|
||||||
import { getStatus } from 'loot-core/src/shared/schedules';
|
|
||||||
import { colors, styles } from 'loot-design/src/style';
|
|
||||||
import SubtractIcon from 'loot-design/src/svg/Subtract';
|
|
||||||
import AddIcon from 'loot-design/src/svg/Add';
|
|
||||||
import InformationOutline from 'loot-design/src/svg/v1/InformationOutline';
|
|
||||||
import {
|
import {
|
||||||
mapField,
|
mapField,
|
||||||
friendlyOp,
|
friendlyOp,
|
||||||
|
@ -36,20 +19,33 @@ import {
|
||||||
FIELD_TYPES,
|
FIELD_TYPES,
|
||||||
TYPE_INFO
|
TYPE_INFO
|
||||||
} from 'loot-core/src/shared/rules';
|
} from 'loot-core/src/shared/rules';
|
||||||
import useSelected, {
|
|
||||||
SelectedProvider
|
|
||||||
} from 'loot-design/src/components/useSelected';
|
|
||||||
import SimpleTransactionsTable from '../accounts/SimpleTransactionsTable';
|
|
||||||
import { StatusBadge } from '../schedules/StatusBadge';
|
|
||||||
import DisplayId from '../util/DisplayId';
|
|
||||||
import { useSchedules } from 'loot-core/src/client/data-hooks/schedules';
|
|
||||||
import {
|
import {
|
||||||
integerToCurrency,
|
integerToCurrency,
|
||||||
integerToAmount,
|
integerToAmount,
|
||||||
amountToInteger
|
amountToInteger
|
||||||
} from 'loot-core/src/shared/util';
|
} from 'loot-core/src/shared/util';
|
||||||
import * as monthUtils from 'loot-core/src/shared/months';
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
Modal,
|
||||||
|
Button,
|
||||||
|
Stack,
|
||||||
|
CustomSelect,
|
||||||
|
Tooltip
|
||||||
|
} from 'loot-design/src/components/common';
|
||||||
|
import useSelected, {
|
||||||
|
SelectedProvider
|
||||||
|
} from 'loot-design/src/components/useSelected';
|
||||||
|
import { colors } from 'loot-design/src/style';
|
||||||
|
import AddIcon from 'loot-design/src/svg/Add';
|
||||||
|
import SubtractIcon from 'loot-design/src/svg/Subtract';
|
||||||
|
import InformationOutline from 'loot-design/src/svg/v1/InformationOutline';
|
||||||
|
|
||||||
|
import SimpleTransactionsTable from '../accounts/SimpleTransactionsTable';
|
||||||
|
import { StatusBadge } from '../schedules/StatusBadge';
|
||||||
import { BetweenAmountInput } from '../util/AmountInput';
|
import { BetweenAmountInput } from '../util/AmountInput';
|
||||||
|
import DisplayId from '../util/DisplayId';
|
||||||
|
import GenericInput from '../util/GenericInput';
|
||||||
|
|
||||||
function updateValue(array, value, update) {
|
function updateValue(array, value, update) {
|
||||||
return array.map(v => (v === value ? update() : v));
|
return array.map(v => (v === value ? update() : v));
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
|
import { send } from 'loot-core/src/platform/client/fetch';
|
||||||
|
import { getTestKeyError } from 'loot-core/src/shared/errors';
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Text,
|
Text,
|
||||||
|
@ -11,9 +14,7 @@ import {
|
||||||
InitialFocus,
|
InitialFocus,
|
||||||
ExternalLink
|
ExternalLink
|
||||||
} from 'loot-design/src/components/common';
|
} from 'loot-design/src/components/common';
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
import { colors } from 'loot-design/src/style';
|
||||||
import { styles, colors } from 'loot-design/src/style';
|
|
||||||
import { getTestKeyError } from 'loot-core/src/shared/errors';
|
|
||||||
|
|
||||||
export default function FixEncryptionKey({
|
export default function FixEncryptionKey({
|
||||||
modalProps,
|
modalProps,
|
||||||
|
|
|
@ -1,19 +1,23 @@
|
||||||
import React, {
|
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
||||||
useState,
|
|
||||||
useEffect,
|
|
||||||
useRef,
|
|
||||||
useCallback,
|
|
||||||
useMemo,
|
|
||||||
useImperativeHandle
|
|
||||||
} from 'react';
|
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { css } from 'glamor';
|
|
||||||
import { format as formatDate, parseISO } from 'date-fns';
|
import { format as formatDate, parseISO } from 'date-fns';
|
||||||
import * as undo from 'loot-core/src/platform/client/undo';
|
import { css } from 'glamor';
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
|
||||||
|
import { pushModal } from 'loot-core/src/client/actions/modals';
|
||||||
import { initiallyLoadPayees } from 'loot-core/src/client/actions/queries';
|
import { initiallyLoadPayees } from 'loot-core/src/client/actions/queries';
|
||||||
import q from 'loot-core/src/client/query-helpers';
|
import q from 'loot-core/src/client/query-helpers';
|
||||||
import { liveQueryContext } from 'loot-core/src/client/query-hooks';
|
import { liveQueryContext } from 'loot-core/src/client/query-hooks';
|
||||||
|
import { getPayeesById } from 'loot-core/src/client/reducers/queries';
|
||||||
|
import { send } from 'loot-core/src/platform/client/fetch';
|
||||||
|
import * as undo from 'loot-core/src/platform/client/undo';
|
||||||
|
import { getMonthYearFormat } from 'loot-core/src/shared/months';
|
||||||
|
import { mapField, friendlyOp } from 'loot-core/src/shared/rules';
|
||||||
|
import {
|
||||||
|
extractScheduleConds,
|
||||||
|
getRecurringDescription
|
||||||
|
} from 'loot-core/src/shared/schedules';
|
||||||
|
import { integerToCurrency } from 'loot-core/src/shared/util';
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Text,
|
Text,
|
||||||
|
@ -36,20 +40,8 @@ import useSelected, {
|
||||||
useSelectedItems,
|
useSelectedItems,
|
||||||
SelectedProvider
|
SelectedProvider
|
||||||
} from 'loot-design/src/components/useSelected';
|
} from 'loot-design/src/components/useSelected';
|
||||||
import { integerToCurrency } from 'loot-core/src/shared/util';
|
import { colors } from 'loot-design/src/style';
|
||||||
import { send, listen, unlisten } from 'loot-core/src/platform/client/fetch';
|
|
||||||
import { pushModal } from 'loot-core/src/client/actions/modals';
|
|
||||||
import { mapField, friendlyOp } from 'loot-core/src/shared/rules';
|
|
||||||
import ArrowRight from 'loot-design/src/svg/RightArrow2';
|
import ArrowRight from 'loot-design/src/svg/RightArrow2';
|
||||||
import InformationOutline from 'loot-design/src/svg/v1/InformationOutline';
|
|
||||||
import ExpandArrow from 'loot-design/src/svg/ExpandArrow';
|
|
||||||
import { colors, styles } from 'loot-design/src/style';
|
|
||||||
import { dayFromDate, getMonthYearFormat } from 'loot-core/src/shared/months';
|
|
||||||
import {
|
|
||||||
extractScheduleConds,
|
|
||||||
getRecurringDescription
|
|
||||||
} from 'loot-core/src/shared/schedules';
|
|
||||||
import { getPayeesById } from 'loot-core/src/client/reducers/queries';
|
|
||||||
|
|
||||||
let SchedulesQuery = liveQueryContext(q('schedules').select('*'));
|
let SchedulesQuery = liveQueryContext(q('schedules').select('*'));
|
||||||
|
|
||||||
|
@ -246,9 +238,9 @@ function ScheduleValue({ value }) {
|
||||||
field="rule"
|
field="rule"
|
||||||
data={schedules}
|
data={schedules}
|
||||||
describe={s => {
|
describe={s => {
|
||||||
let { payee } = extractScheduleConds(s._conditions);
|
let payeeId = s._payee;
|
||||||
return payee
|
return payeeId
|
||||||
? `${byId[payee.value].name} (${s.next_date})`
|
? `${byId[payeeId].name} (${s.next_date})`
|
||||||
: `Next: ${s.next_date}`;
|
: `Next: ${s.next_date}`;
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
import React, { useState, useRef, useEffect } from 'react';
|
import React, { useState, useRef, useEffect } from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
|
||||||
|
import { replaceModal } from 'loot-core/src/client/actions/modals';
|
||||||
|
import { send } from 'loot-core/src/platform/client/fetch';
|
||||||
|
import { Information } from 'loot-design/src/components/alerts';
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Text,
|
Text,
|
||||||
Modal,
|
Modal,
|
||||||
ModalButtons,
|
ModalButtons,
|
||||||
Button,
|
Button,
|
||||||
P,
|
P
|
||||||
Stack
|
|
||||||
} from 'loot-design/src/components/common';
|
} from 'loot-design/src/components/common';
|
||||||
import { Information } from 'loot-design/src/components/alerts';
|
import { colors } from 'loot-design/src/style';
|
||||||
import { colors, styles } from 'loot-design/src/style';
|
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
|
||||||
import { replaceModal } from 'loot-core/src/client/actions/modals';
|
|
||||||
|
|
||||||
let highlightStyle = { color: colors.p5 };
|
let highlightStyle = { color: colors.p5 };
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Text,
|
|
||||||
Modal,
|
Modal,
|
||||||
Button,
|
|
||||||
P,
|
P,
|
||||||
ExternalLink
|
ExternalLink
|
||||||
} from 'loot-design/src/components/common';
|
} from 'loot-design/src/components/common';
|
||||||
|
@ -70,7 +69,4 @@ function WelcomeScreen({ modalProps, actions }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(
|
export default connect(null, actions)(WelcomeScreen);
|
||||||
null,
|
|
||||||
actions
|
|
||||||
)(WelcomeScreen);
|
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import React, { useState, useEffect, useRef } from 'react';
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
import { bindActionCreators } from 'redux';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
|
import { send, listen } from 'loot-core/src/platform/client/fetch';
|
||||||
import * as undo from 'loot-core/src/platform/client/undo';
|
import * as undo from 'loot-core/src/platform/client/undo';
|
||||||
import uuid from 'loot-core/src/platform/uuid';
|
|
||||||
import { send, listen, unlisten } from 'loot-core/src/platform/client/fetch';
|
|
||||||
import { ManagePayees } from 'loot-design/src/components/payees';
|
|
||||||
import { applyChanges } from 'loot-core/src/shared/util';
|
import { applyChanges } from 'loot-core/src/shared/util';
|
||||||
|
import { ManagePayees } from 'loot-design/src/components/payees';
|
||||||
|
|
||||||
function ManagePayeesWithData({
|
function ManagePayeesWithData({
|
||||||
history,
|
history,
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
|
|
||||||
import * as d from 'date-fns';
|
import * as d from 'date-fns';
|
||||||
|
|
||||||
|
import { send } from 'loot-core/src/platform/client/fetch';
|
||||||
|
import * as monthUtils from 'loot-core/src/shared/months';
|
||||||
|
import { integerToCurrency } from 'loot-core/src/shared/util';
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Text,
|
Text,
|
||||||
|
@ -7,18 +12,14 @@ import {
|
||||||
P,
|
P,
|
||||||
AlignedText
|
AlignedText
|
||||||
} from 'loot-design/src/components/common';
|
} from 'loot-design/src/components/common';
|
||||||
import { styles } from 'loot-design/src/style';
|
import { colors, styles } from 'loot-design/src/style';
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
|
||||||
import * as monthUtils from 'loot-core/src/shared/months';
|
|
||||||
import { integerToCurrency } from 'loot-core/src/shared/util';
|
|
||||||
import { fromDateRepr } from './util';
|
|
||||||
import Header from './Header';
|
|
||||||
import Change from './Change';
|
import Change from './Change';
|
||||||
import CashFlowGraph from './graphs/CashFlowGraph';
|
|
||||||
import { cashFlowByDate } from './graphs/cash-flow-spreadsheet';
|
import { cashFlowByDate } from './graphs/cash-flow-spreadsheet';
|
||||||
|
import CashFlowGraph from './graphs/CashFlowGraph';
|
||||||
|
import Header from './Header';
|
||||||
import useReport from './useReport';
|
import useReport from './useReport';
|
||||||
import { useArgsMemo } from './util';
|
import { useArgsMemo } from './util';
|
||||||
import { colors } from 'loot-design/src/style';
|
|
||||||
|
|
||||||
function CashFlow() {
|
function CashFlow() {
|
||||||
const [earliestMonth, setEarliestMonth] = useState(null);
|
const [earliestMonth, setEarliestMonth] = useState(null);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { styles } from 'loot-design/src/style';
|
|
||||||
import { integerToCurrency } from 'loot-core/src/shared/util';
|
import { integerToCurrency } from 'loot-core/src/shared/util';
|
||||||
import { Block } from 'loot-design/src/components/common';
|
import { Block } from 'loot-design/src/components/common';
|
||||||
import { colors } from 'loot-design/src/style'
|
import { colors, styles } from 'loot-design/src/style';
|
||||||
|
|
||||||
function Change({ amount, style }) {
|
function Change({ amount, style }) {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { View } from 'loot-design/src/components/common';
|
|
||||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||||
|
|
||||||
|
import { View } from 'loot-design/src/components/common';
|
||||||
|
|
||||||
class Container extends React.Component {
|
class Container extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const { style, children } = this.props;
|
const { style, children } = this.props;
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import * as d from 'date-fns';
|
import * as d from 'date-fns';
|
||||||
import { colors } from 'loot-design/src/style';
|
|
||||||
import { Block } from 'loot-design/src/components/common';
|
import { Block } from 'loot-design/src/components/common';
|
||||||
|
import { colors } from 'loot-design/src/style';
|
||||||
|
|
||||||
function DateRange({ start, end }) {
|
function DateRange({ start, end }) {
|
||||||
start = d.parseISO(start);
|
start = d.parseISO(start);
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { colors, styles } from 'loot-design/src/style';
|
|
||||||
|
import * as monthUtils from 'loot-core/src/shared/months';
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Select,
|
Select,
|
||||||
Link,
|
|
||||||
Button,
|
Button,
|
||||||
ButtonLink
|
ButtonLink
|
||||||
} from 'loot-design/src/components/common';
|
} from 'loot-design/src/components/common';
|
||||||
import * as monthUtils from 'loot-core/src/shared/months';
|
import { styles } from 'loot-design/src/style';
|
||||||
import ArrowLeft from 'loot-design/src/svg/v1/ArrowLeft';
|
import ArrowLeft from 'loot-design/src/svg/v1/ArrowLeft';
|
||||||
|
|
||||||
function validateStart(allMonths, start, end) {
|
function validateStart(allMonths, start, end) {
|
||||||
|
|
|
@ -1,20 +1,22 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { bindActionCreators } from 'redux';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import * as d from 'date-fns';
|
import * as d from 'date-fns';
|
||||||
|
import { bindActionCreators } from 'redux';
|
||||||
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
import { View, P } from 'loot-design/src/components/common';
|
import { send } from 'loot-core/src/platform/client/fetch';
|
||||||
import { styles } from 'loot-design/src/style';
|
|
||||||
import * as monthUtils from 'loot-core/src/shared/months';
|
import * as monthUtils from 'loot-core/src/shared/months';
|
||||||
import { integerToCurrency } from 'loot-core/src/shared/util';
|
import { integerToCurrency } from 'loot-core/src/shared/util';
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
import { View, P } from 'loot-design/src/components/common';
|
||||||
import Header from './Header';
|
import { styles } from 'loot-design/src/style';
|
||||||
import { fromDateRepr } from './util';
|
|
||||||
import useReport from './useReport';
|
import Change from './Change';
|
||||||
import netWorthSpreadsheet from './graphs/net-worth-spreadsheet';
|
import netWorthSpreadsheet from './graphs/net-worth-spreadsheet';
|
||||||
import NetWorthGraph from './graphs/NetWorthGraph';
|
import NetWorthGraph from './graphs/NetWorthGraph';
|
||||||
import Change from './Change';
|
import Header from './Header';
|
||||||
import { useArgsMemo } from './util';
|
import useReport from './useReport';
|
||||||
|
import { fromDateRepr, useArgsMemo } from './util';
|
||||||
|
|
||||||
function NetWorth({ accounts }) {
|
function NetWorth({ accounts }) {
|
||||||
const [earliestMonth, setEarliestMonth] = useState(null);
|
const [earliestMonth, setEarliestMonth] = useState(null);
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { bindActionCreators } from 'redux';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { bindActionCreators } from 'redux';
|
||||||
import { VictoryBar, VictoryGroup, VictoryVoronoiContainer } from 'victory';
|
import { VictoryBar, VictoryGroup, VictoryVoronoiContainer } from 'victory';
|
||||||
|
|
||||||
import * as actions from 'loot-core/src/client/actions';
|
import * as actions from 'loot-core/src/client/actions';
|
||||||
import { View, Block, AnchorLink } from 'loot-design/src/components/common';
|
|
||||||
import { colors, styles } from 'loot-design/src/style';
|
|
||||||
import * as monthUtils from 'loot-core/src/shared/months';
|
import * as monthUtils from 'loot-core/src/shared/months';
|
||||||
import { integerToCurrency } from 'loot-core/src/shared/util';
|
import { integerToCurrency } from 'loot-core/src/shared/util';
|
||||||
import { useArgsMemo } from './util';
|
import { View, Block, AnchorLink } from 'loot-design/src/components/common';
|
||||||
|
import { colors, styles } from 'loot-design/src/style';
|
||||||
|
|
||||||
|
import Change from './Change';
|
||||||
import theme from './chart-theme';
|
import theme from './chart-theme';
|
||||||
import Container from './Container';
|
import Container from './Container';
|
||||||
|
import DateRange from './DateRange';
|
||||||
|
import { simpleCashFlow } from './graphs/cash-flow-spreadsheet';
|
||||||
|
import netWorthSpreadsheet from './graphs/net-worth-spreadsheet';
|
||||||
|
import NetWorthGraph from './graphs/NetWorthGraph';
|
||||||
import Tooltip from './Tooltip';
|
import Tooltip from './Tooltip';
|
||||||
import useReport from './useReport';
|
import useReport from './useReport';
|
||||||
import netWorthSpreadsheet from './graphs/net-worth-spreadsheet';
|
import { useArgsMemo } from './util';
|
||||||
import { simpleCashFlow } from './graphs/cash-flow-spreadsheet';
|
|
||||||
import NetWorthGraph from './graphs/NetWorthGraph';
|
|
||||||
import Change from './Change';
|
|
||||||
import DateRange from './DateRange';
|
|
||||||
|
|
||||||
function Card({ flex, to, style, children }) {
|
function Card({ flex, to, style, children }) {
|
||||||
const containerProps = { flex, margin: 15 };
|
const containerProps = { flex, margin: 15 };
|
||||||
|
@ -110,7 +113,10 @@ function CashFlowCard() {
|
||||||
const end = monthUtils.currentDay();
|
const end = monthUtils.currentDay();
|
||||||
const start = monthUtils.currentMonth() + '-01';
|
const start = monthUtils.currentMonth() + '-01';
|
||||||
|
|
||||||
const data = useReport('cash_flow_simple', useArgsMemo(simpleCashFlow)(start, end));
|
const data = useReport(
|
||||||
|
'cash_flow_simple',
|
||||||
|
useArgsMemo(simpleCashFlow)(start, end)
|
||||||
|
);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import { VictoryTooltip } from 'victory';
|
|
||||||
import { css, before } from 'glamor';
|
import { css, before } from 'glamor';
|
||||||
|
import { VictoryTooltip } from 'victory';
|
||||||
|
|
||||||
import { colors } from 'loot-design/src/style';
|
import { colors } from 'loot-design/src/style';
|
||||||
|
|
||||||
class Tooltip extends React.Component {
|
class Tooltip extends React.Component {
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import * as d from 'date-fns';
|
||||||
import {
|
import {
|
||||||
VictoryChart,
|
VictoryChart,
|
||||||
VictoryBar,
|
VictoryBar,
|
||||||
|
@ -7,11 +9,12 @@ import {
|
||||||
VictoryVoronoiContainer,
|
VictoryVoronoiContainer,
|
||||||
VictoryGroup
|
VictoryGroup
|
||||||
} from 'victory';
|
} from 'victory';
|
||||||
import * as d from 'date-fns';
|
|
||||||
|
import { colors } from 'loot-design/src/style';
|
||||||
|
|
||||||
|
import theme from '../chart-theme';
|
||||||
import Container from '../Container';
|
import Container from '../Container';
|
||||||
import Tooltip from '../Tooltip';
|
import Tooltip from '../Tooltip';
|
||||||
import theme from '../chart-theme';
|
|
||||||
import { colors } from 'loot-design/src/style';
|
|
||||||
|
|
||||||
function CashFlowGraph({ style, start, end, graphData, isConcise, compact }) {
|
function CashFlowGraph({ style, start, end, graphData, isConcise, compact }) {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import * as d from 'date-fns';
|
||||||
import {
|
import {
|
||||||
VictoryChart,
|
VictoryChart,
|
||||||
VictoryBar,
|
VictoryBar,
|
||||||
|
@ -7,10 +9,10 @@ import {
|
||||||
VictoryVoronoiContainer,
|
VictoryVoronoiContainer,
|
||||||
VictoryGroup
|
VictoryGroup
|
||||||
} from 'victory';
|
} from 'victory';
|
||||||
import * as d from 'date-fns';
|
|
||||||
|
import theme from '../chart-theme';
|
||||||
import Container from '../Container';
|
import Container from '../Container';
|
||||||
import Tooltip from '../Tooltip';
|
import Tooltip from '../Tooltip';
|
||||||
import theme from '../chart-theme';
|
|
||||||
|
|
||||||
function Area({ start, end, data, style, scale, range }) {
|
function Area({ start, end, data, style, scale, range }) {
|
||||||
const zero = scale.y(0);
|
const zero = scale.y(0);
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import * as monthUtils from 'loot-core/src/shared/months';
|
|
||||||
import * as d from 'date-fns';
|
import * as d from 'date-fns';
|
||||||
import { AlignedText } from 'loot-design/src/components/common';
|
|
||||||
import { integerToCurrency, integerToAmount } from 'loot-core/src/shared/util';
|
|
||||||
import q from 'loot-core/src/client/query-helpers';
|
import q from 'loot-core/src/client/query-helpers';
|
||||||
|
import * as monthUtils from 'loot-core/src/shared/months';
|
||||||
|
import { integerToCurrency, integerToAmount } from 'loot-core/src/shared/util';
|
||||||
|
import { AlignedText } from 'loot-design/src/components/common';
|
||||||
|
|
||||||
import { fromDateRepr, fromDateReprToDay, runAll, index } from '../util';
|
import { fromDateRepr, fromDateReprToDay, runAll, index } from '../util';
|
||||||
|
|
||||||
export function simpleCashFlow(start, end) {
|
export function simpleCashFlow(start, end) {
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mergeObjects, flattenArray } from 'loot-core/src/shared/util';
|
|
||||||
import * as monthUtils from 'loot-core/src/shared/months';
|
|
||||||
import * as d from 'date-fns';
|
import * as d from 'date-fns';
|
||||||
import { AlignedText } from 'loot-design/src/components/common';
|
|
||||||
import q, { runQuery } from 'loot-core/src/client/query-helpers';
|
import q, { runQuery } from 'loot-core/src/client/query-helpers';
|
||||||
|
import * as monthUtils from 'loot-core/src/shared/months';
|
||||||
import {
|
import {
|
||||||
integerToCurrency,
|
integerToCurrency,
|
||||||
integerToAmount,
|
integerToAmount,
|
||||||
amountToInteger
|
amountToInteger
|
||||||
} from 'loot-core/src/shared/util';
|
} from 'loot-core/src/shared/util';
|
||||||
import { fromDateRepr, runAll, index } from '../util';
|
import { AlignedText } from 'loot-design/src/components/common';
|
||||||
|
|
||||||
|
import { index } from '../util';
|
||||||
|
|
||||||
export default function createSpreadsheet(start, end, accounts) {
|
export default function createSpreadsheet(start, end, accounts) {
|
||||||
return async (spreadsheet, setData) => {
|
return async (spreadsheet, setData) => {
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Route } from 'react-router-dom';
|
import { Route } from 'react-router-dom';
|
||||||
|
|
||||||
import { View } from 'loot-design/src/components/common';
|
import { View } from 'loot-design/src/components/common';
|
||||||
import Overview from './Overview';
|
|
||||||
import NetWorth from './NetWorth';
|
|
||||||
import CashFlow from './CashFlow';
|
import CashFlow from './CashFlow';
|
||||||
|
import NetWorth from './NetWorth';
|
||||||
|
import Overview from './Overview';
|
||||||
|
|
||||||
class Reports extends React.Component {
|
class Reports extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import q, { runQuery } from 'loot-core/src/client/query-helpers';
|
|
||||||
|
import { runQuery } from 'loot-core/src/client/query-helpers';
|
||||||
|
|
||||||
export function useArgsMemo(func) {
|
export function useArgsMemo(func) {
|
||||||
return (...args) => {
|
return (...args) => {
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
import React, { useCallback, useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
|
||||||
import { useLocation, useHistory } from 'react-router-dom';
|
import { useLocation, useHistory } from 'react-router-dom';
|
||||||
import q, { runQuery } from 'loot-core/src/client/query-helpers';
|
|
||||||
import Platform from 'loot-core/src/client/platform';
|
import Platform from 'loot-core/src/client/platform';
|
||||||
import { useSchedules } from 'loot-core/src/client/data-hooks/schedules';
|
import q, { runQuery } from 'loot-core/src/client/query-helpers';
|
||||||
import { send } from 'loot-core/src/platform/client/fetch';
|
import { send } from 'loot-core/src/platform/client/fetch';
|
||||||
|
import { getRecurringDescription } from 'loot-core/src/shared/schedules';
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Text,
|
|
||||||
Stack,
|
Stack,
|
||||||
Button,
|
Button,
|
||||||
ButtonWithLoading,
|
ButtonWithLoading,
|
||||||
|
@ -18,19 +17,18 @@ import {
|
||||||
TableHeader,
|
TableHeader,
|
||||||
Row,
|
Row,
|
||||||
Field,
|
Field,
|
||||||
Cell,
|
|
||||||
SelectCell
|
SelectCell
|
||||||
} from 'loot-design/src/components/table';
|
} from 'loot-design/src/components/table';
|
||||||
import { getRecurringDescription } from 'loot-core/src/shared/schedules';
|
|
||||||
import { colors, styles } from 'loot-design/src/style';
|
|
||||||
import useSelected, {
|
import useSelected, {
|
||||||
useSelectedDispatch,
|
useSelectedDispatch,
|
||||||
useSelectedItems,
|
useSelectedItems,
|
||||||
SelectedProvider
|
SelectedProvider
|
||||||
} from 'loot-design/src/components/useSelected';
|
} from 'loot-design/src/components/useSelected';
|
||||||
|
import { colors } from 'loot-design/src/style';
|
||||||
|
|
||||||
import { Page } from '../Page';
|
import { Page } from '../Page';
|
||||||
import { ScheduleAmountCell } from './SchedulesTable';
|
|
||||||
import DisplayId from '../util/DisplayId';
|
import DisplayId from '../util/DisplayId';
|
||||||
|
import { ScheduleAmountCell } from './SchedulesTable';
|
||||||
|
|
||||||
let ROW_HEIGHT = 43;
|
let ROW_HEIGHT = 43;
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue