drg_cms 0.6.0.6 → 0.6.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +25 -10
  3. data/app/assets/javascripts/drg_cms/drg_cms.js +281 -106
  4. data/app/assets/stylesheets/drg_cms/drg_cms.css +417 -152
  5. data/app/assets/stylesheets/drg_cms/select-multiple.css +9 -12
  6. data/app/assets/stylesheets/drg_cms_cms.css +1 -1
  7. data/app/controllers/cmsedit_controller.rb +247 -175
  8. data/app/controllers/dc_application_controller.rb +251 -173
  9. data/app/controllers/dc_common_controller.rb +81 -48
  10. data/app/controls/dc_help_control.rb +126 -0
  11. data/app/controls/dc_report.rb +223 -0
  12. data/app/forms/all_options.yml +38 -10
  13. data/app/forms/cms_menu.yml +7 -1
  14. data/app/forms/dc_big_table.yml +1 -0
  15. data/app/forms/dc_big_table_value.yml +1 -0
  16. data/app/forms/dc_category.yml +2 -1
  17. data/app/forms/dc_design.yml +1 -0
  18. data/app/forms/dc_help_1.yml +109 -0
  19. data/app/forms/dc_journal.yml +3 -1
  20. data/app/forms/dc_link.yml +1 -1
  21. data/app/forms/dc_menu.yml +2 -0
  22. data/app/forms/dc_menu_item.yml +1 -0
  23. data/app/forms/dc_page.yml +6 -0
  24. data/app/forms/dc_part.yml +1 -0
  25. data/app/forms/dc_piece.yml +1 -0
  26. data/app/forms/dc_poll.yml +15 -5
  27. data/app/forms/dc_poll_item.yml +2 -1
  28. data/app/forms/dc_poll_result.yml +9 -0
  29. data/app/forms/dc_simple_menu.yml +2 -0
  30. data/app/forms/dc_site.yml +4 -12
  31. data/app/forms/dc_user.yml +27 -11
  32. data/app/forms/dc_user_role.yml +3 -0
  33. data/app/helpers/cms_common_helper.rb +375 -0
  34. data/app/helpers/{cmsedit_edit_helper.rb → cms_edit_helper.rb} +109 -65
  35. data/app/helpers/{cmsedit_helper.rb → cms_helper.rb} +93 -48
  36. data/app/helpers/{cmsedit_index_helper.rb → cms_index_helper.rb} +240 -206
  37. data/app/helpers/dc_application_helper.rb +108 -327
  38. data/app/models/concerns/dc_page_concern.rb +14 -4
  39. data/app/models/concerns/dc_piece_concern.rb +1 -1
  40. data/app/models/concerns/dc_policy_rule_concern.rb +20 -8
  41. data/app/models/concerns/dc_site_concern.rb +67 -44
  42. data/app/models/concerns/dc_user_concern.rb +58 -19
  43. data/app/models/dc_design.rb +29 -19
  44. data/app/models/dc_filter.rb +26 -18
  45. data/app/models/dc_key_value_store.rb +1 -0
  46. data/app/models/dc_permission.rb +49 -9
  47. data/app/models/dc_policy.rb +25 -14
  48. data/app/models/dc_policy_role.rb +22 -11
  49. data/app/models/dc_poll.rb +1 -0
  50. data/app/models/dc_poll_result.rb +4 -2
  51. data/app/models/dc_temp.rb +6 -3
  52. data/app/models/dc_user_role.rb +2 -2
  53. data/app/models/drgcms_form_fields/date_picker.rb +6 -3
  54. data/app/models/drgcms_form_fields/datetime_picker.rb +4 -3
  55. data/app/models/drgcms_form_fields/drgcms_field.rb +20 -5
  56. data/app/models/drgcms_form_fields/embedded.rb +23 -16
  57. data/app/models/drgcms_form_fields/file_field.rb +2 -2
  58. data/app/models/drgcms_form_fields/file_select.rb +2 -2
  59. data/app/models/drgcms_form_fields/hash_field.rb +11 -7
  60. data/app/models/drgcms_form_fields/hidden_field.rb +1 -1
  61. data/app/models/drgcms_form_fields/link_to.rb +2 -2
  62. data/app/models/drgcms_form_fields/method.rb +66 -0
  63. data/app/models/drgcms_form_fields/multitext_autocomplete.rb +18 -12
  64. data/app/models/drgcms_form_fields/number_field.rb +4 -3
  65. data/app/models/drgcms_form_fields/radio.rb +10 -5
  66. data/app/models/drgcms_form_fields/readonly.rb +13 -17
  67. data/app/models/drgcms_form_fields/select.rb +58 -41
  68. data/app/models/drgcms_form_fields/text_autocomplete.rb +41 -33
  69. data/app/models/drgcms_form_fields.rb +12 -1
  70. data/app/renderers/dc_big_menu_renderer.rb +1 -0
  71. data/app/renderers/dc_gallery_renderer.rb +1 -0
  72. data/app/renderers/dc_menu_renderer.rb +1 -0
  73. data/app/renderers/dc_page_renderer.rb +8 -6
  74. data/app/renderers/dc_part_renderer.rb +1 -0
  75. data/app/renderers/dc_piece_renderer.rb +1 -1
  76. data/app/renderers/dc_poll_renderer.rb +56 -55
  77. data/app/renderers/dc_renderer.rb +1 -0
  78. data/app/renderers/dc_simple_menu_renderer.rb +1 -0
  79. data/app/views/cmsedit/_edit_stuff.html.erb +5 -2
  80. data/app/views/cmsedit/edit.html.erb +4 -1
  81. data/app/views/cmsedit/index.html.erb +3 -2
  82. data/app/views/cmsedit/new.html.erb +5 -2
  83. data/app/views/dc_common/_help.html.erb +17 -0
  84. data/app/views/layouts/models.html.erb +2 -1
  85. data/config/locales/drgcms_en.yml +17 -2
  86. data/config/locales/drgcms_sl.yml +22 -4
  87. data/config/locales/models_en.yml +16 -7
  88. data/config/locales/models_sl.yml +21 -12
  89. data/drg_cms.gemspec +16 -16
  90. data/lib/drg_cms/version.rb +1 -1
  91. data/lib/drg_cms.rb +98 -0
  92. data/lib/generators/new_drg_form/new_drg_form_generator.rb +5 -3
  93. data/lib/tasks/database.rake +6 -56
  94. metadata +39 -35
  95. data/app/helpers/application_helper.rb +0 -2
  96. data/app/models/__dc_dummy.rb +0 -102
