drg_cms 0.6.1.0 → 0.6.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +25 -10
  3. data/app/assets/fonts/ibm-plex-sans-300.woff2 +0 -0
  4. data/app/assets/fonts/ibm-plex-sans-400.woff2 +0 -0
  5. data/app/assets/fonts/ibm-plex-sans-500.woff2 +0 -0
  6. data/app/assets/fonts/ibm-plex-sans-600.woff2 +0 -0
  7. data/app/assets/fonts/ibm-plex-sans-700.woff2 +0 -0
  8. data/app/assets/fonts/ibm-plex-sans-italic.woff2 +0 -0
  9. data/app/assets/javascripts/drg_cms/drg_cms.js +178 -55
  10. data/app/assets/stylesheets/drg_cms/drg_cms.css +218 -94
  11. data/app/assets/stylesheets/drg_cms/select-multiple.css +1 -1
  12. data/app/controllers/cmsedit_controller.rb +29 -24
  13. data/app/controllers/dc_application_controller.rb +78 -166
  14. data/app/controllers/dc_common_controller.rb +56 -47
  15. data/app/controls/dc_help_control.rb +12 -0
  16. data/app/controls/dc_report.rb +7 -9
  17. data/app/controls/design_element_settings_control.rb +1 -1
  18. data/app/forms/all_options.yml +25 -6
  19. data/app/forms/dc_big_table.yml +0 -2
  20. data/app/forms/dc_big_table_value.yml +0 -2
  21. data/app/forms/dc_design.yml +1 -2
  22. data/app/forms/dc_folder_permission.yml +0 -2
  23. data/app/forms/dc_help_1.yml +2 -1
  24. data/app/forms/dc_json_ld.yml +0 -3
  25. data/app/forms/dc_menu.yml +6 -12
  26. data/app/forms/dc_menu_item.yml +1 -3
  27. data/app/forms/dc_page.yml +5 -2
  28. data/app/forms/dc_policy.yml +2 -5
  29. data/app/forms/dc_poll.yml +10 -16
  30. data/app/forms/dc_seo.yml +1 -2
  31. data/app/forms/dc_simple_menu.yml +1 -2
  32. data/app/forms/dc_site.yml +5 -7
  33. data/app/helpers/cms_common_helper.rb +2 -3
  34. data/app/helpers/cms_edit_helper.rb +41 -31
  35. data/app/helpers/cms_helper.rb +6 -6
  36. data/app/helpers/cms_index_helper.rb +79 -34
  37. data/app/helpers/dc_application_helper.rb +99 -85
  38. data/app/models/concerns/dc_page_concern.rb +3 -2
  39. data/app/models/concerns/dc_piece_concern.rb +1 -1
  40. data/app/models/concerns/dc_site_concern.rb +10 -4
  41. data/app/models/concerns/dc_user_concern.rb +3 -3
  42. data/app/models/dc_big_table.rb +2 -2
  43. data/app/models/dc_filter.rb +28 -22
  44. data/app/models/dc_site.rb +0 -1
  45. data/app/models/dc_temp.rb +7 -0
  46. data/app/models/drgcms_form_fields/comment.rb +11 -2
  47. data/app/models/drgcms_form_fields/date_picker.rb +2 -0
  48. data/app/models/drgcms_form_fields/drgcms_field.rb +2 -1
  49. data/app/models/drgcms_form_fields/embedded.rb +4 -2
  50. data/app/models/drgcms_form_fields/number_field.rb +4 -3
  51. data/app/models/drgcms_form_fields/readonly.rb +13 -17
  52. data/app/models/drgcms_form_fields/select.rb +16 -18
  53. data/app/models/drgcms_form_fields/text_autocomplete.rb +39 -23
  54. data/app/renderers/dc_page_renderer.rb +7 -6
  55. data/app/renderers/dc_poll_renderer.rb +16 -20
  56. data/app/views/cmsedit/_edit_stuff.html.erb +5 -2
  57. data/app/views/cmsedit/_form.html.erb +3 -2
  58. data/app/views/cmsedit/_result.html.erb +21 -18
  59. data/app/views/cmsedit/edit.html.erb +2 -1
  60. data/app/views/cmsedit/index.html.erb +1 -1
  61. data/app/views/cmsedit/new.html.erb +3 -2
  62. data/app/views/dc_common/_help.html.erb +12 -3
  63. data/app/views/layouts/cms.html.erb +3 -5
  64. data/config/locales/drgcms_en.yml +5 -2
  65. data/config/locales/drgcms_sl.yml +5 -2
  66. data/config/locales/models_en.yml +2 -0
  67. data/config/locales/models_sl.yml +5 -3
  68. data/drg_cms.gemspec +16 -16
  69. data/lib/drg_cms/version.rb +1 -1
  70. data/lib/drg_cms.rb +46 -12
  71. metadata +35 -29
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bdd59e26395442cc8bec436e5a05940e762f373bfd30a83d5ddca87b443627a4
4
- data.tar.gz: be25c10a78a2fc6ed37f5e02484cfbff1d28b8cadb8546432f5b67665578006f
3
+ metadata.gz: 36ffde8dc003d78a30e69a2a1f45530841829c5b66d247e7bcece0d3c94a1a15
4
+ data.tar.gz: 3e1c6a0762f22cce3500de3c4ee0e2258c25f6f39a2aa3dc82f3febd15535449
5
5
  SHA512:
