drg_cms 0.5.7 → 0.5.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -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