drg_cms 0.5.52.9 → 0.5.52.12

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