Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React autosave: patient dashboard form #3216

Merged

Conversation

mercedesb
Copy link
Contributor

@mercedesb mercedesb commented Jun 6, 2024

I rule and have completed some work on Case Manager that's ready for review!

This PR rewrites the patient dashboard form in React with safe autosave.

The commits might be the easiest way to review the changes.

  • Allow patients#update to respond to json
  • Add a few base reusable component types for creating forms (Input, Select, and Tooltip)
  • Add a useFetch hook for easy async data fetching
  • Add a useFlash hook for rendering flash messages
  • Rebuild the form in React

Screen recordings with CSP turned on

Before rewriting in React (notice console error)

Screen.Recording.2024-06-06.at.10.15.11.AM.mov

After rewriting in React (no console error)

Screen.Recording.2024-06-06.at.10.12.15.AM.mov

Note: there's a small little jump that happens sometimes but I haven't figured out where it's coming from yet

For reviewer:

  • Adjust the title to explain what it does for the notification email to the listserv.
  • Tag this PR:
    • feature if it contains a feature, fix, or similar. This is anything that contains a user-facing fix in some way, such as frontend changes, alterations to backend behavior, or bug fixes.
    • dependencies if it contains library upgrades or similar. This is anything that upgrades any dependency, such as a Gemfile update or npm package upgrade.
  • If it contains neither, no need to tag this PR.

@mercedesb mercedesb force-pushed the react-autosave/patient-dashboard-form branch 5 times, most recently from f4ff837 to 8bd0f85 Compare June 8, 2024 23:23
@mercedesb mercedesb force-pushed the react-autosave/patient-dashboard-form branch from 8bd0f85 to 4434764 Compare June 8, 2024 23:46
@mercedesb mercedesb force-pushed the react-autosave/patient-dashboard-form branch from 4434764 to 93c9ab6 Compare June 9, 2024 00:01
Copy link
Member

@lomky lomky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is looking great! If you'd add a bit of context where I've flagged and get the system tests going, I think we're gtg!

