engine2 1.0.4 → 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +0 -0
  3. data/Rakefile +4 -4
  4. data/app/{engine2actions.coffee → actions.coffee} +341 -215
  5. data/app/app.coffee +0 -0
  6. data/app/app.css +17 -0
  7. data/app/engine2.coffee +158 -208
  8. data/app/modal.coffee +138 -0
  9. data/bower.json +4 -2
  10. data/conf/message.yaml +5 -0
  11. data/conf/message_pl.yaml +7 -2
  12. data/config.coffee +24 -12
  13. data/engine2.gemspec +8 -8
  14. data/lib/engine2.rb +12 -10
  15. data/lib/engine2/action.rb +1338 -133
  16. data/lib/engine2/action/array.rb +189 -0
  17. data/lib/engine2/{meta/decode_meta.rb → action/decode.rb} +52 -21
  18. data/lib/engine2/action/delete.rb +64 -0
  19. data/lib/engine2/action/form.rb +16 -0
  20. data/lib/engine2/{meta/infra_meta.rb → action/infra.rb} +123 -89
  21. data/lib/engine2/action/link.rb +117 -0
  22. data/lib/engine2/action/list.rb +333 -0
  23. data/lib/engine2/action/save.rb +28 -0
  24. data/lib/engine2/action/view.rb +8 -0
  25. data/lib/engine2/action_node.rb +221 -0
  26. data/lib/engine2/core.rb +175 -87
  27. data/lib/engine2/handler.rb +14 -13
  28. data/lib/engine2/model.rb +85 -43
  29. data/lib/engine2/models/Files.rb +4 -1
  30. data/lib/engine2/models/UserInfo.rb +6 -3
  31. data/lib/engine2/post_bootstrap.rb +4 -3
  32. data/lib/engine2/pre_bootstrap.rb +10 -6
  33. data/lib/engine2/scheme.rb +107 -65
  34. data/lib/engine2/templates.rb +41 -6
  35. data/lib/engine2/type_info.rb +51 -23
  36. data/lib/engine2/version.rb +2 -1
  37. data/package.json +22 -16
  38. data/public/favicon.ico +0 -0
  39. data/public/img/ajax-loader-dark.gif +0 -0
  40. data/public/img/ajax-loader.gif +0 -0
  41. data/views/fields/blob.slim +1 -1
  42. data/views/fields/bs_select.slim +2 -2
  43. data/views/fields/bsselect_picker.slim +4 -4
  44. data/views/fields/bsselect_picker_opt.slim +5 -5
  45. data/views/fields/checkbox.slim +4 -4
  46. data/views/fields/checkbox_button.slim +6 -0
  47. data/views/fields/checkbox_buttons.slim +3 -3
  48. data/views/fields/checkbox_buttons_opt.slim +3 -3
  49. data/views/fields/currency.slim +2 -2
  50. data/views/fields/date.slim +4 -4
  51. data/views/fields/date_range.slim +9 -9
  52. data/views/fields/date_time.slim +9 -9
  53. data/views/fields/datetime.slim +8 -8
  54. data/views/fields/decimal.slim +1 -1
  55. data/views/fields/decimal_date.slim +3 -3
  56. data/views/fields/decimal_time.slim +3 -3
  57. data/views/fields/email.slim +3 -3
  58. data/views/fields/file_store.slim +11 -11
  59. data/views/fields/input_text.slim +4 -4
  60. data/views/fields/integer.slim +1 -1
  61. data/views/fields/list_bsmselect.slim +20 -0
  62. data/views/fields/list_bsselect.slim +5 -5
  63. data/views/fields/list_bsselect_opt.slim +6 -6
  64. data/views/fields/list_buttons.slim +1 -1
  65. data/views/fields/list_buttons_opt.slim +2 -2
  66. data/views/fields/list_mbuttons.slim +9 -0
  67. data/views/fields/list_mbuttons_opt.slim +11 -0
  68. data/views/fields/list_mselect.slim +12 -0
  69. data/views/fields/list_select.slim +4 -4
  70. data/views/fields/list_select_opt.slim +5 -5
  71. data/views/fields/password.slim +4 -4
  72. data/views/fields/radio_checkbox.slim +3 -3
  73. data/views/fields/scaffold.slim +2 -2
  74. data/views/fields/scaffold_picker.slim +5 -5
  75. data/views/fields/select_picker.slim +3 -3
  76. data/views/fields/select_picker_opt.slim +4 -4
  77. data/views/fields/text_area.slim +4 -3
  78. data/views/fields/time.slim +5 -4
  79. data/views/fields/typeahead_picker.slim +12 -9
  80. data/views/index.slim +3 -3
  81. data/views/infra/index.slim +0 -0
  82. data/views/infra/inspect.slim +41 -10
  83. data/views/modals/close_m.slim +0 -0
  84. data/views/modals/confirm_m.slim +0 -0
  85. data/views/modals/empty_m.slim +0 -0
  86. data/views/modals/menu_m.slim +1 -1
  87. data/views/modals/yes_no_m.slim +0 -0
  88. data/views/panels/menu_m.slim +1 -1
  89. data/views/scaffold/confirm.slim +0 -0
  90. data/views/scaffold/fields.slim +6 -4
  91. data/views/scaffold/form.slim +1 -1
  92. data/views/scaffold/form_collapse.slim +4 -3
  93. data/views/scaffold/form_tabs.slim +3 -2
  94. data/views/scaffold/list.slim +0 -0
  95. data/views/scaffold/message.slim +0 -0
  96. data/views/scaffold/search.slim +4 -4
  97. data/views/scaffold/search_collapse.slim +8 -7
  98. data/views/scaffold/search_tabs.slim +6 -5
  99. data/views/scaffold/view.slim +2 -2
  100. data/views/scaffold/view_collapse.slim +5 -4
  101. data/views/scaffold/view_tabs.slim +4 -3
  102. data/views/search_fields/bsmselect_picker.slim +4 -4
  103. data/views/search_fields/bsselect_picker.slim +4 -4
  104. data/views/search_fields/checkbox.slim +3 -3
  105. data/views/search_fields/checkbox2.slim +5 -5
  106. data/views/search_fields/checkbox_buttons.slim +3 -3
  107. data/views/search_fields/date.slim +20 -0
  108. data/views/search_fields/date_range.slim +8 -8
  109. data/views/search_fields/decimal_date_range.slim +5 -5
  110. data/views/search_fields/input_text.slim +2 -2
  111. data/views/search_fields/integer.slim +1 -1
  112. data/views/search_fields/integer_range.slim +2 -2
  113. data/views/search_fields/list_bsmselect.slim +4 -4
  114. data/views/search_fields/list_bsselect.slim +4 -4
  115. data/views/search_fields/list_buttons.slim +2 -2
  116. data/views/search_fields/list_mbuttons.slim +12 -0
  117. data/views/search_fields/list_select.slim +3 -3
  118. data/views/search_fields/scaffold_picker.slim +2 -2
  119. data/views/search_fields/select_picker.slim +3 -3
  120. data/views/search_fields/typeahead_picker.slim +8 -7
  121. metadata +53 -48
  122. data/lib/engine2/meta.rb +0 -1216
  123. data/lib/engine2/meta/array_meta.rb +0 -82
  124. data/lib/engine2/meta/delete_meta.rb +0 -60
  125. data/lib/engine2/meta/form_meta.rb +0 -15
  126. data/lib/engine2/meta/link_meta.rb +0 -134
  127. data/lib/engine2/meta/list_meta.rb +0 -281
  128. data/lib/engine2/meta/save_meta.rb +0 -50
  129. data/lib/engine2/meta/view_meta.rb +0 -7
  130. data/public/__sinatra__/404.png +0 -0
  131. data/public/__sinatra__/500.png +0 -0