@@ -27,60 +27,43 @@
27
27
  # data found in 3 major sections of DRG CMS form: index, result_set and form sections.
28
28
  #
29
29
  ###########################################################################
30
- module CmseditIndexHelper
30
+ module CmsIndexHelper
31
31
 
32
- ############################################################################
33
- # Get standard actions when actions directive contains single line.
34
- # Subroutine of dc_actions_for_index
35
- #
36
- # Allows for actions: new, filter, standard syntax
37
- ############################################################################
38
- def define_standard_actions(actions_params, standard)
39
- actions = {}
40
- actions_params.split(',').each do |an_action|
41
- an_action.strip!
42
- if an_action == 'standard'
43
- actions.merge!(standard)
44
- else
45
- standard.each do |index, action|
46
- (actions[index] = action; break) if action == an_action
47
- end
48
- end
49
- end
50
- actions
51
- end
52
-
53
32
  ############################################################################
54
33
  # Creates action div for cmsedit index action.
55
34
  ############################################################################
56
- def dc_actions_for_index()
35
+ def dc_actions_for_index
57
36
  @js = @form['script'] || @form['js'] || ''
58
37
  @css = @form['css'] || ''
59
- return '' if @form['index'].nil? or @form['readonly']
38
+ return '' if @form['index'].nil?
39
+
60
40
  actions = @form['index']['actions']
61
41
  return '' if actions.blank?
62
42
 
63
43
  std_actions = {2 => 'new', 3 => 'sort', 4 => 'filter' }
44
+ std_actions.delete(2) if @form['readonly']
45
+
64
46
  if actions.class == String
65
- actions = define_standard_actions(actions, std_actions)
47
+ actions = dc_define_standard_actions(actions, std_actions)
66
48
  elsif actions['standard']
67
49
  actions.merge!(std_actions)
68
50
  actions['standard'] = nil
69
51
  end
70
52
 
71
- # start div with hidden spinner image
72
- html = <<EOT
53
+ # start div with hidden spinner image
54
+ html = %(
73
55
  <form id="dc-action-menu">
74
56
  <span class="dc-spinner">#{fa_icon('spinner lg spin')}</span>
75
- <ul class="dc-action-menu">
76
- EOT
77
- # Remove actions settings and sort
57
+ <ul class="dc-action-menu">)
58
+
59
+ # Remove actions settings and sort
78
60
  only_actions = []
79
61
  actions.each { |key, value| only_actions << [key, value] if key.class == Integer }
80
62
  only_actions.sort_by!(&:first)
81
63
  only_actions.each do |key, options|
82
64
  session[:form_processing] = "index:actions: #{key}=#{options}"
83
65
  next if options.nil? # must be
66
+
84
67
  url = @parms.clone
85
68
  yaml = options.class == String ? {'type' => options} : options # if single definition simulate type parameter
86
69
  action = yaml['type'].to_s.downcase
