Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 83 additions & 70 deletions app/views/organizations/_affiliation_fields.html.erb
Original file line number Diff line number Diff line change
@@ -1,83 +1,96 @@
<% if allowed_to?(:manage?, Organization) %>
<% expired = f.object.inactive? || (f.object.end_date.present? && f.object.end_date < Date.current) %>
<div data-controller="inactive-toggle">
<div class="nested-fields flex flex-wrap gap-x-4 gap-y-1 items-end mb-4 rounded-lg border p-3 <%= expired ? 'bg-gray-100 border-gray-300 opacity-60' : 'bg-white border-gray-200' %>"
<div class="nested-fields mb-4 rounded-lg border px-3 pt-3 pb-1 <%= expired ? 'bg-gray-100 border-gray-300 opacity-60' : 'bg-white border-gray-200' %>"
style="border-left: 4px solid <%= f.object.facilitator? ? '#e879f9' : '#d1d5db' %>"
<% if f.object.persisted? %>id="<%= dom_id(f.object) %>"<% end %>
data-inactive-toggle-target="row">
<div style="width: 350px; min-width: 350px; flex-shrink: 0;" data-inactive-toggle-target="profileButton">
<% if f.object.persisted? && f.object.person.present? %>
<label class="block text-sm font-medium text-gray-700 mb-1">Person</label>
<% show_email = f.object.person.profile_show_email? || allowed_to?(:manage?, Person) %>
<%= person_profile_button(f.object.person, truncate_at: 30, subtitle: (f.object.person.preferred_email if show_email)) %>
<%= f.hidden_field :person_id %>
<% else %>
<%= f.input :person_id,
include_blank: true,
required: true,
input_html: {
data: {
controller: "remote-select",
remote_select_model_value: "person"
}
},
label: "Person"
%>
<% end %>
</div>

<div class="w-full sm:w-auto" style="min-width: 200px;">
<%= f.input :title,
as: :text,
input_html: {
rows: 1,
value: f.object&.title || "Facilitator",
style: "height: 42px; min-height: 42px;",
data: {
inactive_toggle_target: "title",
action: "affiliation-dates#recalculate inactive-toggle#updateBorder"
}
} %>
</div>
<div class="flex gap-x-4 items-start">
<div class="shrink-0" style="width: 280px;" data-inactive-toggle-target="profileButton">
<% if f.object.persisted? && f.object.person.present? %>
<label class="block font-medium text-gray-700 mb-1">Person</label>
<% show_email = f.object.person.profile_show_email? || allowed_to?(:manage?, Person) %>
<%= person_profile_button(f.object.person, truncate_at: 25, subtitle: (f.object.person.preferred_email if show_email)) %>
<%= f.hidden_field :person_id %>
<% else %>
<label class="block font-medium text-gray-700 mb-1">Person <abbr>*</abbr></label>
<div class="rounded-md border border-gray-300 shadow-sm overflow-hidden" style="height: 56px;">
<%= f.input :person_id,
include_blank: true,
required: true,
wrapper_html: { class: "mb-0 h-full" },
input_html: {
class: "h-full border-0",
data: {
controller: "remote-select",
remote_select_model_value: "person"
}
},
label: false
%>
</div>
<% end %>
</div>

<div class="w-full sm:w-auto">
<%= f.input :start_date,
as: :string,
label: "Start",
input_html: {
type: "date",
value: (f.object.start_date || (Date.current unless f.object.persisted?))&.strftime("%Y-%m-%d"),
class: "rounded-md border-gray-300 focus:ring-blue-500 focus:border-blue-500 text-sm",
data: { action: "change->affiliation-dates#recalculate" }
} %>
</div>
<div class="flex-1" style="min-width: 150px;">
<%= f.input :title,
as: :text,
wrapper_html: { class: "mb-0" },
input_html: {
rows: 1,
value: f.object&.title || "Facilitator",
style: "height: 56px; min-height: 56px; padding-top: 14px;",
data: {
inactive_toggle_target: "title",
action: "affiliation-dates#recalculate inactive-toggle#updateBorder"
}
} %>
</div>

