admin_it 1.2.8 → 1.3.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.
- checksums.yaml +4 -4
- data/app/assets/javascript/admin_it/admin_it.js +6 -28
- data/app/assets/javascript/admin_it/file_upload.js +109 -0
- data/app/assets/javascript/admin_it/index.js +1 -0
- data/app/assets/stylesheets/admin_it/admin_it.css +21 -0
- data/app/controllers/admin_it/signed_url_controller.rb +1 -0
- data/app/views/admin_it/editors/_image.html.slim +32 -48
- data/app/views/admin_it/shared/_fields.html.slim +1 -1
- data/app/views/admin_it/shared/_form.html.slim +0 -5
- data/lib/admin_it/field/field.rb +17 -5
- data/lib/admin_it/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 117d0fbca72494a8c37ea5eb2abdd847521dd3fc
|
4
|
+
data.tar.gz: ab30fbe27aa45970be70c08c8c08f2dfdef0398f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b8d5ea4ec7dbbe1a2284b19b765593ca158e8706900f2820e7eff81d66e08567a0a010b82a222e083532ecb69d3e9b735fda48b20d4a685b13327f7957f4aec1
|
7
|
+
data.tar.gz: c68d91a6fa29c710176ca48ddc2ac69a13452fe00a155a25413a0f3085adbda7c167772445051a25356df296f66c1eff8c38e0ac3dbeedcfe7a995bc8e1f96fc
|
@@ -72,6 +72,7 @@ var initTabs = function() {
|
|
72
72
|
$('[data-tab="' + $(e.relatedTarget).attr('href') + '"]').removeClass('in');
|
73
73
|
$('[data-tab="' + $(e.target).attr('href') + '"]').addClass('in');
|
74
74
|
$('form input[type="hidden"][name="section"]').val($(this).attr('href').substr(1));
|
75
|
+
initTiles();
|
75
76
|
});
|
76
77
|
var active = $('.active > [data-toggle="tab"]');
|
77
78
|
if (active.length > 0) {
|
@@ -90,33 +91,10 @@ var initLinks = function() {
|
|
90
91
|
}
|
91
92
|
|
92
93
|
var initImageUploads = function() {
|
93
|
-
$
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
dataType: 'xml',
|
98
|
-
add: function(evt, data) {
|
99
|
-
$.ajax({
|
100
|
-
url: $form.data('signUrl') + '/',
|
101
|
-
type: 'GET',
|
102
|
-
dataType: 'json',
|
103
|
-
data: { doc: { title: data.files[0].name } },
|
104
|
-
async: false,
|
105
|
-
success: function(data) {
|
106
|
-
// Now that we have our data, we update the form so it contains all
|
107
|
-
// the needed data to sign the request
|
108
|
-
$form.find('input[name=key]').val(data.key)
|
109
|
-
$form.find('input[name=policy]').val(data.policy)
|
110
|
-
$form.find('input[name=signature]').val(data.signature)
|
111
|
-
}
|
112
|
-
});
|
113
|
-
data.submit();
|
114
|
-
},
|
115
|
-
success: function(data) {
|
116
|
-
// Here we get the file url on s3 in an xml doc
|
117
|
-
var url = $(data).find('Location').text()
|
118
|
-
$($form.data('input')).val(url) // Update the real input in the other form
|
119
|
-
},
|
94
|
+
$('[data-toggle="file-upload"]').fileUpload({
|
95
|
+
success: function(el, response) {
|
96
|
+
$(el.data('image')).attr('src', response.small_url);
|
97
|
+
}
|
120
98
|
});
|
121
99
|
}
|
122
100
|
|
@@ -153,12 +131,12 @@ var initControls = function() {
|
|
153
131
|
initImageUploads();
|
154
132
|
initSelects();
|
155
133
|
initGeoPickers();
|
134
|
+
initTiles();
|
156
135
|
}
|
157
136
|
|
158
137
|
$(document).on('ready page:load', function() {
|
159
138
|
initPartials();
|
160
139
|
// initDialogs();
|
161
|
-
initTiles();
|
162
140
|
initTabs();
|
163
141
|
initPopups();
|
164
142
|
initLinks();
|
@@ -0,0 +1,109 @@
|
|
1
|
+
(function($) {
|
2
|
+
function parseOptions(element, options) {
|
3
|
+
var opts = $.extend({}, $.fn.fileUpload.defaults, element.data(), options);
|
4
|
+
opts.target = $(opts.target).first();
|
5
|
+
if (opts.target.length == 0) opts.target = null;
|
6
|
+
return opts;
|
7
|
+
};
|
8
|
+
|
9
|
+
function getCss(target) {
|
10
|
+
var pos = (target) ? target.position() : { top: 0, left: 0 };
|
11
|
+
if (target) {
|
12
|
+
pos.top -= parseInt(target.css('border-top-width'));
|
13
|
+
pos.left -= parseInt(target.css('border-left-width'));
|
14
|
+
pos.width = target.outerWidth();
|
15
|
+
pos.height = target.outerHeight();
|
16
|
+
}
|
17
|
+
return pos;
|
18
|
+
};
|
19
|
+
|
20
|
+
function completed(opts, success, response) {
|
21
|
+
// replace file input element to preven file uploading while form submitting
|
22
|
+
var input = opts.input
|
23
|
+
.clone()
|
24
|
+
.on('change', function() { addFile.apply(this, [opts]); });
|
25
|
+
opts.input.remove();
|
26
|
+
opts.input = input.appendTo(opts.wrapper);
|
27
|
+
if (!success) {
|
28
|
+
alert('Ошибка загрузки файла');
|
29
|
+
return;
|
30
|
+
}
|
31
|
+
if ($.isFunction(opts.success)) opts.success(input, response);
|
32
|
+
};
|
33
|
+
|
34
|
+
function addFile(opts) {
|
35
|
+
if (opts.started) {
|
36
|
+
alert('В данный момент загружается другой файл. ' +
|
37
|
+
'Дождитесь окончания загрузки');
|
38
|
+
return;
|
39
|
+
}
|
40
|
+
opts.started = true;
|
41
|
+
var xhr = new XMLHttpRequest();
|
42
|
+
var uploaded = false;
|
43
|
+
|
44
|
+
if (xhr.upload) {
|
45
|
+
xhr.upload.addEventListener("load", function(e) { uploaded = true; }, false);
|
46
|
+
} else {
|
47
|
+
uploaded = true;
|
48
|
+
}
|
49
|
+
|
50
|
+
xhr.onreadystatechange = function() {
|
51
|
+
if (this.readyState == 4) {
|
52
|
+
opts.started = false;
|
53
|
+
if (this.status < 400) {
|
54
|
+
completed(
|
55
|
+
opts,
|
56
|
+
uploaded,
|
57
|
+
(uploaded) ? $.parseJSON(this.responseText) : null
|
58
|
+
);
|
59
|
+
} else {
|
60
|
+
completed(opts, false, null);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
};
|
64
|
+
|
65
|
+
var el = opts.input.get(0);
|
66
|
+
var filename = el.files[0].name;
|
67
|
+
var method = (opts.method || opts.uploadMethod || 'POST').toUpperCase();
|
68
|
+
xhr.open(method, opts.url || opts.uploadUrl);
|
69
|
+
xhr.setRequestHeader('Accept', 'application/json');
|
70
|
+
|
71
|
+
// W3C (IE9, Chrome, Safari, Firefox 4+)
|
72
|
+
var formData = new FormData();
|
73
|
+
formData.append(opts.fieldName || 'file', el.files[0], filename);
|
74
|
+
if (opts.token) {
|
75
|
+
formData.append(opts.tokenName || 'token', opts.token);
|
76
|
+
}
|
77
|
+
xhr.send(formData);
|
78
|
+
};
|
79
|
+
|
80
|
+
function init(element, opts) {
|
81
|
+
if (!opts.target) return;
|
82
|
+
if (element.parent().hasClass('file-upload-wrapper')) return;
|
83
|
+
opts.wrapper = $('<div class="file-upload-wrapper"></div>').append(element);
|
84
|
+
// small timeout needed to take effect in DOM model
|
85
|
+
setTimeout(function() {
|
86
|
+
opts.css = getCss(opts.target);
|
87
|
+
opts.wrapper
|
88
|
+
.css(opts.css)
|
89
|
+
.appendTo(opts.target);
|
90
|
+
opts.input = element.on('change', function() { addFile.apply(this, [opts]); });
|
91
|
+
}, 100);
|
92
|
+
return opts;
|
93
|
+
};
|
94
|
+
|
95
|
+
$.fn.fileUpload = function(action, options) {
|
96
|
+
if ($.isPlainObject(action)) options = action;
|
97
|
+
if (typeof action !== 'string') action = 'init';
|
98
|
+
return this.each(function() {
|
99
|
+
var $this = $(this);
|
100
|
+
var opts = parseOptions($this, options);
|
101
|
+
if (action === 'init') {
|
102
|
+
init($this, opts);
|
103
|
+
}
|
104
|
+
});
|
105
|
+
};
|
106
|
+
|
107
|
+
$.fn.fileUpload.defaults = {
|
108
|
+
}
|
109
|
+
})(jQuery);
|
@@ -27,3 +27,24 @@
|
|
27
27
|
.fileupload-image img, .admin-show-image {
|
28
28
|
max-width: 500px;
|
29
29
|
}
|
30
|
+
|
31
|
+
[data-toggle="file-upload"] {
|
32
|
+
opacity: 0,
|
33
|
+
filter: alpha(opacity:0);
|
34
|
+
font-size: 600px;
|
35
|
+
cursor: pointer;
|
36
|
+
padding: 0;
|
37
|
+
margin: 0;
|
38
|
+
border: none;
|
39
|
+
margin-left: -450px;
|
40
|
+
}
|
41
|
+
|
42
|
+
.file-upload-wrapper {
|
43
|
+
position: absolute;
|
44
|
+
overflow: hidden;
|
45
|
+
z-index: 10000;
|
46
|
+
}
|
47
|
+
|
48
|
+
#image_image_button {
|
49
|
+
margin-top: 10px;
|
50
|
+
}
|
@@ -1,50 +1,34 @@
|
|
1
1
|
- for_context ||= context
|
2
|
-
- id ||= "#{for_context.resource.name}_#{field.name}_fileupload"
|
3
|
-
/- opts = { name: name || "#{for_context.resource.name}[#{field.name}]", \
|
4
|
-
/ id: , \
|
5
|
-
/ value: value || field.read(for_context.entity) }
|
6
2
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
/button.btn.btn-warning.cancel type="reset"
|
40
|
-
i.fa.fa-ban>
|
41
|
-
span = t('admin_it.image.cancel')
|
42
|
-
/! The global file processing state
|
43
|
-
span.fileupload-process
|
44
|
-
/! The global progress state
|
45
|
-
.col-lg-3.fileupload-progress.fade
|
46
|
-
/! The global progress bar
|
47
|
-
.progress.progress-striped.active aria-valuemax="100" aria-valuemin="0" role="progressbar"
|
48
|
-
.progress-bar.progress-bar-success style="width:0%;"
|
49
|
-
/! The extended global progress state
|
50
|
-
.progress-extended
|
3
|
+
- name ||= "#{for_context.resource.name}[#{field.name}]"
|
4
|
+
- buttonId = "#{for_context.resource.name}_#{field.name}_button"
|
5
|
+
- imageId = "#{for_context.resource.name}_#{field.name}_image"
|
6
|
+
- value ||= field.read(for_context.entity)
|
7
|
+
- upload_url = field.options[:upload_url]
|
8
|
+
- unless upload_url.blank?
|
9
|
+
- upload_url.gsub!(/:[a-zA-Z][a-zA-Z_0-9]+/) { |n| for_context.entity.send(n[1..-1]) }
|
10
|
+
- opts = { name: name, value: value }
|
11
|
+
- opts[:id] = id if defined? id
|
12
|
+
- opts['data-toggle'] = 'file-upload'
|
13
|
+
- opts['data-target'] = "##{buttonId}"
|
14
|
+
- opts['data-upload-url'] = field.options[:upload_url] if field.options.key?(:upload_url)
|
15
|
+
- opts['data-token-name'] = 'authenticity_token'
|
16
|
+
- opts['data-token'] = form_authenticity_token
|
17
|
+
- opts['data-delete-url'] = field.options[:delete_url] if field.options.key?(:delete_url)
|
18
|
+
- opts['data-image'] = "##{imageId}"
|
19
|
+
|
20
|
+
- url = field.show(for_context.entity)
|
21
|
+
- collapsed = url.blank? ? {} : { class: 'in' }
|
22
|
+
|
23
|
+
div
|
24
|
+
.collapsed *collapsed
|
25
|
+
img src=url id=imageId
|
26
|
+
.btn-group
|
27
|
+
- if opts.key?('data-upload-url')
|
28
|
+
.btn.btn-success id=buttonId
|
29
|
+
i.fa.fa-upload data-toggle="file-select"
|
30
|
+
input type="file" *opts
|
31
|
+
- if opts.key?('data-delete-url') && !url.blank?
|
32
|
+
.btn.btn-danger
|
33
|
+
i.fa.fa-trash-o data-toggle="file-delete"
|
34
|
+
|
@@ -18,7 +18,7 @@
|
|
18
18
|
|
19
19
|
/ visible fields
|
20
20
|
- fields.each do |field|
|
21
|
-
|
21
|
+
/- if field.type == :image
|
22
22
|
- locals = { field: field, for_context: for_context, id: "#{for_context.resource.name}_#{field.name}" }
|
23
23
|
= render partial: File.join(%w(admin_it editors hidden)), locals: locals
|
24
24
|
- next
|
@@ -8,11 +8,6 @@
|
|
8
8
|
- elsif for_context.is_a?(AdminIt::EditContext)
|
9
9
|
- action = resource.single_path(for_context.entity)
|
10
10
|
|
11
|
-
/ images
|
12
|
-
- for_context.fields(scope: { editor: :image }).each do |field|
|
13
|
-
- locals = { field: field, for_context: for_context }
|
14
|
-
= render partial: File.join(%w(admin_it editors image)), locals: locals
|
15
|
-
|
16
11
|
form.form-horizontal role="form" action=action method="POST"
|
17
12
|
input name="authenticity_token" type="hidden" value=form_authenticity_token
|
18
13
|
input name="section" type="hidden" value=parent.section
|
data/lib/admin_it/field/field.rb
CHANGED
@@ -28,6 +28,7 @@ module AdminIt
|
|
28
28
|
dsl_accessor :type, default: TYPES[0]
|
29
29
|
dsl_accessor :placeholder
|
30
30
|
dsl_accessor :partial
|
31
|
+
dsl_accessor :options, default: {}
|
31
32
|
dsl_accessor :editor, default: EDITORS[0]
|
32
33
|
dsl_boolean :readable, :writable, :visible, :sortable, :show_label
|
33
34
|
dsl_block :read, :write, :render, :display
|
@@ -42,7 +43,7 @@ module AdminIt
|
|
42
43
|
end
|
43
44
|
|
44
45
|
class << self
|
45
|
-
attr_reader :read, :write, :render, :display, :type, :partial
|
46
|
+
attr_reader :read, :write, :render, :display, :type, :partial, :options
|
46
47
|
|
47
48
|
protected
|
48
49
|
|
@@ -78,12 +79,17 @@ module AdminIt
|
|
78
79
|
Class.new(base) do
|
79
80
|
@field_name, @entity_class = name, _entity_class
|
80
81
|
import_data_module(base)
|
82
|
+
self.type = opts[:type]
|
81
83
|
@readable = opts[:readable].nil? ? true : opts[:readable] == true
|
82
84
|
@writable = opts[:writable].nil? ? true : opts[:writable] == true
|
83
85
|
@visible = opts[:visible].nil? ? true : opts[:visible] == true
|
84
86
|
@sortable = opts[:sortable].nil? ? true : opts[:sortable] == true
|
87
|
+
@options = opts[:options].is_a?(Hash) ? opts[:options] : {}
|
88
|
+
if type == :image
|
89
|
+
@options[:s3] = {} unless @options[:s3].is_a?(Hash)
|
90
|
+
@options[:s3] = {}.merge(AdminIt.config.s3, @options[:s3])
|
91
|
+
end
|
85
92
|
@show_label = opts[:show_label].nil? ? true : opts[:show_label] == true
|
86
|
-
self.type = opts[:type]
|
87
93
|
self.editor = opts[:editor] unless opts[:editor].nil?
|
88
94
|
end
|
89
95
|
end
|
@@ -104,6 +110,10 @@ module AdminIt
|
|
104
110
|
@partial ||= nil
|
105
111
|
end
|
106
112
|
|
113
|
+
def self.optionis
|
114
|
+
@options ||= {}
|
115
|
+
end
|
116
|
+
|
107
117
|
def self.hide
|
108
118
|
@visible = false
|
109
119
|
end
|
@@ -120,10 +130,12 @@ module AdminIt
|
|
120
130
|
@editor = EDITORS[0]
|
121
131
|
end
|
122
132
|
|
123
|
-
class_attr_reader :entity_class, :display_name, :type, :partial, :editor
|
133
|
+
class_attr_reader :entity_class, :display_name, :type, :partial, :editor,
|
134
|
+
:options
|
124
135
|
attr_writer :visible, :readable, :writable
|
125
136
|
|
126
|
-
def initialize(readable: nil, writable: nil, visible: nil, sortable: nil,
|
137
|
+
def initialize(readable: nil, writable: nil, visible: nil, sortable: nil,
|
138
|
+
show_label: nil, options: nil)
|
127
139
|
run_callbacks :initialize do
|
128
140
|
@readable = readable.nil? ? self.class.readable? : readable == true
|
129
141
|
@writable = writable.nil? ? self.class.writable? : writable == true
|
@@ -226,7 +238,7 @@ module AdminIt
|
|
226
238
|
# end
|
227
239
|
|
228
240
|
def show_value(entity)
|
229
|
-
value =
|
241
|
+
value = read(entity)
|
230
242
|
if type == :enum
|
231
243
|
value.text
|
232
244
|
elsif type == :geo_point
|
data/lib/admin_it/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: admin_it
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexey Ovchinnikov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-07-
|
11
|
+
date: 2014-07-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -247,6 +247,7 @@ files:
|
|
247
247
|
- app/assets/fonts/admin_it/glyphicons-halflings-regular.woff
|
248
248
|
- app/assets/javascript/admin_it/admin_it.js
|
249
249
|
- app/assets/javascript/admin_it/bootstrap.min.js
|
250
|
+
- app/assets/javascript/admin_it/file_upload.js
|
250
251
|
- app/assets/javascript/admin_it/index.js
|
251
252
|
- app/assets/javascript/admin_it/jquery.fileupload-main.js
|
252
253
|
- app/assets/javascript/admin_it/jquery.fileupload-process.js
|