drg_cms 0.5.7 → 0.5.8

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.
@@ -0,0 +1,107 @@
1
+ #encoding: utf-8
2
+ #--
3
+ # Copyright (c) 2014+ Damjan Rems
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ #++
24
+
25
+ ######################################################################
26
+ #
27
+ ######################################################################
28
+ module DrgcmsControls::BrowseModelsControl
29
+ include DcApplicationHelper
30
+
31
+ #########################################################################
32
+ # Determine model class from filename.
33
+ #########################################################################
34
+ def determine_model(path)
35
+ path =~ /(.*)\/(.*).rb/
36
+ begin
37
+ $2.camelize.constantize
38
+ $2
39
+ rescue Exception # it happends
40
+ nil
41
+ end
42
+ end
43
+
44
+ #########################################################################
45
+ # Return array of all models found in application.
46
+ #########################################################################
47
+ def all_collections()
48
+ collections = []
49
+ DrgCms.paths(:forms).each do |path|
50
+ models_dir = File.expand_path("../models", path)
51
+ Dir["#{models_dir}/*.rb"].each do |model_file|
52
+ collection_name = determine_model(model_file)
53
+ collections << collection_name if collection_name
54
+ end
55
+ end
56
+ collections.sort
57
+ end
58
+
59
+ ######################################################################
60
+ # List all collections
61
+ ######################################################################
62
+ def collections()
63
+ @records = []
64
+ all_collections.each do |collection|
65
+ @records << {'id' => collection, 'description' => t("helpers.label.#{collection}.tabletitle") }
66
+ end
67
+ @records
68
+ end
69
+
70
+ ######################################################################
71
+ # List field definition for single model
72
+ ######################################################################
73
+ def fields()
74
+ @records = []
75
+ model = params[:id].classify.constantize
76
+ document = model.new
77
+ document.attribute_names.each do |attribute_name|
78
+ options = model.fields[attribute_name].options
79
+ description = I18n.t("helpers.help.#{params[:id]}.#{attribute_name}")
80
+ description = I18n.t("helpers.label.#{params[:id]}.#{attribute_name}") if description.match('missing:')
81
+ description = attribute_name if description.match('missing:')
82
+
83
+ @records << {'collection' => params[:id],
84
+ 'field' => attribute_name,
85
+ 'type' => options[:type],
86
+ 'description' => description,
87
+ '_default' => options[:default]
88
+ }
89
+ end
90
+ # embedded documents
91
+ document.embedded_relations.each do |a_embedded|
92
+ embedded = a_embedded.last
93
+ description = I18n.t("helpers.help.#{params[:id]}.#{embedded.key}")
94
+ description = I18n.t("helpers.label.#{params[:id]}.#{embedded.key}") if description.match('missing:')
95
+ description = embedded.key if description.match('missing:')
96
+
97
+ @records << {'collection' => params[:id],
98
+ 'field' => embedded.key,
99
+ 'type' => 'Embedded:' + embedded.class_name,
100
+ 'description' => description
101
+ }
102
+ end
103
+
104
+ @records
105
+ end
106
+
107
+ end
@@ -25,7 +25,7 @@
25
25
  ######################################################################
26
26
  # DrgcmsControls for DcPage model.
27
27
  ######################################################################
28
- module DrgcmsControls::DcPageControls
28
+ module DrgcmsControls::DcPageControl
29
29
 
30
30
  ######################################################################
31
31
  # Called when new empty record is created
@@ -43,6 +43,10 @@ result_set:
43
43
  filter: filter_vpis
44
44
  actions_width: 100
45
45
  per_page: 10
46
+ table_style: 'color: green;'
47
+ table_class: 'color: green;'
48
+ tr_style: 'color: green;'
49
+ tr_class: 'color: green;'
46
50
 
47
51
  actions: standard
48
52
 
@@ -51,6 +55,9 @@ result_set:
51
55
  2:
52
56
  type: duplicate
53
57
  dup_fields: name,another_field
58
+ td_class: class-name
59
+ td_style:
60
+ eval: "document['field'] == document['description'] ? 'color: gold;' : 'color: #000;'"
54
61
 
55
62
  3:
56
63
  type: delete
@@ -109,4 +109,11 @@ menu:
109
109
  icon: undo lg
110
110
  table: dc_journal
111
111
 
112
+ 500:
113
+ caption: drgcms.browse_collections
114
+ controller: cmsedit
115
+ icon: table lg
116
+ table: dc_dummy
117
+ formname: dc_browse_models
118
+
112
119
 
@@ -0,0 +1,32 @@
1
+ ## Registration form. Not yet implemented.
2
+ ---
3
+ table: dc_dummy
4
+ title: Browse field definitions
5
+ controls: browse_models
6
+ permissions:
7
+ can_view: admin
8
+
9
+ result_set:
10
+ filter: fields
11
+ tr_style:
12
+ eval: "document['field'] == document['description'] ? 'color: #669;' : 'color: #000;'"
13
+
14
+ columns:
15
+ 10:
16
+ name: collection
17
+ caption: Collection
18
+ td_style: 'width: 150px;'
19
+ 20:
20
+ name: field
21
+ caption: Field name
22
+ td_style: 'width: 150px;'
23
+ 30:
24
+ name: type
25
+ caption: Field type
26
+ 40:
27
+ name: description
28
+ caption: description
29
+ 50:
30
+ name: _default
31
+ caption: Default
32
+
@@ -0,0 +1,26 @@
1
+ ## Registration form. Not yet implemented.
2
+ ---
3
+ table: dc_dummy
4
+ title: Browse collection models
5
+ controls: browse_models
6
+ permissions:
7
+ can_view: admin
8
+
9
+ result_set:
10
+ filter: collections
11
+
12
+ dblclick:
13
+ type: link
14
+ table: dc_dummy
15
+ formname: dc_browse_fields
16
+ action: index
17
+
18
+ columns:
19
+ 10:
20
+ name: id
21
+ caption: Collection
22
+ td_style: 'font-weight: bold;width: 150px;'
23
+
24
+ 20:
25
+ name: description
26
+ caption: Decription
@@ -113,7 +113,7 @@ form:
113
113
  60:
114
114
  name: menu_name
115
115
  type: text_with_select
116
- eval: dc_choices4('dc_simple_menu','name','name')
116
+ eval: dc_choices4(@record.menu_class,'description','name')
117
117
  html:
118
118
  size: 30
119
119
  90:
@@ -146,7 +146,7 @@ form:
146
146
  name: design
147
147
  type: text_area
148
148
  html:
149
- size: 150x40
149
+ size: 130x40
150
150
 
151
151
  5permissions:
152
152
 
@@ -230,56 +230,18 @@ def dc_link_or_ajax(yaml, parms) #:nodoc:
230
230
  rest['class'] = rest['class'].to_s + ' dc-animate'
231
231
  rest['title'] = yaml['title']
232
232
 
233
- # method = yaml['method'] || yaml['request'] || 'get'
234
- # caption = yaml['caption'] || yaml['text']
235
233
  dc_deprecate "Form: result_set:action:text directive will be deprecated. Use caption instead of text." if yaml['text']
236
- #
237
- =begin
238
- if yaml['type'] == 'link'
239
- if yaml['icon'] # icon
240
- link_to( image_tag(yaml['icon'], class: 'dc-link-img dc-link-ajax dc-animate'), parms, method: method, title: t(yaml['title'],yaml['title']) )
241
- else # caption
242
- '<span class="dc-link-ajax dc-animate">' + link_to(" #{t(caption, caption)} ", parms, method: method, title: t(yaml['title'],yaml['title']) ) + '</span>'
243
- end
244
- else # ajax
245
- url = url_for(parms)
246
- if yaml['icon'] # icon
247
- image_tag(yaml['icon'], class: 'dc-link-img dc-link-ajax dc-animate', 'data-url' => url, 'data-request' => method)
248
- else # caption
249
- %Q[<span class="dc-link-ajax dc-animate" data-url="#{url}" data-request="#{method}">#{caption}</span>]
250
- end
251
- end
252
- #####
253
- caption = ''
254
- if yaml['type'] == 'link'
255
- if yaml['icon'] # icon
256
- caption = if yaml['icon'].match('.')
257
- image_tag(yaml['icon'], class: 'dc-link-img dc-link-ajax dc-animate')
258
- else
259
- fa_icon("#{yaml['icon']} 2x" , class: 'dc-link-ajax dc-animate')
260
- end
261
- end
262
- if yaml['caption']
263
- caption << ' ' if caption.size > 0
264
- caption << t(yaml['caption'],yaml['caption'])
265
- end
266
- link_to(caption, parms, method: method, title: t(yaml['title'],yaml['title']) )
267
- else
268
- ''
269
- end
270
- =end
271
234
  if yaml['type'] == 'link'
272
235
  dc_link_to(yaml['caption'], yaml['icon'], parms, rest )
273
236
  else
274
237
  ''
275
238
  end
276
-
277
239
  end
278
240
 
279
241
  ############################################################################
280
242
  # Creates actions that could be performed on single row of result set.
281
243
  ############################################################################
282
- def dc_actions_for_result(record)
244
+ def dc_actions_for_result(document)
283
245
  actions = @form['result_set']['actions']
284
246
  return '' if actions.nil? or @form['readonly']
285
247
  # standard actions
@@ -287,7 +249,7 @@ def dc_actions_for_result(record)
287
249
  std_actions = {' 2' => 'edit', ' 3' => 'delete'}
288
250
  actions.merge!(std_actions) if actions['standard']
289
251
  #
290
- width = @form['result_set']['actions_width'] || 22*actions.size
252
+ width = @form['result_set']['actions_width'] || 20*actions.size
291
253
  html = "<td style=\"width: #{width}px;\">"
292
254
  actions.each do |k,v|
293
255
  session[:form_processing] = "result_set:actions: #{k}=#{v}"
@@ -297,31 +259,31 @@ def dc_actions_for_result(record)
297
259
  html << case
298
260
  when yaml['type'] == 'edit' then
299
261
  parms['action'] = 'edit'
300
- parms['id'] = record.id
262
+ parms['id'] = document.id
301
263
  dc_link_to( nil, 'pencil lg', parms )
302
264
  when yaml['type'] == 'duplicate' then
303
- parms['id'] = record.id
265
+ parms['id'] = document.id
304
266
  # duplicate string will be added to these fields.
305
267
  parms['dup_fields'] = yaml['dup_fields']
306
268
  parms['action'] = 'create'
307
269
  dc_link_to( nil, 'copy lg', parms, data: { confirm: t('drgcms.confirm_dup') }, method: :post )
308
270
  when yaml['type'] == 'delete' then
309
271
  parms['action'] = 'destroy'
310
- parms['id'] = record.id
272
+ parms['id'] = document.id
311
273
  dc_link_to( nil, 'remove lg', parms, data: { confirm: t('drgcms.confirm_delete') }, method: :delete )
312
274
  # undocumented so far
313
275
  when yaml['type'] == 'edit_embedded'
314
276
  parms['controller'] = 'cmsedit'
315
277
  parms['table'] += ";#{yaml['table']}"
316
278
  parms['ids'] ||= ''
317
- parms['ids'] += "#{record.id};"
279
+ parms['ids'] += "#{document.id};"
318
280
  dc_link_to( nil, 'table lg', parms, method: :get )
319
281
  when yaml['type'] == 'link' || yaml['type'] == 'ajax' then
320
282
  if yaml['url']
321
283
  parms['controller'] = yaml['url']
322
- parms['idr'] = record.id
284
+ parms['idr'] = document.id
323
285
  else
324
- parms['id'] = record.id
286
+ parms['id'] = document.id
325
287
  end
326
288
  parms['controller'] = yaml['controller'] if yaml['controller']
327
289
  parms['action'] = yaml['action'] if yaml['action']
@@ -343,19 +305,26 @@ end
343
305
  def dc_header_for_result()
344
306
  c = ''
345
307
  actions = @form['result_set']['actions']
346
- c = '<th style="border-left: 0px;">&nbsp;</th>' unless actions.nil? or @form['readonly']
347
-
308
+ c = '<th>&nbsp;</th>' unless actions.nil? or @form['readonly']
309
+ # preparation for sort icon
310
+ sort_field, sort_direction = nil, nil
311
+ if session[@form['table']]
312
+ sort_field, sort_direction = session[@form['table']][:sort].to_s.split(' ')
313
+ end
314
+ #
348
315
  if (columns = @form['result_set']['columns'])
349
316
  columns.each do |k,v|
350
317
  session[:form_processing] = "result_set:columns: #{k}=#{v}"
351
318
  th = '<th '
352
- v = {'name' => v} if v.class == String
319
+ v = {'name' => v} if v.class == String
353
320
  caption = v['caption'] || t("helpers.label.#{@form['table']}.#{v['name']}")
354
- th << "style=\"#{v['style']}\" " if v['style']
355
- th << "class=\"#{v['class']}\" " if v['class']
356
321
  # no sorting when embedded field or custom filter is active
357
322
  if @tables.size == 1 and @form['result_set']['filter'].nil?
358
- th << ">#{link_to(caption, sort: v['name'], table: @tables[0][1], action: :index )}</th>"
323
+ icon = 'sort lg'
324
+ if v['name'] == sort_field
325
+ icon = sort_direction == '1' ? 'sort-alpha-asc lg' : 'sort-alpha-desc lg'
326
+ end
327
+ th << ">#{dc_link_to(caption, icon, sort: v['name'], table: @tables[0][1], action: :index )}</th>"
359
328
  else
360
329
  th << ">#{caption}</th>"
361
330
  end
@@ -365,6 +334,30 @@ def dc_header_for_result()
365
334
  c.html_safe
366
335
  end
367
336
 
337
+ ############################################################################
338
+ # Creates div with documents of current result set.
339
+ ############################################################################
340
+ def dc_clicks_for_result(document)
341
+ html = ''
342
+ if @form['result_set']['dblclick']
343
+ yaml = @form['result_set']['dblclick']
344
+ opts = {}
345
+ opts[:controller] = yaml['controller'] || 'cmsedit'
346
+ opts[:action] = yaml['action']
347
+ opts[:table] = yaml['table']
348
+ opts[:formname] = yaml['formname']
349
+ opts[:method] = yaml['method'] || 'get'
350
+ opts[:id] = document['id']
351
+ html << ' data-dblclick=' + url_for(opts)
352
+ else
353
+ html << (' data-dblclick=' +
354
+ url_for(action: 'show', controller: 'cmsedit', id: document,
355
+ readonly: (params[:readonly] ? 2 : 1), table: params[:table],
356
+ formname: params[:formname], ids: params[:ids]) ) if @form['form']
357
+ end
358
+ html
359
+ end
360
+
368
361
  ############################################################################
369
362
  # Formats value according to format supplied or data type. There is lots of things missing here.
370
363
  ############################################################################
@@ -384,7 +377,31 @@ def dc_format_value(value, format=nil)
384
377
  end
385
378
 
386
379
  ############################################################################
387
- # Creates div with documents of current result set.
380
+ # Defines style or class for row (tr) or column (td)
381
+ ############################################################################
382
+ def dc_style_or_class(selector, yaml, value, document)
383
+ return '' if yaml.nil?
384
+ html = selector ? "#{selector}=\"" : ''
385
+ html << if yaml.class == String
386
+ yaml
387
+ else
388
+ (yaml['eval'] ? eval(yaml['eval']) : '') rescue 'background-color:red;'
389
+ end
390
+ html << '"' if selector
391
+ html
392
+ end
393
+
394
+ ############################################################################
395
+ # Creates tr code for each row of result set.
396
+ ############################################################################
397
+ def dc_row_for_result(document)
398
+ clas = "dc-#{cycle('odd','even')} " + dc_style_or_class(nil,@form['result_set']['tr_class'],nil,document)
399
+ style = dc_style_or_class('style',@form['result_set']['tr_style'],nil,document)
400
+ "<tr class=\"#{clas}\" #{dc_clicks_for_result(document)} #{style}>".html_safe
401
+ end
402
+
403
+ ############################################################################
404
+ # Creates column for each field of result set document.
388
405
  ############################################################################
389
406
  def dc_columns_for_result(document)
390
407
  html = ''
@@ -393,9 +410,6 @@ def dc_columns_for_result(document)
393
410
  session[:form_processing] = "result_set:columns: #{k}=#{v}"
394
411
  # convert shortcut to hash
395
412
  v = {'name' => v} if v.class == String
396
- td = '<td '
397
- td << "style=\"#{v['style']}\" " if v['style']
398
- td << "class=\"#{v['class']}\" " if v['class']
399
413
  # eval
400
414
  value = if v['eval']
401
415
  if v['eval'].match('dc_name4_id')
@@ -424,10 +438,21 @@ def dc_columns_for_result(document)
424
438
  eval( "#{v['eval']} '#{document[ v['name'] ]}'")
425
439
  end
426
440
  end
427
- else
428
- document.respond_to?(v['name']) ? dc_format_value(document.send( v['name'] ), v['format']) : "!!! #{v['name']}"
441
+ # as field
442
+ elsif document.respond_to?(v['name'])
443
+ dc_format_value(document.send( v['name'] ), v['format'])
444
+ # as hash (dc_dummy)
445
+ elsif document.class == Hash
446
+ document[ v['name'] ]
447
+ # error
448
+ else
449
+ "!!! #{v['name']}"
429
450
  end
430
- html << td << ">#{value}</td>"
451
+ #
452
+ td = '<td '
453
+ td << dc_style_or_class('class',v['td_class'],value,document)
454
+ td << dc_style_or_class('style',v['td_style'],value,document)
455
+ html << "#{td}>#{value}</td>"
431
456
  end
432
457
  end
433
458
  html.html_safe