engine2 1.0.5 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +5 -5
  2. data/app/actions.coffee +93 -58
  3. data/app/app.css +12 -0
  4. data/app/engine2.coffee +42 -24
  5. data/conf/message.yaml +1 -0
  6. data/conf/message_pl.yaml +1 -0
  7. data/config.coffee +2 -2
  8. data/engine2.gemspec +1 -1
  9. data/lib/engine2/action.rb +130 -126
  10. data/lib/engine2/action/array.rb +4 -4
  11. data/lib/engine2/action/decode.rb +13 -9
  12. data/lib/engine2/action/infra.rb +3 -3
  13. data/lib/engine2/action/list.rb +17 -10
  14. data/lib/engine2/action_node.rb +1 -2
  15. data/lib/engine2/core.rb +35 -7
  16. data/lib/engine2/model.rb +64 -15
  17. data/lib/engine2/post_bootstrap.rb +1 -1
  18. data/lib/engine2/pre_bootstrap.rb +10 -0
  19. data/lib/engine2/scheme.rb +2 -2
  20. data/lib/engine2/templates.rb +8 -0
  21. data/lib/engine2/type_info.rb +37 -15
  22. data/lib/engine2/version.rb +1 -1
  23. data/package.json +8 -5
  24. data/views/fields/blob.slim +1 -1
  25. data/views/fields/bs_select.slim +2 -2
  26. data/views/fields/bsselect_picker.slim +4 -4
  27. data/views/fields/bsselect_picker_opt.slim +5 -5
  28. data/views/fields/checkbox.slim +4 -4
  29. data/views/fields/checkbox_buttons.slim +3 -3
  30. data/views/fields/checkbox_buttons_opt.slim +3 -3
  31. data/views/fields/currency.slim +2 -2
  32. data/views/fields/date.slim +4 -4
  33. data/views/fields/date_range.slim +9 -9
  34. data/views/fields/date_time.slim +9 -9
  35. data/views/fields/datetime.slim +8 -8
  36. data/views/fields/decimal.slim +1 -1
  37. data/views/fields/decimal_date.slim +3 -3
  38. data/views/fields/decimal_time.slim +3 -3
  39. data/views/fields/email.slim +3 -3
  40. data/views/fields/file_store.slim +4 -4
  41. data/views/fields/input_text.slim +4 -4
  42. data/views/fields/integer.slim +1 -1
  43. data/views/fields/list_bsmselect.slim +20 -0
  44. data/views/fields/list_bsselect.slim +5 -5
  45. data/views/fields/list_bsselect_opt.slim +6 -6
  46. data/views/fields/list_buttons.slim +1 -1
  47. data/views/fields/list_buttons_opt.slim +2 -2
  48. data/views/fields/list_select.slim +4 -4
  49. data/views/fields/list_select_opt.slim +5 -5
  50. data/views/fields/password.slim +4 -4
  51. data/views/fields/radio_checkbox.slim +3 -3
  52. data/views/fields/scaffold.slim +1 -1
  53. data/views/fields/scaffold_picker.slim +5 -5
  54. data/views/fields/select_picker.slim +3 -3
  55. data/views/fields/select_picker_opt.slim +4 -4
  56. data/views/fields/text_area.slim +3 -3
  57. data/views/fields/time.slim +5 -4
  58. data/views/fields/typeahead_picker.slim +5 -5
  59. data/views/scaffold/fields.slim +4 -4
  60. data/views/scaffold/form.slim +1 -1
  61. data/views/scaffold/form_collapse.slim +4 -3
  62. data/views/scaffold/form_tabs.slim +3 -2
  63. data/views/scaffold/search.slim +2 -2
  64. data/views/scaffold/search_collapse.slim +6 -5
  65. data/views/scaffold/search_tabs.slim +4 -3
  66. data/views/scaffold/view.slim +2 -2
  67. data/views/scaffold/view_collapse.slim +5 -4
  68. data/views/scaffold/view_tabs.slim +4 -3
  69. data/views/search_fields/bsmselect_picker.slim +4 -4
  70. data/views/search_fields/bsselect_picker.slim +4 -4
  71. data/views/search_fields/checkbox.slim +3 -3
  72. data/views/search_fields/checkbox2.slim +5 -5
  73. data/views/search_fields/checkbox_buttons.slim +3 -3
  74. data/views/search_fields/date_range.slim +8 -8
  75. data/views/search_fields/decimal_date_range.slim +5 -5
  76. data/views/search_fields/input_text.slim +2 -2
  77. data/views/search_fields/integer.slim +1 -1
  78. data/views/search_fields/integer_range.slim +2 -2
  79. data/views/search_fields/list_bsmselect.slim +4 -4
  80. data/views/search_fields/list_bsselect.slim +4 -4
  81. data/views/search_fields/list_buttons.slim +2 -2
  82. data/views/search_fields/list_select.slim +3 -3
  83. data/views/search_fields/scaffold_picker.slim +2 -2
  84. data/views/search_fields/select_picker.slim +3 -3
  85. data/views/search_fields/typeahead_picker.slim +4 -4
  86. metadata +6 -5
