drg_cms 0.6.0.6 → 0.6.0.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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/drg_cms/drg_cms.js +92 -36
  3. data/app/assets/stylesheets/drg_cms/drg_cms.css +141 -101
  4. data/app/assets/stylesheets/drg_cms/select-multiple.css +9 -12
  5. data/app/assets/stylesheets/drg_cms_cms.css +1 -1
  6. data/app/controllers/cmsedit_controller.rb +100 -32
  7. data/app/controllers/dc_application_controller.rb +71 -12
  8. data/app/controls/dc_report.rb +227 -0
  9. data/app/forms/all_options.yml +24 -5
  10. data/app/forms/dc_big_table.yml +1 -0
  11. data/app/forms/dc_big_table_value.yml +1 -0
  12. data/app/forms/dc_poll.yml +12 -5
  13. data/app/forms/dc_poll_item.yml +2 -1
  14. data/app/forms/dc_poll_result.yml +9 -0
  15. data/app/forms/dc_site.yml +2 -6
  16. data/app/helpers/cms_common_helper.rb +311 -0
  17. data/app/helpers/{cmsedit_edit_helper.rb → cms_edit_helper.rb} +52 -25
  18. data/app/helpers/{cmsedit_helper.rb → cms_helper.rb} +38 -31
  19. data/app/helpers/{cmsedit_index_helper.rb → cms_index_helper.rb} +152 -155
  20. data/app/helpers/dc_application_helper.rb +20 -234
  21. data/app/models/concerns/dc_site_concern.rb +12 -1
  22. data/app/models/dc_filter.rb +10 -8
  23. data/app/models/dc_permission.rb +30 -0
  24. data/app/models/dc_poll.rb +1 -0
  25. data/app/models/dc_poll_result.rb +4 -2
  26. data/app/models/dc_temp.rb +5 -2
  27. data/app/models/drgcms_form_fields.rb +12 -1
  28. data/app/models/drgcms_form_fields/date_picker.rb +4 -3
  29. data/app/models/drgcms_form_fields/datetime_picker.rb +4 -3
  30. data/app/models/drgcms_form_fields/drgcms_field.rb +18 -4
  31. data/app/models/drgcms_form_fields/embedded.rb +17 -9
  32. data/app/models/drgcms_form_fields/file_field.rb +1 -1
  33. data/app/models/drgcms_form_fields/hidden_field.rb +1 -1
  34. data/app/models/drgcms_form_fields/method.rb +65 -0
  35. data/app/models/drgcms_form_fields/multitext_autocomplete.rb +17 -11
  36. data/app/models/drgcms_form_fields/radio.rb +10 -5
  37. data/app/models/drgcms_form_fields/readonly.rb +1 -1
  38. data/app/models/drgcms_form_fields/select.rb +49 -32
  39. data/app/models/drgcms_form_fields/text_autocomplete.rb +21 -21
  40. data/app/renderers/dc_big_menu_renderer.rb +1 -0
  41. data/app/renderers/dc_gallery_renderer.rb +1 -0
  42. data/app/renderers/dc_menu_renderer.rb +1 -0
  43. data/app/renderers/dc_page_renderer.rb +1 -0
  44. data/app/renderers/dc_part_renderer.rb +1 -0
  45. data/app/renderers/dc_piece_renderer.rb +1 -1
  46. data/app/renderers/dc_poll_renderer.rb +43 -38
  47. data/app/renderers/dc_renderer.rb +1 -0
  48. data/app/renderers/dc_simple_menu_renderer.rb +1 -0
  49. data/config/locales/drgcms_en.yml +3 -2
  50. data/config/locales/drgcms_sl.yml +5 -4
  51. data/config/locales/models_en.yml +9 -2
  52. data/config/locales/models_sl.yml +10 -3
  53. data/lib/drg_cms/version.rb +1 -1
  54. data/lib/generators/new_drg_form/new_drg_form_generator.rb +5 -3
  55. data/lib/tasks/database.rake +6 -56
  56. metadata +35 -33
  57. data/app/helpers/application_helper.rb +0 -2
