terrazzo 0.3.2 → 0.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/app/views/terrazzo/application/_edit_base.json.props +63 -0
- data/app/views/terrazzo/application/_index_base.json.props +91 -0
- data/app/views/terrazzo/application/_new_base.json.props +58 -0
- data/app/views/terrazzo/application/_show_base.json.props +48 -0
- data/app/views/terrazzo/application/edit.json.props +1 -63
- data/app/views/terrazzo/application/index.json.props +1 -91
- data/app/views/terrazzo/application/new.json.props +1 -58
- data/app/views/terrazzo/application/show.json.props +1 -48
- data/lib/generators/terrazzo/views/edit_generator.rb +52 -4
- data/lib/generators/terrazzo/views/index_generator.rb +23 -1
- data/lib/generators/terrazzo/views/new_generator.rb +52 -4
- data/lib/generators/terrazzo/views/show_generator.rb +20 -1
- data/lib/generators/terrazzo/views/templates/pages/_collection.jsx +55 -0
- data/lib/generators/terrazzo/views/templates/pages/index.jsx +7 -49
- data/lib/terrazzo/field/belongs_to.rb +16 -1
- data/lib/terrazzo/field/date.rb +8 -1
- data/lib/terrazzo/field/date_time.rb +8 -1
- data/lib/terrazzo/field/has_many.rb +25 -1
- data/lib/terrazzo/field/number.rb +12 -2
- data/lib/terrazzo/field/polymorphic.rb +3 -1
- data/lib/terrazzo/version.rb +1 -1
- metadata +6 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6da1376c6052a70bacdbb878ee703543e04e0dc044f57cb5b04c35aa08ea536c
|
|
4
|
+
data.tar.gz: 9fe6747b3ee47446e501a37c82978a1e1d00fc33b517ad8c8a34ec13b9620889
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 316fb61ca947bd8a4d581bcd46a6b1c74a4b0b6a2b6c8113e27ceed6df52f124721a2c8b12d09fb7fbe9f09eb69e8a4ead22d79175946d9d1f74a33da23612a9
|
|
7
|
+
data.tar.gz: d15cdb461bfc96aa705c463f0f174ce8490a836afaf8755225d6268edd90462e94019687f3f717a4559e32de3a4dc6711d3b580546477b8f7e674e164f866710
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
param_key = resource_class.model_name.param_key
|
|
2
|
+
|
|
3
|
+
json.pageTitle t("terrazzo.actions.edit", resource_name: resource_name)
|
|
4
|
+
|
|
5
|
+
json.form do
|
|
6
|
+
json.props({
|
|
7
|
+
action: polymorphic_path([namespace, @resource]),
|
|
8
|
+
method: "post",
|
|
9
|
+
encType: "multipart/form-data"
|
|
10
|
+
})
|
|
11
|
+
json.extras do
|
|
12
|
+
if protect_against_forgery?
|
|
13
|
+
json.set!("authenticity_token") do
|
|
14
|
+
json.name "authenticity_token"
|
|
15
|
+
json.type "hidden"
|
|
16
|
+
json.defaultValue form_authenticity_token
|
|
17
|
+
json.autoComplete "off"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
json.set!("_method") do
|
|
21
|
+
json.name "_method"
|
|
22
|
+
json.type "hidden"
|
|
23
|
+
json.value "patch"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
json.fields do
|
|
27
|
+
json.array! @page.attributes("update") do |field|
|
|
28
|
+
json.attribute field.attribute.to_s
|
|
29
|
+
json.label field.attribute.to_s.humanize
|
|
30
|
+
json.fieldType field.field_type
|
|
31
|
+
json.value field.serialize_value(:form)
|
|
32
|
+
json.options field.serializable_options
|
|
33
|
+
json.required field.required?
|
|
34
|
+
json.input field.form_input_attributes(param_key)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
json.fieldGroups do
|
|
38
|
+
json.array! @page.grouped_attributes("update") do |group|
|
|
39
|
+
json.name group[:name]
|
|
40
|
+
json.fields do
|
|
41
|
+
json.array! group[:fields] do |field|
|
|
42
|
+
json.attribute field.attribute.to_s
|
|
43
|
+
json.label field.attribute.to_s.humanize
|
|
44
|
+
json.fieldType field.field_type
|
|
45
|
+
json.value field.serialize_value(:form)
|
|
46
|
+
json.options field.serializable_options
|
|
47
|
+
json.required field.required?
|
|
48
|
+
json.input field.form_input_attributes(param_key)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
json.errors @resource.errors.full_messages
|
|
56
|
+
|
|
57
|
+
json.showPath polymorphic_path([namespace, @resource])
|
|
58
|
+
json.indexPath begin
|
|
59
|
+
url_for(controller: controller_path, action: :index, only_path: true)
|
|
60
|
+
rescue ActionController::UrlGenerationError
|
|
61
|
+
nil
|
|
62
|
+
end
|
|
63
|
+
json.resourceName resource_name
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
json.searchBar do
|
|
2
|
+
json.searchTerm @search_term
|
|
3
|
+
json.searchPath request.path
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
json.filters do
|
|
7
|
+
json.available dashboard.collection_filters.keys.map(&:to_s)
|
|
8
|
+
json.active @active_filter
|
|
9
|
+
json.value @filter_value
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
json.table do
|
|
13
|
+
json.headers do
|
|
14
|
+
json.array! @page.attribute_names do |attr|
|
|
15
|
+
field_class = dashboard.attribute_type_for(attr)
|
|
16
|
+
json.label attr.to_s.humanize
|
|
17
|
+
json.attribute attr.to_s
|
|
18
|
+
json.sortable field_class.sortable?
|
|
19
|
+
json.sortDirection @page.sort_direction_for(attr)
|
|
20
|
+
json.sortUrl url_for(
|
|
21
|
+
@page.order_params_for(attr).merge(
|
|
22
|
+
search: @search_term,
|
|
23
|
+
filter: @active_filter,
|
|
24
|
+
filter_value: @filter_value,
|
|
25
|
+
_page: 1,
|
|
26
|
+
only_path: true
|
|
27
|
+
)
|
|
28
|
+
)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
json.rows do
|
|
33
|
+
json.array! @resources do |resource|
|
|
34
|
+
json.id resource.id
|
|
35
|
+
json.showPath polymorphic_path([namespace, resource]) rescue nil
|
|
36
|
+
json.collectionItemActions collection_item_actions(resource)
|
|
37
|
+
|
|
38
|
+
json.cells do
|
|
39
|
+
json.array! @page.attribute_names do |attr|
|
|
40
|
+
field = dashboard.attribute_type_for(attr).new(attr, nil, :index, resource: resource)
|
|
41
|
+
json.attribute attr.to_s
|
|
42
|
+
json.fieldType field.field_type
|
|
43
|
+
json.value field.serialize_value(:index)
|
|
44
|
+
|
|
45
|
+
if field.class.associative? && field.data.present?
|
|
46
|
+
json.showPath polymorphic_path([namespace, field.data]) rescue nil
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
json.pagination do
|
|
55
|
+
json.currentPage @resources.current_page
|
|
56
|
+
json.totalPages @resources.total_pages
|
|
57
|
+
json.totalCount @resources.total_count
|
|
58
|
+
json.perPage @resources.limit_value
|
|
59
|
+
if @resources.next_page
|
|
60
|
+
json.nextPagePath url_for(
|
|
61
|
+
_page: @resources.next_page,
|
|
62
|
+
search: @search_term,
|
|
63
|
+
order: params[:order],
|
|
64
|
+
direction: params[:direction],
|
|
65
|
+
filter: @active_filter,
|
|
66
|
+
filter_value: @filter_value,
|
|
67
|
+
props_at: "data.pagination",
|
|
68
|
+
only_path: true
|
|
69
|
+
)
|
|
70
|
+
else
|
|
71
|
+
json.nextPagePath nil
|
|
72
|
+
end
|
|
73
|
+
if @resources.prev_page
|
|
74
|
+
json.prevPagePath url_for(
|
|
75
|
+
_page: @resources.prev_page,
|
|
76
|
+
search: @search_term,
|
|
77
|
+
order: params[:order],
|
|
78
|
+
direction: params[:direction],
|
|
79
|
+
filter: @active_filter,
|
|
80
|
+
filter_value: @filter_value,
|
|
81
|
+
props_at: "data.pagination",
|
|
82
|
+
only_path: true
|
|
83
|
+
)
|
|
84
|
+
else
|
|
85
|
+
json.prevPagePath nil
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
json.resourceName resource_name.pluralize
|
|
90
|
+
json.singularResourceName resource_name
|
|
91
|
+
json.newResourcePath route_exists?(:new) ? (new_polymorphic_path([namespace, resource_class]) rescue nil) : nil
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
action = @resource.persisted? ? "update" : "create"
|
|
2
|
+
param_key = resource_class.model_name.param_key
|
|
3
|
+
|
|
4
|
+
json.pageTitle t("terrazzo.actions.new", resource_name: resource_name)
|
|
5
|
+
|
|
6
|
+
json.form do
|
|
7
|
+
json.props({
|
|
8
|
+
action: polymorphic_path([namespace, resource_class]),
|
|
9
|
+
method: "post",
|
|
10
|
+
encType: "multipart/form-data"
|
|
11
|
+
})
|
|
12
|
+
json.extras do
|
|
13
|
+
if protect_against_forgery?
|
|
14
|
+
json.set!("authenticity_token") do
|
|
15
|
+
json.name "authenticity_token"
|
|
16
|
+
json.type "hidden"
|
|
17
|
+
json.defaultValue form_authenticity_token
|
|
18
|
+
json.autoComplete "off"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
json.fields do
|
|
23
|
+
json.array! @page.attributes(action) do |field|
|
|
24
|
+
json.attribute field.attribute.to_s
|
|
25
|
+
json.label field.attribute.to_s.humanize
|
|
26
|
+
json.fieldType field.field_type
|
|
27
|
+
json.value field.serialize_value(:form)
|
|
28
|
+
json.options field.serializable_options
|
|
29
|
+
json.required field.required?
|
|
30
|
+
json.input field.form_input_attributes(param_key)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
json.fieldGroups do
|
|
34
|
+
json.array! @page.grouped_attributes(action) do |group|
|
|
35
|
+
json.name group[:name]
|
|
36
|
+
json.fields do
|
|
37
|
+
json.array! group[:fields] do |field|
|
|
38
|
+
json.attribute field.attribute.to_s
|
|
39
|
+
json.label field.attribute.to_s.humanize
|
|
40
|
+
json.fieldType field.field_type
|
|
41
|
+
json.value field.serialize_value(:form)
|
|
42
|
+
json.options field.serializable_options
|
|
43
|
+
json.required field.required?
|
|
44
|
+
json.input field.form_input_attributes(param_key)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
json.errors @resource.errors.full_messages
|
|
52
|
+
|
|
53
|
+
json.indexPath begin
|
|
54
|
+
url_for(controller: controller_path, action: :index, only_path: true)
|
|
55
|
+
rescue ActionController::UrlGenerationError
|
|
56
|
+
nil
|
|
57
|
+
end
|
|
58
|
+
json.resourceName resource_name
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
json.pageTitle @page.page_title
|
|
2
|
+
|
|
3
|
+
show_field_json = ->(json, field) do
|
|
4
|
+
json.attribute field.attribute.to_s
|
|
5
|
+
json.label field.attribute.to_s.humanize
|
|
6
|
+
json.fieldType field.field_type
|
|
7
|
+
json.value field.serialize_value(:show)
|
|
8
|
+
|
|
9
|
+
if field.class.associative? && field.data.present?
|
|
10
|
+
if field.is_a?(Terrazzo::Field::HasMany)
|
|
11
|
+
json.itemShowPaths(field.data.each_with_object({}) do |record, paths|
|
|
12
|
+
paths[record.id.to_s] = polymorphic_path([namespace, record]) rescue nil
|
|
13
|
+
end)
|
|
14
|
+
json.collectionItemActions(field.data.each_with_object({}) do |record, hash|
|
|
15
|
+
hash[record.id.to_s] = collection_item_actions(record)
|
|
16
|
+
end)
|
|
17
|
+
else
|
|
18
|
+
json.showPath polymorphic_path([namespace, field.data]) rescue nil
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
json.attributeGroups do
|
|
24
|
+
json.array! @page.grouped_attributes do |group|
|
|
25
|
+
json.name group[:name]
|
|
26
|
+
json.attributes do
|
|
27
|
+
json.array! group[:fields] do |field|
|
|
28
|
+
show_field_json.call(json, field)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
json.attributes do
|
|
35
|
+
json.array! @page.attributes do |field|
|
|
36
|
+
show_field_json.call(json, field)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
json.editPath route_exists?(:edit) ? (edit_polymorphic_path([namespace, @resource]) rescue nil) : nil
|
|
41
|
+
json.deletePath route_exists?(:destroy) ? (polymorphic_path([namespace, @resource]) rescue nil) : nil
|
|
42
|
+
json.indexPath begin
|
|
43
|
+
url_for(controller: controller_path, action: :index, only_path: true)
|
|
44
|
+
rescue ActionController::UrlGenerationError
|
|
45
|
+
nil
|
|
46
|
+
end
|
|
47
|
+
json.resourceName resource_name
|
|
48
|
+
json.pluralResourceName resource_name.pluralize
|
|
@@ -1,63 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
json.pageTitle t("terrazzo.actions.edit", resource_name: resource_name)
|
|
4
|
-
|
|
5
|
-
json.form do
|
|
6
|
-
json.props({
|
|
7
|
-
action: polymorphic_path([namespace, @resource]),
|
|
8
|
-
method: "post",
|
|
9
|
-
encType: "multipart/form-data"
|
|
10
|
-
})
|
|
11
|
-
json.extras do
|
|
12
|
-
if protect_against_forgery?
|
|
13
|
-
json.set!("authenticity_token") do
|
|
14
|
-
json.name "authenticity_token"
|
|
15
|
-
json.type "hidden"
|
|
16
|
-
json.defaultValue form_authenticity_token
|
|
17
|
-
json.autoComplete "off"
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
json.set!("_method") do
|
|
21
|
-
json.name "_method"
|
|
22
|
-
json.type "hidden"
|
|
23
|
-
json.value "patch"
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
json.fields do
|
|
27
|
-
json.array! @page.attributes("update") do |field|
|
|
28
|
-
json.attribute field.attribute.to_s
|
|
29
|
-
json.label field.attribute.to_s.humanize
|
|
30
|
-
json.fieldType field.field_type
|
|
31
|
-
json.value field.serialize_value(:form)
|
|
32
|
-
json.options field.serializable_options
|
|
33
|
-
json.required field.required?
|
|
34
|
-
json.input field.form_input_attributes(param_key)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
json.fieldGroups do
|
|
38
|
-
json.array! @page.grouped_attributes("update") do |group|
|
|
39
|
-
json.name group[:name]
|
|
40
|
-
json.fields do
|
|
41
|
-
json.array! group[:fields] do |field|
|
|
42
|
-
json.attribute field.attribute.to_s
|
|
43
|
-
json.label field.attribute.to_s.humanize
|
|
44
|
-
json.fieldType field.field_type
|
|
45
|
-
json.value field.serialize_value(:form)
|
|
46
|
-
json.options field.serializable_options
|
|
47
|
-
json.required field.required?
|
|
48
|
-
json.input field.form_input_attributes(param_key)
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
json.errors @resource.errors.full_messages
|
|
56
|
-
|
|
57
|
-
json.showPath polymorphic_path([namespace, @resource])
|
|
58
|
-
json.indexPath begin
|
|
59
|
-
url_for(controller: controller_path, action: :index, only_path: true)
|
|
60
|
-
rescue ActionController::UrlGenerationError
|
|
61
|
-
nil
|
|
62
|
-
end
|
|
63
|
-
json.resourceName resource_name
|
|
1
|
+
json.partial! partial: "terrazzo/application/edit_base"
|
|
@@ -1,91 +1 @@
|
|
|
1
|
-
json.
|
|
2
|
-
json.searchTerm @search_term
|
|
3
|
-
json.searchPath request.path
|
|
4
|
-
end
|
|
5
|
-
|
|
6
|
-
json.filters do
|
|
7
|
-
json.available dashboard.collection_filters.keys.map(&:to_s)
|
|
8
|
-
json.active @active_filter
|
|
9
|
-
json.value @filter_value
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
json.table do
|
|
13
|
-
json.headers do
|
|
14
|
-
json.array! @page.attribute_names do |attr|
|
|
15
|
-
field_class = dashboard.attribute_type_for(attr)
|
|
16
|
-
json.label attr.to_s.humanize
|
|
17
|
-
json.attribute attr.to_s
|
|
18
|
-
json.sortable field_class.sortable?
|
|
19
|
-
json.sortDirection @page.sort_direction_for(attr)
|
|
20
|
-
json.sortUrl url_for(
|
|
21
|
-
@page.order_params_for(attr).merge(
|
|
22
|
-
search: @search_term,
|
|
23
|
-
filter: @active_filter,
|
|
24
|
-
filter_value: @filter_value,
|
|
25
|
-
_page: 1,
|
|
26
|
-
only_path: true
|
|
27
|
-
)
|
|
28
|
-
)
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
json.rows do
|
|
33
|
-
json.array! @resources do |resource|
|
|
34
|
-
json.id resource.id
|
|
35
|
-
json.showPath polymorphic_path([namespace, resource]) rescue nil
|
|
36
|
-
json.collectionItemActions collection_item_actions(resource)
|
|
37
|
-
|
|
38
|
-
json.cells do
|
|
39
|
-
json.array! @page.attribute_names do |attr|
|
|
40
|
-
field = dashboard.attribute_type_for(attr).new(attr, nil, :index, resource: resource)
|
|
41
|
-
json.attribute attr.to_s
|
|
42
|
-
json.fieldType field.field_type
|
|
43
|
-
json.value field.serialize_value(:index)
|
|
44
|
-
|
|
45
|
-
if field.class.associative? && field.data.present?
|
|
46
|
-
json.showPath polymorphic_path([namespace, field.data]) rescue nil
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
json.pagination do
|
|
55
|
-
json.currentPage @resources.current_page
|
|
56
|
-
json.totalPages @resources.total_pages
|
|
57
|
-
json.totalCount @resources.total_count
|
|
58
|
-
json.perPage @resources.limit_value
|
|
59
|
-
if @resources.next_page
|
|
60
|
-
json.nextPagePath url_for(
|
|
61
|
-
_page: @resources.next_page,
|
|
62
|
-
search: @search_term,
|
|
63
|
-
order: params[:order],
|
|
64
|
-
direction: params[:direction],
|
|
65
|
-
filter: @active_filter,
|
|
66
|
-
filter_value: @filter_value,
|
|
67
|
-
props_at: "data.pagination",
|
|
68
|
-
only_path: true
|
|
69
|
-
)
|
|
70
|
-
else
|
|
71
|
-
json.nextPagePath nil
|
|
72
|
-
end
|
|
73
|
-
if @resources.prev_page
|
|
74
|
-
json.prevPagePath url_for(
|
|
75
|
-
_page: @resources.prev_page,
|
|
76
|
-
search: @search_term,
|
|
77
|
-
order: params[:order],
|
|
78
|
-
direction: params[:direction],
|
|
79
|
-
filter: @active_filter,
|
|
80
|
-
filter_value: @filter_value,
|
|
81
|
-
props_at: "data.pagination",
|
|
82
|
-
only_path: true
|
|
83
|
-
)
|
|
84
|
-
else
|
|
85
|
-
json.prevPagePath nil
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
json.resourceName resource_name.pluralize
|
|
90
|
-
json.singularResourceName resource_name
|
|
91
|
-
json.newResourcePath route_exists?(:new) ? (new_polymorphic_path([namespace, resource_class]) rescue nil) : nil
|
|
1
|
+
json.partial! partial: "terrazzo/application/index_base"
|
|
@@ -1,58 +1 @@
|
|
|
1
|
-
|
|
2
|
-
param_key = resource_class.model_name.param_key
|
|
3
|
-
|
|
4
|
-
json.pageTitle t("terrazzo.actions.new", resource_name: resource_name)
|
|
5
|
-
|
|
6
|
-
json.form do
|
|
7
|
-
json.props({
|
|
8
|
-
action: polymorphic_path([namespace, resource_class]),
|
|
9
|
-
method: "post",
|
|
10
|
-
encType: "multipart/form-data"
|
|
11
|
-
})
|
|
12
|
-
json.extras do
|
|
13
|
-
if protect_against_forgery?
|
|
14
|
-
json.set!("authenticity_token") do
|
|
15
|
-
json.name "authenticity_token"
|
|
16
|
-
json.type "hidden"
|
|
17
|
-
json.defaultValue form_authenticity_token
|
|
18
|
-
json.autoComplete "off"
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
json.fields do
|
|
23
|
-
json.array! @page.attributes(action) do |field|
|
|
24
|
-
json.attribute field.attribute.to_s
|
|
25
|
-
json.label field.attribute.to_s.humanize
|
|
26
|
-
json.fieldType field.field_type
|
|
27
|
-
json.value field.serialize_value(:form)
|
|
28
|
-
json.options field.serializable_options
|
|
29
|
-
json.required field.required?
|
|
30
|
-
json.input field.form_input_attributes(param_key)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
json.fieldGroups do
|
|
34
|
-
json.array! @page.grouped_attributes(action) do |group|
|
|
35
|
-
json.name group[:name]
|
|
36
|
-
json.fields do
|
|
37
|
-
json.array! group[:fields] do |field|
|
|
38
|
-
json.attribute field.attribute.to_s
|
|
39
|
-
json.label field.attribute.to_s.humanize
|
|
40
|
-
json.fieldType field.field_type
|
|
41
|
-
json.value field.serialize_value(:form)
|
|
42
|
-
json.options field.serializable_options
|
|
43
|
-
json.required field.required?
|
|
44
|
-
json.input field.form_input_attributes(param_key)
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
json.errors @resource.errors.full_messages
|
|
52
|
-
|
|
53
|
-
json.indexPath begin
|
|
54
|
-
url_for(controller: controller_path, action: :index, only_path: true)
|
|
55
|
-
rescue ActionController::UrlGenerationError
|
|
56
|
-
nil
|
|
57
|
-
end
|
|
58
|
-
json.resourceName resource_name
|
|
1
|
+
json.partial! partial: "terrazzo/application/new_base"
|
|
@@ -1,48 +1 @@
|
|
|
1
|
-
json.
|
|
2
|
-
|
|
3
|
-
show_field_json = ->(json, field) do
|
|
4
|
-
json.attribute field.attribute.to_s
|
|
5
|
-
json.label field.attribute.to_s.humanize
|
|
6
|
-
json.fieldType field.field_type
|
|
7
|
-
json.value field.serialize_value(:show)
|
|
8
|
-
|
|
9
|
-
if field.class.associative? && field.data.present?
|
|
10
|
-
if field.is_a?(Terrazzo::Field::HasMany)
|
|
11
|
-
json.itemShowPaths(field.data.each_with_object({}) do |record, paths|
|
|
12
|
-
paths[record.id.to_s] = polymorphic_path([namespace, record]) rescue nil
|
|
13
|
-
end)
|
|
14
|
-
json.collectionItemActions(field.data.each_with_object({}) do |record, hash|
|
|
15
|
-
hash[record.id.to_s] = collection_item_actions(record)
|
|
16
|
-
end)
|
|
17
|
-
else
|
|
18
|
-
json.showPath polymorphic_path([namespace, field.data]) rescue nil
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
json.attributeGroups do
|
|
24
|
-
json.array! @page.grouped_attributes do |group|
|
|
25
|
-
json.name group[:name]
|
|
26
|
-
json.attributes do
|
|
27
|
-
json.array! group[:fields] do |field|
|
|
28
|
-
show_field_json.call(json, field)
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
json.attributes do
|
|
35
|
-
json.array! @page.attributes do |field|
|
|
36
|
-
show_field_json.call(json, field)
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
json.editPath route_exists?(:edit) ? (edit_polymorphic_path([namespace, @resource]) rescue nil) : nil
|
|
41
|
-
json.deletePath route_exists?(:destroy) ? (polymorphic_path([namespace, @resource]) rescue nil) : nil
|
|
42
|
-
json.indexPath begin
|
|
43
|
-
url_for(controller: controller_path, action: :index, only_path: true)
|
|
44
|
-
rescue ActionController::UrlGenerationError
|
|
45
|
-
nil
|
|
46
|
-
end
|
|
47
|
-
json.resourceName resource_name
|
|
48
|
-
json.pluralResourceName resource_name.pluralize
|
|
1
|
+
json.partial! partial: "terrazzo/application/show_base"
|
|
@@ -6,18 +6,66 @@ module Terrazzo
|
|
|
6
6
|
class EditGenerator < Rails::Generators::Base
|
|
7
7
|
source_root File.expand_path("templates", __dir__)
|
|
8
8
|
|
|
9
|
+
argument :resource, type: :string, required: false,
|
|
10
|
+
desc: "Resource model (e.g., User) to eject a resource-specific edit view"
|
|
11
|
+
|
|
9
12
|
class_option :namespace, type: :string, default: "admin",
|
|
10
13
|
desc: "Admin namespace"
|
|
11
14
|
|
|
12
15
|
def copy_edit_template
|
|
13
|
-
|
|
16
|
+
if resource.present?
|
|
17
|
+
eject_json_props
|
|
18
|
+
copy_file "pages/edit.jsx", "app/views/#{namespace_name}/#{resource_path}/edit.jsx"
|
|
19
|
+
copy_file "pages/_form.jsx", "app/views/#{namespace_name}/#{resource_path}/_form.jsx"
|
|
20
|
+
eject_new_view if should_eject_new?
|
|
21
|
+
else
|
|
22
|
+
copy_file "pages/edit.jsx", "app/views/#{namespace_name}/application/edit.jsx"
|
|
23
|
+
copy_file "pages/_form.jsx", "app/views/#{namespace_name}/application/_form.jsx"
|
|
24
|
+
eject_new_view if should_eject_new?
|
|
25
|
+
end
|
|
14
26
|
end
|
|
15
27
|
|
|
16
|
-
|
|
17
|
-
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def eject_json_props
|
|
31
|
+
create_file "app/views/#{namespace_name}/#{resource_path}/edit.json.props", <<~RUBY
|
|
32
|
+
json.partial! partial: "terrazzo/application/edit_base"
|
|
33
|
+
# Add custom props below:
|
|
34
|
+
# json.customProp @resource.some_method
|
|
35
|
+
RUBY
|
|
18
36
|
end
|
|
19
37
|
|
|
20
|
-
|
|
38
|
+
def should_eject_new?
|
|
39
|
+
new_path = if resource.present?
|
|
40
|
+
"app/views/#{namespace_name}/#{resource_path}/new.jsx"
|
|
41
|
+
else
|
|
42
|
+
"app/views/#{namespace_name}/application/new.jsx"
|
|
43
|
+
end
|
|
44
|
+
return false if File.exist?(new_path)
|
|
45
|
+
|
|
46
|
+
yes?("Also eject the new view to share the custom form partial? (y/n)")
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def eject_new_view
|
|
50
|
+
if resource.present?
|
|
51
|
+
eject_new_json_props
|
|
52
|
+
copy_file "pages/new.jsx", "app/views/#{namespace_name}/#{resource_path}/new.jsx"
|
|
53
|
+
else
|
|
54
|
+
copy_file "pages/new.jsx", "app/views/#{namespace_name}/application/new.jsx"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def eject_new_json_props
|
|
59
|
+
create_file "app/views/#{namespace_name}/#{resource_path}/new.json.props", <<~RUBY
|
|
60
|
+
json.partial! partial: "terrazzo/application/new_base"
|
|
61
|
+
# Add custom props below:
|
|
62
|
+
# json.customProp SomeModel.some_value
|
|
63
|
+
RUBY
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def resource_path
|
|
67
|
+
resource.underscore.pluralize
|
|
68
|
+
end
|
|
21
69
|
|
|
22
70
|
def namespace_name
|
|
23
71
|
options[:namespace]
|
|
@@ -6,15 +6,37 @@ module Terrazzo
|
|
|
6
6
|
class IndexGenerator < Rails::Generators::Base
|
|
7
7
|
source_root File.expand_path("templates", __dir__)
|
|
8
8
|
|
|
9
|
+
argument :resource, type: :string, required: false,
|
|
10
|
+
desc: "Resource model (e.g., User) to eject a resource-specific index view"
|
|
11
|
+
|
|
9
12
|
class_option :namespace, type: :string, default: "admin",
|
|
10
13
|
desc: "Admin namespace"
|
|
11
14
|
|
|
12
15
|
def copy_index_template
|
|
13
|
-
|
|
16
|
+
if resource.present?
|
|
17
|
+
eject_json_props
|
|
18
|
+
copy_file "pages/index.jsx", "app/views/#{namespace_name}/#{resource_path}/index.jsx"
|
|
19
|
+
copy_file "pages/_collection.jsx", "app/views/#{namespace_name}/#{resource_path}/_collection.jsx"
|
|
20
|
+
else
|
|
21
|
+
copy_file "pages/index.jsx", "app/views/#{namespace_name}/application/index.jsx"
|
|
22
|
+
copy_file "pages/_collection.jsx", "app/views/#{namespace_name}/application/_collection.jsx"
|
|
23
|
+
end
|
|
14
24
|
end
|
|
15
25
|
|
|
16
26
|
private
|
|
17
27
|
|
|
28
|
+
def eject_json_props
|
|
29
|
+
create_file "app/views/#{namespace_name}/#{resource_path}/index.json.props", <<~RUBY
|
|
30
|
+
json.partial! partial: "terrazzo/application/index_base"
|
|
31
|
+
# Add custom props below:
|
|
32
|
+
# json.customProp SomeModel.count
|
|
33
|
+
RUBY
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def resource_path
|
|
37
|
+
resource.underscore.pluralize
|
|
38
|
+
end
|
|
39
|
+
|
|
18
40
|
def namespace_name
|
|
19
41
|
options[:namespace]
|
|
20
42
|
end
|
|
@@ -6,18 +6,66 @@ module Terrazzo
|
|
|
6
6
|
class NewGenerator < Rails::Generators::Base
|
|
7
7
|
source_root File.expand_path("templates", __dir__)
|
|
8
8
|
|
|
9
|
+
argument :resource, type: :string, required: false,
|
|
10
|
+
desc: "Resource model (e.g., User) to eject a resource-specific new view"
|
|
11
|
+
|
|
9
12
|
class_option :namespace, type: :string, default: "admin",
|
|
10
13
|
desc: "Admin namespace"
|
|
11
14
|
|
|
12
15
|
def copy_new_template
|
|
13
|
-
|
|
16
|
+
if resource.present?
|
|
17
|
+
eject_json_props
|
|
18
|
+
copy_file "pages/new.jsx", "app/views/#{namespace_name}/#{resource_path}/new.jsx"
|
|
19
|
+
copy_file "pages/_form.jsx", "app/views/#{namespace_name}/#{resource_path}/_form.jsx"
|
|
20
|
+
eject_edit_view if should_eject_edit?
|
|
21
|
+
else
|
|
22
|
+
copy_file "pages/new.jsx", "app/views/#{namespace_name}/application/new.jsx"
|
|
23
|
+
copy_file "pages/_form.jsx", "app/views/#{namespace_name}/application/_form.jsx"
|
|
24
|
+
eject_edit_view if should_eject_edit?
|
|
25
|
+
end
|
|
14
26
|
end
|
|
15
27
|
|
|
16
|
-
|
|
17
|
-
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def eject_json_props
|
|
31
|
+
create_file "app/views/#{namespace_name}/#{resource_path}/new.json.props", <<~RUBY
|
|
32
|
+
json.partial! partial: "terrazzo/application/new_base"
|
|
33
|
+
# Add custom props below:
|
|
34
|
+
# json.customProp SomeModel.some_value
|
|
35
|
+
RUBY
|
|
18
36
|
end
|
|
19
37
|
|
|
20
|
-
|
|
38
|
+
def should_eject_edit?
|
|
39
|
+
edit_path = if resource.present?
|
|
40
|
+
"app/views/#{namespace_name}/#{resource_path}/edit.jsx"
|
|
41
|
+
else
|
|
42
|
+
"app/views/#{namespace_name}/application/edit.jsx"
|
|
43
|
+
end
|
|
44
|
+
return false if File.exist?(edit_path)
|
|
45
|
+
|
|
46
|
+
yes?("Also eject the edit view to share the custom form partial? (y/n)")
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def eject_edit_view
|
|
50
|
+
if resource.present?
|
|
51
|
+
eject_edit_json_props
|
|
52
|
+
copy_file "pages/edit.jsx", "app/views/#{namespace_name}/#{resource_path}/edit.jsx"
|
|
53
|
+
else
|
|
54
|
+
copy_file "pages/edit.jsx", "app/views/#{namespace_name}/application/edit.jsx"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def eject_edit_json_props
|
|
59
|
+
create_file "app/views/#{namespace_name}/#{resource_path}/edit.json.props", <<~RUBY
|
|
60
|
+
json.partial! partial: "terrazzo/application/edit_base"
|
|
61
|
+
# Add custom props below:
|
|
62
|
+
# json.customProp @resource.some_method
|
|
63
|
+
RUBY
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def resource_path
|
|
67
|
+
resource.underscore.pluralize
|
|
68
|
+
end
|
|
21
69
|
|
|
22
70
|
def namespace_name
|
|
23
71
|
options[:namespace]
|
|
@@ -6,15 +6,34 @@ module Terrazzo
|
|
|
6
6
|
class ShowGenerator < Rails::Generators::Base
|
|
7
7
|
source_root File.expand_path("templates", __dir__)
|
|
8
8
|
|
|
9
|
+
argument :resource, type: :string, required: false,
|
|
10
|
+
desc: "Resource model (e.g., User) to eject a resource-specific show.json.props"
|
|
11
|
+
|
|
9
12
|
class_option :namespace, type: :string, default: "admin",
|
|
10
13
|
desc: "Admin namespace"
|
|
11
14
|
|
|
12
15
|
def copy_show_template
|
|
13
|
-
|
|
16
|
+
if resource.present?
|
|
17
|
+
eject_json_props
|
|
18
|
+
else
|
|
19
|
+
copy_file "pages/show.jsx", "app/views/#{namespace_name}/application/show.jsx"
|
|
20
|
+
end
|
|
14
21
|
end
|
|
15
22
|
|
|
16
23
|
private
|
|
17
24
|
|
|
25
|
+
def eject_json_props
|
|
26
|
+
create_file "app/views/#{namespace_name}/#{resource_path}/show.json.props", <<~RUBY
|
|
27
|
+
json.partial! partial: "terrazzo/application/show_base"
|
|
28
|
+
# Add custom props below:
|
|
29
|
+
# json.customProp @resource.some_method
|
|
30
|
+
RUBY
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def resource_path
|
|
34
|
+
resource.underscore.pluralize
|
|
35
|
+
end
|
|
36
|
+
|
|
18
37
|
def namespace_name
|
|
19
38
|
options[:namespace]
|
|
20
39
|
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import React, { useContext } from "react";
|
|
2
|
+
import { NavigationContext } from "@thoughtbot/superglue";
|
|
3
|
+
|
|
4
|
+
import { SortableHeader, CollectionItemActions } from "../components";
|
|
5
|
+
import { FieldRenderer } from "../fields";
|
|
6
|
+
import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from "../components/ui";
|
|
7
|
+
|
|
8
|
+
export function AdminCollection({ table }) {
|
|
9
|
+
const { visit } = useContext(NavigationContext);
|
|
10
|
+
|
|
11
|
+
const handleRowClick = (e, showPath) => {
|
|
12
|
+
if (!showPath) return;
|
|
13
|
+
if (e.target.closest("a, button, form")) return;
|
|
14
|
+
if (window.getSelection().toString()) return;
|
|
15
|
+
visit(showPath, {});
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div className="overflow-x-auto rounded-md border">
|
|
20
|
+
<Table>
|
|
21
|
+
<TableHeader>
|
|
22
|
+
<TableRow>
|
|
23
|
+
{table.headers.map((header) =>
|
|
24
|
+
<SortableHeader key={header.attribute} {...header} />
|
|
25
|
+
)}
|
|
26
|
+
<TableHead className="w-[120px]">Actions</TableHead>
|
|
27
|
+
</TableRow>
|
|
28
|
+
</TableHeader>
|
|
29
|
+
<TableBody>
|
|
30
|
+
{table.rows.map((row) =>
|
|
31
|
+
<TableRow
|
|
32
|
+
key={row.id}
|
|
33
|
+
className={row.showPath ? "cursor-pointer" : ""}
|
|
34
|
+
onClick={(e) => handleRowClick(e, row.showPath)}>
|
|
35
|
+
{row.cells.map((cell) =>
|
|
36
|
+
<TableCell key={cell.attribute}>
|
|
37
|
+
{cell.showPath ? (
|
|
38
|
+
<a href={cell.showPath} data-sg-visit className="hover:underline">
|
|
39
|
+
<FieldRenderer mode="index" {...cell} />
|
|
40
|
+
</a>
|
|
41
|
+
) : (
|
|
42
|
+
<FieldRenderer mode="index" {...cell} />
|
|
43
|
+
)}
|
|
44
|
+
</TableCell>
|
|
45
|
+
)}
|
|
46
|
+
<TableCell>
|
|
47
|
+
<CollectionItemActions actions={row.collectionItemActions} />
|
|
48
|
+
</TableCell>
|
|
49
|
+
</TableRow>
|
|
50
|
+
)}
|
|
51
|
+
</TableBody>
|
|
52
|
+
</Table>
|
|
53
|
+
</div>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import { useContent
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { useContent } from "@thoughtbot/superglue";
|
|
3
3
|
|
|
4
|
-
import { Layout, SearchBar, Pagination
|
|
5
|
-
import {
|
|
6
|
-
import { Button
|
|
4
|
+
import { Layout, SearchBar, Pagination } from "../components";
|
|
5
|
+
import { AdminCollection } from "./_collection";
|
|
6
|
+
import { Button } from "../components/ui";
|
|
7
7
|
|
|
8
8
|
export default function AdminIndex() {
|
|
9
|
-
const { visit } = useContext(NavigationContext);
|
|
10
9
|
const {
|
|
11
10
|
table,
|
|
12
11
|
searchBar,
|
|
@@ -17,18 +16,11 @@ export default function AdminIndex() {
|
|
|
17
16
|
singularResourceName
|
|
18
17
|
} = useContent();
|
|
19
18
|
|
|
20
|
-
const handleRowClick = (e, showPath) => {
|
|
21
|
-
if (!showPath) return;
|
|
22
|
-
if (e.target.closest("a, button, form")) return;
|
|
23
|
-
if (window.getSelection().toString()) return;
|
|
24
|
-
visit(showPath, {});
|
|
25
|
-
};
|
|
26
|
-
|
|
27
19
|
return (
|
|
28
20
|
<Layout
|
|
29
21
|
navigation={navigation}
|
|
30
22
|
title={resourceName}
|
|
31
|
-
actions={
|
|
23
|
+
actions={newResourcePath &&
|
|
32
24
|
<a href={newResourcePath} data-sg-visit>
|
|
33
25
|
<Button size="sm">New {singularResourceName}</Button>
|
|
34
26
|
</a>
|
|
@@ -38,41 +30,7 @@ export default function AdminIndex() {
|
|
|
38
30
|
<SearchBar {...searchBar} />
|
|
39
31
|
</div>
|
|
40
32
|
|
|
41
|
-
<
|
|
42
|
-
<Table>
|
|
43
|
-
<TableHeader>
|
|
44
|
-
<TableRow>
|
|
45
|
-
{table.headers.map((header) =>
|
|
46
|
-
<SortableHeader key={header.attribute} {...header} />
|
|
47
|
-
)}
|
|
48
|
-
<TableHead className="w-[120px]">Actions</TableHead>
|
|
49
|
-
</TableRow>
|
|
50
|
-
</TableHeader>
|
|
51
|
-
<TableBody>
|
|
52
|
-
{table.rows.map((row) =>
|
|
53
|
-
<TableRow
|
|
54
|
-
key={row.id}
|
|
55
|
-
className={row.showPath ? "cursor-pointer" : ""}
|
|
56
|
-
onClick={(e) => handleRowClick(e, row.showPath)}>
|
|
57
|
-
{row.cells.map((cell) =>
|
|
58
|
-
<TableCell key={cell.attribute}>
|
|
59
|
-
{cell.showPath ? (
|
|
60
|
-
<a href={cell.showPath} data-sg-visit className="hover:underline">
|
|
61
|
-
<FieldRenderer mode="index" {...cell} />
|
|
62
|
-
</a>
|
|
63
|
-
) : (
|
|
64
|
-
<FieldRenderer mode="index" {...cell} />
|
|
65
|
-
)}
|
|
66
|
-
</TableCell>
|
|
67
|
-
)}
|
|
68
|
-
<TableCell>
|
|
69
|
-
<CollectionItemActions actions={row.collectionItemActions} />
|
|
70
|
-
</TableCell>
|
|
71
|
-
</TableRow>
|
|
72
|
-
)}
|
|
73
|
-
</TableBody>
|
|
74
|
-
</Table>
|
|
75
|
-
</div>
|
|
33
|
+
<AdminCollection table={table} />
|
|
76
34
|
|
|
77
35
|
<Pagination {...pagination} />
|
|
78
36
|
</Layout>);
|
|
@@ -14,7 +14,7 @@ module Terrazzo
|
|
|
14
14
|
def serializable_options
|
|
15
15
|
opts = {}
|
|
16
16
|
if resource
|
|
17
|
-
collection =
|
|
17
|
+
collection = ordered_resource_options
|
|
18
18
|
if options[:include_blank]
|
|
19
19
|
collection = [["", nil]] + collection
|
|
20
20
|
end
|
|
@@ -38,6 +38,21 @@ module Terrazzo
|
|
|
38
38
|
|
|
39
39
|
private
|
|
40
40
|
|
|
41
|
+
def ordered_resource_options
|
|
42
|
+
return [] unless associated_class
|
|
43
|
+
scope = if options[:scope].is_a?(Proc)
|
|
44
|
+
options[:scope].call(associated_class)
|
|
45
|
+
elsif options[:scope]
|
|
46
|
+
associated_class.public_send(options[:scope])
|
|
47
|
+
else
|
|
48
|
+
associated_class.all
|
|
49
|
+
end
|
|
50
|
+
scope = scope.reorder(options[:order]) if options[:order]
|
|
51
|
+
pk = association_primary_key
|
|
52
|
+
dashboard = associated_dashboard
|
|
53
|
+
scope.map { |r| [dashboard ? dashboard.display_resource(r) : display_name(r), r.public_send(pk).to_s] }
|
|
54
|
+
end
|
|
55
|
+
|
|
41
56
|
def foreign_key_value
|
|
42
57
|
return nil unless resource
|
|
43
58
|
|
data/lib/terrazzo/field/date.rb
CHANGED
|
@@ -3,8 +3,15 @@ module Terrazzo
|
|
|
3
3
|
class Date < Base
|
|
4
4
|
def serialize_value(_mode)
|
|
5
5
|
return nil if data.nil?
|
|
6
|
+
value = if options[:timezone]
|
|
7
|
+
data.in_time_zone(options[:timezone]).to_date
|
|
8
|
+
elsif data.respond_to?(:in_time_zone)
|
|
9
|
+
data.in_time_zone.to_date
|
|
10
|
+
else
|
|
11
|
+
data
|
|
12
|
+
end
|
|
6
13
|
format = options[:format]
|
|
7
|
-
format ?
|
|
14
|
+
format ? value.strftime(format) : value.to_s
|
|
8
15
|
end
|
|
9
16
|
end
|
|
10
17
|
end
|
|
@@ -3,8 +3,15 @@ module Terrazzo
|
|
|
3
3
|
class DateTime < Base
|
|
4
4
|
def serialize_value(_mode)
|
|
5
5
|
return nil if data.nil?
|
|
6
|
+
value = if options[:timezone]
|
|
7
|
+
data.in_time_zone(options[:timezone])
|
|
8
|
+
elsif data.respond_to?(:in_time_zone)
|
|
9
|
+
data.in_time_zone
|
|
10
|
+
else
|
|
11
|
+
data
|
|
12
|
+
end
|
|
6
13
|
format = options[:format]
|
|
7
|
-
format ?
|
|
14
|
+
format ? value.strftime(format) : value.iso8601
|
|
8
15
|
end
|
|
9
16
|
end
|
|
10
17
|
end
|
|
@@ -45,7 +45,8 @@ module Terrazzo
|
|
|
45
45
|
|
|
46
46
|
def serialize_show_value
|
|
47
47
|
limit = options.fetch(:limit, 5)
|
|
48
|
-
|
|
48
|
+
records = apply_sorting(data)
|
|
49
|
+
all_records = records.to_a
|
|
49
50
|
total = all_records.size
|
|
50
51
|
col_attrs = options[:collection_attributes] || resolve_default_collection_attributes
|
|
51
52
|
|
|
@@ -94,6 +95,29 @@ module Terrazzo
|
|
|
94
95
|
}
|
|
95
96
|
end
|
|
96
97
|
|
|
98
|
+
def resource_options
|
|
99
|
+
return [] unless associated_class
|
|
100
|
+
scope = if options[:scope].is_a?(Proc)
|
|
101
|
+
options[:scope].call(associated_class)
|
|
102
|
+
elsif options[:scope]
|
|
103
|
+
associated_class.public_send(options[:scope])
|
|
104
|
+
else
|
|
105
|
+
associated_class.all
|
|
106
|
+
end
|
|
107
|
+
scope = scope.includes(*options[:includes]) if options.key?(:includes)
|
|
108
|
+
pk = association_primary_key
|
|
109
|
+
dashboard = associated_dashboard
|
|
110
|
+
scope.map { |r| [dashboard ? dashboard.display_resource(r) : display_name(r), r.public_send(pk).to_s] }
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def apply_sorting(records)
|
|
114
|
+
sort_by = options[:sort_by]
|
|
115
|
+
return records unless sort_by
|
|
116
|
+
|
|
117
|
+
direction = options.fetch(:direction, :asc)
|
|
118
|
+
records.reorder(sort_by => direction)
|
|
119
|
+
end
|
|
120
|
+
|
|
97
121
|
def find_associated_dashboard
|
|
98
122
|
klass = associated_class
|
|
99
123
|
"#{klass.name}Dashboard".constantize
|
|
@@ -1,10 +1,20 @@
|
|
|
1
|
+
require "active_support/number_helper"
|
|
2
|
+
|
|
1
3
|
module Terrazzo
|
|
2
4
|
module Field
|
|
3
5
|
class Number < Base
|
|
4
6
|
def serialize_value(mode)
|
|
5
|
-
return data if data.nil? || mode == :form
|
|
7
|
+
return data if data.nil? || mode == :form
|
|
8
|
+
|
|
9
|
+
value = options.key?(:multiplier) ? data * options[:multiplier] : data
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
if options[:format]
|
|
12
|
+
formatter = options[:format][:formatter]
|
|
13
|
+
formatter_options = options[:format][:formatter_options].to_h
|
|
14
|
+
ActiveSupport::NumberHelper.try(formatter, value, **formatter_options) || value
|
|
15
|
+
else
|
|
16
|
+
value
|
|
17
|
+
end
|
|
8
18
|
end
|
|
9
19
|
|
|
10
20
|
def serializable_options
|
|
@@ -15,9 +15,11 @@ module Terrazzo
|
|
|
15
15
|
def serializable_options
|
|
16
16
|
opts = {}
|
|
17
17
|
classes = options[:classes] || []
|
|
18
|
+
order = options[:order]
|
|
18
19
|
opts[:groupedOptions] = classes.each_with_object({}) do |klass, hash|
|
|
19
20
|
klass = klass.constantize if klass.is_a?(::String)
|
|
20
|
-
|
|
21
|
+
scope = order ? klass.order(order) : klass.all
|
|
22
|
+
hash[klass.name] = scope.map { |r| [display_name(r), r.id.to_s] }
|
|
21
23
|
end
|
|
22
24
|
opts
|
|
23
25
|
end
|
data/lib/terrazzo/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: terrazzo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Terrazzo Contributors
|
|
@@ -118,7 +118,11 @@ files:
|
|
|
118
118
|
- Rakefile
|
|
119
119
|
- app/controllers/terrazzo/application_controller.rb
|
|
120
120
|
- app/helpers/terrazzo/collection_actions_helper.rb
|
|
121
|
+
- app/views/terrazzo/application/_edit_base.json.props
|
|
122
|
+
- app/views/terrazzo/application/_index_base.json.props
|
|
121
123
|
- app/views/terrazzo/application/_navigation.json.props
|
|
124
|
+
- app/views/terrazzo/application/_new_base.json.props
|
|
125
|
+
- app/views/terrazzo/application/_show_base.json.props
|
|
122
126
|
- app/views/terrazzo/application/edit.json.props
|
|
123
127
|
- app/views/terrazzo/application/index.json.props
|
|
124
128
|
- app/views/terrazzo/application/new.json.props
|
|
@@ -233,6 +237,7 @@ files:
|
|
|
233
237
|
- lib/generators/terrazzo/views/templates/fields/url/FormField.jsx
|
|
234
238
|
- lib/generators/terrazzo/views/templates/fields/url/IndexField.jsx
|
|
235
239
|
- lib/generators/terrazzo/views/templates/fields/url/ShowField.jsx
|
|
240
|
+
- lib/generators/terrazzo/views/templates/pages/_collection.jsx
|
|
236
241
|
- lib/generators/terrazzo/views/templates/pages/_form.jsx
|
|
237
242
|
- lib/generators/terrazzo/views/templates/pages/_navigation.json.props
|
|
238
243
|
- lib/generators/terrazzo/views/templates/pages/edit.jsx
|