netzke-basepack 0.5.8 → 0.5.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/CHANGELOG.rdoc +18 -0
  2. data/README.rdoc +11 -4
  3. data/Rakefile +19 -3
  4. data/TODO.rdoc +1 -1
  5. data/generators/netzke_basepack/netzke_basepack_generator.rb +13 -0
  6. data/generators/netzke_basepack/templates/create_netzke_field_lists.rb +18 -0
  7. data/generators/netzke_basepack/templates/public_assets/ts-checkbox.gif +0 -0
  8. data/install.rb +1 -1
  9. data/javascripts/basepack.js +124 -30
  10. data/lib/app/models/netzke_field_list.rb +261 -0
  11. data/lib/app/models/netzke_model_attr_list.rb +21 -0
  12. data/lib/app/models/netzke_persistent_array_auto_model.rb +58 -0
  13. data/lib/netzke-basepack.rb +17 -2
  14. data/lib/netzke/active_record.rb +10 -0
  15. data/lib/netzke/active_record/association_attributes.rb +102 -0
  16. data/lib/netzke/active_record/attributes.rb +100 -0
  17. data/lib/netzke/active_record/combobox_options.rb +43 -0
  18. data/lib/netzke/active_record/data_accessor.rb +9 -12
  19. data/lib/netzke/attributes_configurator.rb +195 -0
  20. data/lib/netzke/basic_app.rb +47 -4
  21. data/lib/netzke/configuration_panel.rb +1 -1
  22. data/lib/netzke/data_accessor.rb +7 -30
  23. data/lib/netzke/fields_configurator.rb +106 -41
  24. data/lib/netzke/form_panel.rb +28 -125
  25. data/lib/netzke/form_panel/form_panel_api.rb +2 -3
  26. data/lib/netzke/form_panel/form_panel_fields.rb +147 -0
  27. data/lib/netzke/form_panel/form_panel_js.rb +35 -15
  28. data/lib/netzke/grid_panel.rb +130 -213
  29. data/lib/netzke/grid_panel/grid_panel_api.rb +254 -257
  30. data/lib/netzke/grid_panel/grid_panel_columns.rb +226 -0
  31. data/lib/netzke/grid_panel/grid_panel_js.rb +126 -119
  32. data/lib/netzke/grid_panel/record_form_window.rb +7 -1
  33. data/lib/netzke/json_array_editor.rb +61 -0
  34. data/lib/netzke/plugins/configuration_tool.rb +1 -1
  35. data/lib/netzke/property_editor.rb +3 -3
  36. data/lib/netzke/search_panel.rb +164 -27
  37. data/lib/netzke/tab_panel.rb +14 -12
  38. data/stylesheets/basepack.css +43 -2
  39. data/test/app_root/app/models/book.rb +1 -1
  40. data/test/app_root/app/models/role.rb +3 -0
  41. data/test/app_root/app/models/user.rb +3 -0
  42. data/test/app_root/config/database.yml +1 -1
  43. data/test/app_root/db/migrate/20090102223630_create_netzke_field_lists.rb +18 -0
  44. data/test/app_root/db/migrate/20090423214303_create_roles.rb +11 -0
  45. data/test/app_root/db/migrate/20090423222114_create_users.rb +12 -0
  46. data/test/fixtures/books.yml +4 -2
  47. data/test/fixtures/categories.yml +2 -2
  48. data/test/fixtures/genres.yml +6 -6
  49. data/test/fixtures/roles.yml +8 -0
  50. data/test/fixtures/users.yml +11 -0
  51. data/test/test_helper.rb +2 -0
  52. data/test/unit/active_record_basepack_test.rb +2 -2
  53. data/test/unit/fields_configuration_test.rb +18 -0
  54. data/test/unit/grid_panel_test.rb +29 -27
  55. metadata +41 -16
  56. data/lib/app/models/netzke_auto_column.rb +0 -4
  57. data/lib/app/models/netzke_auto_field.rb +0 -4
  58. data/lib/app/models/netzke_auto_table.rb +0 -61
  59. data/lib/netzke/active_record/basepack.rb +0 -134
  60. data/lib/netzke/grid_panel/javascripts/filters.js +0 -7
  61. data/test/app_root/db/migrate/20090102223630_create_netzke_layouts.rb +0 -14
  62. data/test/unit/helper_model_test.rb +0 -30