@@ -8,6 +8,7 @@
8
8
  :error: Error
9
9
  :no_entry: Entry doesnt exist
10
10
  :decode_selected: selected
11
+ :list_select_selected: Selected
11
12
 
12
13
  :name: Name
13
14
  :mime: Mime
@@ -8,6 +8,7 @@
8
8
  :error: Błąd
9
9
  :no_entry: Wpis nie istnieje
10
10
  :decode_selected: wybranych
11
+ :list_select_selected: Wybranych
11
12
 
12
13
  :name: Nazwa
13
14
  :mime: Mime
@@ -9,7 +9,7 @@ exports.config =
9
9
  "bootstrap-additions": ["dist/bootstrap-additions.css"]
10
10
  "angular-motion": ["dist/angular-motion.css"]
11
11
  "angular-ui-tree": ["dist/angular-ui-tree.css"]
12
- "font-awesome": ["css/font-awesome.css"]
12
+ "fork-awesome": ["css/fork-awesome.css"]
13
13
 
14
14
  modules:
15
15
  definition: 'commonjs'
@@ -64,7 +64,7 @@ exports.config =
64
64
 
65
65
  copycat:
66
66
  fonts: [
67
- "node_modules/font-awesome/fonts"
67
+ "node_modules/fork-awesome/fonts"
68
68
  "node_modules/bootstrap/fonts"
69
69
  ]
70
70
  verbose: true
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
16
16
  spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
17
17
  spec.require_paths = ["lib"]
18
18
 
19
- spec.add_dependency "sequel", '~> 4'
19
+ spec.add_dependency "sequel", '~> 5'
20
20
  if defined? JRUBY_VERSION
21
21
  spec.add_dependency 'jdbc-sqlite3', '~> 3.8'
22
22
  else
@@ -54,9 +54,9 @@ module Engine2
54
54
  def invoke! handler
55
55
  if rmp = @request_action_proc
56
56
  action = self.class.new(node, assets, self)
57
- action_result = action.instance_exec(handler, *action.request_action_proc_params(handler), &rmp)
57
+ result = action.instance_exec(handler, *action.request_action_proc_params(handler), &rmp)
58
58
  action.post_process
59
- response = @requestable ? (action_result || {}) : action.invoke(handler)
59
+ response = @requestable ? (result || {}) : action.invoke(handler)
60
60
  response[:meta] = action.meta
61
61
  response
62
62
  else
@@ -72,8 +72,8 @@ module Engine2
72
72
  @meta[:arguments] = args
73
73
  end
74
74
 
75
- def execute time
76
- @meta[:execute] = time
75
+ def execute command
76
+ (@meta[:execute] ||= []) << command
77
77
  end
78
78
 
79
79
  def dynamic?
@@ -189,11 +189,12 @@ module Engine2
189
189
  @ws_methods.each do |method, blk|
190
190
  ws.on(method) do |evt|
191
191
  begin
192
- if method == :message
193
- blk.(JSON.parse(evt.data, symbolize_names: true), ws, evt)
194
- else
195
- blk.(evt, ws, evt)
196
- end
192
+ data = method == :message ? JSON.parse(evt.data, symbolize_names: true) : evt
193
+ action = self.class.new(node, assets, self)
194
+ result = action.instance_exec(data, ws, evt, &blk)
195
+ result = {} unless result.is_a?(Hash)
196
+ result[:meta] = action.meta
197
+ ws.send! result unless action.meta.empty?
197
198
  rescue Exception => e
198
199
  ws.send! error: {exception: e, method: method}
199
200
  end
@@ -222,18 +223,18 @@ module Engine2
222
223
  end
223
224
 
224
225
  module ActionAPISupport
225
- def info field
226
- (@meta[:info] ||= {})[field.to_sym] ||= {}
226
+ def fields field
227
+ (@meta[:fields] ||= {})[field.to_sym] ||= {}
227
228
  end
228
229
 
229
230
  def config
230
231
  @meta[:config] ||= {}
231
232
  end
232
233
 
