Compare commits

...

147 commits

Author SHA1 Message Date
James Long
3edf947145 Accidentally only build the sourcemap for API bundle 2022-12-08 15:59:12 -05:00
James Long
b34dfb15b2 @actual-app/api 4.1.4 2022-12-08 15:55:29 -05:00
James Long
8b1c5777ad Include the API bundle when publishing 2022-12-08 15:55:05 -05:00
James Long
94c195abb9 Fix API version 2022-12-03 23:34:31 -05:00
James Long
7c1c9bf03a Ignore API bundle 2022-12-03 23:32:57 -05:00
James Long
8f7625831f Prettier 2022-12-03 23:26:11 -05:00
James Long
15e2f2dce7 v22.12.03 2022-12-03 23:26:11 -05:00
Matiss Janis Aboltins
29fb2cc641 Update Account.js 2022-12-03 23:06:59 -05:00
Matiss Janis Aboltins
2566b950c2 feat: ability to add notes to accounts 2022-12-03 23:06:59 -05:00
shall0pass
ba71c1ba05 another 2022-12-03 23:03:19 -05:00
shall0pass
fcde52a9c7 cleanup 2022-12-03 23:03:19 -05:00
shall0pass
94dbbbc68b cleanup 2022-12-03 23:03:19 -05:00
shall0pass
16e01a8f58 fix 2022-12-03 23:03:19 -05:00
shall0pass
a9218e1625 removed additional function 2022-12-03 23:03:19 -05:00
shall0pass
0a61acdf8f Remove the hold for future months button 2022-12-03 23:03:19 -05:00
James Long
157b58a2dd Import only what's needed from the API for importer packages 2022-12-02 10:36:56 -05:00
Matiss Janis Aboltins
7b6909eaa6 fix: add default value to be even more secure against future regressions 2022-11-20 22:49:11 -05:00
Matiss Janis Aboltins
3133ddcda3 fix(useSheetValue): default value should be null not undefined
Fixes #393
2022-11-20 22:49:11 -05:00
James Long
4904da5006 Remove console 2022-11-14 18:01:08 -05:00
James Long
a72ee51e1a Always pull in API package from workspace (fixes #378) 2022-11-14 18:01:08 -05:00
Rich Howell
bf03dfc1cc
Merge pull request #272 from rickdoesdev/master
a11y: update cleared state display for clarity
2022-11-13 18:34:21 +00:00
James Long
a157679906 Fix test 2022-11-12 22:33:49 -05:00
James Long
a4a7803407 Fix lint 2022-11-12 22:33:49 -05:00
James Long
2d9b319e45 Move safeNumber to shared util and tweak implementation 2022-11-12 22:33:49 -05:00
Tom French
4b83552ddf feat: add explicit value checking on saving to / reading from budget 2022-11-12 22:33:49 -05:00
Tom French
5f0da9deb8 fix: replace last usages of | 0 2022-11-12 22:33:49 -05:00
Tom French
e903f5c20d fix: remove unnecessary conversion to 32 bit 2022-11-12 22:33:49 -05:00
Tom French
04aa1731b5 fix: use Math.round in place of truncating digits 2022-11-12 22:33:49 -05:00
Tom French
bb9c9927db fix: use Math.round in place of truncating digits 2022-11-12 22:33:49 -05:00
Tom French
696a094303 fix: replace custom isInteger function with Number.isInteger 2022-11-12 22:33:49 -05:00
Tom French
4421f2a173 fix: use 64bit compatible integer check in aql compiler 2022-11-12 22:33:49 -05:00
Tom French
f1b61cf6f1 fix: use integer check which doesn't require value to be 32 bit 2022-11-12 22:33:49 -05:00
Rich Howell
6075e846d3
Merge pull request #266 from j-f1/update-data-file-index
Update data-file-index.txt
2022-11-12 15:36:42 +00:00
Rich Howell
2857e65ccd
Merge pull request #218 from ezfe/master
Fix enter to create accounts
2022-11-12 15:34:57 +00:00
Rich Howell
29124f624b
Merge pull request #389 from shall0pass/help_button
Add a help button to the menu
2022-11-12 15:05:08 +00:00
shall0pass
aa97994ad2 fix linting error 2022-11-12 04:53:15 -06:00
shall0pass
be3dc26166 launch in separate tab 2022-11-11 18:24:28 -06:00
shall0pass
9ce6f9564c add help button 2022-11-11 18:06:49 -06:00
James Long
12289792da 22.10.25 2022-10-25 10:04:19 -04:00
James Long
c8e759fd49 4.1.1 2022-10-25 02:10:57 -04:00
Rich Howell
2256653c16
Merge pull request #373 from rich-howell/remove-docs
Remove documentation
2022-10-23 12:54:13 +01:00
Rich In SQL
182c77a8e3 Remove documentation 2022-10-23 12:48:52 +01:00
Rich Howell
de232b3ff0
Merge pull request #368 from rich-howell/readme-updates
Update README.md
2022-10-21 19:11:48 +01:00
Rich In SQL
a582975d71 Update README.md
Readme updates
2022-10-21 10:26:47 +01:00
Rich Howell
93f0093c1d
Update stale.yml
Removed auto close
2022-10-20 07:37:53 +01:00
Rich Howell
0e441eeed2
Update stale.yml 2022-10-19 18:48:11 +01:00
Rich Howell
f190443272
Create stale.yml 2022-10-19 18:47:08 +01:00
Rick Cuddy
603179dda1 a11y: update cleared state display for clarity
Create new CircleEmpty svg and set uncleared state to use new icon.

Add 'cursor: pointer' to the cleared field to aid in action awareness.
2022-10-12 19:22:24 +11:00
Jed Fox
fd3c0f9b18
Update data-file-index.txt 2022-10-07 12:05:23 -04:00
James Long
d98b8c1d73 Render a schedule rule with the mapped payee id; fixes crash 2022-10-05 20:14:04 -04:00
Tom French
c9a543310d
Remove dollar sign from close account modal (#244) 2022-09-06 11:02:56 +01:00
Tom French
5a00bf6b43
ci: fix CI to an exact node version (#240) 2022-09-02 20:28:33 +01:00
Tom French
9c0df36e16
Sort import in alphabetical order (#238)
* style: enforce sorting of imports

* style: alphabetize imports

* style: merge duplicated imports
2022-09-02 15:07:24 +01:00
Tom French
dc53a74459
Separate external, monorepo and internal imports (#237)
* style: enforce ordering of imports

* style: sort imports in loot-core

* style: sort imports in desktop-client

* style: sort imports in loot-design

* style: manual fixes
2022-09-02 12:43:37 +01:00
Ezekiel Elin
ecd91b8f8e
Allow enter to create new transaction when focused on cleared column (#234) 2022-09-01 14:11:31 +01:00
Tom French
4c0bd80f24
Enforce linting in loot-design (#233)
* build: add linter to loot-design package

* style: automated fixes

* style: manual linter fixes
2022-09-01 12:47:34 +01:00
Tom French
01d0eb2f0a
style: run linter (#232) 2022-08-31 23:32:25 +01:00
Tom French
0fcfffea57
refactor: create index.js for aql directory (#68) 2022-08-31 22:46:28 +01:00
Tom French
4be86c3d42
Revert "build: update yarn.lock" (#230)
This reverts commit ae8ef2674f.

Revert "Merge pull request #204 from TomAFrench/yarn-workspace-dependencies"

This reverts commit b0ed8d5149, reversing
changes made to 5505a1439a.
2022-08-31 22:44:52 +01:00
Jed Fox
9e7f94a237
Fix handling of -0 in budget summary (#229)
* Fix handling of -0 in budget summary

* Update based on review

Co-Authored-By: Tom French <15848336+TomAFrench@users.noreply.github.com>
2022-08-31 22:38:16 +01:00
Rich Howell
f09f2dfe7b
Update bug-report.yml (#228)
Added Mac OSX and updated description
2022-08-31 19:10:01 +01:00
Tom French
89128faf3f
Merge pull request #164 from bdoherty/windows
build on windows
2022-08-30 21:52:16 +01:00
Tom French
ea2ab1428d
Merge pull request #222 from TomAFrench/remove-unused-patch-dependency
Remove patch-package dependency from loot-design
2022-08-30 21:51:20 +01:00
Tom French
e638cdf467
fix: use correct comment style 2022-08-30 20:35:57 +01:00
Tom French
d293613645 build: remove patch-package dependency from loot-design 2022-08-30 20:33:17 +01:00
bdoherty
18e6eac116
Conditionally set MSYS
Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>
2022-08-31 07:31:03 +12:00
Tom French
ae8ef2674f build: update yarn.lock 2022-08-30 17:07:38 +01:00
Tom French
b0ed8d5149
Merge pull request #204 from TomAFrench/yarn-workspace-dependencies
Use workspace ranges for monorepo dependencies
2022-08-30 16:35:57 +01:00
Tom French
fecca411b0
Merge branch 'master' into windows 2022-08-30 15:07:32 +01:00
Tom French
5505a1439a
Merge pull request #217 from TomAFrench/remove-unused-imports
Remove unused imports and sort imports in desktop-client
2022-08-30 10:19:04 +01:00
Ezekiel Elin
55b9a0e7ef Fix enter to create accounts 2022-08-29 23:47:07 -04:00
Tom French
b552929b29
Merge pull request #214 from trevdor/adm-zip-upgrade
Fix adm-zip install failure
2022-08-30 01:35:23 +01:00
Tom French
887df1e388 refactor: sort imports in desktop-client alphabetically 2022-08-30 01:27:10 +01:00
Tom French
8e41d8d2dd chore: remove unused imports from desktop-client 2022-08-30 01:24:32 +01:00
Trevor Farlow
3773ab9892
adm-zip to 0.5.6 2022-08-26 10:10:15 -06:00
Tom French
be6780f90b
Merge pull request #213 from TomAFrench/lint-desktop-client
Enforce linting in desktop-client
2022-08-25 16:44:32 +01:00
Tom French
1d0b2721db style: prettify .eslintrc.js 2022-08-25 16:36:02 +01:00
Tom French
677faa611d build: make eslint-plugin-prettier a dependency of desktop-client 2022-08-25 16:35:48 +01:00
Tom French
4f0bfe4a1f ci: lint desktop-client in CI 2022-08-25 16:21:26 +01:00
Tom French
3ee7ae16cc style: fix or silence linting errors in desktop-client 2022-08-25 16:20:09 +01:00
Tom French
01be80d562
Merge pull request #203 from TomAFrench/ts-jest
Replace babel-jest with ts-jest
2022-08-24 21:31:21 +01:00
Tom French
d61457716e chore: update remaining test scripts 2022-08-24 21:27:47 +01:00
Tom French
6f86bd77e8 github fix indentation in issue template 2022-08-24 21:25:48 +01:00
Tom French
d83c75d1ae github: update issue template 2022-08-24 21:24:13 +01:00
Tom French
40dbab3732
Merge pull request #208 from rich-howell/master
Bug Report Template & Issues Configuration
2022-08-24 21:19:13 +01:00
Tom French
203ab791f2 fix: correct some re-exports which were breaking things 2022-08-24 21:15:16 +01:00
Tom French
c77273742b fix: stop trying to transform node_modules 2022-08-24 21:15:00 +01:00
Tom French
0e0b46ed5e fix: stop the web tests from running in node environment 2022-08-24 21:14:16 +01:00
Tom French
3118cf26e3 fix: add ts-jest presets which are equivalent to the old transform properties 2022-08-24 21:13:04 +01:00
Tom French
2cedd68e69 fix: add esModuleInterop so that the default imports issue goes away 2022-08-24 21:09:45 +01:00
Tom French
b73ef9153f fix: stop typechecking javascript files
We've got a bunch of type errors that need to be fixed but we want to do that progressively
2022-08-24 21:09:16 +01:00
Tom French
102d92048b chore: allow mobile package to pass with no tests 2022-08-24 20:21:35 +01:00
Tom French
9be15eaee1 build: replace babel-jest with ts-jest 2022-08-24 20:21:35 +01:00
Tom French
e3ee0c61a6
Merge pull request #137 from TomAFrench/skip-failing-test-suites
Skip failing test suites
2022-08-24 20:20:20 +01:00
Tom French
c7a32ec8d0
Update bug-report.yml 2022-08-24 20:18:32 +01:00
Rich Howell
a94def9c55
Merge branch 'actualbudget:master' into master 2022-08-24 18:12:38 +01:00
Rich In SQL
6d31a1cda9 Addition: Issue template
Issue template and configuration.
2022-08-24 18:11:56 +01:00
Tom French
31e2b01df3
Merge pull request #129 from TomAFrench/issue-triage-action
Add action to mark new issues for triage
2022-08-24 17:52:46 +01:00
Tom French
7fa62b431c
Merge pull request #124 from andremralves/fix/hitting-enter-on-bootstrap-page
fix: hitting enter after setting password redirects to demo page
2022-08-24 00:31:02 +01:00
Tom French
f7c977dc12 build: use workspace ranges for monorepo dependencies 2022-08-24 00:07:06 +01:00
Tom French
fc125712dd
Merge pull request #202 from TomAFrench/github-action-test-2
Run tests on github actions
2022-08-23 18:23:56 +01:00
Tom French
5a49d65b72 test: skip failing test suites 2022-08-23 17:25:56 +01:00
Tom French
c40b5e4d5d ci: run tests on github actions 2022-08-23 17:14:46 +01:00
Tom French
973868c654
Merge pull request #139 from TomAFrench/remove-rollup
Remove unused rollup config and dependencies
2022-08-23 16:58:03 +01:00
Tom French
3f0addc78e chore: remove unused rollup config and dependencies 2022-08-23 16:19:29 +01:00
Tom French
16daa294b5
Merge pull request #135 from TomAFrench/remove-unused-deps
Remove unused dependencies
2022-08-23 16:18:29 +01:00
Tom French
26ff01f4c9 Merge branch 'master' into remove-unused-deps
* master:
  style: apply prettier fixes
  style: switch prettier to enforce single quotes
  style: enforce prettier rules in linter
  chore: silence erroneous warning for missing moment.js install
  fix: revert remaining changed weights
  fix: revert changes to weights and pin fast-check version to 2.13.0
  test: make all frequency weights be integer values
2022-08-23 16:13:15 +01:00
Tom French
e54b762e31
Merge pull request #102 from TomAFrench/fix-splitfreq-weights
Fix test failure due to non-integer weight values
2022-08-23 16:04:40 +01:00
Tom French
8f3e9d4b37 Merge branch 'master' into fix-splitfreq-weights
* master:
  style: apply prettier fixes
  style: switch prettier to enforce single quotes
  style: enforce prettier rules in linter
  chore: silence erroneous warning for missing moment.js install
2022-08-23 15:57:50 +01:00
Tom French
b230c52f92
Merge pull request #131 from TomAFrench/silence-moment-errors
Silence warning for missing moment.js install
2022-08-23 15:55:07 +01:00
Tom French
db818f78fa
Merge pull request #130 from TomAFrench/prettier
Enforce prettier rules
2022-08-23 15:54:26 +01:00
Tom French
57e0d713da Merge branch 'master' into fix-splitfreq-weights
* master: (39 commits)
  fix: correct import of merkle in test
  chore: move snapshot to new dir
  refactor: move crdt files into separate directory
  revert: revert pruning of svg imports
  style: nicer re-exporting syntax
  refactor: remove unused imports
  chore: update package scripts to take advantage of yarn v3
  build: add missing eslint dependency to loot-core
  build: add cross-env dependency to desktop-client package.json
  build: remove deprecated nohoist settings and prevent hoisting of mobile dependencies
  fix: move downshift patch to monorepo root
  CI: update CI definition to use yarn v3
  fix: wrap glob in quotes so that it's properly passed to npm-run-all
  chore: update root yarn scripts to use `workspace` command instead of cd
  chore: fix broken builds
  chore: update to yarnv3 and fix missing packages preventing install
  Force react-error-overlay to 6.0.9 to fix error
  Add docs for building for windows (contributed by @ejmurra)
  add: tsconfig.json
  build: replace jwl-dev-utils with react-dev-utils
  ...
2022-08-23 12:37:46 +01:00
Tom French
8d0872c7a4 Merge branch 'master' into prettier
* master:
  fix: correct import of merkle in test
  chore: move snapshot to new dir
  refactor: move crdt files into separate directory
  revert: revert pruning of svg imports
  style: nicer re-exporting syntax
  refactor: remove unused imports
  chore: update package scripts to take advantage of yarn v3
  build: add missing eslint dependency to loot-core
  build: add cross-env dependency to desktop-client package.json
  build: remove deprecated nohoist settings and prevent hoisting of mobile dependencies
  fix: move downshift patch to monorepo root
  CI: update CI definition to use yarn v3
  fix: wrap glob in quotes so that it's properly passed to npm-run-all
  chore: update root yarn scripts to use `workspace` command instead of cd
  chore: fix broken builds
  chore: update to yarnv3 and fix missing packages preventing install
  Force react-error-overlay to 6.0.9 to fix error
  Add docs for building for windows (contributed by @ejmurra)
  add: tsconfig.json
2022-08-23 12:31:04 +01:00
Tom French
0c6304572c build: remove more unused dependencies 2022-08-23 12:24:31 +01:00
Tom French
93a3543464 build: remove unused dependencies 2022-08-23 12:24:03 +01:00
Tom French
8a91006c7b fix: correct import of merkle in test 2022-08-22 23:09:08 -04:00
Tom French
0dcff8e671 chore: move snapshot to new dir 2022-08-22 23:09:08 -04:00
Tom French
6967698d32 refactor: move crdt files into separate directory 2022-08-22 23:09:08 -04:00
Tom French
fc4f120487 revert: revert pruning of svg imports 2022-08-22 22:51:01 -04:00
Tom French
88590dccaa style: nicer re-exporting syntax 2022-08-22 22:51:01 -04:00
Tom French
d705cd351b refactor: remove unused imports 2022-08-22 22:51:01 -04:00
Tom French
3e9cfece83 chore: update package scripts to take advantage of yarn v3 2022-08-22 22:35:07 -04:00
Tom French
1fb6e193f0 build: add missing eslint dependency to loot-core 2022-08-22 22:35:07 -04:00
Tom French
2d9091f179 build: add cross-env dependency to desktop-client package.json 2022-08-22 22:35:07 -04:00
Tom French
58a0910996 build: remove deprecated nohoist settings and prevent hoisting of mobile dependencies 2022-08-22 22:35:07 -04:00
Tom French
aa4d05ece6 fix: move downshift patch to monorepo root 2022-08-22 22:35:07 -04:00
Tom French
2eb4408872 CI: update CI definition to use yarn v3 2022-08-22 22:35:07 -04:00
Tom French
5c96635d79 fix: wrap glob in quotes so that it's properly passed to npm-run-all 2022-08-22 22:35:07 -04:00
Tom French
5dad1070b6 chore: update root yarn scripts to use workspace command instead of cd 2022-08-22 22:35:07 -04:00
Tom French
b41ee56c81 chore: fix broken builds 2022-08-22 22:35:07 -04:00
Tom French
ce5ee1b877 chore: update to yarnv3 and fix missing packages preventing install 2022-08-22 22:35:07 -04:00
Rich Howell
969901103f
Delete ISSUE_TEMPLATE directory 2022-08-21 09:57:16 +01:00
Rich Howell
399aac7c91
Create bug_report.md 2022-08-21 09:57:01 +01:00
James Long
2358c0875d Force react-error-overlay to 6.0.9 to fix error 2022-08-15 11:23:51 -04:00
Brendan Doherty
90f7a205a6 changes needed to build on windows 2022-08-13 05:48:24 +12:00
James Long
a92e740c88 Add docs for building for windows (contributed by @ejmurra) 2022-08-12 09:48:38 -04:00
Wout Mertens
ac1e2b3c79 add: tsconfig.json
This configures TS to look at JS files as well, so that IDEs like VSCode
can provide better edit-time checks
2022-08-12 09:29:18 -04:00
Tom French
d30067b5b9 style: apply prettier fixes 2022-07-24 08:53:05 +01:00
Tom French
5977e020f0 style: switch prettier to enforce single quotes
This is the style predominantly used in the codebase currently.
2022-07-24 08:53:04 +01:00
Tom French
a44834c0d3 style: enforce prettier rules in linter 2022-07-24 08:53:04 +01:00
Tom French
55870be101 chore: silence erroneous warning for missing moment.js install 2022-07-17 17:03:57 +01:00
Tom French
c1761b9302 ci: add action to mark new issues for triage 2022-07-16 11:03:59 +01:00
Tom French
91967ef920 fix: revert remaining changed weights 2022-07-16 10:31:26 +01:00
Tom French
c6335b4f57 Merge branch 'master' into fix-splitfreq-weights
* master: (43 commits)
  build: move dev dependencies from dependencies array and remove unused dependencies
  build: fix offical node version to 16.15.0
  chore: delete unused directory `browser/build`
  docs: remove holiday text from README
  build: update downshift patch to match installed version
  style: revert to using var to minimise diff
  style: replace var with const
  fix: enforce proper length constraints on timestamp counter and node id
  test: fix test to properly pass in invalid inputs individually
  ci: re-add runner os specific caches
  ci: turn boilerplate into composite action
  ci: only build electron app on master
  docs: add comment explaining how to reactivate code signing
  build: remove signing config
  ci: avoid attempting to get CSC_KEY_PASSWORD interactively in github actions
  ci: always use bash as the shell
  ci: cache node_modules per runner os
  ci: avoid duplicate linting in CI
  ci: add electron build to CI
  ci: build api and web packages in CI
  ...
2022-07-08 21:21:51 +01:00
Tom French
2846166a8e fix: revert changes to weights and pin fast-check version to 2.13.0 2022-07-08 21:19:48 +01:00
Andre Alves
a2b67cb153 fix: hitting enter after setting password redirects to demo page 2022-07-06 14:51:03 -03:00
Tom French
c94749aace test: make all frequency weights be integer values 2022-06-27 01:20:14 +01:00
446 changed files with 27756 additions and 87525 deletions

View file

@ -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
View 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
View 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
View 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

View file

@ -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

View 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
View 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
View 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
View file

@ -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
View file

@ -0,0 +1,4 @@
{
"singleQuote": true,
"trailingComma": "none"
}

File diff suppressed because one or more lines are too long

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
View 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

View file

@ -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).

View file

@ -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

View file

@ -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"

View file

@ -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();
```

View file

@ -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
```

View file

@ -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']
});

View file

@ -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
});

View file

@ -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'
]
};

View file

@ -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
View 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

View file

@ -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 } = {}) {

View file

@ -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",

View file

@ -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) {

View file

@ -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,

View file

@ -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"

View file

@ -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

View file

@ -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';

View file

@ -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 = {

View file

@ -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 (

View file

@ -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';

View file

@ -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 }) {

View file

@ -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;

View file

@ -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 }}>

View file

@ -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

View file

@ -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);

View file

@ -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';

View file

@ -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 {

View file

@ -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,

View file

@ -1,4 +1,5 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { import {
View, View,
Text, Text,

View file

@ -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,

View file

@ -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 (

View file

@ -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' });

View file

@ -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';

View file

@ -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);

View file

@ -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 (

View file

@ -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

View 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();

View file

@ -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;

View file

@ -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 = {

View file

@ -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';

View file

@ -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={{ style={{
fontSize: 25, flexDirection: 'row',
fontWeight: 500, alignItems: 'center',
marginLeft: -5, gap: 3,
marginTop: -5, '& .hover-visible': {
backgroundColor: 'transparent', opacity: 0,
'& svg': { display: 'none' }, transition: 'opacity .25s'
'&:hover svg': { display: 'unset' } },
'&:hover .hover-visible': {
opacity: 1
}
}} }}
onClick={() => onExposeName(true)}
> >
{accountName} <View
<Pencil1
style={{ style={{
width: 11, fontSize: 25,
height: 11, fontWeight: 500,
marginLeft: 5, marginRight: 5,
color: colors.n4 marginBottom: 5
}} }}
/> >
</Button> {accountName}
</View>
<NotesButton id={`account-${account.id}`} />
<Button
bare
className="hover-visible"
onClick={() => onExposeName(true)}
>
<Pencil1
style={{
width: 11,
height: 11,
color: colors.n8
}}
/>
</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}

View file

@ -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) {

View file

@ -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}

View file

@ -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) {

View file

@ -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:

View file

@ -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)
) { ) {

View file

@ -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')];

View file

@ -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 }) {

View file

@ -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 }}>

View file

@ -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;

View file

@ -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`

View file

@ -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();

View file

@ -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,17 +231,14 @@ class ManagementApp extends React.Component {
} }
} }
export default connect( export default connect(state => {
state => { let { modalStack } = state.modals;
let { modalStack } = state.modals;
return { return {
files: state.budgets.allFiles, files: state.budgets.allFiles,
userData: state.user.data, userData: state.user.data,
managerHasInitialized: state.app.managerHasInitialized, managerHasInitialized: state.app.managerHasInitialized,
loadingText: state.app.loadingText, loadingText: state.app.loadingText,
currentModals: modalStack.map(modal => modal.name) currentModals: modalStack.map(modal => modal.name)
}; };
}, }, actions)(ManagementApp);
actions
)(ManagementApp);

View file

@ -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,

View file

@ -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);

View file

@ -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();

View file

@ -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();

View file

@ -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>

View file

@ -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) {

View file

@ -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();

View file

@ -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

View file

@ -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 };

View file

@ -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 {

View file

@ -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,

View file

@ -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));

View file

@ -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,

View file

@ -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}`;
}} }}
/> />

View file

@ -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 };

View file

@ -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);

View file

@ -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,

View file

@ -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);

View file

@ -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 (

View file

@ -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;

View file

@ -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);

View file

@ -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) {

View file

@ -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);

View file

@ -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;
} }
@ -218,9 +224,9 @@ function CashFlowCard() {
function Overview({ accounts }) { function Overview({ accounts }) {
return ( return (
<View <View
style={[ style={[
styles.page, styles.page,
{ paddingLeft: 40, paddingRight: 40, minWidth: 700 } { paddingLeft: 40, paddingRight: 40, minWidth: 700 }
]} ]}
> >
<View <View

View file

@ -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 {

View file

@ -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 (

View file

@ -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);

View file

@ -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) {

View file

@ -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) => {

View file

@ -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() {

View file

@ -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) => {

View file

@ -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