headmin 0.3.4 → 0.4.0

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 (157) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +27 -0
  3. data/.gitignore +14 -0
  4. data/.nvmrc +1 -0
  5. data/CHANGELOG.md +24 -0
  6. data/Gemfile +7 -4
  7. data/Gemfile.lock +171 -3
  8. data/README.md +7 -0
  9. data/Rakefile +1 -7
  10. data/app/assets/javascripts/headmin/config/i18n.js +9 -9
  11. data/app/assets/javascripts/headmin/controllers/autocomplete_controller.js +255 -0
  12. data/app/assets/javascripts/headmin/controllers/blocks_controller.js +74 -79
  13. data/app/assets/javascripts/headmin/controllers/date_range_controller.js +24 -24
  14. data/app/assets/javascripts/headmin/controllers/dropzone_controller.js +23 -25
  15. data/app/assets/javascripts/headmin/controllers/file_preview_controller.js +237 -237
  16. data/app/assets/javascripts/headmin/controllers/filter_controller.js +44 -44
  17. data/app/assets/javascripts/headmin/controllers/filters_controller.js +57 -61
  18. data/app/assets/javascripts/headmin/controllers/flatpickr_controller.js +29 -29
  19. data/app/assets/javascripts/headmin/controllers/hello_controller.js +3 -3
  20. data/app/assets/javascripts/headmin/controllers/notification_controller.js +7 -6
  21. data/app/assets/javascripts/headmin/controllers/popup_controller.js +51 -52
  22. data/app/assets/javascripts/headmin/controllers/redactorx_controller.js +36 -9
  23. data/app/assets/javascripts/headmin/controllers/repeater_controller.js +122 -125
  24. data/app/assets/javascripts/headmin/controllers/select_controller.js +40 -39
  25. data/app/assets/javascripts/headmin/controllers/table_actions_controller.js +100 -101
  26. data/app/assets/javascripts/headmin/controllers/table_controller.js +115 -115
  27. data/app/assets/javascripts/headmin/index.js +38 -35
  28. data/app/assets/javascripts/headmin.js +243 -34
  29. data/app/assets/stylesheets/headmin/forms/autocomplete.scss +21 -0
  30. data/app/assets/stylesheets/headmin/forms/file.scss +46 -0
  31. data/app/assets/stylesheets/headmin/forms/repeater.scss +62 -0
  32. data/app/assets/stylesheets/headmin/forms/search.scss +12 -0
  33. data/app/assets/stylesheets/headmin/forms.scss +11 -0
  34. data/app/assets/stylesheets/headmin/general.scss +5 -0
  35. data/app/assets/stylesheets/headmin/overrides/bootstrap.scss +5 -3
  36. data/app/assets/stylesheets/headmin/overrides/redactorx.scss +74 -0
  37. data/app/assets/stylesheets/headmin/popup.scss +1 -0
  38. data/app/assets/stylesheets/headmin/syntax.scss +36 -349
  39. data/app/assets/stylesheets/headmin/table.scss +1 -1
  40. data/app/assets/stylesheets/headmin/utilities/buttons.scss +19 -0
  41. data/app/assets/stylesheets/headmin/utilities/dropzone.scss +72 -0
  42. data/app/assets/stylesheets/headmin/utilities.scss +2 -68
  43. data/app/assets/stylesheets/headmin.css +205 -205
  44. data/app/assets/stylesheets/headmin.scss +1 -1
  45. data/app/helpers/headmin/admin_helper.rb +0 -1
  46. data/app/helpers/headmin/form_helper.rb +2 -8
  47. data/app/models/concerns/headmin/blockable.rb +1 -1
  48. data/app/models/concerns/headmin/field.rb +1 -0
  49. data/app/models/concerns/headmin/form/autocompletable.rb +38 -0
  50. data/app/models/concerns/headmin/form/hintable.rb +19 -0
  51. data/app/models/concerns/headmin/form/input_groupable.rb +23 -0
  52. data/app/models/concerns/headmin/form/labelable.rb +33 -0
  53. data/app/models/concerns/headmin/form/listable.rb +28 -0
  54. data/app/models/concerns/headmin/form/placeholderable.rb +13 -0
  55. data/app/models/concerns/headmin/form/validatable.rb +40 -0
  56. data/app/models/concerns/headmin/form/wrappable.rb +21 -0
  57. data/app/models/headmin/.DS_Store +0 -0
  58. data/app/models/headmin/blocks_view.rb +15 -0
  59. data/app/models/headmin/form/blocks_view.rb +29 -0
  60. data/app/models/headmin/form/checkbox_view.rb +52 -0
  61. data/app/models/headmin/form/date_range_view.rb +25 -0
  62. data/app/models/headmin/form/date_view.rb +45 -0
  63. data/app/models/headmin/form/email_view.rb +48 -0
  64. data/app/models/headmin/form/file_view.rb +116 -0
  65. data/app/models/headmin/form/flatpickr_range_view.rb +102 -0
  66. data/app/models/headmin/form/flatpickr_view.rb +37 -0
  67. data/app/models/headmin/form/hidden_view.rb +10 -0
  68. data/app/models/headmin/form/hint_view.rb +6 -0
  69. data/app/models/headmin/form/input_group_view.rb +19 -0
  70. data/app/models/headmin/form/label_view.rb +24 -0
  71. data/app/models/headmin/form/number_view.rb +49 -0
  72. data/app/models/headmin/form/password_view.rb +44 -0
  73. data/app/models/headmin/form/redactorx_view.rb +59 -0
  74. data/app/models/headmin/form/search_view.rb +48 -0
  75. data/app/models/headmin/form/select_view.rb +62 -0
  76. data/app/models/headmin/form/switch_view.rb +23 -0
  77. data/app/models/headmin/form/text_view.rb +48 -0
  78. data/app/models/headmin/form/textarea_view.rb +44 -0
  79. data/app/models/headmin/form/url_view.rb +48 -0
  80. data/app/models/headmin/form/wrapper_view.rb +19 -0
  81. data/app/models/headmin/form/wysiwyg_view.rb +17 -0
  82. data/app/models/headmin/{thumbnail.rb → thumbnail_view.rb} +6 -1
  83. data/app/models/view_model.rb +58 -0
  84. data/app/views/headmin/_blocks.html.erb +13 -9
  85. data/app/views/headmin/_heading.html.erb +7 -1
  86. data/app/views/headmin/_thumbnail.html.erb +1 -37
  87. data/app/views/headmin/forms/_autocomplete.html.erb +11 -0
  88. data/app/views/headmin/forms/_blocks.html.erb +16 -17
  89. data/app/views/headmin/forms/_checkbox.html.erb +24 -29
  90. data/app/views/headmin/forms/_datalist.html.erb +3 -0
  91. data/app/views/headmin/forms/_date.html.erb +24 -24
  92. data/app/views/headmin/forms/_date_range.html.erb +19 -21
  93. data/app/views/headmin/forms/_email.html.erb +27 -32
  94. data/app/views/headmin/forms/_errors.html.erb +2 -3
  95. data/app/views/headmin/forms/_file.html.erb +84 -181
  96. data/app/views/headmin/forms/_flatpickr.html.erb +19 -20
  97. data/app/views/headmin/forms/_flatpickr_range.html.erb +28 -37
  98. data/app/views/headmin/forms/_hidden.html.erb +9 -10
  99. data/app/views/headmin/forms/_hint.html.erb +16 -0
  100. data/app/views/headmin/forms/_input_group.html.erb +21 -0
  101. data/app/views/headmin/forms/_label.html.erb +5 -13
  102. data/app/views/headmin/forms/_number.html.erb +23 -35
  103. data/app/views/headmin/forms/_password.html.erb +21 -30
  104. data/app/views/headmin/forms/_redactorx.html.erb +21 -40
  105. data/app/views/headmin/forms/_repeater.html.erb +55 -60
  106. data/app/views/headmin/forms/_search.html.erb +43 -0
  107. data/app/views/headmin/forms/_select.html.erb +24 -49
  108. data/app/views/headmin/forms/_switch.html.erb +29 -0
  109. data/app/views/headmin/forms/_text.html.erb +42 -96
  110. data/app/views/headmin/forms/_textarea.html.erb +21 -32
  111. data/app/views/headmin/forms/_url.html.erb +26 -31
  112. data/app/views/headmin/forms/_validation.html.erb +10 -13
  113. data/app/views/headmin/forms/_wrapper.html.erb +9 -0
  114. data/app/views/headmin/forms/_wysiwyg.html.erb +28 -0
  115. data/app/views/headmin/forms/autocomplete/_item.html.erb +3 -0
  116. data/app/views/headmin/forms/autocomplete/_list.html.erb +3 -0
  117. data/app/views/headmin/forms/fields/_group.html.erb +5 -3
  118. data/app/views/headmin/forms/repeater/_row.html.erb +4 -4
  119. data/bin/console +0 -1
  120. data/config/locales/headmin/forms/en.yml +0 -11
  121. data/config/locales/headmin/forms/nl.yml +0 -11
  122. data/esbuild-css.js +18 -18
  123. data/esbuild-js.js +8 -8
  124. data/headmin.gemspec +1 -3
  125. data/lib/generators/templates/controllers/auth/confirmations_controller.rb +0 -2
  126. data/lib/generators/templates/controllers/auth/omniauth_callbacks_controller.rb +0 -2
  127. data/lib/generators/templates/controllers/auth/passwords_controller.rb +0 -2
  128. data/lib/generators/templates/controllers/auth/registrations_controller.rb +0 -2
  129. data/lib/generators/templates/controllers/auth/sessions_controller.rb +0 -2
  130. data/lib/generators/templates/controllers/auth/unlocks_controller.rb +0 -2
  131. data/lib/headmin/version.rb +1 -3
  132. data/lib/headmin.rb +0 -2
  133. data/package-lock.json +5359 -0
  134. data/package.json +12 -4
  135. data/view_model_benchmark.rb +74 -0
  136. data/yarn-error.log +17 -12
  137. data/yarn.lock +1575 -31
  138. metadata +62 -24
  139. data/app/assets/stylesheets/headmin/form.scss +0 -132
  140. data/app/assets/stylesheets/headmin/overrides/redactorx.css +0 -3
  141. data/app/helpers/headmin/documentation_helper.rb +0 -35
  142. data/app/models/headmin/documentation_renderer.rb +0 -32
  143. data/app/models/headmin/form/base.rb +0 -78
  144. data/app/models/headmin/form/text.rb +0 -51
  145. data/app/services/block_service.rb +0 -72
  146. data/app/views/headmin/_card.html.erb +0 -52
  147. data/app/views/headmin/forms/_actions.html.erb +0 -28
  148. data/app/views/headmin/forms/_base.html.erb +0 -114
  149. data/app/views/headmin/forms/_image.html.erb +0 -21
  150. data/app/views/headmin/forms/_video.html.erb +0 -21
  151. data/app/views/headmin/forms/actions/_destroy.html.erb +0 -13
  152. data/app/views/headmin/forms/actions/_save.html.erb +0 -12
  153. data/app/views/headmin/forms/actions/_view.html.erb +0 -15
  154. data/docs/blocks-and-fields.md +0 -54
  155. data/docs/blocks.md +0 -48
  156. data/docs/devise.md +0 -41
  157. data/docs/fields.md +0 -79
