it-logica-application-backbone 0.1.5 → 0.1.6
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.
- data/VERSION +1 -1
- data/app/views/helpers/_build_ajax_callback_code.html.erb +3 -0
- data/app/views/helpers/_build_breadcrumb.html.erb +31 -0
- data/app/views/helpers/_build_datafiles.html.erb +243 -0
- data/app/views/helpers/_build_table.html.erb +4 -0
- data/app/views/helpers/_build_table_data.html.erb +14 -0
- data/app/views/helpers/_build_table_filter.html.erb +114 -0
- data/app/views/helpers/_build_table_pager.html.erb +9 -0
- data/app/views/helpers/_build_table_wrapper.html.erb +115 -0
- data/it-logica-application-backbone.gemspec +17 -1
- data/lib/controller_mixins/csv_instance_methods.rb +15 -0
- data/lib/controller_mixins/renderer_instance_methods.rb +101 -0
- data/lib/initializers/initialize.rb +59 -0
- data/lib/it-logica-application-backbone.rb +3 -0
- data/lib/model_mixins/table_builder_class_methods.rb +189 -0
- data/lib/view_mixins/breadcrumb.rb +44 -0
- data/lib/view_mixins/form.rb +47 -0
- data/lib/view_mixins/link.rb +117 -0
- data/lib/view_mixins/table.rb +6 -0
- metadata +28 -12
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.6
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<ul class="breadcrumb">
|
2
|
+
<li>
|
3
|
+
<%= ajax_link_to "Úvodní stránka", "/" %>
|
4
|
+
<% if !breadcrumb.blank? %>
|
5
|
+
<span class="divider">/</span>
|
6
|
+
<% end %>
|
7
|
+
</li>
|
8
|
+
<% if !breadcrumb.blank? && breadcrumb.kind_of?(Array) %>
|
9
|
+
<% breadcrumb.each_with_index do |b, i| %>
|
10
|
+
<% if is_tree_node?(b) %>
|
11
|
+
<% if breadcrumb.count - 1 == i %>
|
12
|
+
<li class="active"><%= b.name %></li>
|
13
|
+
<% else %>
|
14
|
+
<li>
|
15
|
+
<%= link_to b.name, convert_settings_to_url(b.to_json), :onclick => "load_page(#{b.to_json}); return false;" %>
|
16
|
+
<span class="divider">/</span>
|
17
|
+
</li>
|
18
|
+
<% end %>
|
19
|
+
<% elsif b.kind_of?(Hash) %>
|
20
|
+
<% if breadcrumb.count - 1 == i %>
|
21
|
+
<li class="active"><%= b[:name] %></li>
|
22
|
+
<% else %>
|
23
|
+
<li>
|
24
|
+
<%= link_to b[:name], convert_settings_to_url(b.to_json), :onclick => "load_page(#{b.to_json}); return false;" %>
|
25
|
+
<span class="divider">/</span>
|
26
|
+
</li>
|
27
|
+
<% end %>
|
28
|
+
<% end %>
|
29
|
+
<% end %>
|
30
|
+
<% end %>
|
31
|
+
</ul>
|
@@ -0,0 +1,243 @@
|
|
1
|
+
<% form_id = "fileupload_#{object.id}" %>
|
2
|
+
<% index_url = url_for(:controller => "/datafiles", "datafile[owner_type]" => "#{object.class.name.to_s}", "datafile[owner_id]" => "#{object.id.to_s}") %>
|
3
|
+
<%
|
4
|
+
#if is_tree_node?(object)
|
5
|
+
# tree_node = object
|
6
|
+
# unless tree_node.blank?
|
7
|
+
# bread_crumb_load_tree_recursive(breadcrumb, tree_node)
|
8
|
+
# end
|
9
|
+
#elsif object.respond_to?(:tree_nodes)
|
10
|
+
# if !object.tree_nodes.blank? && !object.tree_nodes.first.blank? && is_tree_node?(object.tree_nodes.first)
|
11
|
+
# tree_node = object.tree_nodes.first if !object.tree_nodes.blank? && !object.tree_nodes.first.blank?
|
12
|
+
# end
|
13
|
+
#end
|
14
|
+
tree_node = { :resource_type => "#{object.class.name.to_s}", :resource_id => "#{object.id.to_s}"}
|
15
|
+
%>
|
16
|
+
<% if !tree_node.blank? %>
|
17
|
+
<script type="text/javascript">
|
18
|
+
// loading tiny_mce connected to datafiles
|
19
|
+
$(document).ready(function () {
|
20
|
+
$('<%= tiny_mce_selector %>').LadasTinyMce(<%= tree_node.to_json.html_safe %>);
|
21
|
+
});
|
22
|
+
</script>
|
23
|
+
<% end %>
|
24
|
+
|
25
|
+
|
26
|
+
<script>
|
27
|
+
var fileUploadErrors = {
|
28
|
+
maxFileSize:'Soubor je příliš velký',
|
29
|
+
minFileSize:'Soubor je příliš malý',
|
30
|
+
acceptFileTypes:'Nepovolený typ souboru',
|
31
|
+
maxNumberOfFiles:'Překročen maximální počet souborů, které lze nahrát zaráz.',
|
32
|
+
uploadedBytes:'Nahrané data překročili velikost souboru.',
|
33
|
+
emptyResult:'Nelze nahrát prázdný soubor'
|
34
|
+
};
|
35
|
+
// var fileUploadErrors = {
|
36
|
+
// maxFileSize: 'File is too big',
|
37
|
+
// minFileSize: 'File is too small',
|
38
|
+
// acceptFileTypes: 'Filetype not allowed',
|
39
|
+
// maxNumberOfFiles: 'Max number of files exceeded',
|
40
|
+
// uploadedBytes: 'Uploaded bytes exceed file size',
|
41
|
+
// emptyResult: 'Empty file upload result'
|
42
|
+
// };
|
43
|
+
window.locale = {
|
44
|
+
"fileupload": {
|
45
|
+
"errors": {
|
46
|
+
"maxFileSize": "File is too big",
|
47
|
+
"minFileSize": "File is too small",
|
48
|
+
"acceptFileTypes": "Filetype not allowed",
|
49
|
+
"maxNumberOfFiles": "Max number of files exceeded",
|
50
|
+
"uploadedBytes": "Uploaded bytes exceed file size",
|
51
|
+
"emptyResult": "Empty file upload result"
|
52
|
+
},
|
53
|
+
"error": "Error",
|
54
|
+
"start": "Start",
|
55
|
+
"cancel": "Cancel",
|
56
|
+
"destroy": "Smazat"
|
57
|
+
}
|
58
|
+
};
|
59
|
+
|
60
|
+
|
61
|
+
</script>
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
<%= form_for Datafile.new, :html => {:multipart => true, :id => "#{form_id}"} do |f| %>
|
67
|
+
<!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
|
68
|
+
<!--<div class="row fileupload-buttonbar btn-group" >-->
|
69
|
+
<% if can_upload %>
|
70
|
+
<div class="fileupload-buttonbar btn-group">
|
71
|
+
<div class="span7">
|
72
|
+
<!-- The fileinput-button span is used to style the file input field as button -->
|
73
|
+
|
74
|
+
<span class="btn btn-success fileinput-button">
|
75
|
+
<i class="icon-plus icon-white"></i>
|
76
|
+
<span>Přidat soubory...</span>
|
77
|
+
|
78
|
+
<%= text_field_tag "datafile[owner_type]", "#{object.class.name.to_s}" %>
|
79
|
+
<%= text_field_tag "datafile[owner_id]", "#{object.id.to_s}" %>
|
80
|
+
<%= f.file_field :file, :multiple => true %>
|
81
|
+
<%#= f.file_field :file%>
|
82
|
+
</span>
|
83
|
+
<button type="submit" class="btn btn-primary start">
|
84
|
+
<i class="icon-upload icon-white"></i>
|
85
|
+
<span>Začít upload</span>
|
86
|
+
</button>
|
87
|
+
<button type="reset" class="btn btn-warning cancel">
|
88
|
+
<i class="icon-ban-circle icon-white"></i>
|
89
|
+
<span>Zrušit upload</span>
|
90
|
+
</button>
|
91
|
+
<!--<button type="button" class="btn btn-danger delete" onclick="if (!confirm('Chcete opravdu smazat označené soubory?')){event.stopPropagation();return false;}">-->
|
92
|
+
<!--<i class="icon-trash icon-white"></i>-->
|
93
|
+
<!--<span>Smazat</span>-->
|
94
|
+
<!--</button>-->
|
95
|
+
<!--<input type="checkbox" class="toggle" title="Označit vše">-->
|
96
|
+
</div>
|
97
|
+
<div class="span5">
|
98
|
+
<!-- The global progress bar -->
|
99
|
+
<div class="progress progress-success progress-striped active fade">
|
100
|
+
<div class="bar" style="width:0%;"></div>
|
101
|
+
</div>
|
102
|
+
</div>
|
103
|
+
</div>
|
104
|
+
<% end %>
|
105
|
+
<!-- The loading indicator is shown during image processing -->
|
106
|
+
<div class="fileupload-loading"></div>
|
107
|
+
<br>
|
108
|
+
<!-- The table listing the files available for upload/download -->
|
109
|
+
<table class="table table-striped">
|
110
|
+
<thead>
|
111
|
+
<th>Náhled</th>
|
112
|
+
<th>Název</th>
|
113
|
+
<th>Vytvořen</th>
|
114
|
+
<th>Velikost</th>
|
115
|
+
<th></th>
|
116
|
+
|
117
|
+
</thead>
|
118
|
+
<tbody class="files" data-toggle="modal-gallery" data-target="#modal-gallery"></tbody>
|
119
|
+
</table>
|
120
|
+
<% end %>
|
121
|
+
|
122
|
+
|
123
|
+
<!-- The template to display files available for upload -->
|
124
|
+
<script id="template-upload" type="text/x-tmpl">
|
125
|
+
{% for (var i=0, file; file=o.files[i]; i++) { %}
|
126
|
+
<tr class="template-upload fade">
|
127
|
+
<td class="preview"><span class="fade"></span></td>
|
128
|
+
<td class="name"><span>{%=file.name%}</span></td>
|
129
|
+
<td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
|
130
|
+
{% if (file.error) { %}
|
131
|
+
<td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span>
|
132
|
+
{%=locale.fileupload.errors[file.error] || file.error%}
|
133
|
+
</td>
|
134
|
+
{% } else if (o.files.valid && !i) { %}
|
135
|
+
<td>
|
136
|
+
<div class="progress progress-success progress-striped active">
|
137
|
+
<div class="bar" style="width:0%;"></div>
|
138
|
+
</div>
|
139
|
+
</td>
|
140
|
+
<td class="start">{% if (!o.options.autoUpload) { %}
|
141
|
+
<button class="btn btn-primary">
|
142
|
+
<i class="icon-upload icon-white"></i>
|
143
|
+
<span>{%=locale.fileupload.start%}</span>
|
144
|
+
</button>
|
145
|
+
{% } %}
|
146
|
+
</td>
|
147
|
+
{% } else { %}
|
148
|
+
<td colspan="2"></td>
|
149
|
+
{% } %}
|
150
|
+
<td class="cancel">{% if (!i) { %}
|
151
|
+
<button class="btn btn-warning">
|
152
|
+
<i class="icon-ban-circle icon-white"></i>
|
153
|
+
<span>{%=locale.fileupload.cancel%}</span>
|
154
|
+
</button>
|
155
|
+
{% } %}
|
156
|
+
</td>
|
157
|
+
</tr>
|
158
|
+
{% } %}
|
159
|
+
</script>
|
160
|
+
<!-- The template to display files available for download -->
|
161
|
+
<script id="template-download" type="text/x-tmpl">
|
162
|
+
{% for (var i=0, file; file=o.files[i]; i++) { %}
|
163
|
+
<tr class="template-download fade">
|
164
|
+
{% if (file.error) { %}
|
165
|
+
<td></td>
|
166
|
+
<td class="name"><span>{%=file.name%}</span></td>
|
167
|
+
<td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
|
168
|
+
<td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span>
|
169
|
+
{%=locale.fileupload.errors[file.error] || file.error%}
|
170
|
+
</td>
|
171
|
+
{% } else { %}
|
172
|
+
<td class="preview">{% if (file.thumbnail_url) { %}
|
173
|
+
<a href="{%=file.url%}" title="{%=file.name%}" rel="gallery" download="{%=file.name%}"><img src="{%=file.thumbnail_url%}"></a>
|
174
|
+
{% } %}
|
175
|
+
</td>
|
176
|
+
<td class="name">
|
177
|
+
{% var sliced_name=file.name; %}
|
178
|
+
{% if (sliced_name.length > 20) { %}
|
179
|
+
{% sliced_name = sliced_name.slice(0,17) + '...'; %}
|
180
|
+
{% } %}
|
181
|
+
<a href="{%=file.url%}" title="{%=file.name%}" rel="{%=file.thumbnail_url&&'gallery'%}" download="{%=file.name%}">{%=sliced_name%}</a>
|
182
|
+
</td>
|
183
|
+
{% var sliced_user_name=file.user_name; %}
|
184
|
+
{% if (sliced_user_name.length > 20) { %}
|
185
|
+
{% sliced_user_name = sliced_user_name.slice(0,17) + '...'; %}
|
186
|
+
{% } %}
|
187
|
+
<td class="size"><span>{%=file.created_at%}, <a href="mailto:{%=file.user_email%}" title="{%=file.user_name%}">{%=sliced_user_name%}</a></span></td>
|
188
|
+
<td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
|
189
|
+
<td colspan="2"></td>
|
190
|
+
{% } %}
|
191
|
+
{% if (file.delete_url) { %}
|
192
|
+
<td class="delete">
|
193
|
+
<button class="btn btn-danger" data-type="{%=file.delete_type%}" data-url="{%=file.delete_url%}" onclick="if (!confirm('Chcete opravdu smazat tento soubor?')){event.stopPropagation();return false;}">
|
194
|
+
<i class="icon-trash icon-white"></i>
|
195
|
+
<span>{%=locale.fileupload.destroy%}</span>
|
196
|
+
</button>
|
197
|
+
<!--<input type="checkbox" name="delete" value="1">-->
|
198
|
+
</td>
|
199
|
+
{% } %}
|
200
|
+
</tr>
|
201
|
+
{% } %}
|
202
|
+
</script>
|
203
|
+
|
204
|
+
|
205
|
+
|
206
|
+
<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->
|
207
|
+
<%= javascript_include_tag 'jquery.ui.widget.js' %>
|
208
|
+
<!-- The Templates and Load Image plugins are included for the FileUpload user interface -->
|
209
|
+
<!--<script src="http://blueimp.github.com/JavaScript-Templates/tmpl.min.js"></script>-->
|
210
|
+
<!--<script src="http://blueimp.github.com/JavaScript-Load-Image/load-image.min.js"></script>-->
|
211
|
+
|
212
|
+
<%= javascript_include_tag 'tmpl.min.js' %>
|
213
|
+
<%= javascript_include_tag 'load-image.min.js' %>
|
214
|
+
|
215
|
+
<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->
|
216
|
+
<%= javascript_include_tag 'jquery.iframe-transport.js' %>
|
217
|
+
<%= javascript_include_tag 'jquery.fileupload.js' %>
|
218
|
+
<%= javascript_include_tag 'jquery.fileupload-ui.js' %>
|
219
|
+
<!-- add include_tag js files to config.assets.precompile in ...environments/production.rb if you have it in vendor/ assets -->
|
220
|
+
|
221
|
+
<script type="text/javascript" charset="utf-8">
|
222
|
+
$(function () {
|
223
|
+
// Initialize the jQuery File Upload widget:
|
224
|
+
$('#<%= form_id %>').fileupload();
|
225
|
+
//
|
226
|
+
// Load existing files:
|
227
|
+
//$.getJSON($('#
|
228
|
+
|
229
|
+
$.getJSON("<%= index_url %>", function (files) {
|
230
|
+
var fu = $('#<%= form_id %>').data('fileupload'),
|
231
|
+
template;
|
232
|
+
fu._adjustMaxNumberOfFiles(-files.length);
|
233
|
+
template = fu._renderDownload(files)
|
234
|
+
.appendTo($('#<%= form_id %> .files'));
|
235
|
+
// Force reflow:
|
236
|
+
fu._reflow = fu._transition && template.length &&
|
237
|
+
template[0].offsetWidth;
|
238
|
+
template.addClass('in');
|
239
|
+
$('#loading').remove();
|
240
|
+
});
|
241
|
+
|
242
|
+
});
|
243
|
+
</script>
|
@@ -0,0 +1,4 @@
|
|
1
|
+
<%= form_tag settings[:filter_path], :html => {:'data-type' => 'html'}, :method => 'POST', :class => 'forms', :remote => true, :id => settings[:form_id] do |f| %>
|
2
|
+
<%= render :partial => "/helpers/build_table_filter", :locals => {:settings => settings} %>
|
3
|
+
<%= render :partial => "/helpers/build_table_wrapper", :locals => {:settings => settings} %>
|
4
|
+
<% end %>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<% settings[:data].each do |row| %>
|
2
|
+
<tr class="<%= cycle('list-line-odd', 'list-line-even') %>">
|
3
|
+
<td class="sortdiv_td">
|
4
|
+
<%#= link_to t('edit'), {:controller => :users_rights, :action => :edit, :id => item.id}, :class => "icon modify" %>
|
5
|
+
<%#= link_to(t('delete'), {:controller => :users_rights, :action => :delete, :id => item.id}, :confirm => 'Are you sure you want to delete this user?', :title => 'Delete', :method => :delete) -%>
|
6
|
+
</td>
|
7
|
+
<% settings[:columns].each do |col| %>
|
8
|
+
<td class="sortdiv_td">
|
9
|
+
<%= row.send(col[:name]) %>
|
10
|
+
</td>
|
11
|
+
<% end %>
|
12
|
+
</tr>
|
13
|
+
<% end %>
|
14
|
+
|
@@ -0,0 +1,114 @@
|
|
1
|
+
<%#= form_tag settings[:filter_path], :html => {:'data-type' => 'html'}, :method => 'POST', :class => 'forms', :remote => true,:id => settings[:form_id] do |f| %>
|
2
|
+
<fieldset>
|
3
|
+
<%#= label_tag :find, "Hledat" %>
|
4
|
+
<%#= text_field_tag :find, settings[:default][:find], {:class => 'text', :id => settings[:form_id] + "_live_search"} %>
|
5
|
+
<%#= submit_tag "Filter",{:class => 'button'} %>
|
6
|
+
</fieldset>
|
7
|
+
|
8
|
+
<%= hidden_field_tag :order_by, settings[:default][:order_by], :id => settings[:form_id] + '_order_by' %>
|
9
|
+
<%= hidden_field_tag :order_by_direction, settings[:default][:order_by_direction], :id => settings[:form_id] + '_order_by_direction' %>
|
10
|
+
<%= hidden_field_tag :page, settings[:default][:page], :id => settings[:form_id] + '_page' %>
|
11
|
+
|
12
|
+
<%# end %>
|
13
|
+
|
14
|
+
<%#= javascript_include_tag 'backbone_js/tmpl.min.js' %>
|
15
|
+
<script type="text/javascript">
|
16
|
+
$(document).ready(function () {
|
17
|
+
<% if settings[:template].blank? %>
|
18
|
+
$("#<%= settings[:form_id] %>_ajax_content").html(tmpl('template-ajax-table', jQuery.parseJSON('<%= settings.to_json.html_safe %>')));
|
19
|
+
apply_modifiers_of_the_table($("#<%= settings[:form_id] %>_ajax_content"));
|
20
|
+
<% end %>
|
21
|
+
formatLinkForPaginationURL('<%= settings[:form_id] %>');
|
22
|
+
|
23
|
+
$("#<%= settings[:form_id] %>")
|
24
|
+
.live("ajax:beforeSend", function (evt, xhr, settings) {
|
25
|
+
ladas_loading_show();
|
26
|
+
})
|
27
|
+
.live("ajax:complete", function (evt, xhr, status) {
|
28
|
+
var parsed_response = jQuery.parseJSON(xhr.responseText);
|
29
|
+
|
30
|
+
//console.log(xhr.responseText)
|
31
|
+
//console.log(parsed_response);
|
32
|
+
//console.log(parsed_response['settings']);
|
33
|
+
$(".<%= settings[:form_id] %>_ajax_pager").html(parsed_response['paginate']);
|
34
|
+
|
35
|
+
//console.log(ladas_build_table('template-ajax-table', parsed_response));
|
36
|
+
<% if settings[:template].blank? %>
|
37
|
+
var parsed_settings = jQuery.parseJSON(parsed_response['settings'])
|
38
|
+
$("#<%= settings[:form_id] %>_ajax_content").html(tmpl('template-ajax-table', parsed_settings));
|
39
|
+
apply_modifiers_of_the_table($("#<%= settings[:form_id] %>_ajax_content"));
|
40
|
+
|
41
|
+
<% else %>
|
42
|
+
var raw_html = parsed_response['settings']
|
43
|
+
$("#<%= settings[:form_id] %>_ajax_content").html(raw_html);
|
44
|
+
<% end %>
|
45
|
+
|
46
|
+
ladas_loading_hide();
|
47
|
+
formatLinkForPaginationURL('<%= settings[:form_id] %>');
|
48
|
+
})
|
49
|
+
});
|
50
|
+
</script>
|
51
|
+
|
52
|
+
|
53
|
+
<script id="template-ajax-table" type="text/x-tmpl">
|
54
|
+
{% for (var i=0, row ; row=o.data[i]; i++) { %}
|
55
|
+
<tr class="">
|
56
|
+
|
57
|
+
{% if (o.row.functions) { %}
|
58
|
+
<td>
|
59
|
+
{% for (var function_name in o.row.functions) { %}
|
60
|
+
{% var settings = o.row.functions[function_name]; %}
|
61
|
+
{% settings.symlink_id = row.row_id; %}
|
62
|
+
{% stringified_settings = JSON.stringify(settings); %}
|
63
|
+
{% var non_ajax_url = build_get_url(settings); %}
|
64
|
+
{% if (settings.confirm) { %}
|
65
|
+
<a href="{%= non_ajax_url %}" class="{%= settings['class'] %}" onclick="if (confirm('{%= settings.confirm %}')){ load_page({%=stringified_settings%}); }; return false;" >{%= settings.name %}</a>
|
66
|
+
{% } else { %}
|
67
|
+
<a href="{%= non_ajax_url %}" class="{%= settings['class'] %}" onclick="load_page({%=stringified_settings%}); return false;">{%= settings.name %}</a>
|
68
|
+
{% } %}
|
69
|
+
{% } %}
|
70
|
+
</td>
|
71
|
+
{% } %}
|
72
|
+
|
73
|
+
{% for (var j=0, col; col=o.columns[j]; j++) { %}
|
74
|
+
<td class="{%= col.class %}">
|
75
|
+
{% if (is_hash(row[col.table + '_' + col.name])) { %}
|
76
|
+
{% var button_settings = row[col.table + '_' + col.name]; %}
|
77
|
+
{% button_settings['origin'] = 'table'; %}
|
78
|
+
{% var stringified_button_settings = JSON.stringify(button_settings); %}
|
79
|
+
|
80
|
+
{% if (button_settings.symlink_controller || button_settings.symlink_action || button_settings.symlink_id || button_settings.symlink_outer_controller || button_settings.symlink_outer_id) { %}
|
81
|
+
<a href="#" class="{%= button_settings['class'] %}" data-tr_class="{%= button_settings.tr_class %}" onclick="load_page({%= stringified_button_settings %}, this); return false;">{%= button_settings['name'] %}</a>
|
82
|
+
{% } else { %}
|
83
|
+
<span class="{%= button_settings['class'] %}" data-tr_class="{%= button_settings.tr_class %}">{%= button_settings['name'] %}</span>
|
84
|
+
{% } %}
|
85
|
+
{% } else if (is_array(row[col.table + '_' + col.name])) { %}
|
86
|
+
{% var one_cell_buttons = row[col.table + '_' + col.name]; %}
|
87
|
+
{% for (var b=0, one_cell_button; one_cell_button=one_cell_buttons[b]; b++) { %}
|
88
|
+
{% var button_settings = one_cell_button; %}
|
89
|
+
{% button_settings['origin'] = 'table'; %}
|
90
|
+
{% var stringified_button_settings = JSON.stringify(button_settings); %}
|
91
|
+
|
92
|
+
{% if (button_settings.symlink_controller || button_settings.symlink_action || button_settings.symlink_id || button_settings.symlink_outer_controller || button_settings.symlink_outer_id) { %}
|
93
|
+
<a href="#" class="{%= button_settings['class'] %}" data-tr_class="{%= button_settings.tr_class %}" onclick="load_page({%= stringified_button_settings %}, this); return false;">{%= button_settings['name'] %}</a>
|
94
|
+
{% } else { %}
|
95
|
+
<span class="{%= button_settings['class'] %}" data-tr_class="{%= button_settings.tr_class %}">{%= button_settings['name'] %}</span>
|
96
|
+
{% } %}
|
97
|
+
{% } %}
|
98
|
+
{% } else if (is_string(row[col.table + '_' + col.name])) { %}
|
99
|
+
{% var sliced_text = row[col.table + '_' + col.name]; %}
|
100
|
+
{% if (col.max_text_length) { %}
|
101
|
+
{% var max = col.max_text_length - 3; %}
|
102
|
+
{% if ( max > 0 && sliced_text.length > max) { %}
|
103
|
+
{% sliced_text = sliced_text.slice(0, col.max_text_length) + "..."; %}
|
104
|
+
{% } %}
|
105
|
+
{% } %}
|
106
|
+
<span title="{%= row[col.table + '_' + col.name] %}">{%= sliced_text %}</span>
|
107
|
+
{% } else { %}
|
108
|
+
<span title="{%= row[col.table + '_' + col.name] %}">{%= row[col.table + '_' + col.name] %}</span>
|
109
|
+
{% } %}
|
110
|
+
</td>
|
111
|
+
{% } %}
|
112
|
+
</tr>
|
113
|
+
{% } %}
|
114
|
+
</script>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<%= ajax_post_link_to "Smazat filtr", settings[:filter_path], :class => "btn", "data-post" => {:clear => true}.to_json, :style => "float: left" %>
|
2
|
+
<div id="<%= settings[:form_id] %>_pagination" class="pager <%= settings[:form_id] %>_pager">
|
3
|
+
<span class="pager_pages">
|
4
|
+
<%= will_paginate settings[:data_paginate], :container => false %>
|
5
|
+
</span>
|
6
|
+
<span class="pager_numberofrecords">
|
7
|
+
<%= page_entries_info settings[:data_paginate] %>
|
8
|
+
</span>
|
9
|
+
</div>
|
@@ -0,0 +1,115 @@
|
|
1
|
+
<table class="table table-bordered table-condensed table_special">
|
2
|
+
<thead>
|
3
|
+
<tr>
|
4
|
+
<th colspan="10000000" class="<%= settings[:form_id] + '_ajax_pager' %>">
|
5
|
+
<%= render :partial => 'helpers/build_table_pager', :locals => {:settings => settings} %>
|
6
|
+
</th>
|
7
|
+
</tr>
|
8
|
+
<tr>
|
9
|
+
<% if !settings[:row].blank? && !settings[:row][:functions].blank? %>
|
10
|
+
<th></th>
|
11
|
+
<% end %>
|
12
|
+
<% settings[:columns].each do |col| %>
|
13
|
+
<th class="<%= col[:class] %>">
|
14
|
+
<div class="th_label">
|
15
|
+
<span><%= col[:label].html_safe %></span>
|
16
|
+
</div>
|
17
|
+
|
18
|
+
<div class="th_filter">
|
19
|
+
<% if col[:column_method].blank? && col[:row_method].blank? && !col[:name].blank? %>
|
20
|
+
<span class="sortButtons az">
|
21
|
+
<span onclick="filter_sort('<%= settings[:form_id] %>','<%= col[:table] + "." +col[:name] %>', 'ASC', this); return false;"
|
22
|
+
title="Sort Ascending"
|
23
|
+
class="icon-arrow-up sort_button sort-up <%= (settings[:params][:order_by] == (col[:table] + "." + col[:name]) && settings[:params][:order_by_direction]=="ASC") ? "active" : "inactive" %>">
|
24
|
+
<span class="oos"></span></span>
|
25
|
+
<span onclick="filter_sort('<%= settings[:form_id] %>','<%= col[:table] + "." +col[:name] %>', 'DESC', this); return false;"
|
26
|
+
title="Sort Descending"
|
27
|
+
class="icon-arrow-down sort_button sort-down <%= (settings[:params][:order_by] == (col[:table] + "." + col[:name]) && settings[:params][:order_by_direction]=="DESC") ? "active" : "inactive" %>">
|
28
|
+
<span class="oos "></span></span>
|
29
|
+
<% end %>
|
30
|
+
<% case col[:filter] %>
|
31
|
+
<% when :find %>
|
32
|
+
<% saved_param = (!settings[:params].blank? && !settings[:params]['find'].blank? && !settings[:params]['find']["#{col[:table]}.#{col[:name]}"].blank?) ? settings[:params]['find']["#{col[:table]}.#{col[:name]}"] : "" %>
|
33
|
+
<span><%= text_field_tag "find[#{col[:table]}.#{col[:name]}]", saved_param,
|
34
|
+
{:class => "input-small text #{settings[:form_id] + '_column_find'}"} %>
|
35
|
+
</span>
|
36
|
+
<% when :multichoice %>
|
37
|
+
<% saved_param = (!settings[:params].blank? && !settings[:params]['multichoice'].blank? && !settings[:params]['multichoice']["#{col[:table]}.#{col[:name]}"].blank?) ? settings[:params]['multichoice']["#{col[:table]}.#{col[:name]}"] : [] %>
|
38
|
+
<span><%= select_tag("multichoice[#{col[:table]}.#{col[:name]}]", options_for_select(col[:filter_data], saved_param),
|
39
|
+
:onchange => "form_submit_watcher('#{settings[:form_id]}')",
|
40
|
+
:multiple => true,
|
41
|
+
:class => "multiselect_class") %></span>
|
42
|
+
<% when :date %>
|
43
|
+
<% saved_param = (!settings[:params].blank? && !settings[:params]['date_from'].blank? && !settings[:params]['date_from']["#{col[:table]}.#{col[:name]}"].blank?) ? settings[:params]['date_from']["#{col[:table]}.#{col[:name]}"] : "" %>
|
44
|
+
<%#= label_tag "date_from[#{col[:table]}.#{col[:name]}]", "Od", :class => "datetime_class_label" %>
|
45
|
+
<%= text_field_tag "date_from[#{col[:table]}.#{col[:name]}]", saved_param, {:class => "datetime_class input-small",
|
46
|
+
:onchange => "form_submit_watcher('#{settings[:form_id]}')",
|
47
|
+
:title => "Datum od"} %>
|
48
|
+
<% saved_param = (!settings[:params].blank? && !settings[:params]['date_to'].blank? && !settings[:params]['date_to']["#{col[:table]}.#{col[:name]}"].blank?) ? settings[:params]['date_to']["#{col[:table]}.#{col[:name]}"] : "" %>
|
49
|
+
<%#= label_tag "date_to[#{col[:table]}.#{col[:name]}]", "Do", :class => "datetime_class_label" %>
|
50
|
+
<%= text_field_tag "date_to[#{col[:table]}.#{col[:name]}]", saved_param, {:class => "datetime_class input-small",
|
51
|
+
:onchange => "form_submit_watcher('#{settings[:form_id]}')",
|
52
|
+
:title => "Datum do"} %>
|
53
|
+
<span></span>
|
54
|
+
<% else %>
|
55
|
+
<% end %>
|
56
|
+
</span>
|
57
|
+
</div>
|
58
|
+
</th>
|
59
|
+
<% end %>
|
60
|
+
</tr>
|
61
|
+
|
62
|
+
</thead>
|
63
|
+
<tbody id="<%= settings[:form_id] %>_ajax_content">
|
64
|
+
<% unless settings[:template].blank? %>
|
65
|
+
<%= render :partial => settings[:template], :locals => {:settings => settings} %>
|
66
|
+
<% end %>
|
67
|
+
</tbody>
|
68
|
+
<tfoot>
|
69
|
+
<tr>
|
70
|
+
<th colspan="10000000" class="<%= settings[:form_id] + '_ajax_pager' %>">
|
71
|
+
<%= render :partial => 'helpers/build_table_pager', :locals => {:settings => settings} %>
|
72
|
+
</th>
|
73
|
+
</tr>
|
74
|
+
</tfoot>
|
75
|
+
</table>
|
76
|
+
|
77
|
+
<script type="text/javascript">
|
78
|
+
$('.<%= settings[:form_id] + "_column_find" %>').livesearch({
|
79
|
+
searchCallback:function (searchTerm) {
|
80
|
+
$('#<%= settings[:form_id] %>').submit();
|
81
|
+
},
|
82
|
+
queryDelay:250,
|
83
|
+
innerText:"",
|
84
|
+
minimumSearchLength:1
|
85
|
+
});
|
86
|
+
</script>
|
87
|
+
|
88
|
+
|
89
|
+
<script type="text/javascript">
|
90
|
+
$.datepicker.setDefaults($.datepicker.regional[ "cs" ]);
|
91
|
+
$('.datetime_class').datetimepicker({
|
92
|
+
dateFormat:"yy-mm-dd",
|
93
|
+
timeFormat:'hh:mm',
|
94
|
+
separator:' ',
|
95
|
+
changeYear:true,
|
96
|
+
yearRange:'<%= Date.today.year - 100 %>:<%= Date.today.year + 30 %>',
|
97
|
+
changeMonth:true
|
98
|
+
});
|
99
|
+
</script>
|
100
|
+
|
101
|
+
|
102
|
+
<script type="text/javascript">
|
103
|
+
$('.multiselect_class').multiselect({
|
104
|
+
selectedText:'<span class="active_multiselect">***</span>',
|
105
|
+
noneSelectedText:"",
|
106
|
+
checkAllText:"Označit vše",
|
107
|
+
uncheckAllText:"Zrušit vše",
|
108
|
+
minWidth:100
|
109
|
+
}, function () {
|
110
|
+
form_submit_watcher('<%=settings[:form_id] %>');
|
111
|
+
});
|
112
|
+
//$('#filled_value_' + fid + '_' + rid).multiselect("open");
|
113
|
+
$(".ui-multiselect-menu").css("width", "240px");
|
114
|
+
$("button.ui-multiselect").css("width", "40px");
|
115
|
+
</script>
|
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "it-logica-application-backbone"
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.6"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ladas"]
|
@@ -51,9 +51,25 @@ Gem::Specification.new do |s|
|
|
51
51
|
"app/assets/javascripts/backbone_js/load-image.min.js",
|
52
52
|
"app/assets/javascripts/backbone_js/time_picker.js",
|
53
53
|
"app/assets/javascripts/backbone_js/tmpl.min.js",
|
54
|
+
"app/views/helpers/_build_ajax_callback_code.html.erb",
|
55
|
+
"app/views/helpers/_build_breadcrumb.html.erb",
|
56
|
+
"app/views/helpers/_build_datafiles.html.erb",
|
57
|
+
"app/views/helpers/_build_table.html.erb",
|
58
|
+
"app/views/helpers/_build_table_data.html.erb",
|
59
|
+
"app/views/helpers/_build_table_filter.html.erb",
|
60
|
+
"app/views/helpers/_build_table_pager.html.erb",
|
61
|
+
"app/views/helpers/_build_table_wrapper.html.erb",
|
54
62
|
"it-logica-application-backbone.gemspec",
|
55
63
|
"lib/backbone_js/engine.rb",
|
64
|
+
"lib/controller_mixins/csv_instance_methods.rb",
|
65
|
+
"lib/controller_mixins/renderer_instance_methods.rb",
|
66
|
+
"lib/initializers/initialize.rb",
|
56
67
|
"lib/it-logica-application-backbone.rb",
|
68
|
+
"lib/model_mixins/table_builder_class_methods.rb",
|
69
|
+
"lib/view_mixins/breadcrumb.rb",
|
70
|
+
"lib/view_mixins/form.rb",
|
71
|
+
"lib/view_mixins/link.rb",
|
72
|
+
"lib/view_mixins/table.rb",
|
57
73
|
"test/helper.rb",
|
58
74
|
"test/test_it-logica-application-backbone.rb"
|
59
75
|
]
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module ControllerMixins::CsvInstanceMethods
|
2
|
+
require 'csv'
|
3
|
+
|
4
|
+
def to_csv(objects, skip_attributes=[], delimiter= ",")
|
5
|
+
return "" if objects.blank?
|
6
|
+
objects_class = objects.first.class
|
7
|
+
filtered_columns = objects_class.column_names - skip_attributes
|
8
|
+
CSV.generate do |csv|
|
9
|
+
csv << filtered_columns
|
10
|
+
objects.each do |object|
|
11
|
+
csv << filtered_columns.collect { |a| object.attributes[a].blank? ? '' : "'#{object.attributes[a]}'" }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module ControllerMixins::RendererInstanceMethods
|
2
|
+
def render_table_for(logged_user, template = nil, &proc)
|
3
|
+
@settings[:template] = template unless template.blank?
|
4
|
+
data = yield
|
5
|
+
class_obj = data.respond_to?(:klass) ? data.klass : data
|
6
|
+
if action_name == "filter"
|
7
|
+
default_params = params
|
8
|
+
default_params = @settings[:default] if !params.blank? && params["clear"]
|
9
|
+
|
10
|
+
@settings = class_obj.prepare_settings(logged_user, data, @settings, default_params)
|
11
|
+
if !params.blank? && params["clear"]
|
12
|
+
session["#{@settings[:form_id]}_params"] = ""
|
13
|
+
render :layout => false, :action => :index
|
14
|
+
else
|
15
|
+
@paginate = render_to_string(:partial => "/helpers/build_table_pager", :locals => {:settings => @settings})
|
16
|
+
session["#{@settings[:form_id]}_params"] = params
|
17
|
+
if @settings[:template].blank?
|
18
|
+
# if there is no template a will return json and tbody renders in javascript template
|
19
|
+
returned_t_body = @settings.to_json
|
20
|
+
else
|
21
|
+
# or there is template so i will return template rendered here in ruby
|
22
|
+
returned_t_body = render_to_string(:partial => @settings[:template], :locals => {:settings => @settings})
|
23
|
+
end
|
24
|
+
|
25
|
+
render :layout => false, :json => {:settings => returned_t_body, :paginate => @paginate}.to_json
|
26
|
+
end
|
27
|
+
elsif action_name == "index"
|
28
|
+
default_params = @settings[:default]
|
29
|
+
default_params = session["#{@settings[:form_id]}_params"] unless session["#{@settings[:form_id]}_params"].blank?
|
30
|
+
@settings = class_obj.prepare_settings(logged_user, data, @settings, default_params)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def fill_settings_with opts
|
35
|
+
settings = {}
|
36
|
+
settings[:symlink_remote] = true
|
37
|
+
unless opts.at(0).nil?
|
38
|
+
opts = opts[0]
|
39
|
+
settings[:symlink_controller] = opts.include?(:controller) ? opts[:controller] : controller_name
|
40
|
+
settings[:symlink_outer_controller] = opts[:outer_controller] if opts.include?(:outer_controller)
|
41
|
+
settings[:symlink_outer_id] = opts[:outer_id] if opts.include?(:outer_id)
|
42
|
+
settings[:symlink_action] = opts[:action] if opts.include?(:action)
|
43
|
+
settings[:symlink_id] = opts[:id] if opts.include?(:id)
|
44
|
+
else
|
45
|
+
settings[:symlink_controller] = controller_name
|
46
|
+
end
|
47
|
+
settings
|
48
|
+
end
|
49
|
+
|
50
|
+
def build_url_path_method(opts)
|
51
|
+
path = ""
|
52
|
+
|
53
|
+
opts = opts[0] unless opts.at(0).nil?
|
54
|
+
|
55
|
+
path += '/' + opts[:outer_controller].to_s if opts.include?(:outer_controller)
|
56
|
+
path += '/' + opts[:outer_id].to_s if opts.include?(:outer_id)
|
57
|
+
path += opts.include?(:controller) ? '/' + opts[:controller].to_s : '/' + controller_name
|
58
|
+
path += '/' + opts[:id].to_s if opts.include?(:id)
|
59
|
+
path += '/' + opts[:action].to_s if opts.include?(:action)
|
60
|
+
|
61
|
+
path
|
62
|
+
end
|
63
|
+
|
64
|
+
# redirect do indexu pokud neni zaznam v db
|
65
|
+
def redirect_not_found(*opts)
|
66
|
+
if request.xhr?
|
67
|
+
render :json => {:message => I18n.t("activerecord.errors.messages.record_not_found"), :settings => fill_settings_with(opts)}, :status => :moved_permanently
|
68
|
+
else
|
69
|
+
redirect_to build_url_path_method(opts), :status => :moved_permanently
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# redirect do indexu po uspesnem smazani
|
74
|
+
def redirect_destroy_ok(*opts)
|
75
|
+
if request.xhr?
|
76
|
+
render :json => {:status => "ok", :message => I18n.t("activerecord.info.messages.deleted"), :settings => fill_settings_with(opts)}, :status => :moved_permanently
|
77
|
+
else
|
78
|
+
redirect_to build_url_path_method(opts), :status => :moved_permanently
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# redirect po uspesnem save
|
83
|
+
def redirect_save_ok(*opts)
|
84
|
+
if request.xhr?
|
85
|
+
render :json => {:status => "ok", :message => I18n.t("activerecord.info.messages.saved"), :settings => fill_settings_with(opts)}, :status => :moved_permanently
|
86
|
+
else
|
87
|
+
redirect_to build_url_path_method(opts), :status => :moved_permanently
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
# redirect po uspesnem save
|
93
|
+
def redirect_save_failed(*opts)
|
94
|
+
if request.xhr?
|
95
|
+
render :json => {:status => "ok", :message => I18n.t("activerecord.errors.messages.save_failed"), :settings => fill_settings_with(opts)}, :status => :moved_permanently
|
96
|
+
else
|
97
|
+
redirect_to build_url_path_method(opts), :status => :moved_permanently
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'view_mixins/link'
|
2
|
+
require 'view_mixins/form'
|
3
|
+
require 'view_mixins/breadcrumb'
|
4
|
+
require 'view_mixins/table'
|
5
|
+
|
6
|
+
require 'model_mixins/table_builder_class_methods'
|
7
|
+
|
8
|
+
require 'controller_mixins/renderer_instance_methods'
|
9
|
+
|
10
|
+
class ActiveRecord::Base
|
11
|
+
extend ModelMixins::TableBuilderClassMethods
|
12
|
+
end
|
13
|
+
|
14
|
+
module ApplicationHelper
|
15
|
+
include ViewMixins::Link
|
16
|
+
include ViewMixins::Form
|
17
|
+
include ViewMixins::Breadcrumb
|
18
|
+
include ViewMixins::Table
|
19
|
+
end
|
20
|
+
|
21
|
+
class ApplicationController
|
22
|
+
include ControllerMixins::RendererInstanceMethods
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
# monkey patch for control of right timestamp when updating a model, in the case that somebody updatedd it in the time beetween show the form and update the form
|
27
|
+
# it will yell it was updated by another user
|
28
|
+
module ActiveRecord
|
29
|
+
# = Active Record Persistence
|
30
|
+
module Persistence
|
31
|
+
|
32
|
+
def update_attributes(attributes, options = {})
|
33
|
+
if timestamp_control = attributes.delete(:control_against_overwrite_by_another_user)
|
34
|
+
if self.attributes['updated_at'] > timestamp_control
|
35
|
+
errors[:base] << I18n.t('activerecord.errors.messages.control_against_overwrite_by_another_user')
|
36
|
+
return false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
with_transaction_returning_status do
|
40
|
+
self.assign_attributes(attributes, options)
|
41
|
+
save
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def update_attributes!(attributes, options = {})
|
46
|
+
if timestamp_control = attributes.delete(:control_against_overwrite_by_another_user)
|
47
|
+
if self.attributes['updated_at'] > timestamp_control
|
48
|
+
errors[:base] << I18n.t('activerecord.errors.messages.control_against_overwrite_by_another_user')
|
49
|
+
return false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
with_transaction_returning_status do
|
53
|
+
self.assign_attributes(attributes, options)
|
54
|
+
save!
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
module ModelMixins::TableBuilderClassMethods
|
2
|
+
def prepare_settings(logged_user, object, settings, params, per_page = 10)
|
3
|
+
params[:page] = 1 if params[:page].blank?
|
4
|
+
params[:order_by] = settings[:default][:order_by] if params[:order_by].blank?
|
5
|
+
params[:order_by_direction] = settings[:default][:order_by_direction] if params[:order_by_direction].blank?
|
6
|
+
params[:per_page] = per_page
|
7
|
+
|
8
|
+
not_selected_items = object.filter(settings, params, per_page)
|
9
|
+
items = not_selected_items.selection(settings)
|
10
|
+
if params[:page].to_i > items.total_pages && items.total_pages > 0
|
11
|
+
params[:page] = 1
|
12
|
+
not_selected_items = object.filter(settings, params, per_page)
|
13
|
+
items = not_selected_items.selection(settings)
|
14
|
+
end
|
15
|
+
|
16
|
+
if settings[:template].blank?
|
17
|
+
another_global_formats = []
|
18
|
+
another_formats = []
|
19
|
+
column_methods = []
|
20
|
+
settings[:columns].each do |col|
|
21
|
+
unless col[:global_format_method].blank?
|
22
|
+
# ToDo dodelat moznost predani parametru do formatovaci metody
|
23
|
+
another_global_format = {:global_format_method => col[:global_format_method],
|
24
|
+
:name => col[:name].blank? ? col[:global_format_method] : col[:name],
|
25
|
+
:table => col[:table]}
|
26
|
+
another_global_formats << another_global_format
|
27
|
+
end
|
28
|
+
unless col[:format_method].blank?
|
29
|
+
another_format = {:format_method => col[:format_method],
|
30
|
+
:name => col[:name].blank? ? col[:format_method] : col[:name],
|
31
|
+
:table => col[:table]}
|
32
|
+
another_formats << another_format
|
33
|
+
end
|
34
|
+
unless col[:column_method].blank?
|
35
|
+
column_methods << {:column_method => col[:column_method],
|
36
|
+
:name => col[:name],
|
37
|
+
:table => col[:table],
|
38
|
+
:column_class => col[:column_class],
|
39
|
+
:column_params => col[:column_params]
|
40
|
+
}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
all_items = items.all # maybe can be done more optimal
|
46
|
+
# same as template_items below, loads objects so column method are better to use
|
47
|
+
# todo think about, but I dont need object, because it's making the same query twice, I just need class and with one outer join it return filtered data, and i include includes to it
|
48
|
+
#template_items = object.joins("RIGHT OUTER JOIN (" + not_selected_items.select(settings[:row][:id] + " AS row_id").to_sql + ") temp_template_query ON #{settings[:row][:id]} = temp_template_query.row_id")
|
49
|
+
if object.respond_to?(:klass)
|
50
|
+
template_items = object.klass.joins("RIGHT OUTER JOIN (" + not_selected_items.uniq.select(settings[:row][:id] + " AS row_id").to_sql + ") temp_template_query ON #{settings[:row][:id]} = temp_template_query.row_id")
|
51
|
+
else
|
52
|
+
template_items = object.joins("RIGHT OUTER JOIN (" + not_selected_items.uniq.select(settings[:row][:id] + " AS row_id").to_sql + ") temp_template_query ON #{settings[:row][:id]} = temp_template_query.row_id")
|
53
|
+
end
|
54
|
+
|
55
|
+
template_items = template_items.includes(settings[:includes])
|
56
|
+
|
57
|
+
#template_items.all
|
58
|
+
# todo dat do knowledge base, kdyz chci aby fungoval include nesmim volat all
|
59
|
+
#template_items.each {|t| t.meeting_registrations.each {|x| puts x.inspect}}
|
60
|
+
|
61
|
+
another_columns = {}
|
62
|
+
unless column_methods.blank?
|
63
|
+
column_method_settings = {:params => params}
|
64
|
+
column_methods.each do |column_method|
|
65
|
+
column_method_settings[:column_params] = column_method[:column_params]
|
66
|
+
#all items == array of array items
|
67
|
+
#template items == AREL
|
68
|
+
if column_method[:column_class].blank?
|
69
|
+
if object.respond_to?(:klass)
|
70
|
+
another_columns[column_method[:column_method]] = object.klass.send(column_method[:column_method], logged_user, all_items, template_items, column_method_settings)
|
71
|
+
else
|
72
|
+
another_columns[column_method[:column_method]] = object.send(column_method[:column_method], logged_user, all_items, template_items, column_method_settings)
|
73
|
+
end
|
74
|
+
else
|
75
|
+
column_method[:column_class] = column_method[:column_class].constantize if column_method[:column_class].kind_of?(String)
|
76
|
+
another_columns[column_method[:column_method]] = column_method[:column_class].send(column_method[:column_method], logged_user, all_items, template_items, column_method_settings)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
if another_global_formats.blank? && another_formats.blank? && column_methods.blank?
|
82
|
+
items_array = items
|
83
|
+
else
|
84
|
+
items_array = []
|
85
|
+
all_items.each do |i|
|
86
|
+
attrs = i.attributes
|
87
|
+
another_global_formats.each do |another_global_format|
|
88
|
+
# todo udelat moznost predani dalsich parametru
|
89
|
+
attrs.merge!({"#{another_global_format[:table]}_#{another_global_format[:name]}" => i.send(another_global_format[:global_format_method].to_sym, attrs["#{another_global_format[:table]}_#{another_global_format[:name]}"])})
|
90
|
+
end
|
91
|
+
another_formats.each do |another_format|
|
92
|
+
attrs.merge!({"#{another_format[:table]}_#{another_format[:name]}" => i.send(another_format[:format_method].to_sym, attrs["#{another_format[:table]}_#{another_format[:name]}"])})
|
93
|
+
end
|
94
|
+
column_methods.each do |column_method|
|
95
|
+
another_column_row = "-"
|
96
|
+
another_column_row = another_columns[column_method[:column_method]][attrs['row_id']] if !another_columns.blank? && !another_columns[column_method[:column_method]].blank? && !another_columns[column_method[:column_method]][attrs['row_id']].blank?
|
97
|
+
attrs.merge!({"#{column_method[:table]}_#{column_method[:name]}" => another_column_row})
|
98
|
+
end
|
99
|
+
|
100
|
+
items_array << attrs
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
settings.merge!({:data => items_array})
|
105
|
+
else
|
106
|
+
template_items = object.joins("RIGHT OUTER JOIN (" + not_selected_items.uniq.select(settings[:row][:id] + " AS row_id").to_sql + ") temp_template_query ON #{settings[:row][:id]} = temp_template_query.row_id")
|
107
|
+
settings.merge!({:data => template_items})
|
108
|
+
end
|
109
|
+
settings.merge!({:data_paginate => items})
|
110
|
+
settings.merge!({:params => params})
|
111
|
+
settings
|
112
|
+
end
|
113
|
+
|
114
|
+
def selection(settings)
|
115
|
+
select_string = ""
|
116
|
+
settings[:columns].each do |col|
|
117
|
+
col[:table] = "unknown" if col[:table].blank?
|
118
|
+
if col[:column_method].blank? && col[:row_method].blank? && !col[:name].blank?
|
119
|
+
select_string += ", " unless select_string.blank?
|
120
|
+
select_string += "#{col[:table]}.#{col[:name]} AS #{col[:table]}_#{col[:name]}"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
select_string += ", " unless select_string.blank?
|
125
|
+
select_string += "#{settings[:row][:id]} AS row_id "
|
126
|
+
|
127
|
+
select(select_string)
|
128
|
+
end
|
129
|
+
|
130
|
+
def filter(settings, params, per_page = 10)
|
131
|
+
order_by = params[:order_by] +' '+ params[:order_by_direction]
|
132
|
+
|
133
|
+
|
134
|
+
cond_str = ""
|
135
|
+
cond_hash = {}
|
136
|
+
if !params.blank? && params['find']
|
137
|
+
params['find'].each_pair do |i, v|
|
138
|
+
unless v.blank?
|
139
|
+
cond_str += " AND " unless cond_str.blank?
|
140
|
+
cond_id = "find_#{i.gsub(/\./, '_')}"
|
141
|
+
cond_str += "#{i} LIKE :#{cond_id}" #OR guest_email LIKE :find"
|
142
|
+
cond_hash.merge!({cond_id.to_sym => "%#{v}%"})
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
if !params.blank? && params['multichoice']
|
148
|
+
params['multichoice'].each_pair do |i, v|
|
149
|
+
unless v.blank?
|
150
|
+
cond_str += " AND " unless cond_str.blank?
|
151
|
+
cond_id = "multichoice_#{i.gsub(/\./, '_')}"
|
152
|
+
|
153
|
+
cond_str += "#{i} IN (:#{cond_id})" #OR guest_email LIKE :find"
|
154
|
+
cond_hash.merge!({cond_id.to_sym => v})
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
if !params.blank? && params['date_from']
|
160
|
+
params['date_from'].each_pair do |i, v|
|
161
|
+
unless v.blank?
|
162
|
+
cond_str += " AND " unless cond_str.blank?
|
163
|
+
cond_id = "date_from_#{i.gsub(/\./, '_')}"
|
164
|
+
cond_str += "#{i} >= :#{cond_id}" #OR guest_email LIKE :find"
|
165
|
+
cond_hash.merge!({cond_id.to_sym => "#{v}"})
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
if !params.blank? && params['date_to']
|
171
|
+
params['date_to'].each_pair do |i, v|
|
172
|
+
unless v.blank?
|
173
|
+
cond_str += " AND " unless cond_str.blank?
|
174
|
+
cond_id = "date_to_#{i.gsub(/\./, '_')}"
|
175
|
+
cond_str += "#{i} <= :#{cond_id}" #OR guest_email LIKE :find"
|
176
|
+
cond_hash.merge!({cond_id.to_sym => "#{v}"})
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
#items = self.joins("LEFT OUTER JOIN intranet_text_pages ON resource_id = intranet_text_pages.id").where(cond_str, cond_hash).paginate(:page => params[:page], :per_page => per_page).order(order_by).selection(settings)
|
182
|
+
#if params[:page].to_i > items.total_pages && items.total_pages > 0
|
183
|
+
# params[:page] = 1
|
184
|
+
# items = self.where(cond_str, cond_hash).paginate(:page => params[:page], :per_page => per_page).order(order_by).selection(settings)
|
185
|
+
#end
|
186
|
+
#items
|
187
|
+
where(cond_str, cond_hash).paginate(:page => params[:page], :per_page => per_page).order(order_by)
|
188
|
+
end
|
189
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module ViewMixins::Breadcrumb
|
2
|
+
def breadcrumb_for(*args)
|
3
|
+
# ToDo dodělat caching tohoto, invalidovat budu pokud nastane SAVE u OBJECT
|
4
|
+
breadcrumb = []
|
5
|
+
args.each do |object|
|
6
|
+
if !object.blank?
|
7
|
+
if is_tree_node?(object)
|
8
|
+
tree_node = object
|
9
|
+
unless tree_node.blank?
|
10
|
+
bread_crumb_load_tree_recursive(breadcrumb, tree_node)
|
11
|
+
end
|
12
|
+
elsif object.respond_to?(:tree_nodes)
|
13
|
+
if !object.tree_nodes.blank? && !object.tree_nodes.first.blank? && is_tree_node?(object.tree_nodes.first)
|
14
|
+
tree_node = object.tree_nodes.first if !object.tree_nodes.blank? && !object.tree_nodes.first.blank?
|
15
|
+
unless tree_node.blank?
|
16
|
+
bread_crumb_load_tree_recursive(breadcrumb, tree_node)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
elsif object.kind_of?(Hash)
|
20
|
+
breadcrumb << object
|
21
|
+
elsif object.kind_of?(Array)
|
22
|
+
object.each do |o|
|
23
|
+
breadcrumb << o
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
render :partial => '/helpers/build_breadcrumb', :layout => false, :locals => {:breadcrumb => breadcrumb}
|
29
|
+
end
|
30
|
+
|
31
|
+
def bread_crumb_load_tree_recursive(breadcrumb, tree_node)
|
32
|
+
unless tree_node.blank?
|
33
|
+
if tree_node.parent_node_id > 0
|
34
|
+
bread_crumb_load_tree_recursive(breadcrumb, tree_node.parent_node)
|
35
|
+
end
|
36
|
+
breadcrumb << tree_node
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def is_tree_node?(object)
|
41
|
+
false
|
42
|
+
#object.kind_of?(Intranet::TreeNode) #|| object.kind_of?(Web::TreeNode) || object.kind_of?(Organizer::TreeNode)
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module ViewMixins::Form
|
2
|
+
|
3
|
+
def ajax_form_for(record, options = {}, &proc)
|
4
|
+
raise ArgumentError, "Missing block" unless block_given?
|
5
|
+
|
6
|
+
options[:html] ||= {}
|
7
|
+
|
8
|
+
case record
|
9
|
+
when String, Symbol
|
10
|
+
object_name = record
|
11
|
+
object = nil
|
12
|
+
else
|
13
|
+
object = record.is_a?(Array) ? record.last : record
|
14
|
+
object_name = options[:as] || ActiveModel::Naming.param_key(object)
|
15
|
+
apply_form_for_options!(record, options)
|
16
|
+
end
|
17
|
+
caller_id = options[:html][:id]
|
18
|
+
options[:html][:remote] = options.delete(:remote) if options.has_key?(:remote)
|
19
|
+
options[:html][:method] = options.delete(:method) if options.has_key?(:method)
|
20
|
+
options[:html][:authenticity_token] = options.delete(:authenticity_token)
|
21
|
+
######### additional logic by ladas ##############
|
22
|
+
#options[:html][:control_against_overwrite_by_another_user] = Time.now
|
23
|
+
################## end ###############3###########
|
24
|
+
|
25
|
+
builder = options[:parent_builder] = instantiate_builder(object_name, object, options, &proc)
|
26
|
+
fields_for = fields_for(object_name, object, options, &proc)
|
27
|
+
default_options = builder.multipart? ? {:multipart => true} : {}
|
28
|
+
output = form_tag(options.delete(:url) || {}, default_options.merge!(options.delete(:html)))
|
29
|
+
######### additional logic by ladas ##############
|
30
|
+
if !object.blank? && !object.id.blank?
|
31
|
+
output << "<fieldset><input type='hidden' name='#{ActiveModel::Naming.param_key(record)}[control_against_overwrite_by_another_user]' value='#{Time.now.utc}' /></fieldset>".html_safe
|
32
|
+
end
|
33
|
+
################## end ###############3###########
|
34
|
+
|
35
|
+
output << fields_for
|
36
|
+
######### additional logic by ladas ##############
|
37
|
+
output.safe_concat(build_ajax_callback_code(caller_id))
|
38
|
+
################## end ###############3###########
|
39
|
+
output.safe_concat('</form>')
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def build_ajax_callback_code(caller_id)
|
44
|
+
render :partial => '/helpers/build_ajax_callback_code', :layout => false, :locals => {:caller_id => caller_id}
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module ViewMixins::Link
|
2
|
+
def ajax_link_to(*args, &block)
|
3
|
+
if block_given?
|
4
|
+
options = args.first || {}
|
5
|
+
html_options = args.second
|
6
|
+
######### additional logic by ladas ##############
|
7
|
+
html_options ||= {}
|
8
|
+
html_options['onclick'] = "parse_link_and_load_page($(this)); return false;"
|
9
|
+
#########################################
|
10
|
+
link_to(capture(&block), options, html_options)
|
11
|
+
else
|
12
|
+
name = args[0]
|
13
|
+
options = args[1] || {}
|
14
|
+
html_options = args[2]
|
15
|
+
######### additional logic by ladas ##############
|
16
|
+
html_options ||= {}
|
17
|
+
html_options['onclick'] = "parse_link_and_load_page($(this)); return false;"
|
18
|
+
#########################################
|
19
|
+
html_options = convert_options_to_data_attributes(options, html_options)
|
20
|
+
url = url_for(options)
|
21
|
+
|
22
|
+
href = html_options['href']
|
23
|
+
tag_options = tag_options(html_options)
|
24
|
+
|
25
|
+
href_attr = "href=\"#{ERB::Util.html_escape(url)}\"" unless href
|
26
|
+
"<a #{href_attr}#{tag_options}>#{ERB::Util.html_escape(name || url)}</a>".html_safe
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def ajax_post_link_to(*args, &block)
|
31
|
+
if block_given?
|
32
|
+
options = args.first || {}
|
33
|
+
html_options = args.second
|
34
|
+
######### additional logic by ladas ##############
|
35
|
+
html_options ||= {}
|
36
|
+
html_options['onclick'] = "parse_link_and_post($(this)); return false;"
|
37
|
+
#########################################
|
38
|
+
link_to(capture(&block), options, html_options)
|
39
|
+
else
|
40
|
+
name = args[0]
|
41
|
+
options = args[1] || {}
|
42
|
+
html_options = args[2]
|
43
|
+
######### additional logic by ladas ##############
|
44
|
+
html_options ||= {}
|
45
|
+
html_options['onclick'] = "parse_link_and_post($(this)); return false;"
|
46
|
+
#########################################
|
47
|
+
html_options = convert_options_to_data_attributes(options, html_options)
|
48
|
+
url = url_for(options)
|
49
|
+
|
50
|
+
href = html_options['href']
|
51
|
+
tag_options = tag_options(html_options)
|
52
|
+
|
53
|
+
href_attr = "href=\"#{ERB::Util.html_escape(url)}\"" unless href
|
54
|
+
"<a #{href_attr}#{tag_options}>#{ERB::Util.html_escape(name || url)}</a>".html_safe
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# used only in jstree
|
59
|
+
def link_tree(*args, &block)
|
60
|
+
if block_given?
|
61
|
+
options = args.first || {}
|
62
|
+
html_options = args.second
|
63
|
+
######### additional logic by ladas ##############
|
64
|
+
html_options ||= {}
|
65
|
+
html_options['onclick'] = "parse_link_and_load_page($(this)); return false;"
|
66
|
+
#########################################
|
67
|
+
link_to(capture(&block), options, html_options)
|
68
|
+
else
|
69
|
+
name = args[0]
|
70
|
+
options = args[1] || {}
|
71
|
+
html_options = args[2]
|
72
|
+
######### additional logic by ladas ##############
|
73
|
+
html_options ||= {}
|
74
|
+
html_options['onclick'] = "parse_link_and_load_page($(this)); return false;"
|
75
|
+
#########################################
|
76
|
+
html_options = convert_options_to_data_attributes(options, html_options)
|
77
|
+
url = url_for(options)
|
78
|
+
|
79
|
+
href = html_options['href']
|
80
|
+
tag_options = tag_options(html_options)
|
81
|
+
|
82
|
+
href_attr = "href=\"#{ERB::Util.html_escape(url)}\"" unless href
|
83
|
+
"<a #{href_attr}#{tag_options}>#{ERB::Util.html_escape(name || url)}</a>".html_safe
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def convert_settings_to_url settings_json
|
88
|
+
# make sure its the same as build_url in ladas_loading.js
|
89
|
+
|
90
|
+
settings = JSON.parse(settings_json)
|
91
|
+
url = ""
|
92
|
+
if settings['url']
|
93
|
+
url += settings['url']
|
94
|
+
else
|
95
|
+
if settings['symlink_outer_controller']
|
96
|
+
url += "/" + settings['symlink_outer_controller']
|
97
|
+
end
|
98
|
+
if settings['symlink_outer_id']
|
99
|
+
url += "/" + settings['symlink_outer_id']
|
100
|
+
end
|
101
|
+
if settings['symlink_controller']
|
102
|
+
url += "/" + settings['symlink_controller']
|
103
|
+
end
|
104
|
+
if settings['symlink_id']
|
105
|
+
url += "/" + settings['symlink_id']
|
106
|
+
end
|
107
|
+
if settings['symlink_action']
|
108
|
+
url += "/" + settings['symlink_action']
|
109
|
+
end
|
110
|
+
if settings['symlink_params']
|
111
|
+
url += settings['params']
|
112
|
+
end
|
113
|
+
end
|
114
|
+
url
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: it-logica-application-backbone
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-07-03 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: shoulda
|
16
|
-
requirement: &
|
16
|
+
requirement: &82436410 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *82436410
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rdoc
|
27
|
-
requirement: &
|
27
|
+
requirement: &82436140 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '3.12'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *82436140
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: bundler
|
38
|
-
requirement: &
|
38
|
+
requirement: &82435750 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 1.1.0
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *82435750
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: jeweler
|
49
|
-
requirement: &
|
49
|
+
requirement: &82435420 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 1.8.4
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *82435420
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: simplecov
|
60
|
-
requirement: &
|
60
|
+
requirement: &82435180 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,7 +65,7 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *82435180
|
69
69
|
description: longer description of your gem
|
70
70
|
email: ladislav.smola@it-logica.cz
|
71
71
|
executables: []
|
@@ -108,9 +108,25 @@ files:
|
|
108
108
|
- app/assets/javascripts/backbone_js/load-image.min.js
|
109
109
|
- app/assets/javascripts/backbone_js/time_picker.js
|
110
110
|
- app/assets/javascripts/backbone_js/tmpl.min.js
|
111
|
+
- app/views/helpers/_build_ajax_callback_code.html.erb
|
112
|
+
- app/views/helpers/_build_breadcrumb.html.erb
|
113
|
+
- app/views/helpers/_build_datafiles.html.erb
|
114
|
+
- app/views/helpers/_build_table.html.erb
|
115
|
+
- app/views/helpers/_build_table_data.html.erb
|
116
|
+
- app/views/helpers/_build_table_filter.html.erb
|
117
|
+
- app/views/helpers/_build_table_pager.html.erb
|
118
|
+
- app/views/helpers/_build_table_wrapper.html.erb
|
111
119
|
- it-logica-application-backbone.gemspec
|
112
120
|
- lib/backbone_js/engine.rb
|
121
|
+
- lib/controller_mixins/csv_instance_methods.rb
|
122
|
+
- lib/controller_mixins/renderer_instance_methods.rb
|
123
|
+
- lib/initializers/initialize.rb
|
113
124
|
- lib/it-logica-application-backbone.rb
|
125
|
+
- lib/model_mixins/table_builder_class_methods.rb
|
126
|
+
- lib/view_mixins/breadcrumb.rb
|
127
|
+
- lib/view_mixins/form.rb
|
128
|
+
- lib/view_mixins/link.rb
|
129
|
+
- lib/view_mixins/table.rb
|
114
130
|
- test/helper.rb
|
115
131
|
- test/test_it-logica-application-backbone.rb
|
116
132
|
homepage: http://github.com/Ladas/it-logica-application-backbone
|
@@ -128,7 +144,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
128
144
|
version: '0'
|
129
145
|
segments:
|
130
146
|
- 0
|
131
|
-
hash:
|
147
|
+
hash: -740967921
|
132
148
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
149
|
none: false
|
134
150
|
requirements:
|