rails_admin_json_editor 0.0.7 → 0.0.8
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/app/assets/javascripts/rails_admin_json_editor/rails_admin_json_editor.js +109 -59
- data/app/assets/stylesheets/rails_admin_json_editor/rails_admin_json_editor.css.scss +4 -0
- data/app/views/rails_admin_json_editor/main/_form_json_editor.html.erb +50 -22
- data/lib/rails_admin_json_editor/version.rb +1 -1
- data/lib/rails_admin_json_editor.rb +12 -2
- 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: 66033e2e1d435edb2107caaad3e774d3c2e1187f
|
4
|
+
data.tar.gz: 1f031aa83e5b878da54539ab47888e193e853837
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7888672433e39229489fb4209d59bd911a4d967ace462ce7860dd901181647bc42f69c51d7f74f3d60eabce4133cf6d8b771d90e5497dea8605868a8692509f2
|
7
|
+
data.tar.gz: 3fffe32b27449490688e0bcb25e7baec737afe87f51bd3bf82f156986a50a06c75e9154c02e1f361601bd38dedea76d995894a951e82cc0f7bf17b3c805fec63
|
@@ -1,80 +1,130 @@
|
|
1
1
|
//= require rails_admin_json_editor/vue.0.11.4
|
2
2
|
//= require rails_admin_json_editor/lodash.2.4.1
|
3
3
|
|
4
|
+
var vm;
|
5
|
+
|
4
6
|
$(document).on('rails_admin.dom_ready', function() {
|
5
7
|
// TODO: Make this possible for multiple instances
|
6
8
|
|
7
|
-
//
|
8
|
-
var data = $('[ref=json-editor]').data('json');
|
9
|
-
if(!data) {
|
10
|
-
data = { components: [] };
|
11
|
-
}
|
9
|
+
// Vue.config.debug = true
|
12
10
|
|
13
|
-
//
|
14
|
-
|
11
|
+
// Get data
|
12
|
+
var jsonResult = $('[ref=json-editor]').data('json-result');
|
13
|
+
var jsonComponentTypes = $('[ref=json-editor]').data('json-component-types');
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
component.tmp = _.clone(componentTmpDefaults);
|
20
|
-
return component;
|
21
|
-
});
|
15
|
+
if(!jsonResult) {
|
16
|
+
jsonResult = { components: [] };
|
17
|
+
}
|
22
18
|
|
23
19
|
// Make sure we let Vue update the json-field, but do it here to prevent data-loss when js is disabled
|
24
|
-
$('[ref=json-
|
20
|
+
$('[ref=json-textarea]').val('');
|
25
21
|
|
26
|
-
//
|
27
|
-
var
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
this.components.push({
|
35
|
-
type: type,
|
22
|
+
// Setup dynamic component-type components
|
23
|
+
var components = {};
|
24
|
+
_.each(jsonComponentTypes, function(c) {
|
25
|
+
components['component-type-' + c.type] = {
|
26
|
+
template: '#template-component-type-' + c.type,
|
27
|
+
data: function() {
|
28
|
+
return {
|
29
|
+
type: null,
|
36
30
|
props: {},
|
37
|
-
|
38
|
-
}
|
31
|
+
expanded: true
|
32
|
+
};
|
39
33
|
},
|
40
|
-
|
41
|
-
|
42
|
-
this.
|
34
|
+
computed: {
|
35
|
+
moveUpEnabled: function() {
|
36
|
+
return this.parentIndex > 0;
|
37
|
+
},
|
38
|
+
moveDownEnabled: function() {
|
39
|
+
return this.parentIndex < this.parentComponents.length - 1;
|
43
40
|
}
|
44
41
|
},
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
var from = index;
|
54
|
-
var to = index + 1;
|
55
|
-
var element = this.components[from];
|
56
|
-
this.components.splice(from, 1);
|
57
|
-
this.components.splice(to, 0, element);
|
58
|
-
},
|
59
|
-
onChangePicker: function(e, index, fieldName) {
|
60
|
-
var el = e.target;
|
61
|
-
var value = el.options[el.selectedIndex].getAttribute('data-json');
|
62
|
-
var json = JSON.parse(value);
|
42
|
+
methods: {
|
43
|
+
moveUp: function() {
|
44
|
+
var from = this.parentIndex;
|
45
|
+
var to = this.parentIndex - 1;
|
46
|
+
var element = this.parentComponents[from];
|
47
|
+
this.parentComponents.splice(from, 1);
|
48
|
+
this.parentComponents.splice(to, 0, element);
|
49
|
+
},
|
63
50
|
|
64
|
-
|
65
|
-
|
51
|
+
moveDown: function() {
|
52
|
+
var from = this.parentIndex;
|
53
|
+
var to = this.parentIndex + 1;
|
54
|
+
var element = this.parentComponents[from];
|
55
|
+
this.parentComponents.splice(from, 1);
|
56
|
+
this.parentComponents.splice(to, 0, element);
|
57
|
+
},
|
66
58
|
|
67
|
-
|
68
|
-
|
69
|
-
|
59
|
+
remove: function() {
|
60
|
+
if(confirm("Are you sure?")) {
|
61
|
+
this.parentComponents.$remove(this.parentIndex);
|
62
|
+
}
|
63
|
+
},
|
70
64
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
65
|
+
// TODO: DRY up with $root.addComponent
|
66
|
+
addComponent: function(event, component, type) {
|
67
|
+
event.preventDefault();
|
68
|
+
|
69
|
+
var clonedProps = _.clone(component.props);
|
70
|
+
if(!clonedProps.components) {
|
71
|
+
clonedProps.components = []
|
72
|
+
}
|
73
|
+
|
74
|
+
var obj = {
|
75
|
+
type: type,
|
76
|
+
props: {}
|
77
|
+
};
|
78
|
+
|
79
|
+
clonedProps.components.push(obj);
|
80
|
+
this.parentComponents[this.parentIndex].props = clonedProps;
|
81
|
+
},
|
82
|
+
|
83
|
+
onChangePicker: function(event, component, fieldName) {
|
84
|
+
var el = event.target;
|
85
|
+
var value = el.options[el.selectedIndex].getAttribute('data-json');
|
86
|
+
var json = JSON.parse(value);
|
87
|
+
|
88
|
+
var clonedProps = _.clone(component.props);
|
89
|
+
clonedProps[fieldName] = json;
|
90
|
+
this.parentComponents[this.parentIndex].props = clonedProps;
|
91
|
+
},
|
92
|
+
|
93
|
+
pickerOptionIsSelected: function(component, fieldName, recordLabel, recordName) {
|
94
|
+
return component.props &&
|
95
|
+
component.props[fieldName] &&
|
96
|
+
component.props[fieldName][recordLabel] &&
|
97
|
+
component.props[fieldName][recordLabel] === recordName;
|
98
|
+
}
|
99
|
+
}
|
100
|
+
};
|
101
|
+
});
|
102
|
+
|
103
|
+
// Let's go
|
104
|
+
vm = new Vue({
|
105
|
+
el: '[ref=json-editor]',
|
106
|
+
data: {
|
107
|
+
components: jsonResult.components,
|
108
|
+
componentTypes: jsonComponentTypes,
|
109
|
+
showJson: false
|
110
|
+
},
|
111
|
+
methods: {
|
112
|
+
addComponent: function(e, type) {
|
113
|
+
e.preventDefault();
|
114
|
+
|
115
|
+
var obj = {
|
116
|
+
type: type,
|
117
|
+
props: {}
|
118
|
+
};
|
119
|
+
|
120
|
+
this.components.push(obj);
|
121
|
+
}
|
122
|
+
},
|
123
|
+
computed: {
|
124
|
+
result: function() {
|
125
|
+
return { components: this.components };
|
77
126
|
}
|
78
|
-
}
|
127
|
+
},
|
128
|
+
components: components
|
79
129
|
});
|
80
130
|
});
|
@@ -3,48 +3,48 @@
|
|
3
3
|
|
4
4
|
<div ref="json-editor"
|
5
5
|
class="json-editor"
|
6
|
-
data-json='<%= raw(field.value.blank? ? '{ "components":[] }' : field.value) %>'
|
6
|
+
data-json-result='<%= raw(field.value.blank? ? '{ "components":[] }' : field.value) %>'
|
7
|
+
data-json-component-types='<%= raw field.components.to_json %>'>
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
<div v-if="component.type == '<%= component.type %>'">
|
9
|
+
<% field.components.each do |component| %>
|
10
|
+
<script type="text/x-template" id="template-component-type-<%= component.type %>">
|
11
|
+
<div class="component">
|
12
12
|
<legend>
|
13
13
|
<%= component.label %>
|
14
14
|
<div class="btn-group btn-group-sm pull-right">
|
15
|
-
<button v-on="click:
|
15
|
+
<button v-on="click: moveUp" type="button" class="btn btn-default {{ moveUpEnabled ? '' : 'disabled' }}">
|
16
16
|
<i class="icon-circle-arrow-up"></i>
|
17
17
|
</button>
|
18
|
-
<button v-on="click:
|
18
|
+
<button v-on="click: moveDown" type="button" class="btn btn-default {{ moveDownEnabled ? '' : 'disabled' }}">
|
19
19
|
<i class="icon-circle-arrow-down"></i>
|
20
20
|
</button>
|
21
|
-
<button v-on="click:
|
22
|
-
<i class="{{
|
21
|
+
<button v-on="click: expanded = !expanded" type="button" class="btn btn-default">
|
22
|
+
<i class="{{ expanded ? 'icon-resize-small' : 'icon-resize-full' }}"></i>
|
23
23
|
</button>
|
24
|
-
<button v-on="click:
|
24
|
+
<button v-on="click:remove" type="button" class="btn btn-default">
|
25
25
|
<i class="icon-remove"></i>
|
26
26
|
</button>
|
27
27
|
</div>
|
28
28
|
</legend>
|
29
29
|
|
30
|
-
<div v-show="
|
30
|
+
<div v-show="expanded">
|
31
31
|
<%= content_tag :p, component.help, class: "help-block" unless component.help.nil? %>
|
32
32
|
|
33
33
|
<% component.fields.each do |f| %>
|
34
34
|
<div class="control-group row">
|
35
|
-
|
35
|
+
<label class="col-sm-2 control-label"><%= f.label %></label>
|
36
36
|
|
37
37
|
<div class="controls col-sm-10">
|
38
38
|
<% if f.type == :string %>
|
39
|
-
|
39
|
+
<input v-model="component.props.<%= f.name %>" type="text" class="form-control" />
|
40
40
|
<% end %>
|
41
41
|
|
42
42
|
<% if f.type == :text %>
|
43
|
-
|
43
|
+
<textarea v-model="component.props.<%= f.name %>" class="form-control"></textarea>
|
44
44
|
<% end %>
|
45
45
|
|
46
46
|
<% if f.type == :picker %>
|
47
|
-
<select v-on="change: onChangePicker($event,
|
47
|
+
<select v-on="change: onChangePicker($event, component, '<%= f.name %>')" class="form-control record-picker">
|
48
48
|
<option value=""></option>
|
49
49
|
<% f.picker_records.each do |record| %>
|
50
50
|
<option
|
@@ -57,13 +57,37 @@
|
|
57
57
|
</select>
|
58
58
|
<% end %>
|
59
59
|
|
60
|
+
<% if f.type == :list %>
|
61
|
+
<% # TODO: DRY up with root-list/dropdown %>
|
62
|
+
<div v-repeat="nested_component: component.props.components">
|
63
|
+
<div
|
64
|
+
v-component="component-type-{{ nested_component.type }}"
|
65
|
+
v-with="component: nested_component, parentComponents: component.props.components, parentIndex: $index">
|
66
|
+
</div>
|
67
|
+
</div>
|
68
|
+
|
69
|
+
<div class="dropdown pull-left">
|
70
|
+
<a class="dropdown-toggle btn btn-info" data-toggle="dropdown" href="#">Component toevoegen <b class="caret"></b></a>
|
71
|
+
<ul class="dropdown-menu">
|
72
|
+
<li v-repeat="componentType: $root.componentTypes">
|
73
|
+
<a href="#" v-on="click: addComponent($event, component, componentType.type)">{{ componentType.label }}</a>
|
74
|
+
</li>
|
75
|
+
</ul>
|
76
|
+
</div>
|
77
|
+
<% end %>
|
78
|
+
|
60
79
|
<%= content_tag :p, f.help, class: "help-block" unless f.help.nil? %>
|
61
80
|
</div>
|
62
81
|
</div>
|
63
82
|
<% end %>
|
64
83
|
</div>
|
65
84
|
</div>
|
66
|
-
|
85
|
+
</script>
|
86
|
+
<% end %>
|
87
|
+
|
88
|
+
<!-- List all components and their fields -->
|
89
|
+
<div v-repeat="component: components">
|
90
|
+
<div v-component="component-type-{{ component.type }}" v-with="component: component, parentComponents: components, parentIndex: $index"></div>
|
67
91
|
</div>
|
68
92
|
|
69
93
|
<!-- Dropdown to add new content -->
|
@@ -71,22 +95,26 @@
|
|
71
95
|
<a class="dropdown-toggle btn btn-info" data-toggle="dropdown" href="#">Component toevoegen <b class="caret"></b></a>
|
72
96
|
|
73
97
|
<ul class="dropdown-menu">
|
74
|
-
|
75
|
-
<
|
76
|
-
|
98
|
+
<li v-repeat="componentType: componentTypes">
|
99
|
+
<a href="#" v-on="click: addComponent($event, componentType.type)">{{ componentType.label }}</a>
|
100
|
+
</li>
|
77
101
|
</ul>
|
78
102
|
</div>
|
79
103
|
|
80
104
|
<!-- Hidden field to store JSON -->
|
81
105
|
<div>
|
82
106
|
<% if Rails.env.development? %>
|
83
|
-
<button v-on="click:
|
107
|
+
<button v-on="click: showJson = !showJson" type="button" class="btn btn-default pull-left btn-toggle-json">
|
84
108
|
<i class="icon-list-alt"></i>
|
85
109
|
</button>
|
86
110
|
<% end %>
|
87
111
|
|
88
|
-
<div v-show="
|
89
|
-
<%= form.text_area field.name,
|
112
|
+
<div v-show="showJson">
|
113
|
+
<%= form.text_area field.name,
|
114
|
+
'v-model' => 'result | json',
|
115
|
+
value: field.value,
|
116
|
+
ref: 'json-textarea',
|
117
|
+
style: 'width:100%; height:400px; margin-top:20px' %>
|
90
118
|
</div>
|
91
119
|
</div>
|
92
120
|
</div>
|
@@ -43,7 +43,7 @@ module RailsAdmin
|
|
43
43
|
def initialize(type)
|
44
44
|
@type = type
|
45
45
|
@fields = []
|
46
|
-
@label = type
|
46
|
+
@label = type.to_s.humanize
|
47
47
|
end
|
48
48
|
|
49
49
|
def field(name, type)
|
@@ -68,11 +68,13 @@ module RailsAdmin
|
|
68
68
|
attr_accessor :label, :help
|
69
69
|
attr_accessor :picker_label
|
70
70
|
attr_accessor :picker_records
|
71
|
+
attr_accessor :components
|
71
72
|
|
72
73
|
def initialize(name, type)
|
73
74
|
@name = name
|
74
75
|
@type = type
|
75
|
-
@label = name
|
76
|
+
@label = name.to_s.humanize
|
77
|
+
@components = [] if type == :list
|
76
78
|
end
|
77
79
|
|
78
80
|
def label(s = nil)
|
@@ -87,6 +89,14 @@ module RailsAdmin
|
|
87
89
|
@picker_label = label
|
88
90
|
@picker_records = records
|
89
91
|
end
|
92
|
+
|
93
|
+
def component(type)
|
94
|
+
component = Component.new(type)
|
95
|
+
|
96
|
+
yield(component) if block_given?
|
97
|
+
|
98
|
+
@components << component
|
99
|
+
end
|
90
100
|
end
|
91
101
|
end
|
92
102
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_admin_json_editor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jasper Haggenburg
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|