233
- def info! *fields, options
234
+ def fields! *fields, options
234
235
  raise E2Error.new("No fields given to info") if fields.empty?
235
236
  fields.each do |field|
236
- info(field).merge! options # rmerge ?
237
+ fields(field).merge! options # rmerge ?
237
238
  end
238
239
  end
239
240
 
@@ -243,24 +244,24 @@ module Engine2
243
244
 
244
245
  def decorate list
245
246
  list.each do |f|
246
- info(f)[:loc] ||= LOCS[f.to_sym]
247
+ fields(f)[:loc] ||= LOCS[f.to_sym]
247
248
  end
248
249
  end
249
250
 
250
251
  def render field, options
251
- info! field, render: options
252
+ fields! field, render: options
252
253
  end
253
254
 
254
255
  def hide_fields *flds
255
- info! *flds, hidden: true
256
+ fields! *flds, hidden: true
256
257
  end
257
258
 
258
259
  def show_fields *flds
259
- info! *flds, hidden: false
260
+ fields! *flds, hidden: false
260
261
  end
261
262
 
262
263
  def field_filter *flds, filter
263
- info! *flds, filter: filter
264
+ fields! *flds, filter: filter
264
265
  end
265
266
  end
266
267
 
@@ -321,23 +322,6 @@ module Engine2
321
322
  show_fields *assets[:model].primary_keys
322
323
  end
323
324
 
324
- def get_type_info name
325
- model = assets[:model]
326
- info = case name
327
- when Symbol
328
- model.type_info[name]
329
- when Sequel::SQL::QualifiedIdentifier
330
- assoc = model.many_to_one_associations[name.table] || model.many_to_many_associations[name.table]
331
- raise E2Error.new("Association #{name.table} not found for model #{model}") unless assoc
332
- assoc.associated_class.type_info[name.column]
333
- else
334
- raise E2Error.new("Unknown type info key: #{name} in model #{model}")
335
- end
336
-
337
- raise E2Error.new("Type info not found for '#{name}' in model '#{model}'") unless info
338
- info
339
- end
340
-
341
325
  # def parent_model_name
342
326
  # model = @assets[:model]
343
327
  # prnt = node.parent
@@ -431,13 +415,13 @@ module Engine2
431
415
  end
432
416
 
433
417
  def find_record handler, id
434
- get_query[assets[:model].primary_keys_hash_qualified(split_keys(id))]
418
+ get_query.load assets[:model].primary_keys_hash_qualified(split_keys(id))
435
419
  end
436
420
 
437
421
  def select *args, use_pk: true, &blk
438
422
  ds = assets[:model].select(*args, &blk)
439
423
  ds = ds.ensure_primary_key if use_pk
440
- ds.setup!(@meta[:fields] = [])
424
+ ds.setup_query(@meta[:field_list] = [])
441
425
  end
442
426
  end
443
427
 
@@ -448,15 +432,15 @@ module Engine2
448
432
  end
449
433
 
450
434
  def field_tabs hash
451
- @meta[:tabs] = hash.map{|k, v| {name: k, loc: LOCS[k], fields: v} }
435
+ @meta[:tab_list] = hash.keys
436
+ @meta[:tabs] = hash.reduce({}){|h, (k, v)| h[k] = {name: k, loc: LOCS[k], field_list: v}; h}
452
437
  end
453
438
 
454
- def lazy_tab tab_name
455
- tabs = @meta[:tabs]
456
- raise E2Error.new("No tabs defined") unless tabs
457
- tab = tabs.find{|t| t[:name] == tab_name}
458
- raise E2Error.new("No tab #{tab_name} defined") unless tab
459
- tab[:lazy] = true
439
+ def tab *tabs, options
440
+ raise E2Error.new("No tabs given to info") if tabs.empty?
441
+ tabs.each do |tab|
442
+ @meta[:tabs][tab].merge! options # rmerge ?
443
+ end
460
444
  end
461
445
  end
462
446
 
@@ -484,7 +468,7 @@ module Engine2
484
468
 
485
469
  def ng_info! name, *selector, expression
486
470
  # expression = "'#{expression}'" if expression.is_a? String
487
- "action.meta.info['#{name}'].#{selector.join('.')} = #{expression}"
471
+ "action.meta.fields['#{name}'].#{selector.join('.')} = #{expression}"
488
472
  end
489
473
 
490
474
  def ng_call name, *args
@@ -542,6 +526,17 @@ module Engine2
542
526
  end
543
527
  end
544
528
 
