drg_cms 0.7.0.8 → 0.7.1.1

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/drg_cms/drg_cms.js +50 -20
  3. data/app/assets/stylesheets/drg_cms/drg_cms.css +89 -31
  4. data/app/assets/stylesheets/drg_cms/select-multiple.css +5 -6
  5. data/app/controllers/cmsedit_controller.rb +57 -24
  6. data/app/controllers/dc_application_controller.rb +18 -21
  7. data/app/controls/dc_poll_result_control.rb +36 -36
  8. data/app/controls/dc_setup_control.rb +53 -0
  9. data/app/forms/all_options.yml +3 -3
  10. data/app/forms/cms_menu.yml +7 -0
  11. data/app/forms/dc_image_search.yml +2 -2
  12. data/app/forms/dc_poll.yml +2 -1
  13. data/app/forms/dc_poll_result.yml +10 -7
  14. data/app/forms/dc_setup.yml +45 -0
  15. data/app/forms/dc_steps_template.yml +4 -1
  16. data/app/helpers/cms_common_helper.rb +14 -10
  17. data/app/helpers/cms_helper.rb +8 -7
  18. data/app/helpers/cms_index_helper.rb +56 -42
  19. data/app/helpers/dc_application_helper.rb +46 -16
  20. data/app/helpers/dc_image_helper.rb +2 -2
  21. data/app/models/concerns/dc_user_concern.rb +1 -1
  22. data/app/models/dc_big_table.rb +1 -1
  23. data/app/models/dc_filter.rb +5 -9
  24. data/app/models/dc_image.rb +1 -1
  25. data/app/models/dc_memory.rb +2 -2
  26. data/app/models/dc_setup.rb +111 -0
  27. data/app/models/drgcms_form_fields/datetime_picker.rb +1 -1
  28. data/app/models/drgcms_form_fields/embedded.rb +17 -9
  29. data/app/models/drgcms_form_fields/multitext_autocomplete.rb +44 -36
  30. data/app/models/drgcms_form_fields/select.rb +21 -5
  31. data/app/renderers/dc_big_menu_renderer.rb +18 -20
  32. data/app/renderers/dc_menu_renderer.rb +21 -58
  33. data/app/renderers/dc_simple_menu_renderer.rb +1 -1
  34. data/app/views/cmsedit/_edit_stuff.html.erb +3 -0
  35. data/config/locales/drgcms_en.yml +8 -0
  36. data/config/locales/drgcms_sl.yml +12 -4
  37. data/config/locales/models_en.yml +17 -1
  38. data/config/locales/models_sl.yml +17 -1
  39. data/lib/drg_cms/version.rb +1 -1
  40. data/lib/drg_cms.rb +22 -23
  41. data/lib/generators/new_drg_form/new_drg_form_generator.rb +32 -14
  42. metadata +5 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f2d3e3ad52492c5dccf2b91cd7c9c1ea203b7a60c21b0e3d4f7947a3b298bd8b
4
- data.tar.gz: a9b23d36c053d8770a661827a211e88172ccadf10eb0c0f17419e0069799f402
3
+ metadata.gz: 836e52abeb4f9f04c54c21d66c4c053b5bc9cb8906904ce6c608b0c03edc57d7
4
+ data.tar.gz: 86469fb38b082d39f20ce81ee903354e11d693db34060a224cf031facd554b45
5
5
  SHA512:
6
- metadata.gz: f745ccb1e0902369746c51da513b1487eca95b1bc02f1bd427ccca2403fc2fd54341cccf8359ab301206fcc5ae4e61d13f03ee30d42b5d3ce0e14a3d357b7d54
7
- data.tar.gz: e61ee50affe2a0aa4a2ea5fd5a386cad6b3a0f614c2fd3233cab5a5ae47e553eeab290ab527678265153d76352b37dac95867a1ff558b4a4c29dcafbb080fcaf
6
+ metadata.gz: af0af1882f81f7240438b80a4138c415ada71850395ce149f3a9b4d30b5e8858081aad9a438e9a7a9749a8e75cc0b16775aec187785a765870d4d726aa4f66e1
7
+ data.tar.gz: d8c3c2d0184e4e97451962203a64d7d4a2e59dd08e5e48320d05f0203a12f8e50cbd0263958d2af189c7ef84f0627f95067558321fb0d44f4ce88b7683897b5d
@@ -120,6 +120,8 @@ update_select_depend = function(select_name, depend_name, method) {
120
120
  $.each(data, function(index, element) {
121
121
  select_field.append( new Option(element['label'], element['id']) );
122
122
  });
123
+ // refresh multiple select field
124
+ if (select_field.hasClass('select-multiple')) { select_field.selectMultiple('refresh') }
123
125
  }
