diff --git a/app/javascript/controllers/bulk_select_controller.js b/app/javascript/controllers/bulk_select_controller.js
index 271b6a0f5..97b024a82 100644
--- a/app/javascript/controllers/bulk_select_controller.js
+++ b/app/javascript/controllers/bulk_select_controller.js
@@ -138,8 +138,13 @@ export default class extends Controller {
count > 0;
if (this.hasDuplicateLinkTarget) {
- this.duplicateLinkTarget.classList.toggle("hidden", count !== 1);
- if (count === 1) {
+ const selectedRow = this._selectedRow();
+ const canDuplicate =
+ count === 1 && selectedRow?.dataset.entryType === "Transaction";
+
+ this.duplicateLinkTarget.classList.toggle("hidden", !canDuplicate);
+
+ if (canDuplicate) {
const url = new URL(
this.duplicateLinkTarget.href,
window.location.origin,
@@ -158,6 +163,14 @@ export default class extends Controller {
return this.pluralLabelValue;
}
+ _selectedRow() {
+ if (this.selectedIdsValue.length !== 1) return null;
+
+ return this.rowTargets.find(
+ (row) => row.dataset.id === this.selectedIdsValue[0],
+ );
+ }
+
_updateGroups() {
this.groupTargets.forEach((group) => {
const rows = this.rowTargets.filter(
diff --git a/app/views/entries/_selection_bar.html.erb b/app/views/entries/_selection_bar.html.erb
index 5bd4b5788..19033d78e 100644
--- a/app/views/entries/_selection_bar.html.erb
+++ b/app/views/entries/_selection_bar.html.erb
@@ -7,6 +7,17 @@
<%= turbo_frame_tag "bulk_transaction_edit_drawer" %>
+
+ <%= link_to new_transaction_path,
+ class: "p-1.5 group/duplicate hover:bg-inverse flex items-center justify-center rounded-md hidden",
+ title: t("transactions.selection_bar.duplicate"),
+ data: {
+ turbo_frame: "modal",
+ bulk_select_target: "duplicateLink"
+ } do %>
+ <%= icon "copy", class: "group-hover/duplicate:text-inverse" %>
+ <% end %>
+
<%= link_to new_transactions_bulk_update_path,
class: "p-1.5 group/edit hover:bg-inverse flex items-center justify-center rounded-md",
title: "Edit",
diff --git a/app/views/trades/_trade.html.erb b/app/views/trades/_trade.html.erb
index b14a7527c..01f690c58 100644
--- a/app/views/trades/_trade.html.erb
+++ b/app/views/trades/_trade.html.erb
@@ -10,6 +10,7 @@
class: "checkbox checkbox--light hidden lg:block",
data: {
id: entry.id,
+ entry_type: entry.entryable_type,
"bulk-select-target": "row",
action: "bulk-select#toggleRowSelection",
checkbox_toggle_target: "selectionEntry"
diff --git a/app/views/transactions/_transaction.html.erb b/app/views/transactions/_transaction.html.erb
index 8366388cb..0fa1a608c 100644
--- a/app/views/transactions/_transaction.html.erb
+++ b/app/views/transactions/_transaction.html.erb
@@ -12,6 +12,7 @@
class: "checkbox checkbox--light hidden lg:block",
data: {
id: entry.id,
+ entry_type: entry.entryable_type,
"bulk-select-target": "row",
action: "bulk-select#toggleRowSelection",
checkbox_toggle_target: "selectionEntry"
diff --git a/app/views/valuations/_valuation.html.erb b/app/views/valuations/_valuation.html.erb
index 46ca62eda..e377eda0f 100644
--- a/app/views/valuations/_valuation.html.erb
+++ b/app/views/valuations/_valuation.html.erb
@@ -11,7 +11,7 @@
<%= check_box_tag dom_id(entry, "selection"),
class: "checkbox checkbox--light hidden lg:block",
- data: { id: entry.id, "bulk-select-target": "row", action: "bulk-select#toggleRowSelection", checkbox_toggle_target: "selectionEntry" } %>
+ data: { id: entry.id, entry_type: entry.entryable_type, "bulk-select-target": "row", action: "bulk-select#toggleRowSelection", checkbox_toggle_target: "selectionEntry" } %>
<%= render DS::FilledIcon.new(icon: icon, size: "md", hex_color: color, rounded: true) %>
diff --git a/test/system/account_activity_test.rb b/test/system/account_activity_test.rb
new file mode 100644
index 000000000..5349b8b10
--- /dev/null
+++ b/test/system/account_activity_test.rb
@@ -0,0 +1,43 @@
+require "application_system_test_case"
+
+class AccountActivityTest < ApplicationSystemTestCase
+ setup do
+ sign_in users(:family_admin)
+
+ @account = accounts(:depository)
+ @transaction_entry = @account.entries.create!(
+ name: "Duplicate source",
+ date: Date.current,
+ amount: 42.50,
+ currency: "USD",
+ entryable: Transaction.new
+ )
+ @valuation_entry = @account.entries.create!(
+ name: "Current balance",
+ date: 1.day.ago.to_date,
+ amount: 1000,
+ currency: "USD",
+ entryable: Valuation.new
+ )
+ end
+
+ test "account activity shows duplicate action for a selected transaction" do
+ visit account_url(@account, tab: "activity")
+
+ find("#" + dom_id(@transaction_entry, "selection")).check
+
+ within "#entry-selection-bar" do
+ assert_selector "a[title='Duplicate']:not(.hidden)"
+ end
+ end
+
+ test "account activity hides duplicate action for a selected valuation" do
+ visit account_url(@account, tab: "activity")
+
+ find("#" + dom_id(@valuation_entry, "selection")).check
+
+ within "#entry-selection-bar" do
+ assert_selector "a[title='Duplicate'].hidden", visible: false
+ end
+ end
+end