editable_components 0.1.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 (188) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +64 -0
  4. data/Rakefile +34 -0
  5. data/app/assets/config/editable_components_manifest.js +2 -0
  6. data/app/assets/fonts/editable_components/icomoon.eot +0 -0
  7. data/app/assets/fonts/editable_components/icomoon.svg +24 -0
  8. data/app/assets/fonts/editable_components/icomoon.ttf +0 -0
  9. data/app/assets/fonts/editable_components/icomoon.woff +0 -0
  10. data/app/assets/javascripts/editable_components/application.js +13 -0
  11. data/app/assets/javascripts/editable_components/dragula/dragula.css +22 -0
  12. data/app/assets/javascripts/editable_components/dragula/dragula.js +908 -0
  13. data/app/assets/javascripts/editable_components/dragula/dragula.min.css +1 -0
  14. data/app/assets/javascripts/editable_components/dragula/dragula.min.js +1 -0
  15. data/app/assets/javascripts/editable_components/dropzone/CONTRIBUTING.md +78 -0
  16. data/app/assets/javascripts/editable_components/dropzone/LICENSE +12 -0
  17. data/app/assets/javascripts/editable_components/dropzone/README.md +134 -0
  18. data/app/assets/javascripts/editable_components/dropzone/basic.css +39 -0
  19. data/app/assets/javascripts/editable_components/dropzone/dropzone-amd-module.js +1782 -0
  20. data/app/assets/javascripts/editable_components/dropzone/dropzone.css +388 -0
  21. data/app/assets/javascripts/editable_components/dropzone/dropzone.js +1767 -0
  22. data/app/assets/javascripts/editable_components/dropzone/min/basic.min.css +1 -0
  23. data/app/assets/javascripts/editable_components/dropzone/min/dropzone-amd-module.min.js +2 -0
  24. data/app/assets/javascripts/editable_components/dropzone/min/dropzone.min.css +1 -0
  25. data/app/assets/javascripts/editable_components/dropzone/min/dropzone.min.js +2 -0
  26. data/app/assets/javascripts/editable_components/main.js +280 -0
  27. data/app/assets/javascripts/editable_components/medium-editor/API.md +520 -0
  28. data/app/assets/javascripts/editable_components/medium-editor/CHANGES.md +1043 -0
  29. data/app/assets/javascripts/editable_components/medium-editor/CODE_OF_CONDUCT.md +13 -0
  30. data/app/assets/javascripts/editable_components/medium-editor/CONTRIBUTING.md +56 -0
  31. data/app/assets/javascripts/editable_components/medium-editor/CUSTOM-EVENTS.md +223 -0
  32. data/app/assets/javascripts/editable_components/medium-editor/LICENSE +36 -0
  33. data/app/assets/javascripts/editable_components/medium-editor/MAINTAINERS.md +33 -0
  34. data/app/assets/javascripts/editable_components/medium-editor/OPTIONS.md +663 -0
  35. data/app/assets/javascripts/editable_components/medium-editor/README.md +725 -0
  36. data/app/assets/javascripts/editable_components/medium-editor/UPGRADE-5.md +146 -0
  37. data/app/assets/javascripts/editable_components/medium-editor/medium-editor.css +230 -0
  38. data/app/assets/javascripts/editable_components/medium-editor/medium-editor.js +7876 -0
  39. data/app/assets/javascripts/editable_components/medium-editor/medium-editor.min.css +1 -0
  40. data/app/assets/javascripts/editable_components/medium-editor/medium-editor.min.js +4 -0
  41. data/app/assets/javascripts/editable_components/medium-editor/themes/beagle.css +78 -0
  42. data/app/assets/javascripts/editable_components/medium-editor/themes/beagle.min.css +1 -0
  43. data/app/assets/javascripts/editable_components/medium-editor/themes/bootstrap.css +67 -0
  44. data/app/assets/javascripts/editable_components/medium-editor/themes/bootstrap.min.css +1 -0
  45. data/app/assets/javascripts/editable_components/medium-editor/themes/default.css +63 -0
  46. data/app/assets/javascripts/editable_components/medium-editor/themes/default.min.css +1 -0
  47. data/app/assets/javascripts/editable_components/medium-editor/themes/flat.css +58 -0
  48. data/app/assets/javascripts/editable_components/medium-editor/themes/flat.min.css +1 -0
  49. data/app/assets/javascripts/editable_components/medium-editor/themes/mani.css +57 -0
  50. data/app/assets/javascripts/editable_components/medium-editor/themes/mani.min.css +1 -0
  51. data/app/assets/javascripts/editable_components/medium-editor/themes/roman.css +58 -0
  52. data/app/assets/javascripts/editable_components/medium-editor/themes/roman.min.css +1 -0
  53. data/app/assets/javascripts/editable_components/medium-editor/themes/tim.css +67 -0
  54. data/app/assets/javascripts/editable_components/medium-editor/themes/tim.min.css +1 -0
  55. data/app/assets/javascripts/editable_components/sizzle/sizzle.js +2272 -0
  56. data/app/assets/javascripts/editable_components/sizzle/sizzle.min.js +3 -0
  57. data/app/assets/javascripts/editable_components/sizzle/sizzle.min.map +1 -0
  58. data/app/assets/javascripts/editable_components/vue/README.md +124 -0
  59. data/app/assets/javascripts/editable_components/vue/vue.common.js +9320 -0
  60. data/app/assets/javascripts/editable_components/vue/vue.common.min.js +7 -0
  61. data/app/assets/javascripts/editable_components/vue/vue.esm.js +9318 -0
  62. data/app/assets/javascripts/editable_components/vue/vue.js +9316 -0
  63. data/app/assets/javascripts/editable_components/vue/vue.min.js +8 -0
  64. data/app/assets/javascripts/editable_components/vue/vue.runtime.common.js +6831 -0
  65. data/app/assets/javascripts/editable_components/vue/vue.runtime.esm.js +6829 -0
  66. data/app/assets/javascripts/editable_components/vue/vue.runtime.js +6827 -0
  67. data/app/assets/javascripts/editable_components/vue/vue.runtime.min.js +7 -0
  68. data/app/assets/stylesheets/editable_components/application.sass +65 -0
  69. data/app/assets/stylesheets/editable_components/blaze/blaze.colors.min.css +1 -0
  70. data/app/assets/stylesheets/editable_components/blaze/blaze.min.css +1 -0
  71. data/app/assets/stylesheets/editable_components/blaze/components.addresses.min.css +1 -0
  72. data/app/assets/stylesheets/editable_components/blaze/components.alerts.min.css +1 -0
  73. data/app/assets/stylesheets/editable_components/blaze/components.avatars.min.css +1 -0
  74. data/app/assets/stylesheets/editable_components/blaze/components.badges.min.css +1 -0
  75. data/app/assets/stylesheets/editable_components/blaze/components.breadcrumbs.min.css +1 -0
  76. data/app/assets/stylesheets/editable_components/blaze/components.bubbles.min.css +1 -0
  77. data/app/assets/stylesheets/editable_components/blaze/components.buttons.min.css +1 -0
  78. data/app/assets/stylesheets/editable_components/blaze/components.calendars.min.css +1 -0
  79. data/app/assets/stylesheets/editable_components/blaze/components.cards.min.css +1 -0
  80. data/app/assets/stylesheets/editable_components/blaze/components.headings.min.css +1 -0
  81. data/app/assets/stylesheets/editable_components/blaze/components.hints.min.css +1 -0
  82. data/app/assets/stylesheets/editable_components/blaze/components.input-groups.min.css +1 -0
  83. data/app/assets/stylesheets/editable_components/blaze/components.inputs.min.css +1 -0
  84. data/app/assets/stylesheets/editable_components/blaze/components.links.min.css +1 -0
  85. data/app/assets/stylesheets/editable_components/blaze/components.lists.min.css +1 -0
  86. data/app/assets/stylesheets/editable_components/blaze/components.navs.min.css +1 -0
  87. data/app/assets/stylesheets/editable_components/blaze/components.overlays.min.css +1 -0
  88. data/app/assets/stylesheets/editable_components/blaze/components.pagination.min.css +1 -0
  89. data/app/assets/stylesheets/editable_components/blaze/components.progress.min.css +1 -0
  90. data/app/assets/stylesheets/editable_components/blaze/components.ranges.min.css +1 -0
  91. data/app/assets/stylesheets/editable_components/blaze/components.tables.min.css +1 -0
  92. data/app/assets/stylesheets/editable_components/blaze/components.tabs.min.css +1 -0
  93. data/app/assets/stylesheets/editable_components/blaze/components.tags.min.css +1 -0
  94. data/app/assets/stylesheets/editable_components/blaze/components.toggles.min.css +1 -0
  95. data/app/assets/stylesheets/editable_components/blaze/components.tooltips.min.css +1 -0
  96. data/app/assets/stylesheets/editable_components/blaze/components.trees.min.css +1 -0
  97. data/app/assets/stylesheets/editable_components/blaze/components.typography.min.css +1 -0
  98. data/app/assets/stylesheets/editable_components/blaze/generics.global.min.css +1 -0
  99. data/app/assets/stylesheets/editable_components/blaze/objects.containers.min.css +1 -0
  100. data/app/assets/stylesheets/editable_components/blaze/objects.drawers.min.css +1 -0
  101. data/app/assets/stylesheets/editable_components/blaze/objects.forms.min.css +1 -0
  102. data/app/assets/stylesheets/editable_components/blaze/objects.grid.min.css +1 -0
  103. data/app/assets/stylesheets/editable_components/blaze/objects.grid.responsive.min.css +1 -0
  104. data/app/assets/stylesheets/editable_components/blaze/objects.images.min.css +1 -0
  105. data/app/assets/stylesheets/editable_components/blaze/objects.media.min.css +1 -0
  106. data/app/assets/stylesheets/editable_components/blaze/objects.modals.min.css +1 -0
  107. data/app/assets/stylesheets/editable_components/blaze/objects.panels.min.css +1 -0
  108. data/app/assets/stylesheets/editable_components/blaze/themes/blaze.example.min.css +1 -0
  109. data/app/assets/stylesheets/editable_components/blaze/utilities.alignment.min.css +1 -0
  110. data/app/assets/stylesheets/editable_components/blaze/utilities.boxing.min.css +1 -0
  111. data/app/assets/stylesheets/editable_components/blaze/utilities.elevation.min.css +1 -0
  112. data/app/assets/stylesheets/editable_components/blaze/utilities.sizes.min.css +1 -0
  113. data/app/assets/stylesheets/editable_components/dragula/dragula.css +22 -0
  114. data/app/assets/stylesheets/editable_components/dragula/dragula.js +908 -0
  115. data/app/assets/stylesheets/editable_components/dragula/dragula.min.css +1 -0
  116. data/app/assets/stylesheets/editable_components/dragula/dragula.min.js +1 -0
  117. data/app/assets/stylesheets/editable_components/main.sass +225 -0
  118. data/app/assets/stylesheets/editable_components/medium-editor/API.md +520 -0
  119. data/app/assets/stylesheets/editable_components/medium-editor/CHANGES.md +1043 -0
  120. data/app/assets/stylesheets/editable_components/medium-editor/CODE_OF_CONDUCT.md +13 -0
  121. data/app/assets/stylesheets/editable_components/medium-editor/CONTRIBUTING.md +56 -0
  122. data/app/assets/stylesheets/editable_components/medium-editor/CUSTOM-EVENTS.md +223 -0
  123. data/app/assets/stylesheets/editable_components/medium-editor/LICENSE +36 -0
  124. data/app/assets/stylesheets/editable_components/medium-editor/MAINTAINERS.md +33 -0
  125. data/app/assets/stylesheets/editable_components/medium-editor/OPTIONS.md +663 -0
  126. data/app/assets/stylesheets/editable_components/medium-editor/README.md +725 -0
  127. data/app/assets/stylesheets/editable_components/medium-editor/UPGRADE-5.md +146 -0
  128. data/app/assets/stylesheets/editable_components/medium-editor/medium-editor.css +230 -0
  129. data/app/assets/stylesheets/editable_components/medium-editor/medium-editor.js +7876 -0
  130. data/app/assets/stylesheets/editable_components/medium-editor/medium-editor.min.css +1 -0
  131. data/app/assets/stylesheets/editable_components/medium-editor/medium-editor.min.js +4 -0
  132. data/app/assets/stylesheets/editable_components/medium-editor/themes/beagle.css +78 -0
  133. data/app/assets/stylesheets/editable_components/medium-editor/themes/beagle.min.css +1 -0
  134. data/app/assets/stylesheets/editable_components/medium-editor/themes/bootstrap.css +67 -0
  135. data/app/assets/stylesheets/editable_components/medium-editor/themes/bootstrap.min.css +1 -0
  136. data/app/assets/stylesheets/editable_components/medium-editor/themes/default.css +63 -0
  137. data/app/assets/stylesheets/editable_components/medium-editor/themes/default.min.css +1 -0
  138. data/app/assets/stylesheets/editable_components/medium-editor/themes/flat.css +58 -0
  139. data/app/assets/stylesheets/editable_components/medium-editor/themes/flat.min.css +1 -0
  140. data/app/assets/stylesheets/editable_components/medium-editor/themes/mani.css +57 -0
  141. data/app/assets/stylesheets/editable_components/medium-editor/themes/mani.min.css +1 -0
  142. data/app/assets/stylesheets/editable_components/medium-editor/themes/roman.css +58 -0
  143. data/app/assets/stylesheets/editable_components/medium-editor/themes/roman.min.css +1 -0
  144. data/app/assets/stylesheets/editable_components/medium-editor/themes/tim.css +67 -0
  145. data/app/assets/stylesheets/editable_components/medium-editor/themes/tim.min.css +1 -0
  146. data/app/controllers/editable_components/blocks_controller.rb +36 -0
  147. data/app/helpers/editable_components/application_helper.rb +4 -0
  148. data/app/jobs/editable_components/application_job.rb +4 -0
  149. data/app/mailers/editable_components/application_mailer.rb +6 -0
  150. data/app/models/editable_components/application_record.rb +5 -0
  151. data/app/models/editable_components/block.rb +176 -0
  152. data/app/models/editable_components/concerns/editable.rb +34 -0
  153. data/app/models/editable_components/item.rb +50 -0
  154. data/app/models/editable_components/item_boolean.rb +23 -0
  155. data/app/models/editable_components/item_datetime.rb +14 -0
  156. data/app/models/editable_components/item_file.rb +46 -0
  157. data/app/models/editable_components/item_float.rb +23 -0
  158. data/app/models/editable_components/item_hash.rb +16 -0
  159. data/app/models/editable_components/item_integer.rb +23 -0
  160. data/app/models/editable_components/item_string.rb +29 -0
  161. data/app/models/editable_components/item_text.rb +19 -0
  162. data/app/views/editable_components/_admin_toolbar.html.erb +105 -0
  163. data/app/views/editable_components/_block.html.erb +6 -0
  164. data/app/views/editable_components/_block_image.html.erb +6 -0
  165. data/app/views/editable_components/_block_multi_text.html.erb +7 -0
  166. data/app/views/editable_components/_block_slide.html.erb +6 -0
  167. data/app/views/editable_components/_block_slider.html.erb +7 -0
  168. data/app/views/editable_components/_block_text.html.erb +5 -0
  169. data/app/views/editable_components/_block_text_with_image.html.erb +12 -0
  170. data/app/views/editable_components/_blocks.html.erb +12 -0
  171. data/config/initializers/editable_components.rb +72 -0
  172. data/config/routes.rb +4 -0
  173. data/db/migrate/20170414173603_create_editable_components_blocks.rb +18 -0
  174. data/db/migrate/20170414173610_create_editable_components_items.rb +11 -0
  175. data/db/migrate/20170414173611_add_items_booleans.rb +5 -0
  176. data/db/migrate/20170414173612_add_items_datetimes.rb +5 -0
  177. data/db/migrate/20170414173613_add_items_files.rb +5 -0
  178. data/db/migrate/20170414173614_add_items_floats.rb +5 -0
  179. data/db/migrate/20170414173615_add_items_hashes.rb +5 -0
  180. data/db/migrate/20170414173616_add_items_integers.rb +5 -0
  181. data/db/migrate/20170414173617_add_items_strings.rb +5 -0
  182. data/db/migrate/20170414173618_add_items_texts.rb +5 -0
  183. data/lib/data/img1.jpg +0 -0
  184. data/lib/editable_components.rb +87 -0
  185. data/lib/editable_components/engine.rb +21 -0
  186. data/lib/editable_components/version.rb +3 -0
  187. data/lib/tasks/editable_components_tasks.rake +4 -0
  188. metadata +264 -0