529
+ module ActionDraggableSupport
530
+ def draggable
531
+ @meta[:draggable] ||= {}
532
+ end
533
+
534
+ def post_run
535
+ super
536
+ draggable[:position_field] ||= 'position' if @meta[:draggable]
537
+ end
538
+ end
539
+
545
540
  class MenuAction < Action
546
541
  include ActionMenuSupport
547
542
  action_type :menu
@@ -583,8 +578,8 @@ module Engine2
583
578
  nd = node.define_node node_name, (blk.arity > 2 ? OnChangeGetAction : OnChangePostAction)
584
579
  nd.*{request &blk}
585
580
 
586
- info! field, remote_onchange: node_name
587
- info! field, remote_onchange_record: :true if blk.arity > 2
581
+ fields! field, remote_onchange: node_name
582
+ fields! field, remote_onchange_record: :true if blk.arity > 2
588
583
  end
589
584
 
590
585
  class OnChangeAction < Action
@@ -626,7 +621,7 @@ module Engine2
626
621
  end
627
622
 
628
623
  module ActionListSupport
629
- include ActionModelSupport, ActionAPISupport, ActionTabSupport, ActionPanelSupport, ActionMenuSupport, ActionOnChangeSupport
624
+ include ActionModelSupport, ActionAPISupport, ActionTabSupport, ActionPanelSupport, ActionMenuSupport, ActionOnChangeSupport, ActionDraggableSupport
630
625
  attr_reader :filters, :orders
631
626
 
632
627
  def pre_run
@@ -638,7 +633,7 @@ module Engine2
638
633
  loc! LOCS[:list_locs]
639
634
  menu :menu do
640
635
  properties break: 2, group_class: "btn-group-xs"
641
- option :search_toggle, icon: "search", show: "action.meta.search_fields", active: "action.ui_state.search_active", button_loc: false
636
+ option :search_toggle, icon: "search", show: "action.meta.search_field_list", active: "action.ui_state.search_active", button_loc: false
642
637
  # divider
643
638
  option :refresh, icon: "refresh", button_loc: false
644
639
  option :default_order, icon: "signal", button_loc: false
@@ -669,7 +664,7 @@ module Engine2
669
664
 
670
665
  def post_run
671
666
  unless panel[:class]
672
- panel_class case @meta[:fields].size
667
+ panel_class case @meta[:field_list].size
673
668
  when 1..3; ''
674
669
  when 4..6; 'modal-large'
675
670
  else; 'modal-huge'
@@ -687,21 +682,22 @@ module Engine2
687
682
  # end
688
683
 
689
684
  def post_process
690
- if fields = @meta[:search_fields]
691
- fields = fields - static.meta[:search_fields] if dynamic?
685
+ model = assets[:model]
686
+ if fields = @meta[:search_field_list]
687
+ fields = fields - static.meta[:search_field_list] if dynamic?
692
688
 
693
689
  decorate(fields)
694
690
  fields.each do |name|
695
- type_info = get_type_info(name)
691
+ type_info = model.find_type_info(name)
696
692
 
697
- # render = info[name][:render]
693
+ # render = fields[name][:render]
698
694
  # if not render
699
- # info[name][:render] = find_renderer(type_info)
695
+ # fields[name][:render] = find_renderer(type_info)
700
696
  # else
701
- # info[name][:render].merge!(find_renderer(type_info)){|key, v1, v2|v1}
697
+ # fields[name][:render].merge!(find_renderer(type_info)){|key, v1, v2|v1}
702
698
  # end
703
699
 
704
- info(name)[:render] ||= begin # set before :fields
700
+ fields(name)[:render] ||= begin # set before :field_list
705
701
  renderer = DefaultSearchRenderers[type_info[:type]] || DefaultSearchRenderers[type_info[:otype]]
706
702
  raise E2Error.new("No search renderer found for field '#{type_info[:name]}'") unless renderer
707
703
  renderer.(self, type_info)
@@ -712,12 +708,12 @@ module Engine2
712
708
  end
713
709
  end
714
710
 
715
- if fields = @meta[:fields]
716
- fields = fields - static.meta[:fields] if dynamic?
711
+ if fields = @meta[:field_list]
712
+ fields = fields - static.meta[:field_list] if dynamic?
717
713
 
718
714
  decorate(fields)
719
715
  fields.each do |name|
720
- type_info = get_type_info(name)
716
+ type_info = model.find_type_info(name)
721
717
  proc = ListRendererPostProcessors[type_info[:type]]
722
718
  proc.(self, name, type_info) if proc
723
719
  end
@@ -731,19 +727,20 @@ module Engine2
731
727
  end
732
728
 
733
729
  def sortable *flds
