editable_components 0.1.0 → 0.1.2
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.
- checksums.yaml +4 -4
- data/README.md +41 -10
- data/app/assets/javascripts/editable_components/main.js +14 -9
- data/app/models/editable_components/block.rb +32 -38
- data/app/models/editable_components/concerns/editable.rb +1 -1
- data/app/views/editable_components/_admin_toolbar.html.erb +0 -1
- data/db/migrate/20170414173603_create_editable_components_blocks.rb +0 -1
- data/lib/editable_components.rb +2 -2
- data/lib/editable_components/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b9da05cf8c46f15fde699247172243145297a9d
|
4
|
+
data.tar.gz: 57698e25090be81d4bdc8488aca81b471a7874b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7fc23be9b8ebbcd7732652f5f418d0c9091248d2736a1295074596687eb9759d18d6294d2a89f8d97ff69128279d8f7e1d2d12ae609bb3db45c052d1efc8161f
|
7
|
+
data.tar.gz: 53070853e6f5e09fcb0fec4821be5c915aebcd386f2c0b36d2878da239977f82da587e054ba1250a5c03470e66e96dd5c6ac61b33773b942317f74966510a38f
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# EditableComponents for Rails
|
1
|
+
# EditableComponents for Rails [](https://badge.fury.io/rb/editable_components)
|
2
2
|
|
3
3
|
A Ruby on Rails plugin to manage UI components editable from the front-end.
|
4
4
|
|
@@ -14,21 +14,21 @@ Goals:
|
|
14
14
|
|
15
15
|