@@ -1,4 +0,0 @@
1
- class NetzkeAutoColumn < NetzkeAutoTable
2
- acts_as_list
3
- default_scope :order => "position"
4
- end
@@ -1,4 +0,0 @@
1
- class NetzkeAutoField < NetzkeAutoTable
2
- acts_as_list
3
- default_scope :order => "position"
4
- end
@@ -1,61 +0,0 @@
1
- require 'acts_as_list'
2
-
3
- class NetzkeAutoTable < ActiveRecord::Base
4
-
5
- # Returns an array of column configuration hashes (without the "id" attribute)
6
- def self.all_columns
7
- self.all.map do |c|
8
- column_hash = c.attributes.reject{ |k,v| k == 'id' }
9
- column_hash.each_pair do |k,v|
10
- # try to detect JSON format
11
- begin
12
- normalized_value = v.is_a?(String) ? ActiveSupport::JSON.decode(v) : v
13
- rescue ActiveSupport::JSON::ParseError
14
- normalized_value = v
15
- end
16
- column_hash[k] = normalized_value
17
- end
18
- column_hash
19
- end
20
- end
21
-
22
- # Build the table with columns for this widget
23
- def self.rebuild_table
24
- connection.drop_table(table_name) if table_exists?
25
-
26
- normalized_config_columns = []
27
-
28
- widget = read_inheritable_attribute(:widget)
29
-
30
- widget.class.config_columns.each do |mc|
31
- column_hash = mc.is_a?(Symbol) ? {:name => mc} : mc
32
- column_hash[:type] ||= :string
33
- normalized_config_columns << column_hash
34
- end
35
-
36
- # create the table with the fields
37
- self.connection.create_table(table_name) do |t|
38
- normalized_config_columns.each do |mc|
39
- t.column mc[:name], mc[:type], :default => mc[:default]
40
- end
41
- t.column :position, :integer
42
- end
43
-
44
- # populate the table with data
45
- create widget.normalized_columns.map(&:deebeefy_values) # rescue ActiveRecord::UnknownAttributeError
46
-
47
- end
48
-
49
- def self.table_name
50
- self.name.tableize
51
- end
52
-
53
- def self.widget=(widget)
54
- write_inheritable_attribute(:widget, widget)
55
- if Netzke::Base.session["#{table_name}_last_widget"] != widget.global_id
56
- rebuild_table
57
- Netzke::Base.session["#{table_name}_last_widget"] = widget.global_id
58
- end
59
- end
60
-
61
- end
@@ -1,134 +0,0 @@
1
- require "activerecord"
2
-
3
- module Netzke::ActiveRecord
4
- # Provides extensions to all ActiveRecord-based classes
5
- module Basepack
6
- def self.included(base)
7
- base.alias_method_chain :method_missing, :basepack
8
- base.alias_method_chain :respond_to?, :basepack
9
- base.extend ClassMethods
10
- end
11
-
12
- # Allow nested association access (assocs separated by "." or "__"), e.g.: proxy_service.asset__gui_folder__name
13
- # Example:
14
- #
15
- # Book.first.genre__name = 'Fantasy'
16
- #
17
- # is the same as:
18
- #
19
- # Book.first.genre = Genre.find_by_name('Fantasy')
20
- #
21
- # The result - easier forms and grids that handle nested models: simply specify column/field name as "genre__name".
22
- def method_missing_with_basepack(method, *args, &block)
23
- # if refering to a column, just pass it to the original method_missing
24
- return method_missing_without_basepack(method, *args, &block) if self.class.column_names.include?(method.to_s)
25
-
26
- split = method.to_s.split(/\.|__/)
27
- if split.size > 1
28
- if split.last =~ /=$/
29
- if split.size == 2
30
- # search for association and assign it to self
31
- assoc = self.class.reflect_on_association(split.first.to_sym)
32
- assoc_method = split.last.chop
33
- if assoc
34
- begin
35
- assoc_instance = assoc.klass.send("find_by_#{assoc_method}", *args)
36
- rescue NoMethodError
37
- assoc_instance = nil
38
- logger.debug "!!! no find_by_#{assoc_method} method for class #{assoc.klass.name}\n"
39
- end
40
- if (assoc_instance)
41
- self.send("#{split.first}=", assoc_instance)
42
- else
43
- logger.debug "!!! Couldn't find association #{split.first} by #{assoc_method} '#{args.first}'"
44
- end
45
- else
46
- method_missing_without_basepack(method, *args, &block)
47
- end
48
- else
49
- method_missing_without_basepack(method, *args, &block)
50
- end
51
- else
52
- res = self
53
- split.each do |m|
54
- if res.respond_to?(m)
55
- res = res.send(m) unless res.nil?
56
- else
57
- res.nil? ? nil : method_missing_without_basepack(method, *args, &block)
58
- end
59
- end
60
- res
61
- end
62
- else
63
- method_missing_without_basepack(method, *args, &block)
64
- end
65
- end
66
-
67
- # Make respond_to? return true for association assignment method, like "genre__name="
68
- def respond_to_with_basepack?(method, include_private = false)
69
- split = method.to_s.split(/__/)
70
- if split.size > 1
71
- if split.last =~ /=$/
72
- if split.size == 2
73
- # search for association and assign it to self
74
- assoc = self.class.reflect_on_association(split.first.to_sym)
75
- assoc_method = split.last.chop
76
- if assoc
77
- assoc.klass.respond_to?("find_by_#{assoc_method}")
78
- else
79
- respond_to_without_basepack?(method, include_private)
80
- end
81
- else
82
- respond_to_without_basepack?(method, include_private)
83
- end
84
- else
85
- # self.respond_to?(split.first) ? self.send(split.first).respond_to?(split[1..-1].join("__")) : false
86
- respond_to_without_basepack?(method, include_private)
87
- end
88
- else
89
- respond_to_without_basepack?(method, include_private)
90
- end
91
- end
92
-
93
- module ClassMethods
94
-
95
- def options_for(column, query = "")
96
- # First, check if we have options for this class and column defined in persistent storage
97
- NetzkePreference.widget_name = self.name
98
- options = NetzkePreference[:combobox_options] || {}
99
- if options[column]
100
- options[column].select{ |o| o.index(/^#{query}/) }
101
- elsif respond_to?("#{column}_combobox_options")
102
- # AR class provides the choices itself
103
- send("#{column}_combobox_options", query)
104
- else
105
- # Returns all unique values for a column, filtered with <tt>query</tt>
106
- if (assoc_name, *assoc_method = column.split('__')).size > 1
107
- # column is an association column
108
- assoc_method = assoc_method.join('__') # in case we get something like country__continent__name
109
- association = reflect_on_association(assoc_name.to_sym) || raise(NameError, "Association #{assoc_name} not known for class #{name}")
110
- association.klass.options_for(assoc_method, query)
111
- else
112
- column = assoc_name
113
- if self.column_names.include?(column)
114
- # it's simply a column in the table
115
- records = query.empty? ? find_by_sql("select distinct #{column} from #{table_name}") : find_by_sql("select distinct #{column} from #{table_name} where #{column} like '#{query}%'")
116
- records.map{|r| r.send(column)}
117
- else
118
- # it's a "virtual" column - the least effective search
119
- records = self.find(:all).map{|r| r.send(column)}.uniq
120
- query.empty? ? records : records.select{|r| r.index(/^#{query}/)}
121
- end
122
- end
123
- end
124
- end
125
-
126
- end
127
-
128
- end
129
- end
130
-
131
- # Extend ActiveRecord
132
- ActiveRecord::Base.class_eval do
133
- include Netzke::ActiveRecord::Basepack
134
- end
@@ -1,7 +0,0 @@
1
- Ext.menu.RangeMenu.prototype.icons = {
2
- gt: '/extjs/examples/grid-filtering/img/greater_then.png',
3
- lt: '/extjs/examples/grid-filtering/img/less_then.png',
4
- eq: '/extjs/examples/grid-filtering/img/equals.png'
5
- };
6
-
7
- Ext.grid.filter.StringFilter.prototype.icon = '/extjs/examples/grid-filtering/img/find.png';
@@ -1,14 +0,0 @@
1
- class CreateNetzkeLayouts < ActiveRecord::Migration
2
- def self.up
3
- create_table :netzke_layouts do |t|
4
- t.string :widget_name
5
- t.string :items_class
6
- t.integer :user_id
7
- t.timestamps
8
- end
9
- end
10
-
11
- def self.down
12
- drop_table :netzke_layouts
13
- end
14
- end
@@ -1,30 +0,0 @@
1
- require 'test_helper'
2
- require 'rubygems'
3
- require 'netzke-core'
4
-
5
- class HelperModelTest < ActiveSupport::TestCase
6
-
7
- test "reading/writing values" do
8
- Netzke::FormPanel.config.deep_merge!({
9
- :persistent_config => true,
10
- :ext_config => {
11
- :enable_config_tool => true
12
- },
13
- })
14
- form = Netzke::FormPanel.new(:model => "Book")
15
- Netzke::PropertyEditor::HelperModel.widget = form
16
- helper_model = Netzke::PropertyEditor::HelperModel.new
17
-
18
- assert(true, helper_model.ext_config__config_tool)
19
-
20
- assert(true, helper_model.persistent_config)
21
-
22
- assert(true, form.ext_config[:enable_config_tool])
23
-
24
- # now try to change the configuration
25
- helper_model.ext_config__config_tool = "false"
26
- # form = Netzke::FormPanel.new(:model => "Book")
27
- # assert(false, form.ext_config[:enable_config_tool]) # FIXME: make it work
28
- end
29
-
30
- end