@@ -0,0 +1 @@
1
+ .medium-toolbar-arrow-under:after{border-color:#2f1e07 transparent transparent;top:60px}.medium-toolbar-arrow-over:before{border-color:transparent transparent #2f1e07}.medium-editor-toolbar{background-color:#2f1e07;border:1px solid #5b3a0e;border-radius:6px}.medium-editor-toolbar li button{background-color:transparent;border:none;border-right:1px solid #5b3a0e;box-sizing:border-box;color:#ffedd5;height:60px;min-width:60px;-webkit-transition:background-color .2s ease-in,color .2s ease-in;transition:background-color .2s ease-in,color .2s ease-in}.medium-editor-toolbar li .medium-editor-button-active,.medium-editor-toolbar li button:hover{background-color:#030200;color:#ffedd5}.medium-editor-toolbar li .medium-editor-button-first{border-bottom-left-radius:6px;border-top-left-radius:6px}.medium-editor-toolbar li .medium-editor-button-last{border-bottom-right-radius:6px;border-right:none;border-top-right-radius:6px}.medium-editor-toolbar-form{background:#2f1e07;border-radius:6px;color:#ffedd5}.medium-editor-toolbar-form .medium-editor-toolbar-input{background:#2f1e07;color:#ffedd5;height:60px}.medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder{color:#ffedd5;color:rgba(255,237,213,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-moz-placeholder{color:#ffedd5;color:rgba(255,237,213,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input::-moz-placeholder{color:#ffedd5;color:rgba(255,237,213,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-ms-input-placeholder{color:#ffedd5;color:rgba(255,237,213,.8)}.medium-editor-toolbar-form a{color:#ffedd5}.medium-editor-toolbar-anchor-preview{background:#2f1e07;border-radius:6px;color:#ffedd5}.medium-editor-placeholder:after{color:#5b3a0e}
@@ -0,0 +1,36 @@
1
+ module EditableComponents
2
+ class BlocksController < ActionController::Base
3
+ protect_from_forgery with: :exception
4
+
5
+ def publish
6
+ model = params[:container].camelcase.constantize rescue nil
7
+ if model && model.ancestors.include?( EditableComponents::Concerns::Editable )
8
+ container = model.find params[:container_id]
9
+ ver = EditableComponents.publish( container, params[:version] )
10
+ respond_to do |format|
11
+ # format.html { redirect_to page_path( @page, version: ver ), notice: "Version: #{ver}" }
12
+ format.html { redirect_back fallback_location: '/', notice: "Version: #{ver}" }
13
+ format.json { render json: { status: :ok }, status: :ok } # , location: container
14
+ end
15
+ end
16
+ # TODO: set errors if not a valid model
17
+ end
18
+
19
+ def update
20
+ model = params[:container].camelcase.constantize rescue nil
21
+ if model && model.ancestors.include?( EditableComponents::Concerns::Editable )
22
+ container = model.find params[:container_id]
23
+ respond_to do |format|
24
+ if EditableComponents.update( container, params )
25
+ format.html { redirect_back fallback_location: '/', notice: 'Saved.' }
26
+ format.json { render json: { status: :ok }, status: :ok } # , location: container
27
+ else
28
+ format.html { redirect_back fallback_location: '/', notice: container.errors.messages[:base].join( ' - ' ) }
29
+ format.json { render json: container.errors, status: :unprocessable_entity }
30
+ end
31
+ end
32
+ end
33
+ # TODO: set errors if not a valid model
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,4 @@
1
+ module EditableComponents
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module EditableComponents
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module EditableComponents
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module EditableComponents
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,176 @@
1
+ module EditableComponents
2
+ class Block < ApplicationRecord
3
+ EMPTY_DATA = OpenStruct.new( { data: '' } )
4
+
5
+ # --- fields options ----------------------------------------------------- #
6
+ serialize :options, JSON
7
+ serialize :validations, JSON
8
+
9
+ # --- relations ---------------------------------------------------------- #
10
+ belongs_to :parent, polymorphic: true
11
+ has_many :ec_blocks, as: :parent, foreign_key: 'parent_id', class_name: 'Block'
12
+ has_many :items
13
+ accepts_nested_attributes_for :ec_blocks, allow_destroy: true
14
+ accepts_nested_attributes_for :items
15
+
16
+ # --- hooks -------------------------------------------------------------- #
17
+ before_create :on_before_create
18
+
19
+ # --- scopes ------------------------------------------------------------- #
20
+ default_scope { order( position: :desc ) }
21
+ scope :published, -> { where( published: true ) unless EditableComponents::Engine.edit_mode }
22
+ scope :with_nested, -> { includes( :items, ec_blocks: :items ) }
23
+
24
+ # --- validations -------------------------------------------------------- #
25
+ validates_presence_of :block_type, :position
26
+
27
+ # --- misc --------------------------------------------------------------- #
28
+ amoeba do
29
+ enable
30
+ # customize( lambda { |original_obj, new_obj|
31
+ # original_obj.unit_pictures.each{|p| new_obj.unit_pictures.new(:data => File.open(p.data.file.path))}
32
+ # })
33
+ end
34
+
35
+ # after_validation :on_after_validation
36
+ #
37
+ # field :block_type, type: String, default: 'text'
38
+ # field :name, type: String, default: ''
39
+ # field :position, type: Integer, default: 0
40
+ # field :published, type: Mongoid::Boolean, default: true
41
+ # field :_init, type: Mongoid::Boolean, default: false
42
+ #
43
+ # embedded_in :parent, polymorphic: true
44
+ #
45
+ # embeds_many :ec_blocks, cascade_callbacks: true, order: :position.desc, class_name: 'EditableComponents::Block'
46
+ # embeds_many :items, cascade_callbacks: true, class_name: 'EditableComponents::Item'
47
+ #
48
+ # accepts_nested_attributes_for :ec_blocks, allow_destroy: true
49
+ # accepts_nested_attributes_for :items
50
+ #
51
+ # # scope :published, -> { where( published: true ) unless ApplicationController.edit_mode }
52
+
53
+ def attr_id
54
+ "#{self.class.to_s.split('::').last}-#{self.id}"
55
+ end
56
+
57
+ def children_type
58
+ EditableComponents.config[:ec_blocks][block_type.to_sym][:children_type]
59
+ end
60
+
61
+ def editable
62
+ Engine.edit_mode ? (
63
+ is_sub_block? ?
64
+ {
65
+ 'data-ec-sub-block': self.id,
66
+ 'data-ec-ct': self.block_type,
67
+ 'data-ec-position': self.position,
68
+ 'data-ec-pub': self.published
69
+ } :
70
+ {
71
+ 'data-ec-block': self.id,
72
+ 'data-ec-container': self.children_type,
73
+ 'data-ec-ct': self.block_type,
74
+ 'data-ec-pub': self.published
75
+ }
76
+ ).map { |k, v| "#{k}=\"#{v}\"" }.join( ' ' ).html_safe : ''
77
+ end
78
+
79
+ # Returns an item by name
80
+ def get( name )
81
+ unless @_items
82
+ @_items = {}
83
+ items.each { |item| @_items[item.name] = item }
84
+ end
85
+ @_items[name]
86
+ end
87
+
88
+ def init
89
+ t = block_type.to_sym
90
+ if Block::block_types.include? t
91
+ init_items self, EditableComponents.config[:ec_blocks][t][:items]
92
+ end
93
+ end
94
+
95
+ def init_items( block, items )
96
+ items.each do |name, type|
97
+ t = type.to_sym
98
+ if type.to_s.start_with? 'item_'
99
+ c = 'EditableComponents::' + ActiveSupport::Inflector.camelize( t )
100
+ begin
101
+ model = c.constantize
102
+ rescue Exception => e
103
+ Rails.logger.error '[ERROR] EditableComponents - init_items: ' + e.message
104
+ model = false
105
+ end
106
+ block.items << model.new( name: name ).init if model
107
+ elsif Block::block_types.include? t.to_sym
108
+ cmp = Block.new( block_type: t, name: name )
109
+ block.ec_blocks << cmp
110
+ init_items( cmp, EditableComponents.config[:ec_blocks][t][:items] )
111
+ end
112
+ end if items
113
+ end
114
+
115
+ def has_parent?
116
+ parent.present?
117
+ end
118
+
119
+ def has_children?
120
+ ec_blocks.exists?
121
+ end
122
+
123
+ def is_sub_block?
124
+ parent.present? && parent_type == 'EditableComponents::Block'
125
+ end
126
+
127
+ def on_before_create
128
+ if self._init
129
+ self._init = false
130
+ if self.name.blank?
131
+ names = parent.ec_blocks.map &:name
132
+ i = 0
133
+ while( ( i += 1 ) < 1000 ) # Search an empty group
134
+ unless names.include? "#{block_type}-#{i}"
135
+ self.name = "#{block_type}-#{i}"
136
+ break
137
+ end
138
+ end
139
+ end
140
+ init
141
+ end
142
+ end
143
+
144
+ def props
145
+ pieces = {}
146
+
147
+ Item::item_types.each do |type|
148
+ pieces[type.pluralize.to_sym] = []
149
+ end
150
+ items.each do |item| # TODO: improve me
151
+ pieces[item.class.type_name.pluralize.to_sym].push item
152
+ end
153
+ Item::item_types.each do |type|
154
+ pieces[type.to_sym] = pieces[type.pluralize.to_sym].any? ? pieces[type.pluralize.to_sym].first : nil # EMPTY_DATA - empty Item per sti class?
155
+ end
156
+
157
+ # pieces = {
158
+ # images: items.select { |item| item.type == ItemImage.to_s },
159
+ # integers: items.select { |item| item.type == ItemInteger.to_s },
160
+ # strings: items.select { |item| item.type == ItemString.to_s },
161
+ # texts: items.select { |item| item.type == ItemText.to_s },
162
+ # }
163
+
164
+ # pieces[:image] = pieces[:images].any? ? pieces[:images].first : EMPTY_DATA
165
+ # pieces[:integers] = pieces[:integers].any? ? pieces[:integers].first : EMPTY_DATA
166
+ # pieces[:string] = pieces[:strings].any? ? pieces[:strings].first : EMPTY_DATA
167
+ # pieces[:text] = pieces[:texts].any? ? pieces[:texts].first : EMPTY_DATA
168
+
169
+ OpenStruct.new( pieces )
170
+ end
171
+
172
+ def self.block_types
173
+ @@block_types ||= EditableComponents.config[:ec_blocks].keys
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,34 @@
1
+ module EditableComponents
2
+ module Concerns
3
+ module Editable
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ # embeds_many :ec_blocks, as: :parent, cascade_callbacks: true, order: :position.desc, class_name: 'EditableComponents::Block'
8
+ has_many :ec_blocks, as: :parent, foreign_key: 'parent_id', class_name: Block.to_s
9
+ accepts_nested_attributes_for :ec_blocks, allow_destroy: true
10
+
11
+ def create_block( type = :text, params = {} )
12
+ block = Block.new( _init: true, block_type: type )
13
+ block.options = params[:options] if params[:options]
14
+ block.validations = params[:validations] if params[:validations]
15
+ ec_blocks << block
16
+ block
17
+ end
18
+
19
+ def current_blocks( version = 0 )
20
+ return @current_blocks if @current_blocks
21
+ version = 0 unless EditableComponents::Engine.edit_mode # no admin = only current version
22
+ @current_blocks = ec_blocks.where( version: version.to_i ).with_nested.published
23
+ end
24
+
25
+ def get_block( name, version = 0 )
26
+ current_blocks( version ).each do |block|
27
+ return block if block.name == name
28
+ end
29
+ nil
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,50 @@
1
+ module EditableComponents
2
+ class Item < ApplicationRecord
3
+ # field :data, type: String
4
+
5
+ # embedded_in :ec_blocks
6
+
7
+ belongs_to :block
8
+
9
+ def attr_id
10
+ "#{self.class_name}-#{self.id}"
11
+ end
12
+
13
+ def class_name
14
+ self.class.to_s.split('::').last
15
+ end
16
+
17
+ def editable
18
+ Engine.edit_mode ? " data-ec-item=\"#{self.id}\" data-ec-input=\"#{self.opt_input}\" data-ec-type=\"#{self.class_name}\"".html_safe : ''
19
+ end
20
+
21
+ def opt_input
22
+ if self.block.options[self.name] && self.block.options[self.name]['input']
23
+ self.block.options[self.name]['input'].to_s
24
+ elsif config[:input]
25
+ config[:input].to_s
26
+ else
27
+ ''
28
+ end
29
+ end
30
+
31
+ def to_s
32
+ self.data
33
+ end
34
+
35
+ def update_data( value )
36
+ self.data = value
37
+ self.save
38
+ end
39
+
40
+ def self.item_types
41
+ @@item_types ||= EditableComponents.config[:items].keys.map &:to_s
42
+ end
43
+
44
+ protected
45
+
46
+ def config
47
+ @config ||= EditableComponents.config[:items][self.class::type_name.to_sym] ? EditableComponents.config[:items][self.class::type_name.to_sym] : {}
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,23 @@
1
+ module EditableComponents
2
+ class ItemBoolean < Item
3
+ alias_attribute :data, :data_boolean
4
+
5
+ def init
6
+ self.data = 0
7
+ self
8
+ end
9
+
10
+ def update_data( value )
11
+ self.data = ( value == 'true' ) ? 1 : 0
12
+ self.save
13
+ end
14
+
15
+ def to_s
16
+ self.data > 0 ? 'true' : 'false'
17
+ end
18
+
19
+ def self.type_name
20
+ 'boolean'
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,14 @@
1
+ module EditableComponents
2
+ class ItemDatetime < Item
3
+ alias_attribute :data, :data_datetime
4
+
5
+ def init
6
+ self.data = Time.now
7
+ self
8
+ end
9
+
10
+ def self.type_name
11
+ 'datetime'
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,46 @@
1
+ module EditableComponents
2
+ class ItemFile < Item
3
+ # has_attached_file :data_string
4
+ # validates_attachment_content_type :data_string, content_type: ['image/jpg', 'image/jpeg', 'image/png', 'image/gif']
5
+
6
+ # include Mongoid::Paperclip
7
+ # has_mongoid_attached_file :data
8
+ # validates_attachment_content_type :data, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
9
+
10
+ mount_uploader :data_file, ::FileUploader
11
+
12
+ alias_attribute :data, :data_file
13
+
14
+ def editable
15
+ Engine.edit_mode ? { 'data-ec-item': self.id, 'data-ec-input': self.opt_input, 'data-ec-type': self.class_name, 'data-ec-block': self.block_id } : {}
16
+ end
17
+
18
+ def init
19
+ self.data_file = File.open( EditableComponents::Engine.root.join( 'lib', 'data', 'img1.jpg' ) )
20
+ self
21
+ end
22
+
23
+ def self.type_name
24
+ 'file'
25
+ end
26
+
27
+ # before_validation :on_before_validation
28
+ #
29
+ # def on_before_validation
30
+ # self.data = File.open( 'rails/editable_components_test/public/img/img1.jpg' )
31
+ # # binding.pry
32
+ # end
33
+
34
+ # before_save :on_before_save
35
+ # before_validation :on_before_validation
36
+ # before_create :on_before_create
37
+ # before_update :on_before_update
38
+ # before_upsert :on_before_upsert
39
+ #
40
+ # def on_before_save; p '>>> before_save'; end
41
+ # def on_before_validation; p '>>> before_validation'; end
42
+ # def on_before_create; p '>>> before_create'; end
43
+ # def on_before_update; p '>>> before_update'; end
44
+ # def on_before_upsert; p '>>> before_upsert'; end
45
+ end
46
+ end
@@ -0,0 +1,23 @@
1
+ module EditableComponents
2
+ class ItemFloat < Item
3
+ alias_attribute :data, :data_float
4
+
5
+ def init
6
+ self.data = 0
7
+ self
8
+ end
9
+
10
+ def update_data( value )
11
+ self.data = value.to_f
12
+ self.save
13
+ end
14
+
15
+ def to_s
16
+ self.data.to_s
17
+ end
18
+
19
+ def self.type_name
20
+ 'float'
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ module EditableComponents
2
+ class ItemHash < Item
3
+ alias_attribute :data, :data_hash
4
+
5
+ serialize :data_hash, JSON
6
+
7
+ def init
8
+ self.data = {}
9
+ self
10
+ end
11
+
12
+ def self.type_name
13
+ 'hash'
14
+ end
15
+ end
16
+ end