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.
- data/CHANGELOG.rdoc +18 -0
- data/README.rdoc +11 -4
- data/Rakefile +19 -3
- data/TODO.rdoc +1 -1
- data/generators/netzke_basepack/netzke_basepack_generator.rb +13 -0
- data/generators/netzke_basepack/templates/create_netzke_field_lists.rb +18 -0
- data/generators/netzke_basepack/templates/public_assets/ts-checkbox.gif +0 -0
- data/install.rb +1 -1
- data/javascripts/basepack.js +124 -30
- data/lib/app/models/netzke_field_list.rb +261 -0
- data/lib/app/models/netzke_model_attr_list.rb +21 -0
- data/lib/app/models/netzke_persistent_array_auto_model.rb +58 -0
- data/lib/netzke-basepack.rb +17 -2
- data/lib/netzke/active_record.rb +10 -0
- data/lib/netzke/active_record/association_attributes.rb +102 -0
- data/lib/netzke/active_record/attributes.rb +100 -0
- data/lib/netzke/active_record/combobox_options.rb +43 -0
- data/lib/netzke/active_record/data_accessor.rb +9 -12
- data/lib/netzke/attributes_configurator.rb +195 -0
- data/lib/netzke/basic_app.rb +47 -4
- data/lib/netzke/configuration_panel.rb +1 -1
- data/lib/netzke/data_accessor.rb +7 -30
- data/lib/netzke/fields_configurator.rb +106 -41
- data/lib/netzke/form_panel.rb +28 -125
- data/lib/netzke/form_panel/form_panel_api.rb +2 -3
- data/lib/netzke/form_panel/form_panel_fields.rb +147 -0
- data/lib/netzke/form_panel/form_panel_js.rb +35 -15
- data/lib/netzke/grid_panel.rb +130 -213
- data/lib/netzke/grid_panel/grid_panel_api.rb +254 -257
- data/lib/netzke/grid_panel/grid_panel_columns.rb +226 -0
- data/lib/netzke/grid_panel/grid_panel_js.rb +126 -119
- data/lib/netzke/grid_panel/record_form_window.rb +7 -1
- data/lib/netzke/json_array_editor.rb +61 -0
- data/lib/netzke/plugins/configuration_tool.rb +1 -1
- data/lib/netzke/property_editor.rb +3 -3
- data/lib/netzke/search_panel.rb +164 -27
- data/lib/netzke/tab_panel.rb +14 -12
- data/stylesheets/basepack.css +43 -2
- data/test/app_root/app/models/book.rb +1 -1
- data/test/app_root/app/models/role.rb +3 -0
- data/test/app_root/app/models/user.rb +3 -0
- data/test/app_root/config/database.yml +1 -1
- data/test/app_root/db/migrate/20090102223630_create_netzke_field_lists.rb +18 -0
- data/test/app_root/db/migrate/20090423214303_create_roles.rb +11 -0
- data/test/app_root/db/migrate/20090423222114_create_users.rb +12 -0
- data/test/fixtures/books.yml +4 -2
- data/test/fixtures/categories.yml +2 -2
- data/test/fixtures/genres.yml +6 -6
- data/test/fixtures/roles.yml +8 -0
- data/test/fixtures/users.yml +11 -0
- data/test/test_helper.rb +2 -0
- data/test/unit/active_record_basepack_test.rb +2 -2
- data/test/unit/fields_configuration_test.rb +18 -0
- data/test/unit/grid_panel_test.rb +29 -27
- metadata +41 -16
- data/lib/app/models/netzke_auto_column.rb +0 -4
- data/lib/app/models/netzke_auto_field.rb +0 -4
- data/lib/app/models/netzke_auto_table.rb +0 -61
- data/lib/netzke/active_record/basepack.rb +0 -134
- data/lib/netzke/grid_panel/javascripts/filters.js +0 -7
- data/test/app_root/db/migrate/20090102223630_create_netzke_layouts.rb +0 -14
- data/test/unit/helper_model_test.rb +0 -30
@@ -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
|