alchemy-custom-model 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +147 -0
- data/Rakefile +32 -0
- data/app/assets/config/alchemy_custom_model_manifest.js +3 -0
- data/app/assets/images/alchemy-custom-model/no_image.png +0 -0
- data/app/assets/javascripts/alchemy-custom-model/change_language.js +11 -0
- data/app/assets/javascripts/alchemy-custom-model/common_init.js +16 -0
- data/app/assets/javascripts/alchemy-custom-model/custom_admin_element_editor.js.coffee +25 -0
- data/app/assets/javascripts/alchemy-custom-model/custom_tiny_mce.js.coffee.erb +95 -0
- data/app/assets/javascripts/alchemy-custom-model/el_finder.js.coffee.erb +241 -0
- data/app/assets/javascripts/alchemy-custom-model/elfinder_ui_manifest.js +4 -0
- data/app/assets/javascripts/alchemy-custom-model/manifest.js +23 -0
- data/app/assets/javascripts/alchemy-custom-model/nested_attributes_sortable.js.coffee +25 -0
- data/app/assets/javascripts/alchemy-custom-model/select2filter.js +51 -0
- data/app/assets/javascripts/alchemy-custom-model/subobjects.js +98 -0
- data/app/assets/javascripts/alchemy-custom-model/total_page_elfinder.js.coffee +15 -0
- data/app/assets/stylesheets/alchemy-custom-model/custom_elfinder.css.scss +130 -0
- data/app/assets/stylesheets/alchemy-custom-model/custom_style.css.scss +228 -0
- data/app/assets/stylesheets/alchemy-custom-model/custom_tiny_mce.scss +6 -0
- data/app/assets/stylesheets/alchemy-custom-model/manifest.css +16 -0
- data/app/controllers/alchemy/custom/model/admin/base_controller.rb +189 -0
- data/app/controllers/alchemy/custom/model/admin/files_controller.rb +106 -0
- data/app/controllers/alchemy/pages_controller_decorator.rb +1 -0
- data/app/helpers/alchemy/custom/model/admin/base_helper.rb +379 -0
- data/app/helpers/alchemy/custom/model/base_helper.rb +18 -0
- data/app/helpers/alchemy/custom/model/custom_model_helper.rb +112 -0
- data/app/helpers/alchemy/pages_helper_decorator.rb +95 -0
- data/app/models/admin_override_to_param.rb +9 -0
- data/app/models/application_record.rb +9 -0
- data/app/views/alchemy/custom/model/admin/base/_buttons_tool.html.erb +16 -0
- data/app/views/alchemy/custom/model/admin/base/_gallery_item.html.erb +4 -0
- data/app/views/alchemy/custom/model/admin/base/_language_tree_select.html.erb +9 -0
- data/app/views/alchemy/custom/model/admin/base/_search_box.html.erb +19 -0
- data/app/views/alchemy/custom/model/admin/base/_seo.html.erb +8 -0
- data/app/views/alchemy/custom/model/admin/base/_table.html.erb +33 -0
- data/app/views/alchemy/custom/model/admin/base/_title.html.erb +3 -0
- data/app/views/alchemy/custom/model/admin/base/edit.html.erb +18 -0
- data/app/views/alchemy/custom/model/admin/base/index.html.erb +39 -0
- data/app/views/alchemy/custom/model/admin/base/new.html.erb +19 -0
- data/app/views/alchemy/custom/model/admin/files/error_notice.json.jbuilder +1 -0
- data/app/views/alchemy/custom/model/admin/files/ui.html.erb +13 -0
- data/config/initializers/elfinder_abilities.rb +1 -0
- data/config/locales/en.yml +11 -0
- data/config/locales/it.yml +21 -0
- data/config/routes.rb +8 -0
- data/lib/alchemy-custom-model.rb +29 -0
- data/lib/alchemy/custom/model/el_finder.rb +17 -0
- data/lib/alchemy/custom/model/el_finder/ability.rb +16 -0
- data/lib/alchemy/custom/model/el_finder/connector.rb +435 -0
- data/lib/alchemy/custom/model/el_finder/image.rb +35 -0
- data/lib/alchemy/custom/model/el_finder/path_name.rb +220 -0
- data/lib/alchemy/custom/model/el_finder/paths.rb +21 -0
- data/lib/alchemy/custom/model/el_finder/paths/active_record_reference.rb +50 -0
- data/lib/alchemy/custom/model/el_finder/paths/base.rb +298 -0
- data/lib/alchemy/custom/model/el_finder/paths/component_file.rb +59 -0
- data/lib/alchemy/custom/model/el_finder/paths/component_files.rb +34 -0
- data/lib/alchemy/custom/model/el_finder/paths/file.rb +23 -0
- data/lib/alchemy/custom/model/el_finder/paths/files.rb +25 -0
- data/lib/alchemy/custom/model/el_finder/paths/image.rb +42 -0
- data/lib/alchemy/custom/model/el_finder/paths/images.rb +31 -0
- data/lib/alchemy/custom/model/el_finder/paths/root.rb +24 -0
- data/lib/alchemy/custom/model/el_finder/volumes.rb +18 -0
- data/lib/alchemy/custom/model/el_finder/volumes/alchemy_file.rb +197 -0
- data/lib/alchemy/custom/model/el_finder/volumes/alchemy_files.rb +51 -0
- data/lib/alchemy/custom/model/el_finder/volumes/alchemy_images.rb +69 -0
- data/lib/alchemy/custom/model/el_finder/volumes/base.rb +149 -0
- data/lib/alchemy/custom/model/el_finder/volumes/component_attribute.rb +130 -0
- data/lib/alchemy/custom/model/engine.rb +40 -0
- data/lib/alchemy/custom/model/global_id_setter.rb +35 -0
- data/lib/alchemy/custom/model/model_decoration.rb +82 -0
- data/lib/alchemy/custom/model/pages_controller_dec.rb +132 -0
- data/lib/alchemy/custom/model/translation_scope.rb +18 -0
- data/lib/alchemy/custom/model/version.rb +7 -0
- data/lib/alchemy/touching_decorator.rb +12 -0
- data/lib/tasks/alchemy_custom_model_tasks.rake +41 -0
- data/vendor/elfinder/css/elfinder.full.css +5117 -0
- data/vendor/elfinder/css/elfinder.min.css +9 -0
- data/vendor/elfinder/css/theme.css +349 -0
- data/vendor/elfinder/js/elfinder.full.js +34270 -0
- data/vendor/elfinder/js/elfinder.min.js +25 -0
- metadata +194 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6e6c70590f98f7fe1059a6473d7040a66c9db41c
|
4
|
+
data.tar.gz: 18f20f4575cafc620bddda500c480fdc625ea86d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 51728d319fc807d859f16377af2b92184f6ade99a46371f55c7677488d078c029c24ba192f2de4a5431443418d968a503aa20887ac1e07b2d3ea60ff16f42fde
|
7
|
+
data.tar.gz: b78843f5e537763eef6dc5e75e0bffcb66ed99a7395ce9ff3a404a9e3f31a74699557ec13dd2c7d791df309be61c31c786eaf86e90b182535d6cad7b1f5c5593
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2018 Alessandro Baccanelli
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
# Alchemy::Custom::Model [WIP]
|
2
|
+
Short description and motivation.
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
How to use my plugin.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'alchemy-custom-model'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
```bash
|
21
|
+
$ gem install alchemy-custom-model
|
22
|
+
```
|
23
|
+
|
24
|
+
Then run the installer
|
25
|
+
```bash
|
26
|
+
bin/rails alchemy_custom_model:install
|
27
|
+
```
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
* Generate your model
|
32
|
+
|
33
|
+
* remember to append a column for language:
|
34
|
+
```ruby
|
35
|
+
t.integer :language_id
|
36
|
+
```
|
37
|
+
* if this model would have a custom url and the relative layout, go to the
|
38
|
+
[friendly_id page](https://github.com/norman/friendly_id) to make the correct install
|
39
|
+
* we can define on the model this attributes to be used for page SEO:
|
40
|
+
* text :meta_description
|
41
|
+
* text :meta_keywords
|
42
|
+
* string :meta_title
|
43
|
+
* boolean :robot_follow
|
44
|
+
* boolean :robot_index
|
45
|
+
|
46
|
+
* include the model decorator
|
47
|
+
```ruby
|
48
|
+
|
49
|
+
include Alchemy::Custom::Model::ModelDecoration
|
50
|
+
|
51
|
+
```
|
52
|
+
* attach yours belongs_to relations to alchemy_elements
|
53
|
+
```ruby
|
54
|
+
|
55
|
+
# For attachments, the foreign_key is the key defined in the model, can be omitted if it's standard Rails naming
|
56
|
+
belongs_to :file, class_name: "Alchemy::Attachment", optional: true, foreign_key: :file_id
|
57
|
+
global_id_setter :file
|
58
|
+
|
59
|
+
# For Pictures
|
60
|
+
belongs_to :picture, class_name: 'Alchemy::Picture', optional: true, touch: true
|
61
|
+
global_id_setter :picture
|
62
|
+
```
|
63
|
+
* Generate your controller:
|
64
|
+
```ruby
|
65
|
+
bin/rails g controller Admin::Posts
|
66
|
+
```
|
67
|
+
* inherit from Alchemy::Custom::Model::Admin::BaseController
|
68
|
+
* Create the routes (prepend it to alchemy routes and alchemy_custom_model routes)
|
69
|
+
* Build the ability for your recipe:
|
70
|
+
```ruby
|
71
|
+
class PostAbility
|
72
|
+
include CanCan::Ability
|
73
|
+
|
74
|
+
def initialize(user)
|
75
|
+
if user.present? && (user.is_admin? or user.has_role?("editor"))
|
76
|
+
can :manage, Post #model
|
77
|
+
can :manage, :admin_posts #routes to the posts withouth _path
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
```
|
83
|
+
|
84
|
+
* build the abilities in ad initializer Es: "menu_and_abilities.rb"
|
85
|
+
```ruby
|
86
|
+
Alchemy::Modules.register_module({
|
87
|
+
name: 'Posts', # custom name
|
88
|
+
order: 2,
|
89
|
+
navigation: {
|
90
|
+
name: 'modules.posts',
|
91
|
+
controller: '/admin/posts', #controller path
|
92
|
+
action: 'index', #action
|
93
|
+
icon: "question" # custom icon
|
94
|
+
}
|
95
|
+
})
|
96
|
+
Alchemy.register_ability(PostAbility)
|
97
|
+
```
|
98
|
+
|
99
|
+
* Costruisci la form per il modello
|
100
|
+
```ruby
|
101
|
+
|
102
|
+
<%= base_form_container do %>
|
103
|
+
<div class="form_in_page">
|
104
|
+
<%= simple_form_for [:admin,@obj] do |f| %>
|
105
|
+
<fieldset>
|
106
|
+
|
107
|
+
<%= f.input :name %>
|
108
|
+
<%= rich_text_editor(f, :description) %>
|
109
|
+
<%= single_image_input(f, :picture) %>
|
110
|
+
<%= single_attachment_input(f, :file) %>
|
111
|
+
...
|
112
|
+
|
113
|
+
```
|
114
|
+
|
115
|
+
* Per elementi come subobject seguire l'esempio di codice nei test che rivedono le varie opzioni
|
116
|
+
* Per modelli che si legano direttamente con componenti di alchemy è necessario utilizzare delle relazioni generiche che identificato il record:
|
117
|
+
```ruby
|
118
|
+
belongs_to :picture, class_name: 'Alchemy::Picture', touch: true
|
119
|
+
belongs_to :alchemy_file_instance, class_name: 'Alchemy::Picture', foreign_key: :picture_id #relazione generica per i files utilizzata nel volume di elfinder
|
120
|
+
```
|
121
|
+
* Per la visualizzazione creare quindi un layout in Alchemy con attributi custom_model e custom_model_action che serve per identificare
|
122
|
+
la generazione dei link index e show
|
123
|
+
```yml
|
124
|
+
- name: layout_name_list
|
125
|
+
elements: [element_for_list]
|
126
|
+
custom_model: "CustomModelClass"
|
127
|
+
custom_model_action: "index"
|
128
|
+
cache: false
|
129
|
+
|
130
|
+
- name: layout_name_show
|
131
|
+
elements: [element_for_show]
|
132
|
+
custom_model: "CustomModelClass"
|
133
|
+
custom_model_action: "show"
|
134
|
+
cache: false
|
135
|
+
```
|
136
|
+
* E' necessario quindi creare le due pagine nella struttura di alchemy
|
137
|
+
|
138
|
+
## Development
|
139
|
+
|
140
|
+
git clone --recursive git@github.com:ArchimediaZerogroup/alchemy-custom-model.git
|
141
|
+
|
142
|
+
docker build -t alchemy_custom_image .
|
143
|
+
|
144
|
+
docker run -it -p3000:3000 --rm -v "$(pwd)":/app alchemy_custom_image bin/rails s -b 0.0.0.0
|
145
|
+
|
146
|
+
## License
|
147
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Alchemy::Custom::Model'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
load 'rails/tasks/statistics.rake'
|
21
|
+
|
22
|
+
require 'bundler/gem_tasks'
|
23
|
+
|
24
|
+
require 'rake/testtask'
|
25
|
+
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
27
|
+
t.libs << 'test'
|
28
|
+
t.pattern = 'test/**/*_test.rb'
|
29
|
+
t.verbose = false
|
30
|
+
end
|
31
|
+
|
32
|
+
task default: :test
|
Binary file
|
@@ -0,0 +1,11 @@
|
|
1
|
+
|
2
|
+
$(document).on("page:change turbolinks:load",function () {
|
3
|
+
|
4
|
+
$('select#change_language').on('change',function (e){
|
5
|
+
var url = window.location.pathname;
|
6
|
+
var delimiter = url.match(/\?/) ? '&' : '?';
|
7
|
+
Turbolinks.visit(url+delimiter+"language_id="+$(this).val());
|
8
|
+
});
|
9
|
+
|
10
|
+
});
|
11
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
$(document).on("'page:change turbolinks:load", function(){
|
2
|
+
$(".datepicker-date").datetimepicker({
|
3
|
+
scrollInput: false,
|
4
|
+
format: "d/m/Y",
|
5
|
+
timepicker: false,
|
6
|
+
datepicker: true,
|
7
|
+
dayOfWeekStart: 0
|
8
|
+
})
|
9
|
+
|
10
|
+
$(".datepicker-time").datetimepicker({
|
11
|
+
format:'H:i',
|
12
|
+
timepicker: true,
|
13
|
+
datepicker: false,
|
14
|
+
step: 15
|
15
|
+
})
|
16
|
+
});
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#= require 'alchemy/alchemy.element_editors'
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
window.CustomProxedElementEditor = $.extend {}, Alchemy.ElementEditors
|
6
|
+
|
7
|
+
|
8
|
+
$.extend window.CustomProxedElementEditor,
|
9
|
+
init: (selector = "#element_area")->
|
10
|
+
@element_area = $(selector)
|
11
|
+
@bindEvents()
|
12
|
+
|
13
|
+
@initialize_tinymce()
|
14
|
+
return
|
15
|
+
|
16
|
+
initialize_tinymce: ()->
|
17
|
+
ids = []
|
18
|
+
@element_area.find('.has_tinymce').each (i, e)->
|
19
|
+
ids.push($(e).attr("id").match(/[0-9]+/)[0])
|
20
|
+
Alchemy.Tinymce.init(ids)
|
21
|
+
|
22
|
+
|
23
|
+
# disattivazione del check di reload pagina
|
24
|
+
$(document).on 'submit', '.simple_form.alchemy', (e)=>
|
25
|
+
window.onbeforeunload = null;
|
@@ -0,0 +1,95 @@
|
|
1
|
+
#= require 'lodash/lodash.js'
|
2
|
+
|
3
|
+
#duplichiamo la classe
|
4
|
+
class CustomTinyMce extends Alchemy.Tinymce
|
5
|
+
|
6
|
+
|
7
|
+
#per come è stato fatto dobbiamo estendere la classe tramite i metodi che usa jquery
|
8
|
+
$.extend CustomTinyMce,
|
9
|
+
|
10
|
+
|
11
|
+
# {
|
12
|
+
# skin: 'alchemy',
|
13
|
+
# width: 'auto',
|
14
|
+
# resize: true,
|
15
|
+
# autoresize_min_height: '105',
|
16
|
+
# autoresize_max_height: '480',
|
17
|
+
# menubar: false,
|
18
|
+
# statusbar: true,
|
19
|
+
# toolbar: [
|
20
|
+
# 'bold italic underline | strikethrough subscript superscript | numlist bullist indent outdent | removeformat | fullscreen',
|
21
|
+
# 'pastetext charmap hr | undo redo | alchemy_link unlink anchor | code'
|
22
|
+
# ],
|
23
|
+
# fix_list_elements: true,
|
24
|
+
# convert_urls: false,
|
25
|
+
# entity_encoding: 'raw',
|
26
|
+
# paste_as_text: true,
|
27
|
+
# element_format: 'html',
|
28
|
+
# branding: false
|
29
|
+
# }
|
30
|
+
|
31
|
+
getDefaultConfig: (id) ->
|
32
|
+
configs = $.extend true, {}, Alchemy.Tinymce.getDefaultConfig(id)
|
33
|
+
configs.init_instance_callback = @initInstanceCallback
|
34
|
+
|
35
|
+
configs.plugins += ",image"
|
36
|
+
configs.toolbar[1] += ' | link image'
|
37
|
+
configs.file_picker_callback = (callback, value, meta)->
|
38
|
+
|
39
|
+
volumes = []
|
40
|
+
|
41
|
+
if (meta.filetype == 'file')
|
42
|
+
volumes.push('AlchemyFiles');
|
43
|
+
|
44
|
+
|
45
|
+
# // Provide image and alt text for the image dialog
|
46
|
+
if (meta.filetype == 'image')
|
47
|
+
volumes.push('AlchemyImages');
|
48
|
+
|
49
|
+
tinymce.activeEditor.windowManager.open({
|
50
|
+
file: '<%= Alchemy::Custom::Model::Engine.routes.url_helpers.admin_elfinder_ui_path() %>?'+$.param({volumes:volumes}),# Routes.admin_elfinder_ui_path(volumes:volumes), #// use an absolute path!
|
51
|
+
title: 'elFinder 2.1',
|
52
|
+
width: 900,
|
53
|
+
height: 450,
|
54
|
+
resizable: 'yes'
|
55
|
+
}, {
|
56
|
+
oninsert: (file, fm)->
|
57
|
+
# // URL normalization
|
58
|
+
url = fm.convAbsUrl(file.url);
|
59
|
+
|
60
|
+
# // Make file info
|
61
|
+
info = file.name + ' (' + fm.formatSize(file.size) + ')';
|
62
|
+
|
63
|
+
# // Provide file and text for the link dialog
|
64
|
+
if (meta.filetype == 'file')
|
65
|
+
callback(file.original_url, {text: info, title: info})
|
66
|
+
|
67
|
+
|
68
|
+
# // Provide image and alt text for the image dialog
|
69
|
+
if (meta.filetype == 'image')
|
70
|
+
callback(file.original_url, {alt: info})
|
71
|
+
|
72
|
+
|
73
|
+
# // Provide alternative source and posted for the media dialog
|
74
|
+
if (meta.filetype == 'media')
|
75
|
+
callback(url)
|
76
|
+
|
77
|
+
return false;
|
78
|
+
});
|
79
|
+
|
80
|
+
return configs
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
initInstanceCallback: (editor) ->
|
85
|
+
$this = $("##{editor.id}")
|
86
|
+
element = $this.closest('.tinymce_container')
|
87
|
+
element.on 'parent_stop_sorted', _.debounce(()=>
|
88
|
+
id = editor.getElement().id.replace(/^tinymce_/, '')
|
89
|
+
editor.remove();
|
90
|
+
CustomTinyMce.initEditor(id)
|
91
|
+
, 100)
|
92
|
+
element.find('.spinner').remove()
|
93
|
+
|
94
|
+
|
95
|
+
@CustomTinyMce = CustomTinyMce
|
@@ -0,0 +1,241 @@
|
|
1
|
+
#= require elfinder/js/elfinder.full
|
2
|
+
# require js-routes
|
3
|
+
#= require 'eventemitter3/umd/eventemitter3'
|
4
|
+
|
5
|
+
##
|
6
|
+
# Classe di elfinder per autoconfigurarsi rispetto a determinate opzioni
|
7
|
+
# mode: Modalità di selezione:
|
8
|
+
# - single_selection -> indica la selezione singola
|
9
|
+
# - multiple_selection -> selection multipla dei files
|
10
|
+
# volumes -> Elenco dei volumi da montare come stringa divisa da ,
|
11
|
+
# AlchemyImages -> solo immagini
|
12
|
+
# AlchemyFiles -> solo attachments
|
13
|
+
# non settato -> tutti -> Alchemy
|
14
|
+
# nome_inventato -> dovrà avere la relativa configurazione nella volumes_cfgs e le informazioni
|
15
|
+
# per identificare correttamente che volume montare
|
16
|
+
# volumes_cfgs -> oggetto con configurazioni per i volumi
|
17
|
+
# l'oggetto dovrà essere composto da chiave=nome del volume usato in volumes e un oggetto con
|
18
|
+
# le configurazioni:
|
19
|
+
# {
|
20
|
+
# - volume = nome del volume da utilizzare in ruby come connettore
|
21
|
+
# - attribute = attributo nell'oggetto a cui si riferisce il collegamento del volume
|
22
|
+
# - object = oggetto identificato con un global_id signed
|
23
|
+
# }
|
24
|
+
#
|
25
|
+
class ElFinderConfigurator
|
26
|
+
|
27
|
+
constructor: (opts)->
|
28
|
+
@ee = new EventEmitter3;
|
29
|
+
|
30
|
+
{@mode, @volumes, @volumes_cfgs}=opts
|
31
|
+
|
32
|
+
@mode = opts.mode ? 'single_selection'
|
33
|
+
@volumes = opts.volumes ? null
|
34
|
+
@volumes_cfgs = opts.volumes_cfgs ? null
|
35
|
+
|
36
|
+
@height = opts.height ? 400 #TODO automatizzare dinamicamente l'altezza?
|
37
|
+
|
38
|
+
@el_finder = null
|
39
|
+
|
40
|
+
start: (container)->
|
41
|
+
@el_finder = container.elfinder(@configurations())
|
42
|
+
@attach_events()
|
43
|
+
|
44
|
+
configurations: ->
|
45
|
+
cfgs = {
|
46
|
+
url:'<%= Alchemy::Custom::Model::Engine.routes.url_helpers.admin_elfinder_path() %>'
|
47
|
+
#lang: 'it',
|
48
|
+
cssAutoLoad: false # Disable CSS auto loading
|
49
|
+
baseUrl: './'
|
50
|
+
height: @height,
|
51
|
+
commands: ['*'],
|
52
|
+
soundPath:'<%= asset_path('/assets/elfinder/sounds') %>',
|
53
|
+
reloadClearHistory: true
|
54
|
+
rememberLastDir: false
|
55
|
+
useBrowserHistory: false
|
56
|
+
commandsOptions:
|
57
|
+
search:
|
58
|
+
incsearch:
|
59
|
+
enable: false # // is enable true or false
|
60
|
+
# minlen: 1 # // minimum number of characters
|
61
|
+
# wait: 10000 # // wait milliseconds
|
62
|
+
searchTypes:
|
63
|
+
SearchMime: # // The key is search type that send to the connector
|
64
|
+
name: 'btnMime'# // Button text to be processed in i18n()
|
65
|
+
title: 'searchMime' #// Button title to be processed in i18n()
|
66
|
+
AlchemyTags:
|
67
|
+
name: 'Alchemy Tags'
|
68
|
+
title: 'Ricerca per tags di alchemy'
|
69
|
+
uiOptions: {
|
70
|
+
toolbar: [
|
71
|
+
#['home', 'back', 'forward', 'up', 'reload'],
|
72
|
+
#['netmount'],
|
73
|
+
#['mkdir', 'mkfile', 'upload'],
|
74
|
+
['upload'],
|
75
|
+
['open', 'download', 'getfile'],
|
76
|
+
#['undo', 'redo'],
|
77
|
+
['rm'],
|
78
|
+
#['copy', 'cut', 'paste', 'rm', 'empty', 'hide'],
|
79
|
+
['duplicate', 'rename', 'edit', 'resize'], #, 'chmod'
|
80
|
+
['selectall', 'selectnone', 'selectinvert'],
|
81
|
+
['quicklook'], #, 'info'
|
82
|
+
#['extract', 'archive'],
|
83
|
+
['search'],
|
84
|
+
['view', 'sort'],
|
85
|
+
#['preference', 'help'],
|
86
|
+
#['fullscreen']
|
87
|
+
]
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
if(@volumes)
|
92
|
+
cfgs.customData = cfgs.customData || {}
|
93
|
+
cfgs.customData['volumes'] = @volumes.split(',')
|
94
|
+
if(@volumes_cfgs)
|
95
|
+
cfgs.customData['volumes_cfgs'] = @volumes_cfgs
|
96
|
+
|
97
|
+
if(@mode == 'single_selection')
|
98
|
+
cfgs.getFileCallback = (file, fm)=>
|
99
|
+
@emit('file_select', file, fm)
|
100
|
+
|
101
|
+
cfgs
|
102
|
+
|
103
|
+
attach_events: ()->
|
104
|
+
@elfinder_instance().bind 'paste', (event, fm)=>
|
105
|
+
@emit('paste_files', event, fm)
|
106
|
+
@emit('change', event, fm)
|
107
|
+
@elfinder_instance().bind 'upload', (event,fm)=>
|
108
|
+
@emit('upload', event, fm)
|
109
|
+
@elfinder_instance().bind 'remove', (event, fm)=>
|
110
|
+
@emit('remove_files', event, fm)
|
111
|
+
@emit('change', event, fm)
|
112
|
+
|
113
|
+
|
114
|
+
on: ()->
|
115
|
+
@ee.on.apply(@ee, arguments)
|
116
|
+
|
117
|
+
once: ()->
|
118
|
+
@ee.once.apply(@ee, arguments)
|
119
|
+
|
120
|
+
emit: ()->
|
121
|
+
@ee.emit.apply(@ee, arguments)
|
122
|
+
|
123
|
+
remove: ()->
|
124
|
+
@el_finder.remove();
|
125
|
+
|
126
|
+
elfinder_instance: ()->
|
127
|
+
@el_finder.elfinder('instance')
|
128
|
+
|
129
|
+
@ElFinderConfigurator = ElFinderConfigurator
|
130
|
+
|
131
|
+
##
|
132
|
+
# Classe per la gestione e configurazione di elfinder e della sua apertura in modal
|
133
|
+
#
|
134
|
+
# Configurazioni presenti su data dell'activator(bottone o altro che lancia l'evento di el finder)
|
135
|
+
#
|
136
|
+
# elfinderTarget -> indica la input in cui posizionare il valore selezionato nella single selection
|
137
|
+
# oppure il selector da utilizzare per rimpiazzare con il contenuto proveniente dal
|
138
|
+
# partial generato
|
139
|
+
#
|
140
|
+
# elfinderThumbTarget -> tag in cui settare la src con la thumb dell'immagine
|
141
|
+
#
|
142
|
+
# elfinderMimeIconUpdater -> selettore css dove applicare le classi di elfinder per l'incona dell'imagine
|
143
|
+
#
|
144
|
+
#
|
145
|
+
# Configurazioni che vengono riportare poi verso ElFinderConfigurator
|
146
|
+
# elfinderMode: Modalità di selezione:
|
147
|
+
# - single_selection -> indica la selezione singola
|
148
|
+
# - multiple_selection -> selection multipla dei files
|
149
|
+
# elfinderVolumes -> Elenco dei volumi da montare
|
150
|
+
# AlchemyImages -> solo immagini
|
151
|
+
# AlchemyFiles -> solo attachments
|
152
|
+
# non settato -> tutti -> Alchemy
|
153
|
+
class ElFinderDialog
|
154
|
+
|
155
|
+
constructor: (@activator)->
|
156
|
+
options = $(@activator).data()
|
157
|
+
|
158
|
+
@opts = {
|
159
|
+
target: options['elfinderTarget'],
|
160
|
+
thumb_target: options['elfinderThumbTarget'],
|
161
|
+
mime_icon_updater: options['elfinderMimeIconUpdater']
|
162
|
+
target_upgrader: options['elfinderTargetUpgrader']
|
163
|
+
}
|
164
|
+
|
165
|
+
@elfinder = new ElFinderConfigurator({
|
166
|
+
mode: options['elfinderMode'],
|
167
|
+
volumes: options['elfinderVolumes'],
|
168
|
+
volumes_cfgs: options['elfinderVolumesCfgs'],
|
169
|
+
height: 700
|
170
|
+
})
|
171
|
+
|
172
|
+
@dialog_container = $("<div><div class='el_finder'></div></div>")
|
173
|
+
$('body').append(@dialog_container)
|
174
|
+
|
175
|
+
|
176
|
+
attach_events: ()->
|
177
|
+
if(@elfinder.mode == 'single_selection')
|
178
|
+
@elfinder.once('file_select', (file, fm)=>
|
179
|
+
$(@opts.target).val(file.global_id)
|
180
|
+
if(@opts.thumb_target)
|
181
|
+
$(@opts.thumb_target).attr('src', file.tmb)
|
182
|
+
if(@opts.mime_icon_updater)
|
183
|
+
$(@opts.mime_icon_updater).attr('class', '').addClass("elfinder-cwd-icon #{fm.mime2class(file.mime)}")
|
184
|
+
|
185
|
+
@close()
|
186
|
+
)
|
187
|
+
|
188
|
+
if(@elfinder.mode == 'multiple_selection')
|
189
|
+
@elfinder.on 'change', (event)=>
|
190
|
+
reload_target_url.call(this)
|
191
|
+
|
192
|
+
@elfinder.on 'upload', (event)=>
|
193
|
+
reload_target_url.call(this)
|
194
|
+
|
195
|
+
reload_target_url = ->
|
196
|
+
$.ajax
|
197
|
+
url: @opts.target_upgrader
|
198
|
+
success: (data)=>
|
199
|
+
elemento_gallery = $(data).find(@opts.target)
|
200
|
+
$(@opts.target).html($(elemento_gallery).html())
|
201
|
+
|
202
|
+
|
203
|
+
open: ->
|
204
|
+
@dialog_container.dialog
|
205
|
+
width: $(document).width() * 0.7
|
206
|
+
modal: true
|
207
|
+
position: { my: "top", at: "top", of: window }
|
208
|
+
|
209
|
+
open: ()=>
|
210
|
+
@elfinder.start(@dialog_container.find('.el_finder'))
|
211
|
+
@attach_events()
|
212
|
+
|
213
|
+
|
214
|
+
close: ->
|
215
|
+
@elfinder.remove();
|
216
|
+
@dialog_container.dialog('close').dialog("destroy");
|
217
|
+
|
218
|
+
|
219
|
+
$(document).on 'click', '.open_el_finder', (e)->
|
220
|
+
e.preventDefault()
|
221
|
+
dialog = new ElFinderDialog(this)
|
222
|
+
dialog.open();
|
223
|
+
|
224
|
+
|
225
|
+
##
|
226
|
+
# Pulizia selezione
|
227
|
+
$(document).on 'click', '.clear_selection', (e)->
|
228
|
+
e.preventDefault()
|
229
|
+
opts = $(this).data();
|
230
|
+
$(opts.clearfieldTarget).val(null)
|
231
|
+
if(opts.clearfieldThumbTarget)
|
232
|
+
$(opts.clearfieldThumbTarget).attr('src', opts.clearfieldThumbTargetReplace)
|
233
|
+
if(opts.clearfieldIcon)
|
234
|
+
$(opts.clearfieldIcon).attr('class','')
|
235
|
+
|
236
|
+
|
237
|
+
|
238
|
+
|
239
|
+
|
240
|
+
|
241
|
+
|