@@ -0,0 +1,189 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Engine2
5
+ class ArrayListAction < Action
6
+ action_type :list
7
+ include ActionListSupport
8
+
9
+ (DefaultFilters ||= {}).merge!(
10
+ exact: lambda{|entries, name, value, type_info, hash|
11
+ entries.select{|e|e[name] == value}
12
+ },
13
+ string: lambda{|entries, name, value, type_info, hash|
14
+ if type_info[:type] == :list_select
15
+ if type_info[:multiselect]
16
+ entries.select{|e|value.include?(e[name].to_s)}
17
+ else
18
+ entries.select{|e|e[name].to_s == value}
19
+ end
20
+ else
21
+ entries.select{|e|e[name].to_s[value]}
22
+ end
23
+
24
+ },
25
+ boolean: lambda{|*args| DefaultFilters[:exact].(*args)},
26
+ integer: lambda{|entries, name, value, type_info, hash|
27
+ if value.is_a? Hash
28
+ from, to = value[:from], value[:to]
29
+ if from && to
30
+ entries.select{|e|e[name] >= from.to_i && e[name] <= to.to_i}
31
+ else
32
+ entries.select{|e| from ? e[name] >= from.to_i : e[name] <= to.to_i}
33
+ end
34
+ elsif value.is_a? Integer
35
+ entries.select{|e|e[name] == value.to_i}
36
+ else
37
+ nil
38
+ end
39
+ }
40
+ )
41
+
42
+ def data_source handler
43
+ []
44
+ end
45
+
46
+ def page_frame handler, entries
47
+ entries
48
+ end
49
+
50
+ def invoke handler
51
+ params = handler.params
52
+ # if params[:initial] || params[:refresh]
53
+ entries = data_source(handler)
54
+
55
+ per_page = lookup(:config, :per_page)
56
+ page = params[:page].to_i
57
+ handler.permit page >= 0 && page < 1000
58
+
59
+ if order_str = params[:order]
60
+ order = order_str.to_sym
61
+ handler.permit lookup(:fields, order, :sort)
62
+ entries = entries.sort_by{|e|e[order].to_s}
63
+ entries = entries.reverse if params[:asc] == "true"
64
+ end
65
+
66
+ if search = params[:search]
67
+ entries = list_search(entries, handler, search)
68
+ end
69
+
70
+ {entries: page_frame(handler, entries[page, per_page]), count: entries.size}
71
+ end
72
+
73
+ def list_search entries, handler, search
74
+ hash = JSON.parse(search, symbolize_names: true) rescue handler.halt_forbidden
75
+ model = assets[:model]
76
+ sfields = lookup(:search_field_list)
77
+ handler.permit sfields
78
+ hash.each_pair do |name, value|
79
+ handler.permit sfields.include?(name)
80
+
81
+ type_info = model.find_type_info(name)
82
+ entries = if filter = (@filters && @filters[name]) || (dynamic? && (static.filters && static.filters[name]))
83
+ filter.(handler, entries, hash)
84
+ elsif filter = DefaultFilters[type_info[:otype]]
85
+ filter.(entries, name, value, type_info, hash)
86
+ else
87
+ raise E2Error.new("Filter not found for field '#{name}' in model '#{model}'") unless filter
88
+ end
89
+
90
+ handler.permit entries
91
+ end
92
+
93
+ entries
94
+ end
95
+ end
96
+
97
+ class ArrayViewAction < Action
98
+ include ActionViewSupport
99
+
100
+ def find_record handler, id
101
+ node.parent.*.data_source(handler)[id.to_i]
102
+ end
103
+ end
104
+
105
+ class ArrayFormAction < Action
106
+ end
107
+
108
+ class ArrayCreateAction < ArrayFormAction
109
+ include ActionCreateSupport
110
+ end
111
+
112
+ class ArrayModifyAction < ArrayFormAction
113
+ include ActionModifySupport
114
+
115
+ def find_record handler, id
116
+ node.parent.*.data_source(handler)[id.to_i]
117
+ end
118
+ end
119
+
120
+ class ArrayDeleteAction < Action
121
+ include ActionDeleteSupport
122
+
123
+ def invoke handler
124
+ handler.permit id = handler.params[:id]
125
+ node.parent.parent.*.data_source(handler).delete_at(id.to_i)
126
+ end
127
+ end
128
+
129
+ class ArraySaveAction < Action
130
+ include ActionApproveSupport
131
+ end
132
+
133
+ class ArrayInsertAction < ArraySaveAction
134
+ include ActionInsertSupport
135
+ action_type :approve
136
+
137
+ def after_approve handler, record
138
+ # handler.permit id = record[:id]
139
+ # ds = node.parent.parent.*.data_source(handler)
140
+ end
141
+ end
142
+
143
+ class ArrayUpdateAction < ArraySaveAction
144
+ include ActionUpdateSupport
145
+ action_type :approve
146
+
147
+ def after_approve handler, record
148
+ handler.permit id = record[:id]
149
+ node.parent.parent.*.data_source(handler)[id].merge!(record.values)
150
+ end
151
+ end
152
+
153
+ class Schemes
154
+ ARRAY_CRUD ||= {array_create: true, array_view: true, array_modify: true, array_delete: true}.freeze
155
+ ARRAY_VIEW ||= {array_view: true}
156
+ end
157
+
158
+ SCHEMES.instance_eval do
159
+ define_scheme :array_view do |name = :view|
160
+ define_node name, ArrayViewAction
161
+ end
162
+
163
+ define_scheme :array_modify do |name = :modify|
164
+ define_node name, ArrayModifyAction do
165
+ define_node :approve, ArrayUpdateAction
166
+ end
167
+ end
168
+
169
+ define_scheme :array_create do |name = :create|
170
+ define_node name, ArrayCreateAction do
171
+ define_node :approve, ArrayInsertAction
172
+ end
173
+ end
174
+
175
+ define_scheme :array_delete do
176
+ run_scheme :confirm, :delete, ArrayDeleteAction,
177
+ message: LOCS[:delete_question], title: LOCS[:confirm_delete_title]
178
+ end
179
+
180
+ define_scheme :array do |name, model, options|
181
+ options ||= Schemes::ARRAY_CRUD
182
+ define_node name, ArrayListAction, model: model do
183
+ options.each{|k, v| run_scheme(k) if v}
184
+
185
+ define_node_bundle :form, :create, :modify if options[:array_create] && options[:array_modify]
186
+ end
187
+ end
188
+ end
189
+ end
@@ -1,8 +1,9 @@
1
1
  # coding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module Engine2