@@ -88,7 +71,7 @@ EOT
88
71
  dc_deprecate "action: url will be deprecated. Use action: link in index: actions! Form #{params['form_name']}"
89
72
  action = 'link'
90
73
  end
91
- # if return_to is present link directly to URL
74
+ # if return_to is present link directly to URL
92
75
  if action == 'link' and yaml['url']
93
76
  url = yaml['url']
94
77
  else
@@ -98,11 +81,12 @@ EOT
98
81
  url['form_name'] = yaml['form_name'] if yaml['form_name']
99
82
  url['control'] = yaml['control'] if yaml['control']
100
83
  end
101
- # html link options
84
+ # html link options
102
85
  yhtml = yaml['html'] || {}
103
86
  yhtml['title'] = yaml['title'] if yaml['title']
104
- code = case
105
- # sort
87
+
88
+ code = case
89
+ # sort
106
90
  when action == 'sort' then
107
91
  choices = [['id','id']]
108
92
  if @form['index']['sort']
@@ -113,26 +97,34 @@ EOT
113
97
  end
114
98
  fa_icon('sort-alpha-asc') + ' ' + t('drgcms.sort') + ' ' +
115
99
  select('sort', 'sort', choices, { include_blank: true },
116
- { class: 'drgcms_sort', 'data-table' => @form['table']} )
117
- # filter
100
+ { class: 'drgcms_sort', 'data-table' => @form['table'], 'data-form' => params['form_name']} )
101
+
102
+ # filter
118
103
  when action == 'filter' then
119
104
  caption = t('drgcms.filter')
120
105
  caption << '&nbsp;' + fa_icon('caret-down lg') + DcFilter.menu_filter(self)
121
- # add filter OFF link
106
+ # add filter OFF link
122
107
  sess = session[@form['table']]
123
108
  if sess and sess[:filter]
124
- caption << '&nbsp;&nbsp;' + dc_link_to(nil,'remove lg', {controller: 'cmsedit',
125
- filter: 'off', table: @form['table']}, { title: DcFilter.title4_filter_off(sess[:filter]) })
109
+ caption << '&nbsp;&nbsp;' + dc_link_to(nil,'remove lg',
110
+ { controller: 'cmsedit', filter: 'off', table: @form['table'], form_name: params['form_name'] },
111
+ { title: DcFilter.title4_filter_off(sess[:filter]) })
126
112
  end
127
113
  caption
128
- # new
114
+
115
+ # new
129
116
  when action == 'new' then
130
117
  caption = yaml['caption'] || 'drgcms.new'
131
118
  dc_link_to(caption,'plus', url, yhtml )
132
- # menu
133
- when action == 'menu' then
134
- caption = t(options['caption'], options['caption']) + '&nbsp;' + fa_icon('caret-down lg')
135
- caption + eval(options['eval'])
119
+
120
+ # menu
121
+ when action == 'menu' then
122
+ if options['caption']
123
+ caption = t(options['caption'], options['caption']) + '&nbsp;' + fa_icon('caret-down lg')
124
+ caption + eval(options['eval'])
125
+ else # when caption is false, provide own actions
126
+ eval(options['eval'])
127
+ end
136
128
  =begin
137
129
  # reorder
138
130
  when action == 'reorder' then
@@ -146,13 +138,16 @@ EOT
146
138
  when action == 'script'
147
139
  html << dc_script_action(options)
148
140
  next
141
+
149
142
  when action == 'field'
150
143
  html << dc_field_action(yaml)
151
144
  next
145
+
152
146
  when %w(ajax link window submit).include?(action)
153
147
  html << dc_link_ajax_window_submit_action(options, nil)
154
148
  next
155
- else
149
+
150
+ else
156
151
  caption = yaml['caption'] || yaml['text']
157
152
  icon = yaml['icon'] ? yaml['icon'] : action
158
153
  dc_link_to(caption, icon, url, yhtml)
@@ -160,22 +155,21 @@ EOT
160
155
  html << "<li class=\"dc-link dc-animate\">#{code}</li>"
161
156
  html << DcFilter.get_filter_field(self) if action == 'filter'
162
157
  end
163
- html << '</ul>'
164
- html << '</form>'
158
+ html << '</ul></form>'
165
159
  html.html_safe
166
160
  end
167
161
 
168
162
  ############################################################################
169
163
  # Creates filter div for cmsedit index/filter action.
170
164
  ############################################################################
171
- def dc_div_filter()
165
+ def dc_div_filter
172
166
  choices = []
173
167
  filter = (@form['index'] and @form['index']['filter']) ? @form['index']['filter'] + ',' : ''
174
168
  filter << 'id as text_field' # filter id is added by default
175
169
  filter.split(',').each do |f|
176
170
  f.strip!
177
171
  name = f.match(' as ') ? f.split(' ').first : f
