engine2 1.0.4 → 1.0.9
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 +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
|
-
|