4
- class DecodeMeta < Meta
5
- include MetaAPISupport, MetaModelSupport, MetaQuerySupport
5
+ class DecodeAction < Action
6
+ include ActionAPISupport, ActionModelSupport, ActionQuerySupport
6
7
 
7
8
  def decode *fields, &blk
8
9
  query select(*fields), &blk
@@ -18,8 +19,8 @@ module Engine2
18
19
  end
19
20
 
20
21
  def post_process
21
- if fields = @meta[:fields]
22
- fields = fields - static.get[:fields] if dynamic?
22
+ if fields = @meta[:field_list]
23
+ fields = fields - static.meta[:field_list] if dynamic?
23
24
  # no decorate here
24
25
  fields.each do |name|
25
26
  type_info = assets[:model].type_info[name] # foreign keys ?
@@ -42,7 +43,7 @@ module Engine2
42
43
  end
43
44
 
44
45
  def post_run
45
- query select(*assets[:model].primary_keys) unless @query
46
+ decode(*assets[:model].primary_keys) unless @query
46
47
  @meta[:separator] = '/' unless @meta[:separator]
47
48
  super
48
49
  @meta[:primary_fields] = assets[:model].primary_keys
@@ -50,48 +51,78 @@ module Engine2
50
51
 
51
52
  end