734
- flds = @meta[:fields] if flds.empty?
735
- info! *flds, sort: true
730
+ flds = @meta[:field_list] if flds.empty?
731
+ fields! *flds, sort: true
736
732
  end
737
733
 
738
734
  def search_live *flds
739
- flds = @meta[:search_fields] if flds.empty?
740
- info! *flds, search_live: true
735
+ flds = @meta[:search_field_list] if flds.empty?
736
+ fields! *flds, search_live: true
741
737
  end
742
738
 
743
739
  def searchable *flds
740
+ @meta.delete(:tab_list)
744
741
  @meta.delete(:tabs)
745
742
  search_template 'scaffold/search'
746
- @meta[:search_fields] = *flds
743
+ @meta[:search_field_list] = *flds
747
744
  end
748
745
 
749
746
  def searchable_tabs tabs
@@ -760,8 +757,8 @@ module Engine2
760
757
  end
761
758
 
762
759
  def filter_case_insensitive name
763
- raise E2Error.new("Field '#{name}' needs to be a string one") unless get_type_info(name)[:otype] == :string
764
- filter(name){|query, hash, handler| query.where(name.ilike("%#{hash[name]}%")) }
760
+ raise E2Error.new("Field '#{name}' needs to be a string one") unless assets[:model].find_type_info(name)[:otype] == :string
761
+ filter(name){|handler, query, hash| query.where(name.ilike("%#{hash[name]}%")) }
765
762
  end
766
763
 
767
764
  def order name, &blk
@@ -794,7 +791,7 @@ module Engine2
794
791
  def validate_and_approve handler, record, parent_id
795
792
  static.before_approve(handler, record)
796
793
  record.valid?
797
- validate_record(handler, record)
794
+ validate_record(handler, record, parent_id)
798
795
  if record.errors.empty?
799
796
  static.after_approve(handler, record)
800
797
  true
@@ -828,10 +825,10 @@ module Engine2
828
825
  (@validations ||= {})[name] = blk
829
826
  end
830
827
 
831
- def validate_record handler, record
828
+ def validate_record handler, record, parent_id
832
829
  @validations.each do |name, val|
833
830
  unless record.errors[name]
834
- result = val.(record, handler)
831
+ result = val.(handler, record, parent_id)
835
832
  record.errors.add(name, result) if result
836
833
  end
837
834
  end if @validations
@@ -844,7 +841,7 @@ module Engine2
844
841
 
845
842
  def post_run
846
843
  super
847
- validate_fields *node.parent.*.meta[:fields] unless validate_fields
844
+ validate_fields *node.parent.*.meta[:field_list] unless validate_fields
848
845
  end
849
846
  end
850
847
 
@@ -859,7 +856,7 @@ module Engine2
859
856
  end
860
857
 
861
858
  def validate_and_approve handler, record, parent_id, validate_only = self.class.validate_only
862
- if validate_only then
859
+ if validate_only
863
860
  super(handler, record, parent_id)
864
861
  else
865
862
  record.skip_save_refresh = true
@@ -868,7 +865,7 @@ module Engine2
868
865
  assoc = assets[:assoc]
869
866
  new_assoc = record.new? && assoc && assoc[:type]
870
867
 
871
- save = lambda do|c|
868
+ save = lambda do |c|
872
869
  if super(handler, record, parent_id)
873
870
  if new_assoc == :one_to_many
874
871
  handler.permit parent_id
@@ -965,16 +962,16 @@ module Engine2
965
962
  end
966
963
 
967
964
  def post_process
968
- if fields = @meta[:fields]
969
- fields = fields - static.meta[:fields] if dynamic?
965
+ if fields = @meta[:field_list]
966
+ model = assets[:model]
967
+ fields = fields - static.meta[:field_list] if dynamic?
970
968
 
971
969
  decorate(fields)
972
970
 
973
971
  fields.each do |name|
974
- # type_info = model.type_info.fetch(name)
975
- type_info = get_type_info(name)
972
+ type_info = model.find_type_info(name)
976
973
 
977
- info(name)[:render] ||= begin
974
+ fields(name)[:render] ||= begin
978
975
  renderer = DefaultFormRenderers[type_info[:type]] # .merge(default: true)
979
976
  raise E2Error.new("No form renderer found for field '#{type_info[:name]}' of type '#{type_info[:type]}'") unless renderer
980
977
  renderer.(self, type_info)
@@ -987,11 +984,11 @@ module Engine2
987
984
  assoc = assets[:assoc]
988
985
  if assoc && assoc[:type] == :one_to_many
