netzke-basepack 0.5.8 → 0.5.9

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 (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