52
53
 
53
- class DecodeListMeta < DecodeMeta
54
- meta_type :decode_list
54
+ class DecodeListAction < DecodeAction
55
+ action_type :decode_list
55
56
 
56
57
  def invoke handler
57
- {entries: get_query.limit(200).all}
58
+ {entries: get_query.limit(200).load_all}
59
+ end
60
+
61
+ def order *fields
62
+ @query = get_query.order *fields
58
63
  end
59
64
  end
60
65
 
61
- class TypeAheadMeta < DecodeMeta
62
- meta_type :typeahead
66
+ class TypeAheadAction < DecodeAction
67
+ action_type :typeahead
63
68
 
64
69
  def pre_run
65
70
  super
66
- limit 10
71
+ @limit = 10
67
72
  end
68
73
 
69
74
  def limit lmt
70
- @meta[:limit] = lmt
75
+ @limit = lmt
76
+ end
77
+
78
+ def get_limit
79
+ @limit
80
+ end
81
+
82
+ def get_case_insensitive
83
+ @case_insensitive
84
+ end
85
+
86
+ def case_insensitive
87
+ @case_insensitive = true
88
+ end
89
+
90
+ def order *fields
91
+ @query = get_query.order *fields
71
92
  end
72
93
 
73
94
  def invoke handler
95
+ model = assets[:model]
74
96
  if query = handler.params[:query]
75
- condition = (@meta[:decode_fields] || @meta[:fields]).map{|f|f.like("%#{query}%")}.inject{|q, f| q | f}
76
- {entries: get_query.where(condition).limit(@meta[:limit]).all}
97
+ fields = @meta[:decode_fields] || static.meta[:decode_fields]
98
+
99
+ entries = if query.to_s.empty?
100
+ get_query
101
+ else
102
+ table_name = model.table_name
103
+ condition = fields.map{|f|table_name.q(f).like("%#{query}%", case_insensitive: @case_insensitive || static.get_case_insensitive)}.reduce{|q, f| q | f}
104
+ get_query.where(condition)
105
+ end.limit(@limit || static.get_limit).load_all
106
+
107
+ {entries: entries}
77
108
  else
78
109
  handler.permit id = handler.params[:id]
79
- record = get_query[Hash[assets[:model].primary_keys.zip(split_keys(id))]]
110
+ record = get_query.unordered.load Hash[model.primary_keys_qualified.zip(split_keys(id))]
80
111
  # handler.halt_not_found(LOCS[:no_entry]) unless record
81
112
  {entry: record}
82
113
  end
83
114
  end
84
115
  end
85
116
 
