lolita 3.0.5 → 3.0.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.
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"