989
986
  # fields.select{|f| assoc[:keys].include? f}.each do |key|
990
- # # hide_fields(key) if self[:info, key, :hidden] == nil
991
- # info! key, disabled: true
987
+ # # hide_fields(key) if self[:fields, key, :hidden] == nil
988
+ # fields! key, disabled: true
992
989
  # end
993
990
  assoc[:keys].each do |key|
994
- info! key, disabled: true if fields.include? key
991
+ fields! key, disabled: true if fields.include? key
995
992
  end
996
993
  end
997
994
  end
@@ -1009,7 +1006,7 @@ module Engine2
1009
1006
  end
1010
1007
 
1011
1008
  def hr_after field, message = '-'
1012
- info! field, hr: message
1009
+ fields! field, hr: message
1013
1010
  end
1014
1011
  end
1015
1012
 
@@ -1022,8 +1019,8 @@ module Engine2
1022
1019
 
1023
1020
  def pre_run
1024
1021
  super
1025
- panel_title LOCS[:create_title]
1026
- node.parent.*.menu(:menu).option_at 0, node.name, icon: "plus-sign", button_loc: false
1022
+ panel_title "#{LOCS[:create_title]} - #{LOCS[assets[:model].table_name]}"
1023
+ node.parent.*.menu(:menu).option_at 0, node.name, icon: "plus-sign", button_loc: false if node.parent.*.is_a?(ListAction)
1027
1024
 
1028
1025
  hide_pk unless assets[:model].natural_key
1029
1026
  end
@@ -1058,7 +1055,7 @@ module Engine2
1058
1055
 
1059
1056
  def pre_run
1060
1057
  super
1061
- panel_title LOCS[:modify_title]
1058
+ panel_title "#{LOCS[:modify_title]} - #{LOCS[assets[:model].table_name]}"
1062
1059
  node.parent.*.menu(:item_menu).option node.name, icon: "pencil", button_loc: false
1063
1060
  end
1064
1061
 
@@ -1084,7 +1081,7 @@ module Engine2
1084
1081
  def post_run
1085
1082
  super
1086
1083
  assets[:model].primary_keys.each do |key| # pre_run ?
1087
- info! key, disabled: true
1084
+ fields! key, disabled: true
1088
1085
  end
1089
1086
  end
1090
1087
  end
@@ -1099,7 +1096,7 @@ module Engine2
1099
1096
  def pre_run
1100
1097
  super
1101
1098
  panel_template 'scaffold/view'
1102
- panel_title LOCS[:view_title]
1099
+ panel_title "#{LOCS[:view_title]} - #{LOCS[assets[:model].table_name]}"
1103
1100
  panel[:backdrop] = true
1104
1101
 
1105
1102
  menu(:panel_menu).option :cancel, icon: "remove"
@@ -1126,12 +1123,13 @@ module Engine2
1126
1123
  end
1127
1124
 
1128
1125
  def post_process
1129
- if fields = @meta[:fields]
1130
- fields = fields - static.meta[:fields] if dynamic?
1126
+ if fields = @meta[:field_list]
1127
+ model = assets[:model]
1128
+ fields = fields - static.meta[:field_list] if dynamic?
1131
1129
 
1132
1130
  decorate(fields)
1133
1131
  fields.each do |name|
1134
- type_info = get_type_info(name)
1132
+ type_info = model.find_type_info(name)
1135
1133
  proc = ListRendererPostProcessors[type_info[:type]]
1136
1134
  proc.(self, name, type_info) if proc
1137
1135
  end
@@ -1174,87 +1172,92 @@ module Engine2
1174
1172
 