178
- # like another field on the form
172
+ # like another field on the form
179
173
  if f.match(' like ')
180
174
  a = f.split(' ')
181
175
  name = a.first
@@ -184,7 +178,7 @@ def dc_div_filter()
184
178
  choices << [ t("helpers.label.#{@form['table']}.#{name}", name), f ]
185
179
  end
186
180
  choices4_operators = t('drgcms.choices4_filter_operators').chomp.split(',').inject([]) {|r,v| r << (v.match(':') ? v.split(':') : v )}
187
- # currently selected options
181
+ # currently selected options
188
182
  if session[@form['table']] and session[@form['table']][:filter]
189
183
  field_name, operators_value, dummy = session[@form['table']][:filter].split("\t")
190
184
  else
@@ -210,7 +204,7 @@ end
210
204
  ############################################################################
211
205
  # Creates popup div for setting filter on result set header.
212
206
  ############################################################################
213
- def dc_filter_popup()
207
+ def dc_filter_popup
214
208
  html = %Q[<div class="filter-popup" style="display: none;">
215
209
  <div>#{t('drgcms.filter_set')}</div>
216
210
  <ul>]
@@ -224,102 +218,95 @@ def dc_filter_popup()
224
218
  end
225
219
 
226
220
  ############################################################################
227
- # Creates title div for cmsedit index result set records. Title div also includes paging
228
- # options.
221
+ # Will return title based on @form['title']
229
222
  ############################################################################
230
- def dc_table_title_for_result(result=nil)
231
- title = if @form['title'] # form has title section
232
- t(@form['title'], @form['title'])
233
- else # get name from translations
234
- t("helpers.label.#{@form['table']}.tabletitle", @form['table'])
235
- end
236
- dc_table_title(title, result)
223
+ def dc_form_title
224
+ return t("helpers.label.#{@form['table']}.tabletitle", @form['table']) if @form['title'].nil?
225
+ return t(@form['title'], @form['title']) if @form['title'].class == String
226
+
227
+ # Hash
228
+ dc_process_eval(@form['title']['eval'], [@form['title']['caption'] || @form['title']['text'], params])
237
229
  end
238
230
 
239
231
  ############################################################################
240
- # Creates code for link or ajax action type. Subroutine of dc_actions_for_result.
232
+ # Creates title div for index action. Title div also includes paging options
233
+ # and help link
241
234
  ############################################################################
242
- def __dc_link_or_ajax_action(yaml, parms) #:nodoc:
243
- rest = {}
244
- rest['method'] = yaml['method'] || yaml['request'] || 'get'
245
- rest['caption'] = yaml['caption'] || yaml['text']
246
- rest['class'] = 'dc-animate'
247
- rest['title'] = yaml['title']
248
-
249
- if yaml['type'] == 'link'
250
- dc_link_to(yaml['caption'], yaml['icon'], parms, rest )
251
- else
252
- rest['data-url'] = url_for(parms)
253
- rest['class'] << " fa fa-#{yaml['icon']}"
254
- fa_icon(yaml['icon'], rest )
255
- end
235
+ def dc_title_for_index(result = nil)
236
+ dc_table_title(dc_form_title(), result)
256
237
  end
257
238
 
258
239
  ############################################################################
259
240
  # Determines actions and width of actions column
260
241
  ############################################################################
261
- def dc_actions_column()
242
+ def dc_actions_column
262
243
  actions = @form['result_set']['actions']
263
- return [{},0] if actions.nil? or dc_dont?(actions)
264
- # standard actions
244
+ return [{}, 0] if actions.nil? || dc_dont?(actions)
245
+
246
+ # standard actions
265
247
  actions = {'standard' => true} if actions.class == String && actions == 'standard'
266
- std_actions = {' 2' => 'edit', ' 3' => 'delete'}
248
+ std_actions = { 2 => 'edit', 5 => 'delete' }
267
249
  if actions['standard']
268
250
  actions.merge!(std_actions)
269
251
  actions.delete('standard')
270
252
  end
271
- #
253
+
272
254
  width = @form['result_set']['actions_width'] || 18*actions.size
273
- [ actions, width ]
255
+ [actions, width]
274
256
  end
275
257
 
276
258
  ############################################################################
277
259
  # Calculates (blank) space required for actions when @record_footer is rendered
278
260
  ############################################################################
279
- def dc_actions_column_for_footer()
261
+ def dc_actions_column_for_footer
280
262
  return '' unless @form['result_set']['actions']
263
+
281
264
  ignore, width = dc_actions_column
282
265
  %Q[<div class="actions" style="width: #{width}px;"></div>].html_safe
283
266
  end
284
267
 
285
-
286
268
  ############################################################################
287
269
  # Creates actions that could be performed on single row of result set.
