lolita 3.2.0.rc.5 → 3.2.0.rc.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +6 -2
- data/History.rdoc +12 -4
- data/Rakefile +7 -0
- data/VERSION +1 -1
- data/app/assets/images/lolita/search_icon.png +0 -0
- data/app/assets/javascripts/lolita/application.js +1 -1
- data/app/assets/javascripts/lolita/tab.js +31 -2
- data/app/assets/stylesheets/lolita/application.css +1 -0
- data/app/assets/stylesheets/lolita/style.css.erb +49 -3
- data/app/controllers/lolita/field_data_controller.rb +14 -2
- data/app/controllers/lolita/rest_controller.rb +7 -2
- data/app/helpers/lolita_helper.rb +0 -1
- data/app/views/components/lolita/configuration/field/array/habtm_autocomplete/_display.html.haml +11 -0
- data/app/views/components/lolita/configuration/field/string/disabled/_display.html.erb +1 -1
- data/app/views/components/lolita/configuration/list/_paginator.html.erb +1 -1
- data/app/views/components/lolita/configuration/list/_title.html.erb +6 -1
- data/app/views/components/lolita/configuration/search/_display.html.haml +2 -0
- data/app/views/components/lolita/navigation/_tree.html.erb +16 -25
- data/app/views/components/lolita/shared/_header.html.erb +1 -1
- data/app/views/layouts/lolita/application.html.erb +2 -3
- data/config/locales/en.yml +1 -24
- data/config/locales/lv.yml +1 -0
- data/config/routes.rb +2 -1
- data/lib/generators/lolita/install_generator.rb +2 -5
- data/lib/generators/templates/lolita.rb +0 -4
- data/lib/lolita/adapter/abstract_adapter.rb +1 -0
- data/lib/lolita/adapter/active_record.rb +19 -0
- data/lib/lolita/adapter/mongoid.rb +60 -0
- data/lib/lolita/configuration/list.rb +23 -2
- data/lib/lolita/configuration/search.rb +90 -0
- data/lib/lolita/controller_additions.rb +15 -0
- data/lib/lolita/controllers/authorization_helpers.rb +56 -0
- data/lib/lolita/controllers/internal_helpers.rb +2 -2
- data/lib/lolita/controllers/user_helpers.rb +23 -11
- data/lib/lolita/mapping.rb +12 -0
- data/lib/lolita/modules/rest.rb +1 -1
- data/lib/lolita/navigation/branch.rb +50 -1
- data/lib/lolita/navigation/tree.rb +10 -0
- data/lib/lolita/rails/routes.rb +1 -4
- data/lib/lolita/rails.rb +0 -2
- data/lib/lolita/search/simple.rb +76 -0
- data/lib/lolita.rb +24 -19
- data/lolita.gemspec +29 -60
- data/lolita.gemspec.orig +434 -0
- data/spec/configuration/list_spec.rb +19 -14
- data/spec/configuration/search_spec.rb +44 -0
- data/spec/rails_app/app/mongoid/post.rb +4 -0
- data/spec/search/simple_spec.rb +48 -0
- data/vendor/assets/javascripts/application_vendor_lolita.js +0 -1
- data/vendor/assets/stylesheets/jquery-ui-1.8.16.custom.css +568 -0
- metadata +88 -85
- data/lib/generators/helpers/file_helper.rb +0 -22
- data/lib/lolita/controllers/view_user_helpers.rb +0 -13
data/Gemfile
CHANGED
@@ -24,8 +24,12 @@ group :assets do
|
|
24
24
|
gem 'uglifier'
|
25
25
|
end
|
26
26
|
|
27
|
-
gem "jeweler", "~> 1.
|
27
|
+
gem "jeweler", "~> 1.6.4", :group=>:development
|
28
28
|
group :test,:development do
|
29
|
+
gem "metric_fu"
|
30
|
+
gem "fattr"
|
31
|
+
gem "arrayfields"
|
32
|
+
gem "map"
|
29
33
|
gem "rspec", "~>2.6.0"
|
30
34
|
gem "rspec-rails","~>2.6.1"
|
31
35
|
gem "factory_girl"
|
@@ -35,4 +39,4 @@ group :test,:development do
|
|
35
39
|
# gem "capybara"
|
36
40
|
gem "database_cleaner"
|
37
41
|
# gem "akephalos"
|
38
|
-
end
|
42
|
+
end
|
data/History.rdoc
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
=== Version 3.2.0
|
2
2
|
* Enhancements
|
3
|
+
* _only_ options added for <b>lolita_for</b>
|
4
|
+
* New options _visible_ added to Lolita::Mapping, now is possible to exclude resource from navigation tree
|
5
|
+
* Search functionality added, included in List
|
6
|
+
* All modules that need to be included by Lolita controllers is added in one Lolita::ControllerAddition
|
7
|
+
* Basic authorization added, now with CanCan.
|
3
8
|
* Created adapter Field and Association classes. Field and association access methods convert data to thoes class objects
|
4
9
|
* Factory module created where factory classes are located
|
5
10
|
* Removed specific pagination methods from adapters
|
@@ -10,17 +15,20 @@
|
|
10
15
|
* Polymorphic association field
|
11
16
|
|
12
17
|
* Changes
|
13
|
-
* using rails 3.1.x
|
18
|
+
* noew using rails 3.1.x
|
14
19
|
* #value, #value=, #record_value removed from Lolita::Configuration::Field
|
15
20
|
* Created pagination in list and in adapters; its possible to customize it for model.
|
16
21
|
* All fields must have name as well as tabs must have type
|
22
|
+
|
23
|
+
* Removed
|
24
|
+
* Lolita::FileHelper from generators removed
|
17
25
|
|
18
26
|
* Bug fixes
|
19
27
|
* Each hook call runs as new instance of Hooks::Runner
|
20
28
|
* All classes fixed to work with both mongoid and AR
|
21
|
-
|
22
|
-
|
23
|
-
=== Version 3.1.18
|
29
|
+
* String disabled builder fixed to use form object
|
30
|
+
|
31
|
+
=== Version 3.1.18
|
24
32
|
* Enhancements
|
25
33
|
*
|
26
34
|
* Bug fixes
|
data/Rakefile
CHANGED
@@ -38,3 +38,10 @@ Rake::RDocTask.new do |rdoc|
|
|
38
38
|
rdoc.rdoc_files.include('README*')
|
39
39
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
40
40
|
end
|
41
|
+
|
42
|
+
require 'metric_fu'
|
43
|
+
MetricFu::Configuration.run do |config|
|
44
|
+
config.rcov[:test_files] = ['spec/**/*_spec.rb']
|
45
|
+
config.rcov[:rcov_opts] << "-Ispec" # Needed to find spec_helper
|
46
|
+
config.metrics -= [:flog]
|
47
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.2.0.rc.
|
1
|
+
3.2.0.rc.6
|
Binary file
|
@@ -1,3 +1,5 @@
|
|
1
|
+
//= require jquery
|
2
|
+
//= require jquery-ui-1.8.13.min
|
1
3
|
$(function(){
|
2
4
|
// Send ajax request with all forms data for given tabs block.
|
3
5
|
function save_tab(tabs){
|
@@ -42,9 +44,9 @@ $(function(){
|
|
42
44
|
}
|
43
45
|
else {
|
44
46
|
// Ensure that it is a number and stop the keypress
|
45
|
-
if (event.keyCode
|
47
|
+
if (!((event.keyCode >= 48 && event.keyCode <= 57) || (event.keyCode >= 96 && event.keyCode <= 105))) {
|
46
48
|
event.preventDefault();
|
47
|
-
}
|
49
|
+
}
|
48
50
|
}
|
49
51
|
})
|
50
52
|
|
@@ -75,4 +77,31 @@ $(function(){
|
|
75
77
|
})
|
76
78
|
})
|
77
79
|
|
80
|
+
$("input[data-autocomplete-url]").live("keyup.autocomplete", function(){
|
81
|
+
$(this).autocomplete({
|
82
|
+
source: function(request, response){
|
83
|
+
$.getJSON(this.element.data("autocomplete-url"), {
|
84
|
+
term: request.term
|
85
|
+
}, response)
|
86
|
+
},
|
87
|
+
focus: function(){
|
88
|
+
return false;
|
89
|
+
},
|
90
|
+
select: function(event, ui){
|
91
|
+
console.log(ui.item.value);
|
92
|
+
var li = $("<li></li>").appendTo($(this).closest(".autocomplete-container").find("ul"));
|
93
|
+
li.text(ui.item.value);
|
94
|
+
$("<a href=''></a>").text(ui.item.delete_link).appendTo(li);
|
95
|
+
$("<input type='hidden'>").attr("name", ui.item.name).val(ui.item.id).appendTo(li);
|
96
|
+
this.value = "";
|
97
|
+
return false;
|
98
|
+
}
|
99
|
+
});
|
100
|
+
});
|
101
|
+
|
102
|
+
$(".autocomplete-container ul li a").live("click", function(){
|
103
|
+
$(this).closest("li").remove();
|
104
|
+
return false;
|
105
|
+
})
|
106
|
+
|
78
107
|
})
|
@@ -4,8 +4,12 @@ html,body{
|
|
4
4
|
body {background: #f3f3f3; font-size: 13px;}
|
5
5
|
|
6
6
|
a, a:visited, a:active {color: #7ac1ed; text-decoration: none;}
|
7
|
-
input[type="button"] {vertical-align: top; padding: 3px 9px;}
|
8
7
|
h1 {font-size: 28px; font-weight: normal; letter-spacing: -1px; line-height: 85px;}
|
8
|
+
input[type="button"] {vertical-align: top; padding: 3px 9px;}
|
9
|
+
.placeholder {color: #aaa;}
|
10
|
+
::placeholder {color: #aaa;}
|
11
|
+
:-moz-placeholder {color: #aaa;}
|
12
|
+
::-webkit-input-placeholder {color: #aaa;}
|
9
13
|
|
10
14
|
#container {
|
11
15
|
width: 90%;
|
@@ -109,6 +113,23 @@ header nav .username {margin-right: 15px;}
|
|
109
113
|
|
110
114
|
/* -------------------------------- */
|
111
115
|
|
116
|
+
/* autocomplete field*/
|
117
|
+
|
118
|
+
.autocomplete-container ul {
|
119
|
+
margin-left: 30px;
|
120
|
+
}
|
121
|
+
.autocomplete-container ul li {
|
122
|
+
list-style-type: none;
|
123
|
+
margin: 5px 0;
|
124
|
+
padding-bottom: 5px;
|
125
|
+
border-bottom: 1px dashed #DDD;
|
126
|
+
}
|
127
|
+
.ui-menu .ui-menu-item a {
|
128
|
+
font-size: 10px;
|
129
|
+
}
|
130
|
+
|
131
|
+
/* -------------------------------- */
|
132
|
+
|
112
133
|
/* error fields and notifications */
|
113
134
|
|
114
135
|
#main .box form .field_with_errors input,
|
@@ -315,7 +336,31 @@ a.create {
|
|
315
336
|
|
316
337
|
.list table td a:active {position: relative; top: 1px;}
|
317
338
|
|
318
|
-
/*
|
339
|
+
/* search in list view */
|
340
|
+
|
341
|
+
#main .boxtitle .black .search {
|
342
|
+
position: absolute;
|
343
|
+
right: 15px;
|
344
|
+
top: 25px;
|
345
|
+
background: none;
|
346
|
+
padding: 0;
|
347
|
+
}
|
348
|
+
#main .boxtitle .black .search input {
|
349
|
+
font-size: 13px;
|
350
|
+
background: #fff url(<%= asset_data_uri "lolita/search_icon.png" %>) no-repeat 5px center;
|
351
|
+
padding: 0 10px 0 18px;
|
352
|
+
border: 1px solid #ccc;
|
353
|
+
border-radius: 10px;
|
354
|
+
-moz-border-radius: 10px;
|
355
|
+
-webkit-border-radius: 10px;
|
356
|
+
height: 20px;
|
357
|
+
line-height: 20px\9;
|
358
|
+
}
|
359
|
+
|
360
|
+
/* -------------------------------------------------------------------------------- */
|
361
|
+
|
362
|
+
/* filter in list view */
|
363
|
+
|
319
364
|
#main form.filter {
|
320
365
|
background: #F3F3F3;
|
321
366
|
padding: 10px;
|
@@ -331,6 +376,7 @@ a.create {
|
|
331
376
|
#main form.filter label {
|
332
377
|
color: #666;
|
333
378
|
}
|
379
|
+
|
334
380
|
/* --------------------------------------------- */
|
335
381
|
|
336
382
|
/* Pagination */
|
@@ -440,4 +486,4 @@ a.create {
|
|
440
486
|
{position: relative;}
|
441
487
|
.ie8 .black {-pie-background: linear-gradient(top, #686868, #2f2f2f);}
|
442
488
|
.ie8 #flash {-pie-background: rgba(255,255,255,0.9);}
|
443
|
-
/* ----------------------------------------------*/
|
489
|
+
/* ----------------------------------------------*/
|
@@ -2,7 +2,7 @@ class Lolita::FieldDataController < ApplicationController
|
|
2
2
|
include Lolita::Controllers::UserHelpers
|
3
3
|
|
4
4
|
before_filter :authenticate_lolita_user!
|
5
|
-
before_filter :find_field
|
5
|
+
before_filter :find_field, :except => [:autocomplete_field]
|
6
6
|
|
7
7
|
def array_polymorphic
|
8
8
|
klass = params[:class].camelize.constantize
|
@@ -17,4 +17,16 @@ class Lolita::FieldDataController < ApplicationController
|
|
17
17
|
field.name.to_s == params[:name].to_s
|
18
18
|
}
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
|
+
def autocomplete_field
|
22
|
+
model = params[:class].singularize.camelize.constantize
|
23
|
+
column = model.lolita.tabs.first.fields.first.name.to_sym
|
24
|
+
data = model.where(model.arel_table[column].matches("%#{params[:term]}%")).map do |record|
|
25
|
+
{:id => record.id,
|
26
|
+
:value => record.send(column),
|
27
|
+
:name => "#{params[:field_class].downcase}[#{params[:class].singularize}_ids][]",
|
28
|
+
:delete_link => I18n.t("lolita.shared.delete")}
|
29
|
+
end
|
30
|
+
render :json => data
|
31
|
+
end
|
32
|
+
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
class Lolita::RestController < ApplicationController
|
2
|
-
include Lolita::
|
3
|
-
include Lolita::Controllers::InternalHelpers
|
2
|
+
include Lolita::ControllerAdditions
|
4
3
|
|
5
4
|
include Lolita::Hooks
|
6
5
|
add_hook :before_new, :after_new, :before_create,:after_create,:before_edit,:after_edit
|
@@ -12,12 +11,14 @@ class Lolita::RestController < ApplicationController
|
|
12
11
|
|
13
12
|
def new
|
14
13
|
self.run(:before_new)
|
14
|
+
authorize!(:create,self.resource_class)
|
15
15
|
build_resource
|
16
16
|
show_form
|
17
17
|
end
|
18
18
|
|
19
19
|
def create
|
20
20
|
self.run(:before_create)
|
21
|
+
authorize!(:create,self.resource_class)
|
21
22
|
build_resource
|
22
23
|
save_and_redirect
|
23
24
|
end
|
@@ -25,12 +26,14 @@ class Lolita::RestController < ApplicationController
|
|
25
26
|
def edit
|
26
27
|
self.run(:before_edit)
|
27
28
|
get_resource
|
29
|
+
authorize!(:update,self.resource)
|
28
30
|
show_form
|
29
31
|
end
|
30
32
|
|
31
33
|
def update
|
32
34
|
self.run(:before_update)
|
33
35
|
get_resource
|
36
|
+
authorize!(:update,self.resource)
|
34
37
|
if self.resource
|
35
38
|
self.resource=resource_with_attributes(self.resource,resource_attributes)
|
36
39
|
save_and_redirect
|
@@ -41,6 +44,7 @@ class Lolita::RestController < ApplicationController
|
|
41
44
|
def destroy
|
42
45
|
self.run(:before_destroy)
|
43
46
|
get_resource
|
47
|
+
authorize!(:destroy, self.resource)
|
44
48
|
if self.resource && self.resource.destroy
|
45
49
|
flash[:notice] = ::I18n.t "lolita.shared.destroy_notice"
|
46
50
|
else
|
@@ -52,6 +56,7 @@ class Lolita::RestController < ApplicationController
|
|
52
56
|
|
53
57
|
def index
|
54
58
|
self.run(:before_index)
|
59
|
+
authorize!(:read,self.resource_class)
|
55
60
|
respond_to do |format|
|
56
61
|
format.html do
|
57
62
|
build_response_for(:list,:page=>page)
|
data/app/views/components/lolita/configuration/field/array/habtm_autocomplete/_display.html.haml
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
- ids_method = field.name.to_s.match(/_ids$/) ? field.name : "#{field.name.to_s.singularize}_ids"
|
2
|
+
|
3
|
+
.autocomplete-container
|
4
|
+
= hidden_field_tag "#{resource_name}[#{ids_method}][]",""
|
5
|
+
= text_field_tag :"autocomplete-#{resource_name}", nil, :"data-autocomplete-url" => autocomplete_field_path(:field_class => tab_form.object.class.to_s, :class => field.name)
|
6
|
+
%ul
|
7
|
+
- resource.persisted? && resource.send(field.name).each do |element|
|
8
|
+
%li
|
9
|
+
= element.send(element.class.lolita.tabs.first.fields.first.name.to_sym)
|
10
|
+
= link_to I18n.t("lolita.shared.delete").downcase, nil
|
11
|
+
= hidden_field_tag "#{resource_name}[#{ids_method}][]", element.id
|
@@ -1 +1 @@
|
|
1
|
-
<div class="disabled-field"><%= raw(
|
1
|
+
<div class="disabled-field"><%= raw(tab_form.object.send(field.name)) %></div>
|
@@ -1 +1 @@
|
|
1
|
-
<%= paginate page, :theme => "lolita" %>
|
1
|
+
<%= paginate page, :theme => "lolita", :params => params %>
|
@@ -1,5 +1,10 @@
|
|
1
1
|
<div class="boxtitle">
|
2
|
-
<h1 class="black"
|
2
|
+
<h1 class="black">
|
3
|
+
<%= resource_class.model_name.human(:count=>2) %>
|
4
|
+
<% if list.search %>
|
5
|
+
<%= render_component list.search, :display %>
|
6
|
+
<% end %>
|
7
|
+
</h1>
|
3
8
|
<div class="arrow">
|
4
9
|
</div>
|
5
10
|
</div>
|
@@ -11,29 +11,20 @@
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end %>
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
b.options[:url]==request.path
|
28
|
-
end
|
29
|
-
}
|
30
|
-
end
|
31
|
-
%>
|
32
|
-
<li class="<%=active ? "active" : ""%> <%=branch.children.branches.any? ? "with-subtree" : ""%> <%=!tree.root? && branch==last_branch ? "last-in-subtree" : ""%>">
|
33
|
-
<%= link_to branch.title, branch.options[:url] || "#" %>
|
34
|
-
<% if branch.children.branches.any? %>
|
35
|
-
<%= render_component(:"lolita/navigation",:tree,:tree=>branch.children) %>
|
14
|
+
<% visible ||= (tree.root? || nil) %>
|
15
|
+
<% if tree.visible?(self) %>
|
16
|
+
<ul <%= !tree.root? ? "class='subtree'" : ""%> style="display:<%=visible ? "block" : "none"%>" >
|
17
|
+
<% last_branch=tree.branches.last %>
|
18
|
+
<%tree.branches.each do |branch|
|
19
|
+
if branch.visible?(self)
|
20
|
+
active = branch.active?(self) %>
|
21
|
+
<li class="<%=active ? "active" : ""%> <%=branch.subtree? ? "with-subtree" : ""%> <%=!tree.root? && branch==last_branch ? "last-in-subtree" : ""%>">
|
22
|
+
<%= link_to branch.title, branch.options[:url] || "#", :onclick => branch.subtree? ? "$(this).next().toggle();return false;" : "" %>
|
23
|
+
<% if branch.subtree? %>
|
24
|
+
<%= render_component(:"lolita/navigation",:tree,:tree=>branch.children, :visible => active) %>
|
25
|
+
<% end %>
|
26
|
+
</li>
|
36
27
|
<% end %>
|
37
|
-
|
38
|
-
|
39
|
-
|
28
|
+
<% end %>
|
29
|
+
</ul>
|
30
|
+
<% end %>
|
@@ -3,7 +3,7 @@
|
|
3
3
|
<% if lolita_current_user %>
|
4
4
|
<nav>
|
5
5
|
<a href="<%=send(:"edit_#{lolita_current_user.class.to_s.downcase}_password_path")%>" class="username"><%=lolita_current_user.email%></a>
|
6
|
-
|
6
|
+
<%= link_to ::I18n.t("lolita.shared.log_out"), send(:"destroy_#{lolita_current_user.class.to_s.downcase}_session_path"), :class => "button grey", :method => Devise.sign_out_via %>
|
7
7
|
</nav>
|
8
8
|
<% end %>
|
9
9
|
</header>
|
@@ -9,9 +9,8 @@
|
|
9
9
|
<head>
|
10
10
|
<meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
11
11
|
|
12
|
-
<title
|
13
|
-
|
14
|
-
|
12
|
+
<title><%=Lolita.application.name%></title><meta name="description" content=""><meta name="author" content="">
|
13
|
+
<%= favicon_link_tag "lolita/favicon.ico"%>
|
15
14
|
<%= stylesheet_link_tag "lolita/application.css" %>
|
16
15
|
<%= yield :style %>
|
17
16
|
<%= javascript_include_tag "lolita/application.js" %>
|
data/config/locales/en.yml
CHANGED
@@ -23,30 +23,7 @@ en:
|
|
23
23
|
filter:
|
24
24
|
apply_button: Apply
|
25
25
|
include_blank_by_title: " -- Filter by %{title} -- "
|
26
|
-
|
27
|
-
shared:
|
28
|
-
save_notice: Successfully saved.
|
29
|
-
save_alert: Save did not succeed.
|
30
|
-
log_out: Sign out
|
31
|
-
edit: Edit
|
32
|
-
delete: Delete
|
33
|
-
and: and
|
34
|
-
powered: Powered Lolita (2010-%{year})
|
35
|
-
nested_form:
|
36
|
-
add: "Add %{resource_name}"
|
37
|
-
tabs:
|
38
|
-
last_save: Last save
|
39
|
-
save: Save
|
40
|
-
save_all: Save all
|
41
|
-
titles:
|
42
|
-
default: "Default"
|
43
|
-
content: "Content"
|
44
|
-
list:
|
45
|
-
add_new: Add new %{name}
|
46
|
-
confirm: "Are you sure you want to delete record?"
|
47
|
-
filter:
|
48
|
-
apply_button: Apply
|
49
|
-
include_blank_by_title: " -- Filter by %{title} -- "
|
26
|
+
search: "Search"
|
50
27
|
views:
|
51
28
|
pagination:
|
52
29
|
previous: "« Previous"
|
data/config/locales/lv.yml
CHANGED
data/config/routes.rb
CHANGED
@@ -2,4 +2,5 @@ Rails.application.routes.draw do
|
|
2
2
|
match '/lolita' => "lolita/info#index"
|
3
3
|
match '/lolita/info/properties' => "lolita/info#properties"
|
4
4
|
match "/lolita/array_field/:name/:field_class/:class/:id" => "lolita/field_data#array_polymorphic", :as => "array_field_data_collector"
|
5
|
-
|
5
|
+
match "/lolita/autocomplete_field/:field_class/:class" => "lolita/field_data#autocomplete_field", :as => "autocomplete_field"
|
6
|
+
end
|
@@ -1,21 +1,18 @@
|
|
1
|
-
require 'generators/helpers/file_helper'
|
2
|
-
|
3
1
|
module Lolita
|
4
2
|
module Generators
|
5
3
|
class InstallGenerator < Rails::Generators::Base
|
6
|
-
include Lolita::Generators::FileHelper
|
7
4
|
source_root File.expand_path("../../templates", __FILE__)
|
8
5
|
desc "Create lolita initializer."
|
9
6
|
|
10
7
|
|
11
8
|
def copy_initializer
|
12
|
-
template "lolita.rb", "config/initializers/lolita.rb" unless
|
9
|
+
template "lolita.rb", "config/initializers/lolita.rb" unless File.exist?(Rails.root + "config/initializers/lolita.rb")
|
13
10
|
end
|
14
11
|
|
15
12
|
def install_modules
|
16
13
|
Lolita.modules.each do |module_name|
|
17
14
|
|
18
|
-
invoke "
|
15
|
+
invoke "lolita:#{module_name.to_s.underscore.gsub("/","_").gsub(/^lolita_/,"")}:install" rescue nil
|
19
16
|
end
|
20
17
|
end
|
21
18
|
|
@@ -8,10 +8,6 @@ Lolita.setup do |config|
|
|
8
8
|
# Define authentication for Lolita controllers.
|
9
9
|
# Call some of your own methods
|
10
10
|
# config.authentication=:is_admin?
|
11
|
-
# Or use some customized logic
|
12
|
-
# config.authentication={
|
13
|
-
# current_user.is_a?(Admin) || current_user.has_role?(:admin)
|
14
|
-
# }
|
15
11
|
|
16
12
|
<% if defined?(Devise) %>
|
17
13
|
<% default_user_class = Devise.mappings.keys.first %>
|
@@ -8,6 +8,7 @@ module Lolita
|
|
8
8
|
abstract_method 'method_name,page,per,options', :pagination_scope_from_klass
|
9
9
|
abstract_method 'name',:reflect_on_association,:field_by_name,:field_by_association
|
10
10
|
abstract_method 'id',:find_by_id
|
11
|
+
abstract_method 'query', :search
|
11
12
|
end
|
12
13
|
end
|
13
14
|
end
|
@@ -200,6 +200,25 @@ module Lolita
|
|
200
200
|
end
|
201
201
|
end
|
202
202
|
|
203
|
+
def search(query, options = {})
|
204
|
+
#TODO raise error or warn when there are lot of records and no index on field
|
205
|
+
resources = self.klass.arel_table
|
206
|
+
content_fields = @dbi.fields.map{|field| field.type!="string" ? nil : field.name.to_sym}.compact
|
207
|
+
if options[:fields] && options[:fields].any?
|
208
|
+
content_fields = content_fields & options[:fields]
|
209
|
+
end
|
210
|
+
scope = nil
|
211
|
+
content_fields.each_with_index do |field,index|
|
212
|
+
new_scope = resources[field].matches("%#{query}%")
|
213
|
+
unless index == 0
|
214
|
+
scope = scope.or(new_scope)
|
215
|
+
else
|
216
|
+
scope = new_scope
|
217
|
+
end
|
218
|
+
end
|
219
|
+
self.klass.where(scope)
|
220
|
+
end
|
221
|
+
|
203
222
|
def db
|
204
223
|
self.klass.connection
|
205
224
|
end
|
@@ -184,6 +184,66 @@ module Lolita
|
|
184
184
|
end
|
185
185
|
end
|
186
186
|
|
187
|
+
def search(query, options = {})
|
188
|
+
content_fields = @dbi.fields.map{|field|
|
189
|
+
if field.type!="string" || field.name.match(/^_/)
|
190
|
+
nil
|
191
|
+
else
|
192
|
+
field.name.to_sym
|
193
|
+
end
|
194
|
+
}.compact
|
195
|
+
if options[:fields] && options[:fields].any?
|
196
|
+
content_fields = content_fields & options[:fields]
|
197
|
+
end
|
198
|
+
content_fields = content_fields.slice(0..3)
|
199
|
+
#result = self.map_reduce_search(content_fields,query)
|
200
|
+
#debugger
|
201
|
+
#result
|
202
|
+
where_hash = {}
|
203
|
+
content_fields.each do |field|
|
204
|
+
where_hash[field] = /#{Regexp.escape(query.to_s)}/
|
205
|
+
end
|
206
|
+
klass.where(where_hash)
|
207
|
+
end
|
208
|
+
|
209
|
+
#FIXME
|
210
|
+
def map_reduce_search(content_fields,query)
|
211
|
+
keys = "[" + @dbi.fields.map{|f|
|
212
|
+
f.primary? || f.name.to_s.match(/^_/) ? nil : "'#{f.name}'"
|
213
|
+
}.compact.join(",").to_s + "]"
|
214
|
+
content_keys = "[" + content_fields.map{|f| "'#{f.name}'"}.join(",").to_s + "]"
|
215
|
+
result_obj = @dbi.fields.map{|f|
|
216
|
+
f.name.to_s.match(/^_/) ? nil : "'#{f.name}': false"
|
217
|
+
}.compact.join(",")
|
218
|
+
result_obj = "{#{result_obj}}"
|
219
|
+
map = %^
|
220
|
+
function(){
|
221
|
+
var doc = #{result_obj};
|
222
|
+
var do_emit = false;
|
223
|
+
for(var k in #{content_keys}){
|
224
|
+
var c_val = this[k];
|
225
|
+
if(c_val && c_val.match(/#{Regexp.escape(query)}/i)){
|
226
|
+
do_emit = true;
|
227
|
+
break;
|
228
|
+
};
|
229
|
+
};
|
230
|
+
if(true){
|
231
|
+
#{keys}.forEach(function(k){
|
232
|
+
doc[k] = this.name;
|
233
|
+
})
|
234
|
+
emit(this.id,doc);
|
235
|
+
};
|
236
|
+
};
|
237
|
+
^
|
238
|
+
reduce = %^
|
239
|
+
function(key,values){
|
240
|
+
|
241
|
+
return values[values.length-1];
|
242
|
+
};
|
243
|
+
^
|
244
|
+
self.collection.map_reduce(map,reduce, {:out => "custom_mr", :query => {}})
|
245
|
+
end
|
246
|
+
|
187
247
|
def db
|
188
248
|
self.klass.db
|
189
249
|
end
|
@@ -18,6 +18,20 @@ module Lolita
|
|
18
18
|
set_default_attributes
|
19
19
|
end
|
20
20
|
|
21
|
+
# For details see Lolita::Configuration::Search
|
22
|
+
def search *args, &block
|
23
|
+
if (args && args.any?) || block_given?
|
24
|
+
@search = Lolita::Configuration::Search.new(self.dbi,*args,&block)
|
25
|
+
end
|
26
|
+
@search
|
27
|
+
end
|
28
|
+
|
29
|
+
# Define or return pagination method. This method is used by DBI adapters to delegate domain specific
|
30
|
+
# pagination back to model.
|
31
|
+
# ====Example
|
32
|
+
# list do
|
33
|
+
# pagination_method :paginate_with_profiles
|
34
|
+
# end
|
21
35
|
def pagination_method(value = nil)
|
22
36
|
if value
|
23
37
|
self.pagination_method = value
|
@@ -29,8 +43,15 @@ module Lolita
|
|
29
43
|
@pagination_method = value
|
30
44
|
end
|
31
45
|
|
32
|
-
|
33
|
-
|
46
|
+
# Return page for list display. Method requires two arguments:
|
47
|
+
# * <tt>current_page</tt> - number of current page
|
48
|
+
# * <tt>request (optional) </tt> - request that is passed to adapter that passes this to model when #pagination_method is defined
|
49
|
+
def paginate(current_page, request = nil)
|
50
|
+
page_criteria = dbi.paginate(current_page,@per,:request => request, :pagination_method => @pagination_method)
|
51
|
+
if self.search
|
52
|
+
page_criteria = page_criteria.merge(self.search.run(request.params[:q],request))
|
53
|
+
end
|
54
|
+
page_criteria
|
34
55
|
end
|
35
56
|
|
36
57
|
# Set columns. Allowed classes are Lolita::Configuration::Columns or
|