Feature/allow for csv upload in import flow #978

Closed
MagnusHJensen wants to merge 11 commits from feature/allow-for-csv-upload-in-import-flow into main
MagnusHJensen commented 2024-07-12 22:03:27 +08:00 (Migrated from github.com)

Closes: #799

This PR enables CSV upload in the load flow of imports.

It adds a dropzone controller, that through an XMLHttpRequest monitors the upload status, which can give you a progress bar.

It also handles wrong file formats and displays it in the dropzone.
it also uploads the parsed CSV and then redirects you back, where you can manually edit the content of the uploaded CSV while still having the success dropzone.

It is also translated and in accordance to the design spec, which can be found here:
https://www.figma.com/design/lonJmVk3HYkwZoIO7xYP2w/Maybe-App-(Community)?node-id=3656-18086&t=t84SVrxXV2CSiCM7-0

Media

https://github.com/user-attachments/assets/c05f8050-be9f-4196-94ca-3f700588a2cf

Closes: #799 This PR enables CSV upload in the load flow of imports. It adds a dropzone controller, that through an XMLHttpRequest monitors the upload status, which can give you a progress bar. It also handles wrong file formats and displays it in the dropzone. it also uploads the parsed CSV and then redirects you back, where you can manually edit the content of the uploaded CSV while still having the success dropzone. It is also translated and in accordance to the design spec, which can be found here: https://www.figma.com/design/lonJmVk3HYkwZoIO7xYP2w/Maybe-App-(Community)?node-id=3656-18086&t=t84SVrxXV2CSiCM7-0 ## Media https://github.com/user-attachments/assets/c05f8050-be9f-4196-94ca-3f700588a2cf
MagnusHJensen (Migrated from github.com) reviewed 2024-07-12 22:03:52 +08:00
@@ -2,6 +2,7 @@ require "ostruct"
class ImportsController < ApplicationController
before_action :set_import, except: %i[ index new create ]
protect_from_forgery with: :null_session, include: %i[ upload_csv ]
MagnusHJensen (Migrated from github.com) commented 2024-07-12 22:03:52 +08:00

I don't think this is the best practice, however was unsure how to make it work from a JS http request.

I don't think this is the best practice, however was unsure how to make it work from a JS http request.
MagnusHJensen (Migrated from github.com) reviewed 2024-07-12 22:04:28 +08:00
@@ -50,1 +66,4 @@
end
end
def configure
MagnusHJensen (Migrated from github.com) commented 2024-07-12 22:04:28 +08:00

The errors are not translated, since they are only logged in the console here, which could be picked up by a service like Sentry.

The dropzone does translate errors as seen in the translation file.

The errors are not translated, since they are only logged in the console here, which could be picked up by a service like Sentry. The dropzone does translate errors as seen in the translation file.
zachgoll (Migrated from github.com) reviewed 2024-07-13 01:00:21 +08:00
@@ -50,1 +66,4 @@
end
end
def configure
zachgoll (Migrated from github.com) commented 2024-07-13 01:00:21 +08:00

No worries, think this is okay!

No worries, think this is okay!
zachgoll (Migrated from github.com) reviewed 2024-07-13 01:19:43 +08:00
zachgoll (Migrated from github.com) commented 2024-07-13 01:19:43 +08:00

This Turbo Stream solution definitely works, but I think we should try to build this flow without any dependencies on Streams to start as outlined in the Turbo handbook:

It’s good practice to start your interaction design without Turbo Streams. Make the entire application work as it would if Turbo Streams were not available, then layer them on as a level-up. This means you won’t come to rely on the updates for flows that need to work in native applications or elsewhere without them.

I'm thinking we should build this endpoint a bit closer to what @tonyvince had in #973:

def upload_csv
  file = import_params[:raw_csv_str]
  @import.raw_csv_str = file.read
  CSV.parse(@import.raw_csv_str)
  if @import.save
    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
rescue CSV::MalformedCSVError, ArgumentError => error
  flash.now[:error] = error.message
  render :load, status: :unprocessable_entity
end

I know some of the designs dictate client-side interactions, but I'm 100% fine deviating a little bit from them for now so that we can achieve the simplest possible flow that's easy to test. This will also help us avoid the protect_from_forgery workaround and quite a bit of Stimulus controller code as we'll just be doing a simple, Rails-native form submission.