1175
1173
  (FormRendererPostProcessors ||= {}).merge!(
1176
1174
  boolean: lambda{|action, field, info|
1177
- action.info(field)[:render].merge! true_value: info[:true_value], false_value: info[:false_value]
1178
- action.info(field)[:dont_strip] = info[:dont_strip] if info[:dont_strip]
1175
+ action.fields(field)[:render].merge! true_value: info[:true_value], false_value: info[:false_value]
1176
+ action.fields(field)[:dont_strip] = info[:dont_strip] if info[:dont_strip]
1179
1177
  },
1180
1178
  date: lambda{|action, field, info|
1181
- action.info(field)[:render].merge! format: info[:format], model_format: info[:model_format]
1179
+ action.fields(field)[:render].merge! format: info[:format], model_format: info[:model_format]
1182
1180
  if date_to = info[:other_date]
1183
- action.info(field)[:render].merge! other_date: date_to #, format: info[:format], model_format: info[:model_format]
1181
+ action.fields(field)[:render].merge! other_date: date_to #, format: info[:format], model_format: info[:model_format]
1184
1182
  action.hide_fields date_to
1185
1183
  elsif time = info[:other_time]
1186
- action.info(field)[:render].merge! other_time: time
1184
+ action.fields(field)[:render].merge! other_time: time
1187
1185
  action.hide_fields time
1188
1186
  end
1189
1187
  },
1190
1188
  time: lambda{|action, field, info|
1191
- action.info(field)[:render].merge! format: info[:format], model_format: info[:model_format]
1189
+ render = action.fields(field)[:render]
1190
+ render[:type] ||= info[:otype] == :string ? :string : :number
1191
+ render.merge! format: info[:format], model_format: info[:model_format]
1192
1192
  },
1193
1193
  decimal_date: lambda{|action, field, info|
1194
1194
  FormRendererPostProcessors[:date].(action, field, info)
1195
- action.info! field, type: :decimal_date
1195
+ action.fields! field, type: :decimal_date
1196
1196
  },
1197
1197
  decimal_time: lambda{|action, field, info|
1198
1198
  FormRendererPostProcessors[:time].(action, field, info)
1199
- action.info! field, type: :decimal_time
1199
+ action.fields! field, type: :decimal_time
1200
1200
  },
1201
1201
  datetime: lambda{|action, field, info|
1202
- action.info(field)[:render].merge! date_format: info[:date_format], time_format: info[:time_format], date_model_format: info[:date_model_format], time_model_format: info[:time_model_format]
1202
+ action.fields(field)[:render].merge! date_format: info[:date_format], time_format: info[:time_format], date_model_format: info[:date_model_format], time_model_format: info[:time_model_format]
1203
1203
  },
1204
1204
  currency: lambda{|action, field, info|
1205
- action.info(field)[:render].merge! symbol: info[:symbol]
1205
+ action.fields(field)[:render].merge! symbol: info[:symbol]
1206
1206
  },
1207
1207
  # date_range: lambda{|action, field, info|
1208
- # action.info[field][:render].merge! other_date: info[:other_date], format: info[:format], model_format: info[:model_format]
1208
+ # action.fields[field][:render].merge! other_date: info[:other_date], format: info[:format], model_format: info[:model_format]
1209
1209
  # action.hide_fields info[:other_date]
1210
- # action.info[field][:decimal_date] = true if info[:validations][:decimal_date]
1210
+ # action.fields[field][:decimal_date] = true if info[:validations][:decimal_date]
1211
1211
  # },
1212
1212
  list_select: lambda{|action, field, info|
1213
- action.info(field)[:render].merge! list: info[:list]
1213
+ render = action.fields(field)[:render]
1214
+ render.merge! values: info[:values]
1215
+ render.merge! max_length: info[:max_length], max_length_html: info[:max_length_html], separator: info[:separator] if info[:multiselect]
1214
1216
  },
1215
1217
  many_to_one: lambda{|action, field, info|
1216
- field_info = action.info(field)
1218
+ field_info = action.fields(field)
1217
1219
  field_info[:assoc] = :"#{info[:assoc_name]}!"
1218
1220
  field_info[:fields] = info[:keys]
1219
1221
  field_info[:type] = info[:otype]
1220
1222
 
1221
1223
  (info[:keys] - [field]).each do |of|
1222
- f_info = action.info(of)
1224
+ f_info = action.fields(of)
1223
1225
  f_info[:hidden] = true
1224
1226
  f_info[:type] = action.assets[:model].type_info[of].fetch(:otype)
1225
1227
  end
1226
1228
  },
1227
1229
  file_store: lambda{|action, field, info|
1228
- action.info(field)[:render].merge! multiple: info[:multiple]
1230
+ action.fields(field)[:render].merge! multiple: info[:multiple]
1229
1231
  },
1230
1232
  star_to_many_field: lambda{|action, field, info|
1231
- field_info = action.info(field)
1233
+ field_info = action.fields(field)
1232
1234
  field_info[:assoc] = :"#{info[:assoc_name]}!"
1233
1235
  }
1234
1236
  )
1235
1237
 