86
- class DecodeEntryMeta < DecodeMeta
87
- meta_type :decode_entry
117
+ class DecodeEntryAction < DecodeAction
118
+ action_type :decode_entry
88
119
 
89
120
  def invoke handler
90
121
  {entries: invoke_decode(handler, handler.param_to_json(:ids))}
91
122
  end
92
123
 
93
124
  def invoke_decode handler, ids
94
- records = get_query.where(ids.map{|keys| Hash[assets[:model].primary_keys.zip(keys)]}.inject{|q, c| q | c}).all
125
+ records = get_query.where(ids.map{|keys| Hash[assets[:model].primary_keys.zip(keys)]}.reduce{|q, c| q | c}).load_all
95
126
  # handler.halt_not_found(LOCS[:no_entry]) if records.empty?
96
127
  records
97
128
  end
@@ -101,9 +132,9 @@ module Engine2
101
132
  if assoc = assets[:assoc]
102
133
  decode = assoc[:model].type_info[assoc[:keys].first][:decode]
103
134
 
104
- if decode[:search][:multiple] && action.parent.parent.*.is_a?(ListMeta)
105
- action.list.*.menu(:panel_menu).option :choose, icon: :ok #, disabled: "action.selected_size() == 0"
106
- action.list.*.menu(:panel_menu).option :cancel, icon: "remove"
135
+ if decode[:search][:multiple] && node.parent.parent.*.is_a?(ListAction)
136
+ node.list.*.menu(:panel_menu).option :choose, icon: :ok #, disabled: "action.selected_size() == 0"
137
+ node.list.*.menu(:panel_menu).option :cancel, icon: "remove"
107
138
  end
108
139
  end
109
140
  end
@@ -0,0 +1,64 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Engine2
5
+ class DeleteActionBase < Action
6
+ def invoke_delete_db handler, ids, from_assoc = nil
7
+ model = assets[:model]
8
+ model.db.transaction do
9
+ ids.each do |id|
10
+ keys = split_keys(id)
11
+
12
+ model.association_reflections.each do |name, assoc|
13
+ ds = case assoc[:type]
14
+ when :one_to_one
15
+ when :one_to_many
16
+ model.db[assoc.associated_class.table_name].where(Hash[assoc[:keys].zip(keys)])
17
+ when :many_to_many
18
+ model.db[assoc[:join_table]].where(Hash[assoc[:left_keys].zip(keys)])
19
+ when :many_to_one
20
+ nil
21
+ else
22
+ unsupported_association assoc[:type]
23
+ end
24
+
25
+ if assoc[:delete] == :cascade || from_assoc == assoc.associated_class.table_name
26
+ ds.delete
27
+ else
28
+ raise Sequel::DestroyFailed.new("#{LOCS[:delete_restricted]}: #{name}") unless ds.empty?
29
+ end if ds
30
+ end
31
+
32
+ rec = model.call(Hash[model.primary_keys.zip(keys)])
33
+ rec.destroy(transaction: false)
34
+ # model.where(model.primary_keys_hash(keys)).delete # model.dataset[model.primary_key => id].delete
35
+ end
36
+ end
37
+
38
+ rescue Sequel::NoExistingObject
39
+ handler.halt_not_found LOCS[:no_entry]
40
+ rescue Sequel::DestroyFailed => failure
41
+ handler.halt_forbidden failure.error.to_s
42
+ {}
43
+ end
44
+ end
45
+
46
+ class DeleteAction < DeleteActionBase
47
+ include ActionDeleteSupport
48
+
49
+ def invoke handler
50
+ handler.permit id = handler.params[:id]
51
+ invoke_delete_db(handler, [id])
52
+ end
53
+ end
54
+
55
+ class BulkDeleteAction < DeleteActionBase
56
+ include ActionBulkDeleteSupport
57
+
58
+ def invoke handler
59
+ ids = handler.param_to_json(:ids)
60
+ handler.permit ids.is_a?(Array)
61
+ invoke_delete_db(handler, ids)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,16 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Engine2
5
+ class FormAction < Action
6
+ include ActionQuerySupport
7
+ end
8
+
9
+ class CreateAction < FormAction
10
+ include ActionCreateSupport
11
+ end
12
+
13
+ class ModifyAction < FormAction
14
+ include ActionModifySupport
15
+ end
16
+ end
@@ -1,61 +1,43 @@
1
1
  # coding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module Engine2
