drg_cms 0.5.52.9 → 0.5.52.12

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 40fa56fbdb21a8a10e26ebeefc4f9ebf1a0a41d3
4
- data.tar.gz: f3c627f7e59044e1826d120174b91c06d7d0ee25
3
+ metadata.gz: 637c9ceaf9353fced28bc05ec02a3ad516d91f54
4
+ data.tar.gz: 949139ee0f5a5351741e94d74d5e7e1502426946
5
5
  SHA512:
6
- metadata.gz: 377369ee96b9fa738a115e607d3e187ab5a1bb951ea767add202be5cc3e3d1ef9f83f39a03ce8411c8c3fc86889c7d250e4f22c2ee51448b90b1ecc0492b0942
7
- data.tar.gz: 2db3772bf7c84abf8a316eb3519f74e86b0d2a2925214f6e8a2a328f2b683ef6fa67df3d56cc4363d2481c7de9e77b030d2481c49ebe720e28a7d43623052f7e
6
+ metadata.gz: c67a0b1046125b1408fa8604b88d5b9993d29832fbe6daac9d829b4f6c2bb7537049da1636eefd5f5d3aaebdc84e3ef0ed5f9dd9abb56d039a857b509367573c
7
+ data.tar.gz: 44e2b256013e943de0edb9e96a947e4deebca64a24686809b2b70ed4d1d9edb827aafb0a300473dbfde0888f6044108150eeb84517ca822529f4b69773083499
@@ -51,6 +51,38 @@ remove_background_from_iframe = function(obj) {
51
51
  '</style>';
52
52
  $(head).append(css);
53
53
  };
54
+
55
+ format_number_field = function(e) {
56
+ var decimals = e.attr("data-decimal") || 2;
57
+ var delimiter = e.attr("data-delimiter") || '.';
58
+ var separator = e.attr("data-separator") || ',';
59
+ var currency = e.attr("data-currency") || '';
60
+ var whole = e.val().split(separator)[0];
61
+ var dec = e.val().split(separator)[1];
62
+ // save value to hidden field which will be used for return
63
+ var field = '#' + e.attr("id").slice(0,-1);
64
+ var value = e.val().replace(delimiter,'.');
65
+
66
+ $(field).val( parseFloat(value).toFixed(decimals) );
67
+
68
+ // decimal part
69
+ if (dec == null) dec = '';
70
+ dec = dec.substring(0, decimals, dec);
71
+ while (dec.length < decimals) dec = dec + '0';
72
+ // whole part
73
+ if (whole == null || whole == '') whole = '0';
74
+ var ar = [];
75
+
76
+ while (whole.length > 0) {
77
+ var pos1 = whole.length - 3
78
+ if (pos1 < 0) pos1 = 0;
79
+ ar.unshift(whole.substr(pos1,3));
80
+ whole = whole.slice(0, -3);
81
+ };
82
+
83
+ if (delimiter !== '') whole = ar.join(delimiter);
84
+ e.val(whole + separator + dec + currency);
85
+ };
54
86
 
55
87
  /*******************************************************************
56
88
  * Activate jquery UI tooltip. This needs jquery.ui >= 1.9
@@ -80,6 +112,8 @@ $(function() {
80
112
  * msg_warn: will display warning message.
81
113
  * msg_info: will display informational message.
82
114
  *
115
+ * popup: will display popup message
116
+ *
83
117
  * #div_divname : will replace divname with value
84
118
  * #div+_divname : will append value to divname
85
119
  * #+div_divname : will prepend value to divname
@@ -126,6 +160,11 @@ process_json_result = function(json) {
126
160
  $('.'+selector).html(val);
127
161
  }
128
162
  break;
163
+ // display popup message
164
+ case 'popup':
165
+ $('#popup').html(val);
166
+ $('#popup').bPopup({ speed: 650, transition: 'slideDown' });
167
+
129
168
  // update div
130
169
  case '#div+':
131
170
  $('#'+what).append(val);
@@ -306,9 +345,14 @@ $(document).ready( function() {
306
345
  * Process Ajax call on cmsedit form actions
307
346
  *******************************************************************/
