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

FFS-2295: Help modal #417

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open

FFS-2295: Help modal #417

wants to merge 31 commits into from

Conversation

GeorgeCodes19
Copy link
Contributor

@GeorgeCodes19 GeorgeCodes19 commented Jan 22, 2025

Ticket

Resolves FFS-2295.

  • Update help topic(s) content
  • Add E2E tests
  • Add /help route to use in iframe
  • Add Help link in top nav that triggers the Help Modal
  • Ensuring that clicking the options link in the help banner triggers the Help Modal
  • Ensuring that the "Go Back" button works within the Help Modal
  • Ensuring that closing the Pinwheel modal triggers the Help Banner to appear

Changes

Context for reviewers

Acceptance testing

  • No acceptance testing needed
    • This change will not affect the user experience (bugfix, dependency updates, etc.)
  • Acceptance testing prior to merge
    • This change can be verified visually via screenshots attached below or by sending a link to a local development environment to the acceptance tester
    • Acceptance testing should be done by design for visual changes, product for behavior/logic changes, or both for changes that impact both.
  • Acceptance testing after merge
    • This change is hard to test locally, so we'll test it in the demo environment (deployed automatically after merge.)
    • Make sure to notify the team once this PR is merged so we don't inadvertently deploy the unaccepted change to production. (e.g. :alert: Deploy block! @ffs-eng I just merged PR [#123] and will be doing acceptance testing in demo - please don't deploy until I'm finished!)

