engine2 1.0.4 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -0
  3. data/Rakefile +1 -1
  4. data/app/{engine2actions.coffee → actions.coffee} +192 -142
  5. data/app/app.coffee +0 -0
  6. data/app/app.css +4 -0
  7. data/app/engine2.coffee +87 -175
  8. data/app/modal.coffee +133 -0
  9. data/bower.json +2 -1
  10. data/conf/message.yaml +0 -0
  11. data/conf/message_pl.yaml +0 -0
  12. data/config.coffee +11 -2
  13. data/engine2.gemspec +2 -2
  14. data/lib/engine2.rb +12 -10
  15. data/lib/engine2/action.rb +1290 -134
  16. data/lib/engine2/{meta/array_meta.rb → action/array.rb} +4 -3
  17. data/lib/engine2/{meta/decode_meta.rb → action/decode.rb} +16 -15
  18. data/lib/engine2/action/delete.rb +65 -0
  19. data/lib/engine2/action/form.rb +16 -0
  20. data/lib/engine2/{meta/infra_meta.rb → action/infra.rb} +118 -85
  21. data/lib/engine2/action/link.rb +117 -0
  22. data/lib/engine2/{meta/list_meta.rb → action/list.rb} +61 -62
  23. data/lib/engine2/action/save.rb +30 -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 +120 -77
  27. data/lib/engine2/handler.rb +9 -10
  28. data/lib/engine2/model.rb +4 -20
  29. data/lib/engine2/models/Files.rb +2 -1
  30. data/lib/engine2/models/UserInfo.rb +6 -3
  31. data/lib/engine2/post_bootstrap.rb +3 -2
  32. data/lib/engine2/pre_bootstrap.rb +1 -0
  33. data/lib/engine2/scheme.rb +98 -47
  34. data/lib/engine2/templates.rb +1 -0
  35. data/lib/engine2/type_info.rb +6 -4
  36. data/lib/engine2/version.rb +2 -1
  37. data/package.json +12 -10
  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 +0 -0
  42. data/views/fields/bs_select.slim +0 -0
  43. data/views/fields/bsselect_picker.slim +0 -0
  44. data/views/fields/bsselect_picker_opt.slim +0 -0
  45. data/views/fields/checkbox.slim +0 -0
  46. data/views/fields/checkbox_buttons.slim +0 -0
  47. data/views/fields/checkbox_buttons_opt.slim +0 -0
  48. data/views/fields/currency.slim +0 -0
  49. data/views/fields/date.slim +0 -0
  50. data/views/fields/date_range.slim +0 -0
  51. data/views/fields/date_time.slim +0 -0
  52. data/views/fields/datetime.slim +0 -0
  53. data/views/fields/decimal.slim +0 -0
  54. data/views/fields/decimal_date.slim +0 -0
  55. data/views/fields/decimal_time.slim +0 -0
  56. data/views/fields/email.slim +0 -0
  57. data/views/fields/file_store.slim +7 -7
  58. data/views/fields/input_text.slim +0 -0
  59. data/views/fields/integer.slim +0 -0
  60. data/views/fields/list_bsselect.slim +0 -0
  61. data/views/fields/list_bsselect_opt.slim +0 -0
  62. data/views/fields/list_buttons.slim +0 -0
  63. data/views/fields/list_buttons_opt.slim +0 -0
  64. data/views/fields/list_select.slim +0 -0
  65. data/views/fields/list_select_opt.slim +0 -0
  66. data/views/fields/password.slim +0 -0
  67. data/views/fields/radio_checkbox.slim +0 -0
  68. data/views/fields/scaffold.slim +0 -0
  69. data/views/fields/scaffold_picker.slim +0 -0
  70. data/views/fields/select_picker.slim +0 -0
  71. data/views/fields/select_picker_opt.slim +0 -0
  72. data/views/fields/text_area.slim +1 -0
  73. data/views/fields/time.slim +0 -0
  74. data/views/fields/typeahead_picker.slim +0 -0
  75. data/views/index.slim +3 -3
  76. data/views/infra/index.slim +0 -0
  77. data/views/infra/inspect.slim +20 -0
  78. data/views/modals/close_m.slim +0 -0
  79. data/views/modals/confirm_m.slim +0 -0
  80. data/views/modals/empty_m.slim +0 -0
  81. data/views/modals/menu_m.slim +1 -1
  82. data/views/modals/yes_no_m.slim +0 -0
  83. data/views/panels/menu_m.slim +1 -1
  84. data/views/scaffold/confirm.slim +0 -0
  85. data/views/scaffold/fields.slim +0 -0
  86. data/views/scaffold/form.slim +0 -0
  87. data/views/scaffold/form_collapse.slim +0 -0
  88. data/views/scaffold/form_tabs.slim +0 -0
  89. data/views/scaffold/list.slim +0 -0
  90. data/views/scaffold/message.slim +0 -0
  91. data/views/scaffold/search.slim +0 -0
  92. data/views/scaffold/search_collapse.slim +0 -0
  93. data/views/scaffold/search_tabs.slim +0 -0
  94. data/views/scaffold/view.slim +0 -0
  95. data/views/scaffold/view_collapse.slim +0 -0
  96. data/views/scaffold/view_tabs.slim +0 -0
  97. data/views/search_fields/bsmselect_picker.slim +0 -0
  98. data/views/search_fields/bsselect_picker.slim +0 -0
  99. data/views/search_fields/checkbox.slim +0 -0
  100. data/views/search_fields/checkbox2.slim +0 -0
  101. data/views/search_fields/checkbox_buttons.slim +0 -0
  102. data/views/search_fields/date_range.slim +0 -0
  103. data/views/search_fields/decimal_date_range.slim +0 -0
  104. data/views/search_fields/input_text.slim +0 -0
  105. data/views/search_fields/integer.slim +0 -0
  106. data/views/search_fields/integer_range.slim +0 -0
  107. data/views/search_fields/list_bsmselect.slim +0 -0
  108. data/views/search_fields/list_bsselect.slim +0 -0
  109. data/views/search_fields/list_buttons.slim +0 -0
  110. data/views/search_fields/list_select.slim +0 -0
  111. data/views/search_fields/scaffold_picker.slim +0 -0
  112. data/views/search_fields/select_picker.slim +0 -0
  113. data/views/search_fields/typeahead_picker.slim +0 -0
  114. metadata +41 -42
  115. data/lib/engine2/meta.rb +0 -1216
  116. data/lib/engine2/meta/delete_meta.rb +0 -60
  117. data/lib/engine2/meta/form_meta.rb +0 -15
  118. data/lib/engine2/meta/link_meta.rb +0 -134
  119. data/lib/engine2/meta/save_meta.rb +0 -50
  120. data/lib/engine2/meta/view_meta.rb +0 -7
  121. data/public/__sinatra__/404.png +0 -0
  122. data/public/__sinatra__/500.png +0 -0
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -7,21 +7,21 @@ e2-action action="[f + '_file_store!']"
7
7
  th Nazwa
8
8
  th Data
9
9
  tbody
10
- tr ng-repeat="f in action.files" ng-hide="f.deleted"
10
+ tr ng-repeat="ff in action.parent().record[f]" ng-hide="ff.deleted"
11
11
  td
12
12
  .btn-group.btn-group-xs
13
- a.btn.btn-default ng-click="action.show_file(f)": span.glyphicon.glyphicon-file
14
- a.btn.btn-default ng-click="action.delete_file(f)": span.glyphicon.glyphicon-trash
13
+ a.btn.btn-default ng-click="action.show_file(ff)": span.glyphicon.glyphicon-file
14
+ a.btn.btn-default ng-click="action.delete_file(ff)": span.glyphicon.glyphicon-trash
15
15
  td
16
- div ng-if="f.id": a ng-href="{{action.action_info().action_resource}}/download?id={{f.id}}" ng-bind="f.name"
17
- div ng-if="!f.id" ng-bind="f.name"
16
+ div ng-if="ff.id": a ng-href="{{action.action_info().action_resource}}/download?id={{ff.id}}" ng-bind="ff.name"
17
+ div ng-if="!ff.id" ng-bind="ff.name"
18
18
 
19
- td ng-bind="f.uploaded"
19
+ td ng-bind="ff.uploaded"
20
20
 
21
21
  div
22
22
  input [
23
23
  type="hidden"
24
- ng-model="action.record[f]"
24
+ ng-model="action.parent().record[f]"
25
25
  ]
26
26
 
27
27
  .progress.progress-striped
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1,5 +1,6 @@
1
1
  .col-lg-11
2
2
  textarea [
3
+ spellcheck="false"
3
4
  ng-model="action.record[f]"
4
5
  cols="{{info.render.cols}}"
5
6
  rows="{{info.render.rows}}"
File without changes
File without changes
@@ -5,11 +5,11 @@ html
5
5
  meta http-equiv="x-ua-compatible" content="IE=edge"
6
6
 
7
7
  link rel="stylesheet" href="engine2vendor.css"
8
- link rel="stylesheet" href="engine2app.css"
8
+ link rel="stylesheet" href="engine2.css"
9
9
  script type="text/javascript" src="engine2vendor.js"
10
10
  script type="text/javascript" src="engine2.js"
11
11
 
12
- body ng-app="app"
12
+ body ng-app="app" ng-strict-di=""
13
13
  e2-action ng-controller="AppController"
14
14
  .nav.navbar.navbar-default
15
15
  .container
@@ -36,5 +36,5 @@ html
36
36
  .navbar-text
37
37
 
38
38
  .container
39
- ng-view
39
+ ui-view
40
40
 
File without changes
@@ -83,3 +83,23 @@ e2-action action="'inspect'"
83
83
  .panel.panel-default
84
84
  .panel-body
85
85
  pre ng-bind="action.globals() | json"
86
+
87
+ div title="Environment" bs-pane=""
88
+ .panel.panel-default
89
+ .panel-body
90
+ pre ng-bind="action.environment | json"
91
+
92
+ div title="Diagnostics" bs-pane=""
93
+ .panel.panel-default
94
+ .panel-body
95
+ a.btn.btn-default ng-click="action.globals().notification('Name', 'Body', undefined, 2000)"
96
+ | Push
97
+ hr
98
+ a.btn.btn-default> ng-click="action.web_socket().send({number: action.number})"
99
+ | Websocket
100
+ | {{action.number}}
101
+ br
102
+ | Event
103
+ pre ng-bind="action.event | json"
104
+ | Socket
105
+ pre ng-bind="action.web_socket() | json"
File without changes
File without changes
File without changes
@@ -1,7 +1,7 @@
1
1
  .modal ng-class="action.meta.panel.class"
2
2
  .modal-dialog
3
3
  .modal-content
4
- .modal-header
4
+ .modal-header ng-if="::action.meta.panel.header"
5
5
  button.close type="button" ng-click="$hide()" ×
6
6
  h4.modal-title ng-bind-html="action.meta.panel.title"
7
7
 
File without changes
@@ -1,5 +1,5 @@
1
1
  .panel.panel-default
2
- .panel-heading
2
+ .panel-heading ng-if="::action.meta.panel.header"
3
3
  h4.modal-title ng-bind-html="action.meta.panel.title"
4
4
  .panel-body
5
5
  | modal-content-to-replace
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
metadata CHANGED
@@ -1,108 +1,108 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: engine2
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - lopex
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-15 00:00:00.000000000 Z
11
+ date: 2017-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
+ name: sequel
14
15
  requirement: !ruby/object:Gem::Requirement
15
16
  requirements:
16
17
  - - "~>"
17
18
  - !ruby/object:Gem::Version
18
19
  version: '4'
19
- name: sequel
20
- prerelease: false
21
20
  type: :runtime
21
+ prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '4'
27
27
  - !ruby/object:Gem::Dependency
28
+ name: sqlite3
28
29
  requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
31
  - - "~>"
31
32
  - !ruby/object:Gem::Version
32
- version: '1.4'
33
- name: rack-contrib
34
- prerelease: false
33
+ version: '1.3'
35
34
  type: :runtime
35
+ prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.4'
40
+ version: '1.3'
41
41
  - !ruby/object:Gem::Dependency
42
+ name: sinatra
42
43
  requirement: !ruby/object:Gem::Requirement
43
44
  requirements:
44
45
  - - "~>"
45
46
  - !ruby/object:Gem::Version
46
- version: '3.8'
47
- name: jdbc-sqlite3
48
- prerelease: false
47
+ version: '2.0'
49
48
  type: :runtime
49
+ prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '3.8'
54
+ version: '2.0'
55
55
  - !ruby/object:Gem::Dependency
56
+ name: slim
56
57
  requirement: !ruby/object:Gem::Requirement
57
58
  requirements:
58
59
  - - "~>"
59
60
  - !ruby/object:Gem::Version
60
- version: '1.4'
61
- name: sinatra
62
- prerelease: false
61
+ version: '3.0'
63
62
  type: :runtime
63
+ prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '1.4'
68
+ version: '3.0'
69
69
  - !ruby/object:Gem::Dependency
70
+ name: faye-websocket
70
71
  requirement: !ruby/object:Gem::Requirement
71
72
  requirements:
72
73
  - - "~>"
73
74
  - !ruby/object:Gem::Version
74
- version: '3.0'
75
- name: slim
76
- prerelease: false
75
+ version: '0.10'
77
76
  type: :runtime
77
+ prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '3.0'
82
+ version: '0.10'
83
83
  - !ruby/object:Gem::Dependency
84
+ name: bundler
84
85
  requirement: !ruby/object:Gem::Requirement
85
86
  requirements:
86
87
  - - "~>"
87
88
  - !ruby/object:Gem::Version
88
89
  version: '1.11'
89
- name: bundler
90
- prerelease: false
91
90
  type: :development
91
+ prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '1.11'
97
97
  - !ruby/object:Gem::Dependency
98
+ name: rake
98
99
  requirement: !ruby/object:Gem::Requirement
99
100
  requirements:
100
101
  - - "~>"
101
102
  - !ruby/object:Gem::Version
102
103
  version: '11'
103
- name: rake
104
- prerelease: false
105
104
  type: :development
105
+ prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
@@ -117,10 +117,11 @@ extra_rdoc_files: []
117
117
  files:
118
118
  - Gemfile
119
119
  - Rakefile
120
+ - app/actions.coffee
120
121
  - app/app.coffee
121
122
  - app/app.css
122
123
  - app/engine2.coffee
123
- - app/engine2actions.coffee
124
+ - app/modal.coffee
124
125
  - bower.json
125
126
  - conf/message.yaml
126
127
  - conf/message_pl.yaml
@@ -128,18 +129,18 @@ files:
128
129
  - engine2.gemspec
129
130
  - lib/engine2.rb
130
131
  - lib/engine2/action.rb
132
+ - lib/engine2/action/array.rb
133
+ - lib/engine2/action/decode.rb
134
+ - lib/engine2/action/delete.rb
135
+ - lib/engine2/action/form.rb
136
+ - lib/engine2/action/infra.rb
137
+ - lib/engine2/action/link.rb
138
+ - lib/engine2/action/list.rb
139
+ - lib/engine2/action/save.rb
140
+ - lib/engine2/action/view.rb
141
+ - lib/engine2/action_node.rb
131
142
  - lib/engine2/core.rb
132
143
  - lib/engine2/handler.rb
133
- - lib/engine2/meta.rb
134
- - lib/engine2/meta/array_meta.rb
135
- - lib/engine2/meta/decode_meta.rb
136
- - lib/engine2/meta/delete_meta.rb
137
- - lib/engine2/meta/form_meta.rb
138
- - lib/engine2/meta/infra_meta.rb
139
- - lib/engine2/meta/link_meta.rb
140
- - lib/engine2/meta/list_meta.rb
141
- - lib/engine2/meta/save_meta.rb
142
- - lib/engine2/meta/view_meta.rb
143
144
  - lib/engine2/model.rb
144
145
  - lib/engine2/models/Files.rb
145
146
  - lib/engine2/models/UserInfo.rb
@@ -150,8 +151,6 @@ files:
150
151
  - lib/engine2/type_info.rb
151
152
  - lib/engine2/version.rb
152
153
  - package.json
153
- - public/__sinatra__/404.png
154
- - public/__sinatra__/500.png
155
154
  - public/favicon.ico
156
155
  - public/img/ajax-loader-dark.gif
157
156
  - public/img/ajax-loader.gif
@@ -232,7 +231,7 @@ homepage: http://none.for.now
232
231
  licenses:
233
232
  - MIT
234
233
  metadata: {}
235
- post_install_message:
234
+ post_install_message:
236
235
  rdoc_options: []
237
236
  require_paths:
238
237
  - lib
@@ -247,9 +246,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
247
246
  - !ruby/object:Gem::Version
248
247
  version: '0'
249
248
  requirements: []
250
- rubyforge_project:
251
- rubygems_version: 2.6.8
252
- signing_key:
249
+ rubyforge_project:
250
+ rubygems_version: 2.6.11
251
+ signing_key:
253
252
  specification_version: 4
254
253
  summary: Tree based routing framework with scaffolding support
255
254
  test_files: []
@@ -1,1216 +0,0 @@
1
- # coding: utf-8
2
- module Engine2
3
- class Meta
4
- attr_reader :action, :assets, :static, :invokable
5
-
6
- class << self
7
- def meta_type mt = nil
8
- mt ? @meta_type = mt : @meta_type
9
- end
10
-
11
- def http_method hm = nil
12
- hm ? @http_method = hm : @http_method
13
- end
14
-
15
- def inherited cls
16
- cls.http_method http_method
17
- end
18
- end
19
-
20
- http_method :get
21
-
22
- def initialize action, assets, static = self
23
- @meta = {}
24
- @action = action
25
- @assets = assets
26
- @static = static
27
- end
28
-
29
- def http_method
30
- @http_method # || (raise E2Error.new("No http method for meta #{self.class}"))
31
- end
32
-
33
- def meta_type
34
- @meta_type || (raise E2Error.new("No meta_type for meta #{self.class}"))
35
- end
36
-
37
- def check_static_meta
38
- raise E2Error.new("Static meta required") if dynamic?
39
- end
40
-
41
- def define_invoke &blk
42
- check_static_meta
43
- self.class.class_eval{define_method :invoke, &blk}
44
- end
45
-
46
- def invoke! handler
47
- if rmp = @request_meta_proc
48
- meta = self.class.new(action, assets, self)
49
- meta_result = meta.instance_exec(handler, *meta.request_meta_proc_params(handler), &rmp)
50
- meta.post_process
51
- response = @requestable ? (meta_result || {}) : meta.invoke(handler)
52
- response[:meta] = meta.get
53
- response
54
- else
55
- invoke(handler)
56
- end
57
- end
58
-
59
- def repeat time
60
- @meta[:repeat] = time
61
- end
62
-
63
- def arguments args
64
- @meta[:arguments] = args
65
- end
66
-
67
- def execute time
68
- @meta[:execute] = time
69
- end
70
-
71
- def get
72
- @meta
73
- end
74
-
75
- def dynamic?
76
- self != @static
77
- end
78
-
79
- # def [] *keys
80
- # @meta.path(*keys)
81
- # end
82
-
83
- # def []= *keys, value
84
- # @meta.path!(*keys, value)
85
- # end
86
-
87
- def lookup *keys
88
- if dynamic? # we are the request meta
89
- value = @meta.path(*keys)
90
- value.nil? ? @static.get.path(*keys) : value
91
- # value || @static.value.path(keys)
92
- else
93
- @meta.path(*keys)
94
- end
95
- end
96
-
97
- def merge *keys
98
- if keys.length == 1
99
- key = keys.first
100
- dynamic? ? @static.get[key].merge(@meta[key] || {}) : @meta[key]
101
- else
102
- dynamic? ? @static.get.path(*keys).merge(@meta.path(*keys)) : @meta.path(*keys)
103
- end
104
- end
105
-
106
- def freeze_meta
107
- hash = @meta
108
- hash.freeze
109
- # hash.each_pair{|k, v| freeze(v) if v.is_a? Hash}
110
- freeze
111
- end
112
-
113
- def request_meta_proc_params handler
114
- []
115
- end
116
-
117
- def request &blk
118
- raise E2Error.new("No block given for request meta") unless blk
119
- raise E2Error.new("Request meta already supplied") if @request_meta_proc
120
- raise E2Error.new("No request block in request meta allowed") if dynamic?
121
- @request_meta_proc = blk
122
- nil
123
- end
124
-
125
- def pre_run
126
- @meta_type = self.class.meta_type
127
- @http_method = self.class.http_method
128
- end
129
-
130
- def action_defined
131
- end
132
-
133
- def post_run
134
- if respond_to? :invoke
135
- @invokable = true
136
- else
137
- if @request_meta_proc
138
- @invokable = true
139
- @requestable = true
140
- else
141
- @meta[:invokable] = false
142
- end
143
- end
144
- post_process
145
- end
146
-
147
- def post_process
148
- end
149
-
150
- def split_keys id
151
- Sequel::split_keys(id)
152
- end
153
- end
154
-
155
- class InlineMeta < Meta
156
- meta_type :inline
157
- end
158
-
159
- class RootMeta < Meta
160
- def initialize *args
161
- super
162
- @meta.merge! environment: Handler::environment, application: Engine2::SETTINGS[:name], key_separator: Engine2::SETTINGS[:key_separator]
163
- end
164
- end
165
-
166
- module MetaAPISupport
167
- def reload_routes!
168
- @meta[:reload_routes] = true
169
- end
170
-
171
- def info
172
- @meta[:info] ||= {}
173
- end
174
-
175
- def config
176
- @meta[:config] ||= {}
177
- end
178
-
179
- def info! *fields, options
180
- raise E2Error.new("No fields given to info") if fields.empty?
181
- fields.each do |field|
182
- (info[field] ||= {}).merge! options # rmerge ?
183
- end
184
- end
185
-
186
- def loc! hash
187
- (@meta[:loc] ||= {}).merge! hash
188
- end
189
-
190
- def decorate list
191
- list.each do |f|
192
- m = (info[f] ||= {})
193
- m[:loc] ||= LOCS[f]
194
- end
195
- end
196
-
197
- def render field, options
198
- info! field, render: options
199
- end
200
-
201
- def hide_fields *flds
202
- info! *flds, hidden: true
203
- end
204
-
205
- def show_fields *flds
206
- info! *flds, hidden: false
207
- end
208
-
209
- def field_filter *flds, filter
210
- info! *flds, filter: filter
211
- end
212
- end
213
-
214
- module MetaMenuSupport
215
- def menu menu_name, &blk
216
- @menus ||= {}
217
- @menus[menu_name] ||= ActionMenuBuilder.new(:root)
218
- @menus[menu_name].instance_eval(&blk) if blk
219
- @menus[menu_name]
220
- end
221
-
222
- def menu? menu_name
223
- @menus && @menus[menu_name]
224
- end
225
-
226
- def post_process
227
- super
228
- if @menus && !@menus.empty?
229
- @meta[:menus] = {}
230
- @menus.each_pair do |name, menu|
231
- @meta[:menus][name] = {entries: menu.to_a, properties: menu.properties}
232
- end
233
- end
234
- end
235
- end
236
-
237
- module MetaModelSupport
238
- def pre_run
239
- if !(mdl = @assets[:model])
240
- act = action
241
- begin
242
- act = act.parent
243
- raise E2Error.new("Model not found in tree for action: #{action.name}") unless act
244
- mdl = act.*.assets[:model]
245
- end until mdl
246
-
247
- if asc = @assets[:assoc]
248
- @assets[:model] = asc.associated_class
249
- # raise E2Error.new("Association '#{asc}' for model '#{asc[:class_name]}' not found") unless @assets[:model]
250
- else
251
- @assets[:model] = mdl
252
- asc = act.*.assets[:assoc]
253
- @assets[:assoc] = asc if asc
254
- end
255
- end
256
-
257
- # @meta[:model!] = assets[:model]
258
- # @meta[:assoc!] = assets[:assoc] ? assets[:assoc][:name] : nil
259
- # @meta[:meta_class!] = self.class
260
- super
261
- end
262
-
263
- def hide_pk
264
- hide_fields *assets[:model].primary_keys
265
- end
266
-
267
- def show_pk
268
- show_fields *assets[:model].primary_keys
269
- end
270
-
271
- def get_type_info name
272
- model = assets[:model]
273
- info = model.type_info[name]
274
- unless info
275
- if name =~ /^(\w+)__(\w+?)$/ # (?:___\w+)?
276
- assoc = model.many_to_one_associations[$1.to_sym] || model.one_to_one_associations[$1.to_sym]
277
- raise E2Error.new("Association #{$1} not found for model #{model}") unless assoc
278
- m = assoc.associated_class
279
- info = m.type_info.fetch($2.to_sym)
280
- else
281
- raise E2Error.new("Type info not found for '#{name}' in model '#{model}'")
282
- end
283
- end
284
- info
285
- end
286
-
287
- # def parent_model_name
288
- # model = @assets[:model]
289
- # prnt = action.parent
290
-
291
- # while prnt && prnt.*.assets[:model] == model
292
- # prnt = prnt.parent
293
- # end
294
- # m = prnt.*.assets[:model]
295
- # m ? m.name : nil
296
- # end
297
-
298
- def action_defined
299
- super
300
- # p_model_name = parent_model_name
301
- model = @assets[:model]
302
-
303
- mt = meta_type
304
- case mt
305
- when :list, :star_to_many_list, :star_to_many_link_list, :star_to_many_field, :star_to_many_field_link_list # :many_to_one_list
306
- model.many_to_one_associations.each do |assoc_name, assoc|
307
- unless assoc[:propagate] == false # || p_model_name == assoc[:class_name]
308
- dc = model.type_info[assoc[:keys].first][:decode]
309
- action.run_scheme :decode, model, assoc_name, dc[:search]
310
- end
311
- end
312
- end
313
-
314
- case mt
315
- when :modify, :create
316
- model.many_to_one_associations.each do |assoc_name, assoc|
317
- unless assoc[:propagate] == false # || p_model_name == assoc[:class_name]
318
- dc = model.type_info[assoc[:keys].first][:decode]
319
- action.run_scheme :decode, model, assoc_name, dc[:form]
320
- end
321
- end
322
- end
323
-
324
- case mt
325
- when :list #, :star_to_many_list, :many_to_one_list # list dropdowns
326
- divider = false
327
- model.one_to_many_associations.merge(model.many_to_many_associations).each do |assoc_name, assoc|
328
- unless assoc[:propagate] == false
329
- menu(:item_menu).divider unless divider
330
- divider ||= true
331
- menu(:item_menu).option :"#{assoc_name}!", icon: "list" # , click: "action.show_assoc($index, \"#{assoc_name}!\")"
332
- action.run_scheme :star_to_many, :"#{assoc_name}!", assoc
333
- end
334
- end
335
- end
336
-
337
- case mt
338
- when :modify, :create
339
- model.type_info.each do |field, info|
340
- case info[:type]
341
- when :blob_store
342
- action.run_scheme :blob_store, model, field
343
- when :foreign_blob_store
344
- action.run_scheme :foreign_blob_store, model, field
345
- when :file_store
346
- action.run_scheme :file_store, model, field
347
- when :star_to_many_field
348
- assoc = model.association_reflections[info[:assoc_name]] # info[:name] ?
349
- raise E2Error.new("Association '#{info[:assoc_name]}' not found for model '#{model}'") unless assoc
350
- action.run_scheme :star_to_many_field, assoc, field
351
- end
352
- end
353
- end
354
- end
355
-
356
- def unsupported_association assoc
357
- raise E2Error.new("Unsupported association: #{assoc}")
358
- end
359
- end
360
-
361
- module MetaQuerySupport
362
- def query q, &blk
363
- @query = q.naked
364
- @query.row_proc = blk if blk
365
- end
366
-
367
- def post_run
368
- query select(*assets[:model].columns) unless @query
369
- super
370
- end
371
-
372
- def get_query # move to query ?
373
- if dynamic?
374
- @query || @static.get_query
375
- else
376
- @query
377
- end
378
- end
379
-
380
- def find_record handler, id
381
- get_query[assets[:model].primary_keys_hash_qualified(split_keys(id))]
382
- end
383
-
384
- def select *args, &blk
385
- assets[:model].select(*args, &blk).ensure_primary_key.setup! (@meta[:fields] = [])
386
- end
387
- end
388
-
389
- module MetaTabSupport
390
- def select_tabs tabs, *args, &blk
391
- field_tabs tabs
392
- select *tabs.map{|name, fields|fields}.flatten, *args, &blk
393
- end
394
-
395
- def field_tabs hash
396
- @meta[:tabs] = hash.map{|k, v| {name: k, loc: LOCS[k], fields: v} }
397
- end
398
-
399
- def lazy_tab tab_name
400
- tabs = @meta[:tabs]
401
- raise E2Error.new("No tabs defined") unless tabs
402
- tab = tabs.find{|t| t[:name] == tab_name}
403
- raise E2Error.new("No tab #{tab_name} defined") unless tab
404
- tab[:lazy] = true
405
- end
406
- end
407
-
408
- module MetaAngularSupport
409
- def ng_execute expr
410
- (@meta[:execute] ||= "") << expr + ";"
411
- end
412
-
413
- def ng_record! name, value
414
- value = case value
415
- when String
416
- "'#{value}'"
417
- when nil
418
- 'null'
419
- else
420
- value
421
- end
422
-
423
- "action.record['#{name}'] = #{value}"
424
- end
425
-
426
- def ng_record name
427
- "action.record['#{name}']"
428
- end
429
-
430
- def ng_info! name, *selector, expression
431
- # expression = "'#{expression}'" if expression.is_a? String
432
- "action.meta.info['#{name}'].#{selector.join('.')} = #{expression}"
433
- end
434
-
435
- def ng_call name, *args
436
- # TODO
437
- end
438
- end
439
-
440
- module MetaPanelSupport
441
- def pre_run
442
- modal_action true
443
- super
444
- end
445
-
446
- def post_run
447
- super
448
- if @meta[:panel]
449
- panel_panel_template 'menu_m' unless panel[:panel_template] == false
450
- # modal_action false if panel[:panel_template] == false
451
- panel_class '' unless panel[:class]
452
- panel_footer true if panel[:footer] != false && menu?(:panel_menu)
453
- end
454
- end
455
-
456
- def panel
457
- @meta[:panel] ||= {}
458
- end
459
-
460
- def modal_action modal = true
461
- panel[:modal_action] = modal
462
- end
463
-
464
- def panel_template tmpl
465
- panel[:template] = tmpl
466
- end
467
-
468
- def panel_panel_template tmpl
469
- panel[:panel_template] = tmpl
470
- end
471
-
472
- def panel_class cls
473
- panel[:class] = cls
474
- end
475
-
476
- def panel_title tle
477
- panel[:title] = tle
478
- end
479
-
480
- def panel_footer ftr
481
- panel[:footer] = ftr
482
- end
483
- end
484
-
485
- class MenuMeta < Meta
486
- include MetaMenuSupport
487
- meta_type :menu
488
-
489
- def invoke handler
490
- {}
491
- end
492
- end
493
-
494
- class ConfirmMeta < Meta
495
- include MetaPanelSupport, MetaMenuSupport
496
- meta_type :confirm
497
-
498
- def message msg
499
- @meta[:message] = msg
500
- end
501
-
502
- def pre_run
503
- super
504
- panel_template 'scaffold/message'
505
- panel_title LOCS[:confirmation]
506
- panel_class 'modal-default'
507
-
508
- menu :panel_menu do
509
- option :approve, icon: "ok", loc: LOCS[:ok], disabled: 'action.action_pending()'
510
- option :cancel, icon: "remove"
511
- end
512
- end
513
-
514
- def invoke handler
515
- params = handler.request.params
516
- # params.merge({arguments: params.keys})
517
- end
518
- end
519
-
520
- module MetaOnChangeSupport
521
- def on_change field, &blk
522
- action_name = :"#{field}_on_change"
523
- act = action.define_action action_name, (blk.arity > 2 ? OnChangeGetMeta : OnChangePostMeta)
524
- act.*{request &blk}
525
-
526
- info! field, remote_onchange: action_name
527
- info! field, remote_onchange_record: :true if blk.arity > 2
528
- end
529
-
530
- class OnChangeMeta < Meta
531
- include MetaAPISupport, MetaAngularSupport
532
-
533
- def request_meta_proc_params handler
534
- if handler.request.post?
535
- json = handler.post_to_json
536
- [json[:value], json[:record]]
537
- else
538
- params = handler.request.params
539
- [params["value"], params["record"]]
540
- end
541
- end
542
-
543
- def invoke handler
544
- {}
545
- end
546
- end
547
-
548
- class OnChangeGetMeta < OnChangeMeta
549
- meta_type :on_change
550
-
551
- def request_meta_proc_params handler
552
- params = handler.request.params
553
- [params["value"], params["record"]]
554
- end
555
- end
556
-
557
- class OnChangePostMeta < OnChangeMeta
558
- http_method :post
559
- meta_type :on_change
560
-
561
- def request_meta_proc_params handler
562
- json = handler.post_to_json
563
- [json[:value], json[:record]]
564
- end
565
- end
566
- end
567
-
568
- module MetaListSupport
569
- include MetaModelSupport, MetaAPISupport, MetaTabSupport, MetaPanelSupport, MetaMenuSupport, MetaOnChangeSupport
570
- attr_reader :filters, :orders
571
-
572
- def pre_run
573
- super
574
- config.merge!(per_page: 10, use_count: false, selectable: true) # search_active: false,
575
-
576
- panel_template 'scaffold/list'
577
- panel_panel_template 'panels/menu_m' unless action.parent.*.assets[:model]
578
- search_template 'scaffold/search'
579
- panel_title "#{:list.icon} #{LOCS[assets[:model].name.to_sym]}"
580
- loc! LOCS[:list_locs]
581
- menu :menu do
582
- properties break: 2, group_class: "btn-group-xs"
583
- option :search_toggle, icon: "search", show: "action.meta.search_fields", active: "action.ui_state.search_active", button_loc: false
584
- # divider
585
- option :refresh, icon: "refresh", button_loc: false
586
- option :default_order, icon: "signal", button_loc: false
587
- divider
588
- option :debug_info, icon: "list-alt" do
589
- option :show_meta, icon: "eye-open"
590
- end
591
- end
592
-
593
- menu :item_menu do
594
- properties break: 1, group_class: "btn-group-xs"
595
- end
596
-
597
- @meta[:state] = [:query, :ui_state]
598
- end
599
-
600
- def field_tabs hash
601
- super
602
- search_template 'scaffold/search_tabs'
603
- end
604
-
605
- def select_toggle_menu
606
- m = menu :menu
607
- unless m.option_index(:select_toggle, false)
608
- m.option_after :default_order, :select_toggle, icon: "check", enabled: "action.meta.config.selectable", active: "action.selection", button_loc: false
609
- end
610
- end
611
-
612
- def post_run
613
- unless panel[:class]
614
- panel_class case @meta[:fields].size
615
- when 1..3; ''
616
- when 4..6; 'modal-large'
617
- else; 'modal-huge'
618
- end
619
- end
620
-
621
- super
622
- @meta[:primary_fields] = assets[:model].primary_keys
623
- end
624
-
625
- # def find_renderer type_info
626
- # renderer = DefaultSearchRenderers[type_info[:type]] || DefaultSearchRenderers[type_info[:otype]]
627
- # raise E2Error.new("No search renderer found for field '#{type_info[:name]}'") unless renderer
628
- # renderer.(self, type_info)
629
- # end
630
-
631
- def post_process
632
- if fields = @meta[:search_fields]
633
- fields = fields - static.get[:search_fields] if dynamic?
634
-
635
- decorate(fields)
636
- fields.each do |name|
637
- type_info = get_type_info(name)
638
-
639
- # render = info[name][:render]
640
- # if not render
641
- # info[name][:render] = find_renderer(type_info)
642
- # else
643
- # info[name][:render].merge!(find_renderer(type_info)){|key, v1, v2|v1}
644
- # end
645
-
646
- info[name][:render] ||= begin # set before :fields
647
- renderer = DefaultSearchRenderers[type_info[:type]] || DefaultSearchRenderers[type_info[:otype]]
648
- raise E2Error.new("No search renderer found for field '#{type_info[:name]}'") unless renderer
649
- renderer.(self, type_info)
650
- end
651
-
652
- proc = SearchRendererPostProcessors[type_info[:type]] || ListRendererPostProcessors[type_info[:type]] # ?
653
- proc.(self, name, type_info) if proc
654
- end
655
- end
656
-
657
- if fields = @meta[:fields]
658
- fields = fields - static.get[:fields] if dynamic?
659
-
660
- decorate(fields)
661
- fields.each do |name|
662
- type_info = get_type_info(name)
663
- proc = ListRendererPostProcessors[type_info[:type]]
664
- proc.(self, name, type_info) if proc
665
- end
666
- end
667
-
668
- super
669
- end
670
-
671
- def search_template template
672
- panel[:search_template] = template
673
- end
674
-
675
- def sortable *flds
676
- flds = @meta[:fields] if flds.empty?
677
- info! *flds, sort: true
678
- end
679
-
680
- def search_live *flds
681
- flds = @meta[:search_fields] if flds.empty?
682
- info! *flds, search_live: true
683
- end
684
-
685
- def searchable *flds
686
- @meta.delete(:tabs)
687
- @meta[:search_fields] = *flds
688
- end
689
-
690
- def searchable_tabs tabs
691
- searchable *tabs.map{|name, fields|fields}.flatten
692
- field_tabs tabs
693
- end
694
-
695
- def template
696
- SearchTemplates
697
- end
698
-
699
- def filter name, &blk
700
- (@filters ||= {})[name] = blk
701
- end
702
-
703
- def filter_case_insensitive name
704
- raise E2Error.new("Field '#{name}' needs to be a string one") unless get_type_info(name)[:otype] == :string
705
- filter(name){|query, hash, handler| query.where(name.ilike("%#{hash[name]}%")) }
706
- end
707
-
708
- def order name, &blk
709
- (@orders ||= {})[name] = blk
710
- end
711
- end
712
-
713
- module MetaApproveSupport
714
- include MetaModelSupport
715
- attr_reader :validations
716
-
717
- def self.included meta
718
- meta.http_method :post
719
- end
720
-
721
- def validate_fields *fields
722
- if fields.empty?
723
- @validate_fields
724
- else
725
- @validate_fields = assets[:model].type_info.keys & (fields + assets[:model].primary_keys).uniq
726
- end
727
- end
728
-
729
- def before_approve handler, record
730
- end
731
-
732
- def after_approve handler, record
733
- end
734
-
735
- def validate_and_approve handler, record, json
736
- static.before_approve(handler, record)
737
- record.valid?
738
- validate_record(handler, record)
739
- if record.errors.empty?
740
- static.after_approve(handler, record)
741
- true
742
- else
743
- false
744
- end
745
- end
746
-
747
- def allocate_record handler, json
748
- model = assets[:model]
749
- json_rec = json[:record]
750
- handler.permit json_rec.is_a?(Hash)
751
- val_fields = (dynamic? ? static.validate_fields : @validate_fields) || model.type_info.keys
752
- handler.permit (json_rec.keys - val_fields).empty?
753
-
754
- record = model.call(json_rec)
755
- record.validate_fields = val_fields
756
- record
757
- end
758
-
759
- def record handler, record
760
- {errors: nil}
761
- end
762
-
763
- def invoke handler
764
- json = handler.post_to_json
765
- record = allocate_record(handler, json)
766
- validate_and_approve(handler, record, json) ? static.record(handler, record) : {record!: record.to_hash, errors!: record.errors}
767
- end
768
-
769
- def validate name, &blk
770
- (@validations ||= {})[name] = blk
771
- end
772
-
773
- def validate_record handler, record
774
- @validations.each do |name, val|
775
- unless record.errors[name]
776
- result = val.(record, handler)
777
- record.errors.add(name, result) if result
778
- end
779
- end if @validations
780
- end
781
-
782
- def post_run
783
- super
784
- validate_fields *action.parent.*.get[:fields] unless validate_fields
785
- end
786
- end
787
-
788
- module MetaFormSupport
789
- include MetaModelSupport, MetaAPISupport, MetaTabSupport, MetaPanelSupport, MetaMenuSupport, MetaAngularSupport, MetaOnChangeSupport
790
-
791
- def field_template template
792
- panel[:field_template] = template
793
- end
794
-
795
- def pre_run
796
- super
797
- panel_template 'scaffold/form'
798
- field_template 'scaffold/fields'
799
- panel_class 'modal-large'
800
-
801
- menu :panel_menu do
802
- option :approve, icon: "ok", disabled: 'action.action_pending()' # text: true,
803
- option :cancel, icon: "remove" # text: true,
804
- end
805
- # modal_action false
806
- end
807
-
808
- def field_tabs hash
809
- super
810
- panel_template 'scaffold/form_tabs'
811
- end
812
-
813
- def record handler, record
814
- end
815
-
816
- def post_process
817
- if fields = @meta[:fields]
818
- fields = fields - static.get[:fields] if dynamic?
819
-
820
- decorate(fields)
821
-
822
- fields.each do |name|
823
- # type_info = model.type_info.fetch(name)
824
- type_info = get_type_info(name)
825
-
826
- info[name][:render] ||= begin
827
- renderer = DefaultFormRenderers[type_info[:type]] # .merge(default: true)
828
- raise E2Error.new("No form renderer found for field '#{type_info[:name]}' of type '#{type_info[:type]}'") unless renderer
829
- renderer.(self, type_info)
830
- end
831
-
832
- proc = FormRendererPostProcessors[type_info[:type]]
833
- proc.(self, name, type_info) if proc
834
- end
835
-
836
- assoc = assets[:assoc]
837
- if assoc && assoc[:type] == :one_to_many
838
- # fields.select{|f| assoc[:keys].include? f}.each do |key|
839
- # # hide_fields(key) if self[:info, key, :hidden] == nil
840
- # info! key, disabled: true
841
- # end
842
- assoc[:keys].each do |key|
843
- info! key, disabled: true if fields.include? key
844
- end
845
- end
846
- end
847
-
848
- super
849
- end
850
-
851
- def post_run
852
- super
853
- @meta[:primary_fields] = assets[:model].primary_keys
854
- end
855
-
856
- def template
857
- Templates
858
- end
859
-
860
- def hr_after field, message = '-'
861
- info! field, hr: message
862
- end
863
- end
864
-
865
- module MetaCreateSupport
866
- include MetaFormSupport
867
-
868
- def self.included meta
869
- meta.meta_type :create
870
- end
871
-
872
- def pre_run
873
- super
874
- panel_title LOCS[:create_title]
875
- action.parent.*.menu(:menu).option_at 0, action.name, icon: "plus-sign", button_loc: false
876
-
877
- hide_pk unless assets[:model].natural_key
878
- end
879
-
880
- def record handler, record
881
- create_record(handler, record)
882
- end
883
-
884
- def create_record handler, record
885
- end
886
-
887
- def invoke handler
888
- record = {}
889
- if assoc = assets[:assoc]
890
- case assoc[:type]
891
- when :one_to_many
892
- handler.permit parent = handler.params[:parent_id]
893
- assoc[:keys].zip(split_keys(parent)).each{|key, val| record[key] = val}
894
- end
895
- end
896
- static.record(handler, record)
897
- {record: record, new: true}
898
- end
899
- end
900
-
901
- module MetaModifySupport
902
- include MetaFormSupport
903
-
904
- def self.included meta
905
- meta.meta_type :modify
906
- end
907
-
908
- def pre_run
909
- super
910
- panel_title LOCS[:modify_title]
911
- action.parent.*.menu(:item_menu).option action.name, icon: "pencil", button_loc: false
912
- end
913
-
914
- def record handler, record
915
- modify_record(handler, record)
916
- end
917
-
918
- def modify_record handler, record
919
- end
920
-
921
- def invoke handler
922
- handler.permit id = handler.params[:id]
923
- record = find_record(handler, id)
924
-
925
- if record
926
- static.record(handler, record)
927
- {record: record}
928
- else
929
- handler.halt_not_found LOCS[:no_entry]
930
- end
931
- end
932
-
933
- def post_run
934
- super
935
- assets[:model].primary_keys.each do |key| # pre_run ?
936
- info! key, disabled: true
937
- end
938
- end
939
- end
940
-
941
- module MetaViewSupport
942
- include MetaModelSupport, MetaAPISupport, MetaTabSupport, MetaPanelSupport, MetaMenuSupport
943
-
944
- def self.included meta
945
- meta.meta_type :view
946
- end
947
-
948
- def pre_run
949
- super
950
- panel_template 'scaffold/view'
951
- panel_title LOCS[:view_title]
952
- panel[:backdrop] = true
953
-
954
- menu(:panel_menu).option :cancel, icon: "remove"
955
- action.parent.*.menu(:item_menu).option action.name, icon: "file", button_loc: false
956
- end
957
-
958
- def field_tabs hash
959
- super
960
- panel_template 'scaffold/view_tabs'
961
- end
962
-
963
- def record handler, record
964
- end
965
-
966
- def invoke handler
967
- handler.permit id = handler.params[:id]
968
- record = find_record(handler, id)
969
- if record
970
- static.record(handler, record)
971
- {record: record}
972
- else
973
- handler.halt_not_found LOCS[:no_entry]
974
- end
975
- end
976
-
977
- def post_process
978
- if fields = @meta[:fields]
979
- fields = fields - static.get[:fields] if dynamic?
980
-
981
- decorate(fields)
982
- fields.each do |name|
983
- type_info = get_type_info(name)
984
- proc = ListRendererPostProcessors[type_info[:type]]
985
- proc.(self, name, type_info) if proc
986
- end
987
- end
988
-
989
- super
990
- end
991
- end
992
-
993
- module MetaDeleteSupport
994
- include MetaModelSupport
995
-
996
- def self.included meta
997
- meta.http_method :delete
998
- meta.meta_type :delete
999
- end
1000
-
1001
- def pre_run
1002
- super
1003
- action.parent.parent.*.menu(:item_menu).option :confirm_delete, icon: "trash", show: "action.selected_size() == 0", button_loc: false
1004
- end
1005
- end
1006
-
1007
- module MetaBulkDeleteSupport
1008
- include MetaModelSupport
1009
-
1010
- def self.included meta
1011
- meta.http_method :delete
1012
- meta.meta_type :bulk_delete
1013
- end
1014
-
1015
- def pre_run
1016
- super
1017
- action.parent.parent.*.select_toggle_menu
1018
- action.parent.parent.*.menu(:menu).option_after :default_order, :confirm_bulk_delete, icon: "trash", show: "action.selected_size() > 0"
1019
- end
1020
- end
1021
-
1022
- (FormRendererPostProcessors ||= {}).merge!(
1023
- boolean: lambda{|meta, field, info|
1024
- meta.info[field][:render].merge! true_value: info[:true_value], false_value: info[:false_value]
1025
- meta.info[field][:dont_strip] = info[:dont_strip] if info[:dont_strip]
1026
- },
1027
- date: lambda{|meta, field, info|
1028
- meta.info[field][:render].merge! format: info[:format], model_format: info[:model_format]
1029
- if date_to = info[:other_date]
1030
- meta.info[field][:render].merge! other_date: date_to #, format: info[:format], model_format: info[:model_format]
1031
- meta.hide_fields date_to
1032
- elsif time = info[:other_time]
1033
- meta.info[field][:render].merge! other_time: time
1034
- meta.hide_fields time
1035
- end
1036
- },
1037
- time: lambda{|meta, field, info|
1038
- meta.info[field][:render].merge! format: info[:format], model_format: info[:model_format]
1039
- },
1040
- decimal_date: lambda{|meta, field, info|
1041
- FormRendererPostProcessors[:date].(meta, field, info)
1042
- meta.info! field, type: :decimal_date
1043
- },
1044
- decimal_time: lambda{|meta, field, info|
1045
- FormRendererPostProcessors[:time].(meta, field, info)
1046
- meta.info! field, type: :decimal_time
1047
- },
1048
- datetime: lambda{|meta, field, info|
1049
- meta.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]
1050
- },
1051
- currency: lambda{|meta, field, info|
1052
- meta.info[field][:render].merge! symbol: info[:symbol]
1053
- },
1054
- # date_range: lambda{|meta, field, info|
1055
- # meta.info[field][:render].merge! other_date: info[:other_date], format: info[:format], model_format: info[:model_format]
1056
- # meta.hide_fields info[:other_date]
1057
- # meta.info[field][:decimal_date] = true if info[:validations][:decimal_date]
1058
- # },
1059
- list_select: lambda{|meta, field, info|
1060
- meta.info[field][:render].merge! list: info[:list]
1061
- },
1062
- many_to_one: lambda{|meta, field, info|
1063
- field_info = meta.info[field]
1064
- field_info[:assoc] = :"#{info[:assoc_name]}!"
1065
- field_info[:fields] = info[:keys]
1066
- field_info[:type] = info[:otype]
1067
-
1068
- (info[:keys] - [field]).each do |of|
1069
- f_info = meta.info.fetch(of)
1070
- f_info[:hidden] = true
1071
- f_info[:type] = meta.assets[:model].type_info[of].fetch(:otype)
1072
- end
1073
- },
1074
- file_store: lambda{|meta, field, info|
1075
- meta.info[field][:render].merge! multiple: info[:multiple]
1076
- },
1077
- star_to_many_field: lambda{|meta, field, info|
1078
- field_info = meta.info[field]
1079
- field_info[:assoc] = :"#{info[:assoc_name]}!"
1080
- }
1081
- )
1082
-
1083
- (ListRendererPostProcessors ||= {}).merge!(
1084
- boolean: lambda{|meta, field, info|
1085
- meta.info! field, type: :boolean # move to meta ?
1086
- meta.info[field][:render] ||= {}
1087
- meta.info[field][:render].merge! true_value: info[:true_value], false_value: info[:false_value]
1088
- },
1089
- list_select: lambda{|meta, field, info|
1090
- meta.info! field, type: :list_select
1091
- meta.info[field][:render] ||= {}
1092
- meta.info[field][:render].merge! list: info[:list]
1093
- },
1094
- datetime: lambda{|meta, field, info|
1095
- meta.info! field, type: :datetime
1096
- },
1097
- decimal_date: lambda{|meta, field, info|
1098
- meta.info! field, type: :decimal_date
1099
- },
1100
- decimal_time: lambda{|meta, field, info|
1101
- meta.info! field, type: :decimal_time
1102
- },
1103
- # date_range: lambda{|meta, field, info|
1104
- # meta.info[field][:type] = :decimal_date if info[:validations][:decimal_date] # ? :decimal_date : :date
1105
- # }
1106
- )
1107
-
1108
- (SearchRendererPostProcessors ||= {}).merge!(
1109
- many_to_one: lambda{|meta, field, info|
1110
- model = meta.assets[:model]
1111
- if model.type_info[field]
1112
- keys = info[:keys]
1113
- else
1114
- meta.check_static_meta
1115
- model = model.many_to_one_associations[field[/^\w+?(?=__)/].to_sym].associated_class
1116
- keys = info[:keys].map{|k| :"#{model.table_name}__#{k}"}
1117
- end
1118
-
1119
- field_info = meta.info[field]
1120
- field_info[:assoc] = :"#{info[:assoc_name]}!"
1121
- field_info[:fields] = keys
1122
- field_info[:type] = info[:otype]
1123
-
1124
- (keys - [field]).each do |of|
1125
- f_info = meta.info[of]
1126
- raise E2Error.new("Missing searchable field: '#{of}' in model '#{meta.assets[:model]}'") unless f_info
1127
- f_info[:hidden_search] = true
1128
- f_info[:type] = model.type_info[of].fetch(:otype)
1129
- end
1130
- },
1131
- date: lambda{|meta, field, info|
1132
- meta.info[field][:render] ||= {}
1133
- meta.info[field][:render].merge! format: info[:format], model_format: info[:model_format] # Model::DEFAULT_DATE_FORMAT
1134
- },
1135
- decimal_date: lambda{|meta, field, info|
1136
- SearchRendererPostProcessors[:date].(meta, field, info)
1137
- }
1138
- )
1139
-
1140
- (DefaultFormRenderers ||= {}).merge!(
1141
- date: lambda{|meta, info|
1142
- info[:other_date] ? Templates.date_range : (info[:other_time] ? Templates.date_time : Templates.date_picker)
1143
-
1144
- },
1145
- time: lambda{|meta, info| Templates.time_picker},
1146
- datetime: lambda{|meta, info| Templates.datetime_picker},
1147
- file_store: lambda{|meta, info| Templates.file_store},
1148
- blob: lambda{|meta, info| Templates.blob}, # !!!
1149
- blob_store: lambda{|meta, info| Templates.blob},
1150
- foreign_blob_store: lambda{|meta, info| Templates.blob},
1151
- string: lambda{|meta, info| Templates.input_text(info[:length])},
1152
- text: lambda{|meta, info| Templates.text},
1153
- integer: lambda{|meta, info| Templates.integer},
1154
- decimal: lambda{|meta, info| Templates.decimal},
1155
- decimal_date: lambda{|meta, info| DefaultFormRenderers[:date].(meta, info)},
1156
- decimal_time: lambda{|meta, info| Templates.time_picker},
1157
- email: lambda{|meta, info| Templates.email(info[:length])},
1158
- password: lambda{|meta, info| Templates.password(info[:length])},
1159
- # date_range: lambda{|meta, info| Templates.date_range},
1160
- boolean: lambda{|meta, info| Templates.checkbox_buttons(optional: !info[:required])},
1161
- currency: lambda{|meta, info| Templates.currency},
1162
- list_select: lambda{|meta, info|
1163
- length = info[:list].length
1164
- if length <= 3
1165
- Templates.list_buttons(optional: !info[:required])
1166
- elsif length <= 15
1167
- max_length = info[:list].max_by{|a|a.last.length}.last.length
1168
- Templates.list_bsselect(max_length, optional: !info[:required])
1169
- else
1170
- max_length = info[:list].max_by{|a|a.last.length}.last.length
1171
- Templates.list_select(max_length, optional: !info[:required])
1172
- end
1173
- },
1174
- star_to_many_field: lambda{|meta, info| Templates.scaffold},
1175
- many_to_one: lambda{|meta, info|
1176
- tmpl_type = info[:decode][:form]
1177
- case
1178
- when tmpl_type[:scaffold]; Templates.scaffold_picker
1179
- when tmpl_type[:list]; Templates.bsselect_picker
1180
- when tmpl_type[:typeahead];Templates.typeahead_picker
1181
- else
1182
- raise E2Error.new("Unknown decode type #{tmpl_type}")
1183
- end
1184
- }, # required/opt
1185
- )
1186
-
1187
- (DefaultSearchRenderers ||= {}).merge!(
1188
- date: lambda{|meta, info| SearchTemplates.date_range},
1189
- decimal_date: lambda{|meta, info| SearchTemplates.date_range},
1190
- integer: lambda{|meta, info| SearchTemplates.integer_range},
1191
- string: lambda{|meta, info| SearchTemplates.input_text},
1192
- boolean: lambda{|meta, info| SearchTemplates.checkbox_buttons},
1193
- list_select: lambda{|meta, info|
1194
- length = info[:list].length
1195
- if length <= 3
1196
- SearchTemplates.list_buttons
1197
- elsif length <= 15
1198
- # max_length = info[:list].max_by{|a|a.last.length}.last.length
1199
- SearchTemplates.list_bsselect(multiple: info[:multiple])
1200
- else
1201
- # max_length = info[:list].max_by{|a|a.last.length}.last.length
1202
- SearchTemplates.list_select
1203
- end
1204
- },
1205
- many_to_one: lambda{|meta, info|
1206
- tmpl_type = info[:decode][:search]
1207
- case
1208
- when tmpl_type[:scaffold]; SearchTemplates.scaffold_picker(multiple: tmpl_type[:multiple])
1209
- when tmpl_type[:list]; SearchTemplates.bsselect_picker(multiple: tmpl_type[:multiple])
1210
- when tmpl_type[:typeahead];SearchTemplates.typeahead_picker
1211
- else
1212
- raise E2Error.new("Unknown decode type #{tmpl_type}")
1213
- end
1214
- }
1215
- )
1216
- end