lolita 3.0.5 → 3.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/.rspec +2 -0
  2. data/GUIDELINE +20 -20
  3. data/VERSION +1 -1
  4. data/app/views/components/lolita/field/_boolean.html.erb +1 -0
  5. data/app/views/components/lolita/field/_select.html.erb +1 -1
  6. data/app/views/components/lolita/field/_text.html.erb +1 -1
  7. data/app/views/components/lolita/navigation/_display.html.erb +1 -1
  8. data/app/views/components/lolita/shared/_flash.html.erb +1 -1
  9. data/app/views/lolita/layouts/application.html.erb +3 -2
  10. data/lib/generators/lolita/{copy_assets_generator.rb → assets_generator.rb} +1 -1
  11. data/lib/generators/lolita/install_generator.rb +6 -3
  12. data/lib/lolita.rb +136 -135
  13. data/lib/lolita/adapter/active_record.rb +110 -110
  14. data/lib/lolita/adapter/mongoid.rb +104 -104
  15. data/lib/lolita/base_configuration.rb +49 -21
  16. data/lib/lolita/configuration/base.rb +76 -76
  17. data/lib/lolita/configuration/factory.rb +46 -0
  18. data/lib/lolita/configuration/field.rb +31 -45
  19. data/lib/lolita/configuration/field/boolean.rb +10 -0
  20. data/lib/lolita/configuration/{field_extensions → field}/collection.rb +25 -17
  21. data/lib/lolita/configuration/field/datetime.rb +10 -0
  22. data/lib/lolita/configuration/field/disabled.rb +10 -0
  23. data/lib/lolita/configuration/field/integer.rb +10 -0
  24. data/lib/lolita/configuration/field/password.rb +10 -0
  25. data/lib/lolita/configuration/field/string.rb +11 -0
  26. data/lib/lolita/configuration/field/text.rb +10 -0
  27. data/lib/lolita/configuration/tab.rb +5 -25
  28. data/lib/lolita/configuration/tab/default.rb +24 -0
  29. data/lib/lolita/configuration/tabs.rb +7 -3
  30. data/lib/lolita/controllers/component_helpers.rb +16 -1
  31. data/lib/lolita/errors.rb +2 -0
  32. data/lib/lolita/mapping.rb +17 -4
  33. data/lib/lolita/modules/rest.rb +1 -1
  34. data/lib/lolita/rails/routes.rb +21 -12
  35. data/lolita.gemspec +15 -5
  36. data/public/javascripts/lolita/main.js +7 -6
  37. data/public/javascripts/lolita/tab.js +36 -36
  38. data/spec/configuration/field_spec.rb +3 -3
  39. data/spec/configuration/tab_spec.rb +2 -2
  40. data/spec/configuration/tabs_spec.rb +7 -0
  41. data/spec/rails_app/public/javascripts/lolita/tab.js +36 -36
  42. data/spec/rails_app/public/javascripts/rails.js +137 -137
  43. metadata +16 -6
  44. 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
- lolita_accessor :name,:title,:field_set,:nested_for,:options, :html_options,:record
29
- attr_reader :dbi,:nested_in,:association_type
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
- self.set_attributes(*args)
34
- self.instance_eval(&block) if block_given?
35
- set_default_values
36
- validate
37
- end
38
-
39
- def type(value=nil)
40
- @type=value if value
41
- add_extension unless @extension_added
42
- @type
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 add_extension #TODO test
121
- @extension_added=true
119
+ def set_default_values
122
120
  set_association
123
- refactor_type
124
- set_association_type
125
- self.extend("Lolita::Configuration::FieldExtensions::#{@type.camelize}".constantize) rescue nil
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 set_association_type #TODO test
126
+ def set_type
127
+ @type=@type.to_s.downcase if @type
146
128
  if @association
147
- @association_type=@dbi.association_macro(@association)
129
+ @type="collection"
130
+ elsif @type.nil? || @type.to_s=="object"
131
+ @type=@@default_type
148
132
  end
149
133
  end
150
134
 
151
- def set_default_values
152
- self.title||=self.name.to_s.capitalize
153
- self.type||="string"
154
- self.options||={}
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
@@ -0,0 +1,10 @@
1
+ module Lolita
2
+ module Configuration
3
+ class BooleanField < Lolita::Configuration::Field
4
+ def initialize *args
5
+ @type="boolean"
6
+ super
7
+ end
8
+ end
9
+ end
10
+ end
@@ -1,18 +1,19 @@
1
1
  module Lolita
2
2
  module Configuration
3
- # Field Extensions is used to extend Field instances. FieldExtensions allow
4
- # different field types have same property with different functionality. For
5
- # example, <code>:find_options</code>, it is possible to avoid <code>order</code>
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
- lolita_accessor :conditions,:text_method,:value_method,:find_options
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 @association
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
- Can't find any content field in #{assoc_dbi.klass}.
49
- Use text_method in #{klass} to set one.
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
@@ -0,0 +1,10 @@
1
+ module Lolita
2
+ module Configuration
3
+ class DatetimeField < Lolita::Configuration::Field
4
+ def initialize *args
5
+ @type="datetime"
6
+ super
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Lolita
2
+ module Configuration
3
+ class DisabledField < Lolita::Configuration::Field
4
+ def initialize *args
5
+ @type="disabled"
6
+ super
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Lolita
2
+ module Configuration
3
+ class IntegerField < Lolita::Configuration::Field
4
+ def initialize *args
5
+ @type="integer"
6
+ super
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Lolita
2
+ module Configuration
3
+ class PasswordField < Lolita::Configuration::Field
4
+ def initialize *args
5
+ @type="password"
6
+ super
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ module Lolita
2
+ module Configuration
3
+ class StringField < Lolita::Configuration::Field
4
+
5
+ def initialize *args, &block
6
+ @type="string"
7
+ super
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ module Lolita
2
+ module Configuration
3
+ class TextField < Lolita::Configuration::Field
4
+ def initialize *args
5
+ @type="text"
6
+ super
7
+ end
8
+ end
9
+ end
10
+ 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.new(self.current_dbi,*args,&block)
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 @type!=:default && @fields.empty?
157
+ default_fields if @fields.empty?
175
158
  end
176
159
 
177
160
  def set_default_attributes
178
- @type=:default unless @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.is_a?(Array)
36
+ if values.respond_to?(:each)
33
37
  values.each{|tab|
34
38
  self<<tab
35
39
  }
36
40
  else
37
- raise ArgumentError, "Tabs must be specified as Array."
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.new(@dbi,type.to_sym)
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
- return render(:partial=>"/components/#{name}#{state ? "/#{state}" : nil}",:locals=>@opts)
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"