6
- metadata.gz: 838507481e4d09277049b1468ddbc18b2e40cc32b5fdcac38224169ab1b761aee445ebd93c0747c409db4f87298e986c9472552bc60d69f7d73031bea58a9c31
7
- data.tar.gz: 41965e0a604a632d975d3081d85d4e1d775ccb01a7e6dbbfad49be732e89f1223b20376024897b13df742bd6b38eab8c4a8f541d5270f127660dfd23e5edd27e
6
+ metadata.gz: 562e2196260eefc0999249e1c0e871cda94b7fd2d303482d39314ec2eb6ae5ae4b32545b8a85c4434a28042d9c2c8b9f2c9dc0a1b1be3a0ec49d20cddece7aef
7
+ data.tar.gz: 03d0849a4040d4b99cf4b8c3b682e77b6c333ad562453700703b49a18d408d2e88555777051cf0b8f61d059ce4bf7e9f1670104f3e3ad786ea226c69c7217c08
data/README.md CHANGED
@@ -1,12 +1,26 @@
1
1
  # DrgCms
2
2
 
3
- DRG CMS is advanced way of programming application for Ruby on Rails. Instead of creating controllers and views for each collection (table) model, DRG CMS introduces single Cmsedit controller which uses DRG Forms to control CRUD database operations.
3
+ DRG CMS is advanced way of programming application for Ruby on Rails.
4
+ Instead of creating controllers and views for each collection (table),
5
+ DRG CMS introduces single Cmsedit controller. All CRUD database actions are
6
+ controlled by DRG Forms file, which can have hundreds of data entry fields
7
+ and still be easy to maintain and update.
4
8
 
5
- DRG CMS uses Mongo DB, leading NO-SQL document database, as database back-end with a help of mongoid gem. Mongoid's flexible document model defines all document fields, indexes, dependencies, validations in single model file with no Rails migrations required.
6
-
7
- DRG CMS can be used for rapid development of complex, data-entry intensive web sites as well as building your private, in-house, Intranet applications.
8
-
9
- DRG CMS has built-in user friendly role based database access system and can be easly extended with help of Ruby on Rails plugin system.
9
+ DRG CMS uses MongoDB, leading NO-SQL document database, as database back-end
10
+ with a help of mongoid gem. Mongoid's flexible document model defines all
11
+ document fields, indexes, dependencies, validations in single model source file with
12
+ no Rails migrations required. When collection model is defined, data entry DRG Form
13
+ can easily be generated with form generator.
14
+
15
+ DRG CMS can be used for rapid development of complex, data-entry intensive web
16
+ sites as well as building your private, in-house, Intranet applications. At
17
+ the same time it can be used as CMS system with support for running
18
+ multiple web sites on single Ruby on Rails instance.
19
+
20
+ DRG CMS has built-in user friendly role based database access system. Administrator
21
+ defines roles and roles rights (no access, can read, can edit) as web site policies.
22
+ Roles are then assigned to users and policies can be assigned to documents (web pages)
23
+ or even parts of a document.
10
24
 
