web47core 3.2.3.7 → 3.2.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 89a0f833ce0b5b96eaeaf2aeffc63a7547d932f86df19e58d615c552f8ae014e
4
- data.tar.gz: 662d682b7c1726d92f97e88a9e063b227a96254d144e871858eb81caf5862c67
3
+ metadata.gz: 502b3b8f2eb2041c496b5fdab4579cd3578d05e436bfaa0cd840da47d30079d2
4
+ data.tar.gz: 64cd85383fbceeaf7fc82488c23df1d7098708c6e043ddf2f595cca16452b1f5
5
5
  SHA512:
6
- metadata.gz: b74804a97ed0727a0924555f968f8ebb918e3e25287fafa78a3bb18937e1f6ad287e0d1bb0313a87b5aa5a14d7a2b1557a061c3c599f381ed3491401e504586b
7
- data.tar.gz: 55074be6de0e97db6a89a02c57230c2c527cecd4a2fb688d84d2c05478076a7761e844d77c823151b5387228a93a444995694830c6f015458fda2517cf6a1350
6
+ metadata.gz: 23373514688cdf82da7b5a34048abf1b96753bd543b3084b27e3cba57466062b6d99bf59360b97d78f5754bb5fba0bdf888f682fcd84efe552230cb7e20f73fc
7
+ data.tar.gz: e0a3d35a324e193f61b1db5b1dfe769dba57ae40743c295082ece2f8f37112f93849b0d299f00c03c1cae98ca01ca3a29aa08ea484a998dce35b2729f4f451bd
@@ -0,0 +1,82 @@
1
+
2
+ class CardNavBuilder
3
+ include ActionView::Helpers::TagHelper
4
+ include SvgIconHelper
5
+
6
+ def initialize(obj, current_ability, show_text: true, view_context: nil)
7
+ @obj = obj
8
+ @show_text = show_text
9
+ @current_ability = current_ability
10
+ @view_context = view_context
11
+ end
12
+
13
+ def restart_link(path, confirm: nil, title: 'Restart')
14
+ return unless can?(:edit, @obj)
15
+
16
+ confirm ||= "Are you sure you want to #{title.downcase} this #{@obj.class_title}?"
17
+ item_link(path, title, :replay, confirm: confirm)
18
+ end
19
+
20
+ def synchronize_link(path, title: 'Sync', icon_name: :sync)
21
+ return unless can?(:edit, @obj)
22
+
23
+ item_link(path, title, icon_name)
24
+ end
25
+
26
+ def action_link(path, title: 'Action', icon_name: :play, method: :get, confirm: nil)
27
+ return unless can?(:read, @obj)
28
+
29
+ item_link(path, title, icon_name, confirm: confirm, method: method)
30
+ end
31
+
32
+ def info_link( path, title: 'Info', icon_name: :info, method: :get)
33
+ return unless can?(:read, @obj)
34
+
35
+ item_link(path, title, icon_name, method: method)
36
+ end
37
+
38
+ def edit_link(path, title: 'Edit')
39
+ return unless can?(:edit, @obj)
40
+
41
+ item_link(path, title, :edit)
42
+ end
43
+
44
+ def create_link(path, title: 'Add', icon_name: :add)
45
+ return unless can?(:create, @obj)
46
+
47
+ item_link(path, title, icon_name)
48
+ end
49
+
50
+ def delete_link(path, confirm: nil, title: 'Delete')
51
+ return unless can?(:manage, @obj)
52
+
53
+ confirm ||= "Are you sure you want to delete this #{@obj.class_title}?"
54
+ item_link(path, title, :delete, confirm: confirm, method: :delete, btn_class: 'text-danger')
55
+ end
56
+
57
+ private
58
+
59
+ def can?(action, obj)
60
+ @current_ability.can?(action, obj)
61
+ end
62
+
63
+ # @abstract The work horse for the card nav item
64
+ # @param [String] path - The path/URL for the action
65
+ # @param [String] title - The title of the action
66
+ # @param [String, Symbol] icon_name - Name of the icon to render
67
+ # @param [String] confirm - If the action requires confirmation before completing
68
+ # @param [String, Symbol] method - The HTTP method to use for the link, default is :get
69
+ # @param [String] btn_class - The class of button that should be used, btn-primary is the default
70
+ # @return HTML - The HTML for the given tag
71
+ def item_link(path, title, icon_name, confirm: nil, method: :get, btn_class: '')
72
+ data = { method: method, bs_toggle: :tooltip, placement: :bottom }
73
+ data[:confirm] = confirm if confirm.present?
74
+
75
+ @view_context.content_tag(:a, href: path, class: "btn #{btn_class}", data: data, title: title) do
76
+ parts = []
77
+ parts << @view_context.svg_icon(icon_name, classes: [])
78
+ parts << @view_context.content_tag(:span, class: 'ms-2 d-none d-md-inline') { title } if @show_text
79
+ @view_context.safe_join(parts)
80
+ end
81
+ end
82
+ end
@@ -1,88 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+
3
4
  #