288
270
  ############################################################################
289
271
  def dc_actions_for_result(document)
290
272
  actions = @form['result_set']['actions']
291
- return '' if actions.nil? or @form['readonly']
292
- #
273
+ return '' if actions.nil? || @form['readonly']
274
+
293
275
  actions, width = dc_actions_column()
294
276
  html = %Q[<ul class="actions" style="width: #{width}px;">]
295
- actions.each do |k,v|
277
+ actions.sort_by(&:first).each do |k, v|
296
278
  session[:form_processing] = "result_set:actions: #{k}=#{v}"
297
- next if k == 'standard' # ignore standard definition
298
- parms = @parms.clone
279
+ parms = @parms.clone
299
280
  # if single definition simulate type parameter
300
- yaml = v.class == String ? {'type' => v} : v
281
+ yaml = v.class == String ? { 'type' => v } : v
301
282
  # code already includes li tag
302
- if %w(ajax link window submit).include?(yaml['type']) then
283
+ if %w(ajax link window submit).include?(yaml['type'])
303
284
  @record = document # otherwise document fields can't be used as parameters
304
- html << dc_link_ajax_window_submit_action(yaml,document)
285
+ html << dc_link_ajax_window_submit_action(yaml, document)
305
286
  else
306
287
  html << '<li class="dc-link">'
307
288
  html << case
289
+ when yaml['type'] == 'check' then
290
+ check_box_tag("check-#{document.id}", false,false,{ class: 'dc-check' })
291
+
308
292
  when yaml['type'] == 'edit' then
309
293
  parms['action'] = 'edit'
310
294
  parms['id'] = document.id
311
295
  dc_link_to( nil, 'pencil lg', parms )
296
+
312
297
  when yaml['type'] == 'duplicate' then
313
298
  parms['id'] = document.id
314
299
  # duplicate string will be added to these fields.
315
300
  parms['dup_fields'] = yaml['dup_fields']
316
301
  parms['action'] = 'create'
317
302
  dc_link_to( nil, 'copy lg', parms, data: { confirm: t('drgcms.confirm_dup') }, method: :post )
303
+
318
304
  when yaml['type'] == 'delete' then
319
305
  parms['action'] = 'destroy'
320
306
  parms['id'] = document.id
321
- parms['return_to'] = request.url
307
+ #parms['return_to'] = request.url
322
308
  dc_link_to( nil, 'remove lg', parms, data: { confirm: t('drgcms.confirm_delete') }, method: :delete )
309
+
323
310
  # undocumented so far
324
311
  when yaml['type'] == 'edit_embedded'
325
312
  parms['controller'] = 'cmsedit'
@@ -327,21 +314,7 @@ def dc_actions_for_result(document)
327
314
  parms['ids'] ||= ''
328
315
  parms['ids'] += "#{document.id};"
329
316
  dc_link_to( nil, 'table lg', parms, method: :get )
330
- =begin
331
- when yaml['type'] == 'link' || yaml['type'] == 'ajax' then
332
- if yaml['url']
333
- parms['controller'] = yaml['url']
334
- parms['idr'] = document.id
335
- else
336
- parms['id'] = document.id
337
- end
338
- parms['controller'] = yaml['controller'] if yaml['controller']
339
- parms['action'] = yaml['action'] if yaml['action']
340
- parms['table'] = yaml['table'] if yaml['table']
341
- parms['form_name'] = yaml['form_name'] if yaml['form_name']
342
- parms['target'] = yaml['target'] if yaml['target']
343
- dc_link_or_ajax_action(yaml, parms)
344
- =end
317
+
345
318
  else # error.
346
319
  yaml['type'].to_s
347
320
  end
@@ -355,37 +328,43 @@ end
355
328
  ############################################################################
356
329
  # Creates header div for result set.
357
330
  ############################################################################
358
- def dc_header_for_result()
331
+ def dc_header_for_result
359
332
  html = '<div class="dc-result-header">'
360
333
  if @form['result_set']['actions'] and !@form['readonly']
361
334
  ignore, width = dc_actions_column()