|
16
16
|
|
17
|
-
###
|
17
|
+
### Install
|
18
18
|
|
19
|
-
|
19
|
+
- Add to the Gemfile: `gem 'editable_components'`
|
20
20
|
|
21
|
-
|
21
|
+
- Copy migrations (Rails 5.x syntax, in Rails 4.x use rake): `rails editable_components:install:migrations`
|
22
22
|
|
23
|
-
|
23
|
+
- Apply them: `rake db:migrate`
|
24
24
|
|
25
|
-
|
25
|
+
- Include the concern *Editable* to your model: `include EditableComponents::Concerns::Editable`
|
26
26
|
|
27
|
-
|
27
|
+
- Add to your application layout (in head, ex. using ERB): `<%= stylesheet_link_tag( EditableComponents::Engine.css ) if EditableComponents::Engine.css %>`
|
28
28
|
|
29
|
-
|
29
|
+
- Add to your application layout (before body closing): `<%= javascript_include_tag( EditableComponents::Engine.js ) if EditableComponents::Engine.js %>`
|
30
30
|
|
31
|
-
|
31
|
+
- Add your blocks to the views (ex. in show):
|
32
32
|
```erb
|
33
33
|
<%= render layout: 'editable_components/blocks', locals: { container: @page } do |blocks| %>
|
34
34
|
<% blocks.each do |block| %>
|
@@ -37,7 +37,38 @@ Goals:
|
|
37
37
|
<% end %>
|
38
38
|
```
|
39
39
|
|
40
|
-
|
40
|
+
- Add some sample data (ex. Page model): `Page.first.create_block :text`
|
41
|
+
|
42
|
+
### Config
|
43
|
+
|
44
|
+
Edit the conf file: `config/initializers/editable_components.rb`
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
conf = EditableComponents.config
|
48
|
+
# Adds a new custom block
|
49
|
+
conf[:ec_blocks][:custom] = {
|
50
|
+
name: 'Custom block',
|
51
|
+
items: {
|
52
|
+
int1: :item_integer,
|
53
|
+
int2: :item_integer,
|
54
|
+
a_float: :item_float
|
55
|
+
}
|
56
|
+
}
|
57
|
+
EditableComponents.config( { components: conf[:ec_blocks] } )
|
58
|
+
```
|
59
|
+
|
60
|
+
Create the new view blocks: `app/views/editable_components/_block_custom.html.erb`
|
61
|
+
|
62
|
+
```erb
|
63
|
+
<% if local_assigns[:block] %>
|
64
|
+
<% block = local_assigns[:block] %>
|
65
|
+
<div <%= block.editable %>>
|
66
|
+
1st number: <span class="num1"<%= block.props.integers[0].editable %>><%= block.props.integers[0] %></span>
|
67
|
+
- 2nd number: <span class="num2"<%= block.props.integers[1].editable %>><%= block.props.integers[1] %></span><br/>
|
68
|
+
A float: <span <%= block.props.float.editable %>><%= block.props.float %></span><br/>
|
69
|
+
</div>
|
70
|
+
<% end %>
|
71
|
+
```
|
41
72
|
|
42
73
|
##### Images
|
43
74
|
|
@@ -2,6 +2,13 @@
|
|
2
2
|
var ecMain = (function() {
|
3
3
|
this.editing = false;
|
4
4
|
return {
|
5
|
+
createInput( parent, name, value ) {
|
6
|
+
var el = document.createElement( 'input' );
|
7
|
+
el.setAttribute( 'type', 'hidden' );
|
8
|
+
el.setAttribute( 'name', name );
|
9
|
+
el.setAttribute( 'value', value );
|
10
|
+
parent.appendChild( el );
|
11
|
+
},
|
5
12
|
dlgPreviewClose: function() {
|
6
13
|
Sizzle( '[data-ec-toolbar]' )[0].style.display = 'block';
|
7
14
|
Sizzle( '[data-ec-dlg="preview"]' )[0].style.display = 'none';
|
@@ -228,45 +235,43 @@ var ecVue = new Vue({
|
|
228
235
|
onSubmit: function( event ) {
|
229
236
|
// event.preventDefault();
|
230
237
|
|
231
|
-
var cmp = this;
|
232
|
-
this.inputs = [];
|
233
238
|
// Update items
|
234
239
|
Sizzle( '[data-ec-item]' ).forEach( function( el ) {
|
235
240
|
var input = el.getAttribute( 'data-ec-input' );
|
236
241
|
if( input != 'file' && input != 'file_image' ) {
|
237
|
-
|
242
|
+
ecMain.createInput( Sizzle( '[data-ec-fields]' )[0], 'ec_cmp[' + el.getAttribute( 'data-ec-type' ) + '][' + el.attributes['data-ec-item'].value + ']', el.innerHTML );
|
238
243
|
}
|
239
244
|
});
|
240
245
|
// Update positions
|
241
246
|
var last = Sizzle( '[data-ec-block]' ).length;
|
242
247
|
Sizzle( '[data-ec-block]' ).forEach( function( el ) {
|
243
|
-
|
248
|
+
ecMain.createInput( Sizzle( '[data-ec-fields]' )[0], 'ec_cmp[Block][' + el.attributes['data-ec-block'].value + '][position]', last-- );
|
244
249
|
var last2 = Sizzle( '[data-ec-sub-block]', el ).length;
|
245
250
|
if( last2 ) {
|
246
251
|
Sizzle( '[data-ec-sub-block]', el ).forEach( function( el2 ) {
|
247
252
|
var sid = el2.getAttribute( 'data-ec-sub-block' );
|
248
|
-
|
253
|
+
ecMain.createInput( Sizzle( '[data-ec-fields]' )[0], 'ec_cmp[Block][' + sid + '][position]', last2-- );
|
249
254
|
});
|
250
255
|
}
|
251
256
|
});
|
252
257
|
// New blocks
|
253
258
|
var cnt = 0;
|
254
259
|
Sizzle( '[data-ec-new-block]' ).forEach( function( el ) {
|
255
|
-
|
260
|
+
ecMain.createInput( Sizzle( '[data-ec-fields]' )[0], 'ec_cmp[Block][0][_add][' + ( cnt++ ) + ']', el.getAttribute( 'data-ec-type' ) );
|
256
261
|
});
|
257
262
|
// New sub blocks
|
258
263
|
Sizzle( '[data-ec-block][data-ec-new-blocks]' ).forEach( function( el ) {
|
259
264
|
cnt = parseInt( el.getAttribute( 'data-ec-new-blocks' ) );
|
260
265
|
for( var i = 0; i < cnt; i++ ) {
|
261
|
-
|
266
|
+
ecMain.createInput( Sizzle( '[data-ec-fields]' )[0], 'ec_cmp[Block][' + el.getAttribute( 'data-ec-block' ) + '][_add][' + i + ']', el.getAttribute( 'data-ec-container' ) );
|
262
267
|
}
|
263
268
|
});
|
264
269
|
// Remove blocks
|
265
270
|
Sizzle( '[data-ec-block][data-ec-destroy="1"]' ).forEach( function( el ) {
|
266
|
-
|
271
|
+
ecMain.createInput( Sizzle( '[data-ec-fields]' )[0], 'ec_cmp[Block][' + el.attributes['data-ec-block'].value + '][_destroy]', '1' );
|
267
272
|
});
|
268
273
|
Sizzle( '[data-ec-sub-block][data-ec-destroy="1"]' ).forEach( function( el ) {
|
269
|
-
|
274
|
+
ecMain.createInput( Sizzle( '[data-ec-fields]' )[0], 'ec_cmp[Block][' + el.attributes['data-ec-sub-block'].value + '][_destroy]', '1' );
|
270
275
|
});
|
271
276
|
},
|
272
277
|
removeBlock: function() {
|
@@ -15,6 +15,7 @@ module EditableComponents
|
|
15
15
|
|
16
16
|
# --- hooks -------------------------------------------------------------- #
|
17
17
|
before_create :on_before_create
|
18
|
+
after_create :on_after_create
|
18
19
|
|
19
20
|
# --- scopes ------------------------------------------------------------- #
|
20
21
|
default_scope { order( position: :desc ) }
|
@@ -85,33 +86,6 @@ module EditableComponents
|
|
85
86
|
@_items[name]
|
86
87
|
end
|
87
88
|
|
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
89
|
def has_parent?
|
116
90
|
parent.present?
|
117
91
|
end
|
@@ -124,20 +98,22 @@ module EditableComponents
|
|
124
98
|
parent.present? && parent_type == 'EditableComponents::Block'
|
125
99
|
end
|
126
100
|
|
101
|
+
def on_after_create
|
102
|
+
# TODO: validates type before creation!
|
103
|
+
t = self.block_type.to_sym
|
104
|
+
Block::init_items( self, EditableComponents.config[:ec_blocks][t][:items] ) if Block::block_types.include?( t )
|
105
|
+
end
|
106
|
+
|
127
107
|
def on_before_create
|
128
|
-
if self.
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
self.name = "#{block_type}-#{i}"
|
136
|
-
break
|
137
|
-
end
|
108
|
+
if self.name.blank?
|
109
|
+
names = parent.ec_blocks.map &:name
|
110
|
+
i = 0
|
111
|
+
while( ( i += 1 ) < 1000 ) # Search an empty group
|
112
|
+
unless names.include? "#{block_type}-#{i}"
|
113
|
+
self.name = "#{block_type}-#{i}"
|
114
|
+
break
|
138
115
|
end
|
139
116
|
end
|
140
|
-
init
|
141
117
|
end
|
142
118
|
end
|
143
119
|
|
@@ -172,5 +148,23 @@ module EditableComponents
|
|
172
148
|
def self.block_types
|
173
149
|
@@block_types ||= EditableComponents.config[:ec_blocks].keys
|
174
150
|
end
|
151
|
+
|
152
|
+
def self.init_items( block, items )
|
153
|
+
items.each do |name, type|
|
154
|
+
t = type.to_sym
|
155
|
+
if type.to_s.start_with? 'item_'
|
156
|
+
c = 'EditableComponents::' + ActiveSupport::Inflector.camelize( t )
|
157
|
+
begin
|
158
|
+
model = c.constantize
|
159
|
+
rescue Exception => e
|
160
|
+
Rails.logger.error '[ERROR] EditableComponents - init_items: ' + e.message
|
161
|
+
model = false
|
162
|
+
end
|
163
|
+
block.items << model.new( name: name ).init if model
|
164
|
+
elsif Block::block_types.include? t.to_sym
|
165
|
+
block.ec_blocks << ( cmp = Block.new( block_type: t, name: name ) )
|
166
|
+
end
|
167
|
+
end if items
|
168
|
+
end
|
175
169
|
end
|
176
170
|
end
|
@@ -9,7 +9,7 @@ module EditableComponents
|
|
9
9
|
accepts_nested_attributes_for :ec_blocks, allow_destroy: true
|
10
10
|
|
11
11
|
def create_block( type = :text, params = {} )
|
12
|
-
block = Block.new(
|
12
|
+
block = Block.new( block_type: type )
|
13
13
|
block.options = params[:options] if params[:options]
|
14
14
|
block.validations = params[:validations] if params[:validations]
|
15
15
|
ec_blocks << block
|
@@ -85,7 +85,6 @@
|
|
85
85
|
<%= form_for page, url: EditableComponents::Engine::routes.url_helpers.ec_update_path( model, page ), method: :patch, as: :ec_cmp, namespace: 'ec', html: { 'data-ec-form': '', 'data-ec-model': model, 'v-cloak': '', 'v-on:submit': 'onSubmit( $event )' } do |f| %>
|
86
86
|
<input type="hidden" name="version" value="<%= @version.to_i %>"/>
|
87
87
|
<div data-ec-fields></div>
|
88
|
-
<input v-for="input in inputs" type="hidden" v-bind:name="input.name" v-bind:value="input.value"/>
|
89
88
|
<%= button_tag( type: 'submit', class: 'c-button c-button--info', title: 'Save changes', 'data-ec-menu-save': '' ) do %>
|
90
89
|
<i data-ec-icon="icon-floppy-disk"></i> save
|
91
90
|
<% end %>
|
@@ -6,7 +6,6 @@ class CreateEditableComponentsBlocks < ActiveRecord::Migration[5.0]
|
|
6
6
|
t.string :name, null: false, default: ''
|
7
7
|
t.integer :position, null: false, default: 0
|
8
8
|
t.boolean :published, null: false, default: true
|
9
|
-
t.boolean :_init, null: false, default: false
|
10
9
|
t.string :options, null: false, default: '{}'
|
11
10
|
t.string :validations, null: false, default: '{}'
|
12
11
|
t.integer :parent_id
|
data/lib/editable_components.rb
CHANGED
@@ -60,7 +60,7 @@ module EditableComponents
|
|
60
60
|
t = block.block_type.to_sym
|
61
61
|
add.keys.each do
|
62
62
|
if @@config[:ec_blocks][t] && @@config[:ec_blocks][t][:children_type]
|
63
|
-
sub_block = EditableComponents::Block.new( parent: block, block_type: @@config[:ec_blocks][t][:children_type], version: version
|
63
|
+
sub_block = EditableComponents::Block.new( parent: block, block_type: @@config[:ec_blocks][t][:children_type], version: version )
|
64
64
|
sub_block.save
|
65
65
|
# TODO: return errors
|
66
66
|
end
|
@@ -74,7 +74,7 @@ module EditableComponents
|
|
74
74
|
add.each do |index, new_type|
|
75
75
|
t = new_type.to_sym
|
76
76
|
# TODO: check if t is a valid block type
|
77
|
-
EditableComponents::Block.new( parent: parent, block_type: t, version: version
|
77
|
+
EditableComponents::Block.new( parent: parent, block_type: t, version: version ).save
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: editable_components
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mat
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-05-
|
11
|
+
date: 2017-05-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|