mirror of
https://github.com/we-promise/sure.git
synced 2026-04-12 08:37:22 +00:00
* Initial account sharing changes * Update schema.rb * Update schema.rb * Change sharing UI to modal * UX fixes and sharing controls * Scope include in finances better * Update totals.rb * Update totals.rb * Scope reports to finance account scope * Update impersonation_sessions_controller_test.rb * Review fixes * Update schema.rb * Update show.html.erb * FIX db validation * Refine edit permissions * Review items * Review * Review * Add application level helper * Critical review * Address remaining review items * Fix modals * more scoping * linter * small UI fix * Fix: Sync broadcasts push unscoped balance sheet to all users * Update sync_complete_event.rb The fix removes the sidebar broadcasts (which rendered unscoped account groups using family.balance_sheet without user context) along with the now-unused sidebar_targets, account_group, and family_balance_sheet private methods. The sidebar will still update correctly — when the sync completes, Family::SyncCompleteEvent#broadcast fires family.broadcast_refresh, which triggers a morph-based page refresh for each user with their own authenticated session, rendering properly scoped sidebar content.
127 lines
5.4 KiB
Plaintext
127 lines
5.4 KiB
Plaintext
<%# locals: (transaction:, can_upload: false, can_delete: false) %>
|
|
|
|
<div id="transaction_attachments_<%= transaction.id %>" class="pb-4">
|
|
<!-- Upload Form -->
|
|
<% if can_upload && transaction.attachments.count < Transaction::MAX_ATTACHMENTS_PER_TRANSACTION %>
|
|
<%= styled_form_with url: transaction_attachments_path(transaction),
|
|
method: :post,
|
|
multipart: true,
|
|
local: true,
|
|
class: "mb-4",
|
|
data: {
|
|
controller: "attachment-upload",
|
|
attachment_upload_max_files_value: Transaction::MAX_ATTACHMENTS_PER_TRANSACTION - transaction.attachments.count,
|
|
attachment_upload_max_size_value: Transaction::MAX_ATTACHMENT_SIZE
|
|
} do |form| %>
|
|
<div class="space-y-3">
|
|
<div>
|
|
<div class="flex flex-col items-center justify-center w-full py-8 border border-secondary border-dashed rounded-xl cursor-pointer bg-surface-inset hover:bg-surface-inset-hover transition-colors text-center px-4"
|
|
data-action="click->attachment-upload#triggerFileInput">
|
|
|
|
<div data-attachment-upload-target="uploadText" class="flex flex-col items-center">
|
|
<%= icon "plus", size: "lg", class: "mb-2 text-secondary" %>
|
|
<p class="text-sm font-medium text-primary"><%= t(".browse_to_add") %></p>
|
|
</div>
|
|
|
|
<div data-attachment-upload-target="fileName" class="flex flex-col items-center hidden w-full px-2">
|
|
<%= icon "file-text", size: "lg", class: "mb-2 text-secondary" %>
|
|
<p class="text-sm font-medium text-primary truncate w-full"></p>
|
|
</div>
|
|
|
|
<%= form.file_field :attachments,
|
|
multiple: true,
|
|
accept: Transaction::ALLOWED_CONTENT_TYPES.join(","),
|
|
class: "hidden",
|
|
data: {
|
|
attachment_upload_target: "fileInput",
|
|
action: "change->attachment-upload#updateSubmitButton"
|
|
} %>
|
|
</div>
|
|
|
|
<p class="text-[10px] text-secondary mt-1 text-center">
|
|
<%= t(".select_up_to",
|
|
count: Transaction::MAX_ATTACHMENTS_PER_TRANSACTION,
|
|
size: Transaction::MAX_ATTACHMENT_SIZE / 1.megabyte,
|
|
used: transaction.attachments.count) %>
|
|
</p>
|
|
</div>
|
|
|
|
<div class="flex justify-end">
|
|
<%= render DS::Button.new(
|
|
text: t(".upload"),
|
|
variant: :primary,
|
|
size: :sm,
|
|
data: { attachment_upload_target: "submitButton" }
|
|
) %>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
<% elsif can_upload %>
|
|
<div class="p-3 mb-4 rounded-lg border border-warning bg-warning/5 flex items-start gap-3">
|
|
<%= icon "alert-circle", size: "sm", color: "warning", class: "mt-0.5" %>
|
|
<div class="text-xs text-warning leading-relaxed font-medium">
|
|
<%= t(".max_reached", count: transaction.attachments.count, max: Transaction::MAX_ATTACHMENTS_PER_TRANSACTION) %>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
|
|
<!-- Attachments List -->
|
|
<% if transaction.attachments.any? %>
|
|
<div class="space-y-2">
|
|
<h4 class="text-sm font-medium text-primary"><%= t(".files", count: transaction.attachments.count) %></h4>
|
|
<div class="space-y-2">
|
|
<% transaction.attachments.each do |attachment| %>
|
|
<div class="flex items-center justify-between p-3 border border-primary rounded-lg bg-container">
|
|
<div class="flex items-center gap-3">
|
|
<div class="flex-shrink-0">
|
|
<% if attachment.image? %>
|
|
<%= icon "image", size: "sm", color: "secondary" %>
|
|
<% else %>
|
|
<%= icon "file", size: "sm", color: "secondary" %>
|
|
<% end %>
|
|
</div>
|
|
<div class="min-w-0 flex-1">
|
|
<p class="text-sm font-medium text-primary truncate"><%= attachment.filename %></p>
|
|
<p class="text-xs text-secondary"><%= number_to_human_size(attachment.byte_size) %></p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex items-center gap-2">
|
|
<%= render DS::Link.new(
|
|
href: transaction_attachment_path(transaction, attachment, disposition: :inline),
|
|
variant: :outline,
|
|
size: :sm,
|
|
icon: "eye",
|
|
text: "",
|
|
target: "_blank"
|
|
) %>
|
|
|
|
<%= render DS::Link.new(
|
|
href: transaction_attachment_path(transaction, attachment, disposition: :attachment),
|
|
variant: :outline,
|
|
size: :sm,
|
|
icon: "download",
|
|
text: "",
|
|
data: { turbo: false }
|
|
) %>
|
|
|
|
<% if can_delete %>
|
|
<%= render DS::Button.new(
|
|
href: transaction_attachment_path(transaction, attachment),
|
|
method: :delete,
|
|
variant: :outline_destructive,
|
|
size: :sm,
|
|
icon: "trash-2",
|
|
confirm: CustomConfirm.for_resource_deletion("attachment")
|
|
) %>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
<% else %>
|
|
<p class="text-sm text-secondary"><%= t(".no_attachments") %></p>
|
|
<% end %>
|
|
</div>
|