@@ -1,102 +1,97 @@
1
- import {Controller} from "@hotwired/stimulus"
2
- import Sortable from "sortablejs";
1
+ import { Controller } from '@hotwired/stimulus'
2
+ import Sortable from 'sortablejs'
3
3
 
4
4
  export default class extends Controller {
5
- static get targets() {
6
- return ["templateBlock", "block", "blocks", "templateEmpty", "button", "buttons"]
7
- }
8
-
9
- connect() {
10
- new Sortable(this.blocksTarget, {
11
- onEnd: () => {
12
- this.reorderPositions()
13
- }
14
- })
15
-
16
- this.toggleEmpty()
17
- }
5
+ static get targets () {
6
+ return ['templateBlock', 'block', 'blocks', 'templateEmpty', 'button', 'buttons']
7
+ }
18
8
 
19
- toggleEmpty() {
20
- if(this.blockCount() > 0) {
21
- const empty = this.blocksTarget.querySelector('#blocks-empty')
22
- if(empty) {
23
- empty.remove()
24
- }
25
- } else {
26
- const empty = this.templateEmptyTarget.innerHTML
27
- this.blocksTarget.insertAdjacentHTML('beforeend', empty)
28
- }
9
+ connect () {
10
+ Sortable.create(this.blocksTarget, {
11
+ onEnd: () => {
12
+ this.reorderPositions()
13
+ }
14
+ })
15
+
16
+ this.toggleEmpty()
17
+ }
18
+
19
+ toggleEmpty () {
20
+ if (this.blockCount() > 0) {
21
+ const empty = this.blocksTarget.querySelector('#blocks-empty')
22
+ if (empty) {
23
+ empty.remove()
24
+ }
25
+ } else {
26
+ const empty = this.templateEmptyTarget.innerHTML
27
+ this.blocksTarget.insertAdjacentHTML('beforeend', empty)
29
28
  }
29
+ }
30
30
 
31
- add(event) {
32
- event.preventDefault()
33
- const blockType = event.target.dataset.type
34
- let html = this.templateBlockTargets.filter(blockTarget => blockTarget.id === blockType)[0].innerHTML
35
-
36
- html = this.setPosition(html)
37
-
38
- const element = this.blocksTarget.querySelector(`li[data-position='${event.target.dataset.position}']`)
31
+ add (event) {
32
+ event.preventDefault()
33
+ const blockType = event.target.dataset.type
34
+ let html = this.templateBlockTargets.filter(blockTarget => blockTarget.id === blockType)[0].innerHTML
39
35
 
40
- if (element) {
41
- element.insertAdjacentHTML('afterend', html)
42
- }
43
- else {
44
- this.blocksTarget.insertAdjacentHTML('afterbegin', html)
45
- }
36
+ html = this.setPosition(html)
46
37
 
47
- // Dispatch an event
48
- this.blocksTarget.dispatchEvent(new CustomEvent('headmin:reinit', {bubbles: true}))
38
+ const element = this.blocksTarget.querySelector(`li[data-position='${event.target.dataset.position}']`)
49
39
 
50
- this.reorderPositions()
51
- this.toggleEmpty()
40
+ if (element) {
41
+ element.insertAdjacentHTML('afterend', html)
42
+ } else {
43
+ this.blocksTarget.insertAdjacentHTML('afterbegin', html)
52
44
  }
53
45
 
54
- remove(event) {
55
- event.preventDefault()
46
+ this.reorderPositions()
47
+ this.toggleEmpty()
48
+ }
56
49
 
57
- const block = event.target.closest(".list-group-item")
58
- const destroyInput = block.querySelector("input[name*='_destroy']")
50
+ remove (event) {
51
+ event.preventDefault()
59
52
 
60
- if (destroyInput) {
61
- destroyInput.value = 1
62
- block.style.display = 'none'
63
- } else {
64
- block.remove()
65
- }
53
+ const block = event.target.closest('.list-group-item')
54
+ const destroyInput = block.querySelector("input[name*='_destroy']")
66
55
 
67
- this.reorderPositions()
68
- this.toggleEmpty()
56
+ if (destroyInput) {
57
+ destroyInput.value = 1
58
+ block.style.display = 'none'
59
+ } else {
60
+ block.remove()
69
61
  }
70
62
 
71
- setPosition(html) {
72
- const position = this.retrieveLastPosition() + 1
63
+ this.reorderPositions()
64
+ this.toggleEmpty()
65
+ }
73
66
 
74
- const regex = new RegExp('99999', "g");
75
- return html.replace(regex, position)
76
- }
67
+ setPosition (html) {
68
+ const position = this.retrieveLastPosition() + 1
77
69
 
78
- retrieveLastPosition() {
79
- const blocks = Array.from(this.blockTargets)
80
- if (blocks.length < 1) {
81
- return 0
82
- }
70
+ return html.replace(/99999/g, position)
71
+ }
83
72
 
84
- const lastBlock = blocks.slice(-1)[0]
85
- return parseInt(lastBlock.querySelector("[name*='position']").value)
73
+ retrieveLastPosition () {
74
+ const blocks = Array.from(this.blockTargets)
75
+ if (blocks.length < 1) {
76
+ return 0
86
77
  }
87
78
 
88
- reorderPositions() {
89
- for (let [index, block] of this.blockTargets.entries()) {
90
- this.changePositionInfo(block, index)
91
- }
92
- }
79
+ const lastBlock = blocks.slice(-1)[0]
80
+ return parseInt(lastBlock.querySelector("[name*='position']").value)
81
+ }
93
82
 
94
- changePositionInfo(block, index) {
95
- block.setAttribute("data-position", index)
96
- block.querySelector("input[name*='position']").value = index
83
+ reorderPositions () {
84
+ for (const [index, block] of this.blockTargets.entries()) {
85
+ this.changePositionInfo(block, index)
97
86
  }
87
+ }
98
88
 
99
- blockCount() {
100
- return this.blockTargets.length;
101
- }
102
- }
89
+ changePositionInfo (block, index) {
90
+ block.setAttribute('data-position', index)
91
+ block.querySelector("input[name*='position']").value = index
92
+ }
93
+
94
+ blockCount () {
95
+ return this.blockTargets.length
96
+ }
97
+ }
@@ -1,32 +1,32 @@
1
- import {Controller} from "@hotwired/stimulus"
1
+ import { Controller } from '@hotwired/stimulus'
2
2
 
3
3
  export default class extends Controller {
4
- static get targets() {
5
- return ["dateInput", "startDateInput", "endDateInput"]
6
- }
4
+ static get targets () {
5
+ return ['dateInput', 'startDateInput', 'endDateInput']
6
+ }
7
7
 
8
- update(event) {
9
- const flatpickr = event.target._flatpickr
10
- const startDate = flatpickr.selectedDates[0]
11
- const endDate = flatpickr.selectedDates[1]
8
+ update (event) {
9
+ const flatpickr = event.target._flatpickr
10
+ const startDate = flatpickr.selectedDates[0]
11
+ const endDate = flatpickr.selectedDates[1]
12
12
 
13
- this.setStartDateInputValue(this.formatDate(startDate))
14
- this.setEndDateInputValue(this.formatDate(endDate))
15
- }
13
+ this.setStartDateInputValue(this.formatDate(startDate))
14
+ this.setEndDateInputValue(this.formatDate(endDate))
15
+ }
16
16
 
17
- setStartDateInputValue(value) {
18
- this.startDateInputTarget.value = value
19
- }
17
+ setStartDateInputValue (value) {
18
+ this.startDateInputTarget.value = value
19
+ }
20
20
 
21
- setEndDateInputValue(value) {
22
- this.endDateInputTarget.value = value
23
- }
21
+ setEndDateInputValue (value) {
22
+ this.endDateInputTarget.value = value
23
+ }
24
24
 
25
- formatDate(date) {
26
- if(date instanceof Date) {
27
- return date.toLocaleDateString('nl-BE', {day: '2-digit', month: '2-digit', year: 'numeric'})
28
- } else {
29
- return null;
30
- }
25
+ formatDate (date) {
26
+ if (date instanceof Date) {
27
+ return date.toLocaleDateString('nl-BE', { day: '2-digit', month: '2-digit', year: 'numeric' })
28
+ } else {
29
+ return null
31
30
  }
32
- }
31
+ }
32
+ }
@@ -1,33 +1,31 @@
1
- import {Controller} from "@hotwired/stimulus"
1
+ import { Controller } from '@hotwired/stimulus'
2
2
 
3
3
  // References:
4
4
  // https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API
5
5
 
6
6
  export default class extends Controller {
7
- static get targets() {
8
- return ["input"]
9
- }
7
+ static get targets () {
8
+ return ['input']
9
+ }
10
10
 
11
- connect() {
12
- this.element.classList.add('h-dropzone')
11
+ connect () {
12
+ // Drag
13
+ this.inputTarget.addEventListener('dragover', (event) => {
14
+ this.element.classList.add('focus')
15
+ })
16
+ this.inputTarget.addEventListener('dragleave', (event) => {
17
+ this.element.classList.remove('focus')
18
+ })
19
+ this.inputTarget.addEventListener('drop', (event) => {
20
+ this.element.classList.remove('focus')
21
+ })
13
22
 
14
- // Drag
15
- this.inputTarget.addEventListener('dragover', (event) => {
16
- this.element.classList.add('dragover')
17
- })
18
- this.inputTarget.addEventListener('dragleave', (event) => {
19
- this.element.classList.remove('dragover')
20
- })
21
- this.inputTarget.addEventListener('drop', (event) => {
22
- this.element.classList.remove('dragover')
23
- })
24
-
25
- // Focus
26
- this.inputTarget.addEventListener('focusin', (event) => {
27
- this.element.classList.add('active')
28
- })
29
- this.inputTarget.addEventListener('focusout', (event) => {
30
- this.element.classList.remove('active')
31
- })
32
- }
23
+ // Focus
24
+ this.inputTarget.addEventListener('focusin', (event) => {
25
+ this.element.classList.add('focus')
26
+ })
27
+ this.inputTarget.addEventListener('focusout', (event) => {
28
+ this.element.classList.remove('focus')
29
+ })
30
+ }
33
31
  }