active_scaffold_vho 3.1.4 → 3.1.5
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/.gitignore +44 -0
- data/Gemfile +1 -9
- data/Gemfile.lock +88 -8
- data/Rakefile +3 -24
- data/active_scaffold_vho.gemspec +16 -375
- data/app/assets/javascripts/jquery/active_scaffold.js +23 -13
- data/app/assets/javascripts/prototype/active_scaffold.js +23 -15
- data/app/assets/stylesheets/active_scaffold_core.css.erb +1 -1
- data/frontends/default/views/_list.html.erb +2 -1
- data/frontends/default/views/_list_messages.html.erb +2 -2
- data/frontends/default/views/_list_pagination.html.erb +3 -6
- data/frontends/default/views/_list_record_columns.html.erb +1 -1
- data/lib/active_scaffold.rb +10 -0
- data/lib/active_scaffold/actions/list.rb +7 -6
- data/lib/active_scaffold/active_record_permissions.rb +25 -0
- data/lib/active_scaffold/attribute_params.rb +5 -2
- data/lib/active_scaffold/bridges/shared/date_bridge.rb +3 -3
- data/lib/active_scaffold/config/core.rb +8 -1
- data/lib/active_scaffold/config/field_search.rb +21 -0
- data/lib/active_scaffold/data_structures/column.rb +16 -2
- data/lib/active_scaffold/finder.rb +18 -28
- data/lib/active_scaffold/helpers/human_condition_helpers.rb +4 -2
- data/lib/active_scaffold/helpers/list_column_helpers.rb +65 -2
- data/lib/active_scaffold/locale/de.yml +118 -0
- data/lib/active_scaffold/locale/en.yml +115 -0
- data/lib/active_scaffold/version.rb +1 -1
- data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet.css +1 -1
- metadata +46 -41
- data/lib/active_scaffold/locale/de.rb +0 -120
- data/lib/active_scaffold/locale/en.rb +0 -119
@@ -118,7 +118,7 @@ $(document).ready(function() {
|
|
118
118
|
});
|
119
119
|
$('a.as_cancel').live('ajax:beforeSend', function(event, xhr, settings) {
|
120
120
|
var as_cancel = $(this);
|
121
|
-
var action_link = ActiveScaffold.
|
121
|
+
var action_link = ActiveScaffold.find_action_link($(this));
|
122
122
|
var refresh_data = as_cancel.attr('data-refresh');
|
123
123
|
|
124
124
|
if (action_link && action_link.position && refresh_data === 'true' && action_link.refresh_url) {
|
@@ -158,19 +158,27 @@ $(document).ready(function() {
|
|
158
158
|
ActiveScaffold.report_500_response(as_scaffold);
|
159
159
|
return true;
|
160
160
|
});
|
161
|
-
$('a
|
161
|
+
$('div.active-scaffold-footer .pagination a').live('ajax:before',function(event) {
|
162
162
|
var as_paginate = $(this);
|
163
|
+
var loading_indicator = as_paginate.closest('.pagination').find('img.loading-indicator').first();
|
163
164
|
var history_controller_id = as_paginate.attr('data-page-history');
|
164
165
|
if (history_controller_id) addActiveScaffoldPageToHistory(as_paginate.attr('href'), history_controller_id);
|
165
|
-
|
166
|
+
|
167
|
+
if (loading_indicator == null || loading_indicator.length == 0) {
|
168
|
+
var table_loading_indicator = as_paginate.closest('div.active-scaffold').find('div.actions img.loading-indicator').first();
|
169
|
+
loading_indicator = table_loading_indicator.clone();
|
170
|
+
loading_indicator.attr('id', null);
|
171
|
+
as_paginate.closest('.pagination').prepend(loading_indicator);
|
172
|
+
}
|
173
|
+
loading_indicator.css('visibility','visible');
|
166
174
|
return true;
|
167
175
|
});
|
168
|
-
$('a
|
176
|
+
$('div.active-scaffold-footer .pagination a').live('ajax:error', function(event, xhr, status, error) {
|
169
177
|
var as_scaffold = $(this).closest('.active-scaffold');
|
170
178
|
ActiveScaffold.report_500_response(as_scaffold);
|
171
179
|
return true;
|
172
180
|
});
|
173
|
-
$('a
|
181
|
+
$('div.active-scaffold-footer .pagination a').live('ajax:complete', function(event) {
|
174
182
|
$(this).prevAll('img.loading-indicator').css('visibility','hidden');
|
175
183
|
return true;
|
176
184
|
});
|
@@ -663,7 +671,7 @@ var ActiveScaffold = {
|
|
663
671
|
},
|
664
672
|
|
665
673
|
report_500_response: function(active_scaffold_id) {
|
666
|
-
server_error = $(active_scaffold_id).find('td.messages-container p.server-error');
|
674
|
+
server_error = $(active_scaffold_id).find('td.messages-container p.server-error').filter(":first");
|
667
675
|
if (!$(server_error).is(':visible')) {
|
668
676
|
server_error.show();
|
669
677
|
}
|
@@ -1101,7 +1109,7 @@ ActiveScaffold.ActionLink.Abstract = Class.extend({
|
|
1101
1109
|
this.adapter.addClass('as_adapter');
|
1102
1110
|
this.adapter.data('action_link', this);
|
1103
1111
|
},
|
1104
|
-
wrap_with_adapter_html: function(content) {
|
1112
|
+
wrap_with_adapter_html: function(content, should_refresh_data) {
|
1105
1113
|
// players_view class missing
|
1106
1114
|
var id_string = null;
|
1107
1115
|
var close_label = this.scaffold().attr('data-closelabel');
|
@@ -1117,7 +1125,7 @@ ActiveScaffold.ActionLink.Abstract = Class.extend({
|
|
1117
1125
|
id_string = this.target.attr('id').replace('list', 'nested');
|
1118
1126
|
}
|
1119
1127
|
|
1120
|
-
return '<tr class="inline-adapter" id="' + id_string + '"><td colspan="99" class="inline-adapter-cell"><div class="' + this.action + '-view ' + controller + '-view view"><a class="inline-adapter-close as_cancel" title="' + close_label + '" data-remote="true" data-refresh="
|
1128
|
+
return '<tr class="inline-adapter" id="' + id_string + '"><td colspan="99" class="inline-adapter-cell"><div class="' + this.action + '-view ' + controller + '-view view"><a class="inline-adapter-close as_cancel" title="' + close_label + '" data-remote="true" data-refresh="' + should_refresh_data + '" href="">' + close_label +'</a>' + content + '</div></td></tr>'
|
1121
1129
|
}
|
1122
1130
|
});
|
1123
1131
|
|
@@ -1154,6 +1162,7 @@ ActiveScaffold.ActionLink.Record = ActiveScaffold.ActionLink.Abstract.extend({
|
|
1154
1162
|
},
|
1155
1163
|
|
1156
1164
|
insert: function(content) {
|
1165
|
+
var should_refresh_data = (typeof(this.refresh_ur)== 'undefined');
|
1157
1166
|
this.close_previous_adapter();
|
1158
1167
|
|
1159
1168
|
if (this.position == 'replace') {
|
@@ -1162,12 +1171,12 @@ ActiveScaffold.ActionLink.Record = ActiveScaffold.ActionLink.Abstract.extend({
|
|
1162
1171
|
}
|
1163
1172
|
|
1164
1173
|
if (this.position == 'after') {
|
1165
|
-
this.target.after(this.wrap_with_adapter_html(content));
|
1174
|
+
this.target.after(this.wrap_with_adapter_html(content, should_refresh_data));
|
1166
1175
|
ActiveScaffold.trigger_load_events(this.target.next().find('[data-as_load]'));
|
1167
1176
|
this.set_adapter(this.target.next());
|
1168
1177
|
}
|
1169
1178
|
else if (this.position == 'before') {
|
1170
|
-
this.target.before(this.wrap_with_adapter_html(content));
|
1179
|
+
this.target.before(this.wrap_with_adapter_html(content, should_refresh_data));
|
1171
1180
|
ActiveScaffold.trigger_load_events(this.target.prev().find('[data-as_load]'));
|
1172
1181
|
this.set_adapter(this.target.prev());
|
1173
1182
|
}
|
@@ -1202,12 +1211,13 @@ ActiveScaffold.ActionLink.Record = ActiveScaffold.ActionLink.Abstract.extend({
|
|
1202
1211
|
},
|
1203
1212
|
|
1204
1213
|
set_opened: function() {
|
1214
|
+
var should_refresh_data = (typeof(this.refresh_ur)== 'undefined');
|
1205
1215
|
if (this.position == 'after') {
|
1206
|
-
var new_adapter = ActiveScaffold.replace(this.target.next(), this.wrap_with_adapter_html(this.target.next().children(':first-child').html()), true);
|
1216
|
+
var new_adapter = ActiveScaffold.replace(this.target.next(), this.wrap_with_adapter_html(this.target.next().children(':first-child').html(), should_refresh_data), true);
|
1207
1217
|
this.set_adapter(new_adapter);
|
1208
1218
|
}
|
1209
1219
|
else if (this.position == 'before') {
|
1210
|
-
var new_adapter = ActiveScaffold.replace(this.target.prev(), this.wrap_with_adapter_html(this.target.prev().children(':first-child').html()), true);
|
1220
|
+
var new_adapter = ActiveScaffold.replace(this.target.prev(), this.wrap_with_adapter_html(this.target.prev().children(':first-child').html(), should_refresh_data), true);
|
1211
1221
|
this.set_adapter(new_adapter);
|
1212
1222
|
}
|
1213
1223
|
this.disable();
|
@@ -1228,7 +1238,7 @@ ActiveScaffold.Actions.Table = ActiveScaffold.Actions.Abstract.extend({
|
|
1228
1238
|
ActiveScaffold.ActionLink.Table = ActiveScaffold.ActionLink.Abstract.extend({
|
1229
1239
|
insert: function(content) {
|
1230
1240
|
if (this.position == 'top') {
|
1231
|
-
this.target.prepend(this.wrap_with_adapter_html(content));
|
1241
|
+
this.target.prepend(this.wrap_with_adapter_html(content, false));
|
1232
1242
|
ActiveScaffold.trigger_load_events(this.target.children().first().find('[data-as_load]'));
|
1233
1243
|
this.set_adapter(this.target.children().first());
|
1234
1244
|
}
|
@@ -209,21 +209,27 @@ document.observe("dom:loaded", function() {
|
|
209
209
|
}
|
210
210
|
return true;
|
211
211
|
});
|
212
|
-
document.on('ajax:before', 'a
|
212
|
+
document.on('ajax:before', 'div.active-scaffold-footer .pagination a', function(event) {
|
213
213
|
var as_paginate = event.findElement();
|
214
|
-
var loading_indicator = as_paginate.up().down('img.loading-indicator');
|
214
|
+
var loading_indicator = as_paginate.up(1).down('img.loading-indicator');
|
215
215
|
var history_controller_id = as_paginate.readAttribute('data-page-history');
|
216
|
-
|
216
|
+
|
217
217
|
if (history_controller_id) addActiveScaffoldPageToHistory(as_paginate.readAttribute('href'), history_controller_id);
|
218
|
-
if (loading_indicator
|
218
|
+
if (loading_indicator == null) {
|
219
|
+
var table_loading_indicator = as_paginate.up('div.active-scaffold').down('div.actions').down('img.loading-indicator');
|
220
|
+
loading_indicator = table_loading_indicator.cloneNode(true);
|
221
|
+
loading_indicator.id = null;
|
222
|
+
as_paginate.up(1).insert({top: loading_indicator});
|
223
|
+
}
|
224
|
+
loading_indicator.style.visibility = 'visible';
|
219
225
|
return true;
|
220
226
|
});
|
221
|
-
document.on('ajax:failure', 'a
|
227
|
+
document.on('ajax:failure', 'div.active-scaffold-footer .pagination a', function(event) {
|
222
228
|
var as_scaffold = event.findElement('.active-scaffold');
|
223
229
|
ActiveScaffold.report_500_response(as_scaffold);
|
224
230
|
return true;
|
225
231
|
});
|
226
|
-
document.on('ajax:complete', 'a
|
232
|
+
document.on('ajax:complete', 'div.active-scaffold-footer .pagination a', function(event) {
|
227
233
|
var as_paginate = event.findElement();
|
228
234
|
var loading_indicator = as_paginate.up().down('img.loading-indicator');
|
229
235
|
|
@@ -333,12 +339,12 @@ document.observe("dom:loaded", function() {
|
|
333
339
|
});
|
334
340
|
document.on('ajax:before', 'form.as_form', function(event) {
|
335
341
|
var as_form = event.findElement('form');
|
336
|
-
|
342
|
+
as_form.fire('as:form_submit');
|
337
343
|
return true;
|
338
344
|
});
|
339
345
|
document.on('submit', 'form.as_form[data-remote!="true"]', function(event) {
|
340
346
|
var as_form = event.findElement('form');
|
341
|
-
|
347
|
+
as_form.fire('as:form_submit');
|
342
348
|
return true;
|
343
349
|
});
|
344
350
|
ActiveScaffold.trigger_load_events($$('[data-as_load]'));
|
@@ -902,7 +908,7 @@ ActiveScaffold.ActionLink.Abstract = Class.create({
|
|
902
908
|
this.adapter.store('action_link', this);
|
903
909
|
},
|
904
910
|
|
905
|
-
wrap_with_adapter_html: function(content) {
|
911
|
+
wrap_with_adapter_html: function(content, should_refresh_data) {
|
906
912
|
// players_view class missing
|
907
913
|
var id_string = null;
|
908
914
|
var close_label = this.scaffold().readAttribute('data-closelabel');
|
@@ -918,7 +924,7 @@ ActiveScaffold.ActionLink.Abstract = Class.create({
|
|
918
924
|
id_string = this.target.readAttribute('id').replace('list', 'nested');
|
919
925
|
}
|
920
926
|
|
921
|
-
return '<tr class="inline-adapter" id="' + id_string + '"><td colspan="99" class="inline-adapter-cell"><div class="' + this.action + '-view ' + controller + '-view view"><a class="inline-adapter-close as_cancel" title="' + close_label + '" data-remote="true" data-refresh="
|
927
|
+
return '<tr class="inline-adapter" id="' + id_string + '"><td colspan="99" class="inline-adapter-cell"><div class="' + this.action + '-view ' + controller + '-view view"><a class="inline-adapter-close as_cancel" title="' + close_label + '" data-remote="true" data-refresh="' + should_refresh_data + '" href="">' + close_label +'</a>' + content + '</div></td></tr>'
|
922
928
|
}
|
923
929
|
});
|
924
930
|
|
@@ -951,6 +957,7 @@ ActiveScaffold.ActionLink.Record = Class.create(ActiveScaffold.ActionLink.Abstra
|
|
951
957
|
},
|
952
958
|
|
953
959
|
insert: function(content) {
|
960
|
+
var should_refresh_data = (typeof(this.refresh_ur)== 'undefined');
|
954
961
|
this.close_previous_adapter();
|
955
962
|
|
956
963
|
if (this.position == 'replace') {
|
@@ -959,12 +966,12 @@ ActiveScaffold.ActionLink.Record = Class.create(ActiveScaffold.ActionLink.Abstra
|
|
959
966
|
}
|
960
967
|
|
961
968
|
if (this.position == 'after') {
|
962
|
-
this.target.insert({after:this.wrap_with_adapter_html(content)});
|
969
|
+
this.target.insert({after:this.wrap_with_adapter_html(content, should_refresh_data)});
|
963
970
|
ActiveScaffold.trigger_load_events(this.target.next().select('[data-as_load]'));
|
964
971
|
this.set_adapter(this.target.next());
|
965
972
|
}
|
966
973
|
else if (this.position == 'before') {
|
967
|
-
this.target.insert({before:this.wrap_with_adapter_html(content)});
|
974
|
+
this.target.insert({before:this.wrap_with_adapter_html(content, should_refresh_data)});
|
968
975
|
ActiveScaffold.trigger_load_events(this.target.previous().select('[data-as_load]'));
|
969
976
|
this.set_adapter(this.target.previous());
|
970
977
|
}
|
@@ -997,12 +1004,13 @@ ActiveScaffold.ActionLink.Record = Class.create(ActiveScaffold.ActionLink.Abstra
|
|
997
1004
|
},
|
998
1005
|
|
999
1006
|
set_opened: function() {
|
1007
|
+
var should_refresh_data = (typeof(this.refresh_ur)== 'undefined');
|
1000
1008
|
if (this.position == 'after') {
|
1001
|
-
var new_adapter = ActiveScaffold.replace(this.target.next(), this.wrap_with_adapter_html(this.target.next().childElements().first().innerHTML), true);
|
1009
|
+
var new_adapter = ActiveScaffold.replace(this.target.next(), this.wrap_with_adapter_html(this.target.next().childElements().first().innerHTML, should_refresh_data), true);
|
1002
1010
|
this.set_adapter(new_adapter);
|
1003
1011
|
}
|
1004
1012
|
else if (this.position == 'before') {
|
1005
|
-
var new_adapter = ActiveScaffold.replace(this.target.previous(), this.wrap_with_adapter_html(this.target.previous().childElements().first().innerHTML), true);
|
1013
|
+
var new_adapter = ActiveScaffold.replace(this.target.previous(), this.wrap_with_adapter_html(this.target.previous().childElements().first().innerHTML, should_refresh_data), true);
|
1006
1014
|
this.set_adapter(new_adapter);
|
1007
1015
|
}
|
1008
1016
|
this.disable();
|
@@ -1023,7 +1031,7 @@ ActiveScaffold.Actions.Table = Class.create(ActiveScaffold.Actions.Abstract, {
|
|
1023
1031
|
ActiveScaffold.ActionLink.Table = Class.create(ActiveScaffold.ActionLink.Abstract, {
|
1024
1032
|
insert: function(content) {
|
1025
1033
|
if (this.position == 'top') {
|
1026
|
-
this.target.insert({top:this.wrap_with_adapter_html(content)});
|
1034
|
+
this.target.insert({top:this.wrap_with_adapter_html(content, false)});
|
1027
1035
|
ActiveScaffold.trigger_load_events(this.target.immediateDescendants().first().select('[data-as_load]'));
|
1028
1036
|
this.set_adapter(this.target.immediateDescendants().first());
|
1029
1037
|
}
|
@@ -8,7 +8,7 @@
|
|
8
8
|
<%= render :partial => 'list_messages', :locals => {:columns => columns} %>
|
9
9
|
<tbody class="records" id="<%= active_scaffold_tbody_id %>">
|
10
10
|
<% if !@records.empty? -%>
|
11
|
-
<%= render :partial => 'list_record', :collection => @
|
11
|
+
<%= render :partial => 'list_record', :collection => @records, :locals => { :hidden => false, :columns => columns, :action_links => active_scaffold_config.action_links.member} %>
|
12
12
|
<% end -%>
|
13
13
|
<% if columns.any? {|c| c.calculation?} -%>
|
14
14
|
<%= render :partial => 'list_calculations', :locals => {:columns => columns} %>
|
@@ -16,3 +16,4 @@
|
|
16
16
|
</tbody>
|
17
17
|
</table>
|
18
18
|
<%= render :partial => 'list_pagination' %>
|
19
|
+
<% save_current_page_num %>
|
@@ -11,7 +11,7 @@
|
|
11
11
|
<p class="filtered-message" <%= ' style="display:none;" '.html_safe unless @filtered %>>
|
12
12
|
<%= @filtered.is_a?(Array) ? render(:partial => 'human_conditions', :locals => {:columns => @filtered}) : as_(active_scaffold_config.list.filtered_message) %>
|
13
13
|
</p>
|
14
|
-
<p id="<%= empty_message_id %>" class="empty-message" <%= ' style="display:none;" '.html_safe unless @
|
14
|
+
<p id="<%= empty_message_id %>" class="empty-message" <%= ' style="display:none;" '.html_safe unless @records.empty? %>>
|
15
15
|
<%= as_(active_scaffold_config.list.no_entries_message) %>
|
16
16
|
</p>
|
17
17
|
</td>
|
@@ -23,7 +23,7 @@
|
|
23
23
|
action_links.add(search_link) -%>
|
24
24
|
<%= render :partial => 'list_actions', :locals => {:record => record, :url_options => params_for(:escape => false, :search => ''), :action_links => action_links.member} %>
|
25
25
|
<% else %>
|
26
|
-
<td class='actions'><%= '<p class="empty-message"> </p>'.html_safe if @
|
26
|
+
<td class='actions'><%= '<p class="empty-message"> </p>'.html_safe if @records.empty? %></td>
|
27
27
|
<% end -%>
|
28
28
|
|
29
29
|
</tr>
|
@@ -1,11 +1,8 @@
|
|
1
1
|
<% if active_scaffold_config.list.pagination -%>
|
2
2
|
<div class="active-scaffold-footer">
|
3
|
-
<% unless
|
4
|
-
<div class="active-scaffold-found"><span class="active-scaffold-records"><%= @
|
3
|
+
<% unless active_scaffold_config.list.pagination == :infinite -%>
|
4
|
+
<div class="active-scaffold-found"><span class="active-scaffold-records"><%= @records.total_count -%></span> <%=as_(:found, :count => @records.total_count) %></div>
|
5
5
|
<% end -%>
|
6
|
-
|
7
|
-
<%= render :partial => 'list_pagination_links', :locals => { :current_page => @page } if @page.pager.infinite? || @page.pager.number_of_pages > 1 %>
|
8
|
-
</div>
|
9
|
-
<br clear="both" /><%# a hack for the Rico Corner problem %>
|
6
|
+
<%= paginate @records, :window => active_scaffold_config.list.page_links_window, :params => params_for(:action => :index), :remote => true %>
|
10
7
|
</div>
|
11
8
|
<% end -%>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<% columns.each do |column| %>
|
2
|
-
<% authorized = record.
|
2
|
+
<% authorized = record.authorized_for_read_column?(column.name) -%>
|
3
3
|
<% column_value = authorized ? get_column_value(record, column) : active_scaffold_config.list.empty_field_text -%>
|
4
4
|
|
5
5
|
<td class="<%= column_class(column, column_value, record) %>" >
|
data/lib/active_scaffold.rb
CHANGED
@@ -212,6 +212,16 @@ module ActiveScaffold
|
|
212
212
|
self.append_view_path(ActionView::ActiveScaffoldResolver.new(path))
|
213
213
|
end
|
214
214
|
self._add_sti_create_links if self.active_scaffold_config.add_sti_create_links?
|
215
|
+
#self.create_list_column_helpers
|
216
|
+
end
|
217
|
+
|
218
|
+
def create_list_column_helpers
|
219
|
+
active_scaffold_config.list.columns.each do |column|
|
220
|
+
method_code = self.helpers.generate_list_column_helper_code(column)
|
221
|
+
helper do
|
222
|
+
eval(method_code)
|
223
|
+
end unless self.helpers.column_controller_override?(column)
|
224
|
+
end
|
215
225
|
end
|
216
226
|
|
217
227
|
# To be called after include action modules
|
@@ -3,6 +3,7 @@ module ActiveScaffold::Actions
|
|
3
3
|
def self.included(base)
|
4
4
|
base.before_filter :list_authorized_filter, :only => [:index, :row]
|
5
5
|
base.helper_method :list_columns
|
6
|
+
base.helper_method :save_current_page_num
|
6
7
|
end
|
7
8
|
|
8
9
|
def index
|
@@ -73,12 +74,8 @@ module ActiveScaffold::Actions
|
|
73
74
|
})
|
74
75
|
end
|
75
76
|
|
76
|
-
|
77
|
-
|
78
|
-
page = page.pager.last
|
79
|
-
active_scaffold_config.list.user.page = page.number
|
80
|
-
end
|
81
|
-
@page, @records = page, page.items
|
77
|
+
@records = find_page(options);
|
78
|
+
@records
|
82
79
|
end
|
83
80
|
|
84
81
|
def each_record_in_page
|
@@ -160,6 +157,10 @@ module ActiveScaffold::Actions
|
|
160
157
|
def action_update_respond_to_yaml
|
161
158
|
render :text => successful? ? "" : Hash.from_xml(response_object.to_xml(:only => list_columns_names)).to_yaml, :content_type => Mime::YAML, :status => response_status
|
162
159
|
end
|
160
|
+
|
161
|
+
def save_current_page_num
|
162
|
+
active_scaffold_config.list.user.page = @records.current_page unless active_scaffold_config.list.pagination == false
|
163
|
+
end
|
163
164
|
|
164
165
|
private
|
165
166
|
def list_authorized_filter
|
@@ -64,6 +64,7 @@ module ActiveRecordPermissions
|
|
64
64
|
def self.included(base)
|
65
65
|
base.extend SecurityMethods
|
66
66
|
base.send :include, SecurityMethods
|
67
|
+
base.class_attribute :auth_column_read_methods
|
67
68
|
end
|
68
69
|
|
69
70
|
# Because any class-level queries get delegated to the instance level via a new record,
|
@@ -110,6 +111,30 @@ module ActiveRecordPermissions
|
|
110
111
|
return ActiveRecordPermissions.default_permission
|
111
112
|
end
|
112
113
|
|
114
|
+
def authorized_for_read_column?(column)
|
115
|
+
self.class.auth_column_read_methods ||= {}
|
116
|
+
methods = self.class.auth_column_read_methods[column]
|
117
|
+
if methods.nil?
|
118
|
+
method = column_and_crud_type_security_method(column, :read)
|
119
|
+
methods = if method && respond_to?(method)
|
120
|
+
[method]
|
121
|
+
else
|
122
|
+
[column_security_method(column),
|
123
|
+
crud_type_security_method(:read)].compact.select {|m| respond_to?(m)}
|
124
|
+
end
|
125
|
+
self.class.auth_column_read_methods[column] = methods
|
126
|
+
end
|
127
|
+
|
128
|
+
# if any method returns false, then return false
|
129
|
+
return false if methods.any? {|m| !send(m)}
|
130
|
+
|
131
|
+
# if any method actually exists then it must've returned true, so return true
|
132
|
+
return true unless methods.empty?
|
133
|
+
|
134
|
+
# if no method exists, return the default permission
|
135
|
+
return ActiveRecordPermissions.default_permission
|
136
|
+
end
|
137
|
+
|
113
138
|
private
|
114
139
|
|
115
140
|
def column_security_method(column)
|
@@ -134,8 +134,11 @@ module ActiveScaffold
|
|
134
134
|
# convert empty strings into nil. this works better with 'null => true' columns (and validations),
|
135
135
|
# and 'null => false' columns should just convert back to an empty string.
|
136
136
|
# ... but we can at least check the ConnectionAdapter::Column object to see if nulls are allowed
|
137
|
-
|
138
|
-
|
137
|
+
if value.is_a? String and value.empty? and !column.column.nil? and column.column.null
|
138
|
+
nil
|
139
|
+
else
|
140
|
+
column.stripped_value(value)
|
141
|
+
end
|
139
142
|
end
|
140
143
|
end
|
141
144
|
|
@@ -73,13 +73,13 @@ module ActiveScaffold
|
|
73
73
|
range_type, range = value[:range].downcase.split('_')
|
74
74
|
format = active_scaffold_human_condition_date_bridge_range_format(range_type, range)
|
75
75
|
from, to = controller.class.date_bridge_from_to(column, value)
|
76
|
-
"#{column.active_record_class.human_attribute_name(column.name)} = #{as_(value[:range].downcase).downcase} (#{I18n.l(from, :format => format)})"
|
76
|
+
"#{column.active_record_class.human_attribute_name(column.name)} = #{as_(value[:range].downcase).downcase} (#{I18n.l(from, :format => format)})" unless from.nil?
|
77
77
|
when 'PAST', 'FUTURE'
|
78
78
|
from, to = controller.class.date_bridge_from_to(column, value)
|
79
|
-
"#{column.active_record_class.human_attribute_name(column.name)} #{as_('BETWEEN'.downcase).downcase} #{I18n.l(from)} - #{I18n.l(to)}"
|
79
|
+
"#{column.active_record_class.human_attribute_name(column.name)} #{as_('BETWEEN'.downcase).downcase} #{I18n.l(from)} - #{I18n.l(to)}" unless from.nil? || to.nil?
|
80
80
|
else
|
81
81
|
from, to = controller.class.date_bridge_from_to(column, value)
|
82
|
-
"#{column.active_record_class.human_attribute_name(column.name)} #{as_(value[:opt].downcase).downcase} #{I18n.l(from)} #{value[:opt] == 'BETWEEN' ? '- ' + I18n.l(to) : ''}"
|
82
|
+
"#{column.active_record_class.human_attribute_name(column.name)} #{as_(value[:opt].downcase).downcase} #{I18n.l(from)} #{value[:opt] == 'BETWEEN' ? '- ' + I18n.l(to) : ''}" unless from.nil? || (value[:opt] == 'BETWEEN' && to.nil?)
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
@@ -167,7 +167,14 @@ module ActiveScaffold::Config
|
|
167
167
|
klass = "ActiveScaffold::Config::#{titled_name}".constantize rescue nil
|
168
168
|
if klass
|
169
169
|
if @actions.include? underscored_name
|
170
|
-
|
170
|
+
@action_configs[name] ||= klass.new(self)
|
171
|
+
eigenclass = class << self; self; end
|
172
|
+
eigenclass.class_eval do
|
173
|
+
define_method(name) do
|
174
|
+
@action_configs[name]
|
175
|
+
end
|
176
|
+
end
|
177
|
+
return send(name)
|
171
178
|
else
|
172
179
|
raise "#{titled_name} is not enabled. Please enable it or remove any references in your configuration (e.g. config.#{underscored_name}.columns = [...])."
|
173
180
|
end
|
@@ -6,6 +6,7 @@ module ActiveScaffold::Config
|
|
6
6
|
@core = core_config
|
7
7
|
|
8
8
|
@text_search = self.class.text_search
|
9
|
+
@or_delimiter = self.class.or_delimiter
|
9
10
|
|
10
11
|
# start with the ActionLink defined globally
|
11
12
|
@link = self.class.link.clone
|
@@ -28,6 +29,11 @@ module ActiveScaffold::Config
|
|
28
29
|
cattr_accessor :text_search
|
29
30
|
@@text_search = :full
|
30
31
|
|
32
|
+
# delimiter to seperate or search string such us: name = Paul,Bernd,Klaus
|
33
|
+
# will search for Paul Or Bernd Or Klaus
|
34
|
+
cattr_accessor :or_delimiter
|
35
|
+
@@or_delimiter = ','
|
36
|
+
|
31
37
|
# instance-level configuration
|
32
38
|
# ----------------------------
|
33
39
|
|
@@ -50,6 +56,8 @@ module ActiveScaffold::Config
|
|
50
56
|
# * false: LIKE ?
|
51
57
|
# Default is :full
|
52
58
|
attr_accessor :text_search
|
59
|
+
|
60
|
+
attr_accessor :or_delimiter
|
53
61
|
|
54
62
|
# the ActionLink for this action
|
55
63
|
attr_accessor :link
|
@@ -62,6 +70,19 @@ module ActiveScaffold::Config
|
|
62
70
|
def optional_columns
|
63
71
|
@optional_columns ||= []
|
64
72
|
end
|
73
|
+
|
74
|
+
# columns which should support or searches
|
75
|
+
# eg like 'x' or ... like 'y'
|
76
|
+
def or_columns=(or_columns)
|
77
|
+
@or_columns = Array(or_columns)
|
78
|
+
end
|
79
|
+
|
80
|
+
def or_columns
|
81
|
+
unless @or_columns
|
82
|
+
self.or_columns = @core.columns.collect{|c| c.name if @core.columns._inheritable.include?(c.name) and c.searchable? and c.column and c.column.text?}.compact
|
83
|
+
end
|
84
|
+
@or_columns
|
85
|
+
end
|
65
86
|
|
66
87
|
# default search params
|
67
88
|
# default_params = {:title => {"from"=>"test", "to"=>"", "opt"=>"%?%"}}
|