Skip to content

Commit

Permalink
Merge pull request #17 from DSACMS/mg-employer-search
Browse files Browse the repository at this point in the history
Simplified Employer Search
  • Loading branch information
allthesignals authored May 14, 2024
2 parents 1550724 + 90d17e3 commit 26eead6
Show file tree
Hide file tree
Showing 12 changed files with 135 additions and 64 deletions.
1 change: 1 addition & 0 deletions app/assets/images/uswds.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
//= link @uswds/uswds/dist/img/icon-dot-gov.svg
//= link @uswds/uswds/dist/img/icon-https.svg
//= link @uswds/uswds/dist/img/usa-icons/close.svg
//= link @uswds/uswds/dist/img/usa-icons-bg/search--white.svg
2 changes: 0 additions & 2 deletions app/controllers/api/argyle_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
class Api::ArgyleController < ApplicationController
skip_before_action :verify_authenticity_token

USER_TOKEN_ENDPOINT = 'https://api-sandbox.argyle.com/v2/user-tokens';

def update_token
Expand Down
15 changes: 12 additions & 3 deletions app/controllers/cbv_flows_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ def entry

def employer_search
@argyle_user_token = fetch_and_store_argyle_token
@companies = fetch_employers
@query = search_params[:query]
@employers = @query.blank? ? [] : fetch_employers(@query)
end

def summary
Expand Down Expand Up @@ -71,8 +72,12 @@ def fetch_and_store_argyle_token
parsed['user_token']
end

def fetch_employers
res = Net::HTTP.get(URI.parse(ITEMS_ENDPOINT), {"Authorization" => "Basic #{Rails.application.credentials.argyle[:api_key]}"})
def fetch_employers(query = '')
request_params = URI.encode_www_form(
mapping_status: 'verified,mapped',
q: query
)
res = Net::HTTP.get(URI(ITEMS_ENDPOINT).tap { |u| u.query = request_params }, {"Authorization" => "Basic #{Rails.application.credentials.argyle[:api_key]}"})
parsed = JSON.parse(res)

parsed['results']
Expand All @@ -84,4 +89,8 @@ def fetch_payroll

parsed['results']
end

def search_params
params.permit(:query)
end
end
8 changes: 7 additions & 1 deletion app/javascript/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,21 @@ import "@uswds/uswds"
// make sure USWDS components are wired to their behavior after a Turbo navigation
import components from "@uswds/uswds/src/js/components"
let initialLoad = true;

document.addEventListener("turbo:load", () => {
if (initialLoad) {
// initial domready is handled by `import "uswds"` code
initialLoad = false
return
}

const target = document.body
Object.keys(components).forEach((key) => {
const behavior = components[key]
behavior.on(target)
})
})
});

document.addEventListener("turbo:frame-render", () => {
initialLoad = true;
});
35 changes: 9 additions & 26 deletions app/javascript/controllers/cbv_flows_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,20 @@ import * as ActionCable from '@rails/actioncable'
import metaContent from "../utilities/meta";
import { loadArgyle, initializeArgyle, updateToken } from "../utilities/argyle"

function toOptionHTML({ value }) {
return `<option value='${value}'>${value}</option>`;
}

export default class extends Controller {
static targets = ["options", "continue", "userAccountId", "fullySynced", "form", "modal"];

selection = null;
static targets = [
"form",
"searchTerms",
"userAccountId",
"modal"
];

argyle = null;

argyleUserToken = null;

cable = ActionCable.createConsumer();

// TODO: information stored on the CbvFlow model can infer whether the paystubs are sync'd
// by checking the value of payroll_data_available_from. We should make that the initial value.
fullySynced = false;

connect() {
// check for this value when connected
this.argyleUserToken = metaContent('argyle_user_token');
Expand All @@ -34,10 +29,7 @@ export default class extends Controller {
console.log("Disconnected");
},
received: (data) => {
console.log("Received some data:", data);
if (data.event === 'paystubs.fully_synced' || data.event === 'paystubs.partially_synced') {
this.fullySynced = true;

this.formTarget.submit();
}
}
Expand All @@ -54,23 +46,14 @@ export default class extends Controller {
console.log(event);
}

search(event) {
const input = event.target.value;
this.optionsTarget.innerHTML = [this.optionsTarget.innerHTML, toOptionHTML({ value: input })].join('');
}

select(event) {
this.selection = event.detail;

this.continueTarget.disabled = false;
this.submit(event.target.dataset.itemId);
}

submit(event) {
event.preventDefault();

submit(itemId) {
loadArgyle()
.then(Argyle => initializeArgyle(Argyle, this.argyleUserToken, {
items: [this.selection.value],
items: [itemId],
onAccountConnected: this.onSignInSuccess.bind(this),
onAccountError: this.onAccountError.bind(this),
// Unsure what these are for!
Expand Down
8 changes: 7 additions & 1 deletion app/javascript/utilities/argyle.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import loadScript from 'load-script';
import metaContent from "./meta";
import CSRF from './csrf';

const ARGYLE_TOKENS_REFRESH = '/api/argyle/tokens';

Expand All @@ -24,7 +25,12 @@ export function initializeArgyle(Argyle, userToken, callbacks) {
}

export const updateToken = async updateToken => {
const response = await fetch(ARGYLE_TOKENS_REFRESH, { method: 'post' }).then(response => response.json());
const response = await fetch(ARGYLE_TOKENS_REFRESH, {
method: 'post',
headers: {
'X-CSRF-Token': CSRF.token,
},
}).then(response => response.json());

updateToken(response.token);
}
36 changes: 36 additions & 0 deletions app/javascript/utilities/csrf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Borrowed from https://github.com/18F/identity-idp/blob/59bc8bb6c47402f386d9248bfad3c0803f68187e/app/javascript/packages/request/index.ts#L25-L59
export default class CSRF {
static get token(): string | null {
return this.#tokenMetaElement?.content || null;
}

static set token(value: string | null) {
if (!value) {
return;
}

if (this.#tokenMetaElement) {
this.#tokenMetaElement.content = value;
}

this.#paramInputElements.forEach((input) => {
input.value = value;
});
}

static get param(): string | undefined {
return this.#paramMetaElement?.content;
}

static get #tokenMetaElement(): HTMLMetaElement | null {
return document.querySelector('meta[name="csrf-token"]');
}

static get #paramMetaElement(): HTMLMetaElement | null {
return document.querySelector('meta[name="csrf-param"]');
}

static get #paramInputElements(): NodeListOf<HTMLInputElement> {
return document.querySelectorAll(`input[name="${this.param}"]`);
}
}
31 changes: 31 additions & 0 deletions app/views/cbv_flows/_employer.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<%= turbo_frame_tag 'employers' do %>
<div class="usa-card-group">
<% @employers.each do |employer| %>
<div class="usa-card usa-card--flag usa-card--media-right flex-1">
<div class="usa-card__container">
<div class="usa-card__header">
<h2 class="usa-card__heading"><%= employer['name'] %></h2>
</div>
<div class="display-none usa-card__media usa-card__media--inset">
<div class="usa-card__img">
<img
src="<%= employer['logo_url'] %>"
alt="A placeholder image"
/>
</div>
</div>
<div class="usa-card__footer">
<button
data-action="click->cbv-flows#select"
data-item-id="<%= employer['id'] %>"
class="usa-button usa-button--outline"
type="button"
>
Select
</button>
</div>
</div>
</div>
<% end %>
</div>
<% end %>
56 changes: 28 additions & 28 deletions app/views/cbv_flows/employer_search.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,39 @@
<h2>Get payment info from your employer.</h2>

<div data-controller="cbv-flows">
<%= form_with url: next_path, method: :post, data: { 'cbv-flows-target': "form" } do |f| %>
<label class="usa-label" for="employer">Search for an employer</label>
<div class="usa-combo-box margin-bottom-3" data-action="input->cbv-flows#search">
<select class="usa-select" name="employer" id="employer" data-cbv-flows-target="options" data-action="change->cbv-flows#select">
<option value>Select an employer</option>
<% @companies.each do |company| %>
<option value='<%= company['id'] %>'>
<%= company['name'] %>
</option>
<% end %>
</select>
<input type="hidden" name="user[account_id]" data-cbv-flows-target="userAccountId" />
</div>
<a
href="#example-modal-3"
class="display-none"
aria-controls="example-modal-3"
data-open-modal
data-cbv-flows-target="modal"
></a>
<%= f.submit "Continue",
class: "usa-button usa-button--outline",
disabled: "disabled",
type: "submit",
data: { action: "click->cbv-flows#submit", 'cbv-flows-target': "continue" }
%>
<button class="usa-button usa-button--outline" disabled="true" type="button">Add Another Employer</button>
<h3 class="site-preview-heading">Search for an employer</h3>
<%= form_with url: cbv_flow_employer_search_path, method: :get, class: 'usa-search usa-search--big', html: { role: 'search' }, data: { turbo_frame: 'employers', turbo_action: 'advance' } do |f| %>
<%= f.label :query, "Search for your employer", class: "usa-sr-only" %>
<%= f.text_field :query, value: @query, class: "usa-input", type: 'search', data: { "cbv-flows-target": "searchTerms" } %>
<button
class="usa-button"
type="submit"
>
<span class="usa-search__submit-text">
Search
</span>
<%= image_tag "@uswds/uswds/dist/img/usa-icons-bg/search--white.svg", class: "usa-search__submit-icon", alt: "Search" %>
</button>
<% end %>

<h3 class="site-preview-heading margin-bottom-2">Results</h3>
<%= render partial: 'employer', locals: { employer: @employers } %>

<%= form_with url: next_path, method: :post, class: 'display-none', data: { 'cbv-flows-target': "form" } do |f| %>
<input type="hidden" name="user[account_id]" data-cbv-flows-target="userAccountId" />
<% end %>

<a
href="#data-fetching-modal"
class="display-none"
aria-controls="data-fetching-modal"
data-open-modal
data-cbv-flows-target="modal"
></a>
<div class="margin-y-3">
<div
class="usa-modal"
id="example-modal-3"
id="data-fetching-modal"
aria-labelledby="modal-3-heading"
aria-describedby="modal-3-description"
data-force-action
Expand Down
2 changes: 1 addition & 1 deletion app/views/pages/home.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<h1>Welcome to Verify.gov</h1>
<h2>This website can help you get approved for Medicaid</h2>
<h2>This website can help you get approved for your benefits.</h2>

<p>Get started here by requesting a link from your caseworker.</p>

Expand Down
5 changes: 3 additions & 2 deletions db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified doc/compliance/rendered/apps/data.logical.pdf
Binary file not shown.

0 comments on commit 26eead6

Please sign in to comment.