308
347
  $('.dc-link-ajax').on('click', function(e) {
348
+ // check HTML5 validations
349
+ if (!$("form")[0].checkValidity() ) {
350
+ $("form")[0].reportValidity();
351
+ return false;
352
+ }
309
353
  var target = e.target;
310
354
  var req = target.getAttribute("data-request");
311
- /* Get some values from elements on the page: */
355
+ // Get values from elements on the page:
312
356
  if (req == "script") {
313
357
  eval (target.getAttribute("data-script"));
314
358
  return false;
@@ -625,8 +669,84 @@ element = $(this).find(':first').attr('id');
625
669
  .mouseleave(function() {
626
670
  console.log("leave");
627
671
  });
628
-
629
672
 
673
+ /*******************************************************************
674
+ * number_field type entered
675
+ *******************************************************************/
676
+ $('.dc-number').on('focus', function(e) {
677
+ var separator = $(this).attr("data-separator") || ',';
678
+ var field = '#' + $(this).attr("id").slice(0,-1);
679
+ var value = $(field).val().replace('.',separator);
680
+ $(this).val( value );
681
+ $(this).select();
682
+ });
683
+
684
+ /*******************************************************************
685
+ * number_field type leaved
686
+ *******************************************************************/
687
+ $('.dc-number').on('focusout', function(e) {
688
+ // format_number_field($(this));
689
+
690
+ var decimals = $(this).attr("data-decimal") || 2;
691
+ var delimiter = $(this).attr("data-delimiter") || '.';
692
+ var separator = $(this).attr("data-separator") || ',';
693
+ var currency = $(this).attr("data-currency") || '';
694
+ var whole = this.value.split(separator)[0];
695
+ var dec = this.value.split(separator)[1];
696
+ // save value to hidden field which will be used for return
697
+ var field = '#' + $(this).attr("id").slice(0,-1);
698
+ var value = this.value.replace(separator,'.');
699
+ // remove negative sign and add at the end
700
+ var sign = whole.substr(0,1);
701
+ if (sign == '-') {
702
+ whole = whole.substr(1,20);
703
+ } else {
704
+ sign = '';
705
+ }
706
+
707
+ $(field).val( parseFloat(value).toFixed(decimals) );
708
+
709
+ // decimal part
710
+ if (dec == null) dec = '';
711
+ dec = dec.substring(0, decimals, dec);
712
+ while (dec.length < decimals) dec = dec + '0';
713
+ // whole part
714
+ if (whole == null || whole == '') whole = '0';
715
+ var ar = [];
716
+ while (whole.length > 0) {
717
+ var pos1 = whole.length - 3
718
+ if (pos1 < 0) pos1 = 0;
719
+ ar.unshift(whole.substr(pos1,3));
720
+ whole = whole.slice(0, -3);
721
+ };
722
+
723
+ if (delimiter !== '') whole = ar.join(delimiter);
724
+ $(this).val(sign + whole + separator + dec + currency);
725
+ });
726
+
727
+ /*******************************************************************
728
+ * number_field type keypressed
729
+ *******************************************************************/
730
+ $('.dc-number').on('keydown', function(e) {
731
+ // Minus sign. Put it on first place
732
+ if (e.which == 109) {
733
+ if($(this).val().substr(0,1) == '-') {
734
+ $(this).val( $(this).val().substr(1,20));
735
+ } else {
736
+ $(this).val( '-' + $(this).val());
737
+ }
738
+ e.preventDefault();
739
+ }
740
+ // Enter. Save value before Enter is processed
741
+ if (e.which == 13) {
742
+ var delimiter = $(this).attr("data-delimiter") || '.';
743
+ var decimals = $(this).attr("data-decimal") || 2;
744
+ var value = $(this).val().replace(delimiter,'.');
745
+ var field = '#' + $(this).attr("id").slice(0,-1);
746
+
747
+ $(field).val( parseFloat(value).toFixed(decimals) );
748
+ }
749
+ });
630
750
  });
631
751
 
632
752
  /*******************************************************************
@@ -8,4 +8,5 @@
8
8
  //= require drg_cms/jquery-migrate
9
9
  //= require jquery_ujs
10
10
  //= require drg_cms/drg_cms
11
+ //= require drg_cms/jquery.bpopup.min
11
12
  //= #require_tree .
@@ -557,6 +557,10 @@ border: 1px solid #ddd;
557
557
  */
558
558
  }
559
559
 