362
- html << %Q[<div class="actions" style="width: #{width}px;"></div>]
335
+ if width > 0 && @form['result_set']['actions'][0].to_s == 'check'
336
+ check_all = fa_icon('check-square-o', class: 'dc-check-all')
337
+ end
338
+ html << %Q[<div class="actions" style="width:#{width}px;">#{check_all}</div>]
363
339
  end
364
340
  # preparation for sort icon
365
341
  sort_field, sort_direction = nil, nil
366
342
  if session[@form['table']]
367
343
  sort_field, sort_direction = session[@form['table']][:sort].to_s.split(' ')
368
344
  end
369
- #
345
+
370
346
  if (columns = @form['result_set']['columns'])
371
- columns.sort.each do |k,v|
347
+ columns.sort.each do |k, v|
372
348
  session[:form_processing] = "result_set:columns: #{k}=#{v}"
373
- th = %Q[<div class="th" style="width: #{v['width'] || '15%'};text-align: #{v['align'] || 'left'};" data-name="#{v['name']}"]
374
- # when no caption or name is defined it might be just spacer
375
- if (caption = v['caption']).nil?
376
- caption = v['name'] ? t("helpers.label.#{@form['table']}.#{v['name']}") : ''
377
- end
349
+ next if v['width'].to_s.match(/hidden|none/i)
350
+
351
+ th = %Q[<div class="th" style="width:#{v['width'] || '15%'};text-align:#{v['align'] || 'left'};" data-name="#{v['name']}"]
352
+ label = v['caption'] || v['label']
353
+ label = (v['name'] ? "helpers.label.#{@form['table']}.#{v['name']}" : '') if label.nil?
354
+ label = t(label) if label.match(/\./)
378
355
  # no sorting when embedded documents or custom filter is active
379
- sort_ok = @form['result_set'].nil? || (@form['result_set'] && @form['result_set']['filter'].nil?)
356
+ #sort_ok = @form['result_set'].nil? || (@form['result_set'] && @form['result_set']['filter'].nil?)
357
+ sort_ok = true
380
358
  sort_ok = sort_ok || (@form['index'] && @form['index']['sort'])
359
+ sort_ok = sort_ok && !dc_dont?(v['sort'], false)
381
360
  if @tables.size == 1 and sort_ok
382
361
  icon = 'sort lg'
383
362
  if v['name'] == sort_field
384
363
  icon = sort_direction == '1' ? 'sort-alpha-asc lg' : 'sort-alpha-desc lg'
385
364
  end
386
- th << ">#{dc_link_to(caption, icon, sort: v['name'], table: params[:table], form_name: params[:form_name], action: :index, icon_pos: :last )}</div>"
365
+ th << ">#{dc_link_to(label, icon, sort: v['name'], table: params[:table], form_name: params[:form_name], action: :index, icon_pos: :last )}</div>"
387
366
  else
388
- th << ">#{caption}</div>"
367
+ th << ">#{label}</div>"
389
368
  end
390
369
  html << "<div class=\"spacer\"></div>" + th
391
370
  end
@@ -407,12 +386,14 @@ def dc_clicks_for_result(document)
407
386
  opts[:form_name] = yaml['form_name']
408
387
  opts[:method] = yaml['method'] || 'get'
409
388
  opts[:id] = document['id']
389
+ opts[:readonly] = yaml['readonly'] if yaml['readonly']
390
+ opts[:window_close] = yaml['window_close'] if yaml['window_close']
410
391
  html << ' data-dblclick=' + url_for(opts)
411
392
  else
412
393
  html << (' data-dblclick=' +
413
- url_for(action: 'show', controller: 'cmsedit', id: document.id,
414
- readonly: (params[:readonly] ? 2 : 1), table: params[:table],
415
- form_name: params[:form_name], ids: params[:ids]) ) if @form['form']
394
+ url_for(action: 'show', controller: 'cmsedit', id: document.id, ids: params[:ids],
395
+ readonly: (params[:readonly] ? 2 : 1), table: params[:table],
396
+ form_name: params[:form_name]) ) if @form['form']
416
397
  end
417
398
  html
418
399
  end
@@ -422,14 +403,15 @@ end
422
403
  ############################################################################
423
404
  def dc_format_value(value, format=nil)
424
405
  return '' if value.nil?
406
+
425
407
  klass = value.class.to_s
426
- case when klass.match('Time') then
427
- format ||= t('time.formats.default')
428
- value.strftime(format)
429
- when klass.match('Date') then
430
- format ||= t('date.formats.default')
431
- value.strftime(format)
432
- when format.to_s[0] == 'N' then
408
+ return CmsCommonHelper.dc_format_date_time(value, format) if klass.match(/time|date/i)
409
+
410
+ format = format.to_s.upcase
411
+ if format[0] == 'N'
412
+ return '' if value == 0 && format.match('Z')
413
+
414
+ format.gsub!('Z', '')
433
415
  dec = format[1].blank? ? nil : format[1].to_i
434
416
  sep = format[2].blank? ? nil : format[2]
435
417
  del = format[3].blank? ? nil : format[3]
@@ -440,26 +422,6 @@ def dc_format_value(value, format=nil)
440
422
  end
441
423
  end
442
424
 