4
5
  # Help with nav items at the top of cards
5
6
  #
6
7
  module CoreCardNavItemsHelper
7
8
  # @abstract Yield the main block for card nav items
8
- def card_nav_items(&block)
9
- content_tag(:ul, class: 'nav nav-pills float-end') do
10
- yield block
11
- end
12
- end
13
-
14
- # @abstract Link to the jobs icon
15
- # @return HTML - The HTML for the given tag
16
- def jobs_nav_link(obj, path, title: 'Jobs')
17
- return unless can?(:view, obj)
18
-
19
- card_nav_item_link(path, title, 'stack-overflow')
20
- end
21
-
22
- # @abstract Link to the jobs icon
23
- # @return HTML - The HTML for the given tag
24
- def current_job_nav_link(obj, path, title: 'Current')
25
- return unless can?(:view, obj)
26
-
27
- card_nav_item_link(path, title, 'run')
28
- end
29
-
30
- # @abstract Link to the jobs icon
31
- # @return HTML - The HTML for the given tag
32
- def start_job_nav_link(obj, path, title: 'Start', confirm: nil)
33
- return unless can?(:view, obj)
34
-
35
- confirm ||= "Are you sure you want to start this #{obj.class_title} job?"
36
- card_nav_item_link(path, title, :play, btn_class: 'btn-success', confirm: confirm, method: :post)
37
- end
38
-
39
- # @abstract Link to restart, replay a given object
40
- # @param [Object] obj - The object to operate on, for permission checks
41
- # @param [String] path - The path/URL for the action
42
- # @param [String] confirm - Override the default confirmation
43
- # @param [String] title - Override the default title of the button
44
- # @return HTML - The HTML for the given tag
45
- def restart_nav_link(obj, path, confirm: nil, title: 'Restart')
46
- return unless can?(:edit, obj)
47
-
48
- confirm ||= "Are you sure you want to restart this #{obj.class_title}?"
49
- card_nav_item_link(path, title, :replay, confirm: confirm)
50
- end
51
-
52
- def edit_nav_link(obj, path, title: 'Edit')
53
- return unless can?(:edit, obj)
54
-
55
- card_nav_item_link(path, title, 'edit')
56
- end
57
-
58
- # @abstract Link to delete an object
59
- # @return HTML - The HTML for the given tag
60
- def delete_nav_link(obj, path, confirm: nil, title: 'Delete')
61
- return unless can?(:manage, obj)
62
-
63
- confirm ||= "Are you sure you want to delete this #{obj.class_title}?"
64
- card_nav_item_link(path, title, :delete, confirm: confirm, method: :delete, btn_class: 'btn-danger')
65
- end
66
-
67
- # @abstract The work horse for the card nav item
68
- # @param [String] path - The path/URL for the action
69
- # @param [String] title - The title of the action
70
- # @param [String, Symbol] icon_name - Name of the icon to render
71
- # @param [String] confirm - If the action requires confirmation before completing
72
- # @param [String|Symbol] method - The HTTP method to use for the link, default is :get
73
- # @param [String] btn_class - The class of button that should be used, btn-primary is the default
74
- # @return HTML - The HTML for the given tag
75
- def card_nav_item_link(path, title, icon_name, confirm: nil, method: :get, btn_class: 'btn-primary')
76
- data = { method: method, turbo_method: method }
77
- if confirm.present?
78
- data[:confirm] = confirm
79
- data[:turbo_confirm] = confirm
80
- end
81
- content_tag(:li, class: 'nav-item me-2') do
82
- link_to path, class: "#{btn_class} btn nav-link active", data: data do
83
- concat(svg_icon(icon_name, classes: ['me-2']))
84
- concat(content_tag(:span, class: 'd-none d-md-inline') { title })
85
- end
9
+ def card_nav_items(obj, title: 'Card Actions', show_text: true, &block)
10
+ builder = CardNavBuilder.new(obj, current_ability, show_text: show_text, view_context: self)
11
+ content_tag(:div, class: 'btn-group', role: :group, aria: { label: title }) do
12
+ capture builder, &block
86
13
  end
