engine2 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +3 -117
  3. data/{views → app}/app.coffee +0 -0
  4. data/{public/css → app}/app.css +203 -196
  5. data/{views → app}/engine2.coffee +111 -60
  6. data/{views → app}/engine2actions.coffee +47 -28
  7. data/bower.json +13 -0
  8. data/conf/message.yaml +2 -1
  9. data/conf/message_pl.yaml +2 -1
  10. data/config.coffee +62 -0
  11. data/engine2.gemspec +2 -5
  12. data/lib/engine2.rb +1 -1
  13. data/lib/engine2/action.rb +9 -24
  14. data/lib/engine2/core.rb +9 -8
  15. data/lib/engine2/handler.rb +1 -5
  16. data/lib/engine2/meta.rb +61 -24
  17. data/lib/engine2/meta/array_meta.rb +82 -0
  18. data/lib/engine2/meta/decode_meta.rb +1 -1
  19. data/lib/engine2/meta/infra_meta.rb +21 -26
  20. data/lib/engine2/meta/list_meta.rb +2 -3
  21. data/lib/engine2/model.rb +5 -5
  22. data/lib/engine2/pre_bootstrap.rb +9 -1
  23. data/lib/engine2/scheme.rb +4 -0
  24. data/lib/engine2/type_info.rb +8 -1
  25. data/lib/engine2/version.rb +1 -1
  26. data/package.json +38 -0
  27. data/public/img/ajax-loader.gif +0 -0
  28. data/views/fields/blob.slim +4 -5
  29. data/views/fields/bs_select.slim +2 -2
  30. data/views/fields/bsselect_picker.slim +1 -2
  31. data/views/fields/bsselect_picker_opt.slim +1 -2
  32. data/views/fields/checkbox.slim +1 -1
  33. data/views/fields/checkbox_buttons.slim +1 -1
  34. data/views/fields/checkbox_buttons_opt.slim +1 -1
  35. data/views/fields/currency.slim +2 -2
  36. data/views/fields/date.slim +0 -1
  37. data/views/fields/date_range.slim +0 -1
  38. data/views/fields/date_time.slim +0 -1
  39. data/views/fields/datetime.slim +0 -2
  40. data/views/fields/decimal.slim +0 -1
  41. data/views/fields/decimal_date.slim +0 -1
  42. data/views/fields/decimal_time.slim +0 -1
  43. data/views/fields/email.slim +1 -2
  44. data/views/fields/file_store.slim +1 -1
  45. data/views/fields/input_text.slim +1 -2
  46. data/views/fields/integer.slim +1 -1
  47. data/views/fields/list_bsselect.slim +1 -2
  48. data/views/fields/list_bsselect_opt.slim +2 -3
  49. data/views/fields/list_buttons.slim +1 -1
  50. data/views/fields/list_buttons_opt.slim +1 -1
  51. data/views/fields/list_select.slim +1 -2
  52. data/views/fields/list_select_opt.slim +2 -3
  53. data/views/fields/password.slim +1 -2
  54. data/views/fields/radio_checkbox.slim +1 -1
  55. data/views/fields/scaffold.slim +1 -1
  56. data/views/fields/scaffold_picker.slim +1 -2
  57. data/views/fields/select_picker.slim +1 -2
  58. data/views/fields/select_picker_opt.slim +1 -2
  59. data/views/fields/text_area.slim +0 -1
  60. data/views/fields/time.slim +0 -1
  61. data/views/fields/typeahead_picker.slim +1 -2
  62. data/views/index.slim +4 -8
  63. data/views/scaffold/fields.slim +4 -4
  64. data/views/scaffold/form.slim +1 -7
  65. data/views/scaffold/form_collapse.slim +19 -0
  66. data/views/scaffold/form_tabs.slim +9 -0
  67. data/views/scaffold/list.slim +1 -12
  68. data/views/scaffold/search.slim +2 -9
  69. data/views/scaffold/search_collapse.slim +26 -0
  70. data/views/scaffold/search_tabs.slim +15 -0
  71. data/views/scaffold/view.slim +5 -15
  72. data/views/scaffold/view_collapse.slim +22 -0
  73. data/views/scaffold/view_tabs.slim +11 -0
  74. data/views/search_fields/bsmselect_picker.slim +1 -2
  75. data/views/search_fields/bsselect_picker.slim +1 -2
  76. data/views/search_fields/checkbox.slim +3 -3
  77. data/views/search_fields/checkbox2.slim +5 -5
  78. data/views/search_fields/checkbox_buttons.slim +2 -2
  79. data/views/search_fields/date_range.slim +0 -2
  80. data/views/search_fields/decimal_date_range.slim +5 -5
  81. data/views/search_fields/input_text.slim +2 -2
  82. data/views/search_fields/integer.slim +1 -1
  83. data/views/search_fields/integer_range.slim +2 -2
  84. data/views/search_fields/list_bsmselect.slim +1 -1
  85. data/views/search_fields/list_bsselect.slim +0 -1
  86. data/views/search_fields/list_buttons.slim +2 -2
  87. data/views/search_fields/list_select.slim +1 -2
  88. data/views/search_fields/scaffold_picker.slim +1 -2
  89. data/views/search_fields/select_picker.slim +1 -2
  90. data/views/search_fields/typeahead_picker.slim +1 -2
  91. metadata +29 -103
  92. data/public/assets/javascripts.js +0 -13
  93. data/public/assets/styles.css +0 -4
  94. data/public/css/angular-motion.css +0 -1022
  95. data/public/css/angular-ui-tree.min.css +0 -1
  96. data/public/css/bootstrap-additions.css +0 -1560
  97. data/public/css/bootstrap.min.css +0 -11
  98. data/public/css/font-awesome.min.css +0 -4
  99. data/public/fonts/FontAwesome.otf +0 -0
  100. data/public/fonts/fontawesome-webfont.eot +0 -0
  101. data/public/fonts/fontawesome-webfont.svg +0 -655
  102. data/public/fonts/fontawesome-webfont.ttf +0 -0
  103. data/public/fonts/fontawesome-webfont.woff +0 -0
  104. data/public/fonts/fontawesome-webfont.woff2 +0 -0
  105. data/public/fonts/glyphicons-halflings-regular.eot +0 -0
  106. data/public/fonts/glyphicons-halflings-regular.svg +0 -288
  107. data/public/fonts/glyphicons-halflings-regular.ttf +0 -0
  108. data/public/fonts/glyphicons-halflings-regular.woff +0 -0
  109. data/public/fonts/glyphicons-halflings-regular.woff2 +0 -0
  110. data/public/images/file.png +0 -0
  111. data/public/images/folder-closed.png +0 -0
  112. data/public/images/folder.png +0 -0
  113. data/public/images/node-closed-2.png +0 -0
  114. data/public/images/node-closed-light.png +0 -0
  115. data/public/images/node-closed.png +0 -0
  116. data/public/images/node-opened-2.png +0 -0
  117. data/public/images/node-opened-light.png +0 -0
  118. data/public/images/node-opened.png +0 -0
  119. data/public/img/ajax-loader-light.gif +0 -0
  120. data/public/js/angular-animate.js +0 -4147
  121. data/public/js/angular-cookies.js +0 -322
  122. data/public/js/angular-local-storage.js +0 -455
  123. data/public/js/angular-route.js +0 -1025
  124. data/public/js/angular-sanitize.js +0 -717
  125. data/public/js/angular-strap.js +0 -4339
  126. data/public/js/angular-strap.tpl.js +0 -43
  127. data/public/js/angular-ui-tree.js +0 -1569
  128. data/public/js/angular.js +0 -30868
  129. data/public/js/i18n/angular-locale_pl.js +0 -115
  130. data/public/js/lodash.custom.min.js +0 -99
  131. data/public/js/ng-file-upload-shim.min.js +0 -2
  132. data/public/js/ng-file-upload.min.js +0 -3
  133. data/views/engine2templates.coffee +0 -0
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "engine2",
3
+ "version": "1.0.0",
4
+ "dependencies": {
5
+ "angular-strap": "^2.3.10",
6
+ "angular": "^1.5.8"
7
+ },
8
+ "overrides": {
9
+ "angular": {
10
+ "main": []
11
+ }
12
+ }
13
+ }
@@ -1,4 +1,3 @@
1
- :engine2_resource_loaded: true
2
1
  :default_date_format: yyyy-MM-dd
