-
-
Notifications
You must be signed in to change notification settings - Fork 454
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
5309 update contact type selection #5564
5309 update contact type selection #5564
Conversation
}, | ||
item: function(data, escape) { | ||
return ` | ||
<div class="badge rounded-pill primary-bg py-2 px-3 active form-check-label"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
custom badges of selected items
}, | ||
optgroup_header: function(data, escape) { | ||
return ` | ||
<span class='d-flex optgroup-header'> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make sure that highlighting doesn't mess up spacing of optgroup header
option: function(data, escape) { | ||
return ` | ||
<div class='d-flex gap-1'> | ||
<span class='d-flex gap-1'>${escape(data.label)}</span> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
b/c of a quirk w/ the highlighting implementation in tomselect, using gap-1
and d-flex
to keep everything on the same line. My preference exists for maintaining spaces and adding one extra space to the right than removing spaces altogether.
I think this implementation is good enough, though if we choose to remove highlighting altogether, we would likely avoid this being a problem.
remove_button: { | ||
title: 'Remove this item', | ||
className: 'text-primary p-1 mx-2 deactive-bg rounded-circle', | ||
label: `<i class="lni lni-close p-1"></i>` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
custom remove button, as per figma mockups
<div class="form-check checkbox-style mb-1"> | ||
<%= | ||
contact_type_exists = default_checked ? true : @casa_case.contact_types.include?(contact_type) | ||
contact_type_exists = false unless controller.controller_name == 'casa_cases' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm lacking the context here for what this view logic is doing, but when I grepped the code base, I couldn't find other circumstances in which this partial is reused, so I'm removing.
makes me feel icky to have a call based on controller name in my view, anyway 😬
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
following up -- I think this may be the context in which an admin is working with the file. this may require additional investigation.
</div> | ||
</div> | ||
<p>Choose from the available options below by searching or selecting from the dropdown menu.</p> | ||
<% last_case = @casa_cases.sort_by(&:created_at).last %> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems like there was already a convention of storing some of the view logic state in the partial before, so I stuck with it for speed. Would be happy to extract to a presenter or a decorator in order to encapsulate viewlogic here.
</div> | ||
<script type="text/javascript"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dead code once we remove checkboxes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is still dead code.
@@ -51,7 +51,7 @@ def update | |||
|
|||
def get_cases_and_contact_types | |||
@casa_cases = policy_scope(current_organization.casa_cases) | |||
@casa_cases = @casa_cases.where(id: @case_contact.casa_case_id) if @case_contact.active? | |||
@casa_cases = @casa_cases.find(@case_contact.casa_case_id) if @case_contact.active? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is wrong, will revert
…l/casa into 5309_update_contact_type_selection
Hi @afogel thanks again for jamming on this. Are you still working on this or does it just need review? Happy to push that along if so :) |
this still needs work wrt to tests. I've had less bandwidth over the last bit of time, but the core of the functionality is there. I do think there are some scenarios that may be caught by tests which aren't simply visual changes. That said, it's hard to gauge which are which as since most of the breaking tests are just brittle tests that don't catch real bugs. |
thank you @afogel I'll see what I can do about getting help with tests :) |
app/models/learning_hour.rb
Outdated
@@ -52,7 +52,6 @@ def user_org_learning_topic_enable? | |||
# id :bigint not null, primary key | |||
# duration_hours :integer not null | |||
# duration_minutes :integer not null | |||
# learning_type :integer default(5) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strange removal?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's fix the tests and prove that it works :)
I couldn't agree more that the tests should be fixed (though that's not what proves that it works 🙃 ); I'm just limited in the amount of time I have rn. I'll try to turn back to it, but may not be able to finish pushing it over the finish line for a bit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems solid overall, that being said I don't have that much context. Most of my feedback is minor questions / suggestions so don't mind that there is a lot of it. 🙂
Only parts I would consider blockers would be the highlight styling, potentially unused code and whether or not contact types are required.
app/models/case_contact.rb
Outdated
@@ -27,7 +27,7 @@ class CaseContact < ApplicationRecord | |||
validate :draft_case_ids_not_empty, if: :active_or_details? | |||
|
|||
has_many :case_contact_contact_type | |||
has_many :contact_types, through: :case_contact_contact_type, source: :contact_type | |||
has_and_belongs_to_many :contact_types, join_table: "case_contact_contact_types" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we sure that habtm is more correct than many through? Cause the CaseContactContactType
model exists.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general has_many, :through
is preferred over HABTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reverting
app/models/casa_org.rb
Outdated
def contact_types_as_hash_map | ||
ContactType.joins(:contact_type_group).where(active: true, contact_type_group: {casa_org: self}).order(:name).map(&:hash_for_multiple_select) | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bit of a nit:
I feel like having hash_for_multiple_select
in a different class makes this harder to understand. I'm not sure what the shape of the data is and I need to find where that method lives to find out.
contact_types = query stuff
contact_types.map { |type| {hash: stuff}}
I think doing all the work in this method is easier to follow especially since hash_for_multiple_select
isnt used anywhere else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add some Rdoc here, but the hash_for_multiple_select
is being used twice now and it acts upon the ContactType.
db/schema.rb
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changes seem unrelated to PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this getting used?
<template data-multiple-select-target="option"> | ||
<div class='d-flex gap-1'> | ||
<span class='d-flex gap-1'>DATA_LABEL</span> | ||
<% if @option_sub_text %> | ||
<span class="fst-italic text-muted">DATA_SUB_TEXT</span> | ||
<% end %> | ||
</div> | ||
</template> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently, this look real funky with highlighting. You can do something like :
#parent_element_whatever_it_is {
div {
white-space: break-space;
}
span + span {
margin-inline-start: 1.5rem;
}
}
and get rid of the gap classes and it will get rid of the weird spacing around the highlights.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this getting used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The select menu looks great! Two things worth considering (I don't have enough background on the issue to tell how much they matter):
- You got rid of the optgroups with group headings (CASA, family, etc). I think that makes it a bit unclear that you can use them to filter the search. like if I search for "CASA" its not clear to me why I get the results I do:
I don't know if there were technical reasons for this but I think the optgroups were nice from a UX perspective.
- No clue if this is an improvement from a UX perspective but maybe the input should clear on selecting an item. That way if you do something like "father enter mother enter" you don't have to backspace out what you inputted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Was part of the original ticket/Figma
- I like that, will investigate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That totally fair, kinda assumed it was from original screenshots. My thoughts were that since they want "A user should be able to fuzzy search based on “Contact Type Groups” (see “Editing CASA Organization page in admin portal), ie searching “Family” would still display “Grandparent”
I think a user isn't gonna realize they can search by group without some sort of indication of it. Idk if that makes sense.
@@ -43,10 +43,8 @@ class CasaCase < ApplicationRecord | |||
belongs_to :judge, optional: true | |||
belongs_to :casa_org | |||
validates :birth_month_year_youth, presence: true | |||
validates_presence_of :casa_case_contact_types, message: ": At least one contact type must be selected", if: :validate_contact_type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved back to has_many and re-added validation
app/views/casa_cases/_form.html.erb
Outdated
<!-- TODO - need to refactor this --> | ||
<%= render "case_contacts/form/contact_types", form: form, options: @contact_type_options, selected_items: @contact_type_selected_items %> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on talk to Linda. This should restrict the contact types available for a case. It currently does not seem to be working, if I pick a type of "CASA" for a case, then try to make a case contact for that case I see all the options available.
Also pretty sure this is related to a validation but I can update the case to not have no contact type set.
I also noticed that you can circumvent contact type restrictions but that is unrelated to the PR. #5605
@name = name | ||
@options = options.to_json | ||
@selected_items = selected_items | ||
@option_sub_text = option_sub_text |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: maybe render_option_subtext
? I initially thought this would be the text itself (I think the text is in the options hash right?).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it
Awesome, appreciate the thorough review! I'll try to poke around over the next bit of time and respond. I've honestly lost much of the context since I worked on the ticket a month ago, and I was also lacking some of the context around use cases, so it'll take a bit of time to go through, but I appreciate the feedback! |
app/views/casa_cases/_form.html.erb
Outdated
<!-- TODO - need to refactor this --> | ||
<%= render "case_contacts/form/contact_types", form: form, options: @contact_type_options, selected_items: @contact_type_selected_items %> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on talk to Linda. This should restrict the contact types available for a case. It currently does not seem to be working, if I pick a type of "CASA" for a case, then try to make a case contact for that case I see all the options available.
Also pretty sure this is related to a validation but I can update the case to not have no contact type set.
I also noticed that you can circumvent contact type restrictions but that is unrelated to the PR. #5605
Brandon reached out to some stakeholders (not sure who) at my request to determine what this functionality should look like. Some ways they might want it are harder than others. There are two pieces of functionality that are not related but might seem related to them:
1 is what Brandon was checking on. I think Mallory, Brandon, and I might have a discussion about the best user experience here. There's a thread in the Slack about it so far. 2 I initially pulled out, not quite understanding the context. Yuri rightfully pointed out after discussing with Linda that this is a much used feature. I will be putting it back in. Here's the Slack thread for that convo. |
It really was some cool work you did here @afogel. I did some extra stuff to try to get this over the line quickly, since you were busy. Very good bones here. |
awesome, thanks! So sorry I'm strapped for time now 😬 |
@afogel @schoork @elasticspoon - not sure if I ever gave the feedback here but volunteers wanted to keep the logic as is for the "show how long since a particular contact type has been contacted". Is this info what is needed to get this wrapped up? Sorry I have been so busy lately. |
Sorry, also been busy. Will take a look but pretty sure that's how I implemented it after some initial feedback |
@bcastillo32 This has the requested functionality. |
What github issue is this PR for, if any?
Resolves #5309
What changed, and why?
This code change an existing code dependency library to create a better UX when selecting contact types.
To accomplish this, I refactored an existing stimulus controller to allow for the instantiation a multi-select with option groups. The tomselect library provides all the requested functionality, though there are a few differences in UX from the figma spec (e.g., no checkboxes, once options are selected, they disappear from the dropdown options).
Though not explicitly requested in spec, the solution also provides highlighting to improve UX of search functionality.
This change also removes some custom JS (related to checkboxes) and view logic that seems unnecessary, given that this partial is only used in this form.
How will this affect user permissions?
This code change is expressly focused on view logic.
How is this tested? (please write tests!) 💖💪
Since this is a change to view logic, the best testing is either manual QA or e2e tests.
User story for manual QA:
As a volunteer, I should be able to arrive on this form page.
Selecting the dropdown should allow me to see different options, grouped by contact group type.
I should be able to select and remove multiple contact types using the mouse.
I should be able to select and remove multiple contact types using the keyboard.
When I submit this stage of the contact wizard, I should be able to return and see that the contact types have persisted (those I selected are still there).
Screenshots please :)
Feedback please? (optional)
Well scoped ticket, fun to work on. Well done!