4
- SCHEMES::define_scheme :infra! do |user_info_model = UserInfo|
5
- define_action :infra! do
6
- self.* do
7
- extend MetaPanelSupport, MetaMenuSupport, MetaAPISupport
8
- panel_panel_template false
9
- panel_template 'infra/index'
10
- loc! logged_on: LOCS[:logged_on]
11
- menu :menu do
12
- properties group_class: "btn-group-sm"
13
- option :inspect_modal, icon: :wrench, button_loc: false # , show: "action.logged_on"
14
-
15
- option :logout_form, icon: :"log-out" # , show: "action.logged_on"
16
- option :login_form, icon: :"log-in", disabled: 'action.action_pending()' # , show: "!action.logged_on"
17
- end
18
-
19
- @meta_type = :infra
20
-
21
- define_invoke do |handler|
22
- user = handler.user
23
- {user: user ? user.to_hash : nil}
24
- end
25
- end
5
+ SCHEMES::define_scheme :login! do |user_info_model = UserInfo|
6
+ define_node :login_form, LoginFormAction, model: user_info_model do
7
+ access!{|h|!h.logged_in?}
8
+ define_node :login, LoginAction
9
+ end
10
+ end
26
11
 
27
- define_action :login_form, LoginFormMeta, model: user_info_model do
28
- access!{|h|!h.logged_in?}
29
- define_action :login, LoginMeta
30
- end
12
+ SCHEMES::define_scheme :logout! do
13
+ define_node :logout_form, LogoutFormAction do
14
+ access! &:logged_in?
15
+ define_node :logout, LogoutAction
16
+ end
17
+ end
31
18
 
32
- define_action :logout_form, LogoutFormMeta do
33
- access! &:logged_in?
34
- define_action :logout, LogoutMeta
35
- end
19
+ SCHEMES::define_scheme :infra! do |user_info_model = UserInfo|
20
+ run_scheme :login!, user_info_model
21
+ define_node :infra!, InfraAction do
22
+ run_scheme :login!, user_info_model
23
+ run_scheme :logout!
36
24
 
37
- define_action :inspect_modal do
25
+ define_node :inspect_modal, InspectModalAction do
38
26
  access! &:logged_in?
39
- # access!{|h|h.user[:name] == 'admin'}
40
- self.* do
41
- extend MetaPanelSupport, MetaMenuSupport
42
- modal_action
43
- panel_template 'infra/inspect'
44
- panel_title "#{:wrench.icon} Inspect"
45
- panel_class "modal-huge"
46
- panel[:backdrop] = true
47
- menu(:panel_menu).option :cancel, icon: "remove"
48
- end
49
- define_action :inspect do
27
+ define_node :"inspect_#{SETTINGS[:name]}", WebSocketAction.inherit do
50
28
  self.* do
51
- @meta_type = :inspect
29
+ @action_type = :inspect
30
+
31
+ ws_message do |msg, ws|
32
+ ws.send! number: msg[:number].to_i + 1
33
+ end
52
34
  end
53
35
 
54
- define_action_invoke :models do |handler|
36
+ define_invoke :models do |handler|
55
37
  {models: Sequel::DATABASES.map{|db| {name: db.uri, models: db.models.keys} }}
56
38
  end
57
39
 
58
- define_action_invoke :model_info do |handler|
40
+ define_invoke :model_info do |handler|
59
41
  db_name = handler.params[:db]
60
42
  handler.permit db = Sequel::DATABASES.find{|d|d.uri == db_name || (d.uri && d.uri.start_with?(db_name))}
61
43
  handler.permit model = db.models[handler.params[:model].to_sym]
@@ -71,18 +53,22 @@ module Engine2
71
53
  }
72
54
  }
73
55
  end
56
+
57
+ define_invoke :environment do |handler|
58
+ {environment: handler.env}
59
+ end
74
60
  end
75
61
  end
76
62
  end
77
63
  end
78
64
 
79
65
  SCHEMES::define_scheme :menu! do
80
- define_action :menu!, MenuMeta do
66
+ define_node :menu!, MenuAction do
81
67
  end
82
68
  end
83
69
 
84
- class FileStoreMeta < Meta
85
- meta_type :file_store
70
+ class FileStoreAction < Action
71
+ action_type :file_store
86
72
 
87
73
  attr_accessor :model, :field
88
74
 
@@ -93,7 +79,7 @@ module Engine2
93
79
  end
94
80
 
95
81
 
96
- module BlobSupportMeta
82
+ module BlobSupportAction
97
83
  def serve_blob handler, entry, inf
98
84
  handler.permit entry
99
85
  handler.attachment entry[inf[:name_field]]
@@ -102,8 +88,8 @@ module Engine2
102
88
  end
103
89
  end
104
90
 
105
- class DownloadFileStoreMeta < Meta
106
- meta_type :download
91
+ class DownloadFileStoreAction < Action
92
+ action_type :download
107
93
 