3
2
  :default_date_short_format: yy-MM-dd
4
3
  :default_date_model_format: yyyy-MM-dd
@@ -88,6 +87,8 @@
88
87
  :invalid_email_format: Incorrect email format
89
88
  :invalid_format: Incorrect format
90
89
 
90
+ :currency_symbol: $
91
+
91
92
  :access_forbidden: Access forbidden
92
93
  :access_unauthorized: Access unauthorized
93
94
  :access_not_found: Not found
@@ -1,4 +1,3 @@
1
- :engine2_resource_loaded: true
2
1
  :default_date_format: yyyy-MM-dd
3
2
  :default_date_short_format: yy-MM-dd
4
3
  :default_date_model_format: yyyy-MM-dd
@@ -93,6 +92,8 @@
93
92
  :access_not_found: Nie znaleziono
94
93
  :access_method_not_allowed: Metoda niedozwolona
95
94
 
95
+ :currency_symbol: zł
96
+
96
97
  :list_locs:
97
98
  :search: Szukaj
98
99
  :page: Strona
@@ -0,0 +1,62 @@
1
+ exports.config =
2
+ npm:
3
+ enabled: true
4
+ globals:
5
+ _: 'lodash'
6
+ angular: 'angular'
7
+ styles:
8
+ "bootstrap": ["dist/css/bootstrap.css"]
9
+ "bootstrap-additions": ["dist/bootstrap-additions.css"]
10
+ "angular-motion": ["dist/angular-motion.css"]
11
+ "angular-ui-tree": ["dist/angular-ui-tree.css"]
12
+ "font-awesome": ["css/font-awesome.css"]
13
+
14
+ modules:
15
+ definition: 'commonjs'
16
+ wrapper: false
17
+
18
+ paths:
19
+ public: 'public'
20
+ watched: ['app']
21
+
22
+ files:
23
+ javascripts:
24
+ joinTo:
25
+ 'engine2vendor.js': /^node_modules|bower_components/
26
+ 'engine2.js': /^app/
27
+
28
+ stylesheets:
29
+ joinTo:
30
+ 'engine2vendor.css': /^node_modules/
31
+ 'engine2app.css': /^app/
32
+ order:
33
+ before: [
34
+ /bootstrap.css$/
35
+ ]
36
+
37
+ plugins:
38
+ on: ["ng-annotate-brunch"]
39
+
40
+ uglify:
41
+ mangle: true
42
+ compress:
43
+ global_defs:
44
+ DEBUG: false
45
+
46
+ replacement:
47
+ replacements: [
48
+ files: [/vendor.js$/]
49
+ match: (
50
+ fix = "$modal.$element = compileData.link(modalScope, function(clonedElement, scope) {});"
51
+ find: fix.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1")
52
+ replace: "#{fix}$modal.$backdrop = backdropElement;"
53
+ )
54
+ ]
55
+
56
+ copycat:
57
+ fonts: [
58
+ "node_modules/font-awesome/fonts"
59
+ "node_modules/bootstrap/fonts"
60
+ ]
61
+ verbose: true
62
+ onlyChanged: true
@@ -17,6 +17,7 @@ Gem::Specification.new do |spec|
17
17
  spec.require_paths = ["lib"]