124
126
  });
125
127
  };
@@ -292,10 +294,12 @@ process_json_result = function(json) {
292
294
  closeClass: 'dc-link' });
293
295
  }
294
296
  else {
295
- $('#popup').html(value);
297
+ if (selector == '') { selector = 'info' }
298
+ let popup_html = '<div class="popup-' + selector + '">' + value + '<br><button class="dc-link">OK</button></div>';
299
+ $('#popup').html(popup_html);
296
300
  $('#popup').bPopup( {
297
301
  transition: 'slideDown', transitionClose: 'slideDown', speed: 300,
298
- opacity: 0, position: ['auto', 20],
302
+ opacity: 0, position: ['auto', 'auto'],
299
303
  closeClass: 'dc-link' });
300
304
  }
301
305
  // resize parent iframe if smaller then 500px to ensure popup some space
@@ -520,19 +524,44 @@ dc_image_preview = function(img) {
520
524
  *******************************************************************/
521
525
  dc_image_select = function(img) {
522
526
  let ck_func_name = $.getUrlParam('CKEditorFuncNum');
523
- let field_name = $.getUrlParam('field_name');
524
- if (ck_func_name !== '') {
527
+ let field_name = $.getUrlParam('field_name');
528
+ if (ck_func_name) {
525
529
  window.opener.CKEDITOR.tools.callFunction(ck_func_name, img);
526
530
  } else {
527
531
  window.opener.document.getElementById(field_name).value = img;
532
+
533
+ // update image preview
534
+ //let img_src = window.opener.$(`#td_${field_name} .dc-image-preview img`);
535
+ //img_src.attr("src", img);
536
+
537
+ // even better. Click save button.
538
+ window.opener.$(`.mi.mi-save`).first().click();
528
539
  }
529
540
  window.close();
530
541
  };
531
542
 
532
-
533
543
  /*******************************************************************
534
- * Events start here
544
+ * Resize iframe_embedded to the size of form.
535
545
  *******************************************************************/
546
+ function resize_iframe_embedded(that) {
547
+ let embedded_height = that.contentWindow.document.body.offsetHeight;
548
+ // workaround. It gets tricky when embedded field is on tab
549
+ if (embedded_height == 0) embedded_height = 50;
550
+ that.style.height = (embedded_height + 30) + 'px';
551
+ // resize parent element too
552
+ let parentWindow= that.contentWindow.parent;
553
+ let parent_height= (parentWindow.document.body.offsetHeight + 30) + 'px';
554
+ parentWindow.frameElement.style.height = parent_height;
555
+ };
556
+
557
+
558
+ /*******************************************************************
559
+ *
560
+ *
561
+ * EVENTS START HERE
562
+ *
563
+ *
564
+ ********************************************************************/
536
565
  $(document).ready( function() {
537
566
  /* This could be the way to focus on first input field on document open
538
567
  if ( $('.dc-form')[0] ) {
@@ -580,6 +609,7 @@ $(document).ready( function() {
580
609
  $('.cms-toggle').bind('click', function(e) {
581
610
  var url = '/dc_common/toggle_edit_mode?return_to=' + window.location.href;
582
611
  if (e.pageX < 30) url = url + '&return_to_ypos=' + e.pageY ;
612
+ console.log(url);
583
613
  window.location.href = url;
584
614
  });
585
615
 
@@ -691,7 +721,7 @@ $(document).ready( function() {
691
721
  });
692
722
 
693
723
  /*******************************************************************
694
- * Resize iframe_cms to the size of its contents. Make at least 500 px high
724
+ * Resize iframe_cms on load to the size of its contents. Make at least 500 px high
695
725
  * unless on initial display.
696
726
  *******************************************************************/
697
727
  $('#iframe_cms').on('load', function() {
@@ -703,7 +733,7 @@ $(document).ready( function() {
703
733
  });
704
734
 
705
735
  /*******************************************************************
706
- * Same goes for editiframe. Resize it + 30px
736
+ * Resize iframe_edit on load to the size of its contents. Resize it + 30px
707
737
  * unless on initial display with no data
708
738
  *******************************************************************/
709
739
  $('#iframe_edit').on('load', function() {
@@ -715,18 +745,16 @@ $(document).ready( function() {
715
745
  });
716
746
 
717
747
  /*******************************************************************
718
- * Same goes for iframe_embedded. Resize it + 30px
748
+ * Resize iframe_embedded on load to the size of its contents.
749
+ * It doesn't work well with firefox, when CK editor object is on the form.
750
+ * Adding some delay is resolving the problem.
719
751
  *******************************************************************/
720
752
  $('.iframe_embedded').on('load', function() {
721
- let embedded_height = this.contentWindow.document.body.offsetHeight;
722
- // workaround. It gets tricky when embedded field is on tab
723
- if (embedded_height == 0) embedded_height = 50;
724
- this.style.height = (embedded_height + 30) + 'px';
725
- // resize parent iframe window too
726
- let parentWindow = this.contentWindow.parent;
727
- let parent_height = (parentWindow.document.body.offsetHeight + 30) + 'px';
728
- //parentWindow.frameElement.setAttribute('style', 'height:' + parent_height);
729
- parentWindow.frameElement.style.height = parent_height;
753
+ if (/Firefox/.test(navigator.userAgent)) {
754
+ setTimeout(resize_iframe_embedded, 100, this);
755
+ } else {
756
+ resize_iframe_embedded(this);
757
+ }
730
758
  });
731
759
 
732
760
  /*******************************************************************
@@ -856,11 +884,13 @@ $(document).ready( function() {
856
884
  let title = this.getAttribute("title");
857
885
  let w = this.getAttribute("data-x") || 1000;
858
886
  let h = this.getAttribute("data-y") || 800;
887
+ let offset = parent.window.scrollY || window.scrollY;
859
888
 
860
889
  url = dc_url_add_params(this, url)
861
890
  $('#popup').bPopup({ loadUrl: url,
862
- transition: 'slideDown', transitionClose: 'slideDown', speed: 300,
863
- opacity: 0, position: ['auto', 20],
891
+ transition: 'slideDown', transitionClose: 'slideDown',
892
+ speed: 300, opacity: 0,
893
+ position: ['auto', offset + 20],
864
894
  closeClass: 'dc-link'
865
895
  });
866
896
  });
@@ -45,7 +45,7 @@
45
45
  font-family: DrgSans;
46
46
  font-style: normal;
47
47
  font-weight: 600;
48
- src: url('ibm-plex-sans-600.woff2') format('woff2')
48
+ src: url('ibm-plex-sans-600.woff2') format('woff2');
49
49
  }
50
50
  @font-face {
51
51
  font-family: DrgSans;
@@ -83,7 +83,6 @@ time, mark, audio, video {
83
83
  margin: 0;
84
84
  padding: 0;
85
85
  border: 0;
86
- font-size: 100%;
87
86
  font: inherit;
88
87
  vertical-align: baseline;
89
88
  }
@@ -138,6 +137,10 @@ textarea, input, select {
138
137
  max-width: 200px;
139
138
  }
140
139
 
140
+ .dc-action-menu .ui-autocomplete-input {
141
+ padding: 8px 4px 8px 12px;
142
+ }
143
+
141
144
  textarea:focus, input:focus, select:focus {
142
145
  border: 1px solid rgba(44, 142, 255, 1);
143
146
  outline: 1px solid rgba(44, 142, 255, 1);
@@ -643,8 +646,7 @@ display: inline-table;
643
646
  /***** FORM *****/
644
647
 
645
648
  #dc-form-container {
646
- display: flex;
647
- padding-left: 4px;
649
+ /*display: flex;*/
648
650
  }
649
651
 
650
652
  #dc-form-left {
@@ -659,7 +661,7 @@ display: inline-table;
659
661
  }
660
662
 
661
663
  .dc-form-frame {
662
- margin: 0px;
664
+ margin: 0;
663
665
  padding: 4px;
664
666
  }
665
667
 
@@ -683,7 +685,6 @@ display: inline-table;
683
685
  border-radius: 2px;
684
686
  margin: 2px 0;
685
687
  }
686
-
687
688
  .dc-form-warning {
688
689
  padding: 8px;
689
690
  background-image: linear-gradient(to bottom, rgba(213, 143, 218, 0.1) 0, rgba(213, 143, 218, 0.5) 100%);
@@ -715,7 +716,7 @@ display: inline-table;
715
716
  color: #555;
716
717
  text-align: right;
717
718
  vertical-align: middle;
718
- font-weight: 600;
719
+ font-weight: 500;
719
720
  padding: 10px 2px;
720
721
  width: 150px;
721
722
  }
@@ -735,6 +736,8 @@ display: inline-table;
735
736
 
736
737
  .dc-form-label.dc-color-odd, .dc-form-label.dc-color-even {background-color: transparent;}
737
738
 
739
+ .dc-form-label.dc-width-0 { padding: 0;}
740
+
738
741
  .dc-align-left {
739
742
  text-align: left;
740
743
  }
@@ -745,7 +748,7 @@ display: inline-table;
745
748
  .dc-form-field {
746
749
  text-align: left;
747
750
  padding: 4px 2px;
748
- z-index: 10;
751
+ /*z-index: 10;*/
749
752
  white-space: nowrap;
750
753
  text-overflow: fade;
751
754
  }
@@ -1076,6 +1079,7 @@ font-size: 1.2em;
1076
1079
  font-size: 1.1em;
1077
1080
  line-height: 1.4em;
1078
1081
  }
1082
+
1079
1083
  /****** jquery ui-autocomplete widget ***************/
1080
1084
  .ui-autocomplete-input {
1081
1085
  padding: 8px 4px 8px 12px;
@@ -1137,16 +1141,7 @@ color: #000;
1137
1141
  margin-left: 4px;
1138
1142
  }
1139
1143
 
1140
-
1141
- .dc-red { color: #f76;}
1142
- .dc-red:hover { color: #c43;}
1143
- .dc-green { color: #9c9;}
1144
- .dc-green:hover { color: #6a6;}
1145
-
1146
- .aui-corner-all {
1147
- background-color: lightyellow;
1148
- }
1149
-
1144
+ /************* login *************/
1150
1145
  #dc-login {
1151
1146
  position: fixed;
1152
1147
  top: 50%;
@@ -1206,10 +1201,10 @@ color: #000;
1206
1201
  color: white;
1207
1202
  }
1208
1203
  .iframe_embedded {
1209
- padding: 4px;
1204
+ padding: 2px;
1210
1205
  background-color: #fff;
1211
1206
  border-radius: 2px;
1212
- border: 2px solid #666;
1207
+ border: 2px solid #888;
1213
1208
  }
1214
1209
 
1215
1210
  #iframe_edit, #iframe_cms {
@@ -1387,6 +1382,7 @@ color: #000;
1387
1382
  max-height: 700px;
1388
1383
  overflow-y: auto;
1389
1384
  max-width: 800px;
1385
+ line-height: 1.5em;
1390
1386
  }
1391
1387
 
1392
1388
  #popup .dc-help h1 {
@@ -1480,6 +1476,35 @@ color: #000;
1480
1476
  display: inline-flex;
1481
1477
  }
1482
1478
 
1479
+ #popup:has(.popup-info) {
1480
+ padding: 1rem;
1481
+ background-image: linear-gradient(to bottom, #dff0d8 0, #c8e5bc 100%);
1482
+ color: darkgreen;
1483
+ font-weight: 600;
1484
+ font-size: 1.1em;
1485
+ min-width: 30%;
1486
+ border: 2px solid darkgreen;
1487
+ }
1488
+
1489
+ #popup:has(.popup-error) {
1490
+ padding: 1rem;
1491
+ background-image: linear-gradient(to bottom, #f2dede 0, #e7c3c3 100%);
1492
+ color: #a94442;
1493
+ font-weight: 600;
1494
+ font-size: 1.1em;
1495
+ min-width: 30%;
1496
+ border: 2px solid #a94442;
1497
+ }
1498
+
1499
+ #popup .popup-info button, #popup .popup-error button {
1500
+ margin-top: 1rem;
1501
+ padding: 4px 2rem;
1502
+ line-height: initial;
1503
+ filter: none;
1504
+ border: 2px solid #222;
1505
+ border-radius: 5px;
1506
+ }
1507
+
1483
1508
  .filter-popup {
1484
1509
  background-color: #fff;
1485
1510
  filter: drop-shadow(2px 2px 8px #888);
@@ -1549,7 +1574,7 @@ cursor: pointer;
1549
1574
 
1550
1575
  #drgcms_filter h1 {
1551
1576
  font-size: 1.8em;
1552
- font-width: 600;
1577
+ font-weight: 600;
1553
1578
  color: rgba(44, 142, 255, 1);
1554
1579
  }
1555
1580
 
@@ -1572,6 +1597,36 @@ cursor: pointer;
1572
1597
  margin-left: 1px;
1573
1598
  }
1574
1599
 
1600
+ /**** reports ****/
1601
+ .report .dc-title { color: #003A68; }
1602
+ .report .dc-result-header {
1603
+ border-bottom: 2px solid #003A68;
1604
+ }
1605
+ .report .dc-result-header .th {
1606
+ color: #003A68;
1607
+ padding: 3px;
1608
+ }
1609
+
1610
+ .report .dc-result-data {
1611
+ padding: 0;
1612
+ }
1613
+
1614
+ .report.dc-form-frame {
1615
+ padding: 0;
1616
+ }
1617
+
1618
+
1619
+ .report .dc-result-data .td {
1620
+ padding: 3px;
1621
+ }
1622
+
1623
+ .iframe_embedded#if_dc_temp {
1624
+ border: none;
1625
+ padding: 0;
1626
+ }
1627
+
1628
+ .report .dc-odd {background-color: #e0eeff;}
1629
+
1575
1630
  /** Radio button input field **/
1576
1631
 
1577
1632
  .dc-radio {
@@ -1613,18 +1668,13 @@ cursor: pointer;
1613
1668
  @media only screen and (max-device-width: 600px) {
1614
1669
  #body-cms {font-size: 11px;}
1615
1670
  #site-top div:nth-of-type(2) {padding-top: 0 !important;}
1616
- .dc-title { font-size: 1.5em;}
1617
-
1618
- .dc-form {
1619
- border: none;
1620
- border-top: 2px solid #888;
1621
- border-bottom: 2px solid #888;
1622
- margin-top: 4px;
1671
+ .dc-title {
1672
+ font-size: 1.5em;
1673
+ padding-bottom: 4px;
1623
1674
  }
1675
+ .dc-form-field { padding-bottom: 4px; }
1624
1676
 
1625
- .dc-form .row-div {
1626
- display: block;
1627
- }
1677
+ .dc-form .row-div { display: block; }
1628
1678
  .dc-form-li {margin-top: 3px;}
1629
1679
 
1630
1680
  .dc-form-label {
@@ -1635,6 +1685,7 @@ cursor: pointer;
1635
1685
  }
1636
1686
  .dc-form-label label {
1637
1687
  font-size: 15px;
1688
+ padding: 0;
1638
1689
  }
1639
1690
 
1640
1691
  .dc-menu { padding: 0;}
@@ -1670,6 +1721,13 @@ cursor: pointer;
1670
1721
  font-size: 2em;
1671
1722
  }
1672
1723
 
1724
+ #menu-hamburger .mi:before{
1725
+ background-color: #222;
1726
+ color: #fff;
1727
+ padding: 1px;
1728
+ border-radius: 2px;
1729
+ }
1730
+
1673
1731
  .cmsedit-container {display: block;}
1674
1732
  .cmsedit-container #cms-menu {display: none;}
1675
1733
  .cmsedit-container #cms-menu.visible {
@@ -63,20 +63,19 @@
63
63
  }
64
64
 
65
65
  .ms-container .ms-selectable li.ms-elem-selectable{
66
- padding: 3px 10px;
66
+ padding: 5px 10px;
67
67
  color: #444;
68
- /* font-size: 14px;*/
69
68
  }
70
69
 
71
- .ms-container .ms-selectable li:nth-child(odd) {
72
- background-color: #f4f4f4;
70
+ .ms-container .ms-selectable li:nth-child(even) {
71
+ background-color: #f8f8f8;
73
72
  }
74
73
 
75
74
  .ms-container .ms-selectable li.ms-hover{
76
75
  cursor: pointer;
77
76
  color: #fff;
78
77
  text-decoration: none;
79
- background-color: #08c;
78
+ background-color: rgba(76,154,255, 0.6);
80
79
  }
81
80
 
82
81
  .ms-container .ms-selectable li.disabled{
@@ -92,10 +91,10 @@
92
91
 
93
92
  .ms-container .ms-selected {
94
93
  font-weight: 600;
94
+ color: darkblue !important;
95
95
  }
96
96
 
97
97
  .pull-right.ms-elem-selected{
98
98
  float: right;
99
- font-size: smaller;
100
99
  padding-left: 4px;
101
100
  }
@@ -77,7 +77,7 @@
77
77
  ########################################################################
78
78
  class CmseditController < DcApplicationController
79
79
  before_action :check_authorization, :except => [:login, :logout, :test, :run]
80
- protect_from_forgery with: :null_session, only: Proc.new { |c| c.request.format.json? }
80
+ protect_from_forgery with: :null_session, only: Proc.new { _1.request.format.json? }
81
81
 
82
82
  layout 'cms'
83
83
 
@@ -108,6 +108,10 @@ end
108
108
  ########################################################################
109
109
  def show
110
110
  find_record
111
+ if @record.nil?
112
+ flash[:error] ||= t('drgcms.doc_no_edit')
113
+ return index
114
+ end
111
115
  # before_show callback
112
116
  if (m = callback_method('before_show') )
113
117
  ret = call_callback_method(m)
@@ -270,11 +274,8 @@ def create
270
274
  # create document
271
275
  if params['id'].nil?
272
276
  # Prevent double form submit
273
- params[:form_time_stamp] = params[:form_time_stamp].to_i
274
- session[:form_time_stamp] ||= 0
275
- return index if params[:form_time_stamp] <= session[:form_time_stamp] && !Rails.env.test?
277
+ return index if double_form_submit?
276
278
 
277
- session[:form_time_stamp] = params[:form_time_stamp]
278
279
  create_new_empty_record
279
280
  if save_data
280
281
  flash[:info] = t('drgcms.doc_saved')
@@ -549,14 +550,14 @@ def check_authorization
549
550
  end
550
551
  dc_form_read
551
552
 
552
- # Permissions can be also defined on form
553
+ # Permissions can be also defined in form
553
554
  #TODO So far only can_view is used. Think about if using other permissions has sense
554
555
  can_view = @form.dig('permissions','can_view')
555
- if can_view.nil? or dc_user_has_role(can_view)
556
+ if can_view.nil? || can_view.split(',').any? { |role| dc_user_has_role(role) }
556
557
  extend_with_control_module
557
558
  else
558
559
  render(action: 'error', locals: { error: t('drgcms.not_authorized')} )
559
- end
560
+ end
560
561
  end
561
562
 
562
563
  ########################################################################
@@ -716,10 +717,10 @@ def save_data
716
717
 
717
718
  form_fields.each do |v|
718
719
  session[:form_processing] = v['name'] # for debuging
719
- next if v['type'].nil? or v['name'].nil? or
720
- v['type'].match('embedded') or # don't wipe embedded types
721
- (params[:edit_only] and params[:edit_only] != v['name']) or # otherwise other fields would be wiped
722
- v['readonly'] or # fields with readonly option don't return value and would be wiped
720
+ next if v['type'].nil? || v['name'].nil? ||
721
+ v['type'].match('embedded') || # don't wipe embedded types
722
+ (params[:edit_only] && params[:edit_only] != v['name']) || # otherwise other fields would be wiped
723
+ v['readonly'] || # fields with readonly option don't return value and would be wiped
723
724
  !@record.respond_to?(v['name']) # there are temporary fields on the form
724
725
  # good to know! How to get type of field @record.fields[v['name']].type
725
726
  # return value from form field definition
@@ -736,7 +737,7 @@ def save_data
736
737
 
737
738
  # save data
738
739
  changes = @record.changes
739
- update_standards() if changes.size > 0 # update only if there has been some changes
740
+ update_standards if changes.size > 0 # update only if there has been some changes
740
741
  if (saved = @record.save)
741
742
  operation = @record.new_record? ? :new : :update
742
743
  save_journal(operation, @record.previous_changes)
@@ -751,9 +752,9 @@ end
751
752
  # in select_fields and deny_fields
752
753
  ########################################################################
753
754
  def separated_to_symbols(data)
754
- data.chomp.split(',').map { |e| e.strip.downcase.to_sym }
755
+ data.chomp.split(',').map { _1.strip.downcase.to_sym }
755
756
  end
756
-
757
+
757
758
  ########################################################################
758
759
  # Will process only (select_fields) and without (deny_fields) option
759
760
  ########################################################################
@@ -877,19 +878,14 @@ def process_collections #:nodoc
877
878
  end
878
879
 
879
880
  ########################################################################
880
- # Process index action for in memory data.
881
+ # Process index action for in memory data. default_filter method must fill @records array
882
+ # with data, that will be shown in browser.
881
883
  ########################################################################
882
884
  def process_in_memory #:nodoc
883
885
  @records = []
884
886
  # result set is defined by filter method in control object
885
- if (method = @form['result_set']['filter'])
886
- send(method) if respond_to?(method)
887
- end
888
- # result set is defined by class method
889
- if (klass_method = @form['result_set']['filter_method'])
890
- _klass, method = klass_method.split('.')
891
- klass = _klass.classify.constantize
892
- @records = klass.send(method) if klass.respond_to?(method)
887
+ if (method = @form['result_set']['filter'] || 'default_filter')
888
+ send(method) if respond_to?(method)
893
889
  end
894
890
  # ensure that record has id field
895
891
  if @records.size > 0
@@ -898,4 +894,41 @@ def process_in_memory #:nodoc
898
894
  false
899
895
  end
900
896
 
897
+ ########################################################################
898
+ # Prevent double form submit
899
+ #
900
+ # There was a problem with old solution when user opened another browser session while
901
+ # entering data into new document. If in new session user added document to some other
902
+ # collection, save to document in primary session was silently ignored. Now creation time for last three forms
903
+ # is remembered. This will work unless user tries to add new document to the same collection in another session.
904
+ # But that is highly unlikely.
905
+ ########################################################################
906
+ def double_form_submit?
907
+ session[:dfs] ||= {}
908
+ form_name = CmsHelper.form_param(params) || CmsHelper.table_param(params)
909
+ params[:form_time_stamp] = params[:form_time_stamp].to_i
910
+ if params[:form_time_stamp] <= update_dfs_time(form_name) && !Rails.env.test? # test must be excluded
911
+ flash[:error] = I18n.t('drgcms.dfs')
912
+ return true
913
+ end
914
+ update_dfs_time(form_name, params[:form_time_stamp])
915
+
916
+ false
917
+ end
918
+
919
+ ########################################################################
920
+ # Updates double_form_submit timings.
921
+ ########################################################################
922
+ def update_dfs_time(form_name, time = nil)
923
+ if time.nil?
924
+ session[:dfs][form_name] ||= 0
925
+ else
926
+ session[:dfs][form_name] = time
927
+ if session[:dfs].size > 3
928
+ oldest = session[:dfs].invert.min
929
+ session[:dfs].delete(oldest.last)
930
+ end
931
+ end
932
+ end
933
+
901
934
  end
@@ -85,7 +85,7 @@ def dc_get_site
85
85
  uri = URI.parse(request.url)
86
86
  cache_key = ['dc_site', uri.host]
87
87
 
88
- @site = dc_cache_read(cache_key)
88
+ @site = DrgCms.cache_read(cache_key)
89
89
  return @site if @site
90
90
 
91
91
  @site = DcSite.find_by(name: uri.host)
@@ -100,7 +100,7 @@ def dc_get_site
100
100
  @site = DcSite.find_by(name: @site.alias_for) if @site
101
101
  end
102
102
  @site = nil if @site && !@site.active # site is disabled
103
- dc_cache_write(cache_key, @site)
103
+ DrgCms.cache_write(cache_key, @site)
104
104
  end
105
105
 
106
106
  ##########################################################################
@@ -160,15 +160,10 @@ protected
160
160
  # if dc_user_can(DcPermission::CAN_VIEW, params[:table]) then ...
161
161
  ############################################################################
162
162
  def dc_user_can(permission, table = params[:table])
163
- table = table.underscore
164
- cache_key = ['dc_permission', table, dc_get_site.id]
165
- permissions = DrgCms.cache_read(cache_key)
166
- if permissions.nil?
167
- permissions = DcPermission.permissions_for_table(table)
168
- DrgCms.cache_write(cache_key, permissions)
169
- end
170
163
  return false if session[:user_roles].nil?
171
164
 
165
+ table = table.underscore
166
+ permissions = DrgCms.cache_read(['dc_permission', table, dc_get_site.id]) { DcPermission.permissions_for_table(table) }
172
167
  session[:user_roles].inject(false) { |r, rule| break true if permissions[rule] && permissions[rule] >= permission }
173
168
  end
174
169
 
@@ -800,7 +795,7 @@ private
800
795
  #
801
796
  # @return [Boolean] : True if redis cache store is active
802
797
  ########################################################################
803
- def redis_cache_store?
798
+ def xredis_cache_store?
804
799
  (Rails.application.config.cache_store.first == :redis_cache_store) rescue false
805
800
  end
806
801
 
@@ -809,31 +804,33 @@ end
809
804
  #
810
805
  # @return [Object] : Redis object
811
806
  ########################################################################
812
- def redis
807
+ def xredis
813
808
  Rails.cache.redis
814
809
  end
815
810
 
816
811
  ########################################################################
817
- # Extends DRGCMS form file. Extended file is processed first and then merged
812
+ # Extends DRG CMS form file. Extended file is processed first and then merged
818
813
  # with code in this form file. Form can extend only single form file.
819
814
  #
820
815
  # [Parameters:]
821
816
  # [extend_option] : Value of @form['extend'] option
822
817
  ########################################################################
823
818
  def dc_form_extend(extend_option)
824
- form_file_name = CmsHelper.form_file_find(extend_option)
825
- @form_js << read_js_drg_form(form_file_name)
826
- form = YAML.load_file( form_file_name )
827
- @form = CmsHelper.forms_merge(form, @form)
828
- # If combined form contains tabs and fields options, merge fields into tabs
829
- if @form['form']['tabs'] && @form['form']['fields']
830
- @form['form']['tabs']['fields'] = @form['form']['fields']
831
- @form['form']['fields'] = nil
819
+ extend_option.chomp.split(',').each do |a_file|
820
+ form_file_name = CmsHelper.form_file_find(a_file.strip)
821
+ @form_js << read_js_drg_form(form_file_name)
822
+ form = YAML.load_file( form_file_name )
823
+ @form = CmsHelper.forms_merge(form, @form)
824
+ # If combined form contains tabs and fields options, move fields into fields tab
825
+ if @form.dig('form', 'tabs') && @form.dig('form', 'fields')
826
+ @form['form']['tabs']['fields'] = @form['form']['fields']
827
+ @form['form']['fields'] = nil
828
+ end
832
829
  end
833
830
  end
834
831
 
835
832
  ########################################################################
836
- # Include code from another DRGCMS form file. Included code is merged
833
+ # Include code from another DRG CMS form file. Included code is merged
837
834
  # with current form file code. Form can include more than one other DRGCMS forms.
838
835
  #
839
836
  # [Parameters:]