…working with view partials"""

This reverts commit 2d09705.
Capybara.default_driver = Capybara.javascript_driver
Capybara.server = :puma
Capybara.register_server :puma do |app, port, host|
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I couldn't get Capybara to automatically register puma as a server so I manually did it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Huh, weird, but ok, sounds good. Since we haven't been in the habit of running these tests, I could believe that they're not configured correctly.

Maybe you weren't running specs locally with bundle exec?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I opted to use a component here since there's now a Help nav item in the main nav as well as a link in the Help banner.

<div class="usa-modal__content">
<div class="usa-modal__main padding-0 margin-0 maxw-none-important">
<div class="usa-modal__body padding-0">
<iframe
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note that I've resorted to an iframe here rather coding a bunch of JS. I figured this would more closely resemble our current approach and that we can add custom Mixpanel/New Relic events using Rails helpers.

Copy link
Contributor

Choose a reason for hiding this comment

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

Kinda a bummer to use an <iframe> but I understand the complexity.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Rather than creating explicit views for each help topic I opted to rely on the en.yml entries and this component since the help topic content share a consistent layout.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This test suite is missing one test that I racked my brain on for a while... when the pinwheel modal closes the help banner appears

I had difficulty with getting Capybara to click the close button located within the Pinwheel modal. I figured we could resort the manual/smoke testing this feature for now, but I've confirmed that it works.

@GeorgeCodes19 GeorgeCodes19 marked this pull request as ready for review January 28, 2025 00:07

private

attr_reader :class_name, :text
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Move to top of class?

end

def before_render
@text ||= t("help.alert.help_options")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Pass this in, rather than setting the default in the component

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This can be a partial since it's only used once.

@@ -18,6 +18,8 @@
<%= render "application/header" %>
<main id="main-content">
<section class="grid-container usa-section">
<%= render HelpAlertComponent.new(visible: params[:help] == "true", help_path: cbv_flow_help_index_path(locale: I18n.locale)) %>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Rather than using HelpAlertComponent we can read the help params within the help controller and use flash instead. This would mean that we don't introduce new patterns.

Comment on lines 9 to 11
def modal_id
"help-modal"
end
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this gets used anywhere

Comment on lines 13 to 15
def open?
@open
end
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this gets used anywhere

Comment on lines 17 to 19
def help_path
@help_path
end
Copy link
Contributor

Choose a reason for hiding this comment

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

I wouldn't wrap this in a method like this because it's somewhat superfluous.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, could be an attr_reader.

Comment on lines 6 to 11
@text = text
end

def before_render
@text ||= t("help.alert.help_options")
end
Copy link
Contributor

Choose a reason for hiding this comment

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

Im' not sure what this is for yet maybe vestigial? I think it's confusing way to set a default

Comment on lines 1 to 4
<%= link_to text, "#help-modal",
class: class_name,
aria: { controls: "help-modal" },
data: { open_modal: true } %>
Copy link
Contributor

Choose a reason for hiding this comment

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

This could be a partial probably

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this can be a partial too

Copy link
Contributor

Choose a reason for hiding this comment

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

I would see if you can get away with a partial for this too :)

Copy link
Contributor

Choose a reason for hiding this comment

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

I woudl investigate whether you could do this within the existing flash error/alert system :)

@@ -54,5 +56,7 @@
</main>
<%= render "application/footer" %>
</div>

<%= render HelpModalComponent.new(open: params[:help_modal] == "true", help_path: cbv_flow_help_index_path(locale: I18n.locale)) %>
Copy link
Contributor

Choose a reason for hiding this comment

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

This is here because this modal can always be accesse and the design calls for accessing the help modal anywhere in the app

Copy link
Contributor

Choose a reason for hiding this comment

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

To match the other param name:

Suggested change
<%= render HelpModalComponent.new(open: params[:help_modal] == "true", help_path: cbv_flow_help_index_path(locale: I18n.locale)) %>
<%= render HelpModalComponent.new(open: params[:help] == "true", help_path: cbv_flow_help_index_path(locale: I18n.locale)) %>


<ol>
<% steps = t("help.show.#{topic}", default: {}).select { |k, _| k.to_s.start_with?('step') } %>
<% steps.each do |step, _| %>
Copy link
Contributor

Choose a reason for hiding this comment

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

I would not use this _ thing :)

Copy link
Contributor

@tdooner tdooner left a comment

Choose a reason for hiding this comment

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

Looking good. Only blocker I see is the CSP policy (the visual regression on the payment_details page.)

</svg>
</button>
</div>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, would have been interesting to try and make a UswdsModal component that took arbitrary contents (i.e. the help <iframe>). Then it would be reusable if we needed another modal elsewhere. Don't worry about it for now, though, just a thought. We could generalize it later if we need another modal.

<div class="usa-modal__content">
<div class="usa-modal__main padding-0 margin-0 maxw-none-important">
<div class="usa-modal__body padding-0">
<iframe
Copy link
Contributor

Choose a reason for hiding this comment

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

Kinda a bummer to use an <iframe> but I understand the complexity.

policy.style_src_elem :self
# Allow inline styles as we have some on the payment_details page:
policy.style_src_attr "'unsafe-inline'"
policy.style_src_attr :self
Copy link
Contributor

@tdooner tdooner Jan 28, 2025

Choose a reason for hiding this comment

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

This will break the payment_details page rendering, since there are some inline styles on that page (see the comment on line 20):

image

(The section headers should have blue backgrounds.)

I'm going to make a ticket to remove the inline styles since they shouldn't be necessary. Until then, we'll have to keep this as "'unsafe-inline'". (edit: it's https://jiraent.cms.gov/browse/FFS-2430 )

@@ -7,25 +7,24 @@
Rails.application.configure do
config.content_security_policy do |policy|
policy.default_src :self
policy.font_src :self
policy.font_src :self, :data
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure I understand why this change is necessary - did you change anything having to do with fonts?


private

attr_reader :topic
Copy link
Contributor

Choose a reason for hiding this comment

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

Should also be at the top (I saw another comment about it in a different file).

Comment on lines +406 to +408
search_keywords: Search your email for keywords like "payroll," "[Payroll Provider Name]," or "company ID."
title: Check your welcome materials
welcome_materials: Your company ID is often in your onboarding documents, welcome email, or payroll setup info.
Copy link
Contributor

Choose a reason for hiding this comment

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

If these are dynamically rendered in the order they appear in this file (and it has to match the designs), you may want to use an array here instead. Something like:

Suggested change
search_keywords: Search your email for keywords like "payroll," "[Payroll Provider Name]," or "company ID."
title: Check your welcome materials
welcome_materials: Your company ID is often in your onboarding documents, welcome email, or payroll setup info.
- Search your email for keywords like "payroll," "[Payroll Provider Name]," or "company ID."
- Check your welcome materials
- Your company ID is often in your onboarding documents, welcome email, or payroll setup info.

Otherwise you may have to fight with the i18n normalizer to get the key names in the right order to match the designs.

@@ -54,5 +56,7 @@
</main>
<%= render "application/footer" %>
</div>

<%= render HelpModalComponent.new(open: params[:help_modal] == "true", help_path: cbv_flow_help_index_path(locale: I18n.locale)) %>
Copy link
Contributor

Choose a reason for hiding this comment

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

To match the other param name:

Suggested change
<%= render HelpModalComponent.new(open: params[:help_modal] == "true", help_path: cbv_flow_help_index_path(locale: I18n.locale)) %>
<%= render HelpModalComponent.new(open: params[:help] == "true", help_path: cbv_flow_help_index_path(locale: I18n.locale)) %>

expect(page).to have_link(I18n.t("help.index.provider"))
expect(page).to have_link(I18n.t("help.index.credentials"))
expect(page).to have_link(I18n.t("help.index.feedback"))
end
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice!

Capybara.default_driver = Capybara.javascript_driver
Capybara.server = :puma
Capybara.register_server :puma do |app, port, host|
Copy link
Contributor

Choose a reason for hiding this comment

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

Huh, weird, but ok, sounds good. Since we haven't been in the habit of running these tests, I could believe that they're not configured correctly.

Maybe you weren't running specs locally with bundle exec?

</ul>
</li>
<% end %>
</ol>
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure we're getting much out of these components since they are single-purpose. If it's gonna be single purpose anyway, for future stuff I think just using views (and possibly partials) is simpler and easier to follow.

@tdooner
Copy link
Contributor

tdooner commented Jan 29, 2025

@GeorgeCodes19 Also, I just discovered weird behavior if the session expires:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants