lolita 3.0.5 → 3.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +2 -0
- data/GUIDELINE +20 -20
- data/VERSION +1 -1
- data/app/views/components/lolita/field/_boolean.html.erb +1 -0
- data/app/views/components/lolita/field/_select.html.erb +1 -1
- data/app/views/components/lolita/field/_text.html.erb +1 -1
- data/app/views/components/lolita/navigation/_display.html.erb +1 -1
- data/app/views/components/lolita/shared/_flash.html.erb +1 -1
- data/app/views/lolita/layouts/application.html.erb +3 -2
- data/lib/generators/lolita/{copy_assets_generator.rb → assets_generator.rb} +1 -1
- data/lib/generators/lolita/install_generator.rb +6 -3
- data/lib/lolita.rb +136 -135
- data/lib/lolita/adapter/active_record.rb +110 -110
- data/lib/lolita/adapter/mongoid.rb +104 -104
- data/lib/lolita/base_configuration.rb +49 -21
- data/lib/lolita/configuration/base.rb +76 -76
- data/lib/lolita/configuration/factory.rb +46 -0
- data/lib/lolita/configuration/field.rb +31 -45
- data/lib/lolita/configuration/field/boolean.rb +10 -0
- data/lib/lolita/configuration/{field_extensions → field}/collection.rb +25 -17
- data/lib/lolita/configuration/field/datetime.rb +10 -0
- data/lib/lolita/configuration/field/disabled.rb +10 -0
- data/lib/lolita/configuration/field/integer.rb +10 -0
- data/lib/lolita/configuration/field/password.rb +10 -0
- data/lib/lolita/configuration/field/string.rb +11 -0
- data/lib/lolita/configuration/field/text.rb +10 -0
- data/lib/lolita/configuration/tab.rb +5 -25
- data/lib/lolita/configuration/tab/default.rb +24 -0
- data/lib/lolita/configuration/tabs.rb +7 -3
- data/lib/lolita/controllers/component_helpers.rb +16 -1
- data/lib/lolita/errors.rb +2 -0
- data/lib/lolita/mapping.rb +17 -4
- data/lib/lolita/modules/rest.rb +1 -1
- data/lib/lolita/rails/routes.rb +21 -12
- data/lolita.gemspec +15 -5
- data/public/javascripts/lolita/main.js +7 -6
- data/public/javascripts/lolita/tab.js +36 -36
- data/spec/configuration/field_spec.rb +3 -3
- data/spec/configuration/tab_spec.rb +2 -2
- data/spec/configuration/tabs_spec.rb +7 -0
- data/spec/rails_app/public/javascripts/lolita/tab.js +36 -36
- data/spec/rails_app/public/javascripts/rails.js +137 -137
- metadata +16 -6
- data/lib/lolita/version.rb +0 -3
@@ -0,0 +1,46 @@
|
|
1
|
+
module Lolita
|
2
|
+
module Configuration
|
3
|
+
module Factory
|
4
|
+
|
5
|
+
def temp_object?
|
6
|
+
@create_temp_object||=false
|
7
|
+
@create_temp_object
|
8
|
+
end
|
9
|
+
|
10
|
+
def add(dbi,*args,&block)
|
11
|
+
@create_temp_object=true
|
12
|
+
begin
|
13
|
+
temp_object=self.new(dbi,*args,&block)
|
14
|
+
rescue Exception => e
|
15
|
+
raise e
|
16
|
+
ensure
|
17
|
+
@create_temp_object=false
|
18
|
+
end
|
19
|
+
factory(temp_object.type).new(dbi,*args,&block)
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
def factory(name)
|
26
|
+
begin
|
27
|
+
Lolita::Configuration.const_get(:"#{to_class(name)}#{factory_name}")
|
28
|
+
rescue
|
29
|
+
error_class=Lolita.const_get(:"#{factory_name}NotFoundError")
|
30
|
+
raise error_class, "Can't find field Lolita::Configuration::#{to_class(name)}#{factory_name}. Add in /configuration/#{factory_name.downcase}/#{name.to_s.downcase}.rb"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_class(name)
|
35
|
+
name.to_s.downcase.gsub(/_\w/) do |m|
|
36
|
+
m.gsub("_","").upcase
|
37
|
+
end.humanize
|
38
|
+
end
|
39
|
+
|
40
|
+
def factory_name
|
41
|
+
@factory_name||=self.to_s.split("::").last
|
42
|
+
@factory_name
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -24,27 +24,24 @@ module Lolita
|
|
24
24
|
# end
|
25
25
|
# end
|
26
26
|
class Field
|
27
|
+
extend Lolita::Configuration::Factory
|
27
28
|
|
28
|
-
|
29
|
-
|
29
|
+
@@default_type="string"
|
30
|
+
lolita_accessor :name,:title,:type,:field_set,:nested_for,:options, :html_options,:record,:association
|
31
|
+
attr_reader :dbi,:nested_in
|
30
32
|
|
31
33
|
def initialize dbi, *args, &block
|
32
34
|
@dbi=dbi
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
def type=(value)
|
46
|
-
@type=value
|
47
|
-
add_extension unless @extension_added
|
35
|
+
begin
|
36
|
+
self.set_attributes(*args)
|
37
|
+
self.instance_eval(&block) if block_given?
|
38
|
+
set_default_values
|
39
|
+
validate
|
40
|
+
rescue Exception=>e
|
41
|
+
unless self.class.temp_object?
|
42
|
+
raise e
|
43
|
+
end
|
44
|
+
end
|
48
45
|
end
|
49
46
|
|
50
47
|
def value value=nil, &block
|
@@ -100,6 +97,7 @@ module Lolita
|
|
100
97
|
if args
|
101
98
|
attributes=args.extract_options!
|
102
99
|
self.name=args.first if args.first
|
100
|
+
self.type=args[1] if args[1]
|
103
101
|
attributes.each{|attr,value|
|
104
102
|
self.send(:"#{attr}=",value)
|
105
103
|
}
|
@@ -116,42 +114,30 @@ module Lolita
|
|
116
114
|
end
|
117
115
|
|
118
116
|
private
|
117
|
+
|
119
118
|
|
120
|
-
def
|
121
|
-
@extension_added=true
|
119
|
+
def set_default_values
|
122
120
|
set_association
|
123
|
-
|
124
|
-
|
125
|
-
self.
|
126
|
-
end
|
127
|
-
|
128
|
-
|
129
|
-
def set_association #TODO test
|
130
|
-
assoc_name=@name.to_s.gsub(/_id$/,"")
|
131
|
-
@association=@dbi.reflect_on_association(assoc_name.to_sym) ||
|
132
|
-
@dbi.reflect_on_association(assoc_name.pluralize.to_sym)
|
133
|
-
end
|
134
|
-
|
135
|
-
def refactor_type #TODO test
|
136
|
-
@type=if @association
|
137
|
-
"collection"
|
138
|
-
elsif [:created_at,:updated_at,:type].include?(@name)
|
139
|
-
"disabled"
|
140
|
-
else
|
141
|
-
@type
|
142
|
-
end
|
121
|
+
set_type
|
122
|
+
self.title||=self.name.to_s.capitalize
|
123
|
+
self.options||={}
|
143
124
|
end
|
144
125
|
|
145
|
-
def
|
126
|
+
def set_type
|
127
|
+
@type=@type.to_s.downcase if @type
|
146
128
|
if @association
|
147
|
-
@
|
129
|
+
@type="collection"
|
130
|
+
elsif @type.nil? || @type.to_s=="object"
|
131
|
+
@type=@@default_type
|
148
132
|
end
|
149
133
|
end
|
150
134
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
135
|
+
# Need here because this don't know how to recognize association.
|
136
|
+
# TODO maybe need move to adapter, and it is converted there
|
137
|
+
def set_association #TODO test
|
138
|
+
assoc_name=@name.to_s.gsub(/_id$/,"")
|
139
|
+
@association||=@dbi.reflect_on_association(assoc_name.to_sym) ||
|
140
|
+
@dbi.reflect_on_association(assoc_name.pluralize.to_sym)
|
155
141
|
end
|
156
142
|
|
157
143
|
def validate
|
@@ -1,18 +1,19 @@
|
|
1
1
|
module Lolita
|
2
2
|
module Configuration
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
# and <code>group</code> usage when it is not neccessary and allow when you
|
7
|
-
# need it.
|
8
|
-
# It depends on field
|
9
|
-
# _type_. Each different field type, can have one extension module. Instance
|
10
|
-
# will be automaticly extended when type is assigned, therefor type should
|
11
|
-
# be called before any type-specific method is called.
|
12
|
-
module FieldExtensions
|
13
|
-
module Collection
|
3
|
+
class CollectionField < Lolita::Configuration::Field
|
4
|
+
lolita_accessor :conditions,:text_method,:value_method,:find_options,:association_type
|
5
|
+
|
14
6
|
|
15
|
-
|
7
|
+
def initialize *args,&block
|
8
|
+
@type="collection"
|
9
|
+
super
|
10
|
+
set_association_type
|
11
|
+
end
|
12
|
+
|
13
|
+
def options_for_select &block
|
14
|
+
@options_for_select=block if block_given?
|
15
|
+
@options_for_select
|
16
|
+
end
|
16
17
|
|
17
18
|
# Collect values for collection type field.
|
18
19
|
# Uses <code>text_method</code> for content. By default it search for
|
@@ -21,7 +22,9 @@ module Lolita
|
|
21
22
|
# <code>find_options</code> for advanced search. When <code>find_options</code>
|
22
23
|
# is used, than <code>conditions</code> is ignored.
|
23
24
|
def association_values() #TODO test
|
24
|
-
if
|
25
|
+
@association_values||=if options_for_select
|
26
|
+
options_for_select
|
27
|
+
elsif @association
|
25
28
|
klass=@dbi.association_class_name(@association).camelize.constantize
|
26
29
|
current_text_method=@text_method || default_text_method(klass)
|
27
30
|
current_value_method=@value_method || :id
|
@@ -34,10 +37,17 @@ module Lolita
|
|
34
37
|
else
|
35
38
|
[]
|
36
39
|
end
|
40
|
+
@association_values
|
37
41
|
end
|
38
42
|
|
39
43
|
private
|
40
44
|
|
45
|
+
def set_association_type #TODO test
|
46
|
+
if @association
|
47
|
+
@association_type||=@dbi.association_macro(@association)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
41
51
|
def default_text_method(klass)
|
42
52
|
assoc_dbi=Lolita::DBI::Base.new(klass)
|
43
53
|
field=assoc_dbi.fields.detect{|f| f[:type].downcase=="string"}
|
@@ -45,13 +55,11 @@ module Lolita
|
|
45
55
|
field[:name]
|
46
56
|
else
|
47
57
|
raise Lolita::FieldTypeError, %^
|
48
|
-
|
49
|
-
|
58
|
+
Can't find any content field in #{assoc_dbi.klass}.
|
59
|
+
Use text_method in #{klass} to set one.
|
50
60
|
^
|
51
61
|
end
|
52
62
|
end
|
53
|
-
# MODULE end
|
54
|
-
end
|
55
63
|
end
|
56
64
|
end
|
57
65
|
end
|
@@ -18,27 +18,10 @@ module Lolita
|
|
18
18
|
# tab(:files)
|
19
19
|
# end
|
20
20
|
class Tab
|
21
|
+
extend Lolita::Configuration::Factory
|
21
22
|
|
22
|
-
class << self
|
23
|
-
|
24
|
-
def add(dbi,*args,&block)
|
25
|
-
type=args.first if args
|
26
|
-
if !type || type==:default
|
27
|
-
temp_tab=self.new(dbi,*args,&block)
|
28
|
-
type=temp_tab.type
|
29
|
-
end
|
30
|
-
unless type==:default
|
31
|
-
begin
|
32
|
-
"Lolita::Configuration::#{type.to_s.camelize}Tab".constantize.new(dbi,*args,&block)
|
33
|
-
rescue NameError
|
34
|
-
raise Lolita::TabNotFoundError, "Lolita::Configuration::#{type.to_s.camelize}Tab not found. Add it in /lolita/configuration/tab/#{type}.rb"
|
35
|
-
end
|
36
|
-
else
|
37
|
-
temp_tab
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
23
|
# For different types there are different builders(cells)
|
24
|
+
@@default_tab_type=:default
|
42
25
|
@@available_types=[:content]
|
43
26
|
|
44
27
|
lolita_accessor :title,:name,:type
|
@@ -64,7 +47,7 @@ module Lolita
|
|
64
47
|
# For details how to pass args and block see Lolita::Configuration::Field.
|
65
48
|
# Return field itself.
|
66
49
|
def field *args, &block
|
67
|
-
field=Lolita::Configuration::Field.
|
50
|
+
field=Lolita::Configuration::Field.add(self.current_dbi,*args,&block)
|
68
51
|
field.field_set=current_fieldset
|
69
52
|
if self.current_dbi!=self.dbi
|
70
53
|
field.nested_in=self.dbi
|
@@ -171,11 +154,11 @@ module Lolita
|
|
171
154
|
private
|
172
155
|
|
173
156
|
def set_default_fields
|
174
|
-
default_fields if @
|
157
|
+
default_fields if @fields.empty?
|
175
158
|
end
|
176
159
|
|
177
160
|
def set_default_attributes
|
178
|
-
@type
|
161
|
+
@type=@@default_tab_type unless @type
|
179
162
|
@name="tab_#{self.__id__}" unless @name
|
180
163
|
@title=@type.to_s.humanize unless @title
|
181
164
|
end
|
@@ -186,9 +169,6 @@ module Lolita
|
|
186
169
|
|
187
170
|
def validate
|
188
171
|
set_default_attributes
|
189
|
-
if type==:default && fields.empty?
|
190
|
-
raise Lolita::NoFieldsGivenError, "At least one field must be specified for default tab."
|
191
|
-
end
|
192
172
|
end
|
193
173
|
|
194
174
|
class << self
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Lolita
|
2
|
+
module Configuration
|
3
|
+
class DefaultTab < Lolita::Configuration::Tab
|
4
|
+
|
5
|
+
def initialize *args,&block
|
6
|
+
self.type=:default
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def set_default_fields
|
13
|
+
warn("Default fields are not set for DefaultTab.")
|
14
|
+
end
|
15
|
+
|
16
|
+
def validate
|
17
|
+
super
|
18
|
+
if fields.empty?
|
19
|
+
raise Lolita::NoFieldsGivenError, "At least one field must be specified for default tab."
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -28,13 +28,17 @@ module Lolita
|
|
28
28
|
}
|
29
29
|
end
|
30
30
|
|
31
|
+
def clear
|
32
|
+
@tabs=[]
|
33
|
+
end
|
34
|
+
|
31
35
|
def tabs=(values)
|
32
|
-
if values.
|
36
|
+
if values.respond_to?(:each)
|
33
37
|
values.each{|tab|
|
34
38
|
self<<tab
|
35
39
|
}
|
36
40
|
else
|
37
|
-
raise ArgumentError, "
|
41
|
+
raise ArgumentError, "#{values.class} did not responded to :each."
|
38
42
|
end
|
39
43
|
end
|
40
44
|
|
@@ -61,7 +65,7 @@ module Lolita
|
|
61
65
|
default_tab_types
|
62
66
|
end
|
63
67
|
tab_types.each{|type|
|
64
|
-
self<<Lolita::Configuration::Tab.
|
68
|
+
self<<Lolita::Configuration::Tab.add(@dbi,type.to_sym)
|
65
69
|
}
|
66
70
|
end
|
67
71
|
|
@@ -29,11 +29,26 @@ module Lolita
|
|
29
29
|
@opts=args.extract_options!
|
30
30
|
name=args[0]
|
31
31
|
state=args[1]
|
32
|
+
format=@opts.delete(:format)
|
32
33
|
raise "Can't render component without name!" unless name
|
33
34
|
will_use_component name
|
34
|
-
|
35
|
+
if format
|
36
|
+
with_format(format) do
|
37
|
+
render(:partial=>"/components/#{name}#{state ? "/#{state}" : nil}",:locals=>@opts)
|
38
|
+
end
|
39
|
+
else
|
40
|
+
render(:partial=>"/components/#{name}#{state ? "/#{state}" : nil}",:locals=>@opts)
|
41
|
+
end
|
35
42
|
end
|
36
43
|
|
44
|
+
def with_format(format, &block)
|
45
|
+
old_formats = formats
|
46
|
+
self.formats = [format]
|
47
|
+
result=block.call
|
48
|
+
self.formats = old_formats
|
49
|
+
result
|
50
|
+
end
|
51
|
+
|
37
52
|
# Require component helper file and extend current instance with component helper module.
|
38
53
|
# ====Example
|
39
54
|
# will_use_component :"lolita/list"
|