87
14
  end
88
15
  end
@@ -14,11 +14,7 @@ module SvgIconHelper
14
14
  def fetch_svg_icon(name, size: 24, type: :outline, classes: [], color: 'currentColor', stroke_width: 2)
15
15
  return if name.blank?
16
16
 
17
- classes = if size <= 24
18
- ['icon', classes].flatten.compact.join(' ')
19
- else
20
- classes.compact.flatten.join(' ')
21
- end
17
+ classes = classes.compact.flatten.join(' ')
22
18
  key = "icon_partial_path:#{name}:#{type}"
23
19
  (partial, stroke) = Rails.cache.fetch(key, expires_in: SystemConfiguration.long_cache) do
24
20
  preferred_path = I18n.exists?("nav.icons.#{name}") ? 'icons/' + I18n.t("nav.icons.#{name}") : "icons/#{type}/#{name}"
@@ -4,16 +4,11 @@
4
4
  .card-title
5
5
  %h4=t('.title')
6
6
  .btn-list
7
- - if can?(:manage, Delayed::Backend::Mongoid::Job)
8
- %a.btn.bg-warning{href: class_action_path(:destroy_all, failed_only:true), title: t('.destroy_failed'), data: {bs_toggle: :tooltip, confirm: t('.confirm_destroy_failed')} }
9
- =svg_icon(:trash, classes: %w(text-white))
10
- %a.btn.bg-danger{href: class_action_path(:destroy_all, failed_only:false), title: t('.destroy_all'), data: {bs_toggle: :tooltip, confirm: t('.confirm_destroy_all')} }
11
- =svg_icon(:trash, classes: %w(text-white))
12
- - if can?(:update, Delayed::Backend::Mongoid::Job)
13
- %a.btn.bg-warning{href: class_action_path(:resubmit_all, failed_only:true), title: t('.resubmit_failed'), data: {bs_toggle: :tooltip, confirm: t('.confirm_resubmit_failed')} }
14
- =svg_icon(:repeat, classes: %w(text-white))
15
- %a.btn.bg-danger{href: class_action_path(:resubmit_all, failed_only:false), title: t('.resubmit_all'), data: {bs_toggle: :tooltip, confirm: t('.confirm_resubmit_all')} }
16
- =svg_icon(:repeat, classes: %w(text-white))
7
+ = card_nav_items(Delayed::Backend::Mongoid::Job) do |nav|
8
+ =nav.delete_link(class_action_path(:destroy_all, failed_only:true), title: t('.destroy_failed'), confirm: t('.confirm_destroy_failed'))
9
+ =nav.delete_link(class_action_path(:destroy_all, failed_only:false), title: t('.destroy_all'), confirm: t('.confirm_destroy_all'))
10
+ =nav.restart_link(class_action_path(:resubmit_all, failed_only:true), title: t('.resubmit_failed'), confirm: t('.confirm_resubmit_failed'))
11
+ =nav.restart_link(class_action_path(:resubmit_all, failed_only:false), title: t('.resubmit_all'), confirm: t('.confirm_resubmit_all'))
17
12
 
