action_blocks 0.1.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 +7 -0
- data/LICENSE +21 -0
- data/README.md +121 -0
- data/Rakefile +33 -0
- data/app/assets/config/action_blocks.js +2 -0
- data/app/assets/javascripts/action_blocks/application.js +15 -0
- data/app/assets/stylesheets/action_blocks/application.css +15 -0
- data/app/controllers/action_blocks/attachments_controller.rb +22 -0
- data/app/controllers/action_blocks/barchart_blocks_controller.rb +14 -0
- data/app/controllers/action_blocks/base_controller.rb +22 -0
- data/app/controllers/action_blocks/blocks_controller.rb +16 -0
- data/app/controllers/action_blocks/command_blocks_controller.rb +6 -0
- data/app/controllers/action_blocks/form_blocks_controller.rb +13 -0
- data/app/controllers/action_blocks/model_blocks_controller.rb +13 -0
- data/app/controllers/action_blocks/table_blocks_controller.rb +13 -0
- data/app/controllers/action_blocks/workspace_blocks_controller.rb +6 -0
- data/app/helpers/action_blocks/application_helper.rb +4 -0
- data/app/jobs/action_blocks/application_job.rb +4 -0
- data/app/mailers/action_blocks/application_mailer.rb +6 -0
- data/app/models/action_blocks/application_record.rb +5 -0
- data/app/views/layouts/action_blocks/application.html.erb +16 -0
- data/config/initializers/action_blocks.rb +9 -0
- data/config/routes.rb +10 -0
- data/lib/action_block_loader.rb +120 -0
- data/lib/action_blocks.rb +76 -0
- data/lib/action_blocks/builders/authorization_builder.rb +21 -0
- data/lib/action_blocks/builders/barchart_builder.rb +48 -0
- data/lib/action_blocks/builders/base_builder.rb +221 -0
- data/lib/action_blocks/builders/block_type.rb +11 -0
- data/lib/action_blocks/builders/command_builder.rb +6 -0
- data/lib/action_blocks/builders/form_builder.rb +117 -0
- data/lib/action_blocks/builders/layout_builder.rb +15 -0
- data/lib/action_blocks/builders/model_builder.rb +566 -0
- data/lib/action_blocks/builders/summary_field_aggregation_functions.rb +41 -0
- data/lib/action_blocks/builders/table_builder.rb +259 -0
- data/lib/action_blocks/builders/workspace_builder.rb +282 -0
- data/lib/action_blocks/data_engine/authorization_adapter.rb +127 -0
- data/lib/action_blocks/data_engine/data_engine.rb +116 -0
- data/lib/action_blocks/data_engine/database_functions.rb +39 -0
- data/lib/action_blocks/data_engine/fields_engine.rb +103 -0
- data/lib/action_blocks/data_engine/filter_adapter.rb +105 -0
- data/lib/action_blocks/data_engine/filter_engine.rb +88 -0
- data/lib/action_blocks/data_engine/selections_via_where_engine.rb +134 -0
- data/lib/action_blocks/data_engine/summary_engine.rb +72 -0
- data/lib/action_blocks/engine.rb +5 -0
- data/lib/action_blocks/error.rb +62 -0
- data/lib/action_blocks/generator_helper.rb +134 -0
- data/lib/action_blocks/generators/action_blocks/model_block/USAGE +8 -0
- data/lib/action_blocks/generators/action_blocks/model_block/model_block_generator.rb +17 -0
- data/lib/action_blocks/generators/action_blocks/model_block/templates/model_block.rb +13 -0
- data/lib/action_blocks/generators/action_blocks/type/USAGE +8 -0
- data/lib/action_blocks/generators/action_blocks/type/templates/controller.rb +3 -0
- data/lib/action_blocks/generators/action_blocks/type/templates/dsl.rb +38 -0
- data/lib/action_blocks/generators/action_blocks/type/templates/type.css +3 -0
- data/lib/action_blocks/generators/action_blocks/type/templates/type.js +22 -0
- data/lib/action_blocks/generators/action_blocks/type/type_generator.rb +33 -0
- data/lib/action_blocks/store.rb +151 -0
- data/lib/action_blocks/version.rb +3 -0
- data/lib/generators/active_blocks/model_block/USAGE +8 -0
- data/lib/generators/active_blocks/model_block/model_block_generator.rb +17 -0
- data/lib/generators/active_blocks/model_block/templates/model_block.rb +13 -0
- data/lib/generators/active_blocks/type/USAGE +8 -0
- data/lib/generators/active_blocks/type/templates/controller.rb +3 -0
- data/lib/generators/active_blocks/type/templates/dsl.rb +38 -0
- data/lib/generators/active_blocks/type/templates/type.css +3 -0
- data/lib/generators/active_blocks/type/templates/type.js +22 -0
- data/lib/generators/active_blocks/type/type_generator.rb +33 -0
- data/lib/tasks/active_blocks_tasks.rake +4 -0
- metadata +128 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module ActionBlocks
|
|
2
|
+
class LayoutBuilder < ActionBlocks::BlockType
|
|
3
|
+
block_type :layout
|
|
4
|
+
sets :title
|
|
5
|
+
builds_many :workspaces, :workspace, 'ActionBlocks::WorkspaceBuilder'
|
|
6
|
+
|
|
7
|
+
def hashify(user)
|
|
8
|
+
{
|
|
9
|
+
key: key,
|
|
10
|
+
title: @title,
|
|
11
|
+
workspace_keys: @workspaces.map(&:key),
|
|
12
|
+
}
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,566 @@
|
|
|
1
|
+
module ActionBlocks
|
|
2
|
+
class ModelBuilder < ActionBlocks::BlockType
|
|
3
|
+
block_type :model
|
|
4
|
+
sets :active_model
|
|
5
|
+
sets :singular_name
|
|
6
|
+
sets :plural_name
|
|
7
|
+
references :name_field, :field, -> (s, obj) {"field-#{obj.id}-#{s}"}
|
|
8
|
+
|
|
9
|
+
builds_many :fields, :identity, 'ActionBlocks::IdentityFieldBuilder'
|
|
10
|
+
builds_many :fields, :string, 'ActionBlocks::StringFieldBuilder'
|
|
11
|
+
builds_many :fields, :text, 'ActionBlocks::TextFieldBuilder'
|
|
12
|
+
builds_many :fields, :datetime, 'ActionBlocks::DatetimeFieldBuilder'
|
|
13
|
+
builds_many :fields, :date, 'ActionBlocks::DateFieldBuilder'
|
|
14
|
+
builds_many :fields, :integer, 'ActionBlocks::IntegerFieldBuilder'
|
|
15
|
+
builds_many :fields, :attachment, 'ActionBlocks::AttachmentBuilder'
|
|
16
|
+
|
|
17
|
+
builds_many :fields, :references, 'ActionBlocks::ReferenceFieldBuilder'
|
|
18
|
+
builds_many :selections, :selection, 'ActionBlocks::SelectionBuilder'
|
|
19
|
+
|
|
20
|
+
validate :active_model_is_an_active_record_class
|
|
21
|
+
def active_model_is_an_active_record_class
|
|
22
|
+
if @active_model.class != Class
|
|
23
|
+
errors.add(:active_model, "Must be an ActiveRecord Class")
|
|
24
|
+
else
|
|
25
|
+
if !@active_model.ancestors.include? ActiveRecord::Base
|
|
26
|
+
errors.add(:active_model, "Must be an ActiveRecord Class")
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def after_build(parent, *args)
|
|
32
|
+
# Every model has an identity field
|
|
33
|
+
if !@fields.map(&:id).include?(:id)
|
|
34
|
+
@dsl_delegate.identity
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def select_requirements(fields = nil)
|
|
39
|
+
sel_reqs = @fields.map(&:select_requirements)
|
|
40
|
+
sel_reqs = sel_reqs.select { |r| fields.include? r[:field_name] } unless fields.nil?
|
|
41
|
+
|
|
42
|
+
return sel_reqs
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def name_to_json(record_id:, user:)
|
|
46
|
+
select_reqs = [name_field.select_requirements]
|
|
47
|
+
filter_reqs = [:eq, :id, record_id]
|
|
48
|
+
engine = DataEngine.new(active_model, select_reqs: select_reqs, filter_reqs: filter_reqs)
|
|
49
|
+
engine.first_to_json
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def selection_filter_reqs(record_id:, user:)
|
|
53
|
+
[
|
|
54
|
+
{
|
|
55
|
+
base_path: [active_model, :id],
|
|
56
|
+
predicate: :eq,
|
|
57
|
+
related_path: [record_id]
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def filter_reqs(record_id:, user:)
|
|
63
|
+
[:eq, :id, record_id]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def hashify(user)
|
|
67
|
+
{
|
|
68
|
+
key: key,
|
|
69
|
+
type: type,
|
|
70
|
+
name_field: name_field.try(:id),
|
|
71
|
+
singular_name: singular_name,
|
|
72
|
+
plural_name: plural_name
|
|
73
|
+
}
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
class ActionBlocks::SelectionBuilder < ActionBlocks::BlockType
|
|
79
|
+
attr_accessor :base_model, :related_model_id, :match_conditions_source
|
|
80
|
+
references :related_model
|
|
81
|
+
block_type :selection
|
|
82
|
+
builds_many :match_conditions, :match_condition, 'ActionBlocks::MatchConditionBuilder'
|
|
83
|
+
builds_many :summaries, :summary, 'ActionBlocks::SummaryFieldBuilder'
|
|
84
|
+
|
|
85
|
+
validate :match_conditions_exist
|
|
86
|
+
def match_conditions_exist
|
|
87
|
+
if @match_conditions.length == 0
|
|
88
|
+
errors.add(:match_conditions, "No match conditions on selection #{key}")
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
validate :match_conditions_come_from_relation_if_relation_exists
|
|
93
|
+
def match_conditions_come_from_relation_if_relation_exists
|
|
94
|
+
if @match_conditions_source == 'user defined'
|
|
95
|
+
# puts @base_model.active_model.reflections.keys.inspect
|
|
96
|
+
relation = @base_model.active_model.reflections[@id.to_s]
|
|
97
|
+
|
|
98
|
+
if relation && relation.collection?
|
|
99
|
+
errors.add(:match_conditions, "Selections name matches name of has_many, but defines match_conditions anyway")
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def key
|
|
105
|
+
"selection-#{@base_model.id}-#{@id}"
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def before_build(parent, id, *args)
|
|
109
|
+
@base_model = parent
|
|
110
|
+
@id = id # aka name
|
|
111
|
+
if args[0]
|
|
112
|
+
@related_model_id = args[0].to_sym
|
|
113
|
+
else
|
|
114
|
+
@related_model_id = @id.to_s.singularize.to_sym
|
|
115
|
+
end
|
|
116
|
+
@related_model_key = "model-#{@related_model_id}"
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def after_build(parent, *args)
|
|
120
|
+
if @match_conditions.length == 0
|
|
121
|
+
build_match_conditions_by_reflecting
|
|
122
|
+
else
|
|
123
|
+
@match_conditions_source = "user defined"
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def build_match_conditions_by_reflecting
|
|
128
|
+
relation = @base_model.active_model.reflections[@id.to_s]
|
|
129
|
+
if relation && relation.collection?
|
|
130
|
+
@match_conditions_source = "relation"
|
|
131
|
+
if relation.class == ActiveRecord::Reflection::HasManyReflection
|
|
132
|
+
@dsl_delegate.match_condition relation.join_keys.foreign_key.to_sym, :eq, relation.join_keys.key.to_sym
|
|
133
|
+
else
|
|
134
|
+
raise "Relation #{relation.class} not supported"
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def match_reqs(*p)
|
|
140
|
+
user = p.first
|
|
141
|
+
match_conditions.map(&:match_reqs)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def record_filter_reqs(record:, user:)
|
|
145
|
+
if record.class != @base_model.active_model
|
|
146
|
+
raise "Selection issue."
|
|
147
|
+
end
|
|
148
|
+
@base_model.selection_filter_reqs(record_id: record.id, user: user)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def hashify(user)
|
|
152
|
+
{
|
|
153
|
+
key: key,
|
|
154
|
+
type: type
|
|
155
|
+
}
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Base - Refers to the selecting model and fields on selecting model
|
|
161
|
+
# Related - Refers to the selected model and fields on selected model
|
|
162
|
+
# e.g. When a Work Order selects Items
|
|
163
|
+
# Item is Related Model
|
|
164
|
+
# WorkOrder is Base Model
|
|
165
|
+
#
|
|
166
|
+
# When building a match condition, its defined in the Base Models
|
|
167
|
+
# builder.
|
|
168
|
+
# e.g. When a Work Order selects Items
|
|
169
|
+
# This selection is declared in the Work Order Model
|
|
170
|
+
#
|
|
171
|
+
# When using a selection to select related items, such as a table
|
|
172
|
+
# the Base Model (Work Order) feels a bit misnamed from this context
|
|
173
|
+
# as Items are being selected and form the foundation of the query.
|
|
174
|
+
|
|
175
|
+
class ActionBlocks::MatchConditionBuilder < ActionBlocks::BaseBuilder
|
|
176
|
+
attr_accessor :related_field_id, :base_field_id, :parent_model, :related_model
|
|
177
|
+
references :base_field
|
|
178
|
+
references :related_field
|
|
179
|
+
sets :predicate
|
|
180
|
+
|
|
181
|
+
def before_build(parent, base_field, predicate, related_field)
|
|
182
|
+
if base_field.is_a? Symbol
|
|
183
|
+
@base_model = parent.base_model
|
|
184
|
+
@base_field_id = base_field
|
|
185
|
+
@base_field_key = "field-#{parent.base_model.id}-#{@base_field_id}"
|
|
186
|
+
else
|
|
187
|
+
@base_value = base_field
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
@related_model = parent.related_model
|
|
191
|
+
@related_field_id = related_field
|
|
192
|
+
@related_field_key = "field-#{parent.related_model_id}-#{@related_field_id}"
|
|
193
|
+
|
|
194
|
+
@predicate = predicate
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def base_match_reqs
|
|
198
|
+
if @base_value
|
|
199
|
+
{
|
|
200
|
+
path: [@base_value]
|
|
201
|
+
}
|
|
202
|
+
else
|
|
203
|
+
field_reqs = base_field.match_requirements(@base_model.active_model)
|
|
204
|
+
{
|
|
205
|
+
path: field_reqs[:path]
|
|
206
|
+
}
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def related_match_reqs
|
|
211
|
+
field_reqs = related_field.match_requirements()
|
|
212
|
+
{
|
|
213
|
+
path: field_reqs[:path]
|
|
214
|
+
}
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def match_reqs
|
|
218
|
+
{
|
|
219
|
+
base_path: base_match_reqs[:path],
|
|
220
|
+
predicate: @predicate,
|
|
221
|
+
related_path: related_match_reqs[:path]
|
|
222
|
+
}
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
class ActionBlocks::FieldBlock < ActionBlocks::BlockType
|
|
228
|
+
attr_accessor :parent_model, :field_type
|
|
229
|
+
block_type :field
|
|
230
|
+
sets :name
|
|
231
|
+
sets :label
|
|
232
|
+
|
|
233
|
+
def key
|
|
234
|
+
"field-#{@parent_model.id}-#{@id}"
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def select_requirements(select_as_prefix = nil)
|
|
238
|
+
{
|
|
239
|
+
field_name: [select_as_prefix,@id].compact.join('_').to_sym,
|
|
240
|
+
path: [@id]
|
|
241
|
+
}
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def match_requirements(select_as_prefix = nil)
|
|
245
|
+
{
|
|
246
|
+
path: [select_as_prefix, @id].compact
|
|
247
|
+
}
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def before_build(parent, *args)
|
|
251
|
+
@parent_model = parent
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
class SummaryFieldBuilder < ActionBlocks::FieldBlock
|
|
256
|
+
include ActionBlocks::SummaryFieldAggregationFunctions
|
|
257
|
+
attr_accessor :parent_reference, :aggregation, :base_model, :related_model_id, :related_model
|
|
258
|
+
references :target_field
|
|
259
|
+
sets :aggregate
|
|
260
|
+
sets :aggregate_parameters
|
|
261
|
+
builds_many :filters, :filter, 'ActionBlocks::MatchConditionBuilder'
|
|
262
|
+
|
|
263
|
+
# validates :aggregate, inclusion: { in: %i[sum count avg min max string_agg] }
|
|
264
|
+
|
|
265
|
+
def before_build(parent, *args)
|
|
266
|
+
@base_model = parent.base_model # required lookup for match conditions
|
|
267
|
+
@related_model = parent.related_model # required lookup for match conditions
|
|
268
|
+
@related_model_id = parent.related_model_id # required lookup for match conditions
|
|
269
|
+
|
|
270
|
+
@field_type = 'summary'
|
|
271
|
+
@field_name = args[0]
|
|
272
|
+
@parent_reference = parent
|
|
273
|
+
@parent_model = @parent_reference.base_model
|
|
274
|
+
|
|
275
|
+
@aggregate = args[1]
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def after_build(parent, *args)
|
|
279
|
+
@parent_model.fields.append(self)
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
# summary_reqs = [{
|
|
283
|
+
# type: :summary
|
|
284
|
+
# root_klass: Rate,
|
|
285
|
+
# select_req: { field_name: :count_of_rates, path: [:id], aggregate: ->(*args) { count(*args) } },
|
|
286
|
+
# match_reqs: [{
|
|
287
|
+
# base_path: [WorkOrder, :rate_sheet_id], # work_order
|
|
288
|
+
# predicate: :eq,
|
|
289
|
+
# related_path: [:rate_sheet_id] # rate
|
|
290
|
+
# }]
|
|
291
|
+
# }]
|
|
292
|
+
def select_requirements(select_as_prefix = nil)
|
|
293
|
+
path_and_function = instance_exec(&@aggregate)
|
|
294
|
+
path = path_and_function[:path]
|
|
295
|
+
function = path_and_function[:function]
|
|
296
|
+
|
|
297
|
+
{
|
|
298
|
+
type: :summary,
|
|
299
|
+
root_klass: parent_reference.related_model.active_model,
|
|
300
|
+
select_req: {
|
|
301
|
+
field_name: @field_name,
|
|
302
|
+
path: path,
|
|
303
|
+
function: function
|
|
304
|
+
},
|
|
305
|
+
match_reqs: parent_reference.match_reqs,
|
|
306
|
+
filter_reqs: filters.map(&:match_reqs)
|
|
307
|
+
}
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def hashify(user)
|
|
311
|
+
{
|
|
312
|
+
type: :summary,
|
|
313
|
+
id: @id
|
|
314
|
+
}
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
class IdentityFieldBuilder < ActionBlocks::FieldBlock
|
|
319
|
+
def before_build(parent, *args)
|
|
320
|
+
@field_type = 'identity'
|
|
321
|
+
@id = :id
|
|
322
|
+
super(parent, :id)
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
def select_requirements(select_as_prefix = nil)
|
|
326
|
+
{
|
|
327
|
+
field_name: [select_as_prefix,@id].compact.join('_').to_sym,
|
|
328
|
+
path: [@id]
|
|
329
|
+
}
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def match_requirements(select_as_prefix = nil)
|
|
333
|
+
{
|
|
334
|
+
path: [select_as_prefix, @id].compact
|
|
335
|
+
}
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
def hashify(user)
|
|
339
|
+
{
|
|
340
|
+
type: :identity,
|
|
341
|
+
id: @id,
|
|
342
|
+
key: @key
|
|
343
|
+
}
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
class ReferenceFieldBuilder < ActionBlocks::FieldBlock
|
|
349
|
+
attr_accessor :association_name
|
|
350
|
+
references :model
|
|
351
|
+
builds_many :lookups, :lookup, 'ActionBlocks::LookupFieldBuilder'
|
|
352
|
+
|
|
353
|
+
def before_build(parent, *args)
|
|
354
|
+
super(parent, *args)
|
|
355
|
+
@association_name = args[0]
|
|
356
|
+
@field_type = 'reference'
|
|
357
|
+
@model_key = "model-#{args[1] || args[0]}"
|
|
358
|
+
add_foreign_key_as_integer(parent)
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
def add_foreign_key_as_integer(parent)
|
|
362
|
+
if relation
|
|
363
|
+
parent.dsl_delegate.integer(relation.join_foreign_key.to_sym)
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
validate :validate_association_name
|
|
368
|
+
|
|
369
|
+
def relation
|
|
370
|
+
if @parent_model.active_model
|
|
371
|
+
@parent_model.active_model.reflections[@association_name.to_s]
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
def validate_association_name
|
|
376
|
+
# puts @parent_model.active_model.reflections.keys.inspect
|
|
377
|
+
# puts @association_name.to_s
|
|
378
|
+
unless relation
|
|
379
|
+
errors.add(:association_name, "Association #{@association_name.to_s} is not a valid relationship for model #{@parent_model.active_model.to_s}. Valid relations include: #{@parent_model.active_model.reflections.keys.inspect}")
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
unless relation && relation.belongs_to?
|
|
383
|
+
errors.add(:association_name, "Association #{@association_name.to_s} is not a valid belongs_to relationship")
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
def select_requirements(select_as_prefix = nil)
|
|
388
|
+
target_data_reqs = model.name_field.select_requirements([select_as_prefix, association_name].compact.join('_'))
|
|
389
|
+
{
|
|
390
|
+
field_name: association_name,
|
|
391
|
+
path: [association_name, target_data_reqs[:path]].flatten,
|
|
392
|
+
}
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
def match_requirements(select_as_prefix = nil)
|
|
396
|
+
{
|
|
397
|
+
path: [select_as_prefix, [association_name, relation.join_primary_key].join('_').to_sym].compact.flatten,
|
|
398
|
+
}
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
def hashify(user)
|
|
402
|
+
{
|
|
403
|
+
type: :reference,
|
|
404
|
+
id: @id
|
|
405
|
+
}
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
class LookupFieldBuilder < ActionBlocks::FieldBlock
|
|
410
|
+
attr_accessor :parent_reference
|
|
411
|
+
references :target_field
|
|
412
|
+
|
|
413
|
+
def before_build(parent, *args)
|
|
414
|
+
@field_type = 'lookup'
|
|
415
|
+
@parent_reference = parent
|
|
416
|
+
mk = @parent_reference.model_key.clone
|
|
417
|
+
mk['model-'] = ''
|
|
418
|
+
@target_field_key = "field-#{mk}-#{args[0]}"
|
|
419
|
+
@parent_model = @parent_reference.parent_model
|
|
420
|
+
@id = "#{parent_reference.id}_#{args[0]}"
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
def after_build(parent, *args)
|
|
424
|
+
@parent_model.fields.append(self)
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
def select_requirements(select_as_prefix = nil)
|
|
428
|
+
target_data_reqs = target_field.select_requirements([select_as_prefix, parent_reference.association_name].compact.join('_'))
|
|
429
|
+
{
|
|
430
|
+
field_name: target_data_reqs[:field_name],
|
|
431
|
+
path: [parent_reference.association_name, target_data_reqs[:path]].flatten,
|
|
432
|
+
}
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
def match_requirements(select_as_prefix = nil)
|
|
436
|
+
target_data_reqs = target_field.select_requirements([select_as_prefix, parent_reference.association_name].compact.join('_'))
|
|
437
|
+
{
|
|
438
|
+
path: [select_as_prefix, parent_reference.association_name, target_data_reqs[:path]].compact.flatten,
|
|
439
|
+
}
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
def hashify(user)
|
|
443
|
+
{
|
|
444
|
+
type: :lookup,
|
|
445
|
+
id: @id
|
|
446
|
+
}
|
|
447
|
+
end
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
class StringFieldBuilder < ActionBlocks::FieldBlock
|
|
451
|
+
def before_build(parent, *args)
|
|
452
|
+
super(parent, *args)
|
|
453
|
+
@field_type = 'string'
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
def hashify(user)
|
|
457
|
+
{
|
|
458
|
+
type: :string,
|
|
459
|
+
id: @id
|
|
460
|
+
}
|
|
461
|
+
end
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
class TextFieldBuilder < ActionBlocks::FieldBlock
|
|
465
|
+
def before_build(parent, *args)
|
|
466
|
+
super(parent, *args)
|
|
467
|
+
@field_type = 'text'
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
def hashify(user)
|
|
471
|
+
{
|
|
472
|
+
type: :text,
|
|
473
|
+
id: @id
|
|
474
|
+
}
|
|
475
|
+
end
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
class DatetimeFieldBuilder < ActionBlocks::FieldBlock
|
|
479
|
+
def before_build(parent, *args)
|
|
480
|
+
super(parent, *args)
|
|
481
|
+
@field_type = 'datetime'
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
def select_requirements(select_as_prefix = nil)
|
|
485
|
+
{
|
|
486
|
+
field_name: [select_as_prefix,@id].compact.join('_').to_sym,
|
|
487
|
+
path: [@id],
|
|
488
|
+
function: -> (*args) { timezone('US/Central', *args) }
|
|
489
|
+
}
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
def hashify(user)
|
|
493
|
+
{
|
|
494
|
+
type: :datetime,
|
|
495
|
+
id: @id
|
|
496
|
+
}
|
|
497
|
+
end
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
class AttachmentBuilder < ActionBlocks::FieldBlock
|
|
501
|
+
sets :attachment_type
|
|
502
|
+
|
|
503
|
+
validates :attachment_type, inclusion: { in: %w(image file),
|
|
504
|
+
message: "%{value} is not a valid attachment" }
|
|
505
|
+
|
|
506
|
+
def before_build(parent, *args)
|
|
507
|
+
super(parent, *args)
|
|
508
|
+
@attachment_type = 'image'
|
|
509
|
+
@field_type = 'attachment'
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
def select_requirements(select_as_prefix = nil)
|
|
513
|
+
{
|
|
514
|
+
field_name: [select_as_prefix,@id].compact.join('_').to_sym,
|
|
515
|
+
path: [:id]
|
|
516
|
+
}
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
def match_requirements(select_as_prefix = nil)
|
|
520
|
+
raise "should not use attachment in match conditions"
|
|
521
|
+
{
|
|
522
|
+
path: [select_as_prefix, @id].compact
|
|
523
|
+
}
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
def hashify(user)
|
|
527
|
+
{
|
|
528
|
+
type: :attachment,
|
|
529
|
+
attachment_type: @attachment_type,
|
|
530
|
+
id: @id,
|
|
531
|
+
model_key: @parent_model.key
|
|
532
|
+
}
|
|
533
|
+
end
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
class DateFieldBuilder < ActionBlocks::FieldBlock
|
|
538
|
+
def before_build(parent, *args)
|
|
539
|
+
super(parent, *args)
|
|
540
|
+
@field_type = 'date'
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
def hashify(user)
|
|
544
|
+
{
|
|
545
|
+
type: :date,
|
|
546
|
+
id: @id
|
|
547
|
+
}
|
|
548
|
+
end
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
class IntegerFieldBuilder < ActionBlocks::FieldBlock
|
|
552
|
+
def before_build(parent, *args)
|
|
553
|
+
super(parent, *args)
|
|
554
|
+
@field_type = 'integer'
|
|
555
|
+
end
|
|
556
|
+
|
|
557
|
+
def hashify(user)
|
|
558
|
+
{
|
|
559
|
+
type: :integer,
|
|
560
|
+
id: @id
|
|
561
|
+
}
|
|
562
|
+
end
|
|
563
|
+
end
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
end
|