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.
- checksums.yaml +4 -4
- data/README.md +7 -3
- data/app/assets/javascripts/drg_cms/drg_cms.js +21 -4
- data/app/assets/stylesheets/drg_cms/drg_cms.css +92 -47
- data/app/controllers/cmsedit_controller.rb +22 -20
- data/app/controllers/drgcms_controls/browse_models_control.rb +107 -0
- data/app/controllers/drgcms_controls/{dc_page_controls.rb → dc_page_control.rb} +1 -1
- data/app/forms/all_options.yml +7 -0
- data/app/forms/cms_menu.yml +7 -0
- data/app/forms/dc_browse_fields.yml +32 -0
- data/app/forms/dc_browse_models.yml +26 -0
- data/app/forms/dc_site.yml +2 -2
- data/app/helpers/cmsedit_helper.rb +84 -59
- data/app/helpers/dc_application_helper.rb +1 -1
- data/app/helpers/dc_poll_renderer.rb +3 -2
- data/app/helpers/dc_simple_menu_renderer.rb +1 -1
- data/app/views/cmsedit/_result.html.erb +6 -8
- data/app/views/layouts/models.html.erb +14 -0
- data/app/views/models/dump_models.html.erb +47 -0
- data/config/locales/drgcms_en.yml +2 -0
- data/config/locales/drgcms_sl.yml +2 -0
- data/config/locales/models_en.yml +9 -0
- data/config/locales/models_sl.yml +11 -0
- data/lib/drg_cms/version.rb +1 -1
- data/lib/tasks/browse_models.rake +128 -0
- data/lib/tasks/database.rake +1 -1
- metadata +9 -5
- data/app/views/dc_mail/subscribe.html.erb +0 -7
- data/app/views/dc_mail/unsubscribe.html.erb +0 -19
@@ -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::
|
28
|
+
module DrgcmsControls::DcPageControl
|
29
29
|
|
30
30
|
######################################################################
|
31
31
|
# Called when new empty record is created
|
data/app/forms/all_options.yml
CHANGED
@@ -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
|
data/app/forms/cms_menu.yml
CHANGED
@@ -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
|
data/app/forms/dc_site.yml
CHANGED
@@ -113,7 +113,7 @@ form:
|
|
113
113
|
60:
|
114
114
|
name: menu_name
|
115
115
|
type: text_with_select
|
116
|
-
eval: dc_choices4(
|
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:
|
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(
|
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'] ||
|
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'] =
|
262
|
+
parms['id'] = document.id
|
301
263
|
dc_link_to( nil, 'pencil lg', parms )
|
302
264
|
when yaml['type'] == 'duplicate' then
|
303
|
-
parms['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'] =
|
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'] += "#{
|
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'] =
|
284
|
+
parms['idr'] = document.id
|
323
285
|
else
|
324
|
-
parms['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
|
347
|
-
|
308
|
+
c = '<th> </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
|
-
|
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
|
-
#
|
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
|
-
|
428
|
-
|
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
|
-
|
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
|