18
13
  .card-body
19
14
  .table-responsive.text-no-wrap
@@ -4,9 +4,9 @@
4
4
  .card
5
5
  .card-header
6
6
  %h3.float-start=t('.title')
7
- = card_nav_items do
8
- = delete_nav_link(@delayed_job, delayed_job_path(@delayed_job))
9
- = restart_nav_link(@delayed_job, resubmit_delayed_job_path(@delayed_job))
7
+ = card_nav_items(@delayed_job) do |nav|
8
+ = nav.delete_link(delayed_job_path(@delayed_job))
9
+ = nav.restart_link(resubmit_delayed_job_path(@delayed_job))
10
10
  .card-body
11
11
  .table-responsive
12
12
  %table.table.card-table.border.table-stripped
@@ -1,10 +1,14 @@
1
1
  - title SystemConfiguration.environment.titleize
2
- = multiple_floating_action_button do
3
- = edit_floating_action_link(SystemConfiguration.configuration, edit_system_configurations_path)
4
- = refresh_floating_action_link(SystemConfiguration.configuration, sync_system_configurations_path)
5
2
  .card
3
+ .card-header.d-flex.justify-content-between
4
+ .card-title System Configuration
5
+ = card_nav_items(SystemConfiguration) do |nav|
6
+ =nav.edit_link(edit_system_configurations_path)
7
+ - if SystemConfiguration.switchboard_configured?
8
+ =nav.synchronize_link(sync_system_configurations_path)
9
+
6
10
  .card-body
7
- .table-responsive
11
+ .table-responsive.text-no-wrap
8
12
  %table.table.border.table-hover.table-vcenter.datatable.card-table.no-wrap.responsive
9
13
  %thead
10
14
  %tr
@@ -50,6 +50,7 @@ en:
50
50
  icons:
51
51
  copy_icon: outline/copy
52
52
  copy_success: filled/circle-check
53
+ check: filled/circle-check
53
54
  copy_error: filled/bug
54
55
  dead: outline/skull
55
56
  running: outline/treadmill
@@ -86,7 +87,13 @@ en:
86
87
  cron: outline/alarm
87
88
  cron_servers: outline/server
88
89
  cron_tabs: outline/calendar-clock
90
+ system_configuration: outline/adjustments-horizontal
91
+ sso_servers: outline/login-2
89
92
  accounts: outline/buildings
93
+ sync: outline/refresh
94
+ edit: outline/edit
95
+ team: outline/users-group
96
+ logout: outline/logout-2
90
97
  system_configurations:
91
98
  show:
92
99
  title: "%{name} System Configuration"
@@ -129,12 +136,12 @@ en:
129
136
  delayed_jobs:
130
137
  index:
131
138
  title: "Delayed Jobs"
132
- resubmit_all: Resubmit All Jobs
133
- resubmit_failed: Resubmit Failed Jobs
139
+ resubmit_all: Resubmit All
140
+ resubmit_failed: Resubmit Failed
134
141
  confirm_resubmit_all: Are you sure you want to resubmit all jobs?
135
142
  confirm_resubmit_failed: Are you sure you want to resbmit failed jobs?
136
- destroy_all: Destroy All Jobs
137
- destroy_failed: Destroy Failed Jobs
143
+ destroy_all: Destroy All
144
+ destroy_failed: Destroy Failed
138
145
  confirm_destroy_all: Are you sure you want to destroy all jobs?
