engine2 1.0.4 → 1.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Gemfile +0 -0
- data/Rakefile +4 -4
- data/app/{engine2actions.coffee → actions.coffee} +341 -215
- data/app/app.coffee +0 -0
- data/app/app.css +17 -0
- data/app/engine2.coffee +158 -208
- data/app/modal.coffee +138 -0
- data/bower.json +4 -2
- data/conf/message.yaml +5 -0
- data/conf/message_pl.yaml +7 -2
- data/config.coffee +24 -12
- data/engine2.gemspec +8 -8
- data/lib/engine2.rb +12 -10
- data/lib/engine2/action.rb +1338 -133
- data/lib/engine2/action/array.rb +189 -0
- data/lib/engine2/{meta/decode_meta.rb → action/decode.rb} +52 -21
- data/lib/engine2/action/delete.rb +64 -0
- data/lib/engine2/action/form.rb +16 -0
- data/lib/engine2/{meta/infra_meta.rb → action/infra.rb} +123 -89
- data/lib/engine2/action/link.rb +117 -0
- data/lib/engine2/action/list.rb +333 -0
- data/lib/engine2/action/save.rb +28 -0
- data/lib/engine2/action/view.rb +8 -0
- data/lib/engine2/action_node.rb +221 -0
- data/lib/engine2/core.rb +175 -87
- data/lib/engine2/handler.rb +14 -13
- data/lib/engine2/model.rb +85 -43
- data/lib/engine2/models/Files.rb +4 -1
- data/lib/engine2/models/UserInfo.rb +6 -3
- data/lib/engine2/post_bootstrap.rb +4 -3
- data/lib/engine2/pre_bootstrap.rb +10 -6
- data/lib/engine2/scheme.rb +107 -65
- data/lib/engine2/templates.rb +41 -6
- data/lib/engine2/type_info.rb +51 -23
- data/lib/engine2/version.rb +2 -1
- data/package.json +22 -16
- data/public/favicon.ico +0 -0
- data/public/img/ajax-loader-dark.gif +0 -0
- data/public/img/ajax-loader.gif +0 -0
- data/views/fields/blob.slim +1 -1
- data/views/fields/bs_select.slim +2 -2
- data/views/fields/bsselect_picker.slim +4 -4
- data/views/fields/bsselect_picker_opt.slim +5 -5
- data/views/fields/checkbox.slim +4 -4
- data/views/fields/checkbox_button.slim +6 -0
- data/views/fields/checkbox_buttons.slim +3 -3
- data/views/fields/checkbox_buttons_opt.slim +3 -3
- data/views/fields/currency.slim +2 -2
- data/views/fields/date.slim +4 -4
- data/views/fields/date_range.slim +9 -9
- data/views/fields/date_time.slim +9 -9
- data/views/fields/datetime.slim +8 -8
- data/views/fields/decimal.slim +1 -1
- data/views/fields/decimal_date.slim +3 -3
- data/views/fields/decimal_time.slim +3 -3
- data/views/fields/email.slim +3 -3
- data/views/fields/file_store.slim +11 -11
- data/views/fields/input_text.slim +4 -4
- data/views/fields/integer.slim +1 -1
- data/views/fields/list_bsmselect.slim +20 -0
- data/views/fields/list_bsselect.slim +5 -5
- data/views/fields/list_bsselect_opt.slim +6 -6
- data/views/fields/list_buttons.slim +1 -1
- data/views/fields/list_buttons_opt.slim +2 -2
- data/views/fields/list_mbuttons.slim +9 -0
- data/views/fields/list_mbuttons_opt.slim +11 -0
- data/views/fields/list_mselect.slim +12 -0
- data/views/fields/list_select.slim +4 -4
- data/views/fields/list_select_opt.slim +5 -5
- data/views/fields/password.slim +4 -4
- data/views/fields/radio_checkbox.slim +3 -3
- data/views/fields/scaffold.slim +2 -2
- data/views/fields/scaffold_picker.slim +5 -5
- data/views/fields/select_picker.slim +3 -3
- data/views/fields/select_picker_opt.slim +4 -4
- data/views/fields/text_area.slim +4 -3
- data/views/fields/time.slim +5 -4
- data/views/fields/typeahead_picker.slim +12 -9
- data/views/index.slim +3 -3
- data/views/infra/index.slim +0 -0
- data/views/infra/inspect.slim +41 -10
- data/views/modals/close_m.slim +0 -0
- data/views/modals/confirm_m.slim +0 -0
- data/views/modals/empty_m.slim +0 -0
- data/views/modals/menu_m.slim +1 -1
- data/views/modals/yes_no_m.slim +0 -0
- data/views/panels/menu_m.slim +1 -1
- data/views/scaffold/confirm.slim +0 -0
- data/views/scaffold/fields.slim +6 -4
- data/views/scaffold/form.slim +1 -1
- data/views/scaffold/form_collapse.slim +4 -3
- data/views/scaffold/form_tabs.slim +3 -2
- data/views/scaffold/list.slim +0 -0
- data/views/scaffold/message.slim +0 -0
- data/views/scaffold/search.slim +4 -4
- data/views/scaffold/search_collapse.slim +8 -7
- data/views/scaffold/search_tabs.slim +6 -5
- data/views/scaffold/view.slim +2 -2
- data/views/scaffold/view_collapse.slim +5 -4
- data/views/scaffold/view_tabs.slim +4 -3
- data/views/search_fields/bsmselect_picker.slim +4 -4
- data/views/search_fields/bsselect_picker.slim +4 -4
- data/views/search_fields/checkbox.slim +3 -3
- data/views/search_fields/checkbox2.slim +5 -5
- data/views/search_fields/checkbox_buttons.slim +3 -3
- data/views/search_fields/date.slim +20 -0
- data/views/search_fields/date_range.slim +8 -8
- data/views/search_fields/decimal_date_range.slim +5 -5
- data/views/search_fields/input_text.slim +2 -2
- data/views/search_fields/integer.slim +1 -1
- data/views/search_fields/integer_range.slim +2 -2
- data/views/search_fields/list_bsmselect.slim +4 -4
- data/views/search_fields/list_bsselect.slim +4 -4
- data/views/search_fields/list_buttons.slim +2 -2
- data/views/search_fields/list_mbuttons.slim +12 -0
- data/views/search_fields/list_select.slim +3 -3
- data/views/search_fields/scaffold_picker.slim +2 -2
- data/views/search_fields/select_picker.slim +3 -3
- data/views/search_fields/typeahead_picker.slim +8 -7
- metadata +53 -48
- data/lib/engine2/meta.rb +0 -1216
- data/lib/engine2/meta/array_meta.rb +0 -82
- data/lib/engine2/meta/delete_meta.rb +0 -60
- data/lib/engine2/meta/form_meta.rb +0 -15
- data/lib/engine2/meta/link_meta.rb +0 -134
- data/lib/engine2/meta/list_meta.rb +0 -281
- data/lib/engine2/meta/save_meta.rb +0 -50
- data/lib/engine2/meta/view_meta.rb +0 -7
- data/public/__sinatra__/404.png +0 -0
- data/public/__sinatra__/500.png +0 -0
@@ -1,82 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
module Engine2
|
4
|
-
class ArrayListMeta < Meta
|
5
|
-
meta_type :list
|
6
|
-
include MetaListSupport
|
7
|
-
|
8
|
-
(DefaultFilters ||= {}).merge!(
|
9
|
-
exact: lambda{|entries, name, value, type_info, hash|
|
10
|
-
entries.select{|e|e[name] == value}
|
11
|
-
},
|
12
|
-
string: lambda{|entries, name, value, type_info, hash|
|
13
|
-
entries.select{|e|e[name].to_s[value]}
|
14
|
-
},
|
15
|
-
boolean: lambda{|*args| DefaultFilters[:exact].(*args)},
|
16
|
-
integer: lambda{|entries, name, value, type_info, hash|
|
17
|
-
if value.is_a? Hash
|
18
|
-
from, to = value[:from], value[:to]
|
19
|
-
if from && to
|
20
|
-
entries.select{|e|e[name] >= from.to_i && e[name] <= to.to_i}
|
21
|
-
else
|
22
|
-
entries.select{|e| from ? e[name] >= from.to_i : e[name] <= to.to_i}
|
23
|
-
end
|
24
|
-
elsif value.is_a? Integer
|
25
|
-
entries.select{|e|e[name] == value.to_i}
|
26
|
-
else
|
27
|
-
nil
|
28
|
-
end
|
29
|
-
}
|
30
|
-
)
|
31
|
-
|
32
|
-
def data_source handler
|
33
|
-
[]
|
34
|
-
end
|
35
|
-
|
36
|
-
def invoke handler
|
37
|
-
params = handler.params
|
38
|
-
# if params[:initial] || params[:refresh]
|
39
|
-
entries = data_source(handler)
|
40
|
-
|
41
|
-
per_page = lookup(:config, :per_page)
|
42
|
-
page = params[:page].to_i
|
43
|
-
handler.permit page >= 0 && page < 1000
|
44
|
-
|
45
|
-
if order_str = params[:order]
|
46
|
-
order = order_str.to_sym
|
47
|
-
handler.permit lookup(:info, order, :sort)
|
48
|
-
entries = entries.sort_by{|e|e[order].to_s}
|
49
|
-
entries = entries.reverse if params[:asc] == "true"
|
50
|
-
end
|
51
|
-
|
52
|
-
if search = params[:search]
|
53
|
-
entries = list_search(entries, handler, search)
|
54
|
-
end
|
55
|
-
|
56
|
-
{entries: entries.drop(page).take(per_page), count: entries.size}
|
57
|
-
end
|
58
|
-
|
59
|
-
def list_search entries, handler, search
|
60
|
-
hash = JSON.parse(search, symbolize_names: true) rescue handler.halt_forbidden
|
61
|
-
model = assets[:model]
|
62
|
-
sfields = lookup(:search_fields)
|
63
|
-
handler.permit sfields
|
64
|
-
hash.each_pair do |name, value|
|
65
|
-
handler.permit sfields.include?(name)
|
66
|
-
|
67
|
-
type_info = get_type_info(name)
|
68
|
-
entries = if filter = (@filters && @filters[name]) || (dynamic? && (static.filters && static.filters[name]))
|
69
|
-
filter.(entries, hash, handler)
|
70
|
-
elsif filter = DefaultFilters[type_info[:otype]]
|
71
|
-
filter.(entries, name, value, type_info, hash)
|
72
|
-
else
|
73
|
-
raise E2Error.new("Filter not found for field '#{name}' in model '#{model}'") unless filter
|
74
|
-
end
|
75
|
-
|
76
|
-
handler.permit entries
|
77
|
-
end
|
78
|
-
|
79
|
-
entries
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
module Engine2
|
4
|
-
class DeleteMetaBase < Meta
|
5
|
-
|
6
|
-
def invoke_delete_db handler, ids
|
7
|
-
begin
|
8
|
-
model = assets[:model]
|
9
|
-
model.db.transaction do
|
10
|
-
ids.each do |id|
|
11
|
-
keys = split_keys(id)
|
12
|
-
restrict = model.association_reflections.select do |name, rel|
|
13
|
-
case rel[:type]
|
14
|
-
when :one_to_many
|
15
|
-
!model.db[name].where(Hash[rel[:keys].zip(keys)]).empty?
|
16
|
-
when :many_to_many
|
17
|
-
!model.db[rel[:join_table]].where(Hash[rel[:left_keys].zip(keys)]).empty?
|
18
|
-
when :many_to_one
|
19
|
-
when :one_to_one
|
20
|
-
else
|
21
|
-
unsupported_association rel[:type]
|
22
|
-
end
|
23
|
-
end
|
24
|
-
raise Sequel::DestroyFailed.new("Blokujące relacje: #{restrict.map{|name, rel| name}.join(', ')}" ) unless restrict.empty?
|
25
|
-
|
26
|
-
rec = model.call(Hash[model.primary_keys.zip(keys)])
|
27
|
-
rec.destroy(transaction: false)
|
28
|
-
# model.where(model.primary_keys_hash(keys)).delete # model.dataset[model.primary_key => id].delete
|
29
|
-
end
|
30
|
-
end
|
31
|
-
{}
|
32
|
-
rescue Sequel::NoExistingObject
|
33
|
-
handler.halt_not_found LOCS[:no_entry]
|
34
|
-
rescue Sequel::DestroyFailed => failure
|
35
|
-
handler.halt_forbidden failure.error.to_s
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
class DeleteMeta < DeleteMetaBase
|
42
|
-
include MetaDeleteSupport
|
43
|
-
|
44
|
-
def invoke handler
|
45
|
-
handler.permit id = handler.params[:id]
|
46
|
-
invoke_delete_db(handler, [id])
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
class BulkDeleteMeta < DeleteMetaBase
|
51
|
-
include MetaBulkDeleteSupport
|
52
|
-
|
53
|
-
def invoke handler
|
54
|
-
ids = handler.param_to_json(:ids)
|
55
|
-
handler.permit ids.is_a?(Array)
|
56
|
-
invoke_delete_db(handler, ids)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
@@ -1,134 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
module Engine2
|
4
|
-
class StarToManyLinkMeta < Meta
|
5
|
-
include MetaModelSupport
|
6
|
-
http_method :post
|
7
|
-
meta_type :star_to_many_link
|
8
|
-
|
9
|
-
def invoke handler
|
10
|
-
json = handler.post_to_json
|
11
|
-
parent = json[:parent_id]
|
12
|
-
ids = json[:ids]
|
13
|
-
handler.permit parent && ids
|
14
|
-
model = assets[:model]
|
15
|
-
assoc = assets[:assoc]
|
16
|
-
case assoc[:type]
|
17
|
-
when :one_to_many
|
18
|
-
model.db.transaction do
|
19
|
-
self.class.one_to_many_link_db model, assoc, split_keys(parent), ids
|
20
|
-
end
|
21
|
-
{}
|
22
|
-
when :many_to_many
|
23
|
-
self.class.many_to_many_link_db model, assoc, split_keys(parent), ids
|
24
|
-
{}
|
25
|
-
else unsupported_association
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.one_to_many_link_db model, assoc, parent, ids
|
30
|
-
pk = Hash[assoc[:keys].zip(parent)]
|
31
|
-
ids.each do |id|
|
32
|
-
model.where(model.primary_keys_hash(Sequel::split_keys(id))).update(pk)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.many_to_many_link_db model, assoc, parent, ids
|
37
|
-
p_pk = Hash[assoc[:left_keys].zip(parent)]
|
38
|
-
values = ids.map do |id|
|
39
|
-
p_pk.merge Hash[assoc[:right_keys].zip(Sequel::split_keys(id))]
|
40
|
-
end
|
41
|
-
model.db[assoc[:join_table]].multi_insert values
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
class StarToManyUnlinkMetaBase < Meta
|
46
|
-
include MetaModelSupport
|
47
|
-
http_method :delete
|
48
|
-
|
49
|
-
def one_to_many_unlink_db handler, ids
|
50
|
-
model = assets[:model]
|
51
|
-
assoc = assets[:assoc]
|
52
|
-
keys = assoc[:keys]
|
53
|
-
if keys.all?{|k|model.db_schema[k][:allow_null] == true}
|
54
|
-
model.db.transaction do
|
55
|
-
self.class.one_to_many_unlink_db model, assoc, ids
|
56
|
-
end
|
57
|
-
{}
|
58
|
-
else
|
59
|
-
handler.halt_method_not_allowed LOCS[:"non_nullable"]
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def self.one_to_many_unlink_db model, assoc, ids
|
64
|
-
keys = assoc[:keys]
|
65
|
-
ids.each do |id|
|
66
|
-
model.where(model.primary_keys_hash(Sequel::split_keys(id))).update(Hash[keys.zip([nil])])
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def many_to_many_unlink_db parent, ids
|
71
|
-
model = assets[:model]
|
72
|
-
assoc = assets[:assoc]
|
73
|
-
|
74
|
-
model.db.transaction do
|
75
|
-
self.class.many_to_many_unlink_db model, assoc, Sequel::split_keys(parent), ids
|
76
|
-
end
|
77
|
-
{}
|
78
|
-
end
|
79
|
-
|
80
|
-
def self.many_to_many_unlink_db model, assoc, parent, ids
|
81
|
-
p_pk = Hash[assoc[:left_keys].zip(parent)]
|
82
|
-
ds = model.db[assoc[:join_table]]
|
83
|
-
ids.each do |id|
|
84
|
-
ds.where(p_pk, Hash[assoc[:right_keys].zip(Sequel::split_keys(id))]).delete
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
class StarToManyUnlinkMeta < StarToManyUnlinkMetaBase
|
90
|
-
meta_type :star_to_many_unlink
|
91
|
-
|
92
|
-
def pre_run
|
93
|
-
super
|
94
|
-
action.parent.parent.*.menu(:item_menu).option :confirm_unlink, icon: "minus", show: "action.selected_size() == 0", button_loc: false
|
95
|
-
end
|
96
|
-
|
97
|
-
def invoke handler
|
98
|
-
handler.permit id = handler.params[:id]
|
99
|
-
assoc = assets[:assoc]
|
100
|
-
case assoc[:type]
|
101
|
-
when :one_to_many
|
102
|
-
one_to_many_unlink_db(handler, [id])
|
103
|
-
when :many_to_many
|
104
|
-
handler.permit parent = handler.params[:parent_id]
|
105
|
-
many_to_many_unlink_db(parent, [id])
|
106
|
-
else unsupported_association
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
class StarToManyBulkUnlinkMeta < StarToManyUnlinkMetaBase
|
112
|
-
meta_type :star_to_many_bulk_unlink
|
113
|
-
|
114
|
-
def pre_run
|
115
|
-
super
|
116
|
-
action.parent.parent.*.select_toggle_menu
|
117
|
-
action.parent.parent.*.menu(:menu).option_after :default_order, :confirm_bulk_unlink, icon: "minus", show: "action.selected_size() > 0", button_loc: false
|
118
|
-
end
|
119
|
-
|
120
|
-
def invoke handler
|
121
|
-
ids = handler.param_to_json(:ids)
|
122
|
-
handler.permit ids.is_a?(Array)
|
123
|
-
assoc = assets[:assoc]
|
124
|
-
case assoc[:type]
|
125
|
-
when :one_to_many
|
126
|
-
one_to_many_unlink_db(handler, ids)
|
127
|
-
when :many_to_many
|
128
|
-
handler.permit parent = handler.params[:parent_id]
|
129
|
-
many_to_many_unlink_db(parent, ids)
|
130
|
-
else unsupported_association
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
@@ -1,281 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
module Engine2
|
4
|
-
class ListMeta < Meta
|
5
|
-
meta_type :list
|
6
|
-
include MetaListSupport, MetaQuerySupport
|
7
|
-
|
8
|
-
(DefaultFilters ||= {}).merge!(
|
9
|
-
string: lambda{|query, name, value, type_info, hash|
|
10
|
-
case type_info[:type]
|
11
|
-
when :many_to_one
|
12
|
-
query.where(name => value)
|
13
|
-
else
|
14
|
-
query.where(name.like("%#{value}%"))
|
15
|
-
end
|
16
|
-
},
|
17
|
-
date: lambda{|query, name, value, type_info, hash|
|
18
|
-
if value.is_a? Hash
|
19
|
-
from, to = value[:from], value[:to]
|
20
|
-
if from && to
|
21
|
-
query.where(name => from .. to)
|
22
|
-
elsif from
|
23
|
-
query.where(name >= Sequel.string_to_date(from))
|
24
|
-
elsif to
|
25
|
-
query.where(name <= Sequel.string_to_date(to))
|
26
|
-
else
|
27
|
-
query # ?
|
28
|
-
end
|
29
|
-
else
|
30
|
-
query.where(name => Sequel.string_to_date(value))
|
31
|
-
end
|
32
|
-
},
|
33
|
-
integer: lambda{|query, name, value, type_info, hash|
|
34
|
-
if value.is_a? Hash
|
35
|
-
from, to = value[:from], value[:to]
|
36
|
-
if from && to
|
37
|
-
query.where(name => from .. to)
|
38
|
-
else
|
39
|
-
query.where(from ? name >= from.to_i : name <= to.to_i)
|
40
|
-
end
|
41
|
-
elsif value.is_a? Integer
|
42
|
-
query.where(name => value)
|
43
|
-
elsif value.is_a? Array
|
44
|
-
if !value.empty?
|
45
|
-
case type_info[:type]
|
46
|
-
when :many_to_one
|
47
|
-
keys = type_info[:keys]
|
48
|
-
if keys.length == 1
|
49
|
-
query.where(name => value)
|
50
|
-
else
|
51
|
-
query.where(keys.map{|k| hash[k]}.transpose.map{|vals| Hash[keys.zip(vals)]}.inject{|q, c| q | c})
|
52
|
-
end
|
53
|
-
when :list_select
|
54
|
-
query.where(name => value) # decode in sql query ?
|
55
|
-
when :integer
|
56
|
-
query
|
57
|
-
else
|
58
|
-
nil
|
59
|
-
end
|
60
|
-
else
|
61
|
-
nil
|
62
|
-
end
|
63
|
-
else
|
64
|
-
nil
|
65
|
-
end
|
66
|
-
}
|
67
|
-
)
|
68
|
-
|
69
|
-
def post_run
|
70
|
-
query select(*assets[:model].columns.reject{|col| assets[:model].type_info[col][:length].to_i > 20}.take(10)) unless @query
|
71
|
-
super
|
72
|
-
end
|
73
|
-
|
74
|
-
def invoke handler
|
75
|
-
params = handler.params
|
76
|
-
model = assets[:model]
|
77
|
-
query = list_context(get_query, handler)
|
78
|
-
|
79
|
-
if search = params[:search]
|
80
|
-
query = list_search(query, handler, search)
|
81
|
-
end
|
82
|
-
|
83
|
-
count = query.count if lookup(:config, :use_count)
|
84
|
-
|
85
|
-
if order_str = params[:order]
|
86
|
-
order = order_str.to_sym
|
87
|
-
handler.permit lookup(:info, order, :sort)
|
88
|
-
|
89
|
-
if order_blk = (@orders && @orders[order]) || (dynamic? && (static.orders && static.orders[order]))
|
90
|
-
query = order_blk.(query, handler)
|
91
|
-
else
|
92
|
-
order = order.qualify(model.table_name) if model.type_info[order]
|
93
|
-
query = query.order(order)
|
94
|
-
end
|
95
|
-
|
96
|
-
query = query.reverse if params[:asc] == "true"
|
97
|
-
end
|
98
|
-
|
99
|
-
per_page = lookup(:config, :per_page)
|
100
|
-
page = params[:page].to_i
|
101
|
-
handler.permit page >= 0 && page < 1000
|
102
|
-
|
103
|
-
query = query.limit(per_page, page)
|
104
|
-
|
105
|
-
res = {entries: query.all}
|
106
|
-
res[:count] = count if count
|
107
|
-
res
|
108
|
-
end
|
109
|
-
|
110
|
-
def list_search query, handler, search
|
111
|
-
hash = JSON.parse(search, symbolize_names: true) rescue handler.halt_forbidden
|
112
|
-
model = assets[:model]
|
113
|
-
sfields = lookup(:search_fields)
|
114
|
-
handler.permit sfields
|
115
|
-
hash.each_pair do |name, value|
|
116
|
-
handler.permit sfields.include?(name)
|
117
|
-
|
118
|
-
type_info = get_type_info(name)
|
119
|
-
query = if filter = (@filters && @filters[name]) || (dynamic? && (static.filters && static.filters[name]))
|
120
|
-
filter.(query, hash, handler)
|
121
|
-
elsif filter = DefaultFilters[type_info[:otype]]
|
122
|
-
name = model.type_info[name] ? name.qualify(model.table_name) : Sequel.expr(name)
|
123
|
-
filter.(query, name, value, type_info, hash)
|
124
|
-
else
|
125
|
-
raise E2Error.new("Filter not found for field '#{name}' in model '#{model}'") unless filter
|
126
|
-
end
|
127
|
-
|
128
|
-
handler.permit query
|
129
|
-
end
|
130
|
-
query
|
131
|
-
end
|
132
|
-
|
133
|
-
def list_context query, handler
|
134
|
-
query
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
#
|
139
|
-
# Many to One
|
140
|
-
#
|
141
|
-
class ManyToOneListMeta < ListMeta
|
142
|
-
meta_type :many_to_one_list
|
143
|
-
|
144
|
-
def pre_run
|
145
|
-
super
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
#
|
150
|
-
# * to Many
|
151
|
-
#
|
152
|
-
class StarToManyListMeta < ListMeta
|
153
|
-
meta_type :star_to_many_list
|
154
|
-
def pre_run
|
155
|
-
super
|
156
|
-
menu(:panel_menu).option_at 0, :cancel, icon: "remove"
|
157
|
-
panel_title "#{:list.icon} #{LOCS[assets[:assoc][:name]]}"
|
158
|
-
end
|
159
|
-
|
160
|
-
# def decode_panel_title handler
|
161
|
-
# if handler.initial?
|
162
|
-
# # Hash[assets[:model].primary_keys.zip(split_keys(id))]]
|
163
|
-
# p action.parent.decode_entry.*.invoke_decode([[handler.params[:parent_id]]])
|
164
|
-
# panel_title "ADFASDF"
|
165
|
-
# end
|
166
|
-
# end
|
167
|
-
|
168
|
-
# def post_run
|
169
|
-
# super
|
170
|
-
# unless @request_meta_proc
|
171
|
-
# request{|h| decode_panel_title h}
|
172
|
-
# end
|
173
|
-
# end
|
174
|
-
|
175
|
-
def list_context query, handler
|
176
|
-
handler.permit parent = handler.params[:parent_id]
|
177
|
-
model = assets[:model]
|
178
|
-
assoc = assets[:assoc]
|
179
|
-
parent_keys = split_keys(parent)
|
180
|
-
case assoc[:type]
|
181
|
-
when :one_to_many
|
182
|
-
keys = assoc[:keys]
|
183
|
-
condition = parent_keys.all?(&:empty?) ? false : Hash[keys.map{|k| k.qualify(model.table_name)}.zip(parent_keys)]
|
184
|
-
if handler.params[:negate]
|
185
|
-
query = query.exclude(condition)
|
186
|
-
query = query.or(Hash[keys.zip([nil])]) if keys.all?{|k|model.db_schema[k][:allow_null] == true} # type_info[:required] ?
|
187
|
-
query
|
188
|
-
else
|
189
|
-
query.where(condition)
|
190
|
-
end
|
191
|
-
when :many_to_many
|
192
|
-
q_pk = model.primary_keys_qualified
|
193
|
-
j_table = assoc[:join_table]
|
194
|
-
l_keys = assoc[:left_keys].map{|k| k.qualify(j_table)}
|
195
|
-
r_keys = assoc[:right_keys].map{|k| k.qualify(j_table)}
|
196
|
-
r_keys_vals = Hash[r_keys.zip(q_pk)]
|
197
|
-
l_keys_vals = parent_keys.all?(&:empty?) ? false : Hash[l_keys.zip(parent_keys)]
|
198
|
-
|
199
|
-
if handler.params[:negate]
|
200
|
-
query.exclude(model.db[j_table].select(nil).where(r_keys_vals, l_keys_vals).exists)
|
201
|
-
else
|
202
|
-
# query.qualify.join(j_table, [r_keys_vals, l_keys_vals])
|
203
|
-
query.qualify.left_join(j_table, r_keys_vals).filter(l_keys_vals)
|
204
|
-
end
|
205
|
-
else unsupported_association
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
class StarToManyLinkListMeta < StarToManyListMeta
|
211
|
-
meta_type :star_to_many_link_list
|
212
|
-
def pre_run
|
213
|
-
super
|
214
|
-
panel_title LOCS[:link_title]
|
215
|
-
menu(:panel_menu).option_at 0, :link, icon: "ok", enabled: "action.selected_size() > 0"
|
216
|
-
action.parent.*.menu(:menu).option_at 0, :link_list, icon: "paperclip", button_loc: false
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
# *_to_many_field
|
221
|
-
class StarToManyFieldMeta < StarToManyListMeta
|
222
|
-
meta_type :star_to_many_field
|
223
|
-
|
224
|
-
def pre_run
|
225
|
-
super
|
226
|
-
modal_action false
|
227
|
-
panel_panel_template false
|
228
|
-
end
|
229
|
-
|
230
|
-
def list_context query, handler
|
231
|
-
unlinked = handler.param_to_json(:unlinked)
|
232
|
-
linked = handler.param_to_json(:linked)
|
233
|
-
query = super(query, handler)
|
234
|
-
model = assets[:model]
|
235
|
-
pks = model.primary_keys_qualified
|
236
|
-
|
237
|
-
if handler.params[:negate]
|
238
|
-
query = unlinked.map{|ln| pks.zip(split_keys(ln))}.inject(query){|q, c| q.or c}
|
239
|
-
# query = query.or *unlinked.map{|unl| Hash[model.primary_keys.zip(split_keys(unl))]}.inject{|q, c| q | c}
|
240
|
-
query = query.where *linked.map{|ln| pks.zip(split_keys(ln)).sql_negate}
|
241
|
-
|
242
|
-
else
|
243
|
-
query = query.where *unlinked.map{|unl| pks.zip(split_keys(unl)).sql_negate}
|
244
|
-
# query = query.or *linked.map{|ln| model.primary_keys.zip(split_keys(ln))}
|
245
|
-
# query = query.or *linked.map{|ln| Hash[model.primary_keys.zip(split_keys(ln))]}.inject{|q, c| q | c}
|
246
|
-
case assets[:assoc][:type]
|
247
|
-
when :one_to_many
|
248
|
-
query = linked.map{|ln| pks.zip(split_keys(ln))}.inject(query){|q, c| q.or c}
|
249
|
-
when :many_to_many
|
250
|
-
query = linked.map{|ln| pks.zip(split_keys(ln))}.inject(query){|q, c| q.or c}.distinct
|
251
|
-
else unsupported_association
|
252
|
-
end unless linked.empty?
|
253
|
-
end
|
254
|
-
|
255
|
-
query
|
256
|
-
end
|
257
|
-
end
|
258
|
-
|
259
|
-
class StarToManyFieldUnlinkMeta < Meta
|
260
|
-
meta_type :star_to_many_field_unlink
|
261
|
-
|
262
|
-
def pre_run
|
263
|
-
super
|
264
|
-
action.parent.parent.*.menu(:item_menu).option :confirm_unlink, icon: "minus", show: "action.selected_size() == 0", button_loc: false
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
class StarToManyFieldLinkListMeta < StarToManyFieldMeta
|
269
|
-
meta_type :star_to_many_field_link_list
|
270
|
-
|
271
|
-
def pre_run
|
272
|
-
super
|
273
|
-
modal_action true
|
274
|
-
panel_panel_template 'scaffold/list'
|
275
|
-
panel_title LOCS[:link_title]
|
276
|
-
menu(:panel_menu).option_at 0, :link, icon: "ok", enabled: "action.selected_size() > 0"
|
277
|
-
action.parent.*.menu(:menu).option_at 0, :link_list, icon: "paperclip", button_loc: false
|
278
|
-
end
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|