108
94
  def invoke handler
109
95
  handler.permit id = handler.params[:id]
@@ -111,28 +97,29 @@ module Engine2
111
97
  handler.permit entry
112
98
  handler.attachment entry[:name]
113
99
  handler.content_type (entry[:mime].to_s.empty? ? "application/octet-stream" : entry[:mime])
114
- info = action.parent.*.model.type_info[action.parent.*.field]
100
+ info = node.parent.*.model.type_info[node.parent.*.field]
115
101
  open("#{info[:store][:files]}/#{entry[:name]}_#{id}", 'rb'){|f|f.read}
116
102
  end
117
103
  end
118
104
 
119
- class UploadFileStoreMeta < Meta
105
+ class UploadFileStoreAction < Action
120
106
  http_method :post
121
- meta_type :upload
107
+ action_type :upload
122
108
 
123
109
  def invoke handler
124
110
  file = handler.params[:file]
125
111
  temp = file[:tempfile]
126
112
  temp.close
127
113
  rackname = File.basename(temp.path)
128
- info = action.parent.*.model.type_info[action.parent.*.field]
129
- File.rename(temp.path, "#{info[:store][:upload]}/#{rackname}")
114
+ info = node.parent.*.model.type_info[node.parent.*.field]
115
+ FileUtils.cp(temp.path, "#{info[:store][:upload]}/#{rackname}") # File.rename(temp.path, "#{info[:store][:upload]}/#{rackname}")
116
+ FileUtils.rm(temp.path)
130
117
  {rackname: rackname}
131
118
  end
132
119
  end
133
120
 
134
- class BlobStoreMeta < Meta
135
- meta_type :blob_store
121
+ class BlobStoreAction < Action
122
+ action_type :blob_store
136
123
 
137
124
  attr_accessor :model, :field
138
125
 
@@ -145,13 +132,13 @@ module Engine2
145
132
  end
146
133
  end
147
134
 
148
- class DownloadBlobStoreMeta < Meta
149
- include BlobSupportMeta
150
- meta_type :download_blob
135
+ class DownloadBlobStoreAction < Action
136
+ include BlobSupportAction
137
+ action_type :download_blob
151
138
 
152
139
  def invoke handler
153
- model = action.parent.*.model
154
- inf = model.type_info[action.parent.*.field]
140
+ model = node.parent.*.model
141
+ inf = model.type_info[node.parent.*.field]
155
142
  handler.permit id = handler.params[:id]
156
143
 
157
144
  entry = model.naked.select(inf[:bytes_field], inf[:name_field], inf[:mime_field]).where(model.primary_keys_hash(split_keys(id))).first
@@ -159,23 +146,23 @@ module Engine2
159
146
  end
160
147
  end
161
148
 
162
- class UploadBlobStoreMeta < Meta
149
+ class UploadBlobStoreAction < Action
163
150
  http_method :post
164
- meta_type :upload_blob
151
+ action_type :upload_blob
165
152
 
166
153
  def invoke handler
167
154
  file = handler.params[:file]
168
155
  temp = file[:tempfile]
169
156
  temp.close
170
157
  rackname = File.basename(temp.path)
171
- info = action.parent.*.model.type_info[action.parent.*.field]
158
+ info = node.parent.*.model.type_info[node.parent.*.field]
172
159
  File.rename(temp.path, "#{info[:store][:upload]}/#{rackname}")
173
160
  {rackname: rackname}
174
161
  end
175
162
  end
176
163
 
177
- class ForeignBlobStoreMeta < Meta
178
- meta_type :blob_store
164
+ class ForeignBlobStoreAction < Action
165
+ action_type :blob_store
179
166
 
180
167
  attr_accessor :model, :field
181
168
 
@@ -195,13 +182,13 @@ module Engine2
195
182
  end
196
183
  end
197
184
 
198
- class DownloadForeignBlobStoreMeta < Meta
199
- include BlobSupportMeta
200
- meta_type :download_blob
185
+ class DownloadForeignBlobStoreAction < Action
186
+ include BlobSupportAction
187
+ action_type :download_blob
201
188
 
202
189
  def invoke handler
203
- model = action.parent.*.model
204
- inf = model.type_info[action.parent.*.field]
190
+ model = node.parent.*.model
191
+ inf = model.type_info[node.parent.*.field]
205
192
  assoc = model.association_reflections[inf[:assoc_name]]
206
193
  blob_model = assoc.associated_class
207
194
  handler.permit id = handler.params[:id]
@@ -213,9 +200,9 @@ module Engine2
213
200
  end
