Compare commits

...

301 Commits

Author SHA1 Message Date
Zach Gollwitzer
b75b41a5e2 Bump to v0.2.0-alpha.1
Signed-off-by: Zach Gollwitzer <zach@maybe.co>
2024-10-25 09:37:50 -04:00
bruno costanzo
2cc89195bf Feature | Filter on uncategorized transactions (#1359)
* allow filtering uncategorized transactions

* user can filter uncategorized transactions test

* rubocop linting
2024-10-25 09:37:05 -04:00
Josh Pigford
aa3342b0dc Stock imports (#1363)
* Initial pass

* Marketstack data provider

* Marketstack data provider

* Refactor a bit
2024-10-24 16:36:50 -05:00
Zach Gollwitzer
b611dfdf37 Add back good job dashboard with auth (#1364) 2024-10-24 17:28:29 -04:00
Zach Gollwitzer
ba49fea89a Locale updates 2024-10-24 16:43:59 -04:00
Zach Gollwitzer
89e107e36c Remove good job dashboard route 2024-10-24 15:56:58 -04:00
Zach Gollwitzer
d93fbbcaa8 Fix tooltip on charts 2024-10-24 12:06:42 -04:00
Josh Pigford
e6403fab70 Modal design tweaks 2024-10-24 10:16:24 -05:00
Zach Gollwitzer
6baffe7539 Beta Testing Round 3 Bug Fixes (#1357)
* Clean up env example files

* Fix duplicate category creations

* Fix duplicate tag and merchant creation

* Add initial valuation to imported accounts

* Add upgrade modal prompt

* Don't hide content on billing page

* Add temporary session for new customers

* Lint fixes

* Fix unused translations

* Fix system tests
2024-10-24 11:02:27 -04:00
Zach Gollwitzer
1d20de770f User Onboarding + Bug Fixes (#1352)
* Bump min supported date to 20 years

* Add basic onboarding

* User onboarding

* Complete onboarding flow

* Cleanup, add user profile update test
2024-10-23 11:20:55 -04:00
Josh Pigford
73e184ad3d Stock Exchanges with seed (#1351)
* Stock Exchanges with seed

* Run the seed file on migration

* Fix for enum column
2024-10-22 14:30:57 -05:00
dependabot[bot]
d3a6f7e0f0 Bump tailwindcss-rails from 2.7.9 to 3.0.0 (#1341)
Bumps [tailwindcss-rails](https://github.com/rails/tailwindcss-rails) from 2.7.9 to 3.0.0.
- [Release notes](https://github.com/rails/tailwindcss-rails/releases)
- [Changelog](https://github.com/rails/tailwindcss-rails/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rails/tailwindcss-rails/compare/v2.7.9...v3.0.0)

---
updated-dependencies:
- dependency-name: tailwindcss-rails
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-22 15:11:26 -04:00
Josh Pigford
9313620968 Updated Synth env variable description 2024-10-22 13:10:51 -05:00
Josh Pigford
a4e87ffb4d Delete extensions.json 2024-10-21 20:20:52 -05:00
Zach Gollwitzer
728b10d08e Fix trade import mapping bug 2024-10-21 12:26:39 -04:00
dependabot[bot]
a27b17deae Bump ruby-lsp-rails from 0.3.19 to 0.3.20 (#1339)
Bumps [ruby-lsp-rails](https://github.com/Shopify/ruby-lsp-rails) from 0.3.19 to 0.3.20.
- [Release notes](https://github.com/Shopify/ruby-lsp-rails/releases)
- [Commits](https://github.com/Shopify/ruby-lsp-rails/compare/v0.3.19...v0.3.20)

---
updated-dependencies:
- dependency-name: ruby-lsp-rails
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-21 10:14:05 -04:00
Nico
1b654faf9a Fixes issue with mapping values during the transactions import (#1327)
* Adds custom debounce timeout to autosubmit form controller

- There's a default debounce timeout based on element type
- You can parameterize debounce timeout on a data-attribute

* Adds corrections based on js_lint

* Restores sleep on test

---------

Co-authored-by: Nicolás Galdámez <nicolas.galdamez@unagisoftware.com>
2024-10-21 10:13:55 -04:00
dependabot[bot]
9b6a2cce56 Bump turbo-rails from 2.0.10 to 2.0.11 (#1343)
Bumps [turbo-rails](https://github.com/hotwired/turbo-rails) from 2.0.10 to 2.0.11.
- [Release notes](https://github.com/hotwired/turbo-rails/releases)
- [Commits](https://github.com/hotwired/turbo-rails/compare/v2.0.10...v2.0.11)

---
updated-dependencies:
- dependency-name: turbo-rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-21 10:12:35 -04:00
dependabot[bot]
5ff9012d3e Bump rails from 7.2.1 to 7.2.1.1 (#1340)
Bumps [rails](https://github.com/rails/rails) from 7.2.1 to 7.2.1.1.
- [Release notes](https://github.com/rails/rails/releases)
- [Commits](https://github.com/rails/rails/compare/v7.2.1...v7.2.1.1)

---
updated-dependencies:
- dependency-name: rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-21 10:10:15 -04:00
dependabot[bot]
da7f19d5ab Bump erb_lint from 0.6.0 to 0.7.0 (#1337)
Bumps [erb_lint](https://github.com/Shopify/erb-lint) from 0.6.0 to 0.7.0.
- [Release notes](https://github.com/Shopify/erb-lint/releases)
- [Commits](https://github.com/Shopify/erb-lint/compare/v0.6.0...v0.7.0)

---
updated-dependencies:
- dependency-name: erb_lint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-21 09:53:51 -04:00
dependabot[bot]
a2e8fb5ce1 Bump good_job from 4.4.1 to 4.4.2 (#1336)
Bumps [good_job](https://github.com/bensheldon/good_job) from 4.4.1 to 4.4.2.
- [Release notes](https://github.com/bensheldon/good_job/releases)
- [Changelog](https://github.com/bensheldon/good_job/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bensheldon/good_job/compare/v4.4.1...v4.4.2)

---
updated-dependencies:
- dependency-name: good_job
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-21 09:53:41 -04:00
dependabot[bot]
b074762809 Bump faker from 3.4.2 to 3.5.1 (#1338)
Bumps [faker](https://github.com/faker-ruby/faker) from 3.4.2 to 3.5.1.
- [Release notes](https://github.com/faker-ruby/faker/releases)
- [Changelog](https://github.com/faker-ruby/faker/blob/main/CHANGELOG.md)
- [Commits](https://github.com/faker-ruby/faker/compare/v3.4.2...v3.5.1)

---
updated-dependencies:
- dependency-name: faker
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-21 09:53:33 -04:00
dependabot[bot]
3cc4cba2b3 Bump octokit from 9.1.0 to 9.2.0 (#1342)
Bumps [octokit](https://github.com/octokit/octokit.rb) from 9.1.0 to 9.2.0.
- [Release notes](https://github.com/octokit/octokit.rb/releases)
- [Changelog](https://github.com/octokit/octokit.rb/blob/main/RELEASE.md)
- [Commits](https://github.com/octokit/octokit.rb/compare/v9.1.0...v9.2.0)

---
updated-dependencies:
- dependency-name: octokit
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-21 09:52:49 -04:00
dependabot[bot]
cb752370cb Bump aws-sdk-s3 from 1.167.0 to 1.169.0 (#1344)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.167.0 to 1.169.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-21 09:52:37 -04:00
dependabot[bot]
720d7aedaf Bump stripe from 13.0.0 to 13.0.1 (#1345)
Bumps [stripe](https://github.com/stripe/stripe-ruby) from 13.0.0 to 13.0.1.
- [Release notes](https://github.com/stripe/stripe-ruby/releases)
- [Changelog](https://github.com/stripe/stripe-ruby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stripe/stripe-ruby/compare/v13.0.0...v13.0.1)

---
updated-dependencies:
- dependency-name: stripe
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-21 09:52:27 -04:00
Josh Pigford
07264e86cb Add accounts count to Intercom 2024-10-19 14:54:51 -05:00
Zach Gollwitzer
3c0fdd84ee Fix mode bug 2024-10-18 18:25:17 -04:00
Zach Gollwitzer
263d65ea7e Basic account onboarding (#1328)
* Basic account onboarding

* Cleanup
2024-10-18 17:18:54 -04:00
Zach Gollwitzer
e8e100e1d8 Rework account views and addition flow (#1324)
* Move accountable partials

* Split accountables into separate view partials

* Fix test

* Add form to permitted partials

* Fix failing system tests

* Update new account modal views

* New sync algorithm implementation

* Update account system test assertions to match new behavior

* Fix off by 1 date error

* Revert new balance sync algorithm

* Add missing account overviews
2024-10-18 14:37:42 -04:00
Josh Pigford
c7c281073f Impersonation (#1325)
* Initial impersonation

* Impersonation audit

* Keep super admin separate

* Remove vscode settings

* Comment cleanup

* Comment out impersonation fixtures for now

* Remove unused controlelr

* Add impersonation testing (#1326)

* Add impersonation testing

* Remove unused method

* Update schema.rb

* Update brakeman

---------

Co-authored-by: Zach Gollwitzer <zach@maybe.co>
2024-10-18 11:26:58 -05:00
Ender Ahmet Yurt
4a3685f503 Redirect upload step (#1323)
* Redirect upload step

* Change redirect page regarding state of the import
2024-10-18 08:10:18 -05:00
Josh Pigford
75a390f03e Account indexes to address some performance issues 2024-10-17 15:45:13 -05:00
Josh Pigford
d4bfcfb6f4 Fix for transaction drawer securities missing prices
Fixes #1321
2024-10-17 10:52:04 -05:00
Josh Pigford
b98f35af0e Another tweak to the bug template 2024-10-17 10:39:56 -05:00
Josh Pigford
629565f7d8 Updated bug report template 2024-10-17 10:20:42 -05:00
Josh Pigford
4118cc8a31 Fix for scrollbars on alerts
Fixes #1320
2024-10-17 10:16:34 -05:00
Josh Pigford
61bf53f233 Rescue RecordNotUnique
Fixes #1319
2024-10-17 09:52:06 -05:00
Guillem Arias Fauste
7f4c1755ef add dashboard account pill tooltips (#1315)
* add dashboard account pill tooltips

* Update app/views/shared/_text_tooltip.erb

Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
Signed-off-by: Guillem Arias Fauste <gariasf@proton.me>

---------

Signed-off-by: Guillem Arias Fauste <gariasf@proton.me>
Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
2024-10-16 13:14:43 -04:00
Tony Vincent
76decc06c3 Maintain order (#1318) 2024-10-16 12:09:52 -04:00
Zach Gollwitzer
f3bb80dde6 Fix pie chart 2024-10-14 17:21:51 -04:00
oxdev03
4ad28d6eff Add BiomeJS for Linting and Formatting JavaScript relates to #1295 (#1299)
* chore: add formatting and linting for javascript code relates to #1295

* use spaces instaed

* add to recommended extensions

* only enforce lint

* auto save
2024-10-14 17:09:27 -04:00
dependabot[bot]
fa3b8b078c Bump good_job from 4.3.0 to 4.4.1 (#1302)
Bumps [good_job](https://github.com/bensheldon/good_job) from 4.3.0 to 4.4.1.
- [Release notes](https://github.com/bensheldon/good_job/releases)
- [Changelog](https://github.com/bensheldon/good_job/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bensheldon/good_job/compare/v4.3.0...v4.4.1)

---
updated-dependencies:
- dependency-name: good_job
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-14 11:44:13 -04:00
dependabot[bot]
d4e7a983f4 Bump tailwindcss-rails from 2.7.7 to 2.7.9 (#1304)
Bumps [tailwindcss-rails](https://github.com/rails/tailwindcss-rails) from 2.7.7 to 2.7.9.
- [Release notes](https://github.com/rails/tailwindcss-rails/releases)
- [Changelog](https://github.com/rails/tailwindcss-rails/blob/v2.7.9/CHANGELOG.md)
- [Commits](https://github.com/rails/tailwindcss-rails/compare/v2.7.7...v2.7.9)

---
updated-dependencies:
- dependency-name: tailwindcss-rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-14 11:02:10 -04:00
dependabot[bot]
7f7140b1cc Bump ruby-lsp-rails from 0.3.18 to 0.3.19 (#1300)
Bumps [ruby-lsp-rails](https://github.com/Shopify/ruby-lsp-rails) from 0.3.18 to 0.3.19.
- [Release notes](https://github.com/Shopify/ruby-lsp-rails/releases)
- [Commits](https://github.com/Shopify/ruby-lsp-rails/compare/v0.3.18...v0.3.19)

---
updated-dependencies:
- dependency-name: ruby-lsp-rails
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-14 11:01:56 -04:00
dependabot[bot]
437aa4bd39 Bump importmap-rails from 2.0.2 to 2.0.3 (#1301)
Bumps [importmap-rails](https://github.com/rails/importmap-rails) from 2.0.2 to 2.0.3.
- [Release notes](https://github.com/rails/importmap-rails/releases)
- [Commits](https://github.com/rails/importmap-rails/compare/v2.0.2...v2.0.3)

---
updated-dependencies:
- dependency-name: importmap-rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-14 11:01:44 -04:00
dependabot[bot]
eabec71f70 Bump rails-settings-cached from 2.9.4 to 2.9.5 (#1305)
Bumps [rails-settings-cached](https://github.com/huacnlee/rails-settings-cached) from 2.9.4 to 2.9.5.
- [Release notes](https://github.com/huacnlee/rails-settings-cached/releases)
- [Changelog](https://github.com/huacnlee/rails-settings-cached/blob/main/CHANGELOG.md)
- [Commits](https://github.com/huacnlee/rails-settings-cached/compare/v2.9.4...v2.9.5)

---
updated-dependencies:
- dependency-name: rails-settings-cached
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-14 11:01:35 -04:00
dependabot[bot]
3bc960e6c1 Bump sentry-ruby from 5.20.1 to 5.21.0 (#1306)
Bumps [sentry-ruby](https://github.com/getsentry/sentry-ruby) from 5.20.1 to 5.21.0.
- [Release notes](https://github.com/getsentry/sentry-ruby/releases)
- [Changelog](https://github.com/getsentry/sentry-ruby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-ruby/compare/5.20.1...5.21.0)

---
updated-dependencies:
- dependency-name: sentry-ruby
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-14 11:01:17 -04:00
Alex Hatzenbuhler
57a81e44ef Add period to value delete modal (#1297) 2024-10-14 10:19:33 -04:00
Zach Gollwitzer
e357c0485f Temp fix for Stimulus charts 2024-10-11 14:40:13 -04:00
Zach Gollwitzer
d9f11e002a Release v0.1.0
Signed-off-by: Zach Gollwitzer <zach@maybe.co>
2024-10-11 13:15:46 -04:00
Zach Gollwitzer
c744237b55 Allow cents in start balance for accounts 2024-10-11 12:43:50 -04:00
Zach Gollwitzer
7dfd7408c7 Show correct precision on account page 2024-10-11 11:49:53 -04:00
Zach Gollwitzer
8f8988c03a Fix minified JS in prod for chart controller 2024-10-11 11:37:33 -04:00
Zach Gollwitzer
a21061fb56 Private method syntax fix in prod 2024-10-11 11:34:51 -04:00
Alex Hatzenbuhler
c5bf1db230 Add additional subtypes, add None option, prefill edit with previously selected option. (#1286)
* Add additional subtypes and allow for None

* Add parens for consistency on 401

* Remove cryptocurrency investment subtype

* Handle nil value

* Use objects current subtype as the initial selection

* Remove "None" option to default to helper prompt

* Fix blank/none selection

* Only include blank if subtype is present

* Simplify investment subtype dropdown

* Improve depository subtype
2024-10-10 21:23:56 -04:00
Zach Gollwitzer
3610c6cae7 Add observed holidays to sync exceptions 2024-10-10 19:29:20 -04:00
Zach Gollwitzer
79ca7e2039 Preserve negative sign on raw CSV values 2024-10-10 18:57:00 -04:00
Aaron Meese
34ebd96c4c fix: default value if user's name isn't set (#1262)
* fix: default value if user's name isn't set

* chore: matched code style

* fix: i18n key for fallback greeting

---------

Co-authored-by: Zach Gollwitzer <zach@maybe.co>
2024-10-10 18:03:47 -04:00
Zach Gollwitzer
3399b74849 Handle market holidays during holding sync (#1292)
* Handle market holidays during holding sync

* Use informal holidays instead of custom override
2024-10-10 18:02:12 -04:00
Arsen Shkrumelyak
77fc5caecf Minor improvements to categories & changelog pages (#1274)
* ui: change category badge border color

* ui/ux: use author's name in changelog

* ui: badge border 25% -> 30%
2024-10-10 16:00:35 -04:00
Zach Gollwitzer
a20809eee3 When unassigned accounts in CSV import, always allow new account creation 2024-10-10 15:51:36 -04:00
Zach Gollwitzer
cd9f20747c Allow inline account creation when importing CSV (#1291)
* Allow inline account creation when importing CSV

* Sanitize numeric inputs for CSV

* CSV import date validation

* Lint fix
2024-10-10 15:14:38 -04:00
Josh Pigford
1746533842 Default to "today" when entering a transactions and value entries 2024-10-10 12:24:20 -05:00
Josh Pigford
6b46831199 Intercom data update 2024-10-10 10:59:06 -05:00
Zach Gollwitzer
aa16807c6c Allow institutions on edit account form 2024-10-10 11:43:28 -04:00
Zach Gollwitzer
dce9adb534 Add institution back as hidden field on account form 2024-10-10 11:39:50 -04:00
Zach Gollwitzer
26bd655e4c Add value tab to investments 2024-10-10 11:35:10 -04:00
Zach Gollwitzer
5c7d2f2b01 Better import instructions, remove ambiguous field (#1284)
* Remove ambiguous institution field

* Add import instructions

* Fix system test

* Remove lint and i18n normalization checks in CI
2024-10-10 11:18:58 -04:00
Guillem Arias Fauste
90278630ed fix: amend inputs on loan, c.c., vehicle, and property partials (#1281)
* fix: use number inputs on partial loan and credit card form views

* amend vehicle partial

* amend property inputs

* fix lint

* Update app/views/accounts/accountables/_credit_card.html.erb

Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
Signed-off-by: Guillem Arias Fauste <gariasf@proton.me>

* Update app/views/accounts/accountables/_loan.html.erb

Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
Signed-off-by: Guillem Arias Fauste <gariasf@proton.me>

---------

Signed-off-by: Guillem Arias Fauste <gariasf@proton.me>
Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
2024-10-10 10:45:17 -04:00
Guillem Arias Fauste
977da34efc fix: use correct delimiter on credit card zero values (#1280) 2024-10-10 10:14:05 -04:00
Zach Gollwitzer
6288139a41 Fix loan term display 2024-10-09 18:34:20 -04:00
Zach Gollwitzer
ff5408c131 Fix group trend color (#1277) 2024-10-09 18:20:45 -04:00
Zach Gollwitzer
0a303ccbd5 Fix currency formatting for 0 values (#1276)
* Fix currency formatting for 0 values

* Fix loan payment calculation for zero interest rate
2024-10-09 18:11:36 -04:00
Zach Gollwitzer
a2ab217925 Bug fixes for specialized account pages (#1275)
* Default for credit card fields

* Save institution on new account forms

* Fix property, vehicle, loan, credit card pages
2024-10-09 17:20:38 -04:00
Zach Gollwitzer
b4d0fdbe0d Link to CSV imports (#1273)
* Link to CSV imports

* Stale param
2024-10-09 15:22:08 -04:00
Zach Gollwitzer
4bfe47540d Basic trade and holdings view (#1271)
* Add trade view

* Lint fix

* Fix stale placeholder variable

* Add holding view
2024-10-09 14:59:18 -04:00
Josh Pigford
f5cb13b42f Padding tweak 2024-10-09 13:20:36 -05:00
Josh Pigford
3893060f8e Early access (#1272)
* Stubbing in early access

* Styling

* Title tweak

* Early access tweaks

Also removed the allow_browser helper as it tends to cause more headaches than we really care about at this point

* Lint
2024-10-09 13:17:58 -05:00
Zach Gollwitzer
54596d51f7 Fix account pill on dashboard (#1270) 2024-10-09 11:38:34 -04:00
Josh Pigford
7758f51be9 Support deprecated SELF_HOSTING_ENABLED variable for now 2024-10-09 09:56:22 -05:00
Josh Pigford
40c09279f3 i18n linter
I really need to remember to run these things before pushing
2024-10-09 09:16:15 -05:00
Josh Pigford
ad52207a25 Lint 2024-10-09 09:12:07 -05:00
Josh Pigford
a33ba11ce9 Update password_reset.html.erb 2024-10-09 09:06:41 -05:00
Josh Pigford
47a43a888c Make the password reset mailer a bit more...beefy 2024-10-09 09:03:21 -05:00
Josh Pigford
0afab5296c Email sender 2024-10-09 08:37:45 -05:00
Alter Lagos
0d7164af9b Set 3000 as the default web port (#1215)
Having by default `PORT=` only assigns to that variable `0`, which is
interpreted by puma to start the web app in a random port when `bin/dev`
is called.
2024-10-09 08:21:15 -04:00
Josh Pigford
597079dc8d Address faraday-multipart warning 2024-10-08 16:58:38 -05:00
Josh Pigford
fc91a34691 Change to mobile-web-app-capable meta tag 2024-10-08 16:56:30 -05:00
Zach Gollwitzer
fd941d714d Add loan and credit card views (#1268)
* Add loan and credit card views

* Lint fix

* Clean up overview card markup

* Lint fix

* Test fix
2024-10-08 17:16:37 -04:00
Josh Pigford
9263dd3bbe Allow promo codes in checkout 2024-10-08 15:19:23 -05:00
Josh Pigford
31f3ff6a16 Billing (#1269)
* Change env SELF_HOSTING_ENABLED to SELF_HOSTED

* Initial Stripe implementation

* Fix portal link

* Use webhook signatures

* Migrated to new Stripe gem conventions

Also updated resource routing

* Added faraday-multipart gem to resolve middleware notice

* Merge fix

* Merge fix

* Temporary upgrade prompt for early access

* Lint fix

* i18n fixes

* Remove catch-all rescue

* Update .env.example
2024-10-08 14:37:47 -05:00
Josh Pigford
41dff228e8 Crop profile images 2024-10-08 14:25:34 -05:00
Josh Pigford
78b0674052 Support for Cloudflare R2 2024-10-08 13:05:45 -05:00
Josh Pigford
3461182725 Ensure self hosted for invite code listing 2024-10-08 12:36:06 -05:00
Josh Pigford
59e4eff24a Lint 2024-10-08 12:30:28 -05:00
Josh Pigford
e70d3d1902 Generate multiple invites 2024-10-08 12:23:23 -05:00
Zach Gollwitzer
2f6479f058 Add empty states to account summary page (#1265)
* Add empty states to account summary page

* Liability icon fix

* Normalize translations

* Clean up modal styles

* Account color updates

* Lint fixes

* Test fix
2024-10-08 13:00:35 -04:00
Josh Pigford
ffd54e4065 Intercom integration (#1267)
* Intercom integration

Includes if/else statements for various ways to reach out. Also, github/discord icons updated to SVG.

* Update app/views/layouts/_sidebar.html.erb

Co-authored-by: Zach Gollwitzer <zach@maybe.co>
Signed-off-by: Josh Pigford <josh@joshpigford.com>

* Update app/views/pages/feedback.html.erb

Co-authored-by: Zach Gollwitzer <zach@maybe.co>
Signed-off-by: Josh Pigford <josh@joshpigford.com>

* Family = Company in Intercom

---------

Signed-off-by: Josh Pigford <josh@joshpigford.com>
Co-authored-by: Zach Gollwitzer <zach@maybe.co>
2024-10-08 10:50:49 -05:00
Zach Gollwitzer
591d149da9 Finalize other assets and liabilities view (#1264) 2024-10-07 20:23:33 -04:00
Zach Gollwitzer
c397f1bd2b Hide infinity trend percentage changes (#1261) 2024-10-07 16:20:36 -04:00
Zach Gollwitzer
d2a6ab1e45 Hide currency for transfers (#1260) 2024-10-07 15:57:47 -04:00
dependabot[bot]
5e3a3b0b38 Bump webmock from 3.23.1 to 3.24.0 (#1252)
Bumps [webmock](https://github.com/bblimke/webmock) from 3.23.1 to 3.24.0.
- [Changelog](https://github.com/bblimke/webmock/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bblimke/webmock/compare/v3.23.1...v3.24.0)

---
updated-dependencies:
- dependency-name: webmock
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-07 10:30:22 -04:00
dependabot[bot]
563db0f8eb Bump pagy from 9.0.9 to 9.1.0 (#1251)
Bumps [pagy](https://github.com/ddnexus/pagy) from 9.0.9 to 9.1.0.
- [Release notes](https://github.com/ddnexus/pagy/releases)
- [Changelog](https://github.com/ddnexus/pagy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ddnexus/pagy/compare/9.0.9...9.1.0)

---
updated-dependencies:
- dependency-name: pagy
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-07 10:30:12 -04:00
dependabot[bot]
2dda598e8a Bump importmap-rails from 2.0.1 to 2.0.2 (#1255)
Bumps [importmap-rails](https://github.com/rails/importmap-rails) from 2.0.1 to 2.0.2.
- [Release notes](https://github.com/rails/importmap-rails/releases)
- [Commits](https://github.com/rails/importmap-rails/compare/v2.0.1...v2.0.2)

---
updated-dependencies:
- dependency-name: importmap-rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-07 10:29:09 -04:00
dependabot[bot]
388f8e4197 Bump ruby-lsp-rails from 0.3.16 to 0.3.18 (#1258)
Bumps [ruby-lsp-rails](https://github.com/Shopify/ruby-lsp-rails) from 0.3.16 to 0.3.18.
- [Release notes](https://github.com/Shopify/ruby-lsp-rails/releases)
- [Commits](https://github.com/Shopify/ruby-lsp-rails/compare/v0.3.16...v0.3.18)

---
updated-dependencies:
- dependency-name: ruby-lsp-rails
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-07 10:28:56 -04:00
dependabot[bot]
1d56c67b4f Bump aws-sdk-s3 from 1.166.0 to 1.167.0 (#1253)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.166.0 to 1.167.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-07 10:24:10 -04:00
dependabot[bot]
f6619aa4e5 Bump tailwindcss-rails from 2.7.6 to 2.7.7 (#1256)
Bumps [tailwindcss-rails](https://github.com/rails/tailwindcss-rails) from 2.7.6 to 2.7.7.
- [Release notes](https://github.com/rails/tailwindcss-rails/releases)
- [Changelog](https://github.com/rails/tailwindcss-rails/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rails/tailwindcss-rails/compare/v2.7.6...v2.7.7)

---
updated-dependencies:
- dependency-name: tailwindcss-rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-07 10:24:00 -04:00
dependabot[bot]
9453313f68 Bump propshaft from 1.0.1 to 1.1.0 (#1257)
Bumps [propshaft](https://github.com/rails/propshaft) from 1.0.1 to 1.1.0.
- [Release notes](https://github.com/rails/propshaft/releases)
- [Commits](https://github.com/rails/propshaft/compare/v1.0.1...v1.1.0)

---
updated-dependencies:
- dependency-name: propshaft
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-07 10:23:50 -04:00
Zach Gollwitzer
9ebcb6fc41 Bump to v0.1.0-alpha.18
Signed-off-by: Zach Gollwitzer <zach@maybe.co>
2024-10-04 15:09:58 -04:00
Zach Gollwitzer
24d3c0243f Handle missing weekend stock prices in sync process (#1242)
* Don't append missing prices if already known

* Add failing test

* Handle weekend stock prices

* Fix tests and gapfill logic
2024-10-04 14:19:45 -04:00
Zach Gollwitzer
e8d7ee3270 Add tag filtering (#1240) 2024-10-04 09:17:48 -04:00
Zach Gollwitzer
73d61fc990 Fix signage on transaction imports (#1236) 2024-10-03 14:59:24 -04:00
Zach Gollwitzer
1ffa13f3b3 Use DB for auth sessions (#1233)
* DB sessions

* Validations for profile image
2024-10-03 14:42:22 -04:00
Zach Gollwitzer
82c298307d Add formatting for EUR locales (#1231)
* Add formatting for EUR locales

* Fix formatting assertion for EUR in english locales
2024-10-03 10:25:38 -04:00
Zach Gollwitzer
ab40289eb4 Allow users to set preferred locale in settings and provide basic date and time localization support (#1226)
* Add basic date and time localization

* Normalize translations

* Localize transaction dates

* Removed unsupported Rails locales
2024-10-02 14:02:17 -04:00
Zach Gollwitzer
7fabca4679 Simplify self host settings controller (#1230) 2024-10-02 12:07:56 -04:00
Zach Gollwitzer
cb75c537fe Fix import migration (#1227) 2024-10-01 18:59:35 -04:00
Zach Gollwitzer
b1d2dc5e97 Add DB connection troubleshooting to self hosting guide
Signed-off-by: Zach Gollwitzer <zach@maybe.co>
2024-10-01 18:57:38 -04:00
Zach Gollwitzer
c3c0ab3530 Fix incorrect partial sync balance generation (#1223) 2024-10-01 13:15:24 -04:00
Alter Lagos
fa3b1e016c Sort currencies by name as a second order (#1216) 2024-10-01 10:48:39 -04:00
Zach Gollwitzer
398b246965 CSV Imports Overhaul (Transactions, Trades, Accounts, and Mint import support) (#1209)
* Remove stale 1.0 import logic and model

* Fresh start

* Checkpoint before removing nav

* First working prototype

* Add trade, account, and mint import flows

* Basic working version with tests

* System tests for each import type

* Clean up mappings flow

* Clean up PR, refactor stale code, tests

* Add back row validations

* Row validations

* Fix import job test

* Fix import navigation

* Fix mint import configuration form

* Currency preset for new accounts
2024-10-01 10:47:59 -04:00
Jestin Palamuttam
23786b444a Fix: Escape button not being handled on settings pages (#1210)
* fix: escape button handler

* feat: location logic for settings page

* fix: linting errors

* fix: linting error

* refactor: settings test
2024-09-30 17:28:15 -04:00
dependabot[bot]
edbf4eb3d6 Bump aws-sdk-s3 from 1.164.0 to 1.166.0 (#1217)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.164.0 to 1.166.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-30 10:19:12 -04:00
dependabot[bot]
367073f046 Bump propshaft from 1.0.0 to 1.0.1 (#1219)
Bumps [propshaft](https://github.com/rails/propshaft) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/rails/propshaft/releases)
- [Commits](https://github.com/rails/propshaft/compare/v1.0.0...v1.0.1)

---
updated-dependencies:
- dependency-name: propshaft
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-30 10:19:03 -04:00
dependabot[bot]
2cb3d806d8 Bump sentry-rails from 5.19.0 to 5.20.1 (#1220)
Bumps [sentry-rails](https://github.com/getsentry/sentry-ruby) from 5.19.0 to 5.20.1.
- [Release notes](https://github.com/getsentry/sentry-ruby/releases)
- [Changelog](https://github.com/getsentry/sentry-ruby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-ruby/compare/5.19.0...5.20.1)

---
updated-dependencies:
- dependency-name: sentry-rails
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-30 10:18:47 -04:00
dependabot[bot]
3dd0aa2f37 Bump tailwindcss-rails from 2.7.4 to 2.7.6 (#1207)
Bumps [tailwindcss-rails](https://github.com/rails/tailwindcss-rails) from 2.7.4 to 2.7.6.
- [Release notes](https://github.com/rails/tailwindcss-rails/releases)
- [Changelog](https://github.com/rails/tailwindcss-rails/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rails/tailwindcss-rails/compare/v2.7.4...v2.7.6)

---
updated-dependencies:
- dependency-name: tailwindcss-rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-24 17:08:29 -04:00
dependabot[bot]
2b9a7fdef3 Bump ruby-lsp-rails from 0.3.14 to 0.3.16 (#1200)
Bumps [ruby-lsp-rails](https://github.com/Shopify/ruby-lsp-rails) from 0.3.14 to 0.3.16.
- [Release notes](https://github.com/Shopify/ruby-lsp-rails/releases)
- [Commits](https://github.com/Shopify/ruby-lsp-rails/compare/v0.3.14...v0.3.16)

---
updated-dependencies:
- dependency-name: ruby-lsp-rails
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-24 17:02:09 -04:00
dependabot[bot]
cb14ef7655 Bump aws-sdk-s3 from 1.162.0 to 1.164.0 (#1198)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.162.0 to 1.164.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-24 17:01:54 -04:00
dependabot[bot]
73ceebccc2 Bump selenium-webdriver from 4.24.0 to 4.25.0 (#1203)
Bumps [selenium-webdriver](https://github.com/SeleniumHQ/selenium) from 4.24.0 to 4.25.0.
- [Release notes](https://github.com/SeleniumHQ/selenium/releases)
- [Changelog](https://github.com/SeleniumHQ/selenium/blob/trunk/rb/CHANGES)
- [Commits](https://github.com/SeleniumHQ/selenium/compare/selenium-4.24.0...selenium-4.25.0)

---
updated-dependencies:
- dependency-name: selenium-webdriver
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-24 17:01:40 -04:00
dependabot[bot]
17f29de773 Bump dotenv-rails from 3.1.2 to 3.1.4 (#1202)
Bumps [dotenv-rails](https://github.com/bkeepers/dotenv) from 3.1.2 to 3.1.4.
- [Release notes](https://github.com/bkeepers/dotenv/releases)
- [Changelog](https://github.com/bkeepers/dotenv/blob/main/Changelog.md)
- [Commits](https://github.com/bkeepers/dotenv/compare/v3.1.2...v3.1.4)

---
updated-dependencies:
- dependency-name: dotenv-rails
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-24 17:01:23 -04:00
dependabot[bot]
60fadc1d68 Bump puma from 6.4.2 to 6.4.3 (#1201)
Bumps [puma](https://github.com/puma/puma) from 6.4.2 to 6.4.3.
- [Release notes](https://github.com/puma/puma/releases)
- [Changelog](https://github.com/puma/puma/blob/master/History.md)
- [Commits](https://github.com/puma/puma/compare/v6.4.2...v6.4.3)

---
updated-dependencies:
- dependency-name: puma
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-24 17:01:11 -04:00
dependabot[bot]
5eaf335c49 Bump faraday from 2.11.0 to 2.12.0 (#1197)
Bumps [faraday](https://github.com/lostisland/faraday) from 2.11.0 to 2.12.0.
- [Release notes](https://github.com/lostisland/faraday/releases)
- [Changelog](https://github.com/lostisland/faraday/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lostisland/faraday/compare/v2.11.0...v2.12.0)

---
updated-dependencies:
- dependency-name: faraday
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-24 17:01:01 -04:00
dependabot[bot]
be8f74b093 Bump turbo-rails from 2.0.7 to 2.0.10 (#1196)
Bumps [turbo-rails](https://github.com/hotwired/turbo-rails) from 2.0.7 to 2.0.10.
- [Release notes](https://github.com/hotwired/turbo-rails/releases)
- [Commits](https://github.com/hotwired/turbo-rails/compare/v2.0.7...v2.0.10)

---
updated-dependencies:
- dependency-name: turbo-rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-24 17:00:47 -04:00
Zach Gollwitzer
b4b4e5df31 Finalize profile settings page for v0.2.0-alpha (#1194)
* Finalize profile settings page

* Translations

* Add ghost button to search menu
2024-09-20 15:56:21 -04:00
Zach Gollwitzer
5942ce7e3c Finalize transaction drawer, simplify money form helpers (#1191)
* Finalize transaction drawer, simplify money form helpers

* Fix money form errors

* Reusable disclosure helper, fix styles

* Final style tweaks
2024-09-20 08:38:19 -04:00
Zach Gollwitzer
730e58d763 Finish remaining transaction filters (#1189)
* Add type filters to transaction search

* Add amount filter
2024-09-17 10:38:02 -04:00
Tony Vincent
e06f0c76f9 Add error handling for vehicle and property account creation (#1179)
* add error handling for vehicle and property account creation

* Add required true for money_field

* Remove rescue in controllers
2024-09-17 10:37:09 -04:00
Zach Gollwitzer
aa6d755402 Fix styles on import modal (#1188)
* Fix styles on import modal

* Remove stale translations
2024-09-16 19:18:07 -04:00
dependabot[bot]
fd40111264 Bump propshaft from 0.9.1 to 1.0.0 (#1187)
Bumps [propshaft](https://github.com/rails/propshaft) from 0.9.1 to 1.0.0.
- [Release notes](https://github.com/rails/propshaft/releases)
- [Commits](https://github.com/rails/propshaft/compare/v0.9.1...v1.0.0)

---
updated-dependencies:
- dependency-name: propshaft
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-16 11:17:16 -04:00
dependabot[bot]
fc0bc1ac96 Bump ruby-lsp-rails from 0.3.13 to 0.3.14 (#1181)
Bumps [ruby-lsp-rails](https://github.com/Shopify/ruby-lsp-rails) from 0.3.13 to 0.3.14.
- [Release notes](https://github.com/Shopify/ruby-lsp-rails/releases)
- [Commits](https://github.com/Shopify/ruby-lsp-rails/compare/v0.3.13...v0.3.14)

---
updated-dependencies:
- dependency-name: ruby-lsp-rails
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-16 10:24:05 -04:00
dependabot[bot]
b7e3c61d09 Bump good_job from 4.2.1 to 4.3.0 (#1183)
Bumps [good_job](https://github.com/bensheldon/good_job) from 4.2.1 to 4.3.0.
- [Release notes](https://github.com/bensheldon/good_job/releases)
- [Changelog](https://github.com/bensheldon/good_job/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bensheldon/good_job/compare/v4.2.1...v4.3.0)

---
updated-dependencies:
- dependency-name: good_job
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-16 10:23:54 -04:00
dependabot[bot]
8181781570 Bump tailwindcss-rails from 2.7.3 to 2.7.4 (#1182)
Bumps [tailwindcss-rails](https://github.com/rails/tailwindcss-rails) from 2.7.3 to 2.7.4.
- [Release notes](https://github.com/rails/tailwindcss-rails/releases)
- [Changelog](https://github.com/rails/tailwindcss-rails/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rails/tailwindcss-rails/compare/v2.7.3...v2.7.4)

---
updated-dependencies:
- dependency-name: tailwindcss-rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-16 10:14:06 -04:00
dependabot[bot]
5a5e27685a Bump turbo-rails from 2.0.6 to 2.0.7 (#1185)
Bumps [turbo-rails](https://github.com/hotwired/turbo-rails) from 2.0.6 to 2.0.7.
- [Release notes](https://github.com/hotwired/turbo-rails/releases)
- [Commits](https://github.com/hotwired/turbo-rails/compare/v2.0.6...v2.0.7)

---
updated-dependencies:
- dependency-name: turbo-rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-16 10:13:49 -04:00
dependabot[bot]
cc1954b33b Bump aws-sdk-s3 from 1.160.0 to 1.162.0 (#1184)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.160.0 to 1.162.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-16 09:44:12 -04:00
dependabot[bot]
9bb9a062ac Bump pagy from 9.0.8 to 9.0.9 (#1186)
Bumps [pagy](https://github.com/ddnexus/pagy) from 9.0.8 to 9.0.9.
- [Release notes](https://github.com/ddnexus/pagy/releases)
- [Changelog](https://github.com/ddnexus/pagy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ddnexus/pagy/compare/9.0.8...9.0.9)

---
updated-dependencies:
- dependency-name: pagy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-16 09:43:59 -04:00
Zach Gollwitzer
52d3528361 Bump to v0.1.0-alpha.17
Signed-off-by: Zach Gollwitzer <zach@maybe.co>
2024-09-13 17:24:46 -04:00
Zach Gollwitzer
d3d9af8bce Add basic self hosted onboarding (#1177)
* Add basic self hosted onboarding

* Lint fix

* Normalize translations
2024-09-13 17:24:19 -04:00
Zach Gollwitzer
0149ca4ea1 Transaction page design fixes (#1176)
* Fix transaction summary spacing

* Fix search input padding

* Search and transfer design fixes
2024-09-13 15:43:16 -04:00
Zach Gollwitzer
30f7c120e1 Allow partial investment quantities (#1174) 2024-09-13 11:45:27 -04:00
Zach Gollwitzer
949d3d80fa Support multi-currency transfers (#1175) 2024-09-13 11:45:19 -04:00
Zach Gollwitzer
c28dd8f940 Omit trend if zero in sidebar (#1173)
* Omit trend if zero in sidebar

* Lint fix
2024-09-13 11:28:47 -04:00
Tony Vincent
277e4476d9 Fix missing sync_all_button partial (#1172)
* Fix missing sync_all_button partial

* Add missing translation

* Bring back partial

* Unify button text translation

* Add test
2024-09-13 11:19:20 -04:00
Zach Gollwitzer
b9341ac302 Add sync status and errors to account settings page (#1169) 2024-09-11 17:24:01 -04:00
Valentin Zwerschke
86741401c3 Fix text (#1168)
Signed-off-by: Valentin Zwerschke <vallezw@gmail.com>
2024-09-11 13:40:29 -04:00
Tony Vincent
edf44bec03 Add setting to disable new user registration on self-hosted instances (#1163)
* Add clipboard stimulus controller

* Add invite codes controller

* Setting to force invite code for new signups

* Fix erb linter

* Normalize keys

* Add POST /invite_codes

* Cleanup clipboard_controller.js

* Create invite codes on-demand

* Design changes

* Style alignment

* Update app/views/invite_codes/_invite_code.html.erb

Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
Signed-off-by: Tony Vincent <tonyvince7@gmail.com>

* Update app/views/invite_codes/_invite_code.html.erb

Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
Signed-off-by: Tony Vincent <tonyvince7@gmail.com>

* Split into individual forms

* Fix missing styles

* Update app/javascript/controllers/clipboard_controller.js

Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
Signed-off-by: Tony Vincent <tonyvince7@gmail.com>

* Fix test

---------

Signed-off-by: Tony Vincent <tonyvince7@gmail.com>
Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
2024-09-11 13:04:39 -04:00
Jestin Palamuttam
5178928b68 fix: html dialog not closing (#1167) 2024-09-11 09:24:38 -04:00
Zach Gollwitzer
ac0ff35360 Update empty account states on dashboard (#1166)
* Update empty account states on dashboard

* Translations
2024-09-10 17:17:10 -04:00
Zach Gollwitzer
04037b8943 Consolidate transaction menu items (#1164)
* Fix valuation frame issue

* Consolidate transactions menu items

* Translations
2024-09-10 14:45:08 -04:00
Zach Gollwitzer
cb13fd2245 Fix valuation frame issue (#1162) 2024-09-09 17:13:52 -04:00
Zach Gollwitzer
eebc07d75e Feedback page (#1160)
* Add feedback page

* Only show latest release on changelog

* Constrain changelog height

* Ignore sanitization warning for Github content

* Add cassette for Github release notes

* Lint fix
2024-09-09 16:54:56 -04:00
dependabot[bot]
c30c1b9698 Bump hotwire-livereload from 1.4.0 to 1.4.1 (#1157)
Bumps [hotwire-livereload](https://github.com/kirillplatonov/hotwire-livereload) from 1.4.0 to 1.4.1.
- [Release notes](https://github.com/kirillplatonov/hotwire-livereload/releases)
- [Commits](https://github.com/kirillplatonov/hotwire-livereload/compare/v1.4.0...v1.4.1)

---
updated-dependencies:
- dependency-name: hotwire-livereload
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-09 07:57:30 -04:00
dependabot[bot]
d3971f9cee Bump inline_svg from 1.9.0 to 1.10.0 (#1156)
Bumps [inline_svg](https://github.com/jamesmartin/inline_svg) from 1.9.0 to 1.10.0.
- [Release notes](https://github.com/jamesmartin/inline_svg/releases)
- [Changelog](https://github.com/jamesmartin/inline_svg/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jamesmartin/inline_svg/compare/v1.9.0...v1.10.0)

---
updated-dependencies:
- dependency-name: inline_svg
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-09 07:57:15 -04:00
dependabot[bot]
9e4b931612 Bump pg from 1.5.7 to 1.5.8 (#1158)
Bumps [pg](https://github.com/ged/ruby-pg) from 1.5.7 to 1.5.8.
- [Changelog](https://github.com/ged/ruby-pg/blob/master/History.md)
- [Commits](https://github.com/ged/ruby-pg/compare/v1.5.7...v1.5.8)

---
updated-dependencies:
- dependency-name: pg
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-09 07:56:05 -04:00
dependabot[bot]
b44da70836 Bump aws-sdk-s3 from 1.159.0 to 1.160.0 (#1159)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.159.0 to 1.160.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-09 07:55:51 -04:00
Zach Gollwitzer
0db75a019b Revert "Do not show registation link when REQUIRE_INVITE_CODE=true (#1148)" (#1155)
This reverts commit 9172eb931b.
2024-09-06 11:37:25 -04:00
dependabot[bot]
ee572d8d1f Bump selenium-webdriver from 4.23.0 to 4.24.0 (#1146)
Bumps [selenium-webdriver](https://github.com/SeleniumHQ/selenium) from 4.23.0 to 4.24.0.
- [Release notes](https://github.com/SeleniumHQ/selenium/releases)
- [Changelog](https://github.com/SeleniumHQ/selenium/blob/trunk/rb/CHANGES)
- [Commits](https://github.com/SeleniumHQ/selenium/compare/selenium-4.23.0...selenium-4.24.0)

---
updated-dependencies:
- dependency-name: selenium-webdriver
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-06 09:25:22 -04:00
dependabot[bot]
33d007a07b Bump good_job from 4.2.0 to 4.2.1 (#1144)
Bumps [good_job](https://github.com/bensheldon/good_job) from 4.2.0 to 4.2.1.
- [Release notes](https://github.com/bensheldon/good_job/releases)
- [Changelog](https://github.com/bensheldon/good_job/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bensheldon/good_job/compare/v4.2.0...v4.2.1)

---
updated-dependencies:
- dependency-name: good_job
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-06 09:25:11 -04:00
dependabot[bot]
3673ab8f03 Bump faraday from 2.10.1 to 2.11.0 (#1145)
Bumps [faraday](https://github.com/lostisland/faraday) from 2.10.1 to 2.11.0.
- [Release notes](https://github.com/lostisland/faraday/releases)
- [Changelog](https://github.com/lostisland/faraday/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lostisland/faraday/compare/v2.10.1...v2.11.0)

---
updated-dependencies:
- dependency-name: faraday
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-06 09:25:02 -04:00
dependabot[bot]
fb42c2ad43 Bump pagy from 9.0.6 to 9.0.8 (#1147)
Bumps [pagy](https://github.com/ddnexus/pagy) from 9.0.6 to 9.0.8.
- [Release notes](https://github.com/ddnexus/pagy/releases)
- [Changelog](https://github.com/ddnexus/pagy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ddnexus/pagy/compare/9.0.6...9.0.8)

---
updated-dependencies:
- dependency-name: pagy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-06 09:24:44 -04:00
Tony Vincent
9172eb931b Do not show registation link when REQUIRE_INVITE_CODE=true (#1148) 2024-09-06 08:52:26 -04:00
Josh Pigford
0c8cf7e217 Update .gitignore 2024-09-03 12:22:54 -04:00
Josh Pigford
0bbf7f82b7 .ai directory 2024-09-03 09:54:01 -04:00
Zach Gollwitzer
c05ee9b572 Remove unused settings temporarily (#1136) 2024-08-27 17:10:31 -04:00
Zach Gollwitzer
38c2b4670c Categories, tags, merchants, and menus improvements (#1135) 2024-08-27 17:06:41 -04:00
Zach Gollwitzer
f82ce59dad Fix merchants color picker (#1134)
* Fix merchants color picker

* Lint fixes
2024-08-26 19:18:27 -04:00
Zach Gollwitzer
166ed4b1ea Fix account transaction form resetting amount to 0 (#1133) 2024-08-26 19:10:17 -04:00
dependabot[bot]
0c0db44b7f Bump rails from 7.2.0 to 7.2.1 (#1130)
Bumps [rails](https://github.com/rails/rails) from 7.2.0 to 7.2.1.
- [Release notes](https://github.com/rails/rails/releases)
- [Commits](https://github.com/rails/rails/compare/v7.2.0...v7.2.1)

---
updated-dependencies:
- dependency-name: rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-26 10:38:46 -04:00
dependabot[bot]
cd254fd19b Bump aws-sdk-s3 from 1.158.0 to 1.159.0 (#1129)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.158.0 to 1.159.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-26 09:37:08 -04:00
dependabot[bot]
0d20be4905 Bump pagy from 9.0.5 to 9.0.6 (#1128)
Bumps [pagy](https://github.com/ddnexus/pagy) from 9.0.5 to 9.0.6.
- [Release notes](https://github.com/ddnexus/pagy/releases)
- [Changelog](https://github.com/ddnexus/pagy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ddnexus/pagy/compare/9.0.5...9.0.6)

---
updated-dependencies:
- dependency-name: pagy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-26 09:36:59 -04:00
Tony Vincent
cf861ccff9 Fix account sync when prices missing (#1127) 2024-08-26 09:36:27 -04:00
dependabot[bot]
525439e44d Bump vcr from 6.2.0 to 6.3.1 (#1131)
Bumps [vcr](https://github.com/vcr/vcr) from 6.2.0 to 6.3.1.
- [Release notes](https://github.com/vcr/vcr/releases)
- [Changelog](https://github.com/vcr/vcr/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vcr/vcr/compare/v6.2.0...v6.3.1)

---
updated-dependencies:
- dependency-name: vcr
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-26 09:35:04 -04:00
Tony Vincent
e1efe97e6f Fix unable to create Deposit entries in investment portfolio (#1125)
* Fix unable to create Deposit entries in investment portfolio

* Add system test for deposit transaction
2024-08-25 17:48:46 -04:00
Zach Gollwitzer
52c729dc33 Bump to v0.1.0-alpha.16
Signed-off-by: Zach Gollwitzer <zach@maybe.co>
2024-08-23 10:39:14 -04:00
Zach Gollwitzer
de9723d63a Fix file upload UI opening twice (#1119)
* Fix file selector opening twice

* rename click() method

* Remove unused method

* Credit original author

Co-authored-by: Tony Yesudas <tonyvince7@gmail.com>

---------

Co-authored-by: Tony Yesudas <tonyvince7@gmail.com>
2024-08-23 10:30:08 -04:00
Zach Gollwitzer
eef4c2643b Rubocop updates (#1118)
* Minimal code style enforcement

* Formatting and lint code updates (no change in functionality)
2024-08-23 10:06:24 -04:00
Zach Gollwitzer
359bceb58e Vehicle view (#1117) 2024-08-23 09:33:42 -04:00
Zach Gollwitzer
e856691c86 Add Property Details View (#1116)
* Add backend for property account details

* Rubocop updates

* Add property form with details

* Revert "Rubocop updates"

This reverts commit 05b0b8f3a4.

* Bump brakeman to latest version

* Add overview section to property view

* Lint fixes
2024-08-23 08:47:08 -04:00
Zach Gollwitzer
4433488562 Fix holding name error (#1113)
* Add optional debugger to bin/dev script

* Fix holding naming
2024-08-20 17:35:23 -04:00
Zach Gollwitzer
37ae51f68a Fix query when account has zero income and expense (#1112)
* Reproduce error

* Apply fix

* Remove uneeded helper
2024-08-20 15:44:32 -04:00
dependabot[bot]
793a6027a3 Bump tailwindcss-rails from 2.7.2 to 2.7.3 (#1103)
Bumps [tailwindcss-rails](https://github.com/rails/tailwindcss-rails) from 2.7.2 to 2.7.3.
- [Release notes](https://github.com/rails/tailwindcss-rails/releases)
- [Changelog](https://github.com/rails/tailwindcss-rails/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rails/tailwindcss-rails/compare/v2.7.2...v2.7.3)

---
updated-dependencies:
- dependency-name: tailwindcss-rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-19 09:42:18 -04:00
dependabot[bot]
4d20b5f2d4 Bump good_job from 4.1.1 to 4.2.0 (#1102)
Bumps [good_job](https://github.com/bensheldon/good_job) from 4.1.1 to 4.2.0.
- [Release notes](https://github.com/bensheldon/good_job/releases)
- [Changelog](https://github.com/bensheldon/good_job/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bensheldon/good_job/compare/v4.1.1...v4.2.0)

---
updated-dependencies:
- dependency-name: good_job
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-19 09:42:02 -04:00
dependabot[bot]
7966c44d7f Bump propshaft from 0.9.0 to 0.9.1 (#1104)
Bumps [propshaft](https://github.com/rails/propshaft) from 0.9.0 to 0.9.1.
- [Release notes](https://github.com/rails/propshaft/releases)
- [Commits](https://github.com/rails/propshaft/compare/v0.9.0...v0.9.1)

---
updated-dependencies:
- dependency-name: propshaft
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-19 09:41:51 -04:00
dependabot[bot]
30b2ff7aa6 Bump ruby-lsp-rails from 0.3.12 to 0.3.13 (#1107)
Bumps [ruby-lsp-rails](https://github.com/Shopify/ruby-lsp-rails) from 0.3.12 to 0.3.13.
- [Release notes](https://github.com/Shopify/ruby-lsp-rails/releases)
- [Commits](https://github.com/Shopify/ruby-lsp-rails/compare/v0.3.12...v0.3.13)

---
updated-dependencies:
- dependency-name: ruby-lsp-rails
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-19 09:26:01 -04:00
dependabot[bot]
f85fdba366 Bump aws-sdk-s3 from 1.157.0 to 1.158.0 (#1105)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.157.0 to 1.158.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-19 09:25:43 -04:00
dependabot[bot]
0cb4e968a0 Bump stimulus-rails from 1.3.3 to 1.3.4 (#1106)
Bumps [stimulus-rails](https://github.com/hotwired/stimulus-rails) from 1.3.3 to 1.3.4.
- [Release notes](https://github.com/hotwired/stimulus-rails/releases)
- [Commits](https://github.com/hotwired/stimulus-rails/compare/v1.3.3...v1.3.4)

---
updated-dependencies:
- dependency-name: stimulus-rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-19 09:25:31 -04:00
dependabot[bot]
8ebf18e04d Bump sentry-ruby from 5.18.2 to 5.19.0 (#1108)
Bumps [sentry-ruby](https://github.com/getsentry/sentry-ruby) from 5.18.2 to 5.19.0.
- [Release notes](https://github.com/getsentry/sentry-ruby/releases)
- [Changelog](https://github.com/getsentry/sentry-ruby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-ruby/compare/5.18.2...5.19.0)

---
updated-dependencies:
- dependency-name: sentry-ruby
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-19 09:25:16 -04:00
Pedro Carmona
0c1ff00c1e Refactor: Allow other import files (#1099)
* Rename stimulus controller

* feature: rename raw_csv_str to raw_file_str
2024-08-19 09:25:07 -04:00
Zach Gollwitzer
e6528bafec Bump to v0.1.0-alpha.15
Signed-off-by: Zach Gollwitzer <zach@maybe.co>
2024-08-16 16:09:37 -04:00
Zach Gollwitzer
1b6ce6af45 Improved UI warning states for holdings with missing data (#1098)
* Fix security price issue flow

* Fix tooltip positioning and add tooltip for missing holding data

* Fix tooltip controller error with stale arrow target

* Lint fixes
2024-08-16 16:08:27 -04:00
Alexander Schrot
4527482aa2 Add support for different column separator in csv import logic (#1096)
* add col_sep to import model

* add validation for col_sep column

* add col_sep option to csv import model

* make use of col_sep option in import model

* add column separator field to new/edit action of an import

* add col_sep parameter to create/update action

* fix spacing between fields

Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
Signed-off-by: Alexander Schrot <alexander@axs-labs.com>

---------

Signed-off-by: Alexander Schrot <alexander@axs-labs.com>
Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
2024-08-16 14:00:16 -04:00
Zach Gollwitzer
707c5ca0ca Account Issue Model and Resolution Flow + Troubleshooting guides (#1090)
* Rough draft of issue system

* Simplify design

* Remove stale files from merge conflicts

* STI for issues

* Cleanup

* Improve Synth api key flow

* Stub api key for test
2024-08-16 12:13:48 -04:00
Alexander Schrot
c70a08aca2 add pagination to account transactions list (#1095)
* add pagination to account transactions list

* use global pagination partial
2024-08-16 09:00:05 -04:00
Zach Gollwitzer
9dda2606d5 Bump Dockerfile to 3.3.4
Signed-off-by: Zach Gollwitzer <zach@maybe.co>
2024-08-15 13:23:40 -04:00
Zach Gollwitzer
acf3564a86 Fix for invalid accountable data (#1086) 2024-08-15 12:49:49 -04:00
Josh Pigford
1f6f55c4a8 Switch to general release of Rails 7.2 2024-08-15 11:17:28 -05:00
Zach Gollwitzer
0691041d37 Update required Ruby version for development in README
Signed-off-by: Zach Gollwitzer <zach@maybe.co>
2024-08-13 12:50:26 -04:00
Chris Covington
b437bb20c4 Bump ruby from 3.3.1 to 3.3.4 (#1084) 2024-08-13 12:49:51 -04:00
Pedro Carmona
3c64f3ff3b Fix: i18n symbol typo (#1085) 2024-08-13 12:31:51 -04:00
dependabot[bot]
82d3b8bcaf Bump rails from 43530b4 to f6d62b5 (#1083)
Bumps [rails](https://github.com/rails/rails) from `43530b4` to `f6d62b5`.
- [Release notes](https://github.com/rails/rails/releases)
- [Commits](43530b4ac9...f6d62b5f21)

---
updated-dependencies:
- dependency-name: rails
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-12 20:41:33 -04:00
Pedro Carmona
14c4b9e93c Refactor: Use native error i18n lookup (#1076) 2024-08-12 20:38:58 -04:00
dependabot[bot]
150fce41a8 Bump ruby-lsp-rails from 0.3.11 to 0.3.12 (#1081)
Bumps [ruby-lsp-rails](https://github.com/Shopify/ruby-lsp-rails) from 0.3.11 to 0.3.12.
- [Release notes](https://github.com/Shopify/ruby-lsp-rails/releases)
- [Commits](https://github.com/Shopify/ruby-lsp-rails/compare/v0.3.11...v0.3.12)

---
updated-dependencies:
- dependency-name: ruby-lsp-rails
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-12 20:33:49 -04:00
dependabot[bot]
67f65d399e Bump bootsnap from 1.18.3 to 1.18.4 (#1079)
Bumps [bootsnap](https://github.com/Shopify/bootsnap) from 1.18.3 to 1.18.4.
- [Changelog](https://github.com/Shopify/bootsnap/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Shopify/bootsnap/compare/v1.18.3...v1.18.4)

---
updated-dependencies:
- dependency-name: bootsnap
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-12 20:33:30 -04:00
dependabot[bot]
72fe6d87f0 Bump tailwindcss-rails from 2.6.5 to 2.7.2 (#1078)
Bumps [tailwindcss-rails](https://github.com/rails/tailwindcss-rails) from 2.6.5 to 2.7.2.
- [Release notes](https://github.com/rails/tailwindcss-rails/releases)
- [Changelog](https://github.com/rails/tailwindcss-rails/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rails/tailwindcss-rails/compare/v2.6.5...v2.7.2)

---
updated-dependencies:
- dependency-name: tailwindcss-rails
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-12 20:26:38 -04:00
Zach Gollwitzer
94be117a02 Deposit, Withdrawal, and Interest Transactions for Investment View (#1075)
* Trade and Transaction builders

* Consolidate logic

* Remove redundant fields from trade form

* Add deposit, withdrawal, and interest form controls
2024-08-09 20:11:27 -04:00
Zach Gollwitzer
f3c44464be Update version.rb
Bump to v0.1.0-alpha.14

Signed-off-by: Zach Gollwitzer <zach@maybe.co>
2024-08-09 17:42:48 -04:00
Zach Gollwitzer
c0908f454a Temp fix for missing accountables on self hosted instances (#1071)
* Temp fix #1068

* Cleanup
2024-08-09 13:31:32 -04:00
Zach Gollwitzer
e05f03b314 Allow user to add buy and sell trade transactions for investment accounts (#1066)
* Consolidate modal form structure into partial + helper

* Scaffold out trade transaction form

* Normalize translations

* Add buy and sell trade form with tests

* Move entryable lists to dedicated controllers

* Delegate entry group contents rendering

* More cleanup

* Extract transaction and valuation update logic from entries controller

* Delegate edit and show actions to entryables

* Trade builder

* Update paths for transaction updates
2024-08-09 11:22:57 -04:00
Tony Vincent
6bca35fa22 Fix minitest assert_nil warning (#1070)
* Fix minitest assert_nil warning

* Remove empty line

* Fix my stupidity
2024-08-09 10:58:01 -04:00
Tony Vincent
6fa40e0fa2 Fetch exchange rates in bulk from synth (#1069)
* Fetch exchnage rates in bulk

* Handle paginated response

* Rename method and improve tests

* Change argument names

* Use standard date format
2024-08-09 10:57:33 -04:00
Tony Vincent
f315370512 Add stimulus tooltip controller (#1065)
* Add Tooltip Stimulus controller

* Add test for tooltip

* Remove comma

* Normalize translations

* Use floating-ui instead popper

* Use component classes

* Increase cross axis value

* Cleanup

* Update app/views/accounts/show.html.erb

Use correct tailwind class

Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
Signed-off-by: Tony Vincent <tonyvince7@gmail.com>

* Use default values for options

* Remove tooltip global variable

* Add arrow target

* Remove unused method

---------

Signed-off-by: Tony Vincent <tonyvince7@gmail.com>
Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
2024-08-08 06:53:27 -04:00
Zach Gollwitzer
6e74414cb2 Add source headers to Synth calls (#1062) 2024-08-05 12:21:12 -04:00
dependabot[bot]
9ad04a82cb Bump rails from 5cb5cad to 43530b4 (#1059)
Bumps [rails](https://github.com/rails/rails) from `5cb5cad` to `43530b4`.
- [Release notes](https://github.com/rails/rails/releases)
- [Commits](5cb5cad322...43530b4ac9)

---
updated-dependencies:
- dependency-name: rails
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-05 09:13:34 -04:00
dependabot[bot]
7c878697f4 Bump pagy from 9.0.3 to 9.0.5 (#1056)
Bumps [pagy](https://github.com/ddnexus/pagy) from 9.0.3 to 9.0.5.
- [Release notes](https://github.com/ddnexus/pagy/releases)
- [Changelog](https://github.com/ddnexus/pagy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ddnexus/pagy/compare/9.0.3...9.0.5)

---
updated-dependencies:
- dependency-name: pagy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-05 09:13:03 -04:00
dependabot[bot]
cdb134077d Bump good_job from 4.1.0 to 4.1.1 (#1053)
Bumps [good_job](https://github.com/bensheldon/good_job) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/bensheldon/good_job/releases)
- [Changelog](https://github.com/bensheldon/good_job/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bensheldon/good_job/compare/v4.1.0...v4.1.1)

---
updated-dependencies:
- dependency-name: good_job
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-05 09:00:32 -04:00
dependabot[bot]
65aeab4681 Bump aws-sdk-s3 from 1.156.0 to 1.157.0 (#1054)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.156.0 to 1.157.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-05 08:59:30 -04:00
dependabot[bot]
e0d2b951d6 Bump erb_lint from 0.5.0 to 0.6.0 (#1057)
Bumps [erb_lint](https://github.com/Shopify/erb-lint) from 0.5.0 to 0.6.0.
- [Release notes](https://github.com/Shopify/erb-lint/releases)
- [Commits](https://github.com/Shopify/erb-lint/compare/v0.5.0...v0.6.0)

---
updated-dependencies:
- dependency-name: erb_lint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-05 08:58:05 -04:00
dependabot[bot]
4eeca00121 Bump faraday from 2.10.0 to 2.10.1 (#1055)
Bumps [faraday](https://github.com/lostisland/faraday) from 2.10.0 to 2.10.1.
- [Release notes](https://github.com/lostisland/faraday/releases)
- [Changelog](https://github.com/lostisland/faraday/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lostisland/faraday/compare/v2.10.0...v2.10.1)

---
updated-dependencies:
- dependency-name: faraday
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-05 08:57:19 -04:00
dependabot[bot]
07a7a6b1aa Bump tailwindcss-rails from 2.6.4 to 2.6.5 (#1058)
Bumps [tailwindcss-rails](https://github.com/rails/tailwindcss-rails) from 2.6.4 to 2.6.5.
- [Release notes](https://github.com/rails/tailwindcss-rails/releases)
- [Changelog](https://github.com/rails/tailwindcss-rails/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rails/tailwindcss-rails/compare/v2.6.4...v2.6.5)

---
updated-dependencies:
- dependency-name: tailwindcss-rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-05 08:57:03 -04:00
Zach Gollwitzer
edda5cb35b Bump to v0.1.0-alpha.13
Signed-off-by: Zach Gollwitzer <zach@maybe.co>
2024-08-02 17:10:16 -04:00
Zach Gollwitzer
ea8309eedd Show cash + holdings value for investment account view (#1046)
* Handle missing tickers in security price syncs

* Show combined cash and holdings value on account page

* Improve partial locals
2024-08-02 17:09:25 -04:00
Zach Gollwitzer
453a54e5e6 Add security prices provider (Synth integration) (#1039)
* User tickers as primary lookup symbol instead of isin

* Add security price provider

* Fetch security prices in bulk to improve sync performance

* Fetch prices in bulk, better mocking for tests
2024-08-01 19:43:23 -04:00
Zach Gollwitzer
c70c8b6d86 Ensure transfer name is populated (#1042)
* Ensure transfer name is populated

* Transfer amount fallback
2024-08-01 12:10:30 -04:00
Tony Vincent
f2a2d2f7e4 Fix demo data reset (#1041)
* Fix demo data reset

* Only delete test user
2024-08-01 08:56:32 -04:00
Mikhail Wahib
0a21c92643 fix: long emails overflow in account menu dropdown (#1034) 2024-07-31 12:24:01 -04:00
dependabot[bot]
2c5f647f53 Bump rails from 1b89033 to 5cb5cad (#1035)
Bumps [rails](https://github.com/rails/rails) from `1b89033` to `5cb5cad`.
- [Release notes](https://github.com/rails/rails/releases)
- [Commits](1b89033460...5cb5cad322)

---
updated-dependencies:
- dependency-name: rails
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-31 09:40:35 -04:00
dependabot[bot]
11f58537db Bump pagy from 9.0.2 to 9.0.3 (#1030)
Bumps [pagy](https://github.com/ddnexus/pagy) from 9.0.2 to 9.0.3.
- [Release notes](https://github.com/ddnexus/pagy/releases)
- [Changelog](https://github.com/ddnexus/pagy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ddnexus/pagy/compare/9.0.2...9.0.3)

---
updated-dependencies:
- dependency-name: pagy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-31 09:32:09 -04:00
dependabot[bot]
6231814e1e Bump mocha from 2.4.2 to 2.4.5 (#1029)
Bumps [mocha](https://github.com/freerange/mocha) from 2.4.2 to 2.4.5.
- [Changelog](https://github.com/freerange/mocha/blob/main/RELEASE.md)
- [Commits](https://github.com/freerange/mocha/compare/v2.4.2...v2.4.5)

---
updated-dependencies:
- dependency-name: mocha
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-31 09:31:13 -04:00
dependabot[bot]
7645a9ec56 Bump image_processing from 1.12.2 to 1.13.0 (#1028)
Bumps [image_processing](https://github.com/janko/image_processing) from 1.12.2 to 1.13.0.
- [Changelog](https://github.com/janko/image_processing/blob/master/CHANGELOG.md)
- [Commits](https://github.com/janko/image_processing/compare/v1.12.2...v1.13.0)

---
updated-dependencies:
- dependency-name: image_processing
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-31 09:31:06 -04:00
dependabot[bot]
08b59ad5fe Bump pg from 1.5.6 to 1.5.7 (#1027)
Bumps [pg](https://github.com/ged/ruby-pg) from 1.5.6 to 1.5.7.
- [Changelog](https://github.com/ged/ruby-pg/blob/master/History.md)
- [Commits](https://github.com/ged/ruby-pg/compare/v1.5.6...v1.5.7)

---
updated-dependencies:
- dependency-name: pg
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-31 09:30:39 -04:00
dependabot[bot]
02adba5280 Bump tailwindcss-rails from 2.6.3 to 2.6.4 (#1031)
Bumps [tailwindcss-rails](https://github.com/rails/tailwindcss-rails) from 2.6.3 to 2.6.4.
- [Release notes](https://github.com/rails/tailwindcss-rails/releases)
- [Changelog](https://github.com/rails/tailwindcss-rails/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rails/tailwindcss-rails/compare/v2.6.3...v2.6.4)

---
updated-dependencies:
- dependency-name: tailwindcss-rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-31 09:30:31 -04:00
dependabot[bot]
1f5721a8b1 Bump sentry-rails from 5.18.1 to 5.18.2 (#1033)
Bumps [sentry-rails](https://github.com/getsentry/sentry-ruby) from 5.18.1 to 5.18.2.
- [Release notes](https://github.com/getsentry/sentry-ruby/releases)
- [Changelog](https://github.com/getsentry/sentry-ruby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-ruby/compare/5.18.1...5.18.2)

---
updated-dependencies:
- dependency-name: sentry-rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-31 09:30:21 -04:00
pranavbabu
7ba9830db5 Fix: Omit layout for turbo frames with custom sidebar layout (#1024)
* Define layout method

* Use with_sidebar method

---------

Co-authored-by: Pranav Babu <babu@maindeck.io>
2024-07-26 12:00:41 -04:00
Zach Gollwitzer
dfc7e1c30c Bump to v0.1.0-alpha.12
Signed-off-by: Zach Gollwitzer <zach@maybe.co>
2024-07-26 10:48:21 -04:00
Zach Gollwitzer
76dd5e57fb Set minimum supported date for account entries (#1023)
* Set minimum supported date for account entries

* Fix validation proc

* Fix date input in system tests
2024-07-26 10:47:27 -04:00
Zach Gollwitzer
701e17829d Fix currency formatting in pie chart visualization (#1022) 2024-07-26 10:36:29 -04:00
Zach Gollwitzer
7c2091b343 Basic Portfolio Views (#1000)
* Add holdings tab to account view

* Basic portfolio UI

* Cleanup

* Handle missing holding data

* Remove synced at (implemented in separate pr)

* translations

* Tweak post sync streams

* Remove stale methods from merge conflict
2024-07-25 16:46:04 -04:00
Zach Gollwitzer
ef4be7948a Implement auto family syncs on login (#1021) 2024-07-25 12:51:50 -04:00
Julius Mieliauskas
c8590d53ba Fix curency format (#1020)
* Fixed currency formatting

* Revert "Fixed currency formatting"

This reverts commit 8c7ff442b8.

* fix currency formating
2024-07-25 10:40:03 -04:00
Tony Vincent
f62c5e43c3 Fix form labels (#1004)
* Fix form labels

* Fix typo

* Change form builder

* Simplify label_html private method of StyledFormBuilder
2024-07-22 10:04:55 -04:00
dependabot[bot]
82568b4d8c Bump rails from 8035bec to 1b89033 (#1007)
Bumps [rails](https://github.com/rails/rails) from `8035bec` to `1b89033`.
- [Release notes](https://github.com/rails/rails/releases)
- [Commits](8035bece70...1b89033460)

---
updated-dependencies:
- dependency-name: rails
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-22 10:00:39 -04:00
dependabot[bot]
9d006409c2 Bump turbo-rails from 2.0.5 to 2.0.6 (#1008)
Bumps [turbo-rails](https://github.com/hotwired/turbo-rails) from 2.0.5 to 2.0.6.
- [Release notes](https://github.com/hotwired/turbo-rails/releases)
- [Commits](https://github.com/hotwired/turbo-rails/compare/v2.0.5...v2.0.6)

---
updated-dependencies:
- dependency-name: turbo-rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-22 09:53:21 -04:00
dependabot[bot]
55a085f01f Bump ruby-lsp-rails from 0.3.10 to 0.3.11 (#1010)
Bumps [ruby-lsp-rails](https://github.com/Shopify/ruby-lsp-rails) from 0.3.10 to 0.3.11.
- [Release notes](https://github.com/Shopify/ruby-lsp-rails/releases)
- [Commits](https://github.com/Shopify/ruby-lsp-rails/compare/v0.3.10...v0.3.11)

---
updated-dependencies:
- dependency-name: ruby-lsp-rails
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-22 09:53:01 -04:00
dependabot[bot]
23dcdf6e26 Bump selenium-webdriver from 4.22.0 to 4.23.0 (#1011)
Bumps [selenium-webdriver](https://github.com/SeleniumHQ/selenium) from 4.22.0 to 4.23.0.
- [Release notes](https://github.com/SeleniumHQ/selenium/releases)
- [Changelog](https://github.com/SeleniumHQ/selenium/blob/trunk/rb/CHANGES)
- [Commits](https://github.com/SeleniumHQ/selenium/compare/selenium-4.22.0...selenium-4.23.0)

---
updated-dependencies:
- dependency-name: selenium-webdriver
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-22 09:52:34 -04:00
dependabot[bot]
05e3e689b5 Bump good_job from 4.0.3 to 4.1.0 (#1012)
Bumps [good_job](https://github.com/bensheldon/good_job) from 4.0.3 to 4.1.0.
- [Release notes](https://github.com/bensheldon/good_job/releases)
- [Changelog](https://github.com/bensheldon/good_job/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bensheldon/good_job/compare/v4.0.3...v4.1.0)

---
updated-dependencies:
- dependency-name: good_job
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-22 09:52:17 -04:00
dependabot[bot]
01f50dc54c Bump mocha from 2.4.0 to 2.4.2 (#1013)
Bumps [mocha](https://github.com/freerange/mocha) from 2.4.0 to 2.4.2.
- [Changelog](https://github.com/freerange/mocha/blob/main/RELEASE.md)
- [Commits](https://github.com/freerange/mocha/compare/v2.4.0...v2.4.2)

---
updated-dependencies:
- dependency-name: mocha
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-22 09:51:43 -04:00
dependabot[bot]
5d213f2e6a Bump tailwindcss-rails from 2.6.1 to 2.6.3 (#1014)
Bumps [tailwindcss-rails](https://github.com/rails/tailwindcss-rails) from 2.6.1 to 2.6.3.
- [Release notes](https://github.com/rails/tailwindcss-rails/releases)
- [Changelog](https://github.com/rails/tailwindcss-rails/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rails/tailwindcss-rails/compare/v2.6.1...v2.6.3)

---
updated-dependencies:
- dependency-name: tailwindcss-rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-22 09:51:31 -04:00
dependabot[bot]
952d847c15 Bump faker from 3.4.1 to 3.4.2 (#1015)
Bumps [faker](https://github.com/faker-ruby/faker) from 3.4.1 to 3.4.2.
- [Release notes](https://github.com/faker-ruby/faker/releases)
- [Changelog](https://github.com/faker-ruby/faker/blob/main/CHANGELOG.md)
- [Commits](https://github.com/faker-ruby/faker/compare/v3.4.1...v3.4.2)

---
updated-dependencies:
- dependency-name: faker
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-22 09:51:12 -04:00
Tony Vincent
e7dc6b88ea Bump pagy with breaking changes fix (#1016) 2024-07-22 09:49:53 -04:00
Tony Vincent
75ded1c18f Set last_login_at only at login instead of every single action (#1017) 2024-07-22 09:37:03 -04:00
Zach Gollwitzer
c0e0c2bf62 Bump to v0.1.0-alpha.11
Signed-off-by: Zach Gollwitzer <zach@maybe.co>
2024-07-19 16:09:05 -04:00
Zach Gollwitzer
fa08f027c7 Sync notifications and troubleshooting guides (#998)
* Add help articles

* Broadcast sync messages as notifications

* Lint fixes

* more lint fixes

* Remove redundant code
2024-07-18 14:39:38 -04:00
Zach Gollwitzer
b200b71284 Add currency validation to account, update demo data generator (#996)
* Add currency validation to account, update demo data generator

* Fix tests
2024-07-17 14:18:12 -04:00
Zach Gollwitzer
ef0f910b9b Build sample portfolio deterministically (#993) 2024-07-17 08:57:28 -04:00
Zach Gollwitzer
e9f42c1a65 Add default currencies to forms based on preference (#994)
* Add default currencies to forms based on preference

* Remove dev debugging
2024-07-17 08:57:17 -04:00
Zach Gollwitzer
e51806b98b More composable forms (#989)
* Make forms more composable, opt-in to form builder

* Remove unused method

* Simpler money input controls

* Add in new form styling to imports

* Lint fixes

* Small tweak of multi select styles
2024-07-16 14:08:24 -04:00
Zach Gollwitzer
47523f64c2 Investment Portfolio Sync (#974)
* Add investment portfolio models

* Add portfolio to demo data

* Setup initial tests

* Rough sketch of sync logic

* Clean up trade sync logic

* Add trade validation

* Integrate trades into sync process
2024-07-16 09:26:49 -04:00
Tony Vincent
d0bc959bee Sanitize input for ilike in Account::Entry.search (#988) 2024-07-16 09:26:14 -04:00
Tony Vincent
cdbca5aff3 Allow CSV file upload in import flow (#986)
* Add .tool-versions to gitignore

* Add dropzone js for drag and drop file uploads

* UI for csv file uploads for import

* dropzone controller and use lucide_icon instead of svg

* Preview for file chosen

* File upload

* Remove dropzone

* Normalize I18n keys and fix lint issues

* Add system tests

* Cleanup

* Remove unwanted
2024-07-16 09:23:45 -04:00
dependabot[bot]
41f9e23f8c Bump rails from 8075866 to 8035bec (#982)
Bumps [rails](https://github.com/rails/rails) from `8075866` to `8035bec`.
- [Release notes](https://github.com/rails/rails/releases)
- [Commits](8075866ae8...8035bece70)

---
updated-dependencies:
- dependency-name: rails
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-15 10:21:24 -04:00
dependabot[bot]
12123449b7 Bump good_job from 4.0.0 to 4.0.3 (#981)
Bumps [good_job](https://github.com/bensheldon/good_job) from 4.0.0 to 4.0.3.
- [Release notes](https://github.com/bensheldon/good_job/releases)
- [Changelog](https://github.com/bensheldon/good_job/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bensheldon/good_job/compare/v4.0.0...v4.0.3)

---
updated-dependencies:
- dependency-name: good_job
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-15 10:07:12 -04:00
dependabot[bot]
a70c6666dc Bump ruby-lsp-rails from 0.3.8 to 0.3.10 (#983)
Bumps [ruby-lsp-rails](https://github.com/Shopify/ruby-lsp-rails) from 0.3.8 to 0.3.10.
- [Release notes](https://github.com/Shopify/ruby-lsp-rails/releases)
- [Commits](https://github.com/Shopify/ruby-lsp-rails/compare/v0.3.8...v0.3.10)

---
updated-dependencies:
- dependency-name: ruby-lsp-rails
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-15 10:04:39 -04:00
dependabot[bot]
1bd5397701 Bump faraday from 2.9.2 to 2.10.0 (#984)
Bumps [faraday](https://github.com/lostisland/faraday) from 2.9.2 to 2.10.0.
- [Release notes](https://github.com/lostisland/faraday/releases)
- [Changelog](https://github.com/lostisland/faraday/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lostisland/faraday/compare/v2.9.2...v2.10.0)

---
updated-dependencies:
- dependency-name: faraday
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-15 10:04:30 -04:00
Andrey Morskov
37d5c149ba Wrap account update in transaction (#985) 2024-07-15 10:03:35 -04:00
Zach Gollwitzer
744ffb68aa Bump to v0.1.0-alpha.10
Signed-off-by: Zach Gollwitzer <zach@maybe.co>
2024-07-12 18:38:17 -04:00
Zach Gollwitzer
34e03c2d6a Make balance editing easier (#976)
* Make balance editing easier

* Translations

* Fix money input option

* Fix balance sync logic

* Rework balance update flow
2024-07-12 13:47:39 -04:00
Zach Gollwitzer
b002a41b35 New demo user data (#972) 2024-07-11 08:37:21 -04:00
Zach Gollwitzer
c6bdf49f10 Account::Sync model and test fixture simplifications (#968)
* Add sync model

* Fresh fixtures for sync tests

* Sync tests overhaul

* Fix entry tests

* Complete remaining model test updates

* Update system tests

* Update demo data task

* Add system tests back to PR checks

* More simplifications, add empty family to fixtures for easier testing
2024-07-10 11:22:59 -04:00
Tony Vincent
de5a2e55b3 Add missing migrations for good_job 4x (#967)
* Goodjob 3.99

* Properly bump to good_job 4.0.0

* Remove accidently tracked .tool-versions
2024-07-09 14:23:19 -04:00
dependabot[bot]
538b00712c Bump rails from df02832 to 8075866 (#962)
Bumps [rails](https://github.com/rails/rails) from `df02832` to `8075866`.
- [Release notes](https://github.com/rails/rails/releases)
- [Commits](df02832784...8075866ae8)

---
updated-dependencies:
- dependency-name: rails
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-08 13:35:30 -04:00
dependabot[bot]
2e56f5726e Bump sentry-rails from 5.18.0 to 5.18.1 (#964)
Bumps [sentry-rails](https://github.com/getsentry/sentry-ruby) from 5.18.0 to 5.18.1.
- [Release notes](https://github.com/getsentry/sentry-ruby/releases)
- [Changelog](https://github.com/getsentry/sentry-ruby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-ruby/compare/5.18.0...5.18.1)

---
updated-dependencies:
- dependency-name: sentry-rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-08 09:15:11 -04:00
dependabot[bot]
3c9cdb16f9 Bump pagy from 8.6.1 to 8.6.3 (#963)
Bumps [pagy](https://github.com/ddnexus/pagy) from 8.6.1 to 8.6.3.
- [Release notes](https://github.com/ddnexus/pagy/releases)
- [Changelog](https://github.com/ddnexus/pagy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ddnexus/pagy/compare/8.6.1...8.6.3)

---
updated-dependencies:
- dependency-name: pagy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-08 09:14:46 -04:00
dependabot[bot]
6d4c871f85 Bump ruby-lsp-rails from 0.3.7 to 0.3.8 (#960)
Bumps [ruby-lsp-rails](https://github.com/Shopify/ruby-lsp-rails) from 0.3.7 to 0.3.8.
- [Release notes](https://github.com/Shopify/ruby-lsp-rails/releases)
- [Commits](https://github.com/Shopify/ruby-lsp-rails/compare/v0.3.7...v0.3.8)

---
updated-dependencies:
- dependency-name: ruby-lsp-rails
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-08 09:14:31 -04:00
dependabot[bot]
dd915c42ed Bump aws-sdk-s3 from 1.155.0 to 1.156.0 (#961)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.155.0 to 1.156.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-08 09:07:52 -04:00
dependabot[bot]
0447d47a53 Bump good_job from 3.29.5 to 4.0.0 (#959)
Bumps [good_job](https://github.com/bensheldon/good_job) from 3.29.5 to 4.0.0.
- [Release notes](https://github.com/bensheldon/good_job/releases)
- [Changelog](https://github.com/bensheldon/good_job/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bensheldon/good_job/compare/v3.29.5...v4.0.0)

---
updated-dependencies:
- dependency-name: good_job
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-08 09:07:12 -04:00
dependabot[bot]
42dec4014e Bump sentry-ruby from 5.18.0 to 5.18.1 (#958)
Bumps [sentry-ruby](https://github.com/getsentry/sentry-ruby) from 5.18.0 to 5.18.1.
- [Release notes](https://github.com/getsentry/sentry-ruby/releases)
- [Changelog](https://github.com/getsentry/sentry-ruby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-ruby/compare/5.18.0...5.18.1)

---
updated-dependencies:
- dependency-name: sentry-ruby
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-08 09:05:30 -04:00
Zach Gollwitzer
6767aaed1d Handle missing exchange rate provider, allow fallback for missing rates (#955)
* Clean up exchange rate logic

* Remove stale method
2024-07-08 09:04:59 -04:00
Magnus Jensen
bef335c631 fix: #951 pointer cursor and bg hover for import flow buttons (#954)
* set cursor to pointer on buttons in imports flow

* add hover bg change on buttons to indicate action

* add rounded hover background to x
2024-07-08 08:56:08 -04:00
Tony Vincent
3ffb6cb62b Add error handling for AccountsController#create (#957) 2024-07-08 08:53:45 -04:00
Zach Gollwitzer
cea90252c8 Bump to v0.1.0-alpha.9
Signed-off-by: Zach Gollwitzer <zach@maybe.co>
2024-07-05 14:16:41 -04:00
Zach Gollwitzer
36cccefb2a Update docker compose example with fixed storage volume (#950) 2024-07-05 14:16:02 -04:00
Tony Vincent
cc6bf6e961 Enable syncing all accounts in one click (#948)
* Enable syncing all accounts on one click

* Remove argument to sync_later method call

* Add partial for sync all accounts button

* Redirect back if possible when syncing all accounts
2024-07-05 07:36:18 -04:00
Tony Vincent
48092cb704 Enque account sync job after creating transfer (#946) 2024-07-04 06:57:26 -04:00
Luke Hurst
cf23453d93 Fix bug where transactions were duplicated in import confirm (#941)
* Fix bug where transactions were duplicated in import confirm

Signed-off-by: Luke Hurst <hurstlj@umich.edu>

* Update imports_test.rb

Signed-off-by: Luke Hurst <hurstlj@umich.edu>

---------

Signed-off-by: Luke Hurst <hurstlj@umich.edu>
2024-07-03 17:44:35 -04:00
Tony Vincent
f1d0a62ac7 Enable updating Account::Entry#amount (#942)
- Enable updating transaction type income/expense
- Enable updating transaction amount
2024-07-03 15:54:05 -04:00
Zach Gollwitzer
3089e3c81d Remove custom currency styling, use default formatter (#937) 2024-07-02 07:27:19 -04:00
dependabot[bot]
0593d8fb7e Bump rails from 9e370f0 to df02832 (#930)
Bumps [rails](https://github.com/rails/rails) from `9e370f0` to `df02832`.
- [Release notes](https://github.com/rails/rails/releases)
- [Commits](9e370f0243...df02832784)

---
updated-dependencies:
- dependency-name: rails
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-01 11:24:51 -04:00
dependabot[bot]
a8ea207d47 Bump good_job from 3.29.4 to 3.29.5 (#929)
Bumps [good_job](https://github.com/bensheldon/good_job) from 3.29.4 to 3.29.5.
- [Release notes](https://github.com/bensheldon/good_job/releases)
- [Changelog](https://github.com/bensheldon/good_job/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bensheldon/good_job/compare/v3.29.4...v3.29.5)

---
updated-dependencies:
- dependency-name: good_job
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-01 11:21:09 -04:00
dependabot[bot]
c225eb6d03 Bump aws-sdk-s3 from 1.152.3 to 1.155.0 (#928)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.152.3 to 1.155.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-01 11:20:33 -04:00
dependabot[bot]
9b148316bc Bump pagy from 8.4.5 to 8.6.1 (#932)
Bumps [pagy](https://github.com/ddnexus/pagy) from 8.4.5 to 8.6.1.
- [Release notes](https://github.com/ddnexus/pagy/releases)
- [Changelog](https://github.com/ddnexus/pagy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ddnexus/pagy/compare/8.4.5...8.6.1)

---
updated-dependencies:
- dependency-name: pagy
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-01 11:19:49 -04:00
dependabot[bot]
8e7fcfd0b4 Bump sentry-ruby from 5.17.3 to 5.18.0 (#933)
Bumps [sentry-ruby](https://github.com/getsentry/sentry-ruby) from 5.17.3 to 5.18.0.
- [Release notes](https://github.com/getsentry/sentry-ruby/releases)
- [Changelog](https://github.com/getsentry/sentry-ruby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-ruby/compare/5.17.3...5.18.0)

---
updated-dependencies:
- dependency-name: sentry-ruby
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-01 11:19:21 -04:00
Zach Gollwitzer
c3314e62d1 Account::Entry Delegated Type (namespace updates part 7) (#923)
* Initial entryable models

* Update transfer and tests

* Update transaction controllers and tests

* Update sync process to use new entries model

* Get dashboard working again

* Update transfers, imports, and accounts to use Account::Entry

* Update system tests

* Consolidate transaction management into entries controller

* Add permitted partial key helper

* Move account transactions list to entries controller

* Delegate transaction entries search

* Move transfer relation to entry

* Update bulk transaction management flows to use entries

* Remove test code

* Test fix attempt

* Update demo data script

* Consolidate remaining transaction partials to entries

* Consolidate valuations controller to entries controller

* Lint fix

* Remove unused files, additional cleanup

* Add back valuation creation

* Make migrations fully reversible

* Stale routes cleanup

* Migrations reversible fix

* Move types to entryable concern

* Fix search when no entries found

* Remove more unused code
2024-07-01 10:49:43 -04:00
843 changed files with 46679 additions and 7764 deletions

64
.ai/cursorrules.md Normal file
View File

@@ -0,0 +1,64 @@
<!-- Copy this file to .cursorrules in the root of the project on your local machine if you'd like to use these rules with Cursor. -->
You are an expert in Ruby, Ruby on Rails, Postgres, Tailwind, Stimulus, Hotwire and Turbo and always use the latest stable versions of those technologies.
**Code Style and Structure**
- Write concise, technical Ruby code with accurate examples.
- Prefer iteration and modularization over code duplication.
- Use descriptive variable names with auxiliary verbs (e.g., is_loading, has_error).
- Structure files: models, controllers, views, helpers, services, jobs, mailers.
**Naming Conventions**
- Use snake_case for file names and directories (e.g., app/models/user_profile.rb).
- Use CamelCase for classes and modules (e.g., UserProfile).
**Ruby on Rails Usage**
- Use Rails conventions for MVC structure.
- Favor scopes over class methods for queries.
- Use strong parameters for mass assignment protection.
- Use partials to DRY up views.
**Syntax and Formatting**
- Use two spaces for indentation.
- Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements.
- Use descriptive method names and keep methods short.
**Commenting Code**
- Write clear, concise comments to explain the purpose of individual functions and methods.
- Use comments to describe the intent and functionality of complex logic.
- Avoid redundant comments that state the obvious.
**UI and Styling**
- Use Tailwind CSS for styling.
- Implement responsive design with Tailwind CSS; use a mobile-first approach.
- Use Stimulus for JavaScript behavior.
- Use Turbo for asynchronous actions and updates.
**Performance Optimization**
- Use eager loading to avoid N+1 queries.
- Cache expensive queries and partials where appropriate.
- Use background jobs for long-running tasks.
- Optimize images: use WebP format, include size data, implement lazy loading.
**Database Querying & Data Model Creation**
- Use ActiveRecord for data querying and model creation.
- Favor database constraints and indexes for data integrity and performance.
- Use migrations to manage schema changes.
**Key Conventions**
- Follow Rails best practices for RESTful routing.
- Optimize for performance and security.
- Use environment variables for configuration.
- Write tests for models, controllers, and features.
**AI Guidelines**
- Follow the users requirements carefully & to the letter.
- Confirm, then write code!
- Suggest solutions that I didn't think about—anticipate my needs
- Focus on readability over being performant.
- Fully implement all requested functionality.
- Leave NO todos, placeholders or missing pieces.
- Don't say things like "additional logic can be added here" — instead, add the logic.
- Be concise. Minimize any other prose.
- Consider new technologies and contrarian ideas, not just the conventional wisdom
- If I ask for adjustments to code, do not repeat all of my code unnecessarily. Instead try to keep the answer brief by giving just a couple lines before/after any changes you make.

View File

@@ -1,4 +1,4 @@
ARG RUBY_VERSION=3.3.1
ARG RUBY_VERSION=3.3.4
FROM ruby:${RUBY_VERSION}-slim-bullseye
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
@@ -17,4 +17,8 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
RUN gem install bundler
RUN gem install foreman
# Install Node.js 20
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y nodejs
WORKDIR /workspace

View File

@@ -10,5 +10,13 @@
"remoteEnv": {
"PATH": "/workspace/bin:${containerEnv:PATH}"
},
"postCreateCommand": "bundle install"
"postCreateCommand": "bundle install && npm install",
"customizations": {
"vscode": {
"extensions": [
"biomejs.biome",
"EditorConfig.EditorConfig"
]
}
}
}

7
.editorconfig Normal file
View File

@@ -0,0 +1,7 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2

View File

@@ -1,11 +1,24 @@
# ================================ PLEASE READ ==========================================
# This file outlines all the possible environment variables supported by the Maybe app.
#
# This includes several features that are for our "hosted" version of Maybe, which most
# open-source contributors won't need.
#
# If you are developing locally, you should be referencing `.env.local.example` instead.
# =======================================================================================
# Custom port config
# For users who have other applications listening at 3000, this allows them to set a value puma will listen to.
PORT=
PORT=3000
# Exchange Rate API
# This is used to convert between different currencies in the app. We use Synth, which is a Maybe product. You can sign up for a free account at synthfinance.com.
# Exchange Rate & US Stock Pricing API
# This is used to convert between different currencies in the app. In addition, it fetches US stock prices. We use Synth, which is a Maybe product. You can sign up for a free account at synthfinance.com.
SYNTH_API_KEY=
# Non-US Stock Pricing API
# This is used to fetch non-US stock prices. We use Marketstack.com for this and while they offer a free tier, it is quite limited. You'll almost certainly need their Basic plan, which is $9.99 per month.
MARKETSTACK_API_KEY=
# SMTP Configuration
# This is only needed if you intend on sending emails from your Maybe instance (such as for password resets or email financial reports).
# Resend.com is a good option that offers a free tier for sending emails.
@@ -15,7 +28,7 @@ SMTP_USERNAME=
SMTP_PASSWORD=
SMTP_TLS_ENABLED=true
# Email Configuration
# Address that emails are sent from
EMAIL_SENDER=
# Database Configuration
@@ -36,8 +49,8 @@ SENTRY_DSN=
# This is useful for controlling who can sign up for your Maybe instance.
REQUIRE_INVITE_CODE=false
# Enables self hosting features
SELF_HOSTING_ENABLED=false
# Enables self hosting features (should be set to true for most folks)
SELF_HOSTED=true
# The hosting platform used to deploy the app (e.g. "render")
# `localhost` (or unset) is used for local development and testing
@@ -86,3 +99,19 @@ GITHUB_REPO_BRANCH=main
# S3_SECRET_ACCESS_KEY=
# S3_REGION= # defaults to `us-east-1` if not set
# S3_BUCKET=
#
# Cloudflare R2
# =============
# ACTIVE_STORAGE_SERVICE=cloudflare
# CLOUDFLARE_ACCOUNT_ID=
# CLOUDFLARE_ACCESS_KEY_ID=
# CLOUDFLARE_SECRET_ACCESS_KEY=
# CLOUDFLARE_BUCKET=
# ======================================================================================================
# Billing Module - responsible for handling billing
# ======================================================================================================
#
STRIPE_PUBLISHABLE_KEY=
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=

8
.env.local.example Normal file
View File

@@ -0,0 +1,8 @@
# To enable / disable self-hosting features.
SELF_HOSTED=false
# Enable Synth market data (careful, this will use your API credits)
SYNTH_API_KEY=yourapikeyhere
# Enable Marketstack market data (careful, this will use your API credits)
MARKETSTACK_API_KEY=yourapikeyhere

8
.env.test Normal file
View File

@@ -0,0 +1,8 @@
SELF_HOSTED=false
SYNTH_API_KEY=fookey
# Set to true if you want SimpleCov reports generated
COVERAGE=false
# Set to true to run test suite serially
DISABLE_PARALLELIZATION=false

17
.env.test.example Normal file
View File

@@ -0,0 +1,17 @@
# ================
# Data Providers
# ---------------------------------------------------------------------------------
# Uncomment and fill in live keys when you need to generate a VCR cassette fixture
# ================
# SYNTH_API_KEY=<add live key here>
# ================
# Miscellaneous
# ================
# Set to true if you want SimpleCov reports generated
COVERAGE=false
# Set to true to run test suite serially
DISABLE_PARALLELIZATION=false

View File

@@ -20,6 +20,12 @@ Steps to reproduce the behavior:
**Expected behavior**
A clear and concise description of what you expected to happen.
**What version of Maybe are you using?**
This could be "Hosted" (i.e. app.maybe.co) or "Self-hosted". If "Self-hosted", please include the version you're currently on.
**What operating system and browser are you using?**
The more info the better.
**Screenshots / Recordings**
If applicable, add screenshots or short video recordings to help show the bug in more detail.

View File

@@ -52,8 +52,25 @@ jobs:
- name: Lint code for consistent style
run: bin/rubocop -f github
- name: Lint templates for consistent style
run: ./bin/erblint ./app/**/*.erb
lint_js:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js environment
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm install
shell: bash
- name: Lint/Format js code
run: npm run lint
test:
runs-on: ubuntu-latest
@@ -97,7 +114,6 @@ jobs:
- name: System tests
run: DISABLE_PARALLELIZATION=true bin/rails test:system
continue-on-error: true # TODO: Eventually we'll enforce for PRs
- name: Keep screenshots from failed system tests
uses: actions/upload-artifact@v4

14
.gitignore vendored
View File

@@ -10,7 +10,8 @@
# Ignore all environment files (except templates).
/.env*
!/.env*.erb
!.env.example
!.env.test
!.env*.example
# Ignore all logfiles and tempfiles.
/log/*
@@ -42,7 +43,9 @@
.idea
# Ignore VS Code
.vscode
.vscode/*
!.vscode/extensions.json
!.vscode/*.code-snippets
# Ignore macOS specific files
*/.DS_Store
@@ -51,7 +54,14 @@
# Ignore .devcontainer files
compose-dev.yaml
# Ignore asdf ruby version file
.tool-versions
# Ignore GCP keyfile
gcp-storage-keyfile.json
coverage
.cursorrules
# Ignore node related files
node_modules

View File

@@ -1,8 +1,15 @@
# Omakase Ruby styling for Rails
inherit_gem: { rubocop-rails-omakase: rubocop.yml }
inherit_gem:
rubocop-rails-omakase: rubocop.yml
Layout/IndentationWidth:
Enabled: true
# Overwrite or add rules to create your own house style
#
# # Use `[a, [b, c]]` not `[ a, [ b, c ] ]`
# Layout/SpaceInsideArrayLiteralBrackets:
# Enabled: false
Layout/IndentationStyle:
EnforcedStyle: spaces
IndentationWidth: 2
Layout/IndentationConsistency:
Enabled: true
Layout/SpaceInsidePercentLiteralDelimiters:
Enabled: true

View File

@@ -1 +1 @@
3.3.1
3.3.4

View File

@@ -1,7 +1,7 @@
# syntax = docker/dockerfile:1
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
ARG RUBY_VERSION=3.3.1
ARG RUBY_VERSION=3.3.4
FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base
# Rails app lives here

14
Gemfile
View File

@@ -3,7 +3,7 @@ source "https://rubygems.org"
ruby file: ".ruby-version"
# Rails
gem "rails", github: "rails/rails", branch: "7-2-stable"
gem "rails", "~> 7.2.1"
# Drivers
gem "pg", "~> 1.5"
@@ -38,27 +38,33 @@ gem "image_processing", ">= 1.2"
gem "bcrypt", "~> 3.1"
gem "faraday"
gem "faraday-retry"
gem "faraday-multipart"
gem "inline_svg"
gem "octokit"
gem "pagy"
gem "rails-settings-cached"
gem "tzinfo-data", platforms: %i[ windows jruby ]
gem "tzinfo-data", platforms: %i[windows jruby]
gem "csv"
gem "redcarpet"
gem "stripe"
gem "intercom-rails"
gem "holidays"
group :development, :test do
gem "debug", platforms: %i[ mri windows ]
gem "debug", platforms: %i[mri windows]
gem "brakeman", require: false
gem "rubocop-rails-omakase", require: false
gem "i18n-tasks"
gem "erb_lint"
gem "dotenv-rails"
end
group :development do
gem "dotenv-rails"
gem "hotwire-livereload"
gem "letter_opener"
gem "ruby-lsp-rails"
gem "web-console"
gem "faker"
end
group :test do

View File

@@ -1,128 +1,101 @@
GIT
remote: https://github.com/maybe-finance/lucide-rails.git
revision: 79d989593ee4ac6c50106ec5e4d2bd4ec8f5af87
revision: 272e5fb8418ea458da3995d6abe0ba0ceee9c9f0
specs:
lucide-rails (0.2.0)
railties (>= 4.1.0)
GIT
remote: https://github.com/rails/rails.git
revision: 9e370f0243870b39ea9801eeb95498f3a0d7bd83
branch: 7-2-stable
GEM
remote: https://rubygems.org/
specs:
actioncable (7.2.0.beta2)
actionpack (= 7.2.0.beta2)
activesupport (= 7.2.0.beta2)
actioncable (7.2.1.1)
actionpack (= 7.2.1.1)
activesupport (= 7.2.1.1)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
zeitwerk (~> 2.6)
actionmailbox (7.2.0.beta2)
actionpack (= 7.2.0.beta2)
activejob (= 7.2.0.beta2)
activerecord (= 7.2.0.beta2)
activestorage (= 7.2.0.beta2)
activesupport (= 7.2.0.beta2)
actionmailbox (7.2.1.1)
actionpack (= 7.2.1.1)
activejob (= 7.2.1.1)
activerecord (= 7.2.1.1)
activestorage (= 7.2.1.1)
activesupport (= 7.2.1.1)
mail (>= 2.8.0)
actionmailer (7.2.0.beta2)
actionpack (= 7.2.0.beta2)
actionview (= 7.2.0.beta2)
activejob (= 7.2.0.beta2)
activesupport (= 7.2.0.beta2)
actionmailer (7.2.1.1)
actionpack (= 7.2.1.1)
actionview (= 7.2.1.1)
activejob (= 7.2.1.1)
activesupport (= 7.2.1.1)
mail (>= 2.8.0)
rails-dom-testing (~> 2.2)
actionpack (7.2.0.beta2)
actionview (= 7.2.0.beta2)
activesupport (= 7.2.0.beta2)
actionpack (7.2.1.1)
actionview (= 7.2.1.1)
activesupport (= 7.2.1.1)
nokogiri (>= 1.8.5)
racc
rack (>= 2.2.4)
rack (>= 2.2.4, < 3.2)
rack-session (>= 1.0.1)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
useragent (~> 0.16)
actiontext (7.2.0.beta2)
actionpack (= 7.2.0.beta2)
activerecord (= 7.2.0.beta2)
activestorage (= 7.2.0.beta2)
activesupport (= 7.2.0.beta2)
actiontext (7.2.1.1)
actionpack (= 7.2.1.1)
activerecord (= 7.2.1.1)
activestorage (= 7.2.1.1)
activesupport (= 7.2.1.1)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.2.0.beta2)
activesupport (= 7.2.0.beta2)
actionview (7.2.1.1)
activesupport (= 7.2.1.1)
builder (~> 3.1)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
activejob (7.2.0.beta2)
activesupport (= 7.2.0.beta2)
activejob (7.2.1.1)
activesupport (= 7.2.1.1)
globalid (>= 0.3.6)
activemodel (7.2.0.beta2)
activesupport (= 7.2.0.beta2)
activerecord (7.2.0.beta2)
activemodel (= 7.2.0.beta2)
activesupport (= 7.2.0.beta2)
activemodel (7.2.1.1)
activesupport (= 7.2.1.1)
activerecord (7.2.1.1)
activemodel (= 7.2.1.1)
activesupport (= 7.2.1.1)
timeout (>= 0.4.0)
activestorage (7.2.0.beta2)
actionpack (= 7.2.0.beta2)
activejob (= 7.2.0.beta2)
activerecord (= 7.2.0.beta2)
activesupport (= 7.2.0.beta2)
activestorage (7.2.1.1)
actionpack (= 7.2.1.1)
activejob (= 7.2.1.1)
activerecord (= 7.2.1.1)
activesupport (= 7.2.1.1)
marcel (~> 1.0)
activesupport (7.2.0.beta2)
activesupport (7.2.1.1)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
logger
logger (>= 1.4.2)
minitest (>= 5.1)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
rails (7.2.0.beta2)
actioncable (= 7.2.0.beta2)
actionmailbox (= 7.2.0.beta2)
actionmailer (= 7.2.0.beta2)
actionpack (= 7.2.0.beta2)
actiontext (= 7.2.0.beta2)
actionview (= 7.2.0.beta2)
activejob (= 7.2.0.beta2)
activemodel (= 7.2.0.beta2)
activerecord (= 7.2.0.beta2)
activestorage (= 7.2.0.beta2)
activesupport (= 7.2.0.beta2)
bundler (>= 1.15.0)
railties (= 7.2.0.beta2)
railties (7.2.0.beta2)
actionpack (= 7.2.0.beta2)
activesupport (= 7.2.0.beta2)
irb (~> 1.13)
rackup (>= 1.0.0)
rake (>= 12.2)
thor (~> 1.0, >= 1.2.2)
zeitwerk (~> 2.6)
GEM
remote: https://rubygems.org/
specs:
addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
ast (2.4.2)
aws-eventstream (1.3.0)
aws-partitions (1.944.0)
aws-sdk-core (3.197.0)
aws-partitions (1.992.0)
aws-sdk-core (3.210.0)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.8)
aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.84.0)
aws-sdk-core (~> 3, >= 3.197.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.152.3)
aws-sdk-core (~> 3, >= 3.197.0)
aws-sdk-kms (1.95.0)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.169.0)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.8)
aws-sigv4 (1.8.0)
aws-sigv4 (~> 1.5)
aws-sigv4 (1.10.0)
aws-eventstream (~> 1, >= 1.0.2)
base64 (0.2.0)
bcrypt (3.1.20)
@@ -135,9 +108,9 @@ GEM
smart_properties
bigdecimal (3.1.8)
bindex (0.8.1)
bootsnap (1.18.3)
bootsnap (1.18.4)
msgpack (~> 1.2)
brakeman (6.1.2)
brakeman (6.2.2)
racc
builder (3.3.0)
capybara (3.40.0)
@@ -151,7 +124,7 @@ GEM
xpath (~> 3.2)
childprocess (5.0.0)
climate_control (1.2.0)
concurrent-ruby (1.3.3)
concurrent-ruby (1.3.4)
connection_pool (2.4.1)
crack (1.0.0)
bigdecimal
@@ -163,47 +136,59 @@ GEM
irb (~> 1.10)
reline (>= 0.3.8)
docile (1.4.0)
dotenv (3.1.2)
dotenv-rails (3.1.2)
dotenv (= 3.1.2)
dotenv (3.1.4)
dotenv-rails (3.1.4)
dotenv (= 3.1.4)
railties (>= 6.1)
drb (2.2.1)
erb_lint (0.5.0)
erb_lint (0.7.0)
activesupport
better_html (>= 2.0.1)
parser (>= 2.7.1.4)
rainbow
rubocop
rubocop (>= 1)
smart_properties
erubi (1.13.0)
et-orbi (1.2.11)
tzinfo
faraday (2.9.2)
faraday-net_http (>= 2.0, < 3.2)
faraday-net_http (3.1.0)
faker (3.5.1)
i18n (>= 1.8.11, < 2)
faraday (2.12.0)
faraday-net_http (>= 2.0, < 3.4)
json
logger
faraday-multipart (1.0.4)
multipart-post (~> 2)
faraday-net_http (3.3.0)
net-http
faraday-retry (2.2.1)
faraday (~> 2.0)
ffi (1.16.3)
fugit (1.11.0)
ffi (1.17.0-aarch64-linux-gnu)
ffi (1.17.0-arm-linux-gnu)
ffi (1.17.0-arm64-darwin)
ffi (1.17.0-x86-linux-gnu)
ffi (1.17.0-x86_64-darwin)
ffi (1.17.0-x86_64-linux-gnu)
fugit (1.11.1)
et-orbi (~> 1, >= 1.2.11)
raabro (~> 1.4)
globalid (1.2.1)
activesupport (>= 6.1)
good_job (3.29.4)
activejob (>= 6.0.0)
activerecord (>= 6.0.0)
concurrent-ruby (>= 1.0.2)
fugit (>= 1.1)
railties (>= 6.0.0)
thor (>= 0.14.1)
hashdiff (1.1.0)
good_job (4.4.2)
activejob (>= 6.1.0)
activerecord (>= 6.1.0)
concurrent-ruby (>= 1.3.1)
fugit (>= 1.11.0)
railties (>= 6.1.0)
thor (>= 1.0.0)
hashdiff (1.1.1)
highline (3.0.1)
hotwire-livereload (1.4.0)
holidays (8.8.0)
hotwire-livereload (1.4.1)
actioncable (>= 6.0.0)
listen (>= 3.0.0)
railties (>= 6.0.0)
i18n (1.14.5)
i18n (1.14.6)
concurrent-ruby (~> 1.0)
i18n-tasks (1.0.14)
activesupport (>= 4.0.2)
@@ -215,18 +200,20 @@ GEM
rails-i18n
rainbow (>= 2.2.2, < 4.0)
terminal-table (>= 1.5.1)
image_processing (1.12.2)
image_processing (1.13.0)
mini_magick (>= 4.9.5, < 5)
ruby-vips (>= 2.0.17, < 3)
importmap-rails (2.0.1)
importmap-rails (2.0.3)
actionpack (>= 6.0.0)
activesupport (>= 6.0.0)
railties (>= 6.0.0)
inline_svg (1.9.0)
inline_svg (1.10.0)
activesupport (>= 3.0)
nokogiri (>= 1.6)
intercom-rails (1.0.1)
activesupport (> 4.0)
io-console (0.7.2)
irb (1.13.2)
irb (1.14.1)
rdoc (>= 4.0.0)
reline (>= 0.4.2)
jmespath (1.6.2)
@@ -240,7 +227,7 @@ GEM
listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
logger (1.6.0)
logger (1.6.1)
loofah (2.22.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
@@ -251,15 +238,16 @@ GEM
net-smtp
marcel (1.0.4)
matrix (0.4.2)
mini_magick (4.12.0)
mini_magick (4.13.2)
mini_mime (1.1.5)
minitest (5.24.0)
mocha (2.4.0)
minitest (5.25.1)
mocha (2.4.5)
ruby2_keywords (>= 0.0.5)
msgpack (1.7.2)
multipart-post (2.4.1)
net-http (0.4.1)
uri
net-imap (0.4.14)
net-imap (0.5.0)
date
net-protocol
net-pop (0.1.2)
@@ -269,41 +257,41 @@ GEM
net-smtp (0.5.0)
net-protocol
nio4r (2.7.3)
nokogiri (1.16.6-aarch64-linux)
nokogiri (1.16.7-aarch64-linux)
racc (~> 1.4)
nokogiri (1.16.6-arm-linux)
nokogiri (1.16.7-arm-linux)
racc (~> 1.4)
nokogiri (1.16.6-arm64-darwin)
nokogiri (1.16.7-arm64-darwin)
racc (~> 1.4)
nokogiri (1.16.6-x86-linux)
nokogiri (1.16.7-x86-linux)
racc (~> 1.4)
nokogiri (1.16.6-x86_64-darwin)
nokogiri (1.16.7-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.16.6-x86_64-linux)
nokogiri (1.16.7-x86_64-linux)
racc (~> 1.4)
octokit (9.1.0)
octokit (9.2.0)
faraday (>= 1, < 3)
sawyer (~> 0.9)
pagy (8.4.5)
parallel (1.24.0)
parser (3.3.1.0)
pagy (9.1.0)
parallel (1.26.3)
parser (3.3.5.0)
ast (~> 2.4.1)
racc
pg (1.5.6)
prism (0.29.0)
propshaft (0.9.0)
pg (1.5.8)
prism (1.2.0)
propshaft (1.1.0)
actionpack (>= 7.0.0)
activesupport (>= 7.0.0)
rack
railties (>= 7.0.0)
psych (5.1.2)
stringio
public_suffix (5.1.0)
puma (6.4.2)
public_suffix (6.0.1)
puma (6.4.3)
nio4r (~> 2.0)
raabro (1.4.0)
racc (1.8.0)
rack (3.1.4)
racc (1.8.1)
rack (3.1.8)
rack-session (2.0.0)
rack (>= 3.0.0)
rack-test (2.1.0)
@@ -311,6 +299,20 @@ GEM
rackup (2.1.0)
rack (>= 3)
webrick (~> 1.8)
rails (7.2.1.1)
actioncable (= 7.2.1.1)
actionmailbox (= 7.2.1.1)
actionmailer (= 7.2.1.1)
actionpack (= 7.2.1.1)
actiontext (= 7.2.1.1)
actionview (= 7.2.1.1)
activejob (= 7.2.1.1)
activemodel (= 7.2.1.1)
activerecord (= 7.2.1.1)
activestorage (= 7.2.1.1)
activesupport (= 7.2.1.1)
bundler (>= 1.15.0)
railties (= 7.2.1.1)
rails-dom-testing (2.2.0)
activesupport (>= 5.0.0)
minitest
@@ -321,33 +323,42 @@ GEM
rails-i18n (7.0.9)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8)
rails-settings-cached (2.9.4)
rails-settings-cached (2.9.5)
activerecord (>= 5.0.0)
railties (>= 5.0.0)
railties (7.2.1.1)
actionpack (= 7.2.1.1)
activesupport (= 7.2.1.1)
irb (~> 1.13)
rackup (>= 1.0.0)
rake (>= 12.2)
thor (~> 1.0, >= 1.2.2)
zeitwerk (~> 2.6)
rainbow (3.1.1)
rake (13.2.1)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
rb-inotify (0.11.1)
ffi (~> 1.0)
rbs (3.6.1)
logger
rdoc (6.7.0)
psych (>= 4.0.0)
redcarpet (3.6.0)
regexp_parser (2.9.2)
reline (0.5.9)
reline (0.5.10)
io-console (~> 0.5)
rexml (3.3.0)
strscan
rubocop (1.63.5)
rexml (3.3.8)
rubocop (1.67.0)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.31.1, < 2.0)
regexp_parser (>= 2.4, < 3.0)
rubocop-ast (>= 1.32.2, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.31.3)
rubocop-ast (1.32.3)
parser (>= 3.3.1.0)
rubocop-minitest (0.35.0)
rubocop (>= 1.61, < 2.0)
@@ -365,30 +376,33 @@ GEM
rubocop-minitest
rubocop-performance
rubocop-rails
ruby-lsp (0.17.1)
ruby-lsp (0.20.1)
language_server-protocol (~> 3.17.0)
prism (>= 0.29.0, < 0.30)
prism (>= 1.2, < 2.0)
rbs (>= 3, < 4)
sorbet-runtime (>= 0.5.10782)
ruby-lsp-rails (0.3.7)
ruby-lsp (>= 0.17.0, < 0.18.0)
ruby-lsp-rails (0.3.20)
ruby-lsp (>= 0.20.0, < 0.21.0)
ruby-progressbar (1.13.0)
ruby-vips (2.2.1)
ruby-vips (2.2.2)
ffi (~> 1.12)
logger
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
sawyer (0.9.2)
addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3)
selenium-webdriver (4.22.0)
securerandom (0.3.1)
selenium-webdriver (4.25.0)
base64 (~> 0.2)
logger (~> 1.4)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
sentry-rails (5.17.3)
sentry-rails (5.21.0)
railties (>= 5.0)
sentry-ruby (~> 5.17.3)
sentry-ruby (5.17.3)
sentry-ruby (~> 5.21.0)
sentry-ruby (5.21.0)
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
simplecov (0.22.0)
@@ -398,55 +412,52 @@ GEM
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.4)
smart_properties (1.17.0)
sorbet-runtime (0.5.11406)
sorbet-runtime (0.5.11609)
stackprof (0.2.26)
stimulus-rails (1.3.3)
stimulus-rails (1.3.4)
railties (>= 6.0.0)
stringio (3.1.1)
strscan (3.1.0)
tailwindcss-rails (2.6.1)
railties (>= 7.0.0)
tailwindcss-rails (2.6.1-aarch64-linux)
railties (>= 7.0.0)
tailwindcss-rails (2.6.1-arm-linux)
railties (>= 7.0.0)
tailwindcss-rails (2.6.1-arm64-darwin)
railties (>= 7.0.0)
tailwindcss-rails (2.6.1-x86_64-darwin)
railties (>= 7.0.0)
tailwindcss-rails (2.6.1-x86_64-linux)
stripe (13.0.1)
tailwindcss-rails (3.0.0)
railties (>= 7.0.0)
tailwindcss-ruby
tailwindcss-ruby (3.4.14)
tailwindcss-ruby (3.4.14-aarch64-linux)
tailwindcss-ruby (3.4.14-arm-linux)
tailwindcss-ruby (3.4.14-arm64-darwin)
tailwindcss-ruby (3.4.14-x86_64-darwin)
tailwindcss-ruby (3.4.14-x86_64-linux)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
thor (1.3.1)
thor (1.3.2)
timeout (0.4.1)
turbo-rails (2.0.5)
turbo-rails (2.0.11)
actionpack (>= 6.0.0)
activejob (>= 6.0.0)
railties (>= 6.0.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (2.5.0)
uri (0.13.0)
unicode-display_width (2.6.0)
uri (0.13.1)
useragent (0.16.10)
vcr (6.2.0)
vcr (6.3.1)
base64
web-console (4.2.1)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
bindex (>= 0.4.0)
railties (>= 6.0.0)
webmock (3.23.1)
webmock (3.24.0)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.8.1)
websocket (1.2.10)
webrick (1.8.2)
websocket (1.2.11)
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.6.16)
zeitwerk (2.7.1)
PLATFORMS
aarch64-linux
@@ -467,14 +478,18 @@ DEPENDENCIES
debug
dotenv-rails
erb_lint
faker
faraday
faraday-multipart
faraday-retry
good_job
holidays
hotwire-livereload
i18n-tasks
image_processing (>= 1.2)
importmap-rails
inline_svg
intercom-rails
letter_opener
lucide-rails!
mocha
@@ -483,8 +498,9 @@ DEPENDENCIES
pg (~> 1.5)
propshaft
puma (>= 5.0)
rails!
rails (~> 7.2.1)
rails-settings-cached
redcarpet
rubocop-rails-omakase
ruby-lsp-rails
selenium-webdriver
@@ -493,6 +509,7 @@ DEPENDENCIES
simplecov
stackprof
stimulus-rails
stripe
tailwindcss-rails
turbo-rails
tzinfo-data
@@ -501,7 +518,7 @@ DEPENDENCIES
webmock
RUBY VERSION
ruby 3.3.1p55
ruby 3.3.4p94
BUNDLED WITH
2.5.9

View File

@@ -1,3 +1,3 @@
web: bin/rails server -b 0.0.0.0
web: ${DEBUG:+rdbg -O -n -c --} bin/rails server -b 0.0.0.0
css: bin/rails tailwindcss:watch
worker: bundle exec good_job start

View File

@@ -42,14 +42,14 @@ The instructions below are for developers to get started with contributing to th
### Requirements
- Ruby 3.3.1
- Ruby 3.3.4
- PostgreSQL >9.3 (ideally, latest stable version)
After cloning the repo, the basic setup commands are:
```sh
cd maybe
cp .env.example .env
cp .env.local.example .env.local
bin/setup
bin/dev

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 127.14 96.36"><path fill="#5865f2" d="M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,1-10.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z"/></svg>

After

Width:  |  Height:  |  Size: 764 B

View File

@@ -0,0 +1 @@
<svg width="98" height="96" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="#24292f"/></svg>

After

Width:  |  Height:  |  Size: 963 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

@@ -0,0 +1,160 @@
<svg width="70" height="70" viewBox="0 0 70 70" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_iii_4725_68011)">
<path d="M1.66199 28.3573C3.33915 4.37286 8.83917 -0.408237 32.8236 1.26892L41.868 1.90136C65.8524 3.57851 70.6335 9.07854 68.9563 33.063L68.3239 42.1073C66.6467 66.0917 61.1467 70.8728 37.1623 69.1957L28.1179 68.5632C4.13349 66.8861 -0.647606 61.3861 1.02955 37.4016L1.66199 28.3573Z" fill="url(#paint0_linear_4725_68011)"/>
<path d="M1.66199 28.3573C3.33915 4.37286 8.83917 -0.408237 32.8236 1.26892L41.868 1.90136C65.8524 3.57851 70.6335 9.07854 68.9563 33.063L68.3239 42.1073C66.6467 66.0917 61.1467 70.8728 37.1623 69.1957L28.1179 68.5632C4.13349 66.8861 -0.647606 61.3861 1.02955 37.4016L1.66199 28.3573Z" fill="black" fill-opacity="0.7"/>
</g>
<path d="M2.82179 28.4384C3.23922 22.4687 3.89051 17.7733 4.98031 14.1012C6.06625 10.4421 7.56711 7.86966 9.64032 6.06745C11.7135 4.26524 14.4698 3.13701 18.2445 2.57088C22.0324 2.00274 26.7729 2.01127 32.7425 2.42871L41.7868 3.06115C47.7565 3.47859 52.452 4.12988 56.124 5.21968C59.7831 6.30562 62.3556 7.80648 64.1578 9.87969C65.96 11.9529 67.0882 14.7092 67.6544 18.4838C68.2225 22.2718 68.214 27.0122 67.7965 32.9819L67.1641 42.0262C66.7466 47.9959 66.0953 52.6913 65.0056 56.3634C63.9196 60.0225 62.4188 62.5949 60.3455 64.3971C58.2723 66.1994 55.516 67.3276 51.7414 67.8937C47.9534 68.4619 43.213 68.4533 37.2434 68.0359L28.199 67.4034C22.2294 66.986 17.5339 66.3347 13.8619 65.2449C10.2028 64.159 7.6303 62.6581 5.82808 60.5849C4.02587 58.5117 2.89764 55.7554 2.33151 51.9808C1.76337 48.1928 1.77191 43.4524 2.18934 37.4827L2.82179 28.4384Z" stroke="white" stroke-width="2.32525"/>
<path d="M2.82179 28.4384C3.23922 22.4687 3.89051 17.7733 4.98031 14.1012C6.06625 10.4421 7.56711 7.86966 9.64032 6.06745C11.7135 4.26524 14.4698 3.13701 18.2445 2.57088C22.0324 2.00274 26.7729 2.01127 32.7425 2.42871L41.7868 3.06115C47.7565 3.47859 52.452 4.12988 56.124 5.21968C59.7831 6.30562 62.3556 7.80648 64.1578 9.87969C65.96 11.9529 67.0882 14.7092 67.6544 18.4838C68.2225 22.2718 68.214 27.0122 67.7965 32.9819L67.1641 42.0262C66.7466 47.9959 66.0953 52.6913 65.0056 56.3634C63.9196 60.0225 62.4188 62.5949 60.3455 64.3971C58.2723 66.1994 55.516 67.3276 51.7414 67.8937C47.9534 68.4619 43.213 68.4533 37.2434 68.0359L28.199 67.4034C22.2294 66.986 17.5339 66.3347 13.8619 65.2449C10.2028 64.159 7.6303 62.6581 5.82808 60.5849C4.02587 58.5117 2.89764 55.7554 2.33151 51.9808C1.76337 48.1928 1.77191 43.4524 2.18934 37.4827L2.82179 28.4384Z" stroke="url(#paint1_linear_4725_68011)" stroke-width="2.32525"/>
<path d="M3.66933 28.4976C4.08541 22.5474 4.73164 17.9253 5.79481 14.343C6.85131 10.7831 8.28392 8.3723 10.1977 6.70866C12.1115 5.04503 14.6982 3.96188 18.3705 3.4111C22.0659 2.85684 26.7329 2.86017 32.6832 3.27625L41.7276 3.9087C47.6779 4.32478 52.2999 4.97101 55.8823 6.03418C59.4422 7.09068 61.8529 8.52329 63.5166 10.4371C65.1802 12.3509 66.2634 14.9376 66.8141 18.6098C67.3684 22.3053 67.3651 26.9723 66.949 32.9226L66.3165 41.967C65.9005 47.9172 65.2542 52.5393 64.1911 56.1216C63.1345 59.6815 61.7019 62.0923 59.7882 63.7559C57.8744 65.4196 55.2877 66.5027 51.6154 67.0535C47.92 67.6078 43.2529 67.6044 37.3026 67.1883L28.2583 66.5559C22.308 66.1398 17.6859 65.4936 14.1036 64.4304C10.5437 63.3739 8.13293 61.9413 6.4693 60.0275C4.80566 58.1137 3.72251 55.527 3.17173 51.8548C2.61747 48.1593 2.6208 43.4923 3.03688 37.542L3.66933 28.4976Z" stroke="url(#paint2_linear_4725_68011)" stroke-opacity="0.05" stroke-width="4.02448"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.20106 14.4635C5.15118 18.0011 4.50747 22.5866 4.09206 28.5272L3.45962 37.5716C3.04421 43.5122 3.04348 48.1426 3.59081 51.7919C4.13394 55.4131 5.1946 57.9152 6.78912 59.7495C8.38363 61.5838 10.7138 62.9824 14.2242 64.0242C17.7617 65.0741 22.3472 65.7178 28.2878 66.1332L37.3322 66.7656C43.2728 67.181 47.9033 67.1818 51.5525 66.6344C55.1738 66.0913 57.6759 65.0306 59.5101 63.4361C61.3444 61.8416 62.743 59.5115 63.7848 56.0011C64.8347 52.4635 65.4784 47.878 65.8938 41.9374L66.5262 32.893C66.9417 26.9524 66.9424 22.322 66.3951 18.6727C65.8519 15.0515 64.7913 12.5494 63.1968 10.7151C61.6022 8.88082 59.2721 7.48225 55.7617 6.44043C52.2241 5.39055 47.6387 4.74684 41.698 4.33143L32.6537 3.69899C26.713 3.28358 22.0826 3.28284 18.4333 3.83018C14.8121 4.3733 12.31 5.43397 10.4757 7.02849C8.64145 8.623 7.24288 10.9531 6.20106 14.4635ZM32.8236 1.26892C8.83917 -0.408237 3.33915 4.37286 1.66199 28.3573L1.02955 37.4016C-0.647606 61.3861 4.13349 66.8861 28.1179 68.5632L37.1623 69.1957C61.1467 70.8728 66.6467 66.0917 68.3239 42.1073L68.9563 33.063C70.6335 9.07854 65.8524 3.57851 41.868 1.90136L32.8236 1.26892Z" fill="url(#paint3_linear_4725_68011)"/>
<g filter="url(#filter1_ddii_4725_68011)">
<path d="M20.8165 43.8927L14.5692 43.4559C13.0888 43.3523 11.8006 44.5292 11.6919 46.0845C11.5831 47.6398 12.695 48.9845 14.1753 49.088L20.4227 49.5248C21.903 49.6284 23.1912 48.4515 23.3 46.8962C23.4087 45.3409 22.2968 43.9962 20.8165 43.8927Z" fill="#F23E94"/>
<path d="M14.5574 43.6244L20.8047 44.0612C22.1842 44.1577 23.2343 45.4143 23.1315 46.8844C23.0287 48.3546 21.814 49.4528 20.4344 49.3564L14.1871 48.9195C12.8076 48.823 11.7576 47.5664 11.8604 46.0963C11.9632 44.6261 13.1779 43.5279 14.5574 43.6244Z" stroke="url(#paint4_linear_4725_68011)" stroke-opacity="0.1" stroke-width="0.33782" stroke-linejoin="round"/>
<path d="M48.3652 51.4775L54.6125 51.9144C56.0928 52.0179 57.381 50.841 57.4898 49.2857C57.5985 47.7305 56.4866 46.3858 55.0063 46.2823L48.759 45.8454C47.2787 45.7419 45.9905 46.9188 45.8817 48.474C45.7729 50.0293 46.8848 51.374 48.3652 51.4775Z" fill="#F23E94"/>
<path d="M54.6243 51.7459L48.3769 51.309C46.9974 51.2126 45.9474 49.956 46.0502 48.4858C46.153 47.0157 47.3677 45.9174 48.7472 46.0139L54.9945 46.4508C56.3741 46.5472 57.4241 47.8038 57.3213 49.274C57.2185 50.7441 56.0038 51.8423 54.6243 51.7459Z" stroke="url(#paint5_linear_4725_68011)" stroke-opacity="0.1" stroke-width="0.33782" stroke-linejoin="round"/>
<path d="M37.3154 45.0271L32.2298 44.6714C30.7495 44.5679 29.4613 45.7448 29.3525 47.3001C29.2438 48.8553 30.3556 50.2001 31.836 50.3036L36.9215 50.6592C38.4019 50.7627 39.6901 49.5858 39.7988 48.0306C39.9076 46.4753 38.7957 45.1306 37.3154 45.0271Z" fill="#F23E94"/>
<path d="M32.218 44.8399L37.3036 45.1956C38.6831 45.292 39.7331 46.5486 39.6303 48.0188C39.5275 49.4889 38.3128 50.5872 36.9333 50.4907L31.8478 50.1351C30.4682 50.0386 29.4182 48.782 29.521 47.3119C29.6238 45.8417 30.8385 44.7435 32.218 44.8399Z" stroke="url(#paint6_linear_4725_68011)" stroke-opacity="0.1" stroke-width="0.33782" stroke-linejoin="round"/>
<path d="M46.5039 43.2046L52.5198 43.6253C54.0001 43.7288 55.2884 42.5519 55.3971 40.9967C55.5059 39.4414 54.394 38.0967 52.9136 37.9932L46.8977 37.5725C45.4174 37.469 44.1292 38.6459 44.0204 40.2011C43.9116 41.7564 45.0235 43.1011 46.5039 43.2046Z" fill="#6927DA"/>
<path d="M52.5316 43.4568L46.5156 43.0361C45.1361 42.9397 44.0861 41.6831 44.1889 40.2129C44.2917 38.7428 45.5064 37.6445 46.8859 37.741L52.9019 38.1617C54.2814 38.2582 55.3314 39.5148 55.2286 40.9849C55.1258 42.455 53.9111 43.5533 52.5316 43.4568Z" stroke="url(#paint7_linear_4725_68011)" stroke-opacity="0.1" stroke-width="0.33782" stroke-linejoin="round"/>
<path d="M23.7094 35.95L17.6934 35.5293C16.2131 35.4258 14.9249 36.6027 14.8161 38.158C14.7074 39.7133 15.8193 41.058 17.2996 41.1615L23.3155 41.5822C24.7959 41.6857 26.0841 40.5088 26.1928 38.9535C26.3016 37.3983 25.1897 36.0535 23.7094 35.95Z" fill="#6927DA"/>
<path d="M17.6817 35.6978L23.6976 36.1185C25.0771 36.215 26.1272 37.4716 26.0244 38.9417C25.9215 40.4119 24.7069 41.5101 23.3273 41.4137L17.3114 40.993C15.9319 40.8965 14.8818 39.6399 14.9846 38.1698C15.0874 36.6996 16.3021 35.6014 17.6817 35.6978Z" stroke="url(#paint8_linear_4725_68011)" stroke-opacity="0.1" stroke-width="0.33782" stroke-linejoin="round"/>
<path d="M39.8134 37.0582L30.8613 36.4322C29.381 36.3287 28.0927 37.5055 27.984 39.0608C27.8752 40.6161 28.9871 41.9608 30.4675 42.0643L39.4195 42.6903C40.8999 42.7938 42.1881 41.6169 42.2968 40.0617C42.4056 38.5064 41.2937 37.1617 39.8134 37.0582Z" fill="#6927DA"/>
<path d="M30.8495 36.6007L39.8016 37.2267C41.1811 37.3231 42.2311 38.5797 42.1283 40.0499C42.0255 41.52 40.8108 42.6183 39.4313 42.5218L30.4792 41.8958C29.0997 41.7994 28.0497 40.5428 28.1525 39.0726C28.2553 37.6025 29.47 36.5042 30.8495 36.6007Z" stroke="url(#paint9_linear_4725_68011)" stroke-opacity="0.1" stroke-width="0.33782" stroke-linejoin="round"/>
<path d="M32.3636 28.1666L20.9406 27.3679C19.4603 27.2643 18.1721 28.4412 18.0633 29.9965C17.9546 31.5518 19.0665 32.8965 20.5468 33L31.9698 33.7988C33.4501 33.9023 34.7383 32.7254 34.8471 31.1701C34.9558 29.6148 33.8439 28.2701 32.3636 28.1666Z" fill="#1570EF"/>
<path d="M20.9289 27.5363L32.3518 28.3351C33.7314 28.4316 34.7814 29.6882 34.6786 31.1583C34.5758 32.6285 33.3611 33.7267 31.9816 33.6303L20.5586 32.8315C19.179 32.735 18.129 31.4784 18.2318 30.0083C18.3346 28.5381 19.5493 27.4399 20.9289 27.5363Z" stroke="url(#paint10_linear_4725_68011)" stroke-opacity="0.1" stroke-width="0.33782" stroke-linejoin="round"/>
<path d="M39.7417 34.3403L50.4352 35.0881C51.9156 35.1916 53.2038 34.0147 53.3125 32.4594C53.4213 30.9042 52.3094 29.5595 50.8291 29.456L40.1356 28.7082C38.6552 28.6047 37.367 29.7816 37.2583 31.3368C37.1495 32.8921 38.2614 34.2368 39.7417 34.3403Z" fill="#1570EF"/>
<path d="M50.447 34.9196L39.7535 34.1718C38.374 34.0754 37.324 32.8188 37.4268 31.3486C37.5296 29.8785 38.7442 28.7802 40.1238 28.8767L50.8173 29.6245C52.1968 29.7209 53.2468 30.9775 53.144 32.4477C53.0412 33.9178 51.8265 35.0161 50.447 34.9196Z" stroke="url(#paint11_linear_4725_68011)" stroke-opacity="0.1" stroke-width="0.33782" stroke-linejoin="round"/>
<path d="M48.8251 21.1728L42.7957 20.7512C41.3154 20.6476 40.0272 21.8245 39.9184 23.3798C39.8097 24.9351 40.9216 26.2798 42.4019 26.3833L48.4312 26.8049C49.9116 26.9084 51.1998 25.7315 51.3085 24.1763C51.4173 22.621 50.3054 21.2763 48.8251 21.1728Z" fill="#22CCEE"/>
<path d="M42.784 20.9196L48.8133 21.3413C50.1928 21.4377 51.2428 22.6943 51.14 24.1645C51.0372 25.6346 49.8226 26.7329 48.443 26.6364L42.4137 26.2148C41.0342 26.1183 39.9841 24.8617 40.0869 23.3916C40.1897 21.9214 41.4044 20.8232 42.784 20.9196Z" stroke="url(#paint12_linear_4725_68011)" stroke-opacity="0.1" stroke-width="0.33782" stroke-linejoin="round"/>
<path d="M30.0984 19.8627L24.0691 19.4411C22.5887 19.3376 21.3005 20.5145 21.1918 22.0697C21.083 23.625 22.1949 24.9697 23.6752 25.0732L29.7046 25.4948C31.1849 25.5983 32.4731 24.4215 32.5819 22.8662C32.6906 21.3109 31.5787 19.9662 30.0984 19.8627Z" fill="#22CCEE"/>
<path d="M24.0573 19.6096L30.0866 20.0312C31.4661 20.1277 32.5162 21.3843 32.4134 22.8544C32.3106 24.3246 31.0959 25.4228 29.7163 25.3263L23.687 24.9047C22.3075 24.8083 21.2574 23.5517 21.3603 22.0815C21.4631 20.6114 22.6777 19.5131 24.0573 19.6096Z" stroke="url(#paint13_linear_4725_68011)" stroke-opacity="0.1" stroke-width="0.33782" stroke-linejoin="round"/>
</g>
<g opacity="0.23" filter="url(#filter2_f_4725_68011)">
<path d="M2.69258 40.4874L12.7122 44.9449L39.098 57.1213L66.9412 61.8859L45.5294 72.5984L-0.202764 68.4613L2.69258 40.4874Z" fill="#F24396"/>
</g>
<g opacity="0.23" filter="url(#filter3_f_4725_68011)">
<path d="M2.56821 1.97031L52.6272 -2.04293L69.5358 11.3492L56.9932 16.1074L23.2807 14.6892L2.56821 1.97031Z" fill="#22CCEE"/>
</g>
<defs>
<filter id="filter0_iii_4725_68011" x="0.72644" y="-2.61149" width="68.533" height="75.6876" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1.27762"/>
<feGaussianBlur stdDeviation="1.59703"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.196078 0 0 0 0 0.188235 0 0 0 0 0.219608 0 0 0 1 0"/>
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_4725_68011"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="3.57731"/>
<feGaussianBlur stdDeviation="2.68298"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.321569 0 0 0 0 0.905882 0 0 0 0 1 0 0 0 0.6 0"/>
<feBlend mode="normal" in2="effect1_innerShadow_4725_68011" result="effect2_innerShadow_4725_68011"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="-3.57731"/>
<feGaussianBlur stdDeviation="1.78866"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.933333 0 0 0 0 0.160784 0 0 0 0 0.509804 0 0 0 0.5 0"/>
<feBlend mode="normal" in2="effect2_innerShadow_4725_68011" result="effect3_innerShadow_4725_68011"/>
</filter>
<filter id="filter1_ddii_4725_68011" x="1.54998" y="10.9893" width="66.0817" height="52.755" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1.6891"/>
<feGaussianBlur stdDeviation="5.0673"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.29135 0 0 0 0 0.0895476 0 0 0 0 0.654593 0 0 0 1 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_4725_68011"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1.6891"/>
<feGaussianBlur stdDeviation="4.22275"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
<feBlend mode="normal" in2="effect1_dropShadow_4725_68011" result="effect2_dropShadow_4725_68011"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_4725_68011" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="-1.6891"/>
<feGaussianBlur stdDeviation="0.844549"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
<feBlend mode="normal" in2="shape" result="effect3_innerShadow_4725_68011"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1.6891"/>
<feGaussianBlur stdDeviation="0.844549"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="effect3_innerShadow_4725_68011" result="effect4_innerShadow_4725_68011"/>
</filter>
<filter id="filter2_f_4725_68011" x="-23.4553" y="17.2348" width="113.649" height="78.6161" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="11.6263" result="effect1_foregroundBlur_4725_68011"/>
</filter>
<filter id="filter3_f_4725_68011" x="-20.6843" y="-25.2955" width="113.473" height="64.6555" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="11.6263" result="effect1_foregroundBlur_4725_68011"/>
</filter>
<linearGradient id="paint0_linear_4725_68011" x1="53.7772" y1="8.36942" x2="38.7315" y2="35.4937" gradientUnits="userSpaceOnUse">
<stop stop-color="#363636"/>
<stop offset="1" stop-color="#141414"/>
</linearGradient>
<linearGradient id="paint1_linear_4725_68011" x1="37.3458" y1="1.58514" x2="32.6401" y2="68.8795" gradientUnits="userSpaceOnUse">
<stop stop-color="#52EDFF"/>
<stop offset="0.274483" stop-color="#4361EE"/>
<stop offset="0.629793" stop-color="#7209B7"/>
<stop offset="1" stop-color="#F12980"/>
</linearGradient>
<linearGradient id="paint2_linear_4725_68011" x1="37.019" y1="6.25836" x2="33.4897" y2="56.7291" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint3_linear_4725_68011" x1="37.3458" y1="1.58514" x2="32.6401" y2="68.8795" gradientUnits="userSpaceOnUse">
<stop stop-color="#52EDFF"/>
<stop offset="0.274483" stop-color="#4361EE"/>
<stop offset="0.629793" stop-color="#7209B7"/>
<stop offset="1" stop-color="#F12980"/>
</linearGradient>
<linearGradient id="paint4_linear_4725_68011" x1="17.6928" y1="43.6743" x2="17.299" y2="49.3064" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint5_linear_4725_68011" x1="51.4888" y1="51.6959" x2="51.8826" y2="46.0638" gradientUnits="userSpaceOnUse">
<stop stop-color="white" stop-opacity="0"/>
<stop offset="1" stop-color="white"/>
</linearGradient>
<linearGradient id="paint6_linear_4725_68011" x1="34.7726" y1="44.8492" x2="34.3788" y2="50.4814" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint7_linear_4725_68011" x1="49.5118" y1="43.415" x2="49.9057" y2="37.7829" gradientUnits="userSpaceOnUse">
<stop stop-color="white" stop-opacity="0"/>
<stop offset="1" stop-color="white"/>
</linearGradient>
<linearGradient id="paint8_linear_4725_68011" x1="20.7014" y1="35.7397" x2="20.3076" y2="41.3718" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint9_linear_4725_68011" x1="35.3373" y1="36.7452" x2="34.9435" y2="42.3773" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint10_linear_4725_68011" x1="26.6521" y1="27.7672" x2="26.2583" y2="33.3994" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint11_linear_4725_68011" x1="45.0885" y1="34.7142" x2="45.4823" y2="29.0821" gradientUnits="userSpaceOnUse">
<stop stop-color="white" stop-opacity="0"/>
<stop offset="1" stop-color="white"/>
</linearGradient>
<linearGradient id="paint12_linear_4725_68011" x1="45.8104" y1="20.962" x2="45.4166" y2="26.5941" gradientUnits="userSpaceOnUse">
<stop stop-color="white" stop-opacity="0"/>
<stop offset="1" stop-color="white"/>
</linearGradient>
<linearGradient id="paint13_linear_4725_68011" x1="27.0837" y1="19.6519" x2="26.6899" y2="25.284" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

View File

@@ -0,0 +1,6 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Frame 1321315963">
<rect width="20" height="20" rx="10" fill="#635BFF"/>
<path id="Vector" fill-rule="evenodd" clip-rule="evenodd" d="M9.35663 7.69056C9.35663 7.20077 9.75747 7.01238 10.4214 7.01238C11.3734 7.01238 12.5759 7.30124 13.5279 7.81615V4.86482C12.4882 4.45037 11.461 4.28711 10.4214 4.28711C7.87854 4.28711 6.1875 5.61835 6.1875 7.84127C6.1875 11.3075 10.9475 10.7549 10.9475 12.2494C10.9475 12.8271 10.4464 13.0155 9.74495 13.0155C8.70527 13.0155 7.37749 12.5885 6.32529 12.0108V14.9998C7.49023 15.5022 8.66769 15.7157 9.74495 15.7157C12.3504 15.7157 14.1416 14.4221 14.1416 12.1741C14.1291 8.43154 9.35663 9.09716 9.35663 7.69056Z" fill="white"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 775 B

View File

@@ -4,30 +4,30 @@
/* Reset rules, default styles applied to plain HTML */
@layer base {
details > summary::-webkit-details-marker {
details>summary::-webkit-details-marker {
@apply hidden;
}
details > summary {
details>summary {
@apply list-none;
}
}
@layer components {
.form-field {
@apply relative rounded-md border bg-white border-alpha-black-100 shadow-xs;
@apply flex flex-col gap-1 relative px-3 py-2 rounded-md border bg-white border-alpha-black-100 shadow-xs w-full;
@apply focus-within:border-gray-900 focus-within:shadow-none focus-within:ring-4 focus-within:ring-gray-100;
}
.form-field__label {
@apply block px-3 pt-2 pb-0 text-xs text-gray-500;
@apply block text-xs text-gray-500 peer-disabled:text-gray-400;
}
.form-field__input {
@apply w-full border-none bg-transparent px-3 pt-1 pb-2 text-sm opacity-100;
@apply border-none bg-transparent text-sm opacity-100 w-full p-0;
@apply focus:opacity-100 focus:outline-none focus:ring-0;
@apply placeholder-shown:opacity-50;
@apply disabled:opacity-50;
@apply disabled:text-gray-400;
}
.form-field__radio {
@@ -35,10 +35,10 @@
}
.form-field__submit {
@apply w-full cursor-pointer rounded-lg bg-black p-3 text-center text-white hover:bg-gray-700;
@apply cursor-pointer rounded-lg bg-black p-3 text-center text-white hover:bg-gray-700;
}
input:checked + label + .toggle-switch-dot {
input:checked+label+.toggle-switch-dot {
transform: translateX(100%);
}
@@ -58,6 +58,23 @@
background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='111827' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");
}
select[multiple="multiple"] {
@apply py-2 pr-2 space-y-0.5;
}
select[multiple="multiple"] option {
@apply py-2 rounded-md;
}
select[multiple="multiple"] option:checked {
@apply after:content-['\2713'] bg-white after:text-gray-500 after:ml-2;
}
select[multiple="multiple"] option:active,
select[multiple="multiple"] option:focus {
@apply bg-white;
}
.maybe-switch {
@apply block bg-gray-100 w-9 h-5 rounded-full cursor-pointer;
@apply after:content-[''] after:block after:absolute after:top-0.5 after:left-0.5 after:bg-white after:w-4 after:h-4 after:rounded-full after:transition-transform after:duration-300 after:ease-in-out;
@@ -77,6 +94,30 @@
@apply font-bold;
}
}
.tooltip {
@apply hidden absolute;
}
.btn {
@apply px-3 py-2 rounded-lg text-sm font-medium cursor-pointer;
}
.btn--primary {
@apply bg-gray-900 text-white hover:bg-gray-700 disabled:bg-gray-50 disabled:hover:bg-gray-50 disabled:text-gray-400;
}
.btn--secondary {
@apply bg-gray-50 hover:bg-gray-100 text-gray-900;
}
.btn--outline {
@apply border border-alpha-black-200 text-gray-900 hover:bg-gray-50;
}
.btn--ghost {
@apply border border-transparent text-gray-900 hover:bg-gray-50;
}
}
/* Small, single purpose classes that should take precedence over other styles */
@@ -93,4 +134,4 @@
.scrollbar::-webkit-scrollbar-thumb:hover {
background: #a6a6a6;
}
}
}

View File

@@ -0,0 +1,14 @@
class Account::CashesController < ApplicationController
layout :with_sidebar
before_action :set_account
def index
end
private
def set_account
@account = Current.family.accounts.find(params[:account_id])
end
end

View File

@@ -0,0 +1,48 @@
class Account::EntriesController < ApplicationController
layout :with_sidebar
before_action :set_account
before_action :set_entry, only: %i[edit update show destroy]
def edit
render entryable_view_path(:edit)
end
def update
@entry.update!(entry_params)
@entry.sync_account_later
respond_to do |format|
format.html { redirect_to account_entry_path(@account, @entry), notice: t(".success") }
format.turbo_stream { render turbo_stream: turbo_stream.replace(@entry) }
end
end
def show
render entryable_view_path(:show)
end
def destroy
@entry.destroy!
@entry.sync_account_later
redirect_to account_url(@entry.account), notice: t(".success")
end
private
def entryable_view_path(action)
@entry.entryable_type.underscore.pluralize + "/" + action.to_s
end
def set_account
@account = Current.family.accounts.find(params[:account_id])
end
def set_entry
@entry = @account.entries.find(params[:id])
end
def entry_params
params.require(:account_entry).permit(:name, :date, :amount, :currency)
end
end

View File

@@ -0,0 +1,28 @@
class Account::HoldingsController < ApplicationController
layout :with_sidebar
before_action :set_account
before_action :set_holding, only: %i[show destroy]
def index
@holdings = @account.holdings.current
end
def show
end
def destroy
@holding.destroy_holding_and_entries!
redirect_back_or_to account_holdings_path(@account)
end
private
def set_account
@account = Current.family.accounts.find(params[:account_id])
end
def set_holding
@holding = @account.holdings.current.find(params[:id])
end
end

View File

@@ -1,10 +0,0 @@
class Account::LogosController < ApplicationController
def show
@account = Current.family.accounts.find(params[:account_id])
render_placeholder
end
def render_placeholder
render formats: :svg
end
end

View File

@@ -0,0 +1,59 @@
class Account::TradesController < ApplicationController
layout :with_sidebar
before_action :set_account
before_action :set_entry, only: :update
def new
@entry = @account.entries.account_trades.new(entryable_attributes: {})
end
def index
@entries = @account.entries.reverse_chronological.where(entryable_type: %w[Account::Trade Account::Transaction])
end
def create
@builder = Account::EntryBuilder.new(entry_params)
if entry = @builder.save
entry.sync_account_later
redirect_to account_path(@account), notice: t(".success")
else
flash[:alert] = t(".failure")
redirect_back_or_to account_path(@account)
end
end
def update
@entry.update!(entry_params)
respond_to do |format|
format.html { redirect_to account_entry_path(@account, @entry), notice: t(".success") }
format.turbo_stream { render turbo_stream: turbo_stream.replace(@entry) }
end
end
private
def set_account
@account = Current.family.accounts.find(params[:account_id])
end
def set_entry
@entry = @account.entries.find(params[:id])
end
def entry_params
params.require(:account_entry)
.permit(
:type, :date, :qty, :ticker, :price, :amount, :notes, :excluded, :currency, :transfer_account_id, :entryable_type,
entryable_attributes: [
:id,
:qty,
:ticker,
:price
]
)
.merge(account: @account)
end
end

View File

@@ -1,22 +0,0 @@
class Account::Transaction::RowsController < ApplicationController
before_action :set_transaction, only: %i[ show update ]
def show
end
def update
@transaction.update! transaction_params
redirect_to account_transaction_row_path(@transaction.account, @transaction)
end
private
def transaction_params
params.require(:transaction).permit(:category_id)
end
def set_transaction
@transaction = Current.family.accounts.find(params[:account_id]).transactions.find(params[:transaction_id])
end
end

View File

@@ -1,6 +0,0 @@
class Account::Transaction::RulesController < ApplicationController
layout "with_sidebar"
def index
end
end

View File

@@ -1,47 +1,57 @@
class Account::TransactionsController < ApplicationController
layout "with_sidebar"
layout :with_sidebar
before_action :set_account
before_action :set_transaction, only: %i[ show update destroy ]
before_action :set_entry, only: :update
def index
@transactions = @account.transactions.ordered
end
def show
@pagy, @entries = pagy(
@account.entries.account_transactions.reverse_chronological,
limit: params[:per_page] || "10"
)
end
def update
@transaction.update! transaction_params
@transaction.sync_account_later
@entry.update!(entry_params)
respond_to do |format|
format.html { redirect_back_or_to account_transaction_path(@account, @transaction), notice: t(".success") }
format.turbo_stream { render turbo_stream: turbo_stream.replace(@transaction) }
format.html { redirect_to account_entry_path(@account, @entry), notice: t(".success") }
format.turbo_stream { render turbo_stream: turbo_stream.replace(@entry) }
end
end
def destroy
@transaction.destroy!
@transaction.sync_account_later
redirect_back_or_to account_url(@transaction.account), notice: t(".success")
end
private
def set_account
@account = Current.family.accounts.find(params[:account_id])
end
def set_transaction
@transaction = @account.transactions.find(params[:id])
def set_entry
@entry = @account.entries.find(params[:id])
end
def search_params
params.fetch(:q, {}).permit(:start_date, :end_date, :search, accounts: [], account_ids: [], categories: [], merchants: [])
end
def entry_params
params.require(:account_entry)
.permit(
:name, :date, :amount, :currency, :excluded, :notes, :entryable_type, :nature,
entryable_attributes: [
:id,
:category_id,
:merchant_id,
{ tag_ids: [] }
]
).tap do |permitted_params|
nature = permitted_params.delete(:nature)
def transaction_params
params.require(:account_transaction).permit(:name, :date, :amount, :currency, :notes, :excluded, :category_id, :merchant_id, tag_ids: [])
if permitted_params[:amount]
amount_value = permitted_params[:amount].to_d
if nature == "income"
amount_value *= -1
end
permitted_params[:amount] = amount_value
end
end
end
end

View File

@@ -1,5 +1,5 @@
class Account::TransfersController < ApplicationController
layout "with_sidebar"
layout :with_sidebar
before_action :set_transfer, only: :destroy
@@ -18,11 +18,12 @@ class Account::TransfersController < ApplicationController
name: transfer_params[:name]
if @transfer.save
@transfer.entries.each(&:sync_account_later)
redirect_to transactions_path, notice: t(".success")
else
# TODO: this is not an ideal way to handle errors and should eventually be improved.
# See: https://github.com/hotwired/turbo-rails/pull/367
flash[:error] = @transfer.errors.full_messages.to_sentence
flash[:alert] = @transfer.errors.full_messages.to_sentence
redirect_to transactions_path
end
end
@@ -39,6 +40,6 @@ class Account::TransfersController < ApplicationController
end
def transfer_params
params.require(:account_transfer).permit(:from_account_id, :to_account_id, :amount, :currency, :date, :name)
params.require(:account_transfer).permit(:from_account_id, :to_account_id, :amount, :date, :name)
end
end

View File

@@ -1,48 +1,26 @@
class Account::ValuationsController < ApplicationController
layout :with_sidebar
before_action :set_account
before_action :set_valuation, only: %i[ show edit update destroy ]
def new
@valuation = @account.valuations.new
end
def show
@entry = @account.entries.account_valuations.new(entryable_attributes: {})
end
def create
@valuation = @account.valuations.build(valuation_params)
@entry = @account.entries.account_valuations.new(entry_params.merge(entryable_attributes: {}))
if @valuation.save
@valuation.sync_account_later
redirect_to account_path(@account), notice: "Valuation created"
if @entry.save
@entry.sync_account_later
redirect_back_or_to account_valuations_path(@account), notice: t(".success")
else
# TODO: this is not an ideal way to handle errors and should eventually be improved.
# See: https://github.com/hotwired/turbo-rails/pull/367
flash[:error] = @valuation.errors.full_messages.to_sentence
flash[:alert] = @entry.errors.full_messages.to_sentence
redirect_to account_path(@account)
end
end
def edit
end
def update
if @valuation.update(valuation_params)
@valuation.sync_account_later
redirect_to account_path(@account), notice: t(".success")
else
# TODO: this is not an ideal way to handle errors and should eventually be improved.
# See: https://github.com/hotwired/turbo-rails/pull/367
flash[:error] = @valuation.errors.full_messages.to_sentence
redirect_to account_path(@account)
end
end
def destroy
@valuation.destroy!
@valuation.sync_account_later
redirect_to account_path(@account), notice: t(".success")
def index
@entries = @account.entries.account_valuations.reverse_chronological
end
private
@@ -51,11 +29,7 @@ class Account::ValuationsController < ApplicationController
@account = Current.family.accounts.find(params[:account_id])
end
def set_valuation
@valuation = @account.valuations.find(params[:id])
end
def valuation_params
params.require(:account_valuation).permit(:date, :value, :currency)
def entry_params
params.require(:account_entry).permit(:name, :date, :amount, :currency)
end
end

View File

@@ -1,9 +1,8 @@
class AccountsController < ApplicationController
layout "with_sidebar"
layout :with_sidebar
include Filterable
before_action :set_account, only: %i[ edit show destroy sync update ]
after_action :sync_account, only: :create
before_action :set_account, only: %i[edit show destroy sync update]
def index
@institutions = Current.family.institutions
@@ -20,13 +19,13 @@ class AccountsController < ApplicationController
end
def list
render layout: false
end
def new
@account = Account.new(
balance: nil,
accountable: Accountable.from_type(params[:type])&.new
)
@account = Account.new(currency: Current.family.currency)
@account.accountable = Accountable.from_type(params[:type])&.new if params[:type].present?
@account.accountable.address = Address.new if @account.accountable.is_a?(Property)
if params[:institution_id]
@account.institution = Current.family.institutions.find_by(id: params[:institution_id])
@@ -34,14 +33,14 @@ class AccountsController < ApplicationController
end
def show
@balance_series = @account.series(period: @period)
end
def edit
@account.accountable.build_address if @account.accountable.is_a?(Property) && @account.accountable.address.blank?
end
def update
@account.update! account_params.except(:accountable_type)
@account.update_with_sync!(account_params)
redirect_back_or_to account_path(@account), notice: t(".success")
end
@@ -52,6 +51,7 @@ class AccountsController < ApplicationController
attributes: account_params.except(:start_date, :start_balance),
start_date: account_params[:start_date],
start_balance: account_params[:start_balance]
@account.sync_later
redirect_back_or_to account_path(@account), notice: t(".success")
end
@@ -65,8 +65,11 @@ class AccountsController < ApplicationController
unless @account.syncing?
@account.sync_later
end
end
redirect_to account_path(@account), notice: t(".success")
def sync_all
Current.family.accounts.active.sync
redirect_back_or_to accounts_path, notice: t(".success")
end
private
@@ -76,10 +79,6 @@ class AccountsController < ApplicationController
end
def account_params
params.require(:account).permit(:name, :accountable_type, :balance, :start_date, :start_balance, :currency, :subtype, :is_active, :institution_id)
end
def sync_account
@account.sync_later
params.require(:account).permit(:name, :accountable_type, :mode, :balance, :start_date, :start_balance, :currency, :subtype, :is_active, :institution_id)
end
end

View File

@@ -1,9 +1,27 @@
class ApplicationController < ActionController::Base
include Authentication, Invitable, SelfHostable
include Onboardable, Localize, AutoSync, Authentication, Invitable, SelfHostable, StoreLocation, Impersonatable
include Pagy::Backend
default_form_builder ApplicationFormBuilder
helper_method :require_upgrade?, :subscription_pending?
# Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has.
allow_browser versions: :modern
private
def require_upgrade?
return false if self_hosted?
return false unless Current.session
return false if Current.family.subscribed?
return false if subscription_pending? || request.path == settings_billing_path
true
end
def subscription_pending?
subscribed_at = Current.session.subscribed_at
subscribed_at.present? && subscribed_at <= Time.current && subscribed_at > 1.hour.ago
end
def with_sidebar
return "turbo_rails/frame" if turbo_frame_request?
"with_sidebar"
end
end

View File

@@ -1,7 +1,7 @@
class CategoriesController < ApplicationController
layout "with_sidebar"
layout :with_sidebar
before_action :set_category, only: %i[ edit update ]
before_action :set_category, only: %i[edit update destroy]
before_action :set_transaction, only: :create
def index
@@ -13,12 +13,14 @@ class CategoriesController < ApplicationController
end
def create
Category.transaction do
category = Current.family.categories.create!(category_params)
@transaction.update!(category_id: category.id) if @transaction
end
@category = Current.family.categories.new(category_params)
redirect_back_or_to transactions_path, notice: t(".success")
if @category.save
@transaction.update(category_id: @category.id) if @transaction
redirect_back_or_to transactions_path, notice: t(".success")
else
redirect_back_or_to transactions_path, alert: t(".failure", error: @category.errors.full_messages.to_sentence)
end
end
def edit
@@ -30,6 +32,12 @@ class CategoriesController < ApplicationController
redirect_back_or_to transactions_path, notice: t(".success")
end
def destroy
@category.destroy
redirect_back_or_to categories_path, notice: t(".success")
end
private
def set_category
@category = Current.family.categories.find(params[:id])

View File

@@ -1,5 +1,5 @@
class Category::DeletionsController < ApplicationController
layout "with_sidebar"
layout :with_sidebar
before_action :set_category
before_action :set_replacement_category, only: :create

View File

@@ -6,17 +6,17 @@ class Category::DropdownsController < ApplicationController
end
private
def set_from_params
if params[:category_id]
@selected_category = categories_scope.find(params[:category_id])
def set_from_params
if params[:category_id]
@selected_category = categories_scope.find(params[:category_id])
end
if params[:transaction_id]
@transaction = Current.family.transactions.find(params[:transaction_id])
end
end
if params[:transaction_id]
@transaction = Current.family.transactions.find(params[:transaction_id])
def categories_scope
Current.family.categories.alphabetically
end
end
def categories_scope
Current.family.categories.alphabetically
end
end

View File

@@ -2,39 +2,45 @@ module Authentication
extend ActiveSupport::Concern
included do
before_action :set_request_details
before_action :authenticate_user!
after_action :set_last_login_at, if: -> { Current.user }
end
class_methods do
def skip_authentication(**options)
skip_before_action :authenticate_user!, **options
skip_after_action :set_last_login_at, **options
end
end
private
def authenticate_user!
if user = User.find_by(id: session[:user_id])
Current.user = user
else
redirect_to new_session_url
def authenticate_user!
if session_record = find_session_by_cookie
Current.session = session_record
else
if self_hosted_first_login?
redirect_to new_registration_url
else
redirect_to new_session_url
end
end
end
end
def login(user)
Current.user = user
reset_session
session[:user_id] = user.id
end
def find_session_by_cookie
Session.find_by(id: cookies.signed[:session_token])
end
def logout
Current.user = nil
reset_session
end
def create_session_for(user)
session = user.sessions.create!
cookies.signed.permanent[:session_token] = { value: session.id, httponly: true }
session
end
def set_last_login_at
Current.user.update(last_login_at: DateTime.now)
end
def self_hosted_first_login?
Rails.application.config.app_mode.self_hosted? && User.count.zero?
end
def set_request_details
Current.user_agent = request.user_agent
Current.ip_address = request.ip
end
end

View File

@@ -0,0 +1,13 @@
module AutoSync
extend ActiveSupport::Concern
included do
before_action :sync_family, if: -> { Current.family.present? && Current.family.needs_sync? }
end
private
def sync_family
Current.family.sync
end
end

View File

@@ -1,9 +1,9 @@
module Filterable
extend ActiveSupport::Concern
extend ActiveSupport::Concern
included do
before_action :set_period
end
included do
before_action :set_period
end
private

View File

@@ -0,0 +1,21 @@
module Impersonatable
extend ActiveSupport::Concern
included do
after_action :create_impersonation_session_log
end
private
def create_impersonation_session_log
return unless Current.session&.active_impersonator_session.present?
Current.session.active_impersonator_session.logs.create!(
controller: controller_name,
action: action_name,
path: request.fullpath,
method: request.method,
ip_address: request.ip,
user_agent: request.user_agent
)
end
end

View File

@@ -7,6 +7,10 @@ module Invitable
private
def invite_code_required?
ENV["REQUIRE_INVITE_CODE"] == "true"
self_hosted? ? Setting.require_invite_for_signup : ENV["REQUIRE_INVITE_CODE"] == "true"
end
def self_hosted?
Rails.application.config.app_mode.self_hosted?
end
end

View File

@@ -0,0 +1,13 @@
module Localize
extend ActiveSupport::Concern
included do
around_action :switch_locale
end
private
def switch_locale(&action)
locale = Current.family.try(:locale) || I18n.default_locale
I18n.with_locale(locale, &action)
end
end

View File

@@ -0,0 +1,17 @@
module Onboardable
extend ActiveSupport::Concern
included do
before_action :redirect_to_onboarding, if: :needs_onboarding?
end
private
def redirect_to_onboarding
redirect_to onboarding_path
end
def needs_onboarding?
Current.user && Current.user.onboarded_at.blank? &&
!%w[/users /onboarding /sessions].any? { |path| request.path.start_with?(path) }
end
end

View File

@@ -2,11 +2,15 @@ module SelfHostable
extend ActiveSupport::Concern
included do
helper_method :self_hosted?
helper_method :self_hosted?, :self_hosted_first_login?
end
private
def self_hosted?
Rails.configuration.app_mode.self_hosted?
end
def self_hosted_first_login?
self_hosted? && User.count.zero?
end
end

View File

@@ -0,0 +1,31 @@
module StoreLocation
extend ActiveSupport::Concern
included do
helper_method :previous_path
before_action :store_return_to
after_action :clear_previous_path
end
def previous_path
session[:return_to] || fallback_path
end
private
def store_return_to
if params[:return_to].present?
session[:return_to] = params[:return_to]
end
end
def clear_previous_path
if request.fullpath == session[:return_to]
session.delete(:return_to)
end
end
def fallback_path
root_path
end
end

View File

@@ -0,0 +1,41 @@
class CreditCardsController < ApplicationController
before_action :set_account, only: :update
def create
account = Current.family
.accounts
.create_with_optional_start_balance! \
attributes: account_params.except(:start_date, :start_balance),
start_date: account_params[:start_date],
start_balance: account_params[:start_balance]
account.sync_later
redirect_to account, notice: t(".success")
end
def update
@account.update_with_sync!(account_params)
redirect_to @account, notice: t(".success")
end
private
def set_account
@account = Current.family.accounts.find(params[:id])
end
def account_params
params.require(:account)
.permit(
:name, :balance, :institution_id, :mode, :start_date, :start_balance, :currency, :accountable_type,
accountable_attributes: [
:id,
:available_credit,
:minimum_payment,
:apr,
:annual_fee,
:expiration_date
]
)
end
end

View File

@@ -1,6 +1,6 @@
class CurrenciesController < ApplicationController
def show
@currency = Money::Currency.all_instances.find { |currency| currency.iso_code == params[:id] }
render json: { step: @currency.step, placeholder: Money.new(0, @currency).format }
currency = Money::Currency.all_instances.find { |currency| currency.iso_code == params[:id] }
render json: currency.as_json.merge({ step: currency.step })
end
end

View File

@@ -0,0 +1,11 @@
class Help::ArticlesController < ApplicationController
layout :with_sidebar
def show
@article = Help::Article.find(params[:id])
unless @article
head :not_found
end
end
end

View File

@@ -0,0 +1,58 @@
class ImpersonationSessionsController < ApplicationController
before_action :require_super_admin!, only: [ :create, :join, :leave ]
before_action :set_impersonation_session, only: [ :approve, :reject, :complete ]
def create
Current.true_user.request_impersonation_for(session_params[:impersonated_id])
redirect_to root_path, notice: t(".success")
end
def join
@impersonation_session = Current.true_user.impersonator_support_sessions.find_by(id: params[:impersonation_session_id])
Current.session.update!(active_impersonator_session: @impersonation_session)
redirect_to root_path, notice: t(".success")
end
def leave
Current.session.update!(active_impersonator_session: nil)
redirect_to root_path, notice: t(".success")
end
def approve
raise_unauthorized! unless @impersonation_session.impersonated == Current.true_user
@impersonation_session.approve!
redirect_to root_path, notice: t(".success")
end
def reject
raise_unauthorized! unless @impersonation_session.impersonated == Current.true_user
@impersonation_session.reject!
redirect_to root_path, notice: t(".success")
end
def complete
@impersonation_session.complete!
redirect_to root_path, notice: t(".success")
end
private
def session_params
params.require(:impersonation_session).permit(:impersonated_id)
end
def set_impersonation_session
@impersonation_session =
Current.true_user.impersonated_support_sessions.find_by(id: params[:id]) ||
Current.true_user.impersonator_support_sessions.find_by(id: params[:id])
end
def require_super_admin!
raise_unauthorized! unless Current.true_user&.super_admin?
end
def raise_unauthorized!
raise ActionController::RoutingError.new("Not Found")
end
end

View File

@@ -0,0 +1,22 @@
class Import::CleansController < ApplicationController
layout "imports"
before_action :set_import
def show
redirect_to import_configuration_path(@import), alert: "Please configure your import before proceeding." unless @import.configured?
rows = @import.rows.ordered
if params[:view] == "errors"
rows = rows.reject { |row| row.valid? }
end
@pagy, @rows = pagy_array(rows, limit: params[:per_page] || "10")
end
private
def set_import
@import = Current.family.imports.find(params[:import_id])
end
end

View File

@@ -0,0 +1,40 @@
class Import::ConfigurationsController < ApplicationController
layout "imports"
before_action :set_import
def show
end
def update
@import.update!(import_params)
@import.generate_rows_from_csv
@import.reload.sync_mappings
redirect_to import_clean_path(@import), notice: "Import configured successfully."
end
private
def set_import
@import = Current.family.imports.find(params[:import_id])
end
def import_params
params.require(:import).permit(
:date_col_label,
:amount_col_label,
:name_col_label,
:category_col_label,
:tags_col_label,
:account_col_label,
:qty_col_label,
:ticker_col_label,
:price_col_label,
:entity_type_col_label,
:notes_col_label,
:currency_col_label,
:date_format,
:signage_convention
)
end
end

View File

@@ -0,0 +1,14 @@
class Import::ConfirmsController < ApplicationController
layout "imports"
before_action :set_import
def show
redirect_to import_clean_path(@import), alert: "You have invalid data, please edit until all errors are resolved" unless @import.cleaned?
end
private
def set_import
@import = Current.family.imports.find(params[:import_id])
end
end

View File

@@ -0,0 +1,43 @@
class Import::MappingsController < ApplicationController
before_action :set_import
def update
mapping = @import.mappings.find(params[:id])
mapping.update! \
create_when_empty: create_when_empty,
mappable: mappable,
value: mapping_params[:value]
redirect_back_or_to import_confirm_path(@import)
end
private
def mapping_params
params.require(:import_mapping).permit(:type, :key, :mappable_id, :mappable_type, :value)
end
def set_import
@import = Current.family.imports.find(params[:import_id])
end
def mappable
return nil unless mappable_class.present?
@mappable ||= mappable_class.find_by(id: mapping_params[:mappable_id], family: Current.family)
end
def create_when_empty
return false unless mapping_class.present?
mapping_params[:mappable_id] == mapping_class::CREATE_NEW_KEY
end
def mappable_class
mapping_params[:mappable_type]&.constantize
end
def mapping_class
mapping_params[:type]&.constantize
end
end

View File

@@ -0,0 +1,24 @@
class Import::RowsController < ApplicationController
before_action :set_import_row
def update
@row.assign_attributes(row_params)
@row.save!(validate: false)
@row.sync_mappings
redirect_to import_row_path(@row.import, @row)
end
def show
end
private
def row_params
params.require(:import_row).permit(:type, :account, :date, :qty, :ticker, :price, :amount, :currency, :name, :category, :tags, :entity_type, :notes)
end
def set_import_row
@import = Current.family.imports.find(params[:import_id])
@row = @import.rows.find(params[:id])
end
end

View File

@@ -0,0 +1,47 @@
class Import::UploadsController < ApplicationController
layout "imports"
before_action :set_import
def show
end
def update
if csv_valid?(csv_str)
@import.assign_attributes(raw_file_str: csv_str, col_sep: upload_params[:col_sep])
@import.save!(validate: false)
redirect_to import_configuration_path(@import), notice: "CSV uploaded successfully."
else
flash.now[:alert] = "Must be valid CSV with headers and at least one row of data"
render :show, status: :unprocessable_entity
end
end
private
def set_import
@import = Current.family.imports.find(params[:import_id])
end
def csv_str
@csv_str ||= upload_params[:csv_file]&.read || upload_params[:raw_file_str]
end
def csv_valid?(str)
require "csv"
begin
csv = CSV.parse(str || "", headers: true)
return false if csv.headers.empty?
return false if csv.count == 0
true
rescue CSV::MalformedCSVError
false
end
end
def upload_params
params.require(:import).permit(:raw_file_str, :csv_file, :col_sep)
end
end

View File

@@ -1,103 +1,48 @@
require "ostruct"
class ImportsController < ApplicationController
before_action :set_import, except: %i[ index new create ]
before_action :set_import, only: %i[show publish destroy]
def publish
@import.publish_later
redirect_to import_path(@import), notice: "Your import has started in the background."
end
def index
@imports = Current.family.imports
render layout: "with_sidebar"
render layout: with_sidebar
end
def new
account = Current.family.accounts.find_by(id: params[:account_id])
@import = Import.new account: account
end
def edit
end
def update
account = Current.family.accounts.find(params[:import][:account_id])
@import.update! account: account
redirect_to load_import_path(@import), notice: t(".import_updated")
@pending_import = Current.family.imports.ordered.pending.first
end
def create
account = Current.family.accounts.find(params[:import][:account_id])
@import = Import.create!(account: account)
import = Current.family.imports.create! import_params
redirect_to load_import_path(@import), notice: t(".import_created")
redirect_to import_upload_path(import)
end
def show
if !@import.uploaded?
redirect_to import_upload_path(@import), alert: "Please finalize your file upload."
elsif !@import.publishable?
redirect_to import_confirm_path(@import), alert: "Please finalize your mappings before proceeding."
end
end
def destroy
@import.destroy!
redirect_to imports_url, notice: t(".import_destroyed"), status: :see_other
end
@import.destroy
def load
end
def load_csv
if @import.update(import_params)
redirect_to configure_import_path(@import), notice: t(".import_loaded")
else
flash.now[:error] = @import.errors.full_messages.to_sentence
render :load, status: :unprocessable_entity
end
end
def configure
unless @import.loaded?
redirect_to load_import_path(@import), alert: t(".invalid_csv")
end
end
def update_mappings
@import.update! import_params(@import.expected_fields.map(&:key))
redirect_to clean_import_path(@import), notice: t(".column_mappings_saved")
end
def clean
unless @import.loaded?
redirect_to load_import_path(@import), alert: t(".invalid_csv")
end
end
def update_csv
update_params = import_params[:csv_update]
@import.update_csv! \
row_idx: update_params[:row_idx],
col_idx: update_params[:col_idx],
value: update_params[:value]
render :clean
end
def confirm
unless @import.cleaned?
redirect_to clean_import_path(@import), alert: t(".invalid_data")
end
end
def publish
if @import.valid?
@import.publish_later
redirect_to imports_path, notice: t(".import_published")
else
flash.now[:error] = t(".invalid_data")
render :confirm, status: :unprocessable_entity
end
redirect_to imports_path, notice: "Your import has been deleted."
end
private
def set_import
@import = Current.family.imports.find(params[:id])
end
def import_params(permitted_mappings = nil)
params.require(:import).permit(:raw_csv_str, column_mappings: permitted_mappings, csv_update: [ :row_idx, :col_idx, :value ])
def import_params
params.require(:import).permit(:type)
end
end

View File

@@ -1,5 +1,5 @@
class InstitutionsController < ApplicationController
before_action :set_institution, except: %i[ new create ]
before_action :set_institution, except: %i[new create]
def new
@institution = Institution.new
@@ -23,6 +23,11 @@ class InstitutionsController < ApplicationController
redirect_to accounts_path, notice: t(".success")
end
def sync
@institution.sync
redirect_back_or_to accounts_path, notice: t(".success")
end
private
def institution_params

View File

@@ -0,0 +1,18 @@
class InviteCodesController < ApplicationController
before_action :ensure_self_hosted
def index
@invite_codes = InviteCode.all
end
def create
InviteCode.generate!
redirect_back_or_to invite_codes_path, notice: "Code generated"
end
private
def ensure_self_hosted
redirect_to root_path unless self_hosted?
end
end

View File

@@ -0,0 +1,19 @@
class Issue::ExchangeRateProviderMissingsController < ApplicationController
before_action :set_issue, only: :update
def update
Setting.synth_api_key = exchange_rate_params[:synth_api_key]
@issue.issuable.sync_later
redirect_back_or_to account_path(@issue.issuable)
end
private
def set_issue
@issue = Current.family.issues.find(params[:id])
end
def exchange_rate_params
params.require(:issue_exchange_rate_provider_missing).permit(:synth_api_key)
end
end

View File

@@ -0,0 +1,13 @@
class IssuesController < ApplicationController
before_action :set_issue, only: :show
def show
render template: "#{@issue.class.name.underscore.pluralize}/show", layout: "issues"
end
private
def set_issue
@issue = Current.family.issues.find(params[:id])
end
end

View File

@@ -0,0 +1,39 @@
class LoansController < ApplicationController
before_action :set_account, only: :update
def create
account = Current.family
.accounts
.create_with_optional_start_balance! \
attributes: account_params.except(:start_date, :start_balance),
start_date: account_params[:start_date],
start_balance: account_params[:start_balance]
account.sync_later
redirect_to account, notice: t(".success")
end
def update
@account.update_with_sync!(account_params)
redirect_to @account, notice: t(".success")
end
private
def set_account
@account = Current.family.accounts.find(params[:id])
end
def account_params
params.require(:account)
.permit(
:name, :balance, :institution_id, :start_date, :mode, :start_balance, :currency, :accountable_type,
accountable_attributes: [
:id,
:rate_type,
:interest_rate,
:term_months
]
)
end
end

View File

@@ -1,7 +1,7 @@
class MerchantsController < ApplicationController
layout "with_sidebar"
layout :with_sidebar
before_action :set_merchant, only: %i[ edit update destroy ]
before_action :set_merchant, only: %i[edit update destroy]
def index
@merchants = Current.family.merchants.alphabetically
@@ -12,8 +12,13 @@ class MerchantsController < ApplicationController
end
def create
Current.family.merchants.create!(merchant_params)
redirect_to merchants_path, notice: t(".success")
@merchant = Current.family.merchants.new(merchant_params)
if @merchant.save
redirect_to merchants_path, notice: t(".success")
else
redirect_to merchants_path, alert: t(".error", error: @merchant.errors.full_messages.to_sentence)
end
end
def edit
@@ -31,11 +36,11 @@ class MerchantsController < ApplicationController
private
def set_merchant
@merchant = Current.family.merchants.find(params[:id])
end
def set_merchant
@merchant = Current.family.merchants.find(params[:id])
end
def merchant_params
params.require(:merchant).permit(:name, :color)
end
def merchant_params
params.require(:merchant).permit(:name, :color)
end
end

View File

@@ -0,0 +1,19 @@
class OnboardingsController < ApplicationController
layout "application"
before_action :set_user
def show
end
def profile
end
def preferences
end
private
def set_user
@user = Current.user
end
end

View File

@@ -1,5 +1,6 @@
class PagesController < ApplicationController
layout "with_sidebar"
skip_before_action :authenticate_user!, only: %i[early_access]
layout :with_sidebar, except: %i[early_access]
include Filterable
@@ -21,22 +22,27 @@ class PagesController < ApplicationController
@accounts = Current.family.accounts
@account_groups = @accounts.by_group(period: @period, currency: Current.family.currency)
@transactions = Current.family.transactions.limit(6).order(date: :desc)
@transaction_entries = Current.family.entries.account_transactions.limit(6).reverse_chronological
# TODO: Placeholders for trendlines
placeholder_series_data = 10.times.map do |i|
{ date: Date.current - i.days, value: Money.new(0) }
{ date: Date.current - i.days, value: Money.new(0, Current.family.currency) }
end
@investing_series = TimeSeries.new(placeholder_series_data)
end
def changelog
@releases_notes = Provider::Github.new.fetch_latest_releases_notes
@release_notes = Provider::Github.new.fetch_latest_release_notes
end
def feedback
end
def invites
def early_access
redirect_to root_path if self_hosted?
@invite_codes_count = InviteCode.count
@invite_code = InviteCode.order("RANDOM()").limit(1).first
render layout: false
end
end

View File

@@ -3,7 +3,7 @@ class PasswordResetsController < ApplicationController
layout "auth"
before_action :set_user_by_token, only: %i[ edit update ]
before_action :set_user_by_token, only: %i[edit update]
def new
end
@@ -33,12 +33,12 @@ class PasswordResetsController < ApplicationController
private
def set_user_by_token
@user = User.find_by_token_for(:password_reset, params[:token])
redirect_to new_password_reset_path, alert: t("password_resets.update.invalid_token") unless @user.present?
end
def set_user_by_token
@user = User.find_by_token_for(:password_reset, params[:token])
redirect_to new_password_reset_path, alert: t("password_resets.update.invalid_token") unless @user.present?
end
def password_params
params.require(:user).permit(:password, :password_confirmation)
end
def password_params
params.require(:user).permit(:password, :password_confirmation)
end
end

View File

@@ -12,7 +12,7 @@ class PasswordsController < ApplicationController
private
def password_params
params.require(:user).permit(:password, :password_confirmation, :password_challenge).with_defaults(password_challenge: "")
end
def password_params
params.require(:user).permit(:password, :password_confirmation, :password_challenge).with_defaults(password_challenge: "")
end
end

View File

@@ -0,0 +1,40 @@
class PropertiesController < ApplicationController
before_action :set_account, only: :update
def create
account = Current.family
.accounts
.create_with_optional_start_balance! \
attributes: account_params.except(:start_date, :start_balance),
start_date: account_params[:start_date],
start_balance: account_params[:start_balance]
account.sync_later
redirect_to account, notice: t(".success")
end
def update
@account.update_with_sync!(account_params)
redirect_to @account, notice: t(".success")
end
private
def set_account
@account = Current.family.accounts.find(params[:id])
end
def account_params
params.require(:account)
.permit(
:name, :balance, :institution_id, :start_date, :mode, :start_balance, :currency, :accountable_type,
accountable_attributes: [
:id,
:year_built,
:area_unit,
:area_value,
address_attributes: [ :line1, :line2, :locality, :region, :country, :postal_code ]
]
)
end
end

View File

@@ -17,7 +17,7 @@ class RegistrationsController < ApplicationController
if @user.save
Category.create_default_categories(@user.family)
login @user
@session = create_session_for(@user)
flash[:notice] = t(".success")
redirect_to root_path
else
@@ -28,17 +28,17 @@ class RegistrationsController < ApplicationController
private
def set_user
@user = User.new user_params.except(:invite_code)
end
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation, :invite_code)
end
def claim_invite_code
unless InviteCode.claim! params[:user][:invite_code]
redirect_to new_registration_path, alert: t("registrations.create.invalid_invite_code")
def set_user
@user = User.new user_params.except(:invite_code)
end
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation, :invite_code)
end
def claim_invite_code
unless InviteCode.claim! params[:user][:invite_code]
redirect_to new_registration_path, alert: t("registrations.create.invalid_invite_code")
end
end
end
end

View File

@@ -0,0 +1,5 @@
class SecuritiesController < ApplicationController
def import
SecuritiesImportJob.perform_later(params[:exchange_mic])
end
end

View File

@@ -1,4 +1,5 @@
class SessionsController < ApplicationController
before_action :set_session, only: :destroy
skip_authentication only: %i[new create]
layout "auth"
@@ -8,7 +9,7 @@ class SessionsController < ApplicationController
def create
if user = User.authenticate_by(email: params[:email], password: params[:password])
login user
@session = create_session_for(user)
redirect_to root_path
else
flash.now[:alert] = t(".invalid_credentials")
@@ -17,7 +18,12 @@ class SessionsController < ApplicationController
end
def destroy
logout
redirect_to root_path, notice: t(".logout_successful")
@session.destroy
redirect_to new_session_path, notice: t(".logout_successful")
end
private
def set_session
@session = Current.user.sessions.find(params[:id])
end
end

View File

@@ -1,7 +1,5 @@
class Settings::BillingsController < SettingsController
def edit
end
def update
def show
@user = Current.user
end
end

View File

@@ -1,71 +1,43 @@
class Settings::HostingsController < SettingsController
before_action :verify_hosting_mode
before_action :raise_if_not_self_hosted
def show
@synth_usage = Current.family.synth_usage
end
def update
if all_updates_valid?
hosting_params.keys.each do |key|
Setting.send("#{key}=", hosting_params[key].strip)
end
if hosting_params[:upgrades_setting].present?
mode = hosting_params[:upgrades_setting] == "manual" ? "manual" : "auto"
target = hosting_params[:upgrades_setting] == "commit" ? "commit" : "release"
redirect_to settings_hosting_path, notice: t(".success")
else
flash.now[:error] = @errors.first.message
render :show, status: :unprocessable_entity
end
end
def send_test_email
unless Setting.smtp_settings_populated?
flash[:error] = t(".missing_smtp_setting_error")
render(:show, status: :unprocessable_entity)
return
Setting.upgrades_mode = mode
Setting.upgrades_target = target
end
begin
NotificationMailer.with(user: Current.user).test_email.deliver_now
rescue => _e
flash[:error] = t(".error")
render :show, status: :unprocessable_entity
return
if hosting_params.key?(:render_deploy_hook)
Setting.render_deploy_hook = hosting_params[:render_deploy_hook]
end
if hosting_params.key?(:require_invite_for_signup)
Setting.require_invite_for_signup = hosting_params[:require_invite_for_signup]
end
if hosting_params.key?(:synth_api_key)
Setting.synth_api_key = hosting_params[:synth_api_key]
end
redirect_to settings_hosting_path, notice: t(".success")
rescue ActiveRecord::RecordInvalid => error
flash.now[:alert] = t(".failure")
render :show, status: :unprocessable_entity
end
private
def all_updates_valid?
@errors = ActiveModel::Errors.new(Setting)
hosting_params.keys.each do |key|
setting = Setting.new(var: key)
setting.value = hosting_params[key].strip
unless setting.valid?
@errors.merge!(setting.errors)
end
end
if hosting_params[:upgrades_mode] == "auto" && hosting_params[:render_deploy_hook].blank?
@errors.add(:render_deploy_hook, t("settings.hostings.update.render_deploy_hook_error"))
end
@errors.empty?
end
def hosting_params
permitted_params = params.require(:setting).permit(:render_deploy_hook, :upgrades_mode, :email_sender, :app_domain, :smtp_host, :smtp_port, :smtp_username, :smtp_password)
result = {}
result[:upgrades_mode] = permitted_params[:upgrades_mode] == "manual" ? "manual" : "auto" if permitted_params.key?(:upgrades_mode)
result[:render_deploy_hook] = permitted_params[:render_deploy_hook] if permitted_params.key?(:render_deploy_hook)
result[:upgrades_target] = permitted_params[:upgrades_mode] unless permitted_params[:upgrades_mode] == "manual" if permitted_params.key?(:upgrades_mode)
result.merge!(permitted_params.slice(:email_sender, :app_domain, :smtp_host, :smtp_port, :smtp_username, :smtp_password))
result
params.require(:setting).permit(:render_deploy_hook, :upgrades_setting, :require_invite_for_signup, :synth_api_key)
end
def verify_hosting_mode
head :not_found unless self_hosted?
def raise_if_not_self_hosted
raise "Settings not available on non-self-hosted instance" unless self_hosted?
end
end

View File

@@ -1,7 +0,0 @@
class Settings::NotificationsController < SettingsController
def edit
end
def update
end
end

View File

@@ -1,26 +1,5 @@
class Settings::PreferencesController < SettingsController
def edit
def show
@user = Current.user
end
def update
preference_params_with_family = preference_params
if Current.family && preference_params[:family_attributes]
family_attributes = preference_params[:family_attributes].merge({ id: Current.family.id })
preference_params_with_family[:family_attributes] = family_attributes
end
if Current.user.update(preference_params_with_family)
redirect_to settings_preferences_path, notice: t(".success")
else
redirect_to settings_preferences_path, notice: t(".success")
render :show, status: :unprocessable_entity
end
end
private
def preference_params
params.require(:user).permit(family_attributes: [ :id, :currency ])
end
end

View File

@@ -1,39 +1,5 @@
class Settings::ProfilesController < SettingsController
def show
end
def update
user_params_with_family = user_params
if params[:user][:delete_profile_image] == "true"
Current.user.profile_image.purge
end
if Current.family && user_params_with_family[:family_attributes]
family_attributes = user_params_with_family[:family_attributes].merge({ id: Current.family.id })
user_params_with_family[:family_attributes] = family_attributes
end
if Current.user.update(user_params_with_family)
redirect_to settings_profile_path, notice: t(".success")
else
redirect_to settings_profile_path, alert: t(".file_size_error")
end
end
def destroy
if Current.user.deactivate
logout
redirect_to root_path, notice: t(".success")
else
redirect_to settings_profile_path, alert: Current.user.errors.full_messages.to_sentence
end
end
private
def user_params
params.require(:user).permit(:first_name, :last_name, :profile_image,
family_attributes: [ :name, :id ])
@user = Current.user
end
end

View File

@@ -1,7 +0,0 @@
class Settings::SecuritiesController < SettingsController
def edit
end
def update
end
end

View File

@@ -1,3 +1,3 @@
class SettingsController < ApplicationController
layout "with_sidebar"
layout :with_sidebar
end

View File

@@ -0,0 +1,47 @@
class SubscriptionsController < ApplicationController
def new
if Current.family.stripe_customer_id.blank?
customer = stripe_client.v1.customers.create(
email: Current.family.primary_user.email,
metadata: { family_id: Current.family.id }
)
Current.family.update(stripe_customer_id: customer.id)
end
session = stripe_client.v1.checkout.sessions.create({
customer: Current.family.stripe_customer_id,
line_items: [ {
price: ENV["STRIPE_PLAN_ID"],
quantity: 1
} ],
mode: "subscription",
allow_promotion_codes: true,
success_url: success_subscription_url + "?session_id={CHECKOUT_SESSION_ID}",
cancel_url: settings_billing_url
})
redirect_to session.url, allow_other_host: true, status: :see_other
end
def show
portal_session = stripe_client.v1.billing_portal.sessions.create(
customer: Current.family.stripe_customer_id,
return_url: settings_billing_url
)
redirect_to portal_session.url, allow_other_host: true, status: :see_other
end
def success
checkout_session = stripe_client.v1.checkout.sessions.retrieve(params[:session_id])
Current.session.update(subscribed_at: Time.at(checkout_session.created))
redirect_to root_path, notice: "You have successfully subscribed to Maybe+."
rescue Stripe::InvalidRequestError
redirect_to settings_billing_path, alert: "Something went wrong processing your subscription. Please contact us to get this fixed."
end
private
def stripe_client
@stripe_client ||= Stripe::StripeClient.new(ENV["STRIPE_SECRET_KEY"])
end
end

View File

@@ -1,5 +1,5 @@
class Tag::DeletionsController < ApplicationController
layout "with_sidebar"
layout :with_sidebar
before_action :set_tag
before_action :set_replacement_tag, only: :create

View File

@@ -1,7 +1,7 @@
class TagsController < ApplicationController
layout "with_sidebar"
layout :with_sidebar
before_action :set_tag, only: %i[ edit update ]
before_action :set_tag, only: %i[edit update destroy]
def index
@tags = Current.family.tags.alphabetically
@@ -12,8 +12,13 @@ class TagsController < ApplicationController
end
def create
Current.family.tags.create!(tag_params)
redirect_to tags_path, notice: t(".created")
@tag = Current.family.tags.new(tag_params)
if @tag.save
redirect_to tags_path, notice: t(".created")
else
redirect_to tags_path, alert: t(".error", error: @tag.errors.full_messages.to_sentence)
end
end
def edit
@@ -24,6 +29,11 @@ class TagsController < ApplicationController
redirect_to tags_path, notice: t(".updated")
end
def destroy
@tag.destroy!
redirect_to tags_path, notice: t(".deleted")
end
private
def set_tag

View File

@@ -1,10 +1,10 @@
class TransactionsController < ApplicationController
layout "with_sidebar"
layout :with_sidebar
def index
@q = search_params
result = Current.family.transactions.search(@q).ordered
@pagy, @transactions = pagy(result, items: params[:per_page] || "10")
result = Current.family.entries.account_transactions.search(@q).reverse_chronological
@pagy, @transaction_entries = pagy(result, limit: params[:per_page] || "50")
@totals = {
count: result.select { |t| t.currency == Current.family.currency }.count,
@@ -14,25 +14,29 @@ class TransactionsController < ApplicationController
end
def new
@transaction = Account::Transaction.new.tap do |txn|
@entry = Current.family.entries.new(entryable: Account::Transaction.new).tap do |e|
if params[:account_id]
txn.account = Current.family.accounts.find(params[:account_id])
e.account = Current.family.accounts.find(params[:account_id])
e.currency = e.account.currency
else
e.currency = Current.family.currency
end
end
end
def create
@transaction = Current.family.accounts
.find(params[:transaction][:account_id])
.transactions
.create!(transaction_params.merge(amount: amount))
@entry = Current.family
.accounts
.find(params[:account_entry][:account_id])
.entries
.create!(transaction_entry_params.merge(amount: amount))
@transaction.sync_account_later
redirect_back_or_to account_path(@transaction.account), notice: t(".success")
@entry.sync_account_later
redirect_back_or_to account_path(@entry.account), notice: t(".success")
end
def bulk_delete
destroyed = Current.family.transactions.destroy_by(id: bulk_delete_params[:transaction_ids])
destroyed = Current.family.entries.destroy_by(id: bulk_delete_params[:entry_ids])
redirect_back_or_to transactions_url, notice: t(".success", count: destroyed.count)
end
@@ -40,19 +44,18 @@ class TransactionsController < ApplicationController
end
def bulk_update
transactions = Current.family.transactions.where(id: bulk_update_params[:transaction_ids])
if transactions.update_all(bulk_update_params.except(:transaction_ids).to_h.compact_blank!)
redirect_back_or_to transactions_url, notice: t(".success", count: transactions.count)
else
flash.now[:error] = t(".failure")
render :index, status: :unprocessable_entity
end
updated = Current.family
.entries
.where(id: bulk_update_params[:entry_ids])
.bulk_update!(bulk_update_params)
redirect_back_or_to transactions_url, notice: t(".success", count: updated)
end
def mark_transfers
Current.family
.transactions
.where(id: bulk_update_params[:transaction_ids])
.entries
.where(id: bulk_update_params[:entry_ids])
.mark_transfers!
redirect_back_or_to transactions_url, notice: t(".success")
@@ -60,8 +63,8 @@ class TransactionsController < ApplicationController
def unmark_transfers
Current.family
.transactions
.where(id: bulk_update_params[:transaction_ids])
.entries
.where(id: bulk_update_params[:entry_ids])
.update_all marked_as_transfer: false
redirect_back_or_to transactions_url, notice: t(".success")
@@ -71,29 +74,32 @@ class TransactionsController < ApplicationController
def amount
if nature.income?
transaction_params[:amount].to_d * -1
transaction_entry_params[:amount].to_d * -1
else
transaction_params[:amount].to_d
transaction_entry_params[:amount].to_d
end
end
def nature
params[:transaction][:nature].to_s.inquiry
params[:account_entry][:nature].to_s.inquiry
end
def bulk_delete_params
params.require(:bulk_delete).permit(transaction_ids: [])
params.require(:bulk_delete).permit(entry_ids: [])
end
def bulk_update_params
params.require(:bulk_update).permit(:date, :notes, :excluded, :category_id, :merchant_id, transaction_ids: [])
params.require(:bulk_update).permit(:date, :notes, :category_id, :merchant_id, entry_ids: [])
end
def search_params
params.fetch(:q, {}).permit(:start_date, :end_date, :search, accounts: [], account_ids: [], categories: [], merchants: [])
params.fetch(:q, {})
.permit(:start_date, :end_date, :search, :amount, :amount_operator, accounts: [], account_ids: [], categories: [], merchants: [], types: [], tags: [])
end
def transaction_params
params.require(:transaction).permit(:name, :date, :amount, :currency, :category_id, tag_ids: [])
def transaction_entry_params
params.require(:account_entry)
.permit(:name, :date, :amount, :currency, :entryable_type, entryable_attributes: [ :category_id ])
.with_defaults(entryable_type: "Account::Transaction", entryable_attributes: {})
end
end

View File

@@ -0,0 +1,51 @@
class UsersController < ApplicationController
before_action :set_user
def update
@user = Current.user
@user.update!(user_params.except(:redirect_to, :delete_profile_image))
@user.profile_image.purge if should_purge_profile_image?
handle_redirect(t(".success"))
end
def destroy
if @user.deactivate
Current.session.destroy
redirect_to root_path, notice: t(".success")
else
redirect_to settings_profile_path, alert: @user.errors.full_messages.to_sentence
end
end
private
def handle_redirect(notice)
case user_params[:redirect_to]
when "onboarding_preferences"
redirect_to preferences_onboarding_path
when "home"
redirect_to root_path
when "preferences"
redirect_to settings_preferences_path, notice: notice
else
redirect_to settings_profile_path, notice: notice
end
end
def should_purge_profile_image?
user_params[:delete_profile_image] == "1" &&
user_params[:profile_image].blank?
end
def user_params
params.require(:user).permit(
:first_name, :last_name, :profile_image, :redirect_to, :delete_profile_image, :onboarded_at,
family_attributes: [ :name, :currency, :country, :locale, :date_format, :id ]
)
end
def set_user
@user = Current.user
end
end

View File

@@ -0,0 +1,41 @@
class VehiclesController < ApplicationController
before_action :set_account, only: :update
def create
account = Current.family
.accounts
.create_with_optional_start_balance! \
attributes: account_params.except(:start_date, :start_balance),
start_date: account_params[:start_date],
start_balance: account_params[:start_balance]
account.sync_later
redirect_to account, notice: t(".success")
end
def update
@account.update_with_sync!(account_params)
redirect_to @account, notice: t(".success")
end
private
def set_account
@account = Current.family.accounts.find(params[:id])
end
def account_params
params.require(:account)
.permit(
:name, :balance, :institution_id, :start_date, :mode, :start_balance, :currency, :accountable_type,
accountable_attributes: [
:id,
:make,
:model,
:year,
:mileage_value,
:mileage_unit
]
)
end
end

View File

@@ -0,0 +1,61 @@
class WebhooksController < ApplicationController
skip_before_action :verify_authenticity_token, only: [ :stripe ]
skip_authentication
def stripe
webhook_body = request.body.read
sig_header = request.env["HTTP_STRIPE_SIGNATURE"]
client = Stripe::StripeClient.new(ENV["STRIPE_SECRET_KEY"])
begin
thin_event = client.parse_thin_event(webhook_body, sig_header, ENV["STRIPE_WEBHOOK_SECRET"])
event = client.v1.events.retrieve(thin_event.id)
case event.type
when /^customer\.subscription\./
handle_subscription_event(event)
when "customer.created", "customer.updated", "customer.deleted"
handle_customer_event(event)
else
Rails.logger.info "Unhandled event type: #{event.type}"
end
rescue JSON::ParserError
render json: { error: "Invalid payload" }, status: :bad_request
return
rescue Stripe::SignatureVerificationError
render json: { error: "Invalid signature" }, status: :bad_request
return
end
render json: { received: true }, status: :ok
end
private
def handle_subscription_event(event)
subscription = event.data.object
family = Family.find_by(stripe_customer_id: subscription.customer)
if family
family.update(
stripe_plan_id: subscription.plan.id,
stripe_subscription_status: subscription.status
)
else
Rails.logger.error "Family not found for Stripe customer ID: #{subscription.customer}"
end
end
def handle_customer_event(event)
customer = event.data.object
family = Family.find_by(stripe_customer_id: customer.id)
if family
family.update(stripe_customer_id: customer.id)
else
Rails.logger.error "Family not found for Stripe customer ID: #{customer.id}"
end
end
end

View File

@@ -0,0 +1,13 @@
module Account::CashesHelper
def brokerage_cash(account)
currency = Money::Currency.new(account.currency)
account.holdings.build \
date: Date.current,
qty: account.balance,
price: 1,
amount: account.balance,
currency: account.currency,
security: Security.new(ticker: currency.iso_code, name: currency.name)
end
end

View File

@@ -0,0 +1,61 @@
module Account::EntriesHelper
def permitted_entryable_partial_path(entry, relative_partial_path)
"account/entries/entryables/#{permitted_entryable_key(entry)}/#{relative_partial_path}"
end
def unconfirmed_transfer?(entry)
entry.marked_as_transfer? && entry.transfer.nil?
end
def transfer_entries(entries)
transfers = entries.select { |e| e.transfer_id.present? }
transfers.map(&:transfer).uniq
end
def entry_icon(entry, is_oldest: false)
if is_oldest
"keyboard"
elsif entry.trend.direction.up?
"arrow-up"
elsif entry.trend.direction.down?
"arrow-down"
else
"minus"
end
end
def entry_style(entry, is_oldest: false)
color = is_oldest ? "#D444F1" : entry.trend.color
mixed_hex_styles(color)
end
def entry_name(entry)
if entry.account_trade?
trade = entry.account_trade
prefix = trade.sell? ? "Sell " : "Buy "
generated = prefix + "#{trade.qty.abs} shares of #{trade.security.ticker}"
name = entry.name || generated
name
else
entry.name || "Transaction"
end
end
def entries_by_date(entries, selectable: true)
entries.group_by(&:date).map do |date, grouped_entries|
content = capture do
yield grouped_entries
end
render partial: "account/entries/entry_group", locals: { date:, entries: grouped_entries, content:, selectable: }
end.join.html_safe
end
private
def permitted_entryable_key(entry)
permitted_entryable_paths = %w[transaction valuation trade]
entry.entryable_name_short.presence_in(permitted_entryable_paths)
end
end

View File

@@ -1,24 +0,0 @@
module Account::TransactionsHelper
def unconfirmed_transfer?(transaction)
transaction.marked_as_transfer && transaction.transfer.nil?
end
def group_transactions_by_date(transactions)
grouped_by_date = {}
transactions.each do |transaction|
if transaction.transfer
transfer_date = transaction.transfer.inflow_transaction.date
grouped_by_date[transfer_date] ||= { transactions: [], transfers: [] }
unless grouped_by_date[transfer_date][:transfers].include?(transaction.transfer)
grouped_by_date[transfer_date][:transfers] << transaction.transfer
end
else
grouped_by_date[transaction.date] ||= { transactions: [], transfers: [] }
grouped_by_date[transaction.date][:transactions] << transaction
end
end
grouped_by_date
end
end

View File

@@ -1,23 +0,0 @@
module Account::ValuationsHelper
def valuation_icon(valuation)
if valuation.oldest?
"keyboard"
elsif valuation.trend.direction.up?
"arrow-up"
elsif valuation.trend.direction.down?
"arrow-down"
else
"minus"
end
end
def valuation_style(valuation)
color = valuation.oldest? ? "#D444F1" : valuation.trend.color
<<-STYLE.strip
background-color: color-mix(in srgb, #{color} 5%, white);
border-color: color-mix(in srgb, #{color} 10%, white);
color: #{color};
STYLE
end
end

View File

@@ -1,4 +1,19 @@
module AccountsHelper
def permitted_accountable_partial(account, name = nil)
permitted_names = %w[tooltip header tabs form]
folder = account.accountable_type.underscore
name ||= account.accountable_type.underscore
raise "Unpermitted accountable partial: #{name}" unless permitted_names.include?(name)
"accounts/accountables/#{folder}/#{name}"
end
def summary_card(title:, &block)
content = capture(&block)
render "accounts/summary_card", title: title, content: content
end
def to_accountable_title(accountable)
accountable.model_name.human
end
@@ -23,18 +38,79 @@ module AccountsHelper
class_mapping(accountable_type)[:hex]
end
# Eventually, we'll have an accountable form for each type of accountable, so
# this helper is a convenience for now to reuse common logic in the accounts controller
def new_account_form_url(account)
case account.accountable_type
when "Property"
properties_path
when "Vehicle"
vehicles_path
when "Loan"
loans_path
when "CreditCard"
credit_cards_path
else
accounts_path
end
end
def edit_account_form_url(account)
case account.accountable_type
when "Property"
property_path(account)
when "Vehicle"
vehicle_path(account)
when "Loan"
loan_path(account)
when "CreditCard"
credit_card_path(account)
else
account_path(account)
end
end
def account_tabs(account)
overview_tab = { key: "overview", label: t("accounts.show.overview"), path: account_path(account, tab: "overview"), partial_path: "accounts/overview" }
holdings_tab = { key: "holdings", label: t("accounts.show.holdings"), path: account_path(account, tab: "holdings"), route: account_holdings_path(account) }
cash_tab = { key: "cash", label: t("accounts.show.cash"), path: account_path(account, tab: "cash"), route: account_cashes_path(account) }
value_tab = { key: "valuations", label: t("accounts.show.value"), path: account_path(account, tab: "valuations"), route: account_valuations_path(account) }
transactions_tab = { key: "transactions", label: t("accounts.show.transactions"), path: account_path(account, tab: "transactions"), route: account_transactions_path(account) }
trades_tab = { key: "trades", label: t("accounts.show.trades"), path: account_path(account, tab: "trades"), route: account_trades_path(account) }
return [ value_tab ] if account.other_asset? || account.other_liability?
return [ overview_tab, value_tab ] if account.property? || account.vehicle?
return [ holdings_tab, cash_tab, trades_tab, value_tab ] if account.investment?
return [ overview_tab, value_tab, transactions_tab ] if account.loan? || account.credit_card?
[ value_tab, transactions_tab ]
end
def selected_account_tab(account)
available_tabs = account_tabs(account)
tab = available_tabs.find { |tab| tab[:key] == params[:tab] }
tab || available_tabs.first
end
def account_groups(period: nil)
assets, liabilities = Current.family.accounts.by_group(currency: Current.family.currency, period: period || Period.last_30_days).values_at(:assets, :liabilities)
[ assets.children.sort_by(&:name), liabilities.children.sort_by(&:name) ].flatten
end
private
def class_mapping(accountable_type)
{
"CreditCard" => { text: "text-red-500", bg: "bg-red-500", bg_transparent: "bg-red-500/10", fill: "fill-red-500", hex: "#F13636" },
"Loan" => { text: "text-fuchsia-500", bg: "bg-fuchsia-500", bg_transparent: "bg-fuchsia-500/10", fill: "fill-fuchsia-500", hex: "#D444F1" },
"OtherLiability" => { text: "text-gray-500", bg: "bg-gray-500", bg_transparent: "bg-gray-500/10", fill: "fill-gray-500", hex: "#737373" },
"Depository" => { text: "text-violet-500", bg: "bg-violet-500", bg_transparent: "bg-violet-500/10", fill: "fill-violet-500", hex: "#875BF7" },
"Investment" => { text: "text-blue-600", bg: "bg-blue-600", bg_transparent: "bg-blue-600/10", fill: "fill-blue-600", hex: "#1570EF" },
"OtherAsset" => { text: "text-green-500", bg: "bg-green-500", bg_transparent: "bg-green-500/10", fill: "fill-green-500", hex: "#12B76A" },
"Property" => { text: "text-cyan-500", bg: "bg-cyan-500", bg_transparent: "bg-cyan-500/10", fill: "fill-cyan-500", hex: "#06AED4" },
"Vehicle" => { text: "text-pink-500", bg: "bg-pink-500", bg_transparent: "bg-pink-500/10", fill: "fill-pink-500", hex: "#F23E94" }
}.fetch(accountable_type, { text: "text-gray-500", bg: "bg-gray-500", bg_transparent: "bg-gray-500/10", fill: "fill-gray-500", hex: "#737373" })
end
def class_mapping(accountable_type)
{
"CreditCard" => { text: "text-red-500", bg: "bg-red-500", bg_transparent: "bg-red-500/10", fill: "fill-red-500", hex: "#F13636" },
"Loan" => { text: "text-fuchsia-500", bg: "bg-fuchsia-500", bg_transparent: "bg-fuchsia-500/10", fill: "fill-fuchsia-500", hex: "#D444F1" },
"OtherLiability" => { text: "text-gray-500", bg: "bg-gray-500", bg_transparent: "bg-gray-500/10", fill: "fill-gray-500", hex: "#737373" },
"Depository" => { text: "text-violet-500", bg: "bg-violet-500", bg_transparent: "bg-violet-500/10", fill: "fill-violet-500", hex: "#875BF7" },
"Investment" => { text: "text-blue-600", bg: "bg-blue-600", bg_transparent: "bg-blue-600/10", fill: "fill-blue-600", hex: "#1570EF" },
"OtherAsset" => { text: "text-green-500", bg: "bg-green-500", bg_transparent: "bg-green-500/10", fill: "fill-green-500", hex: "#12B76A" },
"Property" => { text: "text-cyan-500", bg: "bg-cyan-500", bg_transparent: "bg-cyan-500/10", fill: "fill-cyan-500", hex: "#06AED4" },
"Vehicle" => { text: "text-pink-500", bg: "bg-pink-500", bg_transparent: "bg-pink-500/10", fill: "fill-pink-500", hex: "#F23E94" }
}.fetch(accountable_type, { text: "text-gray-500", bg: "bg-gray-500", bg_transparent: "bg-gray-500/10", fill: "fill-gray-500", hex: "#737373" })
end
end

View File

@@ -1,149 +0,0 @@
class ApplicationFormBuilder < ActionView::Helpers::FormBuilder
def initialize(object_name, object, template, options)
options[:html] ||= {}
options[:html][:class] ||= "space-y-4"
super(object_name, object, template, options)
end
(field_helpers - [ :label, :check_box, :radio_button, :fields_for, :fields, :hidden_field, :file_field ]).each do |selector|
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
def #{selector}(method, options = {})
default_options = { class: "form-field__input" }
merged_options = default_options.merge(options)
return super(method, merged_options) unless options[:label]
@template.form_field_tag do
label(method, *label_args(options)) +
super(method, merged_options.except(:label))
end
end
RUBY_EVAL
end
# See `Monetizable` concern, which adds a _money suffix to the attribute name
# For a monetized field, the setter will always be the attribute name without the _money suffix
def money_field(method, options = {})
money = @object && @object.respond_to?(method) ? @object.send(method) : nil
raise ArgumentError, "The value of #{method} is not a Money object" unless money.is_a?(Money) || money.nil?
money_amount_method = method.to_s.chomp("_money").to_sym
money_currency_method = :currency
readonly_currency = options[:readonly_currency] || false
currency = money&.currency || Money::Currency.new(Current.family.currency) || Money.default_currency
default_options = {
class: "form-field__input",
value: money&.amount,
"data-money-field-target" => "amount",
placeholder: Money.new(0, currency).format,
min: -99999999999999,
max: 99999999999999,
step: currency.step
}
merged_options = default_options.merge(options)
grouped_options = currency_options_for_select
selected_currency = money&.currency&.iso_code || currency.iso_code
@template.form_field_tag data: { controller: "money-field" } do
(label(method, *label_args(options)).to_s if options[:label]) +
@template.tag.div(class: "flex items-center") do
number_field(money_amount_method, merged_options.except(:label)) +
grouped_select(money_currency_method, grouped_options, { selected: selected_currency, disabled: readonly_currency }, class: "ml-auto form-field__input w-fit pr-8", data: { "money-field-target" => "currency", action: "change->money-field#handleCurrencyChange" })
end
end
end
def radio_button(method, tag_value, options = {})
default_options = { class: "form-field__radio" }
merged_options = default_options.merge(options)
super(method, tag_value, merged_options)
end
def grouped_select(method, grouped_choices, options = {}, html_options = {})
default_options = { class: "form-field__input" }
merged_html_options = default_options.merge(html_options)
label_html = label(method, *label_args(options)).to_s if options[:label]
select_html = @template.grouped_collection_select(@object_name, method, grouped_choices, :last, :first, :last, :first, options, merged_html_options)
@template.content_tag(:div, class: "flex items-center") do
label_html.to_s.html_safe + select_html
end
end
def currency_select(method, options = {}, html_options = {})
default_options = { class: "form-field__input" }
merged_options = default_options.merge(html_options)
choices = currency_options_for_select
return @template.grouped_collection_select(@object_name, method, choices, :last, :first, :last, :first, options, merged_options) unless options[:label]
@template.form_field_tag do
label(method, *label_args(options)) +
@template.grouped_collection_select(@object_name, method, choices, :last, :first, :last, :first, options, merged_options.except(:label))
end
end
def select(method, choices, options = {}, html_options = {})
default_options = { class: "form-field__input" }
merged_options = default_options.merge(html_options)
return super(method, choices, options, merged_options) unless options[:label]
@template.form_field_tag do
label(method, *label_args(options)) +
super(method, choices, options, merged_options.except(:label))
end
end
def collection_select(method, collection, value_method, text_method, options = {}, html_options = {})
default_options = { class: "form-field__input" }
merged_options = default_options.merge(html_options)
return super(method, collection, value_method, text_method, options, merged_options) unless options[:label]
@template.form_field_tag do
label(method, *label_args(options)) +
super(method, collection, value_method, text_method, options, merged_options.except(:label))
end
end
def submit(value = nil, options = {})
value, options = nil, value if value.is_a?(Hash)
default_options = { class: "form-field__submit" }
merged_options = default_options.merge(options)
super(value, merged_options)
end
private
def currency_options_for_select
popular_currencies = Money::Currency.popular.map { |currency| [ currency.iso_code, currency.iso_code ] }
all_currencies = Money::Currency.all_instances.map { |currency| [ currency.iso_code, currency.iso_code ] }
all_other_currencies = all_currencies.reject { |c| popular_currencies.map(&:last).include?(c.last) }.sort_by(&:last)
{
I18n.t("accounts.new.currency.popular") => popular_currencies,
I18n.t("accounts.new.currency.all_others") => all_other_currencies
}
end
def label_args(options)
case options[:label]
when Array
options[:label]
when String
[ options[:label], { class: "form-field__label" } ]
when Hash
[ nil, options[:label] ]
else
[ nil, { class: "form-field__label" } ]
end
end
end

View File

@@ -1,6 +1,19 @@
module ApplicationHelper
include Pagy::Frontend
def date_format_options
[
[ "DD-MM-YYYY", "%d-%m-%Y" ],
[ "MM-DD-YYYY", "%m-%d-%Y" ],
[ "YYYY-MM-DD", "%Y-%m-%d" ],
[ "DD/MM/YYYY", "%d/%m/%Y" ],
[ "YYYY/MM/DD", "%Y/%m/%d" ],
[ "MM/DD/YYYY", "%m/%d/%Y" ],
[ "D/MM/YYYY", "%e/%m/%Y" ],
[ "YYYY.MM.DD", "%Y.%m.%d" ]
]
end
def title(page_title)
content_for(:title) { page_title }
end
@@ -9,15 +22,22 @@ module ApplicationHelper
content_for(:header_title) { page_title }
end
def permitted_accountable_partial(name)
name.underscore
def family_notifications_stream
turbo_stream_from [ Current.family, :notifications ] if Current.family
end
def notification(text, **options, &block)
content = tag.p(text)
content = capture &block if block_given?
def family_stream
turbo_stream_from Current.family if Current.family
end
render partial: "shared/notification", locals: { type: options[:type], content: { body: content } }
def render_flash_notifications
notifications = flash.flat_map do |type, message_or_messages|
Array(message_or_messages).map do |message|
render partial: "shared/notification", locals: { type: type, message: message }
end
end
safe_join(notifications)
end
##
@@ -46,9 +66,9 @@ module ApplicationHelper
render partial: "shared/drawer", locals: { content: content }
end
def account_groups(period: nil)
assets, liabilities = Current.family.accounts.by_group(currency: Current.family.currency, period: period || Period.last_30_days).values_at(:assets, :liabilities)
[ assets.children, liabilities.children ].flatten
def disclosure(title, &block)
content = capture &block
render partial: "shared/disclosure", locals: { title: title, content: content }
end
def sidebar_link_to(name, path, options = {})
@@ -65,6 +85,20 @@ module ApplicationHelper
end
end
def mixed_hex_styles(hex)
color = hex || "#1570EF" # blue-600
<<-STYLE.strip
background-color: color-mix(in srgb, #{color} 10%, white);
border-color: color-mix(in srgb, #{color} 30%, white);
color: #{color};
STYLE
end
def circle_logo(name, hex: nil, size: "md")
render partial: "shared/circle_logo", locals: { name: name, hex: hex, size: size }
end
def return_to_path(params, fallback = root_path)
uri = URI.parse(params[:return_to] || fallback)
uri.relative? ? uri.path : root_path
@@ -111,19 +145,36 @@ module ApplicationHelper
end
end
# Wrapper around I18n.l to support custom date formats
def format_date(object, format = :default, options = {})
date = object.to_date
format_code = options[:format_code] || Current.family&.date_format
if format_code.present?
date.strftime(format_code)
else
I18n.l(date, format: format, **options)
end
end
def format_money(number_or_money, options = {})
return nil unless number_or_money
money = Money.new(number_or_money)
options.reverse_merge!(money.default_format_options)
options.reverse_merge!(money.format_options(I18n.locale))
number_to_currency(money.amount, options)
end
def format_money_without_symbol(number_or_money, options = {})
return nil unless number_or_money
money = Money.new(number_or_money)
options.reverse_merge!(money.default_format_options)
options.reverse_merge!(money.format_options(I18n.locale))
ActiveSupport::NumberHelper.number_to_delimited(money.amount.round(options[:precision] || 0), { delimiter: options[:delimiter], separator: options[:separator] })
end
def totals_by_currency(collection:, money_method:, separator: " | ", negate: false, options: {})
def totals_by_currency(collection:, money_method:, separator: " | ", negate: false)
collection.group_by(&:currency)
.transform_values { |item| negate ? item.sum(&money_method) * -1 : item.sum(&money_method) }
.map { |_currency, money| format_money(money) }

View File

@@ -1,6 +0,0 @@
module AuthMessagesHelper
def auth_messages(form = nil)
render "shared/auth_messages", flash: flash,
errors: form&.object&.errors&.full_messages || []
end
end

View File

@@ -4,4 +4,8 @@ module CategoriesHelper
name: "Uncategorized",
color: Category::UNCATEGORIZED_COLOR
end
def family_categories
[ null_category ].concat(Current.family.categories.alphabetically)
end
end

Some files were not shown because too many files have changed in this diff Show More