active_scaffold 4.3.2 → 4.4.0
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 +4 -4
- data/CHANGELOG.rdoc +19 -0
- data/README.md +1 -1
- data/app/assets/javascripts/active_scaffold/active_scaffold.js +98 -11
- data/app/assets/javascripts/active_scaffold/draggable_lists.js +4 -3
- data/app/assets/javascripts/active_scaffold/load.js +20 -5
- data/app/assets/stylesheets/active_scaffold/_images.scss +53 -1
- data/app/assets/stylesheets/active_scaffold/_layout.scss +1 -66
- data/app/views/active_scaffold_overrides/_add_existing_form.html.erb +17 -11
- data/app/views/active_scaffold_overrides/_base_form.html.erb +29 -19
- data/app/views/active_scaffold_overrides/_field_search.html.erb +9 -9
- data/app/views/active_scaffold_overrides/_field_search_columns.html.erb +29 -33
- data/app/views/active_scaffold_overrides/_form.html.erb +43 -34
- data/app/views/active_scaffold_overrides/_form_association.html.erb +3 -3
- data/app/views/active_scaffold_overrides/_form_association_footer.html.erb +20 -16
- data/app/views/active_scaffold_overrides/_form_association_record.html.erb +3 -4
- data/app/views/active_scaffold_overrides/_horizontal_subform_header.html.erb +2 -1
- data/app/views/active_scaffold_overrides/_list.html.erb +6 -4
- data/app/views/active_scaffold_overrides/_list_calculations.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_list_header.html.erb +3 -3
- data/app/views/active_scaffold_overrides/_list_messages.html.erb +19 -19
- data/app/views/active_scaffold_overrides/_list_messages_content.html.erb +5 -5
- data/app/views/active_scaffold_overrides/_list_pagination.html.erb +7 -5
- data/app/views/active_scaffold_overrides/_list_pagination_links.html.erb +5 -3
- data/app/views/active_scaffold_overrides/_list_record.html.erb +13 -8
- data/app/views/active_scaffold_overrides/_list_with_header.html.erb +8 -8
- data/app/views/active_scaffold_overrides/_messages.html.erb +3 -3
- data/app/views/active_scaffold_overrides/_render_field.js.erb +8 -11
- data/app/views/active_scaffold_overrides/_search.html.erb +7 -6
- data/app/views/active_scaffold_overrides/_show.html.erb +4 -4
- data/app/views/active_scaffold_overrides/_show_actions.html.erb +2 -2
- data/app/views/active_scaffold_overrides/_show_columns.html.erb +28 -30
- data/app/views/active_scaffold_overrides/add_existing.js.erb +7 -4
- data/app/views/active_scaffold_overrides/render_field.js.erb +1 -1
- data/config/locales/de.yml +2 -1
- data/config/locales/en.yml +33 -32
- data/config/locales/es.yml +15 -14
- data/config/locales/fr.yml +3 -2
- data/config/locales/hu.yml +3 -2
- data/config/locales/ja.yml +2 -1
- data/config/locales/ro.yml +169 -0
- data/config/locales/ru.yml +8 -7
- data/config/locales/ta.yml +7 -6
- data/config/locales/zh_Hans.yml +14 -13
- data/lib/active_scaffold/actions/common_search.rb +1 -14
- data/lib/active_scaffold/actions/core.rb +55 -16
- data/lib/active_scaffold/actions/field_search.rb +2 -2
- data/lib/active_scaffold/actions/list.rb +35 -13
- data/lib/active_scaffold/actions/nested.rb +31 -7
- data/lib/active_scaffold/actions/show.rb +1 -1
- data/lib/active_scaffold/active_record_permissions.rb +1 -1
- data/lib/active_scaffold/attribute_params.rb +2 -1
- data/lib/active_scaffold/bridges/date_picker/helper.rb +14 -0
- data/lib/active_scaffold/bridges/date_picker.rb +10 -0
- data/lib/active_scaffold/config/list.rb +10 -1
- data/lib/active_scaffold/core.rb +9 -6
- data/lib/active_scaffold/data_structures/action_columns.rb +2 -0
- data/lib/active_scaffold/data_structures/column.rb +27 -6
- data/lib/active_scaffold/data_structures/filter.rb +4 -0
- data/lib/active_scaffold/data_structures/nested_info.rb +8 -1
- data/lib/active_scaffold/data_structures/sorting.rb +1 -1
- data/lib/active_scaffold/extensions/action_view_rendering.rb +1 -1
- data/lib/active_scaffold/finder.rb +66 -21
- data/lib/active_scaffold/helpers/action_link_helpers.rb +43 -18
- data/lib/active_scaffold/helpers/assets_helpers.rb +4 -4
- data/lib/active_scaffold/helpers/filter_helpers.rb +3 -3
- data/lib/active_scaffold/helpers/form_column_helpers.rb +34 -22
- data/lib/active_scaffold/helpers/form_ui_helpers.rb +15 -10
- data/lib/active_scaffold/helpers/framework_ui_helpers.rb +22 -0
- data/lib/active_scaffold/helpers/human_condition_helpers.rb +1 -0
- data/lib/active_scaffold/helpers/list_column_helpers.rb +19 -0
- data/lib/active_scaffold/helpers/pagination_helpers.rb +28 -7
- data/lib/active_scaffold/helpers/search_column_helpers.rb +32 -5
- data/lib/active_scaffold/helpers/tabs_helpers.rb +3 -5
- data/lib/active_scaffold/helpers/view_helpers.rb +12 -0
- data/lib/active_scaffold/tableless.rb +11 -8
- data/lib/active_scaffold/version.rb +2 -2
- data/lib/active_scaffold.rb +169 -0
- data/lib/tasks/bundle.rake +2 -1
- data/lib/tasks/mock_app.rake +43 -0
- metadata +20 -7
- data/shoulda_macros/macros.rb +0 -145
|
@@ -431,6 +431,24 @@ module ActiveScaffold
|
|
|
431
431
|
data
|
|
432
432
|
end
|
|
433
433
|
|
|
434
|
+
def local_sorting?
|
|
435
|
+
@page&.pager&.number_of_pages == 1 && active_scaffold_config.list.local_sorting
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
def column_sort_value(record, column)
|
|
439
|
+
value = record.send(column.name)
|
|
440
|
+
return if value.nil?
|
|
441
|
+
|
|
442
|
+
case column.column.type
|
|
443
|
+
when :time, :datetime, Time then value.to_i
|
|
444
|
+
when :boolean then value ? 1 : 0
|
|
445
|
+
when :binary then nil
|
|
446
|
+
when :integer then value
|
|
447
|
+
when :float, :decimal then (value % 1).zero? ? value.to_i : value
|
|
448
|
+
else value.to_s
|
|
449
|
+
end
|
|
450
|
+
end
|
|
451
|
+
|
|
434
452
|
# MARK
|
|
435
453
|
|
|
436
454
|
def all_marked?
|
|
@@ -465,6 +483,7 @@ module ActiveScaffold
|
|
|
465
483
|
elsif column.inplace_edit
|
|
466
484
|
tag_options[:data] = inplace_edit_data(column)
|
|
467
485
|
end
|
|
486
|
+
|
|
468
487
|
content_tag(:th, column_heading_value(column, sorting, sort_direction) + inplace_edit_control(column), tag_options)
|
|
469
488
|
end
|
|
470
489
|
|
|
@@ -3,8 +3,13 @@
|
|
|
3
3
|
module ActiveScaffold
|
|
4
4
|
module Helpers
|
|
5
5
|
module PaginationHelpers
|
|
6
|
-
def pagination_ajax_link(page_number, url_options, options)
|
|
7
|
-
|
|
6
|
+
def pagination_ajax_link(page_number, url_options, options, text: nil)
|
|
7
|
+
attributes = as_element_attributes(
|
|
8
|
+
:pagination_link,
|
|
9
|
+
proc_options: {page_number: page_number, text: text},
|
|
10
|
+
**options.smart_merge(class: 'as_paginate')
|
|
11
|
+
)
|
|
12
|
+
link_to text ? as_(text) : page_number, url_options.merge(page: page_number), attributes
|
|
8
13
|
end
|
|
9
14
|
|
|
10
15
|
def pagination_url_options(url_options = nil)
|
|
@@ -17,6 +22,22 @@ module ActiveScaffold
|
|
|
17
22
|
url_options
|
|
18
23
|
end
|
|
19
24
|
|
|
25
|
+
def pagination_active_page(page_number, url_options, options)
|
|
26
|
+
attributes = options.slice(:id, :class).smart_merge(class: 'as_paginate current')
|
|
27
|
+
as_element :pagination_active_page, page_number,
|
|
28
|
+
proc_options: {page_number: page_number}, **attributes
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def pagination_gap(options)
|
|
32
|
+
'..'
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Wraps the complete pagination sequence, including previous and next links.
|
|
36
|
+
# UI adapters may override this method and call +super+ to add nested markup.
|
|
37
|
+
def pagination_html(&)
|
|
38
|
+
capture(&)
|
|
39
|
+
end
|
|
40
|
+
|
|
20
41
|
def pagination_ajax_links(current_page, url_options, options, inner_window, outer_window)
|
|
21
42
|
start_number = current_page.number - inner_window
|
|
22
43
|
end_number = current_page.number + inner_window
|
|
@@ -42,16 +63,16 @@ module ActiveScaffold
|
|
|
42
63
|
page = current_page.number - offset
|
|
43
64
|
next unless page < start_number && page > last_page
|
|
44
65
|
|
|
45
|
-
html <<
|
|
66
|
+
html << pagination_gap(options) if page > last_page + 1
|
|
46
67
|
html << pagination_ajax_link(page, url_options, options)
|
|
47
68
|
last_page = page
|
|
48
69
|
end
|
|
49
70
|
end
|
|
50
|
-
html <<
|
|
71
|
+
html << pagination_gap(options) if start_number > last_page + 1
|
|
51
72
|
|
|
52
73
|
[start_number, last_page + 1].max.upto(end_number) do |num|
|
|
53
74
|
html << if current_page.number == num
|
|
54
|
-
|
|
75
|
+
pagination_active_page(num, url_options, options)
|
|
55
76
|
else
|
|
56
77
|
pagination_ajax_link(num, url_options, options)
|
|
57
78
|
end
|
|
@@ -59,10 +80,10 @@ module ActiveScaffold
|
|
|
59
80
|
|
|
60
81
|
if current_page.pager.infinite?
|
|
61
82
|
offsets.each do |offset|
|
|
62
|
-
html <<
|
|
83
|
+
html << pagination_gap(options) << pagination_ajax_link(current_page.number + offset, url_options, options)
|
|
63
84
|
end
|
|
64
85
|
else
|
|
65
|
-
html <<
|
|
86
|
+
html << pagination_gap(options) unless end_number >= current_page.pager.last.number - outer_window - 1
|
|
66
87
|
[end_number + 1, current_page.pager.last.number - outer_window].max.upto(current_page.pager.last.number) do |num|
|
|
67
88
|
html << pagination_ajax_link(num, url_options, options)
|
|
68
89
|
end
|
|
@@ -50,14 +50,29 @@ module ActiveScaffold
|
|
|
50
50
|
|
|
51
51
|
# the standard active scaffold options used for class, name and scope
|
|
52
52
|
def active_scaffold_search_options(column)
|
|
53
|
-
|
|
53
|
+
attributes = {
|
|
54
|
+
name: "search[#{column.name}]",
|
|
55
|
+
class: "#{column.name}-input",
|
|
56
|
+
id: "search_#{column.name}",
|
|
57
|
+
value: field_search_params[column.name.to_s]
|
|
58
|
+
}
|
|
59
|
+
as_element_attributes(:search_control, proc_options: {column: column, search_ui: column.search_ui}, **attributes)
|
|
54
60
|
end
|
|
55
61
|
|
|
56
62
|
def search_attribute(column, record)
|
|
57
63
|
column_options = active_scaffold_search_options(column).merge(object: record)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
64
|
+
search_attribute_html(
|
|
65
|
+
column,
|
|
66
|
+
label_tag(search_label_for(column, column_options), search_column_label(column, record)),
|
|
67
|
+
active_scaffold_search_for(column, column_options)
|
|
68
|
+
)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def search_attribute_html(column, label, field)
|
|
72
|
+
context = {column: column}
|
|
73
|
+
as_element :search_attribute, proc_options: context do
|
|
74
|
+
as_element(:search_attribute_label, label, proc_options: context) <<
|
|
75
|
+
as_element(:search_attribute_field, field, proc_options: context)
|
|
61
76
|
end
|
|
62
77
|
end
|
|
63
78
|
|
|
@@ -156,7 +171,7 @@ module ActiveScaffold
|
|
|
156
171
|
select_options << [as_(:true), true] # rubocop:disable Lint/BooleanSymbol
|
|
157
172
|
select_options << [as_(:false), false] # rubocop:disable Lint/BooleanSymbol
|
|
158
173
|
|
|
159
|
-
select_tag(options[:name], options_for_select(select_options, ActiveScaffold::Core.column_type_cast(options[:value], column.column)), id: options[:id])
|
|
174
|
+
select_tag(options[:name], options_for_select(select_options, ActiveScaffold::Core.column_type_cast(options[:value], column.column, column.model)), id: options[:id])
|
|
160
175
|
end
|
|
161
176
|
# we can't use checkbox ui because it's not possible to decide whether search for this field or not
|
|
162
177
|
alias active_scaffold_search_checkbox active_scaffold_search_boolean
|
|
@@ -296,6 +311,7 @@ module ActiveScaffold
|
|
|
296
311
|
def active_scaffold_search_timestamp(column, options, ui_options: column.options)
|
|
297
312
|
active_scaffold_search_datetime(column, options, ui_options: ui_options, field_ui: :datetime)
|
|
298
313
|
end
|
|
314
|
+
alias active_scaffold_search_timestamptz active_scaffold_search_timestamp
|
|
299
315
|
|
|
300
316
|
def active_scaffold_search_time(column, options, ui_options: column.options)
|
|
301
317
|
active_scaffold_search_datetime(column, options, ui_options: ui_options, field_ui: :time)
|
|
@@ -425,6 +441,17 @@ module ActiveScaffold
|
|
|
425
441
|
[visibles, hiddens]
|
|
426
442
|
end
|
|
427
443
|
|
|
444
|
+
def render_field_search_column(column, record)
|
|
445
|
+
column_css_class = column.css_class unless column.css_class.is_a?(Proc)
|
|
446
|
+
if column.respond_to? :each_column
|
|
447
|
+
as_element :field_search_subsection, class: column_css_class do
|
|
448
|
+
render_subsection column, record, nil, :field_search, partial: 'field_search_columns'
|
|
449
|
+
end
|
|
450
|
+
else
|
|
451
|
+
as_element :field_search_element, search_attribute(column, record), class: "form-element #{column_css_class}"
|
|
452
|
+
end
|
|
453
|
+
end
|
|
454
|
+
|
|
428
455
|
def searched_by?(column)
|
|
429
456
|
value = field_search_params[column.name.to_s]
|
|
430
457
|
case value
|
|
@@ -10,7 +10,7 @@ module ActiveScaffold
|
|
|
10
10
|
tab_options = send(override_helper_per_model(:active_scaffold_tab_options, record.class), column, record)
|
|
11
11
|
used_tabs = send(override_helper_per_model(:active_scaffold_current_tabs, record.class), column, record, tab_options)
|
|
12
12
|
input_helper = override_helper_per_model(:active_scaffold_input_for_tabbed, record.class)
|
|
13
|
-
send(input_helper, column, record, subsection_id, tab_options, used_tabs.map
|
|
13
|
+
send(input_helper, column, record, subsection_id, tab_options, used_tabs.map { |v, _| v }) <<
|
|
14
14
|
active_scaffold_refresh_link(nil, {'data-update_url' => url_for(add_tab_url)}, record, refresh_opts) <<
|
|
15
15
|
active_scaffold_tabs_for(column, record, subsection_id, tab_options, used_tabs, &)
|
|
16
16
|
end
|
|
@@ -32,8 +32,6 @@ module ActiveScaffold
|
|
|
32
32
|
tab_values = record.send(col.name).map(&tabbed_by).compact
|
|
33
33
|
if tabbed_by_association(col, tabbed_by)
|
|
34
34
|
tab_values.map! { |value| [value, value.id.to_s] }
|
|
35
|
-
else
|
|
36
|
-
tab_values.map! { |value| [tab_options.find { |_, tab_value, _| value == tab_value }&.first || value, value] }
|
|
37
35
|
end
|
|
38
36
|
used_choices.merge tab_values
|
|
39
37
|
end
|
|
@@ -41,7 +39,7 @@ module ActiveScaffold
|
|
|
41
39
|
end
|
|
42
40
|
|
|
43
41
|
def active_scaffold_tab_options(column, record)
|
|
44
|
-
subform_column = column.first
|
|
42
|
+
subform_column = column.visible_columns.first
|
|
45
43
|
if subform_column
|
|
46
44
|
tabbed_by = subform_column.options[:tabbed_by] || column.tabbed_by
|
|
47
45
|
if tabbed_by_association(subform_column, tabbed_by)
|
|
@@ -51,7 +49,7 @@ module ActiveScaffold
|
|
|
51
49
|
end
|
|
52
50
|
if tab_column
|
|
53
51
|
label_method = (tab_column.form_ui_options || tab_column.options)[:label_method] || :to_label
|
|
54
|
-
helper_method = association_helper_method(
|
|
52
|
+
helper_method = association_helper_method(tab_column.association, :sorted_association_options_find)
|
|
55
53
|
send(helper_method, tab_column.association, nil, subform_record).map do |opt_record|
|
|
56
54
|
[opt_record.send(label_method), opt_record.id, opt_record]
|
|
57
55
|
end
|
|
@@ -18,6 +18,7 @@ module ActiveScaffold
|
|
|
18
18
|
include ActiveScaffold::Helpers::SearchColumnHelpers
|
|
19
19
|
include ActiveScaffold::Helpers::HumanConditionHelpers
|
|
20
20
|
include ActiveScaffold::Helpers::FilterHelpers
|
|
21
|
+
include ActiveScaffold::Helpers::FrameworkUiHelpers
|
|
21
22
|
|
|
22
23
|
##
|
|
23
24
|
## Delegates
|
|
@@ -31,6 +32,12 @@ module ActiveScaffold
|
|
|
31
32
|
## Uncategorized
|
|
32
33
|
##
|
|
33
34
|
|
|
35
|
+
# UI adapters may override this method and call +super+ to wrap the table,
|
|
36
|
+
# for example in a responsive-table container.
|
|
37
|
+
def list_table_html(&)
|
|
38
|
+
capture(&)
|
|
39
|
+
end
|
|
40
|
+
|
|
34
41
|
def handle_exception_on_column(exception, column, record = nil)
|
|
35
42
|
raise exception if exception.instance_variable_get(:@_active_scaffold_wrapped)
|
|
36
43
|
|
|
@@ -126,6 +133,7 @@ module ActiveScaffold
|
|
|
126
133
|
def column_heading_class(column, sorting)
|
|
127
134
|
classes = "#{column.name}-column_heading "
|
|
128
135
|
classes << "sorted #{sorting.direction_of(column).downcase} " if sorting.sorts_on? column
|
|
136
|
+
classes << 'skip-local-sorting' if column.skip_local_sorting?
|
|
129
137
|
classes << column.css_class unless column.css_class.nil? || column.css_class.is_a?(Proc)
|
|
130
138
|
classes
|
|
131
139
|
end
|
|
@@ -140,6 +148,10 @@ module ActiveScaffold
|
|
|
140
148
|
params[:eid] ? {eid: id_from_controller(params[:eid])} : {}
|
|
141
149
|
end
|
|
142
150
|
|
|
151
|
+
def server_error_msg(content = nil, **attributes, &)
|
|
152
|
+
as_element :server_error, content, **attributes, &
|
|
153
|
+
end
|
|
154
|
+
|
|
143
155
|
def column_empty?(column_value)
|
|
144
156
|
@_empty_values ||= [' ', empty_field_text].compact
|
|
145
157
|
empty = column_value.nil?
|
|
@@ -24,16 +24,19 @@ class ActiveScaffold::Tableless < ActiveRecord::Base
|
|
|
24
24
|
|
|
25
25
|
class Column < ActiveRecord::ConnectionAdapters::Column
|
|
26
26
|
def initialize(name, default, type, null = true, *, **) # rubocop:disable Style/OptionalBooleanParameter,Metrics/ParameterLists
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
connection = ActiveRecord::Base.connection
|
|
28
|
+
sql_type = type.is_a?(Symbol) ? connection.type_to_sql(type) : type.to_s
|
|
29
|
+
cast_type = connection.send(:lookup_cast_type, sql_type)
|
|
30
|
+
metadata = ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(
|
|
31
|
+
sql_type: sql_type,
|
|
32
|
+
type: cast_type.type,
|
|
33
|
+
limit: cast_type.limit,
|
|
34
|
+
precision: cast_type.precision,
|
|
35
|
+
scale: cast_type.scale
|
|
36
|
+
)
|
|
37
|
+
if ActiveRecord.version >= Gem::Version.new('8.1')
|
|
34
38
|
super(name, cast_type, default, metadata, null, *, **)
|
|
35
39
|
else
|
|
36
|
-
metadata = ActiveRecord::Base.connection.send :fetch_type_metadata, type.to_s
|
|
37
40
|
super(name, default, metadata, null, *, **)
|
|
38
41
|
end
|
|
39
42
|
end
|
data/lib/active_scaffold.rb
CHANGED
|
@@ -58,6 +58,174 @@ module ActiveScaffold
|
|
|
58
58
|
mattr_accessor :javascripts, instance_writer: false
|
|
59
59
|
self.javascripts = []
|
|
60
60
|
|
|
61
|
+
# A way to define the tags and html attributes used in different places.
|
|
62
|
+
# Changing the class or replacing the attributes may break the default AS stylesheets, but not JS or functionality.
|
|
63
|
+
#
|
|
64
|
+
# The keys in the hash are the names used by ActiveScaffold to identify the
|
|
65
|
+
# elements.
|
|
66
|
+
# The values are a hash of attributes used to create the markup, supporting the following keys:
|
|
67
|
+
# * The :tag key can be used to specify a different tag name for the element.
|
|
68
|
+
# * The :attributes key can be used to specify additional html attributes.
|
|
69
|
+
# * The :proc key can be used to specify a method to dinamically return the tag and attributes hash, as an array.
|
|
70
|
+
# When :proc is present, :tag and :attributes won't be used. The proc will receive an options hash, which usually
|
|
71
|
+
# will be a hash with html attributes, but in some cases may have other options:
|
|
72
|
+
# * For :action_link_group the hash will have keys such as :level, :first_action, and other options supported by
|
|
73
|
+
# +display_action_links+
|
|
74
|
+
# * For :action_link_separator the hash will have keys such as :level, :level_0_tag, and other options supported by
|
|
75
|
+
# +display_action_links+
|
|
76
|
+
# * Form and search elements receive the column and the configured UI in the options hash.
|
|
77
|
+
# * Action link elements receive the link, record, rendering options, and authorized state.
|
|
78
|
+
# * Pagination elements receive the page number and, for links, the optional text key.
|
|
79
|
+
# Some keys don't have a :tag key, because only attributes are used, the tag is hardcoded, usually elements that are
|
|
80
|
+
# rendered as a form or table, or a table's element (thead, tbody, tr, td, th, tfoot, etc.). For those elements,
|
|
81
|
+
# the :tag key will be ignored if it's set, so the tag can't be changed.
|
|
82
|
+
mattr_reader :ui_elements
|
|
83
|
+
@@ui_elements ||= {
|
|
84
|
+
list: {tag: :div},
|
|
85
|
+
list_header: {tag: :div},
|
|
86
|
+
list_title: {tag: :h2},
|
|
87
|
+
list_actions: {tag: :div},
|
|
88
|
+
filters: {tag: :div, attributes: {class: 'filters'}},
|
|
89
|
+
before_header_table: {tag: :table},
|
|
90
|
+
list_content: {tag: :div},
|
|
91
|
+
list_table: {}, # table
|
|
92
|
+
list_table_head: {}, # thead
|
|
93
|
+
list_table_head_row: {}, # tr
|
|
94
|
+
list_records: {}, # tbody
|
|
95
|
+
list_messages: {attributes: {class: 'messages'}}, # tbody
|
|
96
|
+
list_messages_container: {}, # td
|
|
97
|
+
list_action_messages: {tag: :div},
|
|
98
|
+
filtered_message: {tag: :div, attributes: {class: 'filtered-message'}},
|
|
99
|
+
applied_filters_message: {tag: :div, attributes: {class: 'filtered-message applied-filters'}},
|
|
100
|
+
empty_message: {tag: :p},
|
|
101
|
+
message_reset: {tag: :div, attributes: {class: 'reset'}},
|
|
102
|
+
message_close: {tag: :a, attributes: {href: '#', class: 'close'}},
|
|
103
|
+
server_error: {tag: :p, attributes: {class: 'error-message message server-error'}},
|
|
104
|
+
info_message: {tag: :div, attributes: {class: 'info-message message'}},
|
|
105
|
+
warning_message: {tag: :div, attributes: {class: 'warning-message message'}},
|
|
106
|
+
error_message: {tag: :div, attributes: {class: 'error-message message'}},
|
|
107
|
+
list_footer: {tag: :div, attributes: {class: 'active-scaffold-footer'}},
|
|
108
|
+
list_found: {tag: :div},
|
|
109
|
+
list_found_count: {tag: :span},
|
|
110
|
+
list_calculations: {}, # tr
|
|
111
|
+
pagination_links: {tag: :div},
|
|
112
|
+
pagination_link: {}, # a
|
|
113
|
+
pagination_active_page: {tag: :span},
|
|
114
|
+
record_actions_cell: {}, # td
|
|
115
|
+
record_action_links: {}, # table
|
|
116
|
+
action_link_group: {
|
|
117
|
+
proc: lambda do |options|
|
|
118
|
+
if options[:level]&.zero?
|
|
119
|
+
tag = :div
|
|
120
|
+
attributes = {class: 'action_group'}
|
|
121
|
+
else
|
|
122
|
+
tag = :li
|
|
123
|
+
attributes = {class: ('top' if options[:first_action]).to_s}
|
|
124
|
+
end
|
|
125
|
+
attributes[:class] += ' hover_click' if hover_via_click?
|
|
126
|
+
[tag, attributes]
|
|
127
|
+
end
|
|
128
|
+
},
|
|
129
|
+
action_link_separator: {
|
|
130
|
+
proc: lambda do |options|
|
|
131
|
+
tag = options[:level_0_tag] || :a if options[:level]&.zero?
|
|
132
|
+
[tag || :li, {class: 'separator'}]
|
|
133
|
+
end
|
|
134
|
+
},
|
|
135
|
+
action_link_group_title: {tag: :div},
|
|
136
|
+
action_link_group_content: {tag: :ul},
|
|
137
|
+
action_link: {}, # a
|
|
138
|
+
action_link_item: {tag: :li},
|
|
139
|
+
dynamic_action_group: {tag: :ul, attributes: {class: 'dynamic-menu'}},
|
|
140
|
+
dynamic_action_group_element: {tag: :li},
|
|
141
|
+
search_form: {}, # form
|
|
142
|
+
search_field: {attributes: {class: 'text-input', size: 50, autocomplete: :off}}, # input type=search
|
|
143
|
+
search_control: {}, # input, select or textarea
|
|
144
|
+
search_submit: {attributes: {class: 'submit'}}, # input type=submit
|
|
145
|
+
search_reset: {attributes: {class: 'reset'}}, # a
|
|
146
|
+
field_search_form: {}, # form
|
|
147
|
+
field_search_fields_columns: {tag: :div, attributes: {class: 'form-columns'}},
|
|
148
|
+
field_search_fields_container: {tag: :ol},
|
|
149
|
+
field_search_subsection: {tag: :li, attributes: {class: 'sub-section'}},
|
|
150
|
+
field_search_element: {tag: :li},
|
|
151
|
+
field_search_submit: {attributes: {class: 'submit'}}, # input type=submit
|
|
152
|
+
field_search_reset: {attributes: {class: 'reset'}}, # a
|
|
153
|
+
field_search_footer: {tag: :p},
|
|
154
|
+
form: {}, # form
|
|
155
|
+
form_title: {tag: :h4},
|
|
156
|
+
form_messages_container: {tag: :div},
|
|
157
|
+
form_fields_columns: {tag: :div, attributes: {class: 'form-columns'}},
|
|
158
|
+
fields_container: {tag: :ol},
|
|
159
|
+
form_subsection: {tag: :li, attributes: {class: 'sub-section'}},
|
|
160
|
+
form_subsection_header: {tag: :h5},
|
|
161
|
+
subform: {tag: :li},
|
|
162
|
+
subform_header: {tag: :h5},
|
|
163
|
+
subform_footer: {tag: :div, attributes: {class: 'footer'}},
|
|
164
|
+
subform_record_remove: {}, # a
|
|
165
|
+
subform_record_remove_reason: {tag: :span, attributes: {class: 'destroy reason'}},
|
|
166
|
+
subform_create_another: {}, # a
|
|
167
|
+
subform_replace_with_new: {}, # a
|
|
168
|
+
subform_add_existing: {}, # a
|
|
169
|
+
form_element: {tag: :li},
|
|
170
|
+
form_attribute: {tag: :dl},
|
|
171
|
+
form_attribute_label: {tag: :dt},
|
|
172
|
+
form_attribute_field: {tag: :dd},
|
|
173
|
+
search_attribute: {tag: :dl},
|
|
174
|
+
search_attribute_label: {tag: :dt},
|
|
175
|
+
search_attribute_field: {tag: :dd},
|
|
176
|
+
form_control: {}, # input, select or textarea
|
|
177
|
+
form_field_description: {tag: :span, attributes: {class: 'description'}},
|
|
178
|
+
form_field_description_close: {tag: :span, attributes: {class: 'close'}},
|
|
179
|
+
form_footer: {tag: :p},
|
|
180
|
+
form_submit: {attributes: {class: 'submit'}}, # input type=submit
|
|
181
|
+
form_apply: {attributes: {class: 'submit'}}, # input type=submit
|
|
182
|
+
form_cancel: {}, # a
|
|
183
|
+
field_add_new_subform: {},
|
|
184
|
+
field_add_new_popup: {},
|
|
185
|
+
show_title: {tag: :h4},
|
|
186
|
+
show_actions: {tag: :div},
|
|
187
|
+
show_columns_block: {tag: :dl},
|
|
188
|
+
show_label_block: {tag: :dt},
|
|
189
|
+
show_columns_group: {tag: :dd},
|
|
190
|
+
show_value_block: {tag: :dd},
|
|
191
|
+
show_footer: {tag: :p, attributes: {class: 'form-footer'}},
|
|
192
|
+
show_cancel: {} # a
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
def self.set_element_tag(name, tag)
|
|
196
|
+
(ui_elements[name] ||= {})[:tag] = tag
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Replace an element's complete definition. Use a block instead of +tag+ and
|
|
200
|
+
# +attributes+ to define a dynamic element.
|
|
201
|
+
def self.set_element(name, tag: nil, attributes: nil, &proc)
|
|
202
|
+
if proc && (tag || attributes)
|
|
203
|
+
raise ArgumentError, 'tag and attributes cannot be used with a proc'
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
ui_elements[name] = if proc
|
|
207
|
+
{proc: proc}
|
|
208
|
+
else
|
|
209
|
+
{}.tap do |element|
|
|
210
|
+
element[:tag] = tag if tag
|
|
211
|
+
element[:attributes] = attributes.as_html_attrs if attributes
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def self.set_element_proc(name, &block)
|
|
217
|
+
(ui_elements[name] ||= {})[:proc] = block
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def self.set_element_attributes(name, attributes)
|
|
221
|
+
(ui_elements[name] ||= {})[:attributes] = attributes.as_html_attrs
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def self.add_element_attributes(name, attributes)
|
|
225
|
+
attrs = (ui_elements[name] ||= {})[:attributes] || {}
|
|
226
|
+
ui_elements[name][:attributes] = attrs.smart_merge(attributes)
|
|
227
|
+
end
|
|
228
|
+
|
|
61
229
|
def self.threadsafe!; end
|
|
62
230
|
|
|
63
231
|
mattr_writer :jquery_ui_loaded, instance_writer: false
|
|
@@ -106,3 +274,4 @@ require 'active_scaffold/engine'
|
|
|
106
274
|
require 'ice_nine'
|
|
107
275
|
require 'ice_nine/core_ext/object'
|
|
108
276
|
require 'request_store'
|
|
277
|
+
require 'html_attrs'
|
data/lib/tasks/bundle.rake
CHANGED
|
@@ -16,7 +16,8 @@ namespace :bundle do
|
|
|
16
16
|
gemfiles.each do |gemfile|
|
|
17
17
|
puts "Locking #{File.basename(gemfile)}..."
|
|
18
18
|
Bundler.with_unbundled_env do
|
|
19
|
-
|
|
19
|
+
command = ['bundle', 'lock', "--gemfile=#{gemfile}", '--add-platform', 'ruby']
|
|
20
|
+
system(*command, exception: true)
|
|
20
21
|
end
|
|
21
22
|
end
|
|
22
23
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
namespace :mock_app do
|
|
4
|
+
desc 'Build the mock app stylesheets'
|
|
5
|
+
task :assets do
|
|
6
|
+
environment = {
|
|
7
|
+
'BUNDLE_GEMFILE' => File.expand_path(ENV.fetch('BUNDLE_GEMFILE', 'Gemfile'))
|
|
8
|
+
}
|
|
9
|
+
Dir.chdir('test/mock_app') do
|
|
10
|
+
system(environment, 'rails', 'dartsass:build', exception: true)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
desc 'Start the mock_app server and Dart Sass watcher (default port 3000)'
|
|
15
|
+
task :server do
|
|
16
|
+
args = ARGV.drop_while { |a| a != '--' }.drop(1)
|
|
17
|
+
Dir.chdir('test/mock_app') do
|
|
18
|
+
environment = {'BUNDLE_GEMFILE' => File.expand_path('../../Gemfile', __dir__)}
|
|
19
|
+
system(environment, 'rails', 'dartsass:build', exception: true)
|
|
20
|
+
watcher = Process.spawn(environment, 'rails', 'dartsass:watch')
|
|
21
|
+
_pid, status = Process.wait2(Process.spawn(environment, 'rails', 'server', *args))
|
|
22
|
+
exit status.exitstatus
|
|
23
|
+
ensure
|
|
24
|
+
begin
|
|
25
|
+
if watcher
|
|
26
|
+
Process.kill('TERM', watcher)
|
|
27
|
+
Process.wait(watcher)
|
|
28
|
+
end
|
|
29
|
+
rescue Errno::ECHILD, Errno::ESRCH
|
|
30
|
+
# The watcher already exited.
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
desc 'Start the mock_app console'
|
|
36
|
+
task :console do
|
|
37
|
+
args = ARGV.drop_while { |a| a != '--' }.drop(1)
|
|
38
|
+
Dir.chdir('test/mock_app') do
|
|
39
|
+
exec({'BUNDLE_GEMFILE' => File.expand_path('../../Gemfile', __dir__)},
|
|
40
|
+
'rails', 'console', *args)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
metadata
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active_scaffold
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Many, see README
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: html_attrs
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '1.1'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '1.1'
|
|
13
26
|
- !ruby/object:Gem::Dependency
|
|
14
27
|
name: ice_nine
|
|
15
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -190,6 +203,7 @@ files:
|
|
|
190
203
|
- config/locales/fr.yml
|
|
191
204
|
- config/locales/hu.yml
|
|
192
205
|
- config/locales/ja.yml
|
|
206
|
+
- config/locales/ro.yml
|
|
193
207
|
- config/locales/ru.yml
|
|
194
208
|
- config/locales/ta.yml
|
|
195
209
|
- config/locales/zh_Hans.yml
|
|
@@ -328,6 +342,7 @@ files:
|
|
|
328
342
|
- lib/active_scaffold/helpers/filter_helpers.rb
|
|
329
343
|
- lib/active_scaffold/helpers/form_column_helpers.rb
|
|
330
344
|
- lib/active_scaffold/helpers/form_ui_helpers.rb
|
|
345
|
+
- lib/active_scaffold/helpers/framework_ui_helpers.rb
|
|
331
346
|
- lib/active_scaffold/helpers/human_condition_helpers.rb
|
|
332
347
|
- lib/active_scaffold/helpers/id_helpers.rb
|
|
333
348
|
- lib/active_scaffold/helpers/list_column_helpers.rb
|
|
@@ -356,8 +371,8 @@ files:
|
|
|
356
371
|
- lib/tasks/active_scaffold/assets.rake
|
|
357
372
|
- lib/tasks/brakeman.rake
|
|
358
373
|
- lib/tasks/bundle.rake
|
|
374
|
+
- lib/tasks/mock_app.rake
|
|
359
375
|
- public/blank.html
|
|
360
|
-
- shoulda_macros/macros.rb
|
|
361
376
|
- vendor/assets/images/jquery-ui/ui-bg_diagonals-thick_18_b81900_40x40.png
|
|
362
377
|
- vendor/assets/images/jquery-ui/ui-bg_diagonals-thick_20_666666_40x40.png
|
|
363
378
|
- vendor/assets/images/jquery-ui/ui-bg_flat_10_000000_40x100.png
|
|
@@ -383,7 +398,6 @@ licenses:
|
|
|
383
398
|
- MIT
|
|
384
399
|
metadata:
|
|
385
400
|
rubygems_mfa_required: 'true'
|
|
386
|
-
post_install_message:
|
|
387
401
|
rdoc_options: []
|
|
388
402
|
require_paths:
|
|
389
403
|
- lib
|
|
@@ -398,8 +412,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
398
412
|
- !ruby/object:Gem::Version
|
|
399
413
|
version: '0'
|
|
400
414
|
requirements: []
|
|
401
|
-
rubygems_version: 3.
|
|
402
|
-
signing_key:
|
|
415
|
+
rubygems_version: 3.6.9
|
|
403
416
|
specification_version: 4
|
|
404
417
|
summary: Rails 4.x and 5.x versions of ActiveScaffold supporting prototype and jquery
|
|
405
418
|
test_files: []
|