18
18
 
19
19
  spec.add_dependency "sequel", '~> 4'
20
+ spec.add_dependency "rack-contrib", '~> 1.4'
20
21
  if defined? JRUBY_VERSION
21
22
  spec.add_dependency 'jdbc-sqlite3', '~> 3.8'
22
23
  else
@@ -24,11 +25,7 @@ Gem::Specification.new do |spec|
24
25
  end
25
26
  spec.add_dependency "sinatra", '~> 1.4'
26
27
  spec.add_dependency 'slim', '~> 3.0'
27
- spec.add_dependency "execjs", '~> 2.6'
28
- spec.add_dependency 'coffee-script', '~> 2.4'
29
28
 
30
29
  spec.add_development_dependency "bundler", "~> 1.11"
31
- spec.add_development_dependency "rake", "~> 11.1"
32
- spec.add_development_dependency 'uglifier', '~> 3.0'
33
- spec.add_development_dependency 'yui-compressor', '~> 0.12'
30
+ spec.add_development_dependency "rake", "~> 11"
34
31
  end
@@ -6,7 +6,6 @@ require 'sequel'
6
6
  require 'sinatra'
7
7
  require 'json'
8
8
  require 'slim'
9
- require 'tilt/coffee'
10
9
  require 'engine2/version'