@@ -261,7 +261,7 @@ end
261
261
  def dc_table_title(text, result_set=nil)
262
262
  c = %Q[<div class="dc-title">#{text}]
263
263
  if result_set and result_set.respond_to?(:current_page)
264
- c << %Q[<div class="dc-paginate">#{paginate(result_set, :params => {action: 'index', clear: 'no'})}</div>]
264
+ c << %Q[<div class="dc-paginate">#{paginate(result_set, :params => {action: 'index', clear: 'no', filter: nil})}</div>]
265
265
  end
266
266
  c << '<div style="clear: both;"></div></div>'
267
267
  c.html_safe
@@ -352,7 +352,8 @@ def dc_submit_tag(caption, icon, parms, rest={})
352
352
  end
353
353
  end
354
354
  html = icon_image || ''
355
- html << submit_tag(t(caption, caption), parms)
355
+ #html << submit_tag(t(caption, caption), parms)
356
+ %Q[<button type="submit" class="dc-submit" name="commit" value="#{t(caption, caption)}">#{icon_image} #{t(caption, caption)}</button>].html_safe
356
357
  end
357
358
 
358
359
  ############################################################################
@@ -377,7 +378,7 @@ def dc_link_to(caption, icon, parms, rest={})
377
378
  if parms.class == Hash
378
379
  parms.stringify_keys!
379
380
  rest.stringify_keys!
380
- rest['class'] = rest['class'].to_s + ' dc-animate'
381
+ rest['class'] = rest['class'].to_s + ' dc-animate' unless rest['class'].to_s.match('dc-animate')
381
382
  rest['target'] ||= parms.delete('target')
382
383
  parms['controller'] ||= 'cmsedit'
383
384
  icon_pos = parms.delete('icon_pos') || 'first'
@@ -655,226 +656,6 @@ def dc_menu_class()
655
656
  dc_get_site.menu_class.classify.constantize
656
657
  end
657
658
 
658
-
659
- ####################################################################
660
- # Wrapper for i18 t method, with some spice added. If translation is not found English
661
- # translation value will be returned. And if still not found default value will be returned if passed.
662
- #
663
- # Parameters:
664
- # [key] String. String to be translated into locale.
665
- # [default] String. Value returned if translation is not found.
666
- #
667
- # Example:
668
- # t('translate.this','Enter text for ....')
669
- #
670
- # Returns:
671
- # String. Translated text.
672
- ####################################################################
673
- def t(key, default=nil)
674
- c = I18n.t(key)
675
- if c.class == Hash or c.match( 'translation missing' )
676
- c = I18n.t(key, locale: 'en')
677
- # Still not found. Return default if set
678
- if c.class == Hash or c.match( 'translation missing' )
679
- c = default.nil? ? key : default
680
- end
681
- end
682
- c
683
- end
684
-
685
- ####################################################################
686
- # Returns table (collection) name translation for usage in dialog title. Tablename
687
- # title is provided by helpers.label.table_name.tabletitle locale.
688
- #
689
- # Parameters:
690
- # [tablename] String. Table (collection) name to be translated.
691
- # [default] String. Value returned if translation is not found.
692
- #
693
- # Returns:
694
- # String. Translated text.
695
- ####################################################################
696
- def t_tablename(tablename, default=nil)
697
- t('helpers.label.' + tablename + '.tabletitle', default || tablename)
698
- end
699
-
700
- ############################################################################
701
- # Returns label for field translated to current locale for usage on data entry form.
702
- # Translation is provided by lang.helpers.label.table_name.field_name locale. If
703
- # translation is not found method will capitalize field_name and replace '_' with ' '.
704
- ############################################################################
705
- def t_name(field_name, default='')
706
- c = t("helpers.label.#{@form['table']}.#{field_name}", default)
707
- c = field_name.capitalize.gsub('_',' ') if c.match( 'translation missing' )
708
- c
709
- end
710
-
711
- ############################################################################
712
- # When select field is used on form options for select can be provided by
713
- # helpers.label.table_name.choices4_name locale. This is how select
714
- # field options are translated. Method returns selected choice translated
715
- # to current locale.
716
- #
717
- # Parameters:
718
- # [model] String. Table (collection) model name (lowercase).
719
- # [field] String. Field name used.
720
- # [value] String. Value of field which translation will be returned.
721
- #
722
- # Example:
723
- # # usage in program. Choice values for state are 'Deactivated:0,Active:1,Waiting:2'
724
- # dc_name4_value('dc_user', 'state', @record.active )
725
- #
726
- # # usage in form
727
- # columns:
728
- # 2:
729
- # name: state
730
- # eval: dc_name4_value dc_user, state
731
- #
732
- # Returns:
733
- # String. Descriptive text (translated) for selected choice value.
734
- ############################################################################
735
- def dc_name4_value(model, field, value)
736
- return '' if value.nil?
737
- c = t('helpers.label.' + model + '.choices4_' + field )
738
- a = c.chomp.split(',').inject([]) {|r,v| r << v.split(':') }
739
- a.each {|e| return e.first if e.last.to_s == value.to_s }
740
- ''
741
- end
742
-
743
- ############################################################################
744
- # Return choices for field in model if choices are defined in localization text.
745
- #
746
- # Parameters:
747
- # [model] String. Table (collection) model name (lowercase).
748
- # [field] String. Field name used.
749
- #
750
- # Example:
751
- # dc_choices4_field('dc_user', 'state' )
752
- #
753
- # Returns:
754
- # Array. Choices for select input field
755
- ############################################################################
756
- def dc_choices4_field(model, field)
757
- c = t('helpers.label.' + model + '.choices4_' + field )
758
- return ['error'] if c.match( 'translation missing' )
759
- c.chomp.split(',').inject([]) {|r,v| r << v.split(':') }
760
- end
761
-
762
- ############################################################################
763
- # Will return descriptive text for id key when field in one table (collection) has belongs_to
764
- # relation to other table.
765
- #
766
- # Parameters:
767
- # [model] String. Table (collection) model name (lowercase).
768
- # [field] String. Field name holding the value of descriptive text.
769
- # [field_name] String. ID field name. This is by default id, but can be any other
770
- # (preferred unique) field.
771
- # [value] Value of id_field. Usually a BSON Key but can be any other data type.
772
- #
773
- # Example:
774
- # # usage in program.
775
- # dc_name4_id('dc_user', 'name', nil, dc_page.created_by)
776
- #
777
- # # usage in form
778
- # columns:
779
- # 2:
780
- # name: site_id
781
- # eval: dc_name4_id,site,name
782
- # # username is saved to document instead of user.id field
783
- # 5:
784
- # name: user
785
- # eval: dc_name4_id,dc_user,name,username
786
- #
787
- # Returns:
788
- # String. Name (descriptive value) for specified key in table.
789
- ############################################################################
790
- def dc_name4_id(model, field, field_name, id=nil)
791
- return '' if id.nil?
792
- field_name = (field_name || 'id').strip.to_sym
793
- field = field.strip.to_sym
794
-
795
- model = model.strip.classify.constantize if model.class == String
796
- rec = Mongoid::QueryCache.cache { model.find_by(field_name => id) }
797
- rec.nil? ? '' : (rec.send(field) rescue 'not defined')
798
- end
799
-
800
- ############################################################################
801
- # Return html code for icon presenting boolean value. Icon is a picture of checked or unchecked box.
802
- #
803
- # Parameters:
804
- # [value] Boolean.
805
- #
806
- # Example:
807
- # # usage from program
808
- # dc_icon4_boolean(some_value)
809
- #
810
- # # usage from form description
811
- # columns:
812
- # 10:
813
- # name: active
814
- # eval: dc_icon4_boolean
815
- ############################################################################
816
- def dc_icon4_boolean(value=false)
817
- dc_dont?(value, true) ? fa_icon('square-o lg') : fa_icon('check-square-o lg')
818
- end
819
-
820
- ############################################################################
821
- # Returns html code for displaying date/time formatted by strftime. Will return '' if value is nil.
822
- #
823
- # Parameters:
824
- # [value] Date/DateTime/Time.
825
- # [format] String. strftime format mask. Defaults to locale's default format.
826
- ############################################################################
827
- def dc_format_date_time(value, format=nil)
828
- return '' if value.nil?
829
- format ||= value.class == Date ? t('date.formats.default') : t('time.formats.default')
830
- value.strftime(format)
831
- end
832
-
833
- ####################################################################
834
- #
835
- ####################################################################
836
- def dc_date_time(value, format) #:nodoc:
837
- dc_deprecate 'dc_date_time will be deprecated! Use dc_format_date_time instead.'
838
- dc_format_date_time(value, format)
839
- end
840
-
841
- ############################################################################
842
- # Returns html code for displaying formatted number.
843
- #
844
- # Parameters:
845
- # [value] Numeric number.
846
- # [decimals] Integer. Number of decimals
847
- # [separator] String. Decimals separator
848
- # [delimiter] String. Thousands delimiter.
849
- # [currency] String. Currency symbol if applied to result string.
850
- ############################################################################
851
- def dc_format_number(value=0, decimals=nil, separator=nil, delimiter=nil, currency=nil)
852
- decimals ||= I18n.t('number.currency.format.precision')
853
- separator ||= I18n.t('number.currency.format.separator')
854
- separator = '' if decimals == 0
855
- delimiter ||= I18n.t('number.currency.format.delimiter')
856
- whole, dec = value.to_s.split('.')
857
- whole = '0' if whole.blank?
858
- # remove and remember sign
859
- sign = ''
860
- if whole[0] == '-'
861
- whole.delete_prefix!('-')
862
- sign << '-'
863
- end
864
- # format decimals
865
- dec ||= '0'
866
- dec = dec[0,decimals]
867
- while dec.size < decimals do dec += '0' end
868
- # slice whole on chunks of 3
869
- ar = []
870
- while whole.size > 0 do
871
- n = whole.size >=3 ? 3 : whole.size
872
- ar << whole.slice!(n*-1,n)
873
- end
874
- # put it all back and format
875
- "#{sign}#{ar.reverse.join(delimiter)}#{separator}#{dec}"
876
- end
877
-
878
659
  ####################################################################
879
660
  # Parse site name from url and return dc_site document. Site document will be cached in
880
661
  # @site variable.
@@ -1049,9 +830,6 @@ def dc_choices4(model, name, id='_id', options = {})
1049
830
  qry = qry.in(dc_site_id: sites) if sites
1050
831
  end
1051
832
  qry = qry.and(active: true) if model.method_defined?(:active)
1052
- # qry = qry.sort(name => 1)
1053
- # choices = []
1054
- # qry.each {|v| choices << [ v[name], v[id] ] }
1055
833
  choices = qry.inject([]) {|result,e| result << [ e[name], e[id] ]}
1056
834
  choices.sort_alphabetical_by(&:first) # use UTF-8 sort
1057
835
  end
@@ -1200,7 +978,8 @@ end
1200
978
  ####################################################################
1201
979
  def dc_dont?(what, default=false)
1202
980
  return default if what.nil?
1203
- %w(0 no - false none).include?(what.to_s.downcase.strip)
981
+
982
+ %w(0 n - no none false).include?(what.to_s.downcase.strip)
1204
983
  end
1205
984
 
1206
985
  ############################################################################
@@ -1308,14 +1087,17 @@ end
1308
1087
  # This objects can be params, session, ...
1309
1088
  #
1310
1089
  # Parameters:
1311
- # [object] String: Internal object holding variable. Current values can be session, params, site, page
1090
+ # [object] String: Internal object holding variable. Current values can be session, params, site, page, class
1312
1091
  # [var_name] String[symbol]: Variable name (:user_name, 'user_id', ...)
1313
1092
  #
1314
1093
  # Example:
1315
1094
  # # called when constructing iframe for display
1316
- # dc_internal_var(session, :user_id)
1317
- # dc_internal_var(params, :some_external_parameter)
1318
- # dc_internal_var(site, :name)
1095
+ # dc_internal_var('session', :user_id)
1096
+ # dc_internal_var('params', :some_external_parameter)
1097
+ # dc_internal_var('site', :name)
1098
+ # # or even
1099
+ # dc_internal_var('class', 'ClassName.class_method_name')
1100
+ #
1319
1101
  #
1320
1102
  # Returns:
1321
1103
  # Value of variable or nil when not found
@@ -1328,8 +1110,13 @@ def dc_internal_var(object, var_name)
1328
1110
  when object == 'site' then _origin.dc_get_site.send(var_name)
1329
1111
  when object == 'page' then _origin.page.send(var_name)
1330
1112
  when object == 'record' then _origin.record.send(var_name)
1331
- else
1332
- 'VARIABLE: UNKNOWN OBJECT'
1113
+ when object == 'class' then
1114
+ clas, method_name = var_name.split('.')
1115
+ klas = clas.classify.constantize
1116
+ # call method. Error will be cought below.
1117
+ klas.send(method_name)
1118
+ else
1119
+ 'VARIABLE: UNKNOWN OBJECT'
1333
1120
  end
1334
1121
  rescue Exception => e
1335
1122
  logger.error "Method dc_internal_var. Runtime error. #{e.message}"
@@ -1337,7 +1124,6 @@ def dc_internal_var(object, var_name)
1337
1124
  end
1338
1125
  end
1339
1126
 
1340
-
1341
1127
  ########################################################################
1342
1128
  # Will return whole path to document if document is embedded in another document.
1343
1129
  #
@@ -86,7 +86,7 @@ end
86
86
  # Returns class object of menu collection name
87
87
  ########################################################################
88
88
  def menu_klass()
89
- (self.menu_class.blank? ? 'DcMenu' : self.menu_class).classify.constantize
89
+ (menu_class.blank? ? 'DcMenu' : menu_class).classify.constantize
90
90
  end
91
91
 
92
92
  ########################################################################
@@ -106,5 +106,16 @@ def self.choices4_policies
106
106
  [['a','b']]
107
107
  end
108
108
 
109
+ ########################################################################
110
+ # Return choices for selecting policies for the site
111
+ ########################################################################
112
+ def self.choices_for_menu(menu_class)
113
+ return [] if menu_class.blank?
114
+ menu = menu_class.classify.constantize
115
+ menu.where(active: true).inject([]) do |r, a_menu|
116
+ r << [a_menu.description, a_menu.id]
117
+ end
118
+ end
119
+
109
120
  end
110
121
  end
@@ -110,35 +110,37 @@ def self.get_filter_field(parent)
110
110
  return '' if parent.session[ parent.form['table'] ].nil?
111
111
  filter = parent.session[ parent.form['table'] ][:filter]
112
112
  return '' if filter.nil?
113
- #
113
+
114
114
  filter = YAML.load(filter) rescue nil
115
115
  return '' if filter.nil?
116
- #
116
+
117
117
  field = get_field_form_definition(filter['field'], parent)
118
118
  return '' if field.nil? and filter['input'].nil?
119
119
  field = {} if field.nil?
120
- # If field has choices available in labels, use them. This is most likely select input field.
120
+ # If field has choices available in labels, use them. This is most likely select input field.
121
121
  if field['name']
122
122
  choices = parent.t('helpers.label.' + parent.form['table'] + '.choices4_' + field['name'] )
123
123
  unless choices.match( 'translation missing' ) or choices.match('helpers.label')
124
124
  field['choices'] = choices
125
125
  end
126
126
  end
127
- # field redefined with input keyword. Name must start with _
127
+ # field redefined with input keyword. Name must start with _
128
128
  field['name'] = '_filter_field'
129
129
  field['type'] = filter['input'] if filter['input'].to_s.size > 5
130
130
  field['type'] ||= 'text_field'
131
131
  field['readonly'] = false # must be
132
132
  field['html'] ||= {}
133
133
  field['html']['size'] = 20
134
- # Start with last entered value
135
- field['html']['value'] = filter['value'] unless filter['value'] == '#NIL'
134
+ # Start with last entered value
135
+ field['html']['value'] = filter['value'] unless filter['value'] == '#NIL'
136
136
  field['html']['selected'] = field['html']['value'] # for select field
137
- # url for filter ON action
137
+ # url for filter ON action
138
138
  field['html']['data-url'] = parent.url_for(
139
139
  controller: 'cmsedit',action: :index, filter: 'on',
140
- table: parent.form['table'], form_name: parent.form['form_name'])
140
+ table: parent.form['table'], form_name: parent.params['form_name'])
141
141
  url = field['html']['data-url']
142
+ # remove if present
143
+ field['with_new'] = nil if field['with_new']
142
144
  # create input field object
143
145
  klas_string = field['type'].camelize
144
146
  klas = DrgcmsFormFields::const_get(klas_string) rescue nil
@@ -85,4 +85,34 @@ def self.values_for_permissions #:nodoc:
85
85
  [['NO_ACCESS',0],['CAN_VIEW',1],['CAN_CREATE',2],['CAN_EDIT',4],['CAN_EDIT_ALL',8],['CAN_DELETE',16],['CAN_DELETE_ALL',32],['CAN_ADMIN',64],['SUPERADMIN',128]]
86
86
  end
87
87
 
88
+ #############################################################################
89
+ # Will return permissions for collection
90
+ ############################################################################
91
+ def self.permissions_for_table(collection_name)
92
+ if collection_name.match(';')
93
+ collection, embedded, rest = collection_name.split(';')
94
+ else
95
+ collection, embedded = collection_name, nil
96
+ end
97
+ result = permissions_for('*')
98
+ result = permissions_for("#{collection[0,3]}*", result)
99
+ result = permissions_for(collection, result)
100
+ # include permissions for embedded documents
101
+ result = permissions_for("#{collection};#{embedded}", result) if embedded
102
+ result
103
+ end
104
+
105
+ #############################################################################
106
+ #
107
+ ############################################################################
108
+ def self.permissions_for(collection_name, result = {}) #:nodoc:
109
+ permissions = if collection_name == '*'
110
+ self.find_by(is_default: true)
111
+ else
112
+ self.find_by(table_name: collection_name, active: true)
113
+ end
114
+ permissions.dc_policy_rules.each {|perm| result[perm.dc_policy_role_id] = perm.permission } if permissions
115
+ result
116
+ end
117
+
88
118
  end
@@ -63,6 +63,7 @@ field :operation, type: String
63
63
  field :parameters, type: String
64
64
  field :display, type: String, default: '1'
65
65
  field :css, type: String
66
+ field :js, type: String
66
67
  field :form, type: String
67
68
  field :valid_from, type: DateTime
68
69
  field :valid_to, type: DateTime
@@ -29,15 +29,17 @@
29
29
  # _id BSON::ObjectId _id
30
30
  # dc_poll_id BSON::ObjectId poll id
31
31
  # data String Data saved as YAML
32
- #
32
+ # confirmed Boolean Poll entry was confirmed
33
+ #
33
34
  # Results of polls saved as YAML structure.
34
35
  ########################################################################
35
36
  class DcPollResult
36
37
  include Mongoid::Document
37
38
  include Mongoid::Timestamps
38
39
 
39
- field :data, type: String
40
40
  belongs_to :dc_poll
41
+ field :data, type: String
42
+ field :confirmed, type: Boolean, default: false
41
43
 
42
44
  index( { dc_poll_id: 1 } )
43
45