<div class="w-full sm:w-auto">
<%= f.input :end_date,
as: :string,
label: "End",
input_html: {
type: "date",
value: f.object.end_date&.strftime("%Y-%m-%d"),
class: "rounded-md border-gray-300 focus:ring-blue-500 focus:border-blue-500 text-sm",
data: {
inactive_toggle_target: "endDate",
action: "change->inactive-toggle#toggle change->affiliation-dates#recalculate"
}
} %>
</div>
<div class="shrink-0">
<%= f.input :start_date,
as: :string,
label: "Start",
wrapper_html: { class: "mb-0" },
input_html: {
type: "date",
value: (f.object.start_date || (Date.current unless f.object.persisted?))&.strftime("%Y-%m-%d"),
class: "rounded-md border-gray-300 focus:ring-blue-500 focus:border-blue-500 text-sm",
style: "height: 56px;",
data: { action: "change->affiliation-dates#recalculate" }
} %>
</div>

<div class="w-full sm:w-auto pb-3">
<label class="block text-sm font-medium text-gray-700 mb-1">Primary contact</label>
<%= f.check_box :primary_contact,
checked: f.object.primary_contact? || !f.object.persisted?,
class: "h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" %>
</div>
<div class="shrink-0">
<%= f.input :end_date,
as: :string,
label: "End",
wrapper_html: { class: "mb-0" },
input_html: {
type: "date",
value: f.object.end_date&.strftime("%Y-%m-%d"),
class: "rounded-md border-gray-300 focus:ring-blue-500 focus:border-blue-500 text-sm",
style: "height: 56px;",
data: {
inactive_toggle_target: "endDate",
action: "change->inactive-toggle#toggle change->affiliation-dates#recalculate"
}
} %>
</div>

<div class="w-full text-right admin-only">
<%= link_to_remove_association "Remove",
f,
class: "text-sm text-gray-400 hover:text-red-600 underline whitespace-nowrap admin-only bg-blue-100 rounded px-2 py-1" %>
<div class="shrink-0 whitespace-nowrap">
<label class="block font-medium text-gray-700 mb-1">Primary org contact</label>
<div class="pt-2">
<%= f.check_box :primary_contact,
checked: f.object.primary_contact? || !f.object.persisted?,
class: "h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" %>
</div>
<div class="-mb-2 text-right">
<%= link_to_remove_association "Remove",
f,
class: "text-sm text-gray-400 hover:text-red-600 underline whitespace-nowrap" %>
</div>
</div>
</div>
</div>
</div>
Expand Down
113 changes: 62 additions & 51 deletions app/views/organizations/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -102,56 +102,7 @@

<div class="rounded-lg border border-gray-200 bg-gray-50 p-4 mb-4 shadow-sm">

<% org_earliest_aff = f.object.persisted? ? f.object.affiliations.minimum(:start_date) : nil %>
<% org_aff_ended = f.object.persisted? && f.object.affiliations.any? && !f.object.affiliations.active.exists? %>
<% org_latest_end = f.object.persisted? ? f.object.affiliations.maximum(:end_date) : nil %>
<% org_end_date = org_aff_ended ? org_latest_end : f.object.end_date %>
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
<% if allowed_to?(:manage?, Organization) %>
<div class="">
<div class="shrink-0 relative group cursor-help">
<label class="inline-flex items-center gap-1 text-md font-medium text-gray-700 mb-1">
Affiliated since <i class="fa-solid fa-circle-info text-gray-400 text-xs"></i>
</label>
<div class="hidden group-hover:block absolute z-50 left-0 bottom-full mb-1 bg-blue-100 text-gray-700 text-xs rounded-lg shadow-lg ring-1 ring-blue-200 p-3 w-64 whitespace-normal">
<% if has_affiliations && org_earliest_aff.present? %>
<p>Auto-managed from affiliation records. Earliest affiliation start date: <%= org_earliest_aff.strftime('%b %Y') %>.</p>
<% if f.object.start_date.present? && f.object.start_date.beginning_of_month != org_earliest_aff.beginning_of_month %>
<p class="mt-2 text-gray-500"><i class="fa-solid fa-circle-info mr-1"></i>Organization start_date (<%= f.object.start_date.strftime('%b %Y') %>) differs from earliest affiliation.</p>
<% end %>
<% elsif has_affiliations %>
<p>Auto-managed from affiliation records.<br><br><span class="text-amber-700 font-medium">⚠ No affiliations have a start date. Add a start date to an affiliation record.</span></p>
<% else %>
<p>No affiliations yet. Set this date directly, or add affiliation records to auto-manage it.</p>
<% end %>
<% if org_aff_ended %>
<p class="mt-2 text-amber-700 font-medium">⚠ All affiliations have ended.</p>
<% elsif f.object.end_date.present? && !has_affiliations %>
<p class="mt-2 text-amber-700 font-medium">⚠ Organization end_date: <%= f.object.end_date.strftime('%b %Y') %>.</p>
<% end %>
</div>
<div class="pt-1">
<span class="text-gray-900 font-medium" data-affiliation-dates-target="affiliatedSince"><% if org_aff_ended || (f.object.end_date.present? && !has_affiliations) %><i class="fa-solid fa-circle-xmark text-red-400 mr-1" title="Affiliation ended"></i><% end %><%= (org_earliest_aff || f.object.start_date)&.strftime('%b %Y') || "—" %><%= " – #{org_end_date.strftime('%b %Y')}" if org_end_date.present? %></span>
<% if has_affiliations && org_earliest_aff.nil? %>
<i class="fa-solid fa-triangle-exclamation text-amber-500 ml-1"></i>
<% elsif f.object.start_date.present? && org_earliest_aff.present? && f.object.start_date.beginning_of_month != org_earliest_aff.beginning_of_month %>
<p class="text-xs text-gray-500 mt-1"><i class="fa-solid fa-circle-info mr-1"></i>Organization start_date: <%= f.object.start_date.strftime("%b %Y") %></p>
<% end %>
</div>
</div>
<% unless has_affiliations %>
<%= f.input :start_date,
label: false,
as: :string,
input_html: {
type: 'date',
value: f.object.start_date&.strftime('%Y-%m-%d'),
class: "block w-full rounded-md border-gray-300 shadow-sm focus:ring-blue-500 focus:border-blue-500 mt-2"
} %>
<% end %>
</div>
<% end %>

<div class="flex flex-col">
<%= f.input :agency_type,
label: "Organization Type",
Expand Down Expand Up @@ -301,8 +252,68 @@
</div>