11
10
 
12
11
  %w[
@@ -19,6 +18,7 @@ require 'engine2/version'
19
18
  action.rb
20
19
  scheme.rb
21
20
 
21
+ meta/array_meta.rb
22
22
  meta/list_meta.rb
23
23
  meta/view_meta.rb
24
24
  meta/form_meta.rb
@@ -9,6 +9,10 @@ module Engine2
9
9
 
10
10
  class << self
11
11
  attr_accessor :count
12
+
13
+ def default_meta
14
+ Class.new(InlineMeta){meta_type :inline}
15
+ end
12
16
  end
13
17
 
14
18
  def initialize parent, name, meta_class, assets
@@ -46,7 +50,7 @@ module Engine2
46
50
  result
47
51
  end
48
52
 
49
- def define_action name, meta_class = DummyMeta, assets = {}, &blk
53
+ def define_action name, meta_class = Action.default_meta, assets = {}, &blk
50
54
  ::Kernel.raise E2Error.new("Action #{name} already defined") if @actions[name]
51
55
  action = @actions[name] = Action.new(self, name, meta_class, assets)
52
56
  action.*.pre_run
@@ -59,15 +63,15 @@ module Engine2
59
63
  action
60
64
  end
61
65
 
62
- def define_action_meta name, meta_class = DummyMeta, assets = {}, &blk
66
+ def define_action_meta name, meta_class = Action.default_meta, assets = {}, &blk
63
67
  define_action name, meta_class, assets do
64
68
  self.* &blk
65
69
  end
66
70
  end
67
71
 
68
- def define_action_invoke name, meta_class = DummyMeta, assets = {}, &blk
72
+ def define_action_invoke name, meta_class = Action.default_meta, assets = {}, &blk
69
73
  define_action name, meta_class, assets do
70
- self.*.define_singleton_method(:invoke, &blk)
74
+ self.*.define_invoke &blk
71
75
  end
72
76
  end
73
77
 
@@ -101,8 +105,7 @@ module Engine2
101
105
  access: recheck_access ? nil : a.check_access!(handler),
102
106
  recheck_access: a.recheck_access,
103
107
  terminal: a.actions.empty?,
104
- meta: !meta.get.empty?,
105
- invokable: meta.invokable
108
+ meta: !meta.get.empty?
106
109
  }
107
110
  h
108
111
  end
@@ -189,24 +192,6 @@ module Engine2
189
192
  end
190
193
 
191
194
  ::Kernel::puts "ACTIONS: #{Action.count}, Time: #{::Time.now - time}"