app/controllers/patients_controller.rb Outdated Show resolved Hide resolved
app/controllers/patients_controller.rb Outdated Show resolved Hide resolved
app/models/patient.rb Show resolved Hide resolved
Comment on lines 5 to 33
// Some evil magic for things attached to labels with rails-bootstrap-form
$('.tooltip-header-input').append(' <span class="tooltip-header-help">(?)</span>');
$('.tooltip-header-input').parent('.form-group' ).find('.form-control').each((_, x) => {
$(x).parents( '.form-group' ).find( '.tooltip-header-help' ).tooltip({
html: true,
placement: 'bottom',
title: $(x).data('tooltip-text')
$(".tooltip-header-input:not(:has(span.tooltip-header-help))").append(
' <span class="tooltip-header-help">(?)</span>'
);
$(".tooltip-header-input")
.parent(".form-group")
.find(".form-control")
.each((_, x) => {
$(x)
.parents(".form-group")
.find(".tooltip-header-help")
.tooltip({
html: true,
placement: "bottom",
title: $(x).data("tooltip-text"),
});
});
});

// Similarly evil magic for checkboxes
$('.tooltip-header-checkbox').append(' <span class="tooltip-header-help">(?)</span>')
$('.tooltip-header-checkbox').each((_, x) => {
let text = $(x).parent().find('input[type=checkbox]').data('tooltip-text');
$(x).parent().find( 'span.tooltip-header-help' ).tooltip({
$(".tooltip-header-checkbox:not(:has(span.tooltip-header-help))").append(
' <span class="tooltip-header-help">(?)</span>'
);
$(".tooltip-header-checkbox").each((_, x) => {
let text = $(x).parent().find("input[type=checkbox]").data("tooltip-text");
$(x).parent().find("span.tooltip-header-help").tooltip({
html: true,
placement: 'bottom',
placement: "bottom",
title: text,
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are the two "evil" comments still valid here, or have we adjusted it to be evil magic that works with bootstrap form and avoids the React?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a really good question. The "evil" comments are still valid b/c I haven't removed all of our bootstrap form tooltips. I've just added the ability to use React to render tooltips and have them behave in the same way.

If we eventually get all the tooltips moved to React and don't use bootstrap form, we could probably refactor this code away.

Aside: It looks like my JS formatting extension was a little assertive here and autoformatted this. I'll undo that so the diff is super clear.

app/javascript/src/hooks/useDebounce.js Show resolved Hide resolved
test/system/update_patient_info_test.rb Outdated Show resolved Hide resolved
@mercedesb mercedesb force-pushed the react-autosave/patient-dashboard-form branch from 99b88d2 to ff5ae59 Compare June 10, 2024 22:25
@mercedesb mercedesb marked this pull request as ready for review June 10, 2024 22:31
@lomky
Copy link
Member

lomky commented Jun 14, 2024

Everything is looking good, but in local testing I'm seeing some strange behavior

I'm seeing a parameter error on the server. It's not stopping it from saving, which is also a bit strange?

dcaf_case_management-web-1  | [INFO ] === Processing by PatientsController#update as JSON
dcaf_case_management-web-1  | [INFO ]   Parameters: {"id"=>"83", "name"=>"[FILTERED]", "primary_phone"=>"[FILTERED]", "other_contact"=>nil, "other_phone"=>nil, "other_contact_relationship"=>nil, "identifier"=>"G2-1335", "voicemail_preference"=>"[FILTERED]", "line_legacy"=>nil, "language"=>"[FILTERED]", "pronouns"=>nil, "initial_call_date"=>"2024-06-12", "shared_flag"=>"[FILTERED]", "last_menstrual_period_weeks"=>3, "last_menstrual_period_days"=>0, "age"=>"[FILTERED]", "city"=>"[FILTERED]", "state"=>"[FILTERED]", "county"=>nil, "zipcode"=>"[FILTERED]", "race_ethnicity"=>"[FILTERED]", "employment_status"=>"[FILTERED]", "household_size_children"=>"[FILTERED]", "household_size_adults"=>"[FILTERED]", "insurance"=>"[FILTERED]", "income"=>"[FILTERED]", "special_circumstances"=>"[FILTERED]", "referred_by"=>nil, "referred_to_clinic"=>nil, "completed_ultrasound"=>nil, "appointment_date"=>"[FILTERED]", "procedure_cost"=>"[FILTERED]", "patient_contribution"=>nil, "naf_pledge"=>nil, "fund_pledge"=>nil, "fund_pledged_at"=>nil, "pledge_sent"=>nil, "resolved_without_fund"=>nil, "pledge_generated_at"=>nil, "pledge_sent_at"=>nil, "textable"=>nil, "clinic_id"=>nil, "pledge_generated_by_id"=>nil, "pledge_sent_by_id"=>nil, "last_edited_by_id"=>nil, "created_at"=>"2024-06-12T20:16:27.351-04:00", "updated_at"=>"2024-06-12T20:16:27.351-04:00", "fund_id"=>2, "line_id"=>4, "solidarity"=>nil, "solidarity_lead"=>nil, "procedure_type"=>nil, "status"=>"No Contact Made", "last_menstrual_period_at_appt_weeks"=>nil, "last_menstrual_period_at_appt_days"=>nil, "last_menstrual_period_now_weeks"=>3, "last_menstrual_period_now_days"=>0, "primary_phone_display"=>"[FILTERED]", "authenticity_token"=>"[FILTERED]", "patient"=>{"id"=>"83", "name"=>"[FILTERED]", "primary_phone"=>"[FILTERED]", "other_contact"=>nil, "other_phone"=>nil, "other_contact_relationship"=>nil, "identifier"=>"G2-1335", "voicemail_preference"=>"[FILTERED]", "line_legacy"=>nil, "language"=>"[FILTERED]", "pronouns"=>nil, "initial_call_date"=>"2024-06-12", "shared_flag"=>"[FILTERED]", "last_menstrual_period_weeks"=>3, "last_menstrual_period_days"=>0, "age"=>"[FILTERED]", "city"=>"[FILTERED]", "state"=>"[FILTERED]", "county"=>nil, "zipcode"=>"[FILTERED]", "race_ethnicity"=>"[FILTERED]", "employment_status"=>"[FILTERED]", "household_size_children"=>"[FILTERED]", "household_size_adults"=>"[FILTERED]", "insurance"=>"[FILTERED]", "income"=>"[FILTERED]", "special_circumstances"=>"[FILTERED]", "referred_by"=>nil, "referred_to_clinic"=>nil, "completed_ultrasound"=>nil, "appointment_date"=>"[FILTERED]", "procedure_cost"=>"[FILTERED]", "patient_contribution"=>nil, "naf_pledge"=>nil, "fund_pledge"=>nil, "fund_pledged_at"=>nil, "pledge_sent"=>nil, "resolved_without_fund"=>nil, "pledge_generated_at"=>nil, "pledge_sent_at"=>nil, "textable"=>nil, "clinic_id"=>nil, "pledge_generated_by_id"=>nil, "pledge_sent_by_id"=>nil, "last_edited_by_id"=>nil, "created_at"=>"2024-06-12T20:16:27.351-04:00", "updated_at"=>"2024-06-12T20:16:27.351-04:00", "fund_id"=>2, "line_id"=>4, "solidarity"=>nil, "solidarity_lead"=>nil, "procedure_type"=>nil}}
dcaf_case_management-web-1  | [DEBUG]   Fund Load (0.5ms)  SELECT "funds".* FROM "funds" WHERE "funds"."name" = $1 LIMIT $2  [["name", "[FILTERED]"], ["LIMIT", 1]]
dcaf_case_management-web-1  | [DEBUG]    app/controllers/application_controller.rb:48:in `confirm_tenant_set_development'
dcaf_case_management-web-1  | [DEBUG]   Patient Load (1.3ms)  SELECT "patients".* FROM "patients" WHERE "patients"."fund_id" = $1 AND "patients"."id" = $2 LIMIT $3  [["fund_id", 2], ["id", 83], ["LIMIT", 1]]
dcaf_case_management-web-1  | [DEBUG]   ↳ app/controllers/patients_controller.rb:177:in `find_patient_minimal'
dcaf_case_management-web-1  | [DEBUG] Unpermitted parameters: :id, :identifier, :line_legacy, :pledge_generated_at, :pledge_generated_by_id, :pledge_sent_by_id, :last_edited_by_id, :created_at, :updated_at, :fund_id. Context: { controller: PatientsController, action: update, request: #<ActionDispatch::Request:0x00007fb44ddaaa08>, params: {"id"=>"83", "name"=>"[FILTERED]", "primary_phone"=>"[FILTERED]", "other_contact"=>nil, "other_phone"=>nil, "other_contact_relationship"=>nil, "identifier"=>"G2-1335", "voicemail_preference"=>"[FILTERED]", "line_legacy"=>nil, "language"=>"[FILTERED]", "pronouns"=>nil, "initial_call_date"=>"2024-06-12", "shared_flag"=>"[FILTERED]", "last_menstrual_period_weeks"=>3, "last_menstrual_period_days"=>0, "age"=>"[FILTERED]", "city"=>"[FILTERED]", "state"=>"[FILTERED]", "county"=>nil, "zipcode"=>"[FILTERED]", "race_ethnicity"=>"[FILTERED]", "employment_status"=>"[FILTERED]", "household_size_children"=>"[FILTERED]", "household_size_adults"=>"[FILTERED]", "insurance"=>"[FILTERED]", "income"=>"[FILTERED]", "special_circumstances"=>"[FILTERED]", "referred_by"=>nil, "referred_to_clinic"=>nil, "completed_ultrasound"=>nil, "appointment_date"=>"[FILTERED]", "procedure_cost"=>"[FILTERED]", "patient_contribution"=>nil, "naf_pledge"=>nil, "fund_pledge"=>nil, "fund_pledged_at"=>nil, "pledge_sent"=>nil, "resolved_without_fund"=>nil, "pledge_generated_at"=>nil, "pledge_sent_at"=>nil, "textable"=>nil, "clinic_id"=>nil, "pledge_generated_by_id"=>nil, "pledge_sent_by_id"=>nil, "last_edited_by_id"=>nil, "created_at"=>"2024-06-12T20:16:27.351-04:00", "updated_at"=>"2024-06-12T20:16:27.351-04:00", "fund_id"=>2, "line_id"=>4, "solidarity"=>nil, "solidarity_lead"=>nil, "procedure_type"=>nil, "status"=>"No Contact Made", "last_menstrual_period_at_appt_weeks"=>nil, "last_menstrual_period_at_appt_days"=>nil, "last_menstrual_period_now_weeks"=>3, "last_menstrual_period_now_days"=>0, "primary_phone_display"=>"[FILTERED]", "authenticity_token"=>"[FILTERED]", "controller"=>"patients", "action"=>"update", "patient"=>{"id"=>"83", "name"=>"[FILTERED]", "primary_phone"=>"[FILTERED]", "other_contact"=>nil, "other_phone"=>nil, "other_contact_relationship"=>nil, "identifier"=>"G2-1335", "voicemail_preference"=>"[FILTERED]", "line_legacy"=>nil, "language"=>"[FILTERED]", "pronouns"=>nil, "initial_call_date"=>"2024-06-12", "shared_flag"=>"[FILTERED]", "last_menstrual_period_weeks"=>3, "last_menstrual_period_days"=>0, "age"=>"[FILTERED]", "city"=>"[FILTERED]", "state"=>"[FILTERED]", "county"=>nil, "zipcode"=>"[FILTERED]", "race_ethnicity"=>"[FILTERED]", "employment_status"=>"[FILTERED]", "household_size_children"=>"[FILTERED]", "household_size_adults"=>"[FILTERED]", "insurance"=>"[FILTERED]", "income"=>"[FILTERED]", "special_circumstances"=>"[FILTERED]", "referred_by"=>nil, "referred_to_clinic"=>nil, "completed_ultrasound"=>nil, "appointment_date"=>"[FILTERED]", "procedure_cost"=>"[FILTERED]", "patient_contribution"=>nil, "naf_pledge"=>nil, "fund_pledge"=>nil, "fund_pledged_at"=>nil, "pledge_sent"=>nil, "resolved_without_fund"=>nil, "pledge_generated_at"=>nil, "pledge_sent_at"=>nil, "textable"=>nil, "clinic_id"=>nil, "pledge_generated_by_id"=>nil, "pledge_sent_by_id"=>nil, "last_edited_by_id"=>nil, "created_at"=>"2024-06-12T20:16:27.351-04:00", "updated_at"=>"2024-06-12T20:16:27.351-04:00", "fund_id"=>2, "line_id"=>4, "solidarity"=>nil, "solidarity_lead"=>nil, "procedure_type"=>nil}} }

I also noticed this, which I think started happening when we merged the prework PR:

dcaf_case_management-js-1   |  YN0000:  Resolution step
dcaf_case_management-db-1   | performing post-bootstrap initialization ... ok
dcaf_case_management-css-1  |  YN0002:  root-workspace-0b6124@workspace:. doesn't provide @babel/core (p0a4bf), requested by @babel/preset-env
dcaf_case_management-css-1  | ➤ YN0002: │ root-workspace-0b6124@workspace:. doesn't provide @babel/core (p56e65), requested by @babel/preset-react
dcaf_case_management-css-1  |  YN0002:  root-workspace-0b6124@workspace:. doesn't provide @babel/core (p147eb), requested by babel-jest
dcaf_case_management-css-1  | ➤ YN0000: │ Some peer dependencies are incorrectly met; run yarn explain peer-requirements <hash> for details, where <hash> is the six-letter p-prefixed code
dcaf_case_management-css-1  | ➤ YN0000: └ Completed
dcaf_case_management-css-1  | ➤ YN0000: ┌ Fetch step
dcaf_case_management-js-1   | ➤ YN0002: │ root-workspace-0b6124@workspace:. doesn't provide @babel/core (p0a4bf), requested by @babel/preset-env
dcaf_case_management-js-1   |  YN0002:  root-workspace-0b6124@workspace:. doesn't provide @babel/core (p56e65), requested by @babel/preset-react
dcaf_case_management-js-1   | ➤ YN0002: │ root-workspace-0b6124@workspace:. doesn't provide @babel/core (p147eb), requested by babel-jest
dcaf_case_management-js-1   |  YN0000:  Some peer dependencies are incorrectly met; run yarn explain peer-requirements <hash> for details, where <hash> is the six-letter p-prefixed code
dcaf_case_management-js-1   |  YN0000:  Completed
dcaf_case_management-js-1   |  YN0000:  Fetch step

@mercedesb
Copy link
Contributor Author

I'm seeing a parameter error on the server. It's not stopping it from saving, which is also a bit strange?

@lomky That's normal. I went ahead and updated the js to not send unpermitted params, but Rails will just ignore unpermitted params. It won't stop saving or respond with errors.

I also added the missing peer dependency to fix the other warning in the logs.

@mercedesb mercedesb requested a review from lomky June 14, 2024 22:46
@lomky lomky added the feature label Jul 11, 2024
Copy link
Member

@lomky lomky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing work!

@lomky lomky merged commit 39ce00f into DARIAEngineering:main Jul 11, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants