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.
- checksums.yaml +4 -4
- data/README.md +25 -10
- data/app/assets/javascripts/drg_cms/drg_cms.js +281 -106
- data/app/assets/stylesheets/drg_cms/drg_cms.css +417 -152
- data/app/assets/stylesheets/drg_cms/select-multiple.css +9 -12
- data/app/assets/stylesheets/drg_cms_cms.css +1 -1
- data/app/controllers/cmsedit_controller.rb +247 -175
- data/app/controllers/dc_application_controller.rb +251 -173
- data/app/controllers/dc_common_controller.rb +81 -48
- data/app/controls/dc_help_control.rb +126 -0
- data/app/controls/dc_report.rb +223 -0
- data/app/forms/all_options.yml +38 -10
- data/app/forms/cms_menu.yml +7 -1
- data/app/forms/dc_big_table.yml +1 -0
- data/app/forms/dc_big_table_value.yml +1 -0
- data/app/forms/dc_category.yml +2 -1
- data/app/forms/dc_design.yml +1 -0
- data/app/forms/dc_help_1.yml +109 -0
- data/app/forms/dc_journal.yml +3 -1
- data/app/forms/dc_link.yml +1 -1
- data/app/forms/dc_menu.yml +2 -0
- data/app/forms/dc_menu_item.yml +1 -0
- data/app/forms/dc_page.yml +6 -0
- data/app/forms/dc_part.yml +1 -0
- data/app/forms/dc_piece.yml +1 -0
- data/app/forms/dc_poll.yml +15 -5
- data/app/forms/dc_poll_item.yml +2 -1
- data/app/forms/dc_poll_result.yml +9 -0
- data/app/forms/dc_simple_menu.yml +2 -0
- data/app/forms/dc_site.yml +4 -12
- data/app/forms/dc_user.yml +27 -11
- data/app/forms/dc_user_role.yml +3 -0
- data/app/helpers/cms_common_helper.rb +375 -0
- data/app/helpers/{cmsedit_edit_helper.rb → cms_edit_helper.rb} +109 -65
- data/app/helpers/{cmsedit_helper.rb → cms_helper.rb} +93 -48
- data/app/helpers/{cmsedit_index_helper.rb → cms_index_helper.rb} +240 -206
- data/app/helpers/dc_application_helper.rb +108 -327
- data/app/models/concerns/dc_page_concern.rb +14 -4
- data/app/models/concerns/dc_piece_concern.rb +1 -1
- data/app/models/concerns/dc_policy_rule_concern.rb +20 -8
- data/app/models/concerns/dc_site_concern.rb +67 -44
- data/app/models/concerns/dc_user_concern.rb +58 -19
- data/app/models/dc_design.rb +29 -19
- data/app/models/dc_filter.rb +26 -18
- data/app/models/dc_key_value_store.rb +1 -0
- data/app/models/dc_permission.rb +49 -9
- data/app/models/dc_policy.rb +25 -14
- data/app/models/dc_policy_role.rb +22 -11
- data/app/models/dc_poll.rb +1 -0
- data/app/models/dc_poll_result.rb +4 -2
- data/app/models/dc_temp.rb +6 -3
- data/app/models/dc_user_role.rb +2 -2
- data/app/models/drgcms_form_fields/date_picker.rb +6 -3
- data/app/models/drgcms_form_fields/datetime_picker.rb +4 -3
- data/app/models/drgcms_form_fields/drgcms_field.rb +20 -5
- data/app/models/drgcms_form_fields/embedded.rb +23 -16
- data/app/models/drgcms_form_fields/file_field.rb +2 -2
- data/app/models/drgcms_form_fields/file_select.rb +2 -2
- data/app/models/drgcms_form_fields/hash_field.rb +11 -7
- data/app/models/drgcms_form_fields/hidden_field.rb +1 -1
- data/app/models/drgcms_form_fields/link_to.rb +2 -2
- data/app/models/drgcms_form_fields/method.rb +66 -0
- data/app/models/drgcms_form_fields/multitext_autocomplete.rb +18 -12
- data/app/models/drgcms_form_fields/number_field.rb +4 -3
- data/app/models/drgcms_form_fields/radio.rb +10 -5
- data/app/models/drgcms_form_fields/readonly.rb +13 -17
- data/app/models/drgcms_form_fields/select.rb +58 -41
- data/app/models/drgcms_form_fields/text_autocomplete.rb +41 -33
- data/app/models/drgcms_form_fields.rb +12 -1
- data/app/renderers/dc_big_menu_renderer.rb +1 -0
- data/app/renderers/dc_gallery_renderer.rb +1 -0
- data/app/renderers/dc_menu_renderer.rb +1 -0
- data/app/renderers/dc_page_renderer.rb +8 -6
- data/app/renderers/dc_part_renderer.rb +1 -0
- data/app/renderers/dc_piece_renderer.rb +1 -1
- data/app/renderers/dc_poll_renderer.rb +56 -55
- data/app/renderers/dc_renderer.rb +1 -0
- data/app/renderers/dc_simple_menu_renderer.rb +1 -0
- data/app/views/cmsedit/_edit_stuff.html.erb +5 -2
- data/app/views/cmsedit/edit.html.erb +4 -1
- data/app/views/cmsedit/index.html.erb +3 -2
- data/app/views/cmsedit/new.html.erb +5 -2
- data/app/views/dc_common/_help.html.erb +17 -0
- data/app/views/layouts/models.html.erb +2 -1
- data/config/locales/drgcms_en.yml +17 -2
- data/config/locales/drgcms_sl.yml +22 -4
- data/config/locales/models_en.yml +16 -7
- data/config/locales/models_sl.yml +21 -12
- data/drg_cms.gemspec +16 -16
- data/lib/drg_cms/version.rb +1 -1
- data/lib/drg_cms.rb +98 -0
- data/lib/generators/new_drg_form/new_drg_form_generator.rb +5 -3
- data/lib/tasks/database.rake +6 -56
- metadata +39 -35
- data/app/helpers/application_helper.rb +0 -2
- data/app/models/__dc_dummy.rb +0 -102
@@ -1,6 +1,5 @@
|
|
1
|
-
#coding: utf-8
|
2
1
|
#--
|
3
|
-
# Copyright (c) 2012
|
2
|
+
# Copyright (c) 2012+ Damjan Rems
|
4
3
|
#
|
5
4
|
# Permission is hereby granted, free of charge, to any person obtaining
|
6
5
|
# a copy of this software and associated documentation files (the
|
@@ -46,28 +45,29 @@ layout false
|
|
46
45
|
########################################################################
|
47
46
|
def autocomplete
|
48
47
|
# table parameter must be defined. If not, get it from search parameter
|
49
|
-
if params['table'].nil?
|
48
|
+
if params['table'].nil? && params['search'].match(/\./)
|
50
49
|
name = params['search'].split('.').first
|
51
50
|
params['table'] = name.underscore
|
52
51
|
end
|
53
|
-
|
54
52
|
return render plain: t('drgcms.not_authorized') unless dc_user_can(DcPermission::CAN_VIEW)
|
55
|
-
|
53
|
+
|
56
54
|
table = params['table'].classify.constantize
|
57
|
-
|
58
|
-
# call method in class if search parameter
|
59
|
-
# result must be returned as array of [id, search_field_value]
|
55
|
+
input = params['input'].gsub(/\(|\)|\[|\]|\{|\|\.|\,}/, '')
|
56
|
+
# call method in class if search parameter contains . This is for user defined searches
|
60
57
|
a = if params['search'].match(/\./)
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
58
|
+
#method, additional_params = params['search'].split('.')
|
59
|
+
#data = additional_params ? table.send(method, input, additional_params, self) : table.send(method, input)
|
60
|
+
name, method = params['search'].split('.')
|
61
|
+
data = table.send(method, input)
|
62
|
+
data.map do |v|
|
63
|
+
{ label: v[0], value: v[0], id: (v[1] || v[0]).to_s }
|
64
|
+
end
|
65
|
+
# will search and return field_name defined in params['search']
|
66
|
+
else
|
67
|
+
table.where(params['search'] => /#{input}/i).limit(20).map do |v|
|
68
|
+
{ label: v[params['search']], value: v[params['search']], id: v.id.to_s }
|
69
|
+
end
|
70
|
+
end
|
71
71
|
|
72
72
|
render plain: a.to_json
|
73
73
|
end
|
@@ -93,18 +93,19 @@ end
|
|
93
93
|
##########################################################################
|
94
94
|
def toggle_edit_mode
|
95
95
|
session[:edit_mode] ||= 0
|
96
|
-
# error when not logged in
|
97
|
-
return dc_render_404 if session[:edit_mode] < 1
|
98
|
-
|
99
|
-
#
|
96
|
+
# error when not logged in
|
97
|
+
return dc_render_404 if session[:edit_mode] < 1
|
98
|
+
|
99
|
+
# if return_to_ypos parameter is present it will forward it and thus scroll to
|
100
|
+
# aproximate position it was when toggle was clicked
|
100
101
|
session[:edit_mode] = (session[:edit_mode] == 1) ? 2 : 1
|
101
102
|
uri = Rack::Utils.parse_nested_query(request.url)
|
102
|
-
# it parses only on & so first (return_to) parameter also contains url
|
103
|
+
# it parses only on & so first (return_to) parameter also contains url
|
103
104
|
url = uri.first.last
|
104
105
|
if (i = url.index('return_to_ypos')).to_i > 0
|
105
|
-
url = url[0,i-1]
|
106
|
+
url = url[0, i-1]
|
106
107
|
end
|
107
|
-
# offset CMS menu
|
108
|
+
# offset CMS menu
|
108
109
|
if (ypos = uri['return_to_ypos'].to_i) > 0
|
109
110
|
ypos += session[:edit_mode] == 2 ? 250 : -250
|
110
111
|
end
|
@@ -117,14 +118,16 @@ end
|
|
117
118
|
# Default user login action.
|
118
119
|
####################################################################
|
119
120
|
def process_login
|
120
|
-
# Somebody is probably playing
|
121
|
-
return dc_render_404 unless ( params[:record]
|
121
|
+
# Somebody is probably playing
|
122
|
+
return dc_render_404 unless ( params[:record] && params[:record][:username] && params[:record][:password] )
|
122
123
|
|
123
124
|
unless params[:record][:password].blank? #password must not be empty
|
124
125
|
user = DcUser.find_by(username: params[:record][:username], active: true)
|
125
126
|
if user and user.authenticate(params[:record][:password])
|
126
127
|
fill_login_data(user, params[:record][:remember_me].to_i == 1)
|
127
128
|
return redirect_to params[:return_to] || '/'
|
129
|
+
else
|
130
|
+
clear_login_data # on the safe side
|
128
131
|
end
|
129
132
|
end
|
130
133
|
flash[:error] = t('drgcms.invalid_username')
|
@@ -149,12 +152,11 @@ def login
|
|
149
152
|
if user and user.active
|
150
153
|
fill_login_data(user, true)
|
151
154
|
return redirect_to params[:return_to]
|
152
|
-
|
153
155
|
else
|
154
156
|
clear_login_data # on the safe side
|
155
157
|
end
|
156
158
|
end
|
157
|
-
# Display login
|
159
|
+
# Display login
|
158
160
|
route = params[:route] || 'poll'
|
159
161
|
redirect_to "/#{route}?poll_id=login&return_to=#{params[:return_to]}"
|
160
162
|
end
|
@@ -163,23 +165,23 @@ end
|
|
163
165
|
# Action for restoring document data from journal document.
|
164
166
|
####################################################################
|
165
167
|
def restore_from_journal
|
166
|
-
# Only administrators can perform this operation
|
168
|
+
# Only administrators can perform this operation
|
167
169
|
unless dc_user_has_role('admin')
|
168
170
|
return render plain: { 'msg_info' => (t ('drgcms.not_authorized')) }.to_json
|
169
171
|
end
|
170
|
-
# selected fields to hash
|
172
|
+
# selected fields to hash
|
171
173
|
restore = {}
|
172
|
-
params[:select].each {|key,value| restore[key] = value if value == '1' }
|
174
|
+
params[:select].each { |key,value| restore[key] = value if value == '1' }
|
173
175
|
result = if restore.size == 0
|
174
176
|
{ 'msg_error' => (t ('drgcms.dc_journal.zero_selected')) }
|
175
177
|
else
|
176
178
|
journal_doc = DcJournal.find(params[:id])
|
177
|
-
# update hash with data to be restored
|
179
|
+
# update hash with data to be restored
|
178
180
|
JSON.parse(journal_doc.diff).each {|k,v| restore[k] = v.first if restore[k] }
|
179
|
-
# determine tables and document ids
|
181
|
+
# determine tables and document ids
|
180
182
|
tables = journal_doc.tables.split(';')
|
181
183
|
ids = (journal_doc.ids.blank? ? [] : journal_doc.ids.split(';') ) << journal_doc.doc_id
|
182
|
-
# find document
|
184
|
+
# find document
|
183
185
|
doc = nil
|
184
186
|
tables.each_index do |i|
|
185
187
|
doc = if doc.nil?
|
@@ -188,10 +190,10 @@ def restore_from_journal
|
|
188
190
|
doc.send(tables[i].pluralize).find(ids[i])
|
189
191
|
end
|
190
192
|
end
|
191
|
-
# restore and save values
|
193
|
+
# restore and save values
|
192
194
|
restore.each { |field,value| doc.send("#{field}=",value) }
|
193
195
|
doc.save
|
194
|
-
# TODO Error checking
|
196
|
+
# TODO Error checking
|
195
197
|
{ 'msg_info' => (t ('drgcms.dc_journal.restored')) }
|
196
198
|
end
|
197
199
|
render plain: result.to_json
|
@@ -202,10 +204,11 @@ end
|
|
202
204
|
# window with data formatted as json.
|
203
205
|
########################################################################
|
204
206
|
def copy_clipboard
|
205
|
-
# Only administrators can perform this operation
|
207
|
+
# Only administrators can perform this operation
|
206
208
|
return render(plain: t('drgcms.not_authorized') ) unless dc_user_can(DcPermission::CAN_ADMIN,'dc_site')
|
209
|
+
|
207
210
|
respond_to do |format|
|
208
|
-
# just open new window to same url and come back with html request
|
211
|
+
# just open new window to same url and come back with html request
|
209
212
|
format.json { dc_render_ajax(operation: 'window', url: request.url ) }
|
210
213
|
|
211
214
|
format.html do
|
@@ -213,7 +216,6 @@ def copy_clipboard
|
|
213
216
|
text = "<br><br>[#{params[:table]},#{params[:id]},#{params[:ids]}]<br>"
|
214
217
|
render plain: text + doc.as_document.to_json
|
215
218
|
end
|
216
|
-
|
217
219
|
end
|
218
220
|
end
|
219
221
|
|
@@ -223,17 +225,19 @@ end
|
|
223
225
|
# ajax call for processing data.
|
224
226
|
########################################################################
|
225
227
|
def paste_clipboard
|
226
|
-
# Only administrators can perform this operation
|
228
|
+
# Only administrators can perform this operation
|
227
229
|
return render(plain: t('drgcms.not_authorized') ) unless dc_user_can(DcPermission::CAN_ADMIN,'dc_site')
|
230
|
+
|
228
231
|
result = ''
|
229
232
|
respond_to do |format|
|
230
|
-
# just open new window to same url and come back with html request
|
233
|
+
# just open new window to same url and come back with html request
|
231
234
|
format.html { return render('paste_clipboard', layout: 'cms') }
|
232
235
|
format.json {
|
233
236
|
table, id, ids = nil
|
234
237
|
params[:data].split("\n").each do |line|
|
235
238
|
line.chomp!
|
236
239
|
next if line.size < 5 # empty line. Skip
|
240
|
+
|
237
241
|
begin
|
238
242
|
if line[0] == '[' # id(s)
|
239
243
|
result << "<br>#{line}"
|
@@ -260,7 +264,7 @@ def add_json_ld_schema
|
|
260
264
|
edited_document = DcJsonLd.find_document_by_ids(params[:table], params[:ids])
|
261
265
|
yaml = YAML.load_file( dc_find_form_file('json_ld_schema') )
|
262
266
|
schema_data = yaml[params[:schema]]
|
263
|
-
# Existing document
|
267
|
+
# Existing document
|
264
268
|
if edited_document.dc_json_lds.find_by(type: "@#{params[:schema]}")
|
265
269
|
return render json: {'msg_error' => t('helpers.help.dc_json_ld.add_error', schema: params[:schema] ) }
|
266
270
|
else
|
@@ -269,8 +273,37 @@ def add_json_ld_schema
|
|
269
273
|
render json: {'reload_' => 1}
|
270
274
|
end
|
271
275
|
|
276
|
+
########################################################################
|
277
|
+
# Will provide help data
|
278
|
+
########################################################################
|
279
|
+
def help
|
280
|
+
form_name = params[:form_name] || params[:table]
|
281
|
+
@form = form_name ? YAML.load_file(dc_find_form_file(form_name)) : {}
|
282
|
+
return render json: {} if @form.nil?
|
283
|
+
|
284
|
+
help_file_name = @form['help'] || @form['extend'] || params[:form_name] || params[:table]
|
285
|
+
help_file_name = find_help_file(help_file_name)
|
286
|
+
@help = YAML.load_file(help_file_name) if help_file_name
|
287
|
+
# no auto generated help on index action
|
288
|
+
return render json: {} if params[:type] == 'index' && @help.nil?
|
289
|
+
|
290
|
+
render json: { popup: render_to_string(partial: 'help') }
|
291
|
+
end
|
292
|
+
|
272
293
|
protected
|
273
294
|
|
295
|
+
########################################################################
|
296
|
+
# Will search for help file and return it's path if found
|
297
|
+
########################################################################
|
298
|
+
def find_help_file(help_file_name)
|
299
|
+
file_name = nil
|
300
|
+
DrgCms.paths(:forms).reverse.each do |path|
|
301
|
+
f = "#{path}/help/#{help_file_name}.#{I18n.locale}"
|
302
|
+
file_name = f and break if File.exist?(f)
|
303
|
+
end
|
304
|
+
file_name
|
305
|
+
end
|
306
|
+
|
274
307
|
########################################################################
|
275
308
|
# Subroutine of add_json_ld_schema for adding one element
|
276
309
|
########################################################################
|
@@ -308,7 +341,7 @@ def update_json(json, is_update=false) #:nodoc:
|
|
308
341
|
json.each do |k,v|
|
309
342
|
if v.class == Hash
|
310
343
|
result[k] = v['$oid'] unless is_update
|
311
|
-
#TODO Double check if unless works as expected
|
344
|
+
# TODO Double check if unless works as expected
|
312
345
|
elsif v.class == Array
|
313
346
|
result[k] = []
|
314
347
|
v.each {|e| result[k] << update_json(e, is_update)}
|
@@ -325,22 +358,22 @@ end
|
|
325
358
|
def process_document(line, table, id, ids)
|
326
359
|
if params[:do_update] == '1'
|
327
360
|
doc = dc_find_document(table, id, ids)
|
328
|
-
# document found. Update it and return
|
361
|
+
# document found. Update it and return
|
329
362
|
if doc
|
330
363
|
doc.update( update_json(ActiveSupport::JSON.decode(line), true) )
|
331
364
|
msg = dc_check_model(doc)
|
332
365
|
return (msg ? " ERROR! #{msg}" : " UPDATE. OK.")
|
333
366
|
end
|
334
367
|
end
|
335
|
-
# document will be added to collection
|
368
|
+
# document will be added to collection
|
336
369
|
if ids.to_s.size > 5
|
337
|
-
#TODO Add embedded document
|
370
|
+
#TODO Add embedded document
|
338
371
|
" NOT SUPPORTED YET!"
|
339
372
|
else
|
340
373
|
doc = table.classify.constantize.new( update_json(ActiveSupport::JSON.decode(line)) )
|
341
374
|
doc.save
|
342
375
|
end
|
343
|
-
msg =
|
376
|
+
msg = DrgCms.model_check(doc)
|
344
377
|
msg ? " ERROR! #{msg}" : " NEW. OK."
|
345
378
|
end
|
346
379
|
|
@@ -0,0 +1,126 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2021+ Damjan Rems
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
######################################################################
|
25
|
+
# Controls for creating help files
|
26
|
+
######################################################################
|
27
|
+
module DcHelpControl
|
28
|
+
|
29
|
+
######################################################################
|
30
|
+
# Will fill dc_temp with help documents found in a defined project directory.
|
31
|
+
######################################################################
|
32
|
+
def project_refresh
|
33
|
+
DcTemp.clear(temp_key)
|
34
|
+
if params[:record][:select_project].present?
|
35
|
+
# far less complicated if saved to session
|
36
|
+
session[:help_project] = params[:record][:select_project]
|
37
|
+
session[:help_lang] = params[:record][:lang_1]
|
38
|
+
help_dir_name = "#{session[:help_project]}/help/"
|
39
|
+
# create help directory if not yet exists
|
40
|
+
FileUtils.mkdir(help_dir_name) unless File.exist?(help_dir_name)
|
41
|
+
Dir["#{help_dir_name}*"].each do |file_name|
|
42
|
+
lang = File.extname(file_name).sub('.','')
|
43
|
+
next unless lang == session[:help_lang]
|
44
|
+
|
45
|
+
DcTemp.new(key: temp_key,
|
46
|
+
project: session[:help_project],
|
47
|
+
form_name: File.basename(file_name,'.*'),
|
48
|
+
lang: lang,
|
49
|
+
updated_at: File.mtime(file_name)).save
|
50
|
+
end
|
51
|
+
end
|
52
|
+
render json: { url: url_for(controller: :cmsedit, table: :dc_temp, form_name: :dc_help_1) }
|
53
|
+
end
|
54
|
+
|
55
|
+
######################################################################
|
56
|
+
# Will populate fields with default values
|
57
|
+
######################################################################
|
58
|
+
def dc_new_record
|
59
|
+
@record.project = session[:help_project]
|
60
|
+
@record.lang = session[:help_lang]
|
61
|
+
end
|
62
|
+
|
63
|
+
######################################################################
|
64
|
+
# Will read data from help file
|
65
|
+
######################################################################
|
66
|
+
def dc_before_edit
|
67
|
+
file_name = "#{session[:help_project]}/help/#{@record.form_name}.#{session[:help_lang]}"
|
68
|
+
data = YAML.load_file(file_name)
|
69
|
+
@record.index = data['index']
|
70
|
+
@record.form = data['form']
|
71
|
+
flash[:warning] = "Use only in development!" unless Rails.env.development?
|
72
|
+
end
|
73
|
+
|
74
|
+
######################################################################
|
75
|
+
# Will save data to help file
|
76
|
+
######################################################################
|
77
|
+
def dc_before_save
|
78
|
+
rec = params[:record]
|
79
|
+
file_name = "#{session[:help_project]}/help/#{@record.form_name}.#{@record.lang}"
|
80
|
+
data = { 'index' => @record.index, 'form' => @record.form }
|
81
|
+
File.write(file_name, data.to_yaml)
|
82
|
+
end
|
83
|
+
|
84
|
+
######################################################################
|
85
|
+
# Will return query to report data
|
86
|
+
######################################################################
|
87
|
+
def data_filter
|
88
|
+
DcTemp.where(key: temp_key).order_by(order: 1)
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
######################################################################
|
94
|
+
# Will return choices for select project input field on a form
|
95
|
+
######################################################################
|
96
|
+
def self.choices_for_project
|
97
|
+
r = DrgCms.paths(:forms).map do |path|
|
98
|
+
path = path.to_s
|
99
|
+
a = path.split('/')
|
100
|
+
project = a[a.size - 3]
|
101
|
+
project = if project == 'app'
|
102
|
+
a[a.size - 4] + ' : ' + a.last(2).join('/')
|
103
|
+
else
|
104
|
+
project + ' : ' + a.last
|
105
|
+
end
|
106
|
+
[project, path]
|
107
|
+
end
|
108
|
+
[[I18n.t('drgcms.dc_help.project'), nil]] + r.sort
|
109
|
+
end
|
110
|
+
|
111
|
+
######################################################################
|
112
|
+
# Will return choices for selecting help file name, based on forms already
|
113
|
+
# present in forms directory.
|
114
|
+
######################################################################
|
115
|
+
def self.choices_for_form_name(session)
|
116
|
+
Dir["#{session[:help_project]}/*.yml"].map { |file_name| File.basename(file_name,'.*') }.sort
|
117
|
+
end
|
118
|
+
|
119
|
+
######################################################################
|
120
|
+
# Will return temp key for data saved in dc_temp file
|
121
|
+
######################################################################
|
122
|
+
def temp_key
|
123
|
+
"dc-help-#{session[:user_id]}"
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2020+ Damjan Rems
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
######################################################################
|
25
|
+
# Common methods required by reports
|
26
|
+
######################################################################
|
27
|
+
module DcReport
|
28
|
+
attr_accessor :report_id
|
29
|
+
attr_accessor :bulk
|
30
|
+
|
31
|
+
######################################################################
|
32
|
+
# Clear result if params[:clear] is 'yes' when form is first displayed
|
33
|
+
######################################################################
|
34
|
+
def dc_new_record
|
35
|
+
DcTemp.clear(temp_key) unless params[:clear].to_s == 'no'
|
36
|
+
end
|
37
|
+
|
38
|
+
######################################################################
|
39
|
+
# If exists, set report section as form, so it can be used to display result.
|
40
|
+
######################################################################
|
41
|
+
def dc_update_form
|
42
|
+
return unless @form && @form['report'] && params[:table] == 'dc_temp'
|
43
|
+
|
44
|
+
@form = @form['report']
|
45
|
+
end
|
46
|
+
|
47
|
+
######################################################################
|
48
|
+
# Print to PDF action
|
49
|
+
######################################################################
|
50
|
+
def print
|
51
|
+
begin
|
52
|
+
pdf_do
|
53
|
+
rescue Exception => e
|
54
|
+
dc_dump_exception(e)
|
55
|
+
render json: { msg_error: t('drgcms.runtime_error') } and return
|
56
|
+
end
|
57
|
+
|
58
|
+
pdf_file = "tmp/dokument-#{Time.now.to_i}.pdf"
|
59
|
+
@pdf.render_file Rails.root.join('public', pdf_file)
|
60
|
+
|
61
|
+
render json: print_response(pdf_file)
|
62
|
+
end
|
63
|
+
|
64
|
+
######################################################################
|
65
|
+
# Export data do excel action
|
66
|
+
######################################################################
|
67
|
+
def export
|
68
|
+
export_to_excel( temp_key )
|
69
|
+
end
|
70
|
+
|
71
|
+
######################################################################
|
72
|
+
# Default filter to select data for result.
|
73
|
+
######################################################################
|
74
|
+
def data_filter
|
75
|
+
params['clear'].to_s == 'yes' ? DcTemp.where(key: false) : DcTemp.where(key: temp_key).order_by(order: 1)
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
######################################################################
|
81
|
+
# Will create response message for print action. Response consists of
|
82
|
+
# opening pdf file in new browser tab and additional print_message if defined.
|
83
|
+
######################################################################
|
84
|
+
def print_response(pdf_file)
|
85
|
+
response = { window: "/#{pdf_file}" }
|
86
|
+
response.merge!(report_message) if respond_to?(:report_message, true)
|
87
|
+
response
|
88
|
+
end
|
89
|
+
|
90
|
+
######################################################################
|
91
|
+
# Temp key consists of report name and user's id. Key should be added
|
92
|
+
# to every dc_temp document and is used to define data, which belongs
|
93
|
+
# to current user.
|
94
|
+
######################################################################
|
95
|
+
def temp_key
|
96
|
+
"#{@report_id}-#{session[:user_id]}"
|
97
|
+
end
|
98
|
+
|
99
|
+
######################################################################
|
100
|
+
# Initialize report. Set report_id internal variable and initialize bulk
|
101
|
+
# for bulk saving data to dc_temp collection.
|
102
|
+
######################################################################
|
103
|
+
def init_report(id)
|
104
|
+
@report_id = id
|
105
|
+
@bulk = []
|
106
|
+
end
|
107
|
+
|
108
|
+
######################################################################
|
109
|
+
# Check if all send fields are blank.
|
110
|
+
######################################################################
|
111
|
+
def all_blank?(*fields)
|
112
|
+
fields.each {|e| e.blank? ? true : (break false) }
|
113
|
+
end
|
114
|
+
|
115
|
+
######################################################################
|
116
|
+
# Will write bulk data to dc_temp collection.
|
117
|
+
######################################################################
|
118
|
+
def bulk_write(doc, the_end = false)
|
119
|
+
if doc.nil? || doc.class == TrueClass
|
120
|
+
the_end = true
|
121
|
+
else
|
122
|
+
@bulk << doc
|
123
|
+
end
|
124
|
+
|
125
|
+
if (the_end && @bulk.size > 0) || @bulk.size > 100
|
126
|
+
DcTemp.collection.insert_many(@bulk)
|
127
|
+
@bulk = []
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
######################################################################
|
132
|
+
# Export data to Excel
|
133
|
+
######################################################################
|
134
|
+
def export_to_excel(report_id)
|
135
|
+
read_drg_form if @form.blank?
|
136
|
+
# use report options if present
|
137
|
+
columns = (@form['report'] ? @form['report'] : @form)['result_set']['columns'].sort
|
138
|
+
|
139
|
+
n, workbook = 0, Spreadsheet::Workbook.new
|
140
|
+
excel = workbook.create_worksheet(name: report_id)
|
141
|
+
# header
|
142
|
+
columns.each_with_index do |column, i|
|
143
|
+
caption = column.last['caption'] || column.last['label']
|
144
|
+
label = t(caption)
|
145
|
+
excel[n, i] = label.match('translation missing') ? caption : label
|
146
|
+
end
|
147
|
+
|
148
|
+
data_filter.each do |doc|
|
149
|
+
n += 1
|
150
|
+
columns.each_with_index do |column, i|
|
151
|
+
value = doc[column.last['name']].to_s.gsub('<br>', ";")
|
152
|
+
value = value.gsub(/\<\/strong\>|\<strong\>|\<\/b\>|\<b\>/, '')
|
153
|
+
excel[n, i] = value
|
154
|
+
end
|
155
|
+
end
|
156
|
+
file_name = "#{report_id}-#{Time.now.to_i}.xls"
|
157
|
+
workbook.write Rails.root.join('public', 'tmp', file_name)
|
158
|
+
dc_render_ajax(operation: :window, value: "/tmp/#{file_name}")
|
159
|
+
end
|
160
|
+
|
161
|
+
############################################################################
|
162
|
+
# Returns html code for displaying date/time formatted by strftime. Will return '' if value is nil.
|
163
|
+
#
|
164
|
+
# Parameters:
|
165
|
+
# [value] Date/DateTime/Time.
|
166
|
+
# [format] String. strftime format mask. Defaults to locale's default format.
|
167
|
+
############################################################################
|
168
|
+
def dc_format_date_time(value, format = nil)
|
169
|
+
return '' if value.nil?
|
170
|
+
|
171
|
+
format ||= value.class == Date ? t('date.formats.default') : t('time.formats.default')
|
172
|
+
value.strftime(format)
|
173
|
+
end
|
174
|
+
|
175
|
+
##############################################################################
|
176
|
+
# Initialize PDF document for print
|
177
|
+
##############################################################################
|
178
|
+
def pdf_init(opts={})
|
179
|
+
opts[:margin] ||= [30,30,30,30]
|
180
|
+
opts[:page_size] ||= 'A4'
|
181
|
+
|
182
|
+
pdf = Prawn::Document.new(opts)
|
183
|
+
pdf.font_size = opts[:font_size] if opts[:font_size]
|
184
|
+
|
185
|
+
pdf.encrypt_document( owner_password: :random,
|
186
|
+
permissions: { print_document: true,
|
187
|
+
modify_contents: false,
|
188
|
+
copy_contents: false,
|
189
|
+
modify_annotations: false })
|
190
|
+
pdf.font_families.update(
|
191
|
+
'Arial' => { normal: Rails.root.join('public', 'arial.ttf'),
|
192
|
+
bold: Rails.root.join('public', 'arialbd.ttf') }
|
193
|
+
)
|
194
|
+
pdf.font 'Arial'
|
195
|
+
pdf
|
196
|
+
end
|
197
|
+
|
198
|
+
################################################################################
|
199
|
+
# Prints out single text (or object) on report.
|
200
|
+
#
|
201
|
+
# @param [Object] txt : Text or object. Result of to_s method of the object is
|
202
|
+
# @param [Hash] opts
|
203
|
+
###############################################################################
|
204
|
+
def pdf_text(txt, opts = {})
|
205
|
+
box_opts = opts.dup
|
206
|
+
ypos = @pdf.cursor
|
207
|
+
xpos = opts.delete(:atx) || 0
|
208
|
+
box_opts[:single_line] ||= true
|
209
|
+
box_opts[:at] ||= [xpos, ypos]
|
210
|
+
|
211
|
+
@pdf.text_box(txt.to_s, box_opts)
|
212
|
+
end
|
213
|
+
|
214
|
+
################################################################################
|
215
|
+
# Skip line on report
|
216
|
+
#
|
217
|
+
# @param [Integer] skip . Number of lines to skip. Default 1.
|
218
|
+
###############################################################################
|
219
|
+
def pdf_skip(skip = 1)
|
220
|
+
@pdf.text('<br>' * skip, inline_format: true)
|
221
|
+
end
|
222
|
+
|
223
|
+
end
|