192
- # verify_action_usage
193
- end
194
-
195
- def verify_action_usage
196
- t = ::Time.now
197
- each_action do |action|
198
- meta = action.*
199
- model = meta.assets[:model]
200
- if model
201
- model.one_to_many_associations.each do |a|
202
- end
203
- true
204
- else
205
- true
206
- end
207
-
208
- end
209
- ::Kernel::puts "VERIFY #{::Time.now - t}"
210
195
  end
211
196
 
212
197
  def p *args
@@ -123,7 +123,7 @@ class << Sequel
123
123
  attr_accessor :alias_columns_in_joins
124
124
 
125
125
  def split_keys id
126
- id.split('|')
126
+ id.split(Engine2::SETTINGS[:key_separator])
127
127
  end
128
128
  end
129
129
 
@@ -336,7 +336,7 @@ module E2Model
336
336
  else
337
337
  a = model.many_to_one_associations[table] # || model.one_to_one_associations[table]
338
338
  raise Engine2::E2Error.new("Association #{table} not found for model #{model}") unless a
339
- m = Object.const_get(a[:class_name])
339
+ m = a.associated_class
340
340
  end
341
341
  # raise Engine2::E2Error.new("Model not found for table #{table} in model #{model}") unless m
342
342
  info = m.type_info
@@ -379,7 +379,7 @@ module E2Model
379
379
  @opts[:select].compact!
380
380
 
381
381
  joins.reduce(self) do |joined, (table, assoc)|
382
- m = Object.const_get(assoc[:class_name])
382
+ m = assoc.associated_class
383
383
  keys = assoc[:qualified_key]
384
384
  joined.left_join(table, m.primary_keys.zip(keys.is_a?(Array) ? keys : [keys]))
385
385
  end
@@ -395,7 +395,7 @@ module E2Model
395
395
  end
396
396
  when Sequel::SQL::QualifiedIdentifier
397
397
  yield sel.table, sel.column, al
398
- when Sequel::SQL::AliasedExpression
398
+ when Sequel::SQL::AliasedExpression, Sequel::SQL::Function
399
399
  sel
400
400
  # extract_select sel.expression, sel.aliaz, &blk
401
401
  # expr = sel.expression
@@ -433,9 +433,10 @@ end
433
433
  module Engine2
434
434
  LOCS ||= Hash.new{|h, k| ":#{k}:"}
435
435
  PATH ||= File.expand_path('../..', File.dirname(__FILE__))
436
+ SETTINGS ||= {key_separator: '|'}
436
437
 
437
438
  class << self
438
- attr_reader :app, :app_name, :reloading
439
+ attr_reader :app
439
440
  attr_reader :core_loaded
440
441
 
441
442
  def database name
@@ -490,10 +491,10 @@ module Engine2
490
491
  puts "BOOTSTRAP #{app}, Time: #{Time.new - t}"
491
492
  end
492
493
 
493
- def bootstrap app, opts = {}
494
+ def bootstrap app, settings = {}
494
495
  @app = app
495
- @app_name = opts[:name] || File::basename(app)
496
- @reloading = opts[:reloading]
496
+ SETTINGS.merge! settings
497
+ SETTINGS[:name] ||= File::basename(app)
497
498
  bootstrap_e2db
498
499
 
499
500
  require 'engine2/pre_bootstrap'
@@ -106,15 +106,11 @@ module Engine2
106
106
  halt_server_error Rack::Utils.escape_html(error.inspect) + "<hr>" + error.backtrace.take(30).map{|b| Rack::Utils.escape_html(b)}.join("<br>"), LOCS[:error]
107
107
  end
108
108
 
109
- get "/js/*.js" do |c|
110
- coffee c.to_sym
111
- end
112
-
113
109
  get '/*' do |name|
114
110
  headers 'Cache-Control' => 'no-cache, no-store, must-revalidate', 'Pragma' => 'no-cache', 'Expires' => '0'
115
111
  if name.empty?
116
112
  if settings.development?