1236
1238
  (ListRendererPostProcessors ||= {}).merge!(
1237
1239
  boolean: lambda{|action, field, info|
1238
- action.info! field, type: :boolean # move to action ?
1239
- action.info(field)[:render] ||= {}
1240
- action.info(field)[:render].merge! true_value: info[:true_value], false_value: info[:false_value]
1240
+ action.fields! field, type: :boolean # move to action ?
1241
+ action.fields(field)[:render] ||= {}
1242
+ action.fields(field)[:render].merge! true_value: info[:true_value], false_value: info[:false_value]
1241
1243
  },
1242
1244
  list_select: lambda{|action, field, info|
1243
- action.info! field, type: :list_select
1244
- action.info(field)[:render] ||= {}
1245
- action.info(field)[:render].merge! list: info[:list]
1245
+ action.fields! field, type: :list_select
1246
+ render = (action.fields(field)[:render] ||= {})
1247
+ render.merge! values: info[:values]
1248
+ render.merge! multiselect: true if info[:multiselect]
1246
1249
  },
1247
1250
  datetime: lambda{|action, field, info|
1248
- action.info! field, type: :datetime
1251
+ action.fields! field, type: :datetime
1249
1252
  },
1250
1253
  decimal_date: lambda{|action, field, info|
1251
- action.info! field, type: :decimal_date
1254
+ action.fields! field, type: :decimal_date
1252
1255
  },
1253
1256
  decimal_time: lambda{|action, field, info|
1254
- action.info! field, type: :decimal_time
1257
+ action.fields! field, type: :decimal_time
1255
1258
  },
1256
1259
  # date_range: lambda{|action, field, info|
1257
- # action.info[field][:type] = :decimal_date if info[:validations][:decimal_date] # ? :decimal_date : :date
1260
+ # action.fields[field][:type] = :decimal_date if info[:validations][:decimal_date] # ? :decimal_date : :date
1258
1261
  # }
1259
1262
  )
1260
1263
 
@@ -1269,21 +1272,21 @@ module Engine2
1269
1272
  keys = info[:keys].map{|k| model.table_name.q(k)}
1270
1273
  end
1271
1274
 
1272
- field_info = action.info(field)
1275
+ field_info = action.fields(field)
1273
1276
  field_info[:assoc] = :"#{info[:assoc_name]}!"
1274
1277
  field_info[:fields] = keys
1275
1278
  field_info[:type] = info[:otype]
1276
1279
 
1277
1280
  (keys - [field]).each do |of|
1278
- f_info = action.info(of)
1281
+ f_info = action.fields(of)
1279
1282
  raise E2Error.new("Missing searchable field: '#{of}' in model '#{action.assets[:model]}'") unless f_info
1280
1283
  f_info[:hidden_search] = true
1281
1284
  f_info[:type] = model.type_info[of].fetch(:otype)
1282
1285
  end
1283
1286
  },
1284
1287
  date: lambda{|action, field, info|
1285
- action.info(field)[:render] ||= {}
1286
- action.info(field)[:render].merge! format: info[:format], model_format: info[:model_format] # Model::DEFAULT_DATE_FORMAT
1288
+ action.fields(field)[:render] ||= {}
1289
+ action.fields(field)[:render].merge! format: info[:format], model_format: info[:model_format] # Model::DEFAULT_DATE_FORMAT
1287
1290
  },
1288
1291
  decimal_date: lambda{|action, field, info|
1289
1292
  SearchRendererPostProcessors[:date].(action, field, info)
@@ -1313,14 +1316,15 @@ module Engine2
1313
1316
  boolean: lambda{|action, info| Templates.checkbox_buttons(optional: !info[:required])},
1314
1317
  currency: lambda{|action, info| Templates.currency},
1315
1318
  list_select: lambda{|action, info|
1316
- length = info[:list].length
1317
- if length <= 3
1319
+ length = info[:values].length
1320
+ max_length = info[:values].map(&:last).max_by(&:length).length
1321
+ if info[:multiselect]
1322
+ Templates.list_bsmselect(max_length)
1323
+ elsif length <= 3
1318
1324
  Templates.list_buttons(optional: !info[:required])
1319
1325
  elsif length <= 15
1320
- max_length = info[:list].max_by{|a|a.last.length}.last.length
1321
1326
  Templates.list_bsselect(max_length, optional: !info[:required])
1322
1327
  else
1323
- max_length = info[:list].max_by{|a|a.last.length}.last.length
1324
1328
  Templates.list_select(max_length, optional: !info[:required])
1325
1329
  end
1326
1330
  },
@@ -1344,7 +1348,7 @@ module Engine2
1344
1348
  string: lambda{|action, info| SearchTemplates.input_text},
1345
1349
  boolean: lambda{|action, info| SearchTemplates.checkbox_buttons},
1346
1350
  list_select: lambda{|action, info|
1347
- length = info[:list].length
1351
+ length = info[:values].length
1348
1352
  if length <= 3
1349
1353
  SearchTemplates.list_buttons
1350
1354
  elsif length <= 15