139
146
  confirm_destroy_failed: Are you sure you want to destroy failed jobs?
140
147
  no_data_found: "No Delayed Jobs found"
@@ -169,4 +176,4 @@ en:
169
176
  status: Status
170
177
  pid: PID
171
178
  running: Running?
172
- alive: Alive?
179
+ alive: Alive?
@@ -1,10 +1,6 @@
1
- # frozen_string_literal: true
2
-
3
- require 'simplecov'
1
+ require "simplecov"
4
2
  require 'simplecov_lcov_formatter'
5
3
 
6
- # Load up the files in the workspace and merge or collate them together.
7
- # This should kick out a single coverage file out
8
4
  SimpleCov::Formatter::LcovFormatter.config do |c|
9
5
  c.single_report_path = 'coverage/final.lcov'
10
6
  c.report_with_single_file = true
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Web47core
4
- VERSION = '3.2.3.7'
4
+ VERSION = '3.2.3.9'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: web47core
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.3.7
4
+ version: 3.2.3.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Schroeder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-09-09 00:00:00.000000000 Z
11
+ date: 2025-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -526,15 +526,12 @@ extra_rdoc_files: []
526
526
  files:
527
527
  - LICENSE
528
528
  - README.md
529
- - app/assets/config/manifest.js
530
529
  - app/assets/images/1x1.png
531
- - app/assets/javascript/clipboard.coffee
532
- - app/assets/javascript/flash.coffee
533
- - app/assets/stylesheets/clipboard.scss
534
530
  - app/controllers/errors_controller.rb
535
531
  - app/controllers/exceptions_controller.rb
536
532
  - app/controllers/notifications_controller.rb
537
533
  - app/controllers/status_controller.rb
534
+ - app/helpers/card_nav_builder.rb
538
535
  - app/helpers/core_application_helper.rb
539
536
  - app/helpers/core_avatar_helper.rb
540
537
  - app/helpers/core_breadcrumb_helper.rb
@@ -1,3 +0,0 @@
1
- //= link ../stylesheets .scss
2
- //= link ../javascript .coffee
3
- //= link ../images .png
@@ -1,34 +0,0 @@
1
- #
2
- # Enable copy capability to the machines copy/paste buffer
3
- #
4
- $(document).ready ->
5
- if clipboardEnabled()
6
- $('a.copy').on 'click', (e) ->
7
- node = e.target
8
- textField = document.createElement('textarea')
9
- node.parentNode.insertBefore(textField, node)
10
- try
11
- textField.innerText = $(this).data('clipboard-text')
12
- textField.select()
13
- textField.focus()
14
- if document.execCommand('copy')
15
- M.toast({html: 'Copied!'}, 3000);
16
- else
17
- M.toast({html: 'Unable to copy text'}, 3000);
18
- catch error
19
- M.toast({html: 'Unable to copy text'}, 3000);
20
- finally
21
- textField.parentNode.removeChild(textField)
22
-
23
- else
24
- $('.copy').hide()
25
-
26
- #
27
- # Test that we can issue the execCommand for copy and that it returns
28
- #
29
- clipboardEnabled = ->
30
- try
31
- document.execCommand('copy')
32
- true
33
- catch error
34
- false
@@ -1,6 +0,0 @@
1
- #
2
- # Transform the flash message to toast messages
3
- #
4
- $(document).ready ->
5
- $('.flash .message').each ->
6
- M.toast(html: $(this).html())
@@ -1,13 +0,0 @@
1
- .clipboard {
2
- margin: 0 0 0 2px;
3
- padding: 0;
4
- span {
5
- font-size: 1rem;
6
- }
7
- a.copy {
8
- i.material-icons {
9
- i.material-icons;
10
- font-size: 1rem;
11
- }
12
- }
13
- }