b4um_generators 0.2.11 → 0.2.16
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/.rubocop.yml +2 -2
- data/README.de.md +165 -8
- data/README.md +162 -8
- data/lib/b4um_generators/version.rb +1 -1
- data/lib/generators/b4um/attachment/attachment_generator.rb +83 -23
- data/lib/generators/b4um/authentication/authentication_generator.rb +63 -0
- data/lib/generators/b4um/bento/bento_generator.rb +24 -0
- data/lib/generators/b4um/help/help_generator.rb +148 -11
- data/lib/generators/b4um/in_place/in_place_generator.rb +1231 -0
- data/lib/generators/b4um/in_place/templates/_flash.html.erb +15 -0
- data/lib/generators/b4um/in_place/templates/b4um_in_place_helper.rb +7 -0
- data/lib/generators/b4um/in_place/templates/display_attachment.html.erb.tt +154 -0
- data/lib/generators/b4um/in_place/templates/display_attachments.html.erb.tt +165 -0
- data/lib/generators/b4um/in_place/templates/display_boolean.html.erb.tt +18 -0
- data/lib/generators/b4um/in_place/templates/display_number.html.erb.tt +18 -0
- data/lib/generators/b4um/in_place/templates/display_radio.html.erb.tt +23 -0
- data/lib/generators/b4um/in_place/templates/display_rich_text.html.erb.tt +123 -0
- data/lib/generators/b4um/in_place/templates/display_select.html.erb.tt +23 -0
- data/lib/generators/b4um/in_place/templates/display_text.html.erb.tt +18 -0
- data/lib/generators/b4um/in_place/templates/edit_attachment.html.erb.tt +83 -0
- data/lib/generators/b4um/in_place/templates/edit_attachments.html.erb.tt +65 -0
- data/lib/generators/b4um/in_place/templates/edit_boolean.html.erb.tt +32 -0
- data/lib/generators/b4um/in_place/templates/edit_number.html.erb.tt +26 -0
- data/lib/generators/b4um/in_place/templates/edit_radio.html.erb.tt +32 -0
- data/lib/generators/b4um/in_place/templates/edit_rich_text.html.erb.tt +25 -0
- data/lib/generators/b4um/in_place/templates/edit_select.html.erb.tt +28 -0
- data/lib/generators/b4um/in_place/templates/edit_text.html.erb.tt +25 -0
- data/lib/generators/b4um/in_place/templates/in_place.css +935 -0
- data/lib/generators/b4um/in_place/templates/in_place_controller.js +115 -0
- data/lib/generators/b4um/install/install_generator.rb +18 -13
- data/lib/generators/b4um/install/templates/_flash.html.erb +15 -0
- data/lib/generators/b4um/install/templates/_footer.html.erb +6 -1
- data/lib/generators/b4um/install/templates/b4um/forms.css +127 -0
- data/lib/generators/b4um/install/templates/b4um/tables.css +49 -0
- data/lib/generators/b4um/install/templates/image_lightbox_controller.js +34 -1
- data/lib/generators/b4um/install/templates/rich_text_controller.js +22 -0
- data/lib/generators/b4um/install/templates/scroll_to_top_controller.js +12 -0
- data/lib/generators/b4um/scaffold/scaffold_generator.rb +106 -0
- data/lib/generators/b4um/scaffold/templates/_form.html.erb.tt +29 -0
- data/lib/generators/b4um/scaffold/templates/_resource.html.erb.tt +35 -0
- data/lib/generators/b4um/scaffold/templates/_table.html.erb.tt +31 -0
- data/lib/generators/b4um/table/table_generator.rb +187 -5
- data/lib/generators/b4um/table/templates/_table.html.erb.tt +286 -0
- data/lib/generators/b4um/trix/trix_generator.rb +104 -6
- metadata +27 -3
|
@@ -14,6 +14,14 @@ module B4um
|
|
|
14
14
|
default: [],
|
|
15
15
|
banner: "field:type field:type"
|
|
16
16
|
|
|
17
|
+
class_option :select,
|
|
18
|
+
type: :string,
|
|
19
|
+
desc: "Renders a field as a select value. Example: status:Active=Aktiv,Inactive=Inaktiv"
|
|
20
|
+
|
|
21
|
+
class_option :radio,
|
|
22
|
+
type: :string,
|
|
23
|
+
desc: "Renders a field as a radio value. Example: condition:new=Neu,used=Gebraucht"
|
|
24
|
+
|
|
17
25
|
class << self
|
|
18
26
|
def desc(_description = nil)
|
|
19
27
|
"Generates a B4UM table partial for an existing model."
|
|
@@ -27,6 +35,22 @@ module B4um
|
|
|
27
35
|
"Model not found: app/models/#{file_name}.rb"
|
|
28
36
|
end
|
|
29
37
|
|
|
38
|
+
def validate_editor_configurations
|
|
39
|
+
configurations = {
|
|
40
|
+
select: select_configuration,
|
|
41
|
+
radio: radio_configuration
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
configurations.each do |option_name, configuration|
|
|
45
|
+
validate_editor_configuration(
|
|
46
|
+
option_name,
|
|
47
|
+
configuration
|
|
48
|
+
)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
validate_editor_configuration_conflict(configurations)
|
|
52
|
+
end
|
|
53
|
+
|
|
30
54
|
def create_table_partial
|
|
31
55
|
template(
|
|
32
56
|
"_table.html.erb.tt",
|
|
@@ -38,19 +62,177 @@ module B4um
|
|
|
38
62
|
)
|
|
39
63
|
end
|
|
40
64
|
|
|
65
|
+
def update_index_layout
|
|
66
|
+
return unless File.exist?(index_path)
|
|
67
|
+
|
|
68
|
+
index = File.read(index_path)
|
|
69
|
+
|
|
70
|
+
updated_index = index.sub(
|
|
71
|
+
/render\s+["'](?:bento|table|list|alternating)["']/,
|
|
72
|
+
'render "table"'
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
return if updated_index == index
|
|
76
|
+
|
|
77
|
+
File.write(index_path, updated_index)
|
|
78
|
+
end
|
|
79
|
+
|
|
41
80
|
private
|
|
42
81
|
|
|
43
|
-
def
|
|
44
|
-
|
|
45
|
-
|
|
82
|
+
def model_class
|
|
83
|
+
class_name.constantize
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def database_columns
|
|
87
|
+
model_class.columns.index_by(&:name)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def rich_text_fields
|
|
91
|
+
model_class.reflect_on_all_associations(:has_one)
|
|
92
|
+
.filter_map do |association|
|
|
93
|
+
association.name.to_s.delete_prefix("rich_text_") if
|
|
94
|
+
association.name.to_s.start_with?("rich_text_")
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def single_attachment_fields
|
|
99
|
+
model_class.reflect_on_all_attachments
|
|
100
|
+
.select { |reflection| reflection.macro == :has_one_attached }
|
|
101
|
+
.map { |reflection| reflection.name.to_s }
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def multiple_attachment_fields
|
|
105
|
+
model_class.reflect_on_all_attachments
|
|
106
|
+
.select { |reflection| reflection.macro == :has_many_attached }
|
|
107
|
+
.map { |reflection| reflection.name.to_s }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def available_field_names
|
|
111
|
+
(
|
|
112
|
+
database_field_names +
|
|
113
|
+
rich_text_fields +
|
|
114
|
+
single_attachment_fields +
|
|
115
|
+
multiple_attachment_fields
|
|
116
|
+
).uniq
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def database_field_names
|
|
120
|
+
database_columns.keys - %w[id created_at updated_at]
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def field_type(field)
|
|
124
|
+
return :rich_text if rich_text_fields.include?(field)
|
|
125
|
+
return :attachment if single_attachment_fields.include?(field)
|
|
126
|
+
return :attachments if multiple_attachment_fields.include?(field)
|
|
127
|
+
|
|
128
|
+
database_columns.fetch(field).type
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def table_field_names
|
|
132
|
+
return available_field_names if fields.empty?
|
|
133
|
+
|
|
134
|
+
fields.map { |field| field.split(":", 2).first }
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def validate_editor_configuration(option_name, configuration)
|
|
138
|
+
return unless options[option_name].present?
|
|
139
|
+
|
|
140
|
+
unless configuration
|
|
141
|
+
raise Thor::Error,
|
|
142
|
+
"Invalid --#{option_name} configuration. " \
|
|
143
|
+
"Expected FIELD:VALUE[,VALUE...]"
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
return if table_field_names.include?(configuration[:field])
|
|
147
|
+
|
|
148
|
+
raise Thor::Error,
|
|
149
|
+
"--#{option_name} field #{configuration[:field]} " \
|
|
150
|
+
"must be one of the generated fields: #{fields.join(", ")}"
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def validate_editor_configuration_conflict(configurations)
|
|
154
|
+
select = configurations[:select]
|
|
155
|
+
radio = configurations[:radio]
|
|
156
|
+
|
|
157
|
+
return unless select && radio
|
|
158
|
+
return unless select[:field] == radio[:field]
|
|
159
|
+
|
|
160
|
+
raise Thor::Error,
|
|
161
|
+
"Field #{select[:field]} cannot use both --select and --radio"
|
|
162
|
+
end
|
|
46
163
|
|
|
164
|
+
def select_configuration
|
|
165
|
+
field_configuration(:select)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def radio_configuration
|
|
169
|
+
field_configuration(:radio)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def field_configuration(option_name)
|
|
173
|
+
value = options[option_name]
|
|
174
|
+
return unless value.present?
|
|
175
|
+
|
|
176
|
+
field, values = value.split(":", 2)
|
|
177
|
+
|
|
178
|
+
return unless field.present? && values.present?
|
|
179
|
+
|
|
180
|
+
choices = field_choices(values)
|
|
181
|
+
return if choices.empty?
|
|
182
|
+
|
|
183
|
+
{
|
|
184
|
+
field: field,
|
|
185
|
+
values: choices
|
|
186
|
+
}
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def field_choices(values)
|
|
190
|
+
values.split(",").filter_map do |choice|
|
|
191
|
+
value, label = choice.strip.split("=", 2)
|
|
192
|
+
|
|
193
|
+
next if value.blank?
|
|
194
|
+
|
|
195
|
+
{
|
|
196
|
+
value: value,
|
|
197
|
+
label: label.presence || value
|
|
198
|
+
}
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def select_field?(field)
|
|
203
|
+
configuration = select_configuration
|
|
204
|
+
|
|
205
|
+
configuration &&
|
|
206
|
+
configuration[:field] == field &&
|
|
207
|
+
configuration[:values].any?
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def radio_field?(field)
|
|
211
|
+
configuration = radio_configuration
|
|
212
|
+
|
|
213
|
+
configuration &&
|
|
214
|
+
configuration[:field] == field &&
|
|
215
|
+
configuration[:values].any?
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def table_attributes
|
|
219
|
+
table_field_names.map do |field|
|
|
47
220
|
TableAttribute.new(
|
|
48
|
-
|
|
49
|
-
(
|
|
221
|
+
field,
|
|
222
|
+
field_type(field)
|
|
50
223
|
)
|
|
51
224
|
end
|
|
52
225
|
end
|
|
53
226
|
|
|
227
|
+
def index_path
|
|
228
|
+
File.join(
|
|
229
|
+
destination_root,
|
|
230
|
+
"app/views",
|
|
231
|
+
plural_table_name,
|
|
232
|
+
"index.html.erb"
|
|
233
|
+
)
|
|
234
|
+
end
|
|
235
|
+
|
|
54
236
|
def model_path
|
|
55
237
|
File.join(
|
|
56
238
|
destination_root,
|
|
@@ -14,12 +14,298 @@
|
|
|
14
14
|
<tr>
|
|
15
15
|
<% table_attributes.each do |attribute| -%>
|
|
16
16
|
<td>
|
|
17
|
+
<% if select_field?(attribute.name) -%>
|
|
17
18
|
<% if attribute.name == "status" -%>
|
|
19
|
+
<span class="b4um-badge">
|
|
20
|
+
<%%=
|
|
21
|
+
<%= select_configuration[:values].inspect %>.to_h {
|
|
22
|
+
|choice| [choice[:value], choice[:label]]
|
|
23
|
+
}.fetch(
|
|
24
|
+
<%= file_name %>.<%= attribute.name %>,
|
|
25
|
+
<%= file_name %>.<%= attribute.name %>
|
|
26
|
+
)
|
|
27
|
+
%>
|
|
28
|
+
</span>
|
|
29
|
+
<% else -%>
|
|
30
|
+
<%%=
|
|
31
|
+
<%= select_configuration[:values].inspect %>.to_h {
|
|
32
|
+
|choice| [choice[:value], choice[:label]]
|
|
33
|
+
}.fetch(
|
|
34
|
+
<%= file_name %>.<%= attribute.name %>,
|
|
35
|
+
<%= file_name %>.<%= attribute.name %>
|
|
36
|
+
)
|
|
37
|
+
%>
|
|
38
|
+
<% end -%>
|
|
39
|
+
<% elsif radio_field?(attribute.name) -%>
|
|
40
|
+
<%%=
|
|
41
|
+
<%= radio_configuration[:values].inspect %>.to_h {
|
|
42
|
+
|choice| [choice[:value], choice[:label]]
|
|
43
|
+
}.fetch(
|
|
44
|
+
<%= file_name %>.<%= attribute.name %>,
|
|
45
|
+
<%= file_name %>.<%= attribute.name %>
|
|
46
|
+
)
|
|
47
|
+
%>
|
|
48
|
+
<% elsif attribute.type == :rich_text -%>
|
|
49
|
+
<div
|
|
50
|
+
class="b4um-table__rich-text trix-content"
|
|
51
|
+
data-controller="image-lightbox rich-text"
|
|
52
|
+
data-action="keydown->image-lightbox#keydown"
|
|
53
|
+
>
|
|
54
|
+
<%%= <%= file_name %>.<%= attribute.name %> %>
|
|
55
|
+
|
|
56
|
+
<div
|
|
57
|
+
class="image-lightbox"
|
|
58
|
+
data-image-lightbox-target="overlay"
|
|
59
|
+
data-action="click->image-lightbox#closeOnBackground"
|
|
60
|
+
tabindex="-1"
|
|
61
|
+
role="dialog"
|
|
62
|
+
aria-modal="true"
|
|
63
|
+
aria-label="Image preview"
|
|
64
|
+
hidden
|
|
65
|
+
>
|
|
66
|
+
<div
|
|
67
|
+
class="image-lightbox__counter"
|
|
68
|
+
data-image-lightbox-target="counter"
|
|
69
|
+
></div>
|
|
70
|
+
|
|
71
|
+
<button
|
|
72
|
+
type="button"
|
|
73
|
+
class="image-lightbox__close"
|
|
74
|
+
aria-label="Close image"
|
|
75
|
+
data-action="click->image-lightbox#close"
|
|
76
|
+
>
|
|
77
|
+
×
|
|
78
|
+
</button>
|
|
79
|
+
|
|
80
|
+
<button
|
|
81
|
+
type="button"
|
|
82
|
+
class="image-lightbox__navigation image-lightbox__navigation--previous"
|
|
83
|
+
aria-label="Previous image"
|
|
84
|
+
data-action="click->image-lightbox#previous"
|
|
85
|
+
>
|
|
86
|
+
‹
|
|
87
|
+
</button>
|
|
88
|
+
|
|
89
|
+
<div
|
|
90
|
+
class="image-lightbox__stage"
|
|
91
|
+
data-image-lightbox-target="stage"
|
|
92
|
+
data-action="
|
|
93
|
+
pointerdown->image-lightbox#pointerDown
|
|
94
|
+
pointermove->image-lightbox#pointerMove
|
|
95
|
+
pointerup->image-lightbox#pointerUp
|
|
96
|
+
pointercancel->image-lightbox#pointerCancel
|
|
97
|
+
"
|
|
98
|
+
>
|
|
99
|
+
<img
|
|
100
|
+
class="image-lightbox__image"
|
|
101
|
+
data-image-lightbox-target="image"
|
|
102
|
+
alt=""
|
|
103
|
+
>
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
<button
|
|
107
|
+
type="button"
|
|
108
|
+
class="image-lightbox__navigation image-lightbox__navigation--next"
|
|
109
|
+
aria-label="Next image"
|
|
110
|
+
data-action="click->image-lightbox#next"
|
|
111
|
+
>
|
|
112
|
+
›
|
|
113
|
+
</button>
|
|
114
|
+
|
|
115
|
+
<div
|
|
116
|
+
class="image-lightbox__thumbnails"
|
|
117
|
+
data-image-lightbox-target="thumbnails"
|
|
118
|
+
></div>
|
|
119
|
+
|
|
120
|
+
<div
|
|
121
|
+
class="image-lightbox__caption"
|
|
122
|
+
data-image-lightbox-target="caption"
|
|
123
|
+
></div>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
<% elsif attribute.type == :attachment -%>
|
|
127
|
+
<%% if <%= file_name %>.<%= attribute.name %>.attached? %>
|
|
128
|
+
<div
|
|
129
|
+
class="b4um-table__media"
|
|
130
|
+
data-controller="image-lightbox"
|
|
131
|
+
data-action="keydown->image-lightbox#keydown"
|
|
132
|
+
>
|
|
133
|
+
<button
|
|
134
|
+
type="button"
|
|
135
|
+
class="b4um-table__image-button"
|
|
136
|
+
data-image-lightbox-target="item"
|
|
137
|
+
data-image-lightbox-url="<%%= url_for(<%= file_name %>.<%= attribute.name %>) %>"
|
|
138
|
+
data-image-lightbox-alt="<%%= <%= file_name %>.<%= attribute.name %>.filename.to_s %>"
|
|
139
|
+
data-action="click->image-lightbox#open"
|
|
140
|
+
>
|
|
141
|
+
<%%= image_tag <%= file_name %>.<%= attribute.name %>,
|
|
142
|
+
class: "b4um-table__image",
|
|
143
|
+
alt: <%= file_name %>.<%= attribute.name %>.filename.to_s %>
|
|
144
|
+
</button>
|
|
145
|
+
|
|
146
|
+
<div
|
|
147
|
+
class="image-lightbox"
|
|
148
|
+
data-image-lightbox-target="overlay"
|
|
149
|
+
data-action="click->image-lightbox#closeOnBackground"
|
|
150
|
+
tabindex="-1"
|
|
151
|
+
role="dialog"
|
|
152
|
+
aria-modal="true"
|
|
153
|
+
aria-label="Image preview"
|
|
154
|
+
hidden
|
|
155
|
+
>
|
|
156
|
+
<div
|
|
157
|
+
class="image-lightbox__counter"
|
|
158
|
+
data-image-lightbox-target="counter"
|
|
159
|
+
></div>
|
|
160
|
+
|
|
161
|
+
<button
|
|
162
|
+
type="button"
|
|
163
|
+
class="image-lightbox__close"
|
|
164
|
+
aria-label="Close image"
|
|
165
|
+
data-action="click->image-lightbox#close"
|
|
166
|
+
>
|
|
167
|
+
×
|
|
168
|
+
</button>
|
|
169
|
+
|
|
170
|
+
<div
|
|
171
|
+
class="image-lightbox__stage"
|
|
172
|
+
data-image-lightbox-target="stage"
|
|
173
|
+
data-action="
|
|
174
|
+
pointerdown->image-lightbox#pointerDown
|
|
175
|
+
pointermove->image-lightbox#pointerMove
|
|
176
|
+
pointerup->image-lightbox#pointerUp
|
|
177
|
+
pointercancel->image-lightbox#pointerCancel
|
|
178
|
+
"
|
|
179
|
+
>
|
|
180
|
+
<img
|
|
181
|
+
class="image-lightbox__image"
|
|
182
|
+
data-image-lightbox-target="image"
|
|
183
|
+
alt=""
|
|
184
|
+
>
|
|
185
|
+
</div>
|
|
186
|
+
|
|
187
|
+
<div
|
|
188
|
+
class="image-lightbox__thumbnails"
|
|
189
|
+
data-image-lightbox-target="thumbnails"
|
|
190
|
+
></div>
|
|
191
|
+
|
|
192
|
+
<div
|
|
193
|
+
class="image-lightbox__caption"
|
|
194
|
+
data-image-lightbox-target="caption"
|
|
195
|
+
></div>
|
|
196
|
+
</div>
|
|
197
|
+
</div>
|
|
198
|
+
<%% else %>
|
|
199
|
+
<span class="b4um-table__media-empty">No image</span>
|
|
200
|
+
<%% end %>
|
|
201
|
+
<% elsif attribute.type == :attachments -%>
|
|
202
|
+
<%% if <%= file_name %>.<%= attribute.name %>.attached? %>
|
|
203
|
+
<div
|
|
204
|
+
class="b4um-table__media"
|
|
205
|
+
data-controller="image-lightbox"
|
|
206
|
+
data-action="keydown->image-lightbox#keydown"
|
|
207
|
+
>
|
|
208
|
+
<%% <%= file_name %>.<%= attribute.name %>.each do |image| %>
|
|
209
|
+
<button
|
|
210
|
+
type="button"
|
|
211
|
+
class="b4um-table__image-button"
|
|
212
|
+
data-image-lightbox-target="item"
|
|
213
|
+
data-image-lightbox-url="<%%= url_for(image) %>"
|
|
214
|
+
data-image-lightbox-alt="<%%= image.filename.to_s %>"
|
|
215
|
+
data-action="click->image-lightbox#open"
|
|
216
|
+
>
|
|
217
|
+
<%%= image_tag image,
|
|
218
|
+
class: "b4um-table__image",
|
|
219
|
+
alt: image.filename.to_s %>
|
|
220
|
+
</button>
|
|
221
|
+
<%% end %>
|
|
222
|
+
|
|
223
|
+
<div
|
|
224
|
+
class="image-lightbox"
|
|
225
|
+
data-image-lightbox-target="overlay"
|
|
226
|
+
data-action="click->image-lightbox#closeOnBackground"
|
|
227
|
+
tabindex="-1"
|
|
228
|
+
role="dialog"
|
|
229
|
+
aria-modal="true"
|
|
230
|
+
aria-label="Image gallery"
|
|
231
|
+
hidden
|
|
232
|
+
>
|
|
233
|
+
<div
|
|
234
|
+
class="image-lightbox__counter"
|
|
235
|
+
data-image-lightbox-target="counter"
|
|
236
|
+
></div>
|
|
237
|
+
|
|
238
|
+
<button
|
|
239
|
+
type="button"
|
|
240
|
+
class="image-lightbox__close"
|
|
241
|
+
aria-label="Close image"
|
|
242
|
+
data-action="click->image-lightbox#close"
|
|
243
|
+
>
|
|
244
|
+
×
|
|
245
|
+
</button>
|
|
246
|
+
|
|
247
|
+
<button
|
|
248
|
+
type="button"
|
|
249
|
+
class="image-lightbox__navigation image-lightbox__navigation--previous"
|
|
250
|
+
aria-label="Previous image"
|
|
251
|
+
data-action="click->image-lightbox#previous"
|
|
252
|
+
>
|
|
253
|
+
‹
|
|
254
|
+
</button>
|
|
255
|
+
|
|
256
|
+
<div
|
|
257
|
+
class="image-lightbox__stage"
|
|
258
|
+
data-image-lightbox-target="stage"
|
|
259
|
+
data-action="
|
|
260
|
+
pointerdown->image-lightbox#pointerDown
|
|
261
|
+
pointermove->image-lightbox#pointerMove
|
|
262
|
+
pointerup->image-lightbox#pointerUp
|
|
263
|
+
pointercancel->image-lightbox#pointerCancel
|
|
264
|
+
"
|
|
265
|
+
>
|
|
266
|
+
<img
|
|
267
|
+
class="image-lightbox__image"
|
|
268
|
+
data-image-lightbox-target="image"
|
|
269
|
+
alt=""
|
|
270
|
+
>
|
|
271
|
+
</div>
|
|
272
|
+
|
|
273
|
+
<button
|
|
274
|
+
type="button"
|
|
275
|
+
class="image-lightbox__navigation image-lightbox__navigation--next"
|
|
276
|
+
aria-label="Next image"
|
|
277
|
+
data-action="click->image-lightbox#next"
|
|
278
|
+
>
|
|
279
|
+
›
|
|
280
|
+
</button>
|
|
281
|
+
|
|
282
|
+
<div
|
|
283
|
+
class="image-lightbox__thumbnails"
|
|
284
|
+
data-image-lightbox-target="thumbnails"
|
|
285
|
+
></div>
|
|
286
|
+
|
|
287
|
+
<div
|
|
288
|
+
class="image-lightbox__caption"
|
|
289
|
+
data-image-lightbox-target="caption"
|
|
290
|
+
></div>
|
|
291
|
+
</div>
|
|
292
|
+
</div>
|
|
293
|
+
<%% else %>
|
|
294
|
+
<span class="b4um-table__media-empty">No images</span>
|
|
295
|
+
<%% end %>
|
|
296
|
+
<% elsif attribute.name == "status" -%>
|
|
18
297
|
<span class="b4um-badge">
|
|
19
298
|
<%%= <%= file_name %>.<%= attribute.name %> %>
|
|
20
299
|
</span>
|
|
21
300
|
<% elsif attribute.type == :text -%>
|
|
22
301
|
<%%= truncate(<%= file_name %>.<%= attribute.name %>, length: 100) %>
|
|
302
|
+
<% elsif attribute.type == :decimal -%>
|
|
303
|
+
<%%= number_with_precision(
|
|
304
|
+
<%= file_name %>.<%= attribute.name %>,
|
|
305
|
+
precision: 2,
|
|
306
|
+
delimiter: ".",
|
|
307
|
+
separator: ","
|
|
308
|
+
) %>
|
|
23
309
|
<% else -%>
|
|
24
310
|
<%%= <%= file_name %>.<%= attribute.name %> %>
|
|
25
311
|
<% end -%>
|
|
@@ -133,16 +133,75 @@ module B4um
|
|
|
133
133
|
end
|
|
134
134
|
|
|
135
135
|
def update_form
|
|
136
|
-
|
|
136
|
+
form = File.read(form_path)
|
|
137
|
+
|
|
138
|
+
return if form.include?("form.rich_text_area :#{attribute}")
|
|
139
|
+
|
|
140
|
+
if form.include?("form.text_area :#{attribute}")
|
|
141
|
+
gsub_file(
|
|
142
|
+
form_path,
|
|
143
|
+
"form.text_area :#{attribute}",
|
|
144
|
+
"form.rich_text_area :#{attribute}"
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
gsub_file(
|
|
148
|
+
form_path,
|
|
149
|
+
/<div class="form-field form-field--textarea">(?=\s*<%= form\.rich_text_area :#{Regexp.escape(attribute)})/,
|
|
150
|
+
'<div class="form-field form-field--rich-text">'
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
return
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
insert_into_file(
|
|
137
157
|
form_path,
|
|
138
|
-
|
|
139
|
-
|
|
158
|
+
<<~ERB,
|
|
159
|
+
<div class="form-field form-field--rich-text">
|
|
160
|
+
<%= form.rich_text_area :#{attribute} %>
|
|
161
|
+
<%= form.label :#{attribute}, class: "form-label" %>
|
|
162
|
+
</div>
|
|
163
|
+
|
|
164
|
+
ERB
|
|
165
|
+
before: ' <div class="form-actions">'
|
|
140
166
|
)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def update_controller_params
|
|
170
|
+
return unless File.exist?(controller_path)
|
|
171
|
+
|
|
172
|
+
controller = File.read(controller_path)
|
|
173
|
+
|
|
174
|
+
params_method = controller[
|
|
175
|
+
/def #{Regexp.escape(name.underscore)}_params.*?^\s*end/m,
|
|
176
|
+
0
|
|
177
|
+
]
|
|
178
|
+
|
|
179
|
+
unless params_method
|
|
180
|
+
raise Thor::Error,
|
|
181
|
+
"Could not find #{name.underscore}_params in #{controller_path}"
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
parameter = ":#{attribute}"
|
|
185
|
+
|
|
186
|
+
return if params_method.include?(parameter)
|
|
187
|
+
|
|
188
|
+
updated_method =
|
|
189
|
+
if params_method.match?(/\w+:\s*\[\]/)
|
|
190
|
+
params_method.sub(
|
|
191
|
+
/(?=\w+:\s*\[\])/,
|
|
192
|
+
"#{parameter}, "
|
|
193
|
+
)
|
|
194
|
+
else
|
|
195
|
+
params_method.sub(
|
|
196
|
+
/\s*\]\s*\)\s*$/,
|
|
197
|
+
", #{parameter} ])"
|
|
198
|
+
)
|
|
199
|
+
end
|
|
141
200
|
|
|
142
201
|
gsub_file(
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
202
|
+
controller_path,
|
|
203
|
+
params_method,
|
|
204
|
+
updated_method
|
|
146
205
|
)
|
|
147
206
|
end
|
|
148
207
|
|
|
@@ -151,6 +210,8 @@ module B4um
|
|
|
151
210
|
|
|
152
211
|
resource_name = name.underscore
|
|
153
212
|
|
|
213
|
+
add_rich_text_resource_field(resource_name)
|
|
214
|
+
|
|
154
215
|
preview_length =
|
|
155
216
|
'local_assigns\.fetch\(:preview_length,\s*160\)'
|
|
156
217
|
|
|
@@ -374,6 +435,36 @@ module B4um
|
|
|
374
435
|
|
|
375
436
|
private
|
|
376
437
|
|
|
438
|
+
def add_rich_text_resource_field(resource_name)
|
|
439
|
+
partial = File.read(resource_partial_path)
|
|
440
|
+
|
|
441
|
+
return if partial.include?("#{resource_name}.#{attribute}")
|
|
442
|
+
|
|
443
|
+
field = <<~ERB
|
|
444
|
+
<div class="resource-field">
|
|
445
|
+
<strong class="resource-label">#{attribute.humanize}:</strong>
|
|
446
|
+
<span class="resource-value">
|
|
447
|
+
<% if local_assigns[:compact] %>
|
|
448
|
+
<%= b4um_rich_text_preview(
|
|
449
|
+
#{resource_name}.#{attribute},
|
|
450
|
+
length: local_assigns.fetch(:preview_length, 160)
|
|
451
|
+
) %>
|
|
452
|
+
<% else %>
|
|
453
|
+
<%= #{resource_name}.#{attribute} %>
|
|
454
|
+
<% end %>
|
|
455
|
+
</span>
|
|
456
|
+
</div>
|
|
457
|
+
ERB
|
|
458
|
+
|
|
459
|
+
closing_div = partial.rindex("</div>")
|
|
460
|
+
|
|
461
|
+
return unless closing_div
|
|
462
|
+
|
|
463
|
+
partial.insert(closing_div, field)
|
|
464
|
+
|
|
465
|
+
File.write(resource_partial_path, partial)
|
|
466
|
+
end
|
|
467
|
+
|
|
377
468
|
def action_text_installed?
|
|
378
469
|
Dir.glob(
|
|
379
470
|
File.join(
|
|
@@ -401,6 +492,13 @@ module B4um
|
|
|
401
492
|
)
|
|
402
493
|
end
|
|
403
494
|
|
|
495
|
+
def controller_path
|
|
496
|
+
File.join(
|
|
497
|
+
destination_root,
|
|
498
|
+
"app/controllers/#{name.underscore.pluralize}_controller.rb"
|
|
499
|
+
)
|
|
500
|
+
end
|
|
501
|
+
|
|
404
502
|
def resource_partial_path
|
|
405
503
|
File.join(
|
|
406
504
|
destination_root,
|