560
+ .dc-number {
561
+ text-align: right;
562
+ }
563
+
560
564
  .dc-readonly {
561
565
  display: inline-block;
562
566
  font-size: 14px;
@@ -28,7 +28,7 @@
28
28
  -ms-transition: border linear 0.2s, box-shadow linear 0.2s;
29
29
  -o-transition: border linear 0.2s, box-shadow linear 0.2s;
30
30
  transition: border linear 0.2s, box-shadow linear 0.2s;
31
- border: 1px solid #ccc;
31
+ border: 2px solid #ddd;
32
32
  -webkit-border-radius: 3px;
33
33
  -moz-border-radius: 3px;
34
34
  border-radius: 3px;
@@ -70,7 +70,7 @@ end
70
70
  ######################################################################
71
71
  # List field definition for single model
72
72
  ######################################################################
73
- def fields()
73
+ def all_fields()
74
74
  @records = []
75
75
  model = params[:id].classify.constantize
76
76
  document = model.new
@@ -779,16 +779,16 @@ end
779
779
  # to get all edit fields on form. This method does it. Subroutine of save_data.
780
780
  ########################################################################
781
781
  def fields_on_form() #:nodoc:
782
- fields = []
782
+ form_fields = []
783
783
  if @form['form']['fields']
784
784
  # read only field elements (key is Integer)
785
- @form['form']['fields'].each {|key,options| fields << options if key.class == Integer }
785
+ @form['form']['fields'].each {|key,options| form_fields << options if key.class == Integer }
786
786
  else
787
787
  @form['form']['tabs'].keys.each do |tab|
788
- @form['form']['tabs'][tab].each {|key,options| fields << options if key.class == Integer }
788
+ @form['form']['tabs'][tab].each {|key,options| form_fields << options if key.class == Integer }
789
789
  end
790
790
  end
791
- fields
791
+ form_fields
792
792
  end
793
793
 
794
794
  ########################################################################
@@ -796,17 +796,17 @@ end
796
796
  # It also saves journal data and calls before_save and after_save callbacks.
797
797
  ########################################################################
798
798
  def save_data
799
- fields = fields_on_form()
800
- return true if fields.size == 0
799
+ form_fields = fields_on_form()
800
+ return true if form_fields.size == 0
801
801
  #
802
- fields.each do |v|
802
+ form_fields.each do |v|
803
803
  session[:form_processing] = v['name'] # for debuging
804
804
  next if v['type'].nil? or
805
805
  v['type'].match('embedded') or # don't wipe embedded types
806
806
  (params[:edit_only] and params[:edit_only] != v['name']) or # otherwise other fields would be wiped
807
807
  v['readonly'] or # fields with readonly option don't return value and would be wiped
808
808
  !@record.respond_to?(v['name']) # there can be temporary fields on the form
809
- # good to know how to get type of field @record.fields[v['name']].type
809
+ # good to know! How to get type of field @record.fields[v['name']].type
810
810
  # return value from form field definition
811
811
  value = DrgcmsFormFields.const_get(v['type'].camelize).get_data(params, v['name'])
812
812
  @record.send("#{v['name']}=", value)
@@ -327,7 +327,7 @@ def dc_process_default_request()
327
327
  dc_set_options(@site.settings)
328
328
  # HOMEPAGE. When no parameters is set
329
329
  params[:path] = @site.homepage_link if params[:id].nil? and params[:path].nil?
330
- @options[:path] = params[:path].split('/')
330
+ @options[:path] = params[:path].to_s.split('/')
331
331
  params[:path] = @options[:path].first if @options[:path].size > 1
332
332
  # some other process request. It should fail if not defined
333
333
  return send(@site.request_processor) unless @site.request_processor.blank?
@@ -187,8 +187,7 @@ end
187
187
  ########################################################################
188
188
  def copy_clipboard
189
189
  # Only administrators can perform this operation
190
- return render(plain: t('drgcms.not_authorized') ) unless dc_user_has_role('admin')
191
- #
190
+ return render(plain: t('drgcms.not_authorized') ) unless dc_user_can(DcPermission::CAN_ADMIN,'dc_site')
192
191
  respond_to do |format|
193
192
  # just open new window to same url and come back with html request
194
193
  format.json { dc_render_ajax(operation: 'window', url: request.url ) }
@@ -209,8 +208,7 @@ end
209
208
  ########################################################################
210
209
  def paste_clipboard
211
210
  # Only administrators can perform this operation
212
- return render(plain: t('drgcms.not_authorized') ) unless dc_user_has_role('admin')
213
-
211
+ return render(plain: t('drgcms.not_authorized') ) unless dc_user_can(DcPermission::CAN_ADMIN,'dc_site')
214
212
  result = ''
215
213
  respond_to do |format|
216
214
  # just open new window to same url and come back with html request
@@ -299,10 +297,11 @@ end
299
297
  # Fills session with data related to successful login.
300
298
  ####################################################################
301
299
  def fill_login_data(user, remember_me)
302
- session[:user_id] = user.id
303
- session[:user_name] = user.name
304
- session[:edit_mode] = 0
300
+ session[:user_id] = user.id
301
+ session[:user_name] = user.name
302
+ session[:edit_mode] = 0
305
303
  session[:user_roles] = []
304
+
306
305
  # special for SUPERADMIN
307
306
  sa = DcPolicyRole.find_by(system_name: 'superadmin')
308
307
  if sa and (role = user.dc_user_roles.find_by(dc_policy_role_id: sa.id))
@@ -310,6 +309,9 @@ def fill_login_data(user, remember_me)
310
309
  session[:edit_mode] = 2
311
310
  return
312
311
  end
312
+ # Every user has guest role
313
+ guest = DcPolicyRole.find_by(system_name: 'guest')
314
+ session[:user_roles] << guest.id if guest
313
315
  # read default policy from site
314
316
  default_policy = dc_get_site().dc_policies.find_by(is_default: true)
315
317
  # load user roles
@@ -324,13 +326,6 @@ def fill_login_data(user, remember_me)
324
326
  session[:edit_mode] = 1 if policy_role.permission > 1
325
327
  session[:user_roles] << role.dc_policy_role_id
326
328
  end
327
- # Add default guest role if no role set
328
- # This was previously in dc_user_can. I belive it should be here.
329
- #TODO This might not be the best idea. Check in the future.
330
- if session[:user_roles].size == 0
331
- guest = DcPolicyRole.find_by(:system_name => 'guest')
332
- session[:user_roles] << guest.id if guest
333
- end
334
329
  # Save remember me cookie if not CMS user and remember me is selected
335
330
  if session[:edit_mode] == 0 and remember_me
336
331
  cookies.signed[:remember_me] = { :value => user.id, :expires => 180.days.from_now}
@@ -100,11 +100,11 @@ form:
100
100
  name: menu_class
101
101
  type: text_field
102
102
  size: 20
103
- 60:
104
- name: menu_name
105
- type: text_with_select
106
- eval: dc_choices4(@record.menu_class,'description','name')
107
- size: 30
103
+ # 60:
104
+ # name: menu_name
105
+ # type: text_with_select
106
+ # eval: dc_choices4(@record.menu_class,'description','name')
107
+ # size: 30
108
108
  70:
109
109
  name: menu_id
110
110
  type: select
@@ -364,12 +364,18 @@ def dc_format_value(value, format=nil)
364
364
  # :TODO: Enable formating numbers.
365
365
  return '' if value.nil?
366
366
  klass = value.class.to_s
367
- if klass.match('Time')
367
+ case when klass.match('Time') then
368
368
  format ||= t('time.formats.default')
369
369
  value.strftime(format)
370
- elsif klass.match('Date')
370
+ when klass.match('Date') then
371
371
  format ||= t('date.formats.default')
372
372
  value.strftime(format)
373
+ when format.to_s[0] == 'N' then
374
+ dec = format[1].blank? ? nil : format[1].to_i
375
+ sep = format[2].blank? ? nil : format[2]
376
+ del = format[3].blank? ? nil : format[3]
377
+ cur = format[4].blank? ? nil : format[4]
378
+ dc_format_number(value, dec, sep, del, cur)
373
379
  else
374
380
  value.to_s
375
381
  end
@@ -675,7 +681,7 @@ end
675
681
  ############################################################################
676
682
  # Creates input fields for one tab. Subroutine of dc_fields_for_form.
677
683
  ############################################################################
678
- def dc_fields_for_tab(fields) #:nodoc:
684
+ def dc_fields_for_tab(fields_on_tab) #:nodoc:
679
685
  @js ||= ''
680
686
  html = '<div class="dc-form">'
681
687
  labels_pos = dc_check_and_default(@form['form']['labels_pos'], 'right', ['top','left','right'])
@@ -687,7 +693,7 @@ def dc_fields_for_tab(fields) #:nodoc:
687
693
  # form_options = fields.select {|field| field.class != Integer }
688
694
  # columns = form_options.try(:[],'columns') || 1
689
695
  # Select form fields and sort them by key
690
- form_fields = fields.select {|field| field.class == Integer }
696
+ form_fields = fields_on_tab.select {|field| field.class == Integer }
691
697
  form_fields.to_a.sort.each do |element|
692
698
  options = element.last
693
699
  session[:form_processing] = "form:fields: #{element.first}=#{options}"
@@ -761,9 +767,9 @@ end
761
767
  def dc_fields_for_form()
762
768
  html, tabs, tdata = '',[], ''
763
769
  # Only fields defined
764
- if (fields = @form['form']['fields'])
770
+ if (form_fields = @form['form']['fields'])
765
771
  html << "<div id='data_fields' " + (@form['form']['height'] ? "style=\"height: #{@form['form']['height']}px;\">" : '>')
766
- html << dc_fields_for_tab(fields) + '</div>'
772
+ html << dc_fields_for_tab(form_fields) + '</div>'
767
773
  else
768
774
  # there are multiple tabs on form
769
775
  first = true # first tab
@@ -766,10 +766,10 @@ end
766
766
  ############################################################################
767
767
  def dc_name4_id(model, field, field_name, id=nil)
768
768
  return '' if id.nil?
769
- field_name = 'id' if field_name.nil?
769
+ field_name ||= 'id'
770
770
  model = model.strip.classify.constantize if model.class == String
771
771
  rec = Mongoid::QueryCache.cache { model.find_by(field_name.strip.to_sym => id) }
772
- rec.nil? ? '' : rec[field]
772
+ rec.nil? ? '' : (rec.send(field) rescue 'not defined')
773
773
  end
774
774
 
775
775
  ############################################################################
@@ -813,6 +813,44 @@ def dc_date_time(value, format) #:nodoc:
813
813
  dc_format_date_time(value, format)
814
814
  end
815
815
 
816
+ ############################################################################
817
+ # Returns html code for displaying formatted number.
818
+ #
819
+ # Parameters:
820
+ # [value] Numeric number.
821
+ # [decimals] Integer. Number of decimals
822
+ # [separator] String. Decimals separator
823
+ # [delimiter] String. Thousands delimiter.
824
+ # [currency] String. Currency symbol if applied to result string.
825
+ ############################################################################
826
+ def dc_format_number(value=0, decimals=nil, separator=nil, delimiter=nil, currency=nil)
827
+ decimals ||= I18n.t('number.currency.format.precision')
828
+ separator ||= I18n.t('number.currency.format.separator')
829
+ separator = '' if decimals == 0
830
+ delimiter ||= I18n.t('number.currency.format.delimiter')
831
+ whole,dec = value.to_s.split('.')
832
+ whole = '0' if whole.blank?
833
+ # remove and remember sign
834
+ sign = whole[0,1]
835
+ if sign == '-'
836
+ whole = whole[1,20]
837
+ else
838
+ sign = ''
839
+ end
840
+ # format decimals
841
+ dec ||= '0'
842
+ dec = dec[0,decimals]
843
+ while dec.size < decimals do dec += '0' end
844
+ # slice whole on chunks of 3
845
+ ar = []
846
+ while whole.size > 0 do
847
+ n = whole.size >=3 ? 3 : whole.size
848
+ ar << whole.slice!(n*-1,n)
849
+ end
850
+ # put it all back and format
851
+ "#{sign}#{ar.reverse.join(delimiter)}#{separator}#{dec}"
852
+ end
853
+
816
854
  ####################################################################
817
855
  # Parse site name from url and return dc_site document. Site document will be cached in
818
856
  # @site variable.
@@ -1056,7 +1094,6 @@ def dc_user_can_view(ctrl, policy_id)
1056
1094
  policy_id = nil unless policy_id.class == BSON::ObjectId
1057
1095
  #
1058
1096
  site = ctrl.site
1059
- policies = site.dc_policies
1060
1097
  policies = if site.inherit_policy.blank?
1061
1098
  site.dc_policies
1062
1099
  else
@@ -1075,7 +1112,7 @@ def dc_user_can_view(ctrl, policy_id)
1075
1112
  return false, 'Access policy not found for part!' unless part_policy
1076
1113
  part_policy.dc_policy_rules.to_a.each { |v| permissions[v.dc_policy_role_id] = v.permission }
1077
1114
  end
1078
- # apply guest role if user has no roles defined
1115
+ # apply guest role if no roles defined
1079
1116
  if ctrl.session[:user_roles].nil?
1080
1117
  role = Mongoid::QueryCache.cache { DcPolicyRole.find_by(system_name: 'guest', active: true) }
1081
1118
  return false, 'System guest role not defined!' unless role
@@ -110,6 +110,8 @@ end
110
110
  # [item] MenuItem.
111
111
  ########################################################################
112
112
  def link_4menu(item)
113
+ # just horizontal line
114
+ return item.caption if item.caption == '<hr>'
113
115
  # prepand to link
114
116
  link = if !item.link_prepend.blank?
115
117
  item.link_prepend
@@ -226,35 +226,31 @@ end
226
226
  def as_dropdown
227
227
  html = link_4edit
228
228
  return "#{html}#{@opts[:name]}<br>Menu not found!" if @menu.nil?
229
- #
230
- items = @menu.dc_simple_menu_items.sort {|a,b| a.order <=> b.order}
231
- @selected = find_selected
232
-
233
- html << "<div id='#{@menu.div_name}'>" unless @menu.div_name.blank?
234
- html << '<table><tr>'
235
229
  # sort items acording to :order
230
+ items = @menu.dc_simple_menu_items.where(active: true).order_by(order: 1)
231
+ @selected = find_selected
232
+ div_name = (@menu.div_name.blank? ? @menu.name : @menu.div_name ).downcase
233
+
234
+ html << "<div id='#{div_name}'><ul>"
236
235
  items.each do |item|
237
- next unless item.active
238
236
  # menu can be hidden from user
239
237
  can_view, msg = dc_user_can_view(@parent, item)
240
238
  next unless can_view
241
239
  #
242
- selector = item.id == @selected.id ? 'th' : 'td'
243
- html << "<#{selector}>#{ link_4menu(item) }"
244
- y = YAML.load(item.submenu) || {}
245
- if y.size > 0
240
+ selected = item.id == @selected.id ? 'selected' : ''
241
+ html << "<li class=\"#{selected}\">#{ link_4menu(item) }"
242
+ y = YAML.load(item.submenu) rescue {}
243
+ if y and y.size > 0
246
244
  html << '<ul>'
247
245
  y.each do |k,v|
248
- html << "<li>#{@parent.link_to(v['title'], v['link'], {target: v['target']})}</li>"
246
+ v ||= k # defined as array
247
+ html << (v['title'] == '<hr>' ? '<hr>' : "<li>#{@parent.link_to(v['title'], v['link'], {target: v['target']})}</li>" )
249
248
  end
250
249
  html << '</ul>'
251
250
  end
252
- html << "</#{selector}>"
253
-
251
+ html << "</li>"
254
252
  end
255
- html << '</tr></table>'
256
- html << '</div>' unless @menu.div_name.blank?
257
- html
253
+ html << '</ul></div>'
258
254
  end
259
255
 
260
256
  ########################################################################
@@ -273,10 +269,9 @@ def default
273
269
  div_name = (@menu.div_name.to_s.size > 2 ? @menu.div_name : @menu.name).downcase
274
270
  html << "<div class=\"#{div_name}\">"
275
271
  html << "<ul class=\"ul-#{div_name}\">"
276
- # sort items acording to :order
277
- items = @menu.dc_simple_menu_items.sort {|a,b| a.order <=> b.order}
272
+ #
273
+ items = @menu.dc_simple_menu_items.where(active: true).order_by(order: 1)
278
274
  items.each do |item|
279
- next unless item.active
280
275
  # menu can be hidden from user
281
276
  can_view, msg = dc_user_can_view(@parent, item)
282
277
  next unless can_view
@@ -286,15 +281,16 @@ def default
286
281
  end
287
282
  html << "</ul></div>"
288
283
  # submenu
289
- html << "<div class=\"sub-#{div_name}\">
290
- <ul class=\"ul-sub-#{div_name}\">"
291
- y = YAML.load(@selected.submenu) rescue []
292
- if y.class == Hash
284
+ y = YAML.load(@selected.submenu) rescue {}
285
+ if y and y.size > 0
286
+ html << "\n<div class=\"sub-#{div_name}\"><ul class=\"ul-sub-#{div_name}\">"
293
287
  y.each do |k,v|
294
- html << "<li class=\"li-sub-#{div_name}\">#{@parent.link_to(v['title'], v['link'])}</li>"
288
+ v ||= k # defined as array
289
+ html << "<li class=\"li-sub-#{div_name}\">#{@parent.link_to(v['title'], v['link'])}</li>\n"
295
290
  end
291
+ html << "</ul></div>\n"
296
292
  end
297
- html << '</ul></div>'
293
+ html
298
294
  end
299
295
 
300
296
 
@@ -93,7 +93,7 @@ end
93
93
  # Return choices for select for site_id
94
94
  ########################################################################
95
95
  def self.choices4_site
96
- result = all.inject([]) { |r,site| r << [ (site.active ? '' : t('drgcms.disabled') ) + site.name, site._id] }
96
+ result = all.inject([]) { |r,site| r << [ (site.active ? '' : I18n.t('drgcms.disabled') ) + site.name, site._id] }
97
97
  result.sort {|a,b| a[0] <=> b[0]}
98
98
  end
99
99
 
@@ -74,10 +74,11 @@ has_secure_password
74
74
  index( { username: 1 }, { unique: true } )
75
75
  index( { email: 1 }, { unique: true } )
76
76
  index 'dc_user_roles.dc_policy_role_id' => 1
77
-
78
77
  index 'members' => 1
79
78
 
80
79
  validates_length_of :username, minimum: 4
80
+ validates :username, uniqueness: true
81
+ validates :email, uniqueness: true
81
82
  before_save :do_before_save
82
83
 
83
84
  ##########################################################################
@@ -113,8 +113,9 @@ class DcDesign
113
113
  # end user.
114
114
  ########################################################################
115
115
  def self.choices4_design(site=nil)
116
- list = site.nil? ? where(active: true) : where(active: true).in(site_id: [nil,site.id])
117
- list.sort(name: 1).inject([]) { |r,design| r << [ design.description, design._id] }
116
+ list = site.nil? ? where(active: true) : where(active: true).in(site_id: [nil,site.id]).to_a
117
+ list.sort! { |w1, w2| w1.description.casecmp(w2.description) }
118
+ list.inject([]) { |r, design| r << [ design.description, design._id] }
118
119
  end
119
120
 
120
121
  end
@@ -88,8 +88,8 @@ def self.get_field_form_definition(name, parent) #:nodoc:
88
88
  form = parent.form
89
89
  form['form']['tabs'].each do |tab|
90
90
  # Array with 2 elements. First is tabname, second is data
91
- fields = tab.last
92
- fields.each {|k,v| return v if (k.class == Integer and v['name'] == name) }
91
+ my_fields = tab.last
92
+ my_fields.each {|k,v| return v if (k.class == Integer and v['name'] == name) }
93
93
  end if form['form']['tabs'] # I know. But nice.
94
94
  #
95
95
  form['form']['fields'].each do |field|
@@ -121,10 +121,11 @@ def self.get_filter_field(parent)
121
121
  end
122
122
  end
123
123
  # field redefined with input keyword. Name must start with _
124
- field['name'] = '_filter_field'
125
- field['type'] = filter['input'] if filter['input'].to_s.size > 5
126
- field['type'] ||= 'text_field'
127
- field['html'] ||= {}
124
+ field['name'] = '_filter_field'
125
+ field['type'] = filter['input'] if filter['input'].to_s.size > 5
126
+ field['type'] ||= 'text_field'
127
+ field['readonly'] = false # must be
128
+ field['html'] ||= {}
128
129
  field['html']['size'] = 20
129
130
  # Start with last entered value
130
131
  field['html']['value'] = filter['value'] unless filter['value'] == '#NIL'
@@ -61,7 +61,7 @@ module DrgcmsFormFields
61
61
  # most of the common code for custom form field already implemented.
62
62
  ###########################################################################
63
63
  class DrgcmsField
64
- attr_reader :html, :js
64
+ attr_reader :js
65
65
 
66
66
  ####################################################################
67
67
  # DrgcmsField initialization code.
@@ -86,9 +86,17 @@ def initialize( parent, record, yaml )
86
86
  end
87
87
  @html = ''
88
88
  @js = ''
89
+ @css = @yaml['css']
89
90
  self
90
91
  end
91
92
 
93
+ ####################################################################
94
+ # Returns html code together with CSS code.
95
+ ####################################################################
96
+ def html
97
+ @html + (@css ? "\n<style type=\"text/css\">#{@css}</style>" : '')
98
+ end
99
+
92
100
  ####################################################################
93
101
  # Wrapper for i18 t method, with some spice added. If translation is not found English
94
102
  # translation value will be returned. And if still not found default value will be returned if passed.
@@ -1302,8 +1310,9 @@ end
1302
1310
  # 10:
1303
1311
  # name: title
1304
1312
  # type: text_field
1313
+ # size: 30
1305
1314
  # html:
1306
- # size: 30
1315
+ # required: yes
1307
1316
  ###########################################################################
1308
1317
  class TextField < DrgcmsField
1309
1318
 
@@ -1320,6 +1329,64 @@ def render
1320
1329
  end
1321
1330
  end
1322
1331
 
1332
+ ###########################################################################
1333
+ # Implementation of number_field DRG CMS form field. Number fields can be
1334
+ # formated for display with thousands delimiters and decimal separators and
1335
+ # can have currency symbol.
1336
+ #
1337
+ # ===Form options:
1338
+ # * +type:+ number_field (required)
1339
+ # * +name:+ Field name (required)
1340
+ # * +format:+ Format options
1341
+ # * +decimals:+ No of decimal places
1342
+ # * +separator:+ decimal separator (yes no , .) Default yes if decimals > 0
1343
+ # * +delimiter:+ Thousands delimiter (yes no , .) Default defind by locals
1344
+ # * +currency:+ Currency sign (yes no sign) Default no. If yes defined by locals
1345
+ # * +html:+ html options which apply to text_field field (optional)
1346
+ #
1347
+ # Form example:
1348
+ # 10:
1349
+ # name: title
1350
+ # type: number_field
1351
+ # size: 10
1352
+ # format:
1353
+ # decimals: 2
1354
+ # delimiter: false
1355
+ ###########################################################################
1356
+ class NumberField < DrgcmsField
1357
+
1358
+ ###########################################################################
1359
+ # Render text_field field html code
1360
+ ###########################################################################
1361
+ def render
1362
+ return ro_standard if @readonly
1363
+ set_initial_value
1364
+ #
1365
+ record = record_text_for(@yaml['name'])
1366
+ @yaml['html'] ||= {}
1367
+ @yaml['html']['class'] = 'dc-number'
1368
+ @yaml['html']['data-decimal'] = @yaml.dig('format','decimal') || 2
1369
+ @yaml['html']['data-delimiter'] = @yaml.dig('format','delimiter') || I18n.t('number.currency.format.delimiter')
1370
+ @yaml['html']['data-separator'] = @yaml.dig('format','separator') || I18n.t('number.currency.format.separator')
1371
+ # @yaml['html']['data-currency'] = @yaml.dig('format','currency') == 'yes' ? I18n.t('number.currency.format.currency') : @yaml.dig('format','currency')
1372
+ value = @record[@yaml['name']] || 0
1373
+
1374
+ @html << @parent.hidden_field( record, @yaml['name'], value: value )
1375
+
1376
+ @yaml['html']['value'] = @parent.dc_format_number(value, @yaml['html']['data-decimal'], @yaml['html']['data-separator'], @yaml['html']['data-delimiter'] )
1377
+ @html << @parent.text_field( nil,"record_#{@yaml['name']}1", @yaml['html'])
1378
+ self
1379
+ end
1380
+
1381
+ ###########################################################################
1382
+ # Return value. Return nil if input field is empty
1383
+ ###########################################################################
1384
+ def self.get_data(params, name)
1385
+ return 0 if params['record'][name].blank?
1386
+ params['record'][name].match('.') ? BigDecimal.new(params['record'][name]) : Integer.new(params['record'][name])
1387
+ end
1388
+ end
1389
+
1323
1390
  ###########################################################################
1324
1391
  # Implementation of text_with_select DRG CMS form field. Field will provide
1325
1392
  # text_field entry field with select dropdown box with optional values for the field.
@@ -27,8 +27,7 @@ Gem::Specification.new do |s|
27
27
 
28
28
  s.add_dependency 'bcrypt' #, '~> 3.0.0'
29
29
  s.add_dependency 'mongoid'#, '~> 5'
30
- # s.add_dependency 'mongo_session_store-rails4'
31
- # s.add_dependency 'kaminari'
30
+
32
31
  s.add_dependency 'kaminari-mongoid'
33
32
  s.add_dependency 'kaminari-actionview'
34
33
  s.add_dependency 'font-awesome-rails'
@@ -1,6 +1,5 @@
1
- #coding: utf-8
2
1
  #--
3
- # Copyright (c) 2012-2013 Damjan Rems
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
@@ -1,4 +1,27 @@
1
+ #--
2
+ # Copyright (c) 2012+ 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
+
1
24
  module DrgCms #:nodoc:
2
25
  # drg_cms gem version
3
- VERSION = "0.5.52.9"
26
+ VERSION = "0.5.52.12"
4
27
  end
@@ -82,15 +82,20 @@ result_set:
82
82
  # Choose from
83
83
  # #{@model.attribute_names.join(',')}
84
84
  columns:
85
- 1:
85
+ 10:
86
86
  name: #{@model.attribute_names[1]}
87
- style: 'align: left; width: 100px'
88
- 2:
87
+ style: 'color: red'
88
+ width: 10%
89
+ align: right
90
+ 20:
89
91
  name: #{@model.attribute_names[2]}
90
- 3:
92
+ 30:
91
93
  name: created_at
92
94
  format: '%d.%m.%Y'
93
- 4:
95
+ 40:
96
+ name: created_by
97
+ eval: dc_name4_id,dc_user,name
98
+ 50:
94
99
  name: active
95
100
  eval: dc_icon4_boolean
96
101
 
@@ -53,7 +53,7 @@ def collections(what)
53
53
  next if model.nil?
54
54
  next unless model.respond_to?(:mongo_client)
55
55
  record = {'id' => collection, 'description' => I18n.t("helpers.label.#{collection}.tabletitle") }
56
- list << [record, fields(collection)]
56
+ list << [record, model_fields(collection)]
57
57
  end
58
58
  list
59
59
  end
@@ -61,7 +61,7 @@ end
61
61
  ######################################################################
62
62
  # List field definition for single model
63
63
  ######################################################################
64
- def fields(collection)
64
+ def model_fields(collection)
65
65
  records = []
66
66
  model = collection.classify.constantize
67
67
  document = model.new
@@ -112,11 +112,11 @@ def create_output(descriptions)
112
112
  body = ''
113
113
  descriptions.each do |description|
114
114
  collection = description.first
115
- fields = description.last
115
+ all_fields = description.last
116
116
  body << "#\n# == Schema information\n#\n"
117
117
  body << "# Collection name: #{collection['id']} : #{collection['description']}\n#\n"
118
118
 
119
- fields.each do |field|
119
+ all_fields.each do |field|
120
120
  body << "# #{field['field'].ljust(20)} #{field['type'].to_s.ljust(20)} #{field['description']}\n"
121
121
  end
122
122
  body << "\n\n"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: drg_cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.52.9
4
+ version: 0.5.52.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Damjan Rems
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-07 00:00:00.000000000 Z
11
+ date: 2018-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails