Rende usabili i filtri destinatari e permette di eliminare le bozze email.
Le listbox non applicavano sport e altri criteri; ora i filtri sono checkbox, c'è «mai contattati» e dal cruscotto si cancellano le bozze. La lista organizzazioni allinea le colonne al foglio campagna. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
<%# locals: (name:, choices:, selected:, scroll: false) %>
|
||||
<% selected_values = Array(selected).map(&:to_s) %>
|
||||
<% box_class = scroll ? "max-h-40 space-y-0.5 overflow-y-auto rounded-lg border border-zinc-200 p-2 dark:border-zinc-700" : "space-y-0.5" %>
|
||||
<div class="<%= box_class %>">
|
||||
<%= hidden_field_tag "#{name}[]", "" %>
|
||||
<% Array(choices).each do |label, value| %>
|
||||
<label class="flex min-h-9 cursor-pointer items-center gap-2 rounded-md px-1 text-sm hover:bg-zinc-50 dark:hover:bg-zinc-800">
|
||||
<%= check_box_tag "#{name}[]", value, selected_values.include?(value.to_s), class: "size-4 shrink-0" %>
|
||||
<span><%= label %></span>
|
||||
</label>
|
||||
<% end %>
|
||||
<% if Array(choices).empty? %>
|
||||
<p class="px-1 text-xs text-zinc-500">Nessun valore in anagrafica.</p>
|
||||
<% end %>
|
||||
</div>
|
||||
@@ -0,0 +1,4 @@
|
||||
<%# locals: (mailing:, label: "Elimina bozza", extra_class: nil, form_class: nil) %>
|
||||
<%= button_to label, mailing_path(mailing), method: :delete,
|
||||
class: [btn_danger, extra_class].compact.join(" "),
|
||||
form: { class: form_class, data: { turbo_confirm: "Eliminare la bozza «#{mailing.name}»? Non si può annullare." } } %>
|
||||
@@ -6,7 +6,6 @@
|
||||
"test_b" => "Solo chi ha già Test B in scheda."
|
||||
}
|
||||
extra_parts = @filters.summary_parts.drop(1)
|
||||
compact_select = "#{input_class} h-28 py-1"
|
||||
org_open = @filters.organization_extra_active? || @open_sections.include?("organization")
|
||||
campaign_open = @filters.campaign_extra_active? || @open_sections.include?("campaign")
|
||||
history_open = @filters.history_active? || @open_sections.include?("history")
|
||||
@@ -30,7 +29,7 @@
|
||||
<section class="<%= card_class %> space-y-4 p-4 md:p-6">
|
||||
<div>
|
||||
<h2 class="text-base font-semibold">Chi deve ricevere questa email?</h2>
|
||||
<p class="mt-1 text-sm text-zinc-500">Tre cose bastano: lista di partenza, sport, regione. Il resto è opzionale.</p>
|
||||
<p class="mt-1 text-sm text-zinc-500">Lista di partenza, sport, regione e chi non ha mai ricevuto una email. Il resto è opzionale.</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@@ -39,19 +38,25 @@
|
||||
<p class="mt-1 text-xs text-zinc-500"><%= preset_hints[@filters.preset] %></p>
|
||||
</div>
|
||||
|
||||
<label class="flex min-h-11 cursor-pointer items-start gap-3 text-sm">
|
||||
<%= hidden_field_tag "filters[never_contacted]", "0" %>
|
||||
<%= check_box_tag "filters[never_contacted]", "1", @filters.history_kind == "never", class: "mt-1 size-5 shrink-0" %>
|
||||
<span>
|
||||
<span class="font-medium">Solo mai contattati</span>
|
||||
<span class="mt-0.5 block text-xs text-zinc-500">Nessuna email di campagna inviata dal CRM, né in questa né in altre liste.</span>
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<div class="grid gap-4 md:grid-cols-2">
|
||||
<div>
|
||||
<label class="mb-1 block text-sm font-medium">Sport</label>
|
||||
<%= hidden_field_tag "filters[sports][]", "" %>
|
||||
<%= select_tag "filters[sports][]", options_for_select(@sport_options, @filters["sports"]),
|
||||
multiple: true, size: 5, class: compact_select %>
|
||||
<p class="mt-1 text-xs text-zinc-500">Vuoto = tutti gli sport. Tieni premuto Ctrl o Cmd per più valori.</p>
|
||||
<%= render "mailings/audience_choices", name: "filters[sports]",
|
||||
choices: @sport_options.map { |sport| [sport, sport] }, selected: @filters["sports"] %>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1 block text-sm font-medium">Regione</label>
|
||||
<%= hidden_field_tag "filters[regions][]", "" %>
|
||||
<%= select_tag "filters[regions][]", options_for_select(@region_options, @filters["regions"]),
|
||||
multiple: true, size: 5, class: compact_select %>
|
||||
<%= render "mailings/audience_choices", name: "filters[regions]",
|
||||
choices: @region_options.map { |region| [region, region] }, selected: @filters["regions"], scroll: true %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -74,27 +79,23 @@
|
||||
<div class="grid gap-4 md:grid-cols-2">
|
||||
<div>
|
||||
<label class="mb-1 block text-sm font-medium">M/F</label>
|
||||
<%= hidden_field_tag "filters[team_genders][]", "" %>
|
||||
<%= select_tag "filters[team_genders][]", options_for_select(Catalog::TEAM_GENDERS.map { |k, v| [v, k] }, @filters["team_genders"]),
|
||||
multiple: true, size: 3, class: compact_select %>
|
||||
<%= render "mailings/audience_choices", name: "filters[team_genders]",
|
||||
choices: Catalog::TEAM_GENDERS.map { |k, v| [v, k] }, selected: @filters["team_genders"] %>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1 block text-sm font-medium">Provincia</label>
|
||||
<%= hidden_field_tag "filters[provinces][]", "" %>
|
||||
<%= select_tag "filters[provinces][]", options_for_select(@province_options, @filters["provinces"]),
|
||||
multiple: true, size: 4, class: compact_select %>
|
||||
<%= render "mailings/audience_choices", name: "filters[provinces]",
|
||||
choices: @province_options.map { |province| [province, province] }, selected: @filters["provinces"], scroll: true %>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1 block text-sm font-medium">Streaming</label>
|
||||
<%= hidden_field_tag "filters[streaming_statuses][]", "" %>
|
||||
<%= select_tag "filters[streaming_statuses][]", options_for_select(Catalog::STREAMING_STATUSES.map { |k, v| [v, k] }, @filters["streaming_statuses"]),
|
||||
multiple: true, size: 4, class: compact_select %>
|
||||
<%= render "mailings/audience_choices", name: "filters[streaming_statuses]",
|
||||
choices: Catalog::STREAMING_STATUSES.map { |k, v| [v, k] }, selected: @filters["streaming_statuses"] %>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1 block text-sm font-medium">Stato organizzazione</label>
|
||||
<%= hidden_field_tag "filters[statuses][]", "" %>
|
||||
<%= select_tag "filters[statuses][]", options_for_select(Catalog::ORGANIZATION_STATUSES.map { |k, v| [v, k] }, @filters["statuses"]),
|
||||
multiple: true, size: 4, class: compact_select %>
|
||||
<%= render "mailings/audience_choices", name: "filters[statuses]",
|
||||
choices: Catalog::ORGANIZATION_STATUSES.map { |k, v| [v, k] }, selected: @filters["statuses"] %>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1 block text-sm font-medium">N. lista da</label>
|
||||
@@ -117,22 +118,19 @@
|
||||
<div class="grid gap-4 md:grid-cols-2">
|
||||
<div>
|
||||
<label class="mb-1 block text-sm font-medium">Stato invio campagna</label>
|
||||
<%= hidden_field_tag "filters[send_statuses][]", "" %>
|
||||
<%= select_tag "filters[send_statuses][]", options_for_select(Catalog::SEND_STATUSES.map { |k, v| [v, k] }, @filters["send_statuses"]),
|
||||
multiple: true, size: 3, class: compact_select %>
|
||||
<%= render "mailings/audience_choices", name: "filters[send_statuses]",
|
||||
choices: Catalog::SEND_STATUSES.map { |k, v| [v, k] }, selected: @filters["send_statuses"] %>
|
||||
<p class="mt-1 text-xs text-zinc-500">Serve soprattutto se la lista di partenza è «tutte».</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1 block text-sm font-medium">Test A/B in scheda</label>
|
||||
<%= hidden_field_tag "filters[ab_variants][]", "" %>
|
||||
<%= select_tag "filters[ab_variants][]", options_for_select(Catalog::AB_VARIANTS.map { |k, v| [v, k] }, @filters["ab_variants"]),
|
||||
multiple: true, size: 2, class: compact_select %>
|
||||
<%= render "mailings/audience_choices", name: "filters[ab_variants]",
|
||||
choices: Catalog::AB_VARIANTS.map { |k, v| [v, k] }, selected: @filters["ab_variants"] %>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1 block text-sm font-medium">Stage pipeline</label>
|
||||
<%= hidden_field_tag "filters[pipeline_stages][]", "" %>
|
||||
<%= select_tag "filters[pipeline_stages][]", options_for_select(Catalog::PIPELINE_STAGES.map { |k, v| [v, k] }, @filters["pipeline_stages"]),
|
||||
multiple: true, size: 5, class: compact_select %>
|
||||
<%= render "mailings/audience_choices", name: "filters[pipeline_stages]",
|
||||
choices: Catalog::PIPELINE_STAGES.map { |k, v| [v, k] }, selected: @filters["pipeline_stages"] %>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1 block text-sm font-medium">Valore stimato</label>
|
||||
@@ -144,7 +142,7 @@
|
||||
<%= render layout: "mailings/audience_disclosure", locals: {
|
||||
name: "history",
|
||||
title: "Storico email",
|
||||
hint: "Chi ha già ricevuto o aperto una campagna",
|
||||
hint: "Ricevute, aperte o invii recenti (i mai contattati stanno sopra)",
|
||||
open: history_open,
|
||||
count: @filters.history_active? ? 1 : 0
|
||||
} do %>
|
||||
@@ -153,13 +151,12 @@
|
||||
<label class="mb-1 block text-sm font-medium">Criterio</label>
|
||||
<%= select_tag "filters[history_kind]", options_for_select([
|
||||
["Nessun filtro storico", ""],
|
||||
["Mai ricevuta una campagna", "never"],
|
||||
["Ha ricevuto questa campagna", "received"],
|
||||
["Non ha ricevuto questa campagna", "not_received"],
|
||||
["Ha aperto questa campagna", "opened"],
|
||||
["Ha ricevuto ma non aperto questa campagna", "not_opened"],
|
||||
["Inviata negli ultimi N giorni", "recent"]
|
||||
], @filters.history_kind), class: input_class %>
|
||||
], @filters.history_kind == "never" ? "" : @filters.history_kind), class: input_class %>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1 block text-sm font-medium">Campagna</label>
|
||||
@@ -188,17 +185,15 @@
|
||||
</label>
|
||||
<div>
|
||||
<label class="mb-1 block text-sm font-medium">Chi ha già ricevuto</label>
|
||||
<%= hidden_field_tag "filters[exclude_received_mailing_ids][]", "" %>
|
||||
<%= select_tag "filters[exclude_received_mailing_ids][]",
|
||||
options_from_collection_for_select(@history_mailings, :id, :name, @filters["exclude_received_mailing_ids"]),
|
||||
multiple: true, size: 4, class: compact_select %>
|
||||
<%= render "mailings/audience_choices", name: "filters[exclude_received_mailing_ids]",
|
||||
choices: @history_mailings.map { |mailing| [mailing.name, mailing.id] },
|
||||
selected: @filters["exclude_received_mailing_ids"], scroll: true %>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1 block text-sm font-medium">Chi ha aperto</label>
|
||||
<%= hidden_field_tag "filters[exclude_opened_mailing_ids][]", "" %>
|
||||
<%= select_tag "filters[exclude_opened_mailing_ids][]",
|
||||
options_from_collection_for_select(@history_mailings, :id, :name, @filters["exclude_opened_mailing_ids"]),
|
||||
multiple: true, size: 4, class: compact_select %>
|
||||
<%= render "mailings/audience_choices", name: "filters[exclude_opened_mailing_ids]",
|
||||
choices: @history_mailings.map { |mailing| [mailing.name, mailing.id] },
|
||||
selected: @filters["exclude_opened_mailing_ids"], scroll: true %>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1 block text-sm font-medium">Chi ha ricevuto qualcosa negli ultimi N giorni</label>
|
||||
|
||||
@@ -63,22 +63,29 @@
|
||||
<% else %>
|
||||
<div class="divide-y divide-zinc-100 dark:divide-zinc-800 md:hidden">
|
||||
<% @mailings.each do |mailing| %>
|
||||
<%= link_to mailing, class: "block p-4 active:bg-zinc-50 dark:active:bg-zinc-800" do %>
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div class="min-w-0">
|
||||
<div class="font-semibold"><%= mailing.name %></div>
|
||||
<div class="mt-0.5 text-xs text-zinc-500 break-anywhere"><%= mailing.mail_identity.from_email %></div>
|
||||
<div class="p-4">
|
||||
<%= link_to mailing, class: "block active:bg-zinc-50 dark:active:bg-zinc-800" do %>
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div class="min-w-0">
|
||||
<div class="font-semibold"><%= mailing.name %></div>
|
||||
<div class="mt-0.5 text-xs text-zinc-500 break-anywhere"><%= mailing.mail_identity.from_email %></div>
|
||||
</div>
|
||||
<%= mailing_status_badge(mailing.status) %>
|
||||
</div>
|
||||
<%= mailing_status_badge(mailing.status) %>
|
||||
</div>
|
||||
<div class="mt-3"><%= progress_bar(mailing.progress_percentage) %></div>
|
||||
<div class="mt-2 text-xs text-zinc-500">
|
||||
<%= mailing.sent_count %> inviate · <%= mailing.opened_count %> aperte · <%= mailing.pending_count %> in coda
|
||||
<% if mailing.sending? && mailing.next_send_at.present? && mailing.next_send_at > Time.current %>
|
||||
· Riparte <%= l(mailing.next_send_at, format: :short) %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="mt-3"><%= progress_bar(mailing.progress_percentage) %></div>
|
||||
<div class="mt-2 text-xs text-zinc-500">
|
||||
<%= mailing.sent_count %> inviate · <%= mailing.opened_count %> aperte · <%= mailing.pending_count %> in coda
|
||||
<% if mailing.sending? && mailing.next_send_at.present? && mailing.next_send_at > Time.current %>
|
||||
· Riparte <%= l(mailing.next_send_at, format: :short) %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if mailing.draft? %>
|
||||
<div class="mt-3">
|
||||
<%= render "mailings/delete_draft_button", mailing: mailing, extra_class: "w-full" %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="hidden md:block">
|
||||
@@ -90,6 +97,7 @@
|
||||
<th class="px-4 py-3">Avanzamento</th>
|
||||
<th class="px-4 py-3">Stato</th>
|
||||
<th class="px-4 py-3">Prossimo / creato</th>
|
||||
<th class="px-4 py-3"><span class="sr-only">Azioni</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-zinc-100 dark:divide-zinc-800">
|
||||
@@ -128,6 +136,11 @@
|
||||
<%= format_dt(mailing.created_at) %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<% if mailing.draft? %>
|
||||
<%= render "mailings/delete_draft_button", mailing: mailing, label: "Elimina", extra_class: "text-sm", form_class: "inline" %>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
<%= link_to "Modifica contenuto", edit_mailing_path(@mailing), class: btn_secondary %>
|
||||
<%= link_to "Raffina destinatari", audience_mailing_path(@mailing), class: btn_secondary %>
|
||||
<%= button_to "Rigenera lista", refresh_recipients_mailing_path(@mailing), method: :post, class: btn_secondary %>
|
||||
<%= render "mailings/delete_draft_button", mailing: @mailing, extra_class: "flex-1 sm:flex-none" %>
|
||||
<% elsif @mailing.sending? %>
|
||||
<%= button_to "Ferma invio", cancel_mailing_path(@mailing), method: :post,
|
||||
class: btn_danger,
|
||||
@@ -333,9 +334,7 @@
|
||||
<% end %>
|
||||
|
||||
<% if @mailing.draft? %>
|
||||
<%= button_to "Elimina bozza", mailing_path(@mailing), method: :delete,
|
||||
class: btn_danger,
|
||||
form: { data: { turbo_confirm: "Eliminare questa bozza?" } } %>
|
||||
<%= render "mailings/delete_draft_button", mailing: @mailing %>
|
||||
<% end %>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
</div>
|
||||
<%= opp ? stage_badge(opp.pipeline_stage) : nil %>
|
||||
</div>
|
||||
<div class="mt-1 break-anywhere text-xs text-zinc-500"><%= org.email.presence || "—" %></div>
|
||||
<div class="mt-2 flex flex-wrap items-center gap-2 text-xs text-zinc-500">
|
||||
<%= streaming_badge(org.streaming_status) %>
|
||||
<% if opp&.ab_variant.present? %><%= ab_variant_badge(opp.ab_variant) %><% end %>
|
||||
@@ -63,31 +64,52 @@
|
||||
<table class="min-w-full divide-y divide-zinc-100 dark:divide-zinc-800 text-sm">
|
||||
<thead class="bg-zinc-50 text-left text-xs uppercase tracking-wide text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400">
|
||||
<tr>
|
||||
<th class="px-4 py-3">N.</th>
|
||||
<th class="px-4 py-3">Organizzazione</th>
|
||||
<th class="px-4 py-3">Regione</th>
|
||||
<th class="px-4 py-3">M/F</th>
|
||||
<th class="px-4 py-3">Streaming</th>
|
||||
<th class="px-4 py-3">Test</th>
|
||||
<th class="px-4 py-3">Stage</th>
|
||||
<th class="px-4 py-3">Invio</th>
|
||||
<th class="px-3 py-3">N.</th>
|
||||
<th class="px-3 py-3">Regione</th>
|
||||
<th class="px-3 py-3">Prov.</th>
|
||||
<th class="px-3 py-3">Società</th>
|
||||
<th class="px-3 py-3">M/F</th>
|
||||
<th class="px-3 py-3">Email verificata</th>
|
||||
<th class="px-3 py-3">Sito / profilo</th>
|
||||
<th class="px-3 py-3">Streaming rilevato</th>
|
||||
<th class="px-3 py-3">Evidenza / fit commerciale</th>
|
||||
<th class="px-3 py-3">Test A/B</th>
|
||||
<th class="px-3 py-3">Stato invio</th>
|
||||
<th class="px-3 py-3">Data invio</th>
|
||||
<th class="px-3 py-3">Esito</th>
|
||||
<th class="px-3 py-3">Demo / Trial</th>
|
||||
<th class="px-3 py-3">Conversione</th>
|
||||
<th class="px-3 py-3">Piano</th>
|
||||
<th class="px-3 py-3">Fonte contatto / ricerca</th>
|
||||
<th class="px-3 py-3">Data verifica</th>
|
||||
<th class="px-3 py-3">Note follow-up</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-zinc-100 dark:divide-zinc-800">
|
||||
<% @organizations.each do |org| %>
|
||||
<% opp = org.campaign_opportunity(current_project) %>
|
||||
<tr class="hover:bg-zinc-50 dark:hover:bg-zinc-800/80">
|
||||
<td class="px-4 py-3 tabular-nums text-zinc-500"><%= org.list_position || "—" %></td>
|
||||
<td class="px-4 py-3">
|
||||
<td class="whitespace-nowrap px-3 py-3 tabular-nums text-zinc-500"><%= org.list_position || "—" %></td>
|
||||
<td class="whitespace-nowrap px-3 py-3"><%= org.region.presence || "—" %></td>
|
||||
<td class="whitespace-nowrap px-3 py-3"><%= org.province.presence || "—" %></td>
|
||||
<td class="px-3 py-3">
|
||||
<%= link_to org.name, org, class: "font-medium text-zinc-900 hover:underline dark:text-zinc-100" %>
|
||||
<div class="text-xs text-slate-500"><%= org.email.presence || org.organization_type_label %></div>
|
||||
</td>
|
||||
<td class="px-4 py-3"><%= [org.region, org.province].compact_blank.join(" · ").presence || "—" %></td>
|
||||
<td class="px-4 py-3"><%= org.team_gender_label.presence || "—" %></td>
|
||||
<td class="px-4 py-3"><%= streaming_badge(org.streaming_status) || "—" %></td>
|
||||
<% opp = org.campaign_opportunity(current_project) %>
|
||||
<td class="px-4 py-3"><%= opp&.ab_variant.presence || "—" %></td>
|
||||
<td class="px-4 py-3"><%= opp ? stage_badge(opp.pipeline_stage) : "—" %></td>
|
||||
<td class="px-4 py-3"><%= opp&.send_status_label.presence || "—" %></td>
|
||||
<td class="whitespace-nowrap px-3 py-3"><%= org.team_gender_label.presence || "—" %></td>
|
||||
<td class="px-3 py-3"><%= mailto_link(org.email, class: "text-sky-700 hover:underline dark:text-sky-400") %></td>
|
||||
<td class="px-3 py-3"><%= external_link(org.website, class: "text-sky-700 hover:underline dark:text-sky-400") %></td>
|
||||
<td class="whitespace-nowrap px-3 py-3"><%= streaming_badge(org.streaming_status) || "—" %></td>
|
||||
<td class="px-3 py-3 text-zinc-600 dark:text-zinc-300"><%= table_clip(org.commercial_fit) %></td>
|
||||
<td class="px-3 py-3"><%= opp&.ab_variant.present? ? ab_variant_badge(opp.ab_variant) : "—" %></td>
|
||||
<td class="whitespace-nowrap px-3 py-3"><%= opp&.send_status_label.presence || "—" %></td>
|
||||
<td class="whitespace-nowrap px-3 py-3"><%= format_date(opp&.sent_on) %></td>
|
||||
<td class="px-3 py-3"><%= table_clip(opp&.outcome, length: 24) %></td>
|
||||
<td class="whitespace-nowrap px-3 py-3"><%= opp ? yes_no(opp.demo_trial) : "—" %></td>
|
||||
<td class="whitespace-nowrap px-3 py-3"><%= opp ? yes_no(opp.converted) : "—" %></td>
|
||||
<td class="whitespace-nowrap px-3 py-3"><%= opp&.product.presence || "—" %></td>
|
||||
<td class="px-3 py-3"><%= external_link(org.source_url, class: "text-sky-700 hover:underline dark:text-sky-400") %></td>
|
||||
<td class="whitespace-nowrap px-3 py-3"><%= format_date(org.verified_at) %></td>
|
||||
<td class="px-3 py-3 text-zinc-600 dark:text-zinc-300"><%= table_clip(org.notes) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
|
||||
Reference in New Issue
Block a user