443
- ############################################################################
444
- # Defines style or class for row (tr) or column (td)
445
- ############################################################################
446
- def dc_style_or_class(selector, yaml, value, record)
447
- return '' if yaml.nil?
448
- # alias record and value so both names can be used in eval
449
- field, document = value, record
450
- html = selector ? "#{selector}=\"" : ''
451
- html << if yaml.class == String
452
- yaml
453
- # direct evaluate expression
454
- elsif yaml['eval']
455
- eval(yaml['eval']) rescue 'background-color:red;'
456
- elsif yaml['method']
457
- dc_process_eval(yaml['method'],record)
458
- end
459
- html << '"' if selector
460
- html
461
- end
462
-
463
425
  ############################################################################
464
426
  # Creates tr code for each row of result set.
465
427
  ############################################################################
@@ -469,6 +431,61 @@ def dc_row_for_result(document)
469
431
  "<div id=\"#{document.id}\" class=\"dc-result-data #{clas}\" #{dc_clicks_for_result(document)} #{style}>".html_safe
470
432
  end
471
433
 
434
+ ############################################################################
435
+ # Creates column for each field of result set document.
436
+ ############################################################################
437
+ def dc_columns_for_result(document)
438
+ return '' unless @form['result_set']['columns']
439
+
440
+ html = ''
441
+ @form['result_set']['columns'].sort.each do |k,v|
442
+ session[:form_processing] = "result_set:columns: #{k}=#{v}"
443
+ next if v['width'].to_s.match(/hidden|none/i)
444
+
445
+ # convert shortcut to hash
446
+ v = {'name' => v} if v.class == String
447
+ begin
448
+ # eval
449
+ value = if v['eval']
450
+ dc_process_column_eval(v, document)
451
+ # as field
452
+ elsif document.respond_to?(v['name'])
453
+ dc_format_value(document.send( v['name'] ), v['format'])
454
+ # as hash (dc_memory)
455
+ elsif document.class == Hash
456
+ dc_format_value(document[ v['name'] ], v['format'])
457
+ # error
458
+ else
459
+ "??? #{v['name']}"
460
+ end
461
+ rescue Exception => e
462
+ dc_log_exception(e, 'dc_columns_for_result')
463
+ value = '!!!Error'
464
+ end
465
+ html << '<div class="spacer"></div>'
466
+ # set class
467
+ clas = dc_style_or_class(nil, v['td_class'], value, document)
468
+ # set width and align an additional style
469
+ style = dc_style_or_class(nil, v['td_style'] || v['style'], value, document)
470
+ flex_align = v['align'].to_s == 'right' ? 'flex-direction:row-reverse;' : ''
471
+ width_align = %Q[width:#{v['width'] || '15%'};#{flex_align}]
472
+ style = "style=\"#{width_align}#{style}\" "
473
+
474
+ html << "<div class=\"td #{clas}\" #{style}>#{value}</div>"
475
+ end
476
+ html.html_safe
477
+ end
478
+
479
+ ############################################################################
480
+ # Split eval expression to array by parameters.
481
+ # Ex. Will split dc_name4_value(one ,"two") => ['dc_name4_value', 'one', 'two']
482
+ ############################################################################
483
+ def dc_eval_to_array(expression)
484
+ expression.split(/\ |\,|\(|\)/).delete_if {|e| e.blank? }.map {|e| e.gsub(/\'|\"/,'').strip }
485
+ end
486
+
487
+ private
488
+
472
489
  ############################################################################
473
490
  # Process eval. Breaks eval option and calls with send method.
474
491
  # Parameters:
@@ -491,77 +508,94 @@ end
491
508
  # Used for processing single field column on result_set or form head.
492
509
  ############################################################################
493
510
  def dc_process_column_eval(yaml, document)
494
- # dc_name4_id
495
- if yaml['eval'].match('dc_name4_id')
496
- a = yaml['eval'].split(/\ |\,/)
497
- if a.size == 3
498
- dc_name4_id(a[1], a[2], nil, document[ yaml['name'] ])
511
+ # dc_name_for_id
512
+ if yaml['eval'].match(/dc_name4_id|dc_name_for_id/)
513
+ parms = dc_eval_to_array(yaml['eval'])
514
+ if parms.size == 3
515
+ dc_name_for_id(parms[1], parms[2], nil, document[ yaml['name'] ])
499
516
  else
500
- dc_name4_id(a[1], a[2], a[3], document[ yaml['name'] ])
517
+ dc_name_for_id(parms[1], parms[2], parms[3], document[ yaml['name'] ])
501
518
  end
502
- # dc_name4_value
503
- elsif yaml['eval'].match('dc_name4_value')
504
- dc_name4_value( @form['table'], yaml['name'], document[ yaml['name'] ] )
519
+
520
+ # dc_name_for_value from locale definition
521
+ elsif yaml['eval'].match(/dc_name4_value|dc_name_for_value/)
522
+ parms = dc_eval_to_array(yaml['eval'])
523
+ if parms.size == 1
524
+ dc_name_for_value( @form['table'], yaml['name'], document[ yaml['name'] ] )
525
+ else
526
+ dc_name_for_value( parms[1], parms[2], document[ yaml['name'] ] )
527
+ end
528
+
529
+ # defined in helpers. For example dc_icon_for_boolean
530
+ elsif respond_to?(yaml['eval'])
531
+ send(yaml['eval'], document[yaml['name']])
532
+
533
+ # defined in model
534
+ elsif document.respond_to?(yaml['eval'])
535
+ document.send(yaml['eval'])
536
+
537
+ # special eval
505
538
  elsif yaml['eval'].match('eval ')
506
539
  # TO DO evaluate with specified parameters
540
+
541
+ # eval with params
507
542
  else
508
- parameters = if yaml['params']
509
- # pass document as parameter
510
- if yaml['params'] == 'document' or yaml['params'] == 'record'
511
- document
512
- else
513
- yaml['params'].chomp.split(',').inject([]) do |result,e|
514
- result << document[e.strip]
515
- end
516
- end
543
+ parms = {}
544
+ if yaml['params'].class == String
545
+ parms = dc_value_for_parameter(yaml['params'], document)
546
+ elsif yaml['params'].class == Hash
547
+ yaml['params'].each { |k, v| parms[k] = dc_value_for_parameter(v) }
517
548
  else
518
- document[ yaml['name'] ]
549
+ parms = document[ yaml['name'] ]
519
550
  end
520
- # evaluate by calling send method
521
- dc_process_eval(yaml['eval'], parameters)
551
+ dc_process_eval(yaml['eval'], parms)
522
552
  end
523
553
  end
524
554
 
525
555
  ############################################################################
526
- # Creates column for each field of result set document.
556
+ # Defines style or class for row (tr) or column (td)
527
557
  ############################################################################
528
- def dc_columns_for_result(document)
529
- return '' unless @form['result_set']['columns']
530
- html = ''
531
- @form['result_set']['columns'].sort.each do |k,v|
532
- session[:form_processing] = "result_set:columns: #{k}=#{v}"
533
- # convert shortcut to hash
534
- v = {'name' => v} if v.class == String
535
- begin
536
- # eval
537
- value = if v['eval']
538
- dc_process_column_eval(v, document)
539
- # as field
540
- elsif document.respond_to?(v['name'])
541
- dc_format_value(document.send( v['name'] ), v['format'])
542
- # as hash (dc_memory)
543
- elsif document.class == Hash
544
- dc_format_value(document[ v['name'] ], v['format'])
545
- # error
546
- else
547
- "!!! #{v['name']}"
548
- end
549
- rescue Exception => e
550
- dc_log_exception(e)
551
- value = '!!!Error'
552
- end
553
- html << '<div class="spacer"></div>'
554
- # set class
555
- clas = dc_style_or_class(nil, v['td_class'], value, document)
556
- # set width and align an additional style
557
- style = dc_style_or_class(nil, v['td_style'] || v['style'], value, document)
558
- width_align = %Q[width: #{v['width'] || '15%'};text-align: #{v['align'] || 'left'};]
559
- style = "#{width_align}#{style}"
558
+ def dc_style_or_class(selector, yaml, value, record)
559
+ return '' if yaml.nil?
560
560
 
561
- html << "<div class=\"td #{clas}\" style=\"#{style}\">#{value}</div>"
561
+ # alias record and value so both names can be used in eval
562
+ field, document = value, record
563
+ html = selector ? "#{selector}=\"" : ''
564
+ begin
565
+ html << if yaml.class == String
566
+ yaml
567
+ # direct evaluate expression
568
+ elsif yaml['eval']
569
+ eval(yaml['eval'])
570
+ elsif yaml['method']
571
+ dc_process_eval(yaml['method'], record)
572
+ end
573
+ rescue Exception => e
574
+ dc_log_exception(e, 'dc_style_or_class')
562
575
  end
563
- html.html_safe
564
- end
576
+ html << '"' if selector
577
+ html
578
+ end
565
579
 
580
+ ############################################################################
581
+ # Get standard actions when actions directive contains single line.
582
+ # Subroutine of dc_actions_for_index
583
+ #
584
+ # Allows for actions: new, filter, standard syntax
585
+ ############################################################################
586
+ def dc_define_standard_actions(actions_params, standard)
587
+ actions = {}
588
+ actions_params.split(',').each do |an_action|
589
+ an_action.strip!
590
+ if an_action == 'standard'
591
+ actions.merge!(standard)
592
+ else
593
+ standard.each do |index, action|
594
+ (actions[index] = action; break) if action == an_action
595
+ end
596
+ end
597
+ end
598
+ actions
599
+ end
566
600
 
567
601
  end