<div class="rounded-lg border border-gray-200 <%= DomainTheme.bg_class_for(:people) %> p-4 mb-4 shadow-sm">
<% org_earliest_aff = f.object.persisted? ? f.object.affiliations.minimum(:start_date) : nil %>
<% org_aff_ended = f.object.persisted? && f.object.affiliations.any? && !f.object.affiliations.active.exists? %>
<% org_latest_end = f.object.persisted? ? f.object.affiliations.maximum(:end_date) : nil %>
<% org_end_date = org_aff_ended ? org_latest_end : f.object.end_date %>
<% org_decorated = f.object.decorate %>
<% org_fac_start = org_decorated.facilitator_since_date %>
<% org_fac_ended = org_decorated.facilitation_end_date %>
<div class="flex flex-col md:flex-row gap-6 mb-4">
<div class="shrink-0 relative group cursor-help">
<label class="inline-flex items-center gap-1 text-md font-medium text-gray-700 mb-1">
Affiliated since <i class="fa-solid fa-circle-info text-gray-400 text-xs"></i>
</label>
<div class="hidden group-hover:block absolute z-50 left-0 bottom-full mb-1 bg-blue-100 text-gray-700 text-xs rounded-lg shadow-lg ring-1 ring-blue-200 p-3 w-64 whitespace-normal">
<% if has_affiliations && org_earliest_aff.present? %>
<p>Auto-managed from affiliation records. Earliest affiliation start date: <%= org_earliest_aff.strftime('%b %Y') %>.</p>
<% if f.object.start_date.present? && f.object.start_date.beginning_of_month != org_earliest_aff.beginning_of_month %>
<p class="mt-2 text-gray-500"><i class="fa-solid fa-circle-info mr-1"></i>Organization start_date (<%= f.object.start_date.strftime('%b %Y') %>) differs from earliest affiliation.</p>
<% end %>
<% elsif has_affiliations %>
<p>Auto-managed from affiliation records.<br><br><span class="text-amber-700 font-medium">⚠ No affiliations have a start date. Add a start date to an affiliation record.</span></p>
<% else %>
<p>No affiliations yet. Set this date directly, or add affiliation records to auto-manage it.</p>
<% end %>
<% if org_aff_ended %>
<p class="mt-2 text-amber-700 font-medium">⚠ All affiliations have ended.</p>
<% elsif f.object.end_date.present? && !has_affiliations %>
<p class="mt-2 text-amber-700 font-medium">⚠ Organization end_date: <%= f.object.end_date.strftime('%b %Y') %>.</p>
<% end %>
</div>
<div class="pt-1">
<span class="text-gray-900 font-medium" data-affiliation-dates-target="affiliatedSince"><% if org_aff_ended || (f.object.end_date.present? && !has_affiliations) %><i class="fa-solid fa-circle-xmark text-red-400 mr-1" title="Affiliation ended"></i><% end %><%= (org_earliest_aff || f.object.start_date)&.strftime('%b %Y') || "—" %><%= " – #{org_end_date.strftime('%b %Y')}" if org_end_date.present? %></span>
<% if has_affiliations && org_earliest_aff.nil? %>
<i class="fa-solid fa-triangle-exclamation text-amber-500 ml-1"></i>
<% elsif f.object.start_date.present? && org_earliest_aff.present? && f.object.start_date.beginning_of_month != org_earliest_aff.beginning_of_month %>
<p class="text-xs text-gray-500 mt-1"><i class="fa-solid fa-circle-info mr-1"></i>Organization start_date: <%= f.object.start_date.strftime("%b %Y") %></p>
<% end %>
</div>
<% unless has_affiliations %>
<%= f.input :start_date,
label: false,
as: :string,
input_html: {
type: 'date',
value: f.object.start_date&.strftime('%Y-%m-%d'),
class: "block w-full rounded-md border-gray-300 shadow-sm focus:ring-blue-500 focus:border-blue-500 mt-2"
} %>
<% end %>
</div>
<div class="shrink-0 relative group cursor-help">
<label class="inline-flex items-center gap-1 text-md font-medium text-gray-700 mb-1">
Facilitations/program since <i class="fa-solid fa-circle-info text-gray-400 text-xs"></i>
</label>
<div class="hidden group-hover:block absolute z-50 left-0 bottom-full mb-1 bg-blue-100 text-gray-700 text-xs rounded-lg shadow-lg ring-1 ring-blue-200 p-3 w-64 whitespace-normal">
<p>Earliest start date from affiliations with 'facilitator' in the title. Edit affiliation records to change this date.</p>
</div>
<div class="pt-1">
<span class="text-gray-900 font-medium" data-affiliation-dates-target="facilitatorSince"><% if org_fac_ended %><i class="fa-solid fa-circle-xmark text-red-400 mr-1" title="No active facilitator affiliations"></i><% end %><%= org_fac_start&.strftime("%b %Y") || "—" %><%= " – #{org_fac_ended.strftime('%b %Y')}" if org_fac_ended %></span>
</div>
</div>
</div>
<% if allowed_to?(:manage?, Organization) %>
<div class="admin-only bg-blue-100 p-3" data-controller="paginated-fields" data-paginated-fields-per-page-value="10" data-affiliation-dates-target="affiliationsContainer">
<div class="p-3" data-controller="paginated-fields" data-paginated-fields-per-page-value="10" data-affiliation-dates-target="affiliationsContainer">
<%= f.fields_for :affiliations do |affiliation_form| %>
<div data-paginated-fields-target="item">
<%= render "affiliation_fields",
Expand All @@ -311,7 +322,7 @@
<% end %>
<div data-paginated-fields-target="nav"></div>

<div class="admin-only bg-blue-100 p-3 mt-6"><%= link_to_add_association "➕ Add Affiliation",
<div class="p-3 mt-6"><%= link_to_add_association "➕ Add Affiliation",
f,
:affiliations,
class: "btn btn-secondary-outline" %></div>
Expand Down
Loading