From 809c5546483146ec38298a767349774f20572f1e Mon Sep 17 00:00:00 2001 From: Sergio Cambra Date: Tue, 10 Dec 2024 19:16:20 +0100 Subject: [PATCH 1/3] support separators in action links --- .../stylesheets/active_scaffold_colors.scss | 7 +++++ .../stylesheets/active_scaffold_layout.css | 21 +++++++++++++ .../data_structures/action_link_separator.rb | 13 ++++++++ .../data_structures/action_links.rb | 16 +++++----- .../helpers/action_link_helpers.rb | 30 +++++++++++++++---- 5 files changed, 74 insertions(+), 13 deletions(-) create mode 100644 lib/active_scaffold/data_structures/action_link_separator.rb diff --git a/app/assets/stylesheets/active_scaffold_colors.scss b/app/assets/stylesheets/active_scaffold_colors.scss index 8f423ae122..4769c6b267 100644 --- a/app/assets/stylesheets/active_scaffold_colors.scss +++ b/app/assets/stylesheets/active_scaffold_colors.scss @@ -110,6 +110,9 @@ color: $column_color; color: $header_color; } +.active-scaffold div.actions a.separator { +border-color: $action_group_border_color; +} .active-scaffold-header div.actions a.disabled { color: $actions_disabled_color; } @@ -191,6 +194,10 @@ color: $column_empty_color; border-color: $column_actions_border_color; } +.active-scaffold tr.record td.actions table td.separator { +border-color: $column_actions_border_color; +} + .active-scaffold tr.record td.actions a.disabled { color: $actions_disabled_color; } diff --git a/app/assets/stylesheets/active_scaffold_layout.css b/app/assets/stylesheets/active_scaffold_layout.css index 8cf31bc1d8..2deebf197c 100644 --- a/app/assets/stylesheets/active_scaffold_layout.css +++ b/app/assets/stylesheets/active_scaffold_layout.css @@ -110,6 +110,12 @@ top: 14px; top: -3px; } +.active-scaffold div.actions a.separator { + border-right: 1px solid; + padding-right: 0; + padding-left: 0; +} + .active-scaffold div.actions a.disabled { opacity: 0.5; } @@ -251,6 +257,11 @@ text-align: right; padding: 0 2px; } +.active-scaffold tr.record td.actions table td.separator { + border-right: solid 1px; + padding: 0; +} + .active-scaffold tr.record td.actions a, .active-scaffold tr.record td.actions div { font-weight: bold; @@ -304,6 +315,16 @@ width: auto; text-align: left; } +.active-scaffold .actions .action_group ul li.separator { + border-top-width: 1px; + border-top-style: solid; + height: 0; +} + +.active-scaffold .actions .action_group ul li.separator + li { + border-top: none; +} + .active-scaffold .actions .action_group ul li div { margin: 0; padding: 5px 5px 5px 25px; diff --git a/lib/active_scaffold/data_structures/action_link_separator.rb b/lib/active_scaffold/data_structures/action_link_separator.rb new file mode 100644 index 0000000000..4cb0efff93 --- /dev/null +++ b/lib/active_scaffold/data_structures/action_link_separator.rb @@ -0,0 +1,13 @@ +class ActionLinkSeparator + def initialize(weight) + @weight = weight + end + + attr_reader :weight + + def ==(other) + other == :separator + end + + def name_to_cache; end # :nodoc: +end \ No newline at end of file diff --git a/lib/active_scaffold/data_structures/action_links.rb b/lib/active_scaffold/data_structures/action_links.rb index 1aa3c43d62..94e56c2ac0 100644 --- a/lib/active_scaffold/data_structures/action_links.rb +++ b/lib/active_scaffold/data_structures/action_links.rb @@ -34,6 +34,11 @@ def add(action, options = {}) end alias << add + def add_separator(weight = 0) + raise "Call add_separator on a group" if name == :root + add_to_set ActionLinkSeparator.new(weight) + end + def add_to_set(link) @set << link end @@ -51,6 +56,7 @@ def add_to_group(link, group_name = nil) def [](val) links = [] @set.each do |item| + next if item == :separator if item.is_a?(ActiveScaffold::DataStructures::ActionLinks) collected = item[val] links << collected unless collected.nil? @@ -64,6 +70,7 @@ def [](val) def find_duplicate(link) links = [] @set.each do |item| + next if item == :separator if item.is_a?(ActiveScaffold::DataStructures::ActionLinks) collected = item.find_duplicate(link) links << collected unless collected.nil? @@ -75,7 +82,8 @@ def find_duplicate(link) end def delete(val) - each(:include_set => true) do |link, set| + each(include_set: true) do |link, set| + next if link == :separator if link.action.to_s == val.to_s set.delete link break @@ -109,12 +117,6 @@ def each(options = {}, &block) end end - def collect_by_type(type = nil) - links = [] - subgroup(type).each(type) { |link| links << link } - links - end - def collect @set end diff --git a/lib/active_scaffold/helpers/action_link_helpers.rb b/lib/active_scaffold/helpers/action_link_helpers.rb index bb6a90ae29..7fd849b3fb 100644 --- a/lib/active_scaffold/helpers/action_link_helpers.rb +++ b/lib/active_scaffold/helpers/action_link_helpers.rb @@ -35,32 +35,50 @@ def display_action_links(action_links, record, options, &block) options[:level] ||= 0 options[:first_action] = true output = ActiveSupport::SafeBuffer.new + prev_link = separator = nil - action_links.each(:reverse => options.delete(:reverse), :groups => true) do |link| + action_links.each(reverse: options.delete(:reverse), groups: true) do |link| + if link == :separator + separator = true if prev_link + next + end + content = nil if link.is_a? ActiveScaffold::DataStructures::ActionLinks unless link.empty? options[:level] += 1 content = display_action_links(link, record, options, &block) options[:level] -= 1 if content.present? - output << display_action_link(link, content, record, options) + content = display_action_link(link, content, record, options) options[:first_action] = false end end elsif !skip_action_link?(link, *Array(options[:for])) authorized, reason = action_link_authorized?(link, *Array(options[:for])) next if !authorized && options[:skip_unauthorized] - output << display_action_link(link, nil, record, options.merge(:authorized => authorized, :not_authorized_reason => reason)) + + content = display_action_link(link, nil, record, options.merge(authorized: authorized, not_authorized_reason: reason)) options[:first_action] = false end + if content.present? + prev_link = true + output << display_action_link_separator(options) if separator + output << content + separator = false + end end output end + def display_action_link_separator(options) + tag = options[:level_0_tag] || :a if options[:level].zero? + content_tag(tag || :li, ' '.html_safe, class: 'separator') + end + def display_action_link(link, content, record, options) if content html_classes = hover_via_click? ? 'hover_click ' : '' - if (options[:level]).zero? + if options[:level].zero? html_classes << 'action_group' group_tag = :div else @@ -72,9 +90,9 @@ def display_action_link(link, content, record, options) end else content = render_action_link(link, record, options) - content = content_tag(:li, content, :class => ('top' if options[:first_action])) unless (options[:level]).zero? + content = content_tag(:li, content, class: ('top' if options[:first_action])) unless options[:level].zero? end - content = content_tag(options[:level_0_tag], content, options[:options_level_0_tag]) if (options[:level]).zero? && options[:level_0_tag] + content = content_tag(options[:level_0_tag], content, options[:options_level_0_tag]) if options[:level].zero? && options[:level_0_tag] content end From be71491d67e480446b9752119275fec2ef1fa592 Mon Sep 17 00:00:00 2001 From: Sergio Cambra Date: Tue, 10 Dec 2024 19:16:20 +0100 Subject: [PATCH 2/3] update changelog [skip ci] --- CHANGELOG.rdoc | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc index bb5a967bfe..2f00f49415 100644 --- a/CHANGELOG.rdoc +++ b/CHANGELOG.rdoc @@ -4,6 +4,7 @@ - Improve detection of member action links when list view is replaced with other structure, based on 'record' html class, instead of tags - Support :table position for member action links, replacing the whole table - Support changing the view partial used to render a record, default to 'list_record', better support refreshing a record when list view is replaced with other way to render records +- Support separators in action links = 3.7.10 - Move code from on_create.js.erb to partials, so it's easier to change parts, e.g. how new record is rendered From 00b17fa0dcf52cb08c5141dcacecaa3ffb3691f3 Mon Sep 17 00:00:00 2001 From: Sergio Cambra Date: Sat, 14 Dec 2024 16:48:18 +0100 Subject: [PATCH 3/3] fix rubocop offenses --- .../data_structures/action_link_separator.rb | 2 +- .../data_structures/action_links.rb | 6 +++- .../helpers/action_link_helpers.rb | 29 +++++++++---------- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/lib/active_scaffold/data_structures/action_link_separator.rb b/lib/active_scaffold/data_structures/action_link_separator.rb index 4cb0efff93..64db917263 100644 --- a/lib/active_scaffold/data_structures/action_link_separator.rb +++ b/lib/active_scaffold/data_structures/action_link_separator.rb @@ -10,4 +10,4 @@ def ==(other) end def name_to_cache; end # :nodoc: -end \ No newline at end of file +end diff --git a/lib/active_scaffold/data_structures/action_links.rb b/lib/active_scaffold/data_structures/action_links.rb index 94e56c2ac0..0bbd74fd24 100644 --- a/lib/active_scaffold/data_structures/action_links.rb +++ b/lib/active_scaffold/data_structures/action_links.rb @@ -35,7 +35,8 @@ def add(action, options = {}) alias << add def add_separator(weight = 0) - raise "Call add_separator on a group" if name == :root + raise 'Call add_separator on a group' if name == :root + add_to_set ActionLinkSeparator.new(weight) end @@ -57,6 +58,7 @@ def [](val) links = [] @set.each do |item| next if item == :separator + if item.is_a?(ActiveScaffold::DataStructures::ActionLinks) collected = item[val] links << collected unless collected.nil? @@ -71,6 +73,7 @@ def find_duplicate(link) links = [] @set.each do |item| next if item == :separator + if item.is_a?(ActiveScaffold::DataStructures::ActionLinks) collected = item.find_duplicate(link) links << collected unless collected.nil? @@ -84,6 +87,7 @@ def find_duplicate(link) def delete(val) each(include_set: true) do |link, set| next if link == :separator + if link.action.to_s == val.to_s set.delete link break diff --git a/lib/active_scaffold/helpers/action_link_helpers.rb b/lib/active_scaffold/helpers/action_link_helpers.rb index 7fd849b3fb..12e93c0702 100644 --- a/lib/active_scaffold/helpers/action_link_helpers.rb +++ b/lib/active_scaffold/helpers/action_link_helpers.rb @@ -44,15 +44,7 @@ def display_action_links(action_links, record, options, &block) end content = nil if link.is_a? ActiveScaffold::DataStructures::ActionLinks - unless link.empty? - options[:level] += 1 - content = display_action_links(link, record, options, &block) - options[:level] -= 1 - if content.present? - content = display_action_link(link, content, record, options) - options[:first_action] = false - end - end + content = display_action_link_group(link, record, options, &block) unless link.empty? elsif !skip_action_link?(link, *Array(options[:for])) authorized, reason = action_link_authorized?(link, *Array(options[:for])) next if !authorized && options[:skip_unauthorized] @@ -60,16 +52,23 @@ def display_action_links(action_links, record, options, &block) content = display_action_link(link, nil, record, options.merge(authorized: authorized, not_authorized_reason: reason)) options[:first_action] = false end - if content.present? - prev_link = true - output << display_action_link_separator(options) if separator - output << content - separator = false - end + next if content.blank? + + prev_link = true + output << display_action_link_separator(options) if separator + output << content + separator = false end output end + def display_action_link_group(link, record, options, &block) + options[:level] += 1 + content = display_action_links(link, record, options, &block) + options[:level] -= 1 + display_action_link(link, content, record, options).tap { options[:first_action] = false } if content.present? + end + def display_action_link_separator(options) tag = options[:level_0_tag] || :a if options[:level].zero? content_tag(tag || :li, ' '.html_safe, class: 'separator')