This Turbo Stream solution definitely works, but I think we should try to build this flow without any dependencies on Streams to start as [outlined in the Turbo handbook](https://turbo.hotwired.dev/handbook/streams#progressively-enhance-when-necessary): > It’s good practice to start your interaction design without Turbo Streams. Make the entire application work as it would if Turbo Streams were not available, then layer them on as a level-up. This means you won’t come to rely on the updates for flows that need to work in native applications or elsewhere without them. I'm thinking we should build this endpoint a bit closer to what @tonyvince had in #973: ```rb def upload_csv file = import_params[:raw_csv_str] @import.raw_csv_str = file.read CSV.parse(@import.raw_csv_str) if @import.save 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 rescue CSV::MalformedCSVError, ArgumentError => error flash.now[:error] = error.message render :load, status: :unprocessable_entity end ``` I know some of the designs dictate client-side interactions, but I'm 100% fine deviating a little bit from them for now so that we can achieve the simplest possible flow that's easy to test. This will also help us avoid the `protect_from_forgery` workaround and quite a bit of Stimulus controller code as we'll just be doing a simple, Rails-native form submission.
tonyvince commented 2024-07-15 16:29:09 +08:00 (Migrated from github.com)

Awesome job setting up this PR ❤️
I think what we have in #973 is closer to the designs. If you don't want to make many changes, maybe we can at least copy the sample file download part?

Screenshot 2024-07-15 at 10 24 05
Awesome job setting up this PR ❤️ I think what we have in #973 is closer to the designs. If you don't want to make many changes, maybe we can at least copy the [sample file download part](https://github.com/maybe-finance/maybe/pull/973/files#diff-84ad6e219ec134bdb059b41d19d0017c3d528af110e7e76d1a3f6c4c73c85dcfR38)? <img width="799" alt="Screenshot 2024-07-15 at 10 24 05" src="https://github.com/user-attachments/assets/ce0e1f5d-c5b8-4be4-9178-cc7d0d6f52df">
MagnusHJensen commented 2024-07-15 17:16:20 +08:00 (Migrated from github.com)

Awesome job setting up this PR ❤️ I think what we have in #973 is closer to the designs. If you don't want to make many changes, maybe we can at least copy the sample file download part?

Screenshot 2024-07-15 at 10 24 05

Hey,

I'm going to move the download part away from turbo stream and just into progressing after a download like you did.

In regards to the table, see this comment: https://github.com/maybe-finance/maybe/issues/799#issuecomment-2214126257 where it was stated that mismatch between designs and application can and will occur as of right now, so the table already in the application is correct, and should not be changed, that is what I understand from it.

> Awesome job setting up this PR ❤️ I think what we have in #973 is closer to the designs. If you don't want to make many changes, maybe we can at least copy the [sample file download part](https://github.com/maybe-finance/maybe/pull/973/files#diff-84ad6e219ec134bdb059b41d19d0017c3d528af110e7e76d1a3f6c4c73c85dcfR38)? > > <img alt="Screenshot 2024-07-15 at 10 24 05" width="799" src="https://private-user-images.githubusercontent.com/17843050/348641103-ce0e1f5d-c5b8-4be4-9178-cc7d0d6f52df.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjEwMzUxNjYsIm5iZiI6MTcyMTAzNDg2NiwicGF0aCI6Ii8xNzg0MzA1MC8zNDg2NDExMDMtY2UwZTFmNWQtYzViOC00YmU0LTkxNzgtY2M3ZDBkNmY1MmRmLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MTUlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzE1VDA5MTQyNlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWNmZDg4ODQyMzQ1ZWRiNzhhNjMyNTNlN2FlMmVhZWU0MWFlNjlkNGJiMTU4MTIyMGE3MDkwOGI5MzBjOGI5MTcmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.-tlHu84w277NvbzaU2ZO-aomX0YaXF0vuWH1SX4485I"> Hey, I'm going to move the download part away from turbo stream and just into progressing after a download like you did. In regards to the table, see this comment: https://github.com/maybe-finance/maybe/issues/799#issuecomment-2214126257 where it was stated that mismatch between designs and application can and will occur as of right now, so the table already in the application is correct, and should not be changed, that is what I understand from it.
tonyvince commented 2024-07-15 17:29:31 +08:00 (Migrated from github.com)

so the table already in the application is correct, and should not be changed

I was referring to the sample CSV file download part. See

> so the table already in the application is correct, and should not be changed I was referring to the sample CSV file download part. [See](https://github.com/maybe-finance/maybe/pull/973/files#diff-84ad6e219ec134bdb059b41d19d0017c3d528af110e7e76d1a3f6c4c73c85dcfR31-R44)
MagnusHJensen commented 2024-07-16 01:07:04 +08:00 (Migrated from github.com)

Ah okay, feel free to go with @tonyvince's suggestion, since it's already made and closer to the wanted outcome.

Ah okay, feel free to go with @tonyvince's suggestion, since it's already made and closer to the wanted outcome.

Pull request closed

Sign in to join this conversation.