214
201
  end
215
202
 
216
- # class UploadForeignBlobStoreMeta < Meta
203
+ # class UploadForeignBlobStoreAction < Action
217
204
  # http_method :post
218
- # meta_type :upload_blob
205
+ # action_type :upload_blob
219
206
 
220
207
  # def invoke handler
221
208
  # file = handler.params[:file]
@@ -227,17 +214,63 @@ module Engine2
227
214
  # end
228
215
  # end
229
216
 
230
- class LoginFormMeta < Meta
231
- include MetaFormSupport
232
- meta_type :login_form
217
+ class InfraAction < Action
218
+ include ActionPanelSupport, ActionMenuSupport, ActionAPISupport
219
+ action_type :infra
220
+
221
+ def pre_run
222
+ super
223
+ panel_panel_template false
224
+ panel_template 'infra/index'
225
+ loc! logged_on: LOCS[:logged_on]
226
+ menu :menu do
227
+ properties group_class: "btn-group-sm"
228
+ option :inspect_modal, icon: :wrench, button_loc: false # , show: "action.logged_on"
229
+ end
230
+ end
231
+
232
+ def invoke handler
233
+ user = handler.user
234
+ {user: user ? user.to_hash : nil}
235
+ end
236
+
237
+ def login_meta menu_properties = {show: 'false'}, &blk
238
+ node.login_form.* &blk
239
+ menu(:menu).modify_option :login_form, menu_properties
240
+ node.parent.login_form.* &blk
241
+ end
242
+ end
243
+
244
+ class InspectModalAction < Action
245
+ include ActionPanelSupport, ActionMenuSupport
246
+ action_type :inline
247
+
248
+ def pre_run
249
+ super
250
+ modal_action
251
+ panel_template 'infra/inspect'
252
+ panel_title "#{:wrench.icon} Inspect"
253
+ panel_class "modal-huge"
254
+ panel[:backdrop] = true
255
+ menu(:panel_menu).option :close, icon: "remove"
256
+ end
257
+ end
258
+
259
+ class LoginFormAction < Action
260
+ include ActionFormSupport
261
+ action_type :login_form
233
262
 
234
263
  def pre_run
235
264
  super
236
265
  panel_class 'modal-default'
237
266
  panel_title LOCS[:login_title]
238
- info! :name, loc: LOCS[:user_name]
267
+ fields! :name, loc: LOCS[:user_name]
239
268
  menu(:panel_menu).modify_option :approve, name: :login, icon: :"log-in"
240
- @meta[:fields] = [:name, :password]
269
+ @meta[:field_list] = [:name, :password]
270
+ parent_action = node.parent.*
271
+ if parent_action.is_a? ActionMenuSupport
272
+ parent_action.menu(:menu).option :login_form, icon: :"log-in", disabled: "action.action_pending()"
273
+ end
241
274
  end
242
275
 
243
276
  def invoke handler
@@ -245,11 +278,11 @@ module Engine2
245
278
  end
246
279
  end
247
280
 
248
- class LoginMeta < Meta
249
- include MetaApproveSupport
250
- meta_type :login
281
+ class LoginAction < Action
282
+ include ActionApproveSupport
283
+ action_type :login
251
284
 
252
- def validate_record handler, record
285
+ def validate_record handler, record, parent_id
253
286
  super
254
287
  record.values[:password] = nil
255
288
  end
@@ -263,15 +296,16 @@ module Engine2
263
296
  end
264
297
  end
265
298
 
266
- class LogoutFormMeta < Meta
267
- include MetaPanelSupport, MetaMenuSupport
268
- meta_type :logout_form
299
+ class LogoutFormAction < Action
300
+ include ActionPanelSupport, ActionMenuSupport
301
+ action_type :logout_form
269
302
  def pre_run
270
303
  super
271
304
  panel_template 'scaffold/message'
272
305
  panel_title LOCS[:logout_title]
273
306
  panel_class 'modal-default'
274
307
  @meta[:message] = LOCS[:logout_message]
308
+ node.parent.*.menu(:menu).option :logout_form, icon: :"log-out" # , show: "action.logged_on"
275
309
  menu :panel_menu do
276
310
  option :logout, icon: "ok", loc: LOCS[:ok]
277
311
  option :cancel, icon: "remove"
@@ -279,8 +313,8 @@ module Engine2
279
313
  end
280
314
  end
281
315
 
282
- class LogoutMeta < Meta
283
- meta_type :logout
316
+ class LogoutAction < Action
317
+ action_type :logout
284
318
 
285
319
  def invoke handler
286
320
  handler.session.clear