11
25
  Project Tracking
12
26
  ----------------
@@ -16,9 +30,10 @@ Project Tracking
16
30
  Compatibility
17
31
  -------------
18
32
 
19
- DRG CMS is tested against Ruby 2.2 and higher, Rails 5.0 and higher, Mongoid 6, MongoDB 3.0, 3.2, 3.4
20
-
21
- Version from 0.5.51 and higher requires Ruby 2.4.x and Rails 5.1.x
33
+ DRG CMS is being actively developed since 2012 and has been live tested in production
34
+ since beginning. It runs against latest technology Ruby (3.0), Rails (6.1)
35
+ and MongoDB (4.4) and had so far little or no problems advancing to latest versions
36
+ of required programs.
22
37
 
23
38
  Documentation
24
39
  -------------
@@ -29,7 +44,7 @@ Please see the DRG CMS website for up-to-date documentation:
29
44
  License (MIT LICENCE)
30
45
  ---------------------
31
46
 
32
- Copyright (c) 2012-2018 Damjan Rems
47
+ Copyright (c) 2012-2021 Damjan Rems
33
48
 
34
49
  Permission is hereby granted, free of charge, to any person obtaining
35
50
  a copy of this software and associated documentation files (the
@@ -184,12 +184,12 @@ $(function() {
184
184
  *******************************************************************/
185
185
 
186
186
  process_json_result = function(json) {
187
- var i, w, operation, selector, msg_div, field;
187
+ let i, w, operation, selector, msg_div, field;
188
188
  $.each(json, function(key, value) {
189
189
  i = key.search('_');
190
190
  if (i > 1) {
191
- operation = key.substring(0,i);
192
- selector = key.substring(i+1,100);
191
+ operation = key.substring(0, i);
192
+ selector = key.substring(i+1, 100);
193
193
  } else {
194
194
  operation = key;
195
195
  selector = '';
@@ -207,7 +207,7 @@ process_json_result = function(json) {
207
207
  // select field
208
208
  } else if (field.is('select')) {
209
209
  // options for select field
210
- if (value && value.isArray) {
210
+ if (Array.isArray(value)) {
211
211
  field.empty();
212
212
  $.each(value, function(index, v) {
213
213
  field.append( new Option(v[0], v[1]) );
@@ -226,6 +226,11 @@ process_json_result = function(json) {
226
226
  }
227
227
  break;
228
228
 
229
+ /**** transfer focus to field ****/
230
+ case 'focus':
231
+ $('#' + value).focus();
232
+ break;
233
+
229
234
  /**** display message ****/
230
235
  case 'msg':
231
236
  let msg_div = 'dc-form-' + selector;
@@ -240,9 +245,14 @@ process_json_result = function(json) {
240
245
 
241
246
  /**** display popup message ****/
242
247
  case 'popup':
243
- $('#popup').html(value);
244
- $('#popup').bPopup({ speed: 650, transition: 'slideUp'});
245
- break;
248
+ if (selector == 'url') {
249
+ $('#popup').bPopup({ loadUrl: value });
250
+ }
251
+ else {
252
+ $('#popup').html(value);
253
+ $('#popup').bPopup({speed: 650, transition: 'slideUp', position: ['auto',1]});
254
+ }
255
+ break;
246
256
 
247
257
  /**** update div ****/
248
258
  case '#div+':
@@ -268,13 +278,16 @@ process_json_result = function(json) {
268
278
  case 'url':
269
279
  window.location.href = value;
270
280
  break;
281
+ case 'parenturl':
282
+ parent.location.href = value;
283
+ break;
271
284
  case 'alert':
272
285
  alert(value);
273
286
  break;
274
287
  case 'window':
275
288
  if (value == 'close') { window.close();
276
289
  } else if (value == 'reload') {
277
- location.reload();
290
+ window.location.href = window.location.href;
278
291
  } else {
279
292
  w = window.open(value, selector);
280
293
  w.focus();
@@ -294,10 +307,12 @@ process_json_result = function(json) {
294
307
  case 'reload':
295
308
  value = value.toString();
296
309
  if (value == 'parent') {
297
- parent.location.reload();
310
+ //parent.location.reload();
311
+ parent.location.href = parent.location.href;
312
+
298
313
  /*** this would be current window (reload: true) ****/
299
314
  } else if (value.length < 5) {
300
- location.reload();
315
+ window.location.href = window.location.href;
301
316
  /*** reload iframe ****/
302
317
  } else {
303
318
  $( '#' + value ).attr('src', $( '#' + value ).attr('src'));
@@ -316,6 +331,17 @@ function dc_reload_window() {
316
331
  location.reload();
317
332
  }
318
333
 
334
+ /*******************************************************************
335
+ * Will open popup window
336
+ *******************************************************************/
337
+ function popup_window(url, title, parent_win, w, h) {
338
+ let y = parent_win.top.outerHeight / 2 + parent_win.top.screenY - (h / 2);
339
+ let x = parent_win.top.outerWidth / 2 + parent_win.top.screenX - (w / 2);
340
+ let win = parent_win.open(url, 'dc_popup', `toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=${w}, height=${h}, top=${y}, left=${x}`);
341
+ win.document.title = title;
342
+ return win;
343
+ }
344
+
319
345
  /*******************************************************************
320
346
  * Will select first editable input field on form. Works only when tab
321
347
  * is selected. Still have to find out, what to do on initial display.
@@ -377,6 +403,15 @@ dc_toggle_div = function(div) {
377
403
  }
378
404
  };
379
405
 
406
+ /*****************************************************************
407
+ * Return value of the input field on a form
408
+ ******************************************************************/
409
+ function dc_get_field_value(field_name) {
410
+ field_name = field_name.replace('record_', '');
411
+ let field = $('[name="record[' + field_name + ']"]');
412
+ return field.val();
413
+ }
414
+
380
415
  /*******************************************************************
381
416
  *
382
417
  *******************************************************************/
@@ -453,13 +488,48 @@ $(document).ready( function() {
453
488
  * Sort action clicked on cmsedit
454
489
  *******************************************************************/
455
490
  $('.drgcms_sort').change( function(e) {
456
- var table = e.target.getAttribute("data-table");
457
- var form = e.target.getAttribute("data-form");
458
- var sort = e.target.value;
491
+ let table = e.target.getAttribute("data-table");
492
+ let form = e.target.getAttribute("data-form");
493
+ if (form === null) form = table;
494
+ let sort = e.target.value;
459
495
  e.target.value = null;
460
496
  window.location.href = "/cmsedit?sort=" + sort + "&table=" + table + "&form_name=" + form;
461
497
  });
462
-
498
+
499
+ /*******************************************************************
500
+ * Click on dc-check-all icon. Check or uncheck all checkboxes
501
+ *******************************************************************/
502
+ $('.dc-check-all').on('click',function(e) {
503
+ let checkboxes = $('.dc-check');
504
+ if ($(this).hasClass('fa-check-square-o')) {
505
+ // check all checkboxes
506
+ checkboxes.each( function() {
507
+ $(this).prop('checked', true);
508
+ $(this).parent().closest('div').addClass('dc-checked');
509
+ });
510
+ $(this).removeClass('fa-check-square-o').addClass('fa-square-o');
511
+ } else {
512
+ // uncheck all checkboxes
513
+ checkboxes.each( function() {
514
+ $(this).prop('checked', false);
515
+ $(this).parent().closest('div').removeClass('dc-checked');
516
+ });
517
+ $(this).removeClass('fa-square-o').addClass('fa-check-square-o');
518
+ }
519
+ });
520
+
521
+ /*******************************************************************
522
+ * Click on dc-check icon. Change color of background of element
523
+ *******************************************************************/
524
+ $('.dc-check').on('click',function(e) {
525
+ let parent = $(this).parent().closest('div');
526
+ if ($(this).prop('checked')) {
527
+ parent.addClass('dc-checked');
528
+ } else {
529
+ parent.removeClass('dc-checked');
530
+ }
531
+ });
532
+
463
533
  /*******************************************************************
464
534
  * Tab clicked on form. Hide old and show selected div.
465
535
  *******************************************************************/
@@ -523,7 +593,7 @@ $(document).ready( function() {
523
593
  $('.iframe_embedded').on('load', function() {
524
594
  let embedded_height = this.contentWindow.document.body.offsetHeight;
525
595
  // workaround. It gets tricky when embedded field is on tab
526
- if (embedded_height == 0) embedded_height = 500;
596
+ if (embedded_height == 0) embedded_height = 50;
527
597
  this.style.height = (embedded_height + 30) + 'px';
528
598
  // resize parent iframe window too
529
599
  let parentWindow = this.contentWindow.parent;
@@ -538,38 +608,55 @@ $(document).ready( function() {
538
608
  $('.dc-link-ajax').on('click', function(e) {
539
609
  // confirmation if required
540
610
  if (confirmation_is_cancled(this)) {return false;}
541
-
611
+
612
+ // url must be specified in data-url
613
+ let url = this.getAttribute("data-url");
614
+ if (url.length < 5) return false;
615
+
542
616
  // check HTML5 validations
543
617
  if ($("form")[0] && !$("form")[0].checkValidity() ) {
544
618
  $("form")[0].reportValidity();
545
619
  return false;
546
620
  }
547
- let req = this.getAttribute("data-request");
548
- // Get values from elements on the page:
549
- if (req == "script") {
550
- eval (this.getAttribute("data-script"));
551
- return false;
552
- }
553
- else if (req == "post") {
554
- data = $('form').serialize();
555
- }
556
- else {
557
- data = {};
558
- req = 'get'; // by default
621
+
622
+ let data = {};
623
+ let request = this.getAttribute("data-request");
624
+ switch (request) {
625
+ case 'script':
626
+ eval(this.getAttribute("data-script"));
627
+ return false;
628
+
629
+ case 'post':
630
+ data = $('form').serialize();
631
+ break;
632
+
633
+ default:
634
+ request = 'get'; // by default
559
635
  }
560
636
 
561
- let url = this.getAttribute("data-url");
562
- if (url.length < 5) return false;
637
+ // add checkbox id-s to data if checkboxes present
638
+ let checkboxes = $('.dc-check');
639
+ if (checkboxes.length > 0) {
640
+ let checked = [];
641
+ checkboxes.each( function() {
642
+ if ($(this).prop('checked')) checked.push($(this).attr("id"));
643
+ })
644
+ data['checked'] = checked;
645
+ }
563
646
 
564
647
  $('.dc-spinner').show();
565
648
  $.ajax({
566
649
  url: url,
567
- type: req,
650
+ type: request,
568
651
  dataType: "json",
569
652
  data: data,
570
653
  success: function(data) {
571
654
  process_json_result(data);
572
655
  $('.dc-spinner').hide();
656
+ },
657
+ error: function (request, status, error) {
658
+ $('.dc-spinner').css('color','red');
659
+ alert(request.responseText);
573
660
  }
574
661
  });
575
662
  });
@@ -593,24 +680,35 @@ $(document).ready( function() {
593
680
  form.setAttribute('action', url);
594
681
  form.setAttribute('method', "post");
595
682
  form.submit();
596
- });
597
-
683
+ });
684
+
598
685
  /*******************************************************************
599
- will open a new window with URL specified.
686
+ Will open a new window with URL specified.
600
687
  ********************************************************************/
601
- $('.dc-window-open').on('click', function(e) {
602
- // confirmation if required
603
- if (confirmation_is_cancled(this)) {return false;}
604
-
605
- var url = this.getAttribute("data-url");
606
- var title = this.getAttribute("title");
607
- var w = 1000;
608
- var h = 800;
609
- var left = (screen.width/2)-(w/2);
610
- var top = (screen.height/2)-(h/2);
611
- var win = window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left);
612
- win.focus();
613
- });
688
+ $('.dc-window-open').on('click', function(e) {
689
+ // confirmation if required
690
+ if (confirmation_is_cancled(this)) { return false; }
691
+
692
+ let url = this.getAttribute("data-url");
693
+ let title = this.getAttribute("title");
694
+ let w = this.getAttribute("data-x") || 1000;
695
+ let h = this.getAttribute("data-y") || 800;
696
+ // add fields values from current formto url
697
+ let fields = this.getAttribute("data-fields");
698
+ if (fields) {
699
+ let form_parms = '?';
700
+ // ? separator already in url
701
+ if (url.match(/\?/)) { form_parms = ''; }
702
+ fields.split(',').forEach( function(field) {
703
+ let value = dc_get_field_value(field);
704
+ if (value) {form_parms += '&' + field + '=' + value;}
705
+ });
706
+ url += form_parms;
707
+ }
708
+
709
+ let win = popup_window(url, title, window, w, h);
710
+ win.focus();
711
+ });
614
712
 
615
713
  /*******************************************************************
616
714
  * Animate button on click
@@ -666,17 +764,28 @@ $(document).ready( function() {
666
764
 
667
765
  $('.dc-link-submit').on('click', function(e) {
668
766
  $('.dc-spinner').show();
669
- });
767
+ });
768
+
769
+ /*******************************************************************
770
+ * Hide spinner when validation error occured
771
+ *******************************************************************/
772
+ $(':input').on("invalid", function(event) {
773
+ $('.dc-spinner').hide();
774
+ });
670
775
 
671
776
  /*******************************************************************
672
777
  * Add button clicked while in edit. Create window dialog for adding new record
673
778
  * into required table. This is helper scenario, when user is selecting
674
779
  * data from with text_autocomplete and data doesn't exist in belongs_to table.
675
780
  *******************************************************************/
676
- $('.in-edit-add').on('click', function(e) {
677
- let url = '/cmsedit/new?table=' + this.getAttribute("data-table");
678
- // I know. It doesn't work as expected. But it will do for now.
679
- w = window.open(url, '', 'chrome=yes,width=800,height=600,resizable,scrollbars=yes,status=1,centerscreen=yes,modal=yes');
781
+ $('.in-edit-add').on('click', function(e) {
782
+ let id = this.getAttribute("data-id");
783
+ let table = this.getAttribute("data-table");
784
+ let url = '/cmsedit/new?window_close=0&table=' + table;
785
+ if (id) {
786
+ url = '/cmsedit/' + id + '/edit?window_close=0&table=' + table;
787
+ }
788
+ let w = popup_window(url, '', window, 1000, 800);
680
789
  w.focus();
681
790
  });
682
791
 
@@ -832,9 +941,16 @@ $(document).ready( function() {
832
941
  * work on all field types.
833
942
  *******************************************************************/
834
943
  $('.record_filter_field_icon').on('click', function(e) {
835
- var field = $('#_record__filter_field');
836
- var url = $(this).parents('span').attr("data-url");
837
- url = url + "&filter_value=" + field.val();
944
+ let field = $('#_record__filter_field');
945
+ let url = $(this).parents('span').attr("data-url");
946
+ let value = null;
947
+
948
+ if (field.is(':checkbox')) {
949
+ value = field.is(':checked'); }
950
+ else {
951
+ value = field.val();
952
+ }
953
+ url = url + "&filter_value=" + value;
838
954
  location.href = url;
839
955
  });
840
956
 
@@ -1066,6 +1182,13 @@ $(document).ready( function() {
1066
1182
  dc_toggle_div(div);
1067
1183
  });
1068
1184
 
1185
+ /*******************************************************************
1186
+ * Show-Hide CMS menu on hamburger click
1187
+ *******************************************************************/
1188
+ $('#menu-hamburger').on('click', function(e) {
1189
+ $('.cmsedit-container #menu').toggleClass('visible');
1190
+ });
1191
+
1069
1192
  });
1070
1193
 
1071
1194
  /*******************************************************************