117
- load('engine2.rb') if Engine2::reloading
113
+ load('engine2.rb') if Engine2::SETTINGS[:reloading]
118
114
  Engine2::reload
119
115
  end
120
116
  name = 'index'
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
  module Engine2
3
3
  class Meta
4
- attr_reader :action, :assets, :invokable, :static
4
+ attr_reader :action, :assets, :static, :invokable
5
5
 
6
6
  class << self
7
7
  def meta_type mt = nil
@@ -38,12 +38,17 @@ module Engine2
38
38
  raise E2Error.new("Static meta required") if dynamic?
39
39
  end
40
40
 
41
+ def define_invoke &blk
42
+ check_static_meta
43
+ self.class.class_eval{define_method :invoke, &blk}
44
+ end
45
+
41
46
  def invoke! handler
42
47
  if rmp = @request_meta_proc
43
48
  meta = self.class.new(action, assets, self)
44
- meta.instance_exec(handler, *meta.request_meta_proc_params(handler), &rmp)
49
+ meta_result = meta.instance_exec(handler, *meta.request_meta_proc_params(handler), &rmp)
45
50
  meta.post_process
46
- response = meta.invoke(handler)
51
+ response = @requestable ? (meta_result || {}) : meta.invoke(handler)
47
52
  response[:meta] = meta.get
48
53
  response
49
54
  else
@@ -51,6 +56,18 @@ module Engine2
51
56
  end
52
57
  end
53
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
+
54
71
  def get
55
72
  @meta
56
73
  end
@@ -114,7 +131,16 @@ module Engine2
114
131
  end
115
132
 
116
133
  def post_run
117
- @invokable = respond_to?(:invoke)
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
118
144
  post_process
119
145
  end
120
146
 
@@ -126,15 +152,14 @@ module Engine2
126
152
  end
127
153
  end
128
154
 
129
- class DummyMeta < Meta
130
- meta_type :dummy
155
+ class InlineMeta < Meta
156
+ meta_type :inline
131
157
  end
132
158
 
133
159
  class RootMeta < Meta
134
160
  def initialize *args
135
161
  super
136
- @meta[:environment] = Handler::environment
137
- @meta[:application] = Engine2::app_name
162
+ @meta.merge! environment: Handler::environment, application: Engine2::SETTINGS[:name], key_separator: Engine2::SETTINGS[:key_separator]
138
163
  end
139
164
  end
140
165
 
@@ -220,7 +245,7 @@ module Engine2
220
245
  end until mdl
221
246
 
222
247
  if asc = @assets[:assoc]
223
- @assets[:model] = Object.const_get(asc[:class_name])
248
+ @assets[:model] = asc.associated_class
224
249
  # raise E2Error.new("Association '#{asc}' for model '#{asc[:class_name]}' not found") unless @assets[:model]
225
250
  else
226
251
  @assets[:model] = mdl
@@ -250,7 +275,7 @@ module Engine2
250
275
  if name =~ /^(\w+)__(\w+?)$/ # (?:___\w+)?
251
276
  assoc = model.many_to_one_associations[$1.to_sym] || model.one_to_one_associations[$1.to_sym]
252
277
  raise E2Error.new("Association #{$1} not found for model #{model}") unless assoc
253
- m = Object.const_get(assoc[:class_name])
278
+ m = assoc.associated_class
254
279
  info = m.type_info.fetch($2.to_sym)
255
280
  else
256
281
  raise E2Error.new("Type info not found for '#{name}' in model '#{model}'")
@@ -546,7 +571,7 @@ module Engine2
546
571
 
547
572
  def pre_run
548
573
  super
549
- config.merge!(per_page: 10, use_count: false, show_item_menu: true, selectable: true) # search_active: false,
574
+ config.merge!(per_page: 10, use_count: false, selectable: true) # search_active: false,
550
575
 
551
576
  panel_template 'scaffold/list'
552
577
  panel_panel_template 'panels/menu_m' unless action.parent.*.assets[:model]
@@ -572,6 +597,11 @@ module Engine2
572
597
  @meta[:state] = [:query, :ui_state]
573
598
  end
574
599
 
600
+ def field_tabs hash
601
+ super
602
+ search_template 'scaffold/search_tabs'
603
+ end
604
+
575
605
  def select_toggle_menu
576
606
  m = menu :menu
577
607
  unless m.option_index(:select_toggle, false)
@@ -670,6 +700,11 @@ module Engine2
670
700
  (@filters ||= {})[name] = blk
671
701
  end
672
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
+
673
708
  def order name, &blk
674
709
  (@orders ||= {})[name] = blk
675
710
  end
@@ -770,6 +805,11 @@ module Engine2
770
805
  # modal_action false
771
806
  end
772
807
 
808
+ def field_tabs hash
809
+ super
810
+ panel_template 'scaffold/form_tabs'
811
+ end
812
+
773
813
  def record handler, record
774
814
  end
775
815
 
@@ -909,11 +949,17 @@ module Engine2
909
949
  super
910
950
  panel_template 'scaffold/view'
911
951
  panel_title LOCS[:view_title]
952
+ panel[:backdrop] = true
912
953
 
913
954
  menu(:panel_menu).option :cancel, icon: "remove"
914
955
  action.parent.*.menu(:item_menu).option action.name, icon: "file", button_loc: false
915
956
  end
916
957
 
958
+ def field_tabs hash
959
+ super
960
+ panel_template 'scaffold/view_tabs'
961
+ end
962
+
917
963
  def record handler, record
918
964
  end
919
965
 
@@ -1002,6 +1048,9 @@ module Engine2
1002
1048
  datetime: lambda{|meta, field, info|
1003
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]
1004
1050
  },
1051
+ currency: lambda{|meta, field, info|
1052
+ meta.info[field][:render].merge! symbol: info[:symbol]
1053
+ },
1005
1054
  # date_range: lambda{|meta, field, info|
1006
1055
  # meta.info[field][:render].merge! other_date: info[:other_date], format: info[:format], model_format: info[:model_format]
1007
1056
  # meta.hide_fields info[:other_date]
@@ -1024,14 +1073,10 @@ module Engine2
1024
1073
  },
1025
1074
  file_store: lambda{|meta, field, info|
1026
1075
  meta.info[field][:render].merge! multiple: info[:multiple]
1027
- # meta[:model] = meta.action.model.table_name
1028
1076
  },
1029
1077
  star_to_many_field: lambda{|meta, field, info|
1030
1078
  field_info = meta.info[field]
1031
1079
  field_info[:assoc] = :"#{info[:assoc_name]}!"
1032
- # meta.info[field][:render].merge! multiple: info[:multiple]
1033
- # field_info = meta.info[field]
1034
- # field_info[:resource] ||= "#{Handler::API}#{meta.model.namespace}/#{info[:assoc_name]}"
1035
1080
  }
1036
1081
  )
1037
1082
 
@@ -1067,15 +1112,7 @@ module Engine2
1067
1112
  keys = info[:keys]
1068
1113
  else
1069
1114
  meta.check_static_meta
1070
- model = Object.const_get(model.many_to_one_associations[field[/^\w+?(?=__)/].to_sym][:class_name])
1071
- # meta.action.define_action :"#{info[:assoc_name]}!" do # assoc_#{aname}
1072
- # define_action :decode, DecodeEntryMeta, assoc: model.association_reflections[info[:assoc_name]] do
1073
- # run_scheme :default_many_to_one
1074
- # end
1075
- # end
1076
-
1077
- # verify associations ?
1078
- # model = Model.models.fetch(field[/^\w+?(?=__)/].to_sym)
1115
+ model = model.many_to_one_associations[field[/^\w+?(?=__)/].to_sym].associated_class
1079
1116
  keys = info[:keys].map{|k| :"#{model.table_name}__#{k}"}
1080
1117
  end
1081
1118