netzke-basepack 0.3.1 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +22 -0
- data/Manifest +6 -4
- data/README.rdoc +2 -2
- data/Rakefile +1 -1
- data/generators/netzke_form_panel/templates/create_netzke_form_panel_fields.rb +5 -6
- data/generators/netzke_grid_panel/templates/create_netzke_grid_panel_columns.rb +2 -1
- data/javascripts/basepack.js +2 -0
- data/lib/app/models/netzke_form_panel_field.rb +35 -3
- data/lib/app/models/netzke_grid_panel_column.rb +39 -2
- data/lib/netzke-basepack.rb +0 -1
- data/lib/netzke/accordion_panel.rb +51 -15
- data/lib/netzke/ar_ext.rb +14 -6
- data/lib/netzke/basic_app.rb +5 -5
- data/lib/netzke/border_layout_panel.rb +19 -4
- data/lib/netzke/container.rb +2 -6
- data/lib/netzke/db_fields.rb +40 -0
- data/lib/netzke/fields_configurator.rb +10 -18
- data/lib/netzke/form_panel.rb +42 -128
- data/lib/netzke/form_panel_extras/interface.rb +49 -0
- data/lib/netzke/form_panel_extras/js_builder.rb +131 -0
- data/lib/netzke/grid_panel.rb +20 -12
- data/lib/netzke/grid_panel_extras/interface.rb +181 -0
- data/lib/netzke/grid_panel_extras/js_builder.rb +322 -0
- data/lib/netzke/table_editor.rb +110 -0
- data/lib/netzke/wrapper.rb +1 -3
- data/netzke-basepack.gemspec +8 -8
- data/test/app_root/db/migrate/20090102223811_create_netzke_grid_panel_columns.rb +3 -1
- data/test/border_layout_panel_test.rb +8 -12
- data/test/grid_panel_test.rb +3 -3
- data/test/test_helper.rb +8 -0
- metadata +15 -11
- data/lib/netzke/column.rb +0 -50
- data/lib/netzke/grid_panel_interface.rb +0 -167
- data/lib/netzke/grid_panel_js_builder.rb +0 -298
- data/test/column_test.rb +0 -27
data/CHANGELOG
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
v0.3.3
|
2
|
+
Bug fix: application not loading the widget specified in the URL (Ext.History-related).
|
3
|
+
Some code refactoring and readability improvements.
|
4
|
+
Ext.componentCache renamed into Ext.netzke.cache.
|
5
|
+
New widget: TableEditor (a compound widget containing a grid and a form for editing table data).
|
6
|
+
BorderLayoutPanel: a function getRegionWidget(region) added to access a widget in the specified region.
|
7
|
+
Bug fix: BasicApp: FeedbackGhost now gets instantiated before BasicApp.
|
8
|
+
Clearer handling of requests to non-existing aggregatees.
|
9
|
+
Bug fix: now Ext 2.2.1 compatible.
|
10
|
+
Column operations are now handled properly when :persistent_layout is set to false.
|
11
|
+
Grid/Form fields configuration is extended with "ext_config" field which stores (in JSON-format) all the extra configuration, which gives extra flexibility to individual column/field configuration.
|
12
|
+
:persistent_layout set to false now makes a widget ignore what's in the DB.
|
13
|
+
Bug fix: AccordionPanel doesn't crash when no active item is specified.
|
14
|
+
Bug fix: redundant flash messages for GridPanel.
|
15
|
+
FeedbackGhost won't be showing anything if given an empty array.
|
16
|
+
Cleaner handling of validations in GridPanel.
|
17
|
+
FormPanel ready for the demo.
|
18
|
+
|
19
|
+
v0.3.2
|
20
|
+
Minor code restructuring.
|
21
|
+
Working on FormPanel cont'd.
|
22
|
+
|
1
23
|
v0.3.1
|
2
24
|
Added the "conditions" configuration option to GridPanel to limit the search
|
3
25
|
Basic column editor for grids has been replaced with FieldsConfigurator, which can do a bit more
|
data/Manifest
CHANGED
@@ -17,17 +17,20 @@ lib/netzke/accordion_panel.rb
|
|
17
17
|
lib/netzke/ar_ext.rb
|
18
18
|
lib/netzke/basic_app.rb
|
19
19
|
lib/netzke/border_layout_panel.rb
|
20
|
-
lib/netzke/column.rb
|
21
20
|
lib/netzke/container.rb
|
21
|
+
lib/netzke/db_fields.rb
|
22
22
|
lib/netzke/fields_configurator.rb
|
23
23
|
lib/netzke/form_panel.rb
|
24
|
+
lib/netzke/form_panel_extras/interface.rb
|
25
|
+
lib/netzke/form_panel_extras/js_builder.rb
|
24
26
|
lib/netzke/grid_panel.rb
|
25
|
-
lib/netzke/
|
26
|
-
lib/netzke/
|
27
|
+
lib/netzke/grid_panel_extras/interface.rb
|
28
|
+
lib/netzke/grid_panel_extras/js_builder.rb
|
27
29
|
lib/netzke/panel.rb
|
28
30
|
lib/netzke/preference_grid.rb
|
29
31
|
lib/netzke/properties_tool.rb
|
30
32
|
lib/netzke/property_grid.rb
|
33
|
+
lib/netzke/table_editor.rb
|
31
34
|
lib/netzke/wrapper.rb
|
32
35
|
lib/netzke-basepack.rb
|
33
36
|
LICENSE
|
@@ -66,7 +69,6 @@ test/app_root/vendor/plugins/acts_as_list/lib/active_record/acts/list.rb
|
|
66
69
|
test/app_root/vendor/plugins/acts_as_list/README
|
67
70
|
test/ar_ext_test.rb
|
68
71
|
test/border_layout_panel_test.rb
|
69
|
-
test/column_test.rb
|
70
72
|
test/console_with_fixtures.rb
|
71
73
|
test/fixtures/books.yml
|
72
74
|
test/fixtures/categories.yml
|
data/README.rdoc
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
= netzke-basepack
|
2
|
-
A pack of basic Rails/
|
2
|
+
A pack of basic Rails/ExtJS widgets as a part of the Netzke framework. Live demo/tutorials on http://blog.writelesscode.com. Introduction to the Netzke framework: http://github.com/skozlov/netzke/tree/master
|
3
3
|
|
4
4
|
Note that if you would like to modify this code or experiment with it, you may be better off cloning this project into your app's vendor/plugin directory - it will then behave as a Rails plugin.
|
5
5
|
|
@@ -84,4 +84,4 @@ TODO: this part will be covered later
|
|
84
84
|
= Credentials
|
85
85
|
Testing done with the help of http://github.com/pluginaweek/plugin_test_helper
|
86
86
|
|
87
|
-
Copyright (c) 2009 Sergei Kozlov, released under the MIT license
|
87
|
+
Copyright (c) 2008-2009 Sergei Kozlov, released under the MIT license
|
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ Echoe.new("netzke-basepack") do |p|
|
|
5
5
|
p.email = "sergei@writelesscode.com"
|
6
6
|
p.summary = "Base Netzke widgets - grid, form, tree, and more"
|
7
7
|
p.url = "http://writelesscode.com"
|
8
|
-
p.runtime_dependencies = ["searchlogic >=1.6.2", "netzke-core >= 0.2.
|
8
|
+
p.runtime_dependencies = ["searchlogic >=1.6.2", "netzke-core >= 0.2.6"]
|
9
9
|
p.development_dependencies = []
|
10
10
|
p.test_pattern = 'test/**/*_test.rb'
|
11
11
|
|
@@ -2,14 +2,13 @@ class CreateNetzkeFormPanelFields < ActiveRecord::Migration
|
|
2
2
|
def self.up
|
3
3
|
create_table :netzke_form_panel_fields do |t|
|
4
4
|
t.string :name
|
5
|
-
t.string :
|
6
|
-
t.boolean :read_only
|
7
|
-
t.integer :position
|
5
|
+
t.string :field_label
|
8
6
|
t.boolean :hidden
|
9
|
-
t.
|
10
|
-
t.
|
11
|
-
t.string :
|
7
|
+
t.boolean :disabled
|
8
|
+
t.string :xtype
|
9
|
+
t.string :ext_config, :limit => 1024
|
12
10
|
|
11
|
+
t.integer :position
|
13
12
|
t.integer :layout_id
|
14
13
|
|
15
14
|
t.timestamps
|
@@ -4,12 +4,13 @@ class CreateNetzkeGridPanelColumns < ActiveRecord::Migration
|
|
4
4
|
t.string :name
|
5
5
|
t.string :label
|
6
6
|
t.boolean :read_only
|
7
|
-
t.integer :position
|
8
7
|
t.boolean :hidden
|
9
8
|
t.integer :width
|
10
9
|
t.string :editor, :limit => 32
|
11
10
|
t.string :renderer, :limit => 32
|
11
|
+
t.string :ext_config, :limit => 1024
|
12
12
|
|
13
|
+
t.integer :position
|
13
14
|
t.integer :layout_id
|
14
15
|
|
15
16
|
t.timestamps
|
data/javascripts/basepack.js
CHANGED
@@ -3,16 +3,48 @@ class NetzkeFormPanelField < ActiveRecord::Base
|
|
3
3
|
|
4
4
|
acts_as_list :scope => :layout
|
5
5
|
|
6
|
+
validate :valid_ext_config
|
7
|
+
|
8
|
+
expose_columns :id,
|
9
|
+
:name,
|
10
|
+
:field_label,
|
11
|
+
:hidden,
|
12
|
+
{:name => :disabled, :renderer => "checkbox"},
|
13
|
+
:ext_config
|
14
|
+
|
15
|
+
|
6
16
|
def self.create_layout_for_widget(widget)
|
7
|
-
layout = NetzkeLayout.
|
17
|
+
layout = NetzkeLayout.create_with_user(:widget_name => widget.id_name, :items_class => self.name)
|
8
18
|
|
9
|
-
columns =
|
19
|
+
columns = widget.default_db_fields
|
10
20
|
|
11
21
|
for c in columns
|
12
22
|
config_for_create = c.merge(:layout_id => layout.id).stringify_values!
|
13
|
-
|
23
|
+
new_field = self.new
|
24
|
+
ext_config = {}
|
25
|
+
for k in config_for_create.keys
|
26
|
+
if new_field.respond_to?("#{k}=")
|
27
|
+
new_field.send("#{k}=", config_for_create[k])
|
28
|
+
else
|
29
|
+
ext_config[k] = config_for_create[k]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
new_field.ext_config = ext_config.to_js
|
33
|
+
new_field.save!
|
14
34
|
end
|
15
35
|
|
16
36
|
layout
|
17
37
|
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def valid_ext_config
|
42
|
+
begin
|
43
|
+
JSON.parse(ext_config)
|
44
|
+
rescue
|
45
|
+
errors.add(:ext_config, "is not valid JSON")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
18
50
|
end
|
@@ -3,15 +3,52 @@ class NetzkeGridPanelColumn < ActiveRecord::Base
|
|
3
3
|
|
4
4
|
acts_as_list :scope => :layout
|
5
5
|
|
6
|
+
validate :valid_ext_config
|
7
|
+
|
8
|
+
expose_columns :id,
|
9
|
+
:name,
|
10
|
+
:label,
|
11
|
+
{:name => :read_only, :label => "R/O"},
|
12
|
+
:hidden,
|
13
|
+
{:name => :width, :width => 50},
|
14
|
+
{:name => :editor, :editor => :combo_box},
|
15
|
+
{:name => :renderer, :editor => :combo_box},
|
16
|
+
:ext_config
|
17
|
+
|
6
18
|
def self.create_layout_for_widget(widget)
|
7
19
|
layout = NetzkeLayout.create_with_user(:widget_name => widget.id_name, :items_class => self.name)
|
8
|
-
columns =
|
20
|
+
columns = widget.default_db_fields
|
9
21
|
|
10
22
|
for c in columns
|
11
23
|
config_for_create = c.merge(:layout_id => layout.id).stringify_values!
|
12
|
-
|
24
|
+
new_field = self.new
|
25
|
+
ext_config = {}
|
26
|
+
for k in config_for_create.keys
|
27
|
+
if new_field.respond_to?("#{k}=")
|
28
|
+
new_field.send("#{k}=", config_for_create[k])
|
29
|
+
else
|
30
|
+
ext_config[k] = config_for_create[k]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
new_field.ext_config = ext_config.to_js
|
35
|
+
new_field.save!
|
36
|
+
|
37
|
+
# config_for_create = c.merge(:layout_id => layout.id).stringify_values!
|
38
|
+
# create(config_for_create)
|
13
39
|
end
|
14
40
|
|
15
41
|
layout
|
16
42
|
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def valid_ext_config
|
47
|
+
begin
|
48
|
+
JSON.parse(ext_config)
|
49
|
+
rescue
|
50
|
+
errors.add(:ext_config, "is not valid JSON")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
17
54
|
end
|
data/lib/netzke-basepack.rb
CHANGED
@@ -20,7 +20,6 @@ end
|
|
20
20
|
Netzke::Base.config[:javascripts] << "#{File.dirname(__FILE__)}/../javascripts/basepack.js"
|
21
21
|
Netzke::Base.config[:javascripts] << "#{File.dirname(__FILE__)}/../javascripts/check_column.js"
|
22
22
|
|
23
|
-
# TODO: implement configurable loading of JS, to spare the traffic at the initial loading
|
24
23
|
extjs_dir = "#{RAILS_ROOT}/public/extjs"
|
25
24
|
|
26
25
|
# Filters in GridPanel
|
@@ -1,15 +1,26 @@
|
|
1
1
|
module Netzke
|
2
|
+
#
|
3
|
+
# AccordionPanel
|
4
|
+
#
|
5
|
+
# Features:
|
6
|
+
# * Dynamically loads widgets for the panels that get expanded for the first time
|
7
|
+
# * Gets loaded along with the widget that is to be put into the active (expanded) panel (saves us a server request)
|
8
|
+
#
|
9
|
+
# TODO:
|
10
|
+
# * Stores the last active panel in the persistent_configuration
|
11
|
+
#
|
2
12
|
class AccordionPanel < Base
|
3
13
|
#
|
4
14
|
# JS-class generation
|
5
15
|
#
|
6
|
-
|
16
|
+
module ClassMethods
|
7
17
|
|
8
18
|
def js_default_config
|
9
19
|
super.merge({
|
10
20
|
:layout => 'accordion',
|
21
|
+
:defaults => {:layout => 'fit'}, # all items will be of type Panel with layout 'fit'
|
11
22
|
:listeners => {
|
12
|
-
# every item gets an expand event
|
23
|
+
# every item gets an expand event set, which dynamically loads a widget into this item
|
13
24
|
:add => {
|
14
25
|
:fn => <<-JS.l
|
15
26
|
function(self, comp){
|
@@ -26,19 +37,50 @@ module Netzke
|
|
26
37
|
# loads widget into the panel if it wasn't loaded yet
|
27
38
|
:load_item_widget => <<-JS.l,
|
28
39
|
function(panel) {
|
29
|
-
if (!panel.getWidget()) panel.loadWidget(this.id + "__" + panel.
|
40
|
+
if (!panel.getWidget()) panel.loadWidget(this.id + "__" + panel.containerFor + "__get_widget");
|
41
|
+
}
|
42
|
+
JS
|
43
|
+
|
44
|
+
:on_widget_load => <<-JS.l
|
45
|
+
function(){
|
46
|
+
// immediately instantiate the active panel
|
47
|
+
var activePanel = this.findById(this.id + "_active");
|
48
|
+
var activeItemConfig = this.initialConfig[this.initialConfig.expandedItem+"Config"];
|
49
|
+
if (activeItemConfig) activePanel.add(new Ext.netzke.cache[activeItemConfig.widgetClassName](activeItemConfig));
|
30
50
|
}
|
31
51
|
JS
|
32
52
|
}
|
33
53
|
end
|
54
|
+
end
|
55
|
+
extend ClassMethods
|
56
|
+
|
57
|
+
# some configuration normalization
|
58
|
+
def initialize(*args)
|
59
|
+
super
|
60
|
+
|
61
|
+
seen_active = false
|
62
|
+
|
63
|
+
config[:items].each_with_index do |item, i|
|
64
|
+
# if some items are provided without names, give them generated names
|
65
|
+
item[:name] ||= "item#{i}"
|
34
66
|
|
67
|
+
# remove duplucated :active configuration
|
68
|
+
if item[:active]
|
69
|
+
item[:active] = nil if seen_active
|
70
|
+
seen_active = true
|
71
|
+
end
|
72
|
+
end
|
35
73
|
end
|
36
74
|
|
37
75
|
def js_config
|
38
|
-
|
76
|
+
expanded_widget_config = config[:items].select{|i| i[:active]}.first
|
77
|
+
super.merge({
|
78
|
+
:items => items,
|
79
|
+
:expanded_item => expanded_widget_config && expanded_widget_config[:name]
|
80
|
+
})
|
39
81
|
end
|
40
82
|
|
41
|
-
# the items are late aggregatees
|
83
|
+
# the items are late aggregatees, besides the ones that are marked "active"
|
42
84
|
def initial_aggregatees
|
43
85
|
res = {}
|
44
86
|
config[:items].each_with_index do |item, i|
|
@@ -48,22 +90,16 @@ module Netzke
|
|
48
90
|
res
|
49
91
|
end
|
50
92
|
|
93
|
+
# configuration for items (fit-panels)
|
51
94
|
def items
|
52
95
|
res = []
|
53
96
|
config[:items].each_with_index do |item, i|
|
54
97
|
item_config = {
|
55
|
-
:id => item[:
|
56
|
-
:title => item[:title] || (item[:name] && item[:name].humanize)
|
57
|
-
:
|
98
|
+
:id => item[:active] && id_name + '_active',
|
99
|
+
:title => item[:title] || (item[:name] && item[:name].humanize),
|
100
|
+
:container_for => item[:name], # to know which fit panel will load which widget
|
58
101
|
:collapsed => !(item[:active] || false)
|
59
102
|
}
|
60
|
-
|
61
|
-
# directly embed the widget in the active panel
|
62
|
-
if item[:active]
|
63
|
-
item_instance = Netzke::Base.instance_by_config(item.merge(:name => "#{id_name}__#{item[:name]}"))
|
64
|
-
item_config[:items] = ["new Ext.componentCache['#{item[:widget_class_name]}'](#{item_instance.js_config.to_js})".l]
|
65
|
-
end
|
66
|
-
|
67
103
|
res << item_config
|
68
104
|
end
|
69
105
|
res
|
data/lib/netzke/ar_ext.rb
CHANGED
@@ -193,13 +193,21 @@ module Netzke
|
|
193
193
|
# detect ActiveRecord column type (if the column is "real") or fall back to :virtual
|
194
194
|
type = (columns_hash[config[:name].to_s] && columns_hash[config[:name].to_s].type) || :virtual
|
195
195
|
|
196
|
-
|
197
|
-
:
|
198
|
-
:
|
199
|
-
:
|
200
|
-
# :hidden => config[:name] == :id, # hide "id" column by default
|
201
|
-
:xtype => XTYPE_MAP[type]
|
196
|
+
defaults = {
|
197
|
+
:field_label => config[:name].to_s.gsub('__', '_').humanize,
|
198
|
+
:xtype => XTYPE_MAP[type],
|
199
|
+
:hidden => config[:name] == :id
|
202
200
|
}
|
201
|
+
|
202
|
+
res = defaults.merge(config)
|
203
|
+
|
204
|
+
# res = {
|
205
|
+
# :name => config[:name].to_s || "unnamed",
|
206
|
+
# :field_label => config[:field_label] || config[:name].to_s.gsub('__', '_').humanize,
|
207
|
+
# # :disabled => config[:name] == :id, # make "id" column disabled by default
|
208
|
+
# # :hidden => config[:name] == :id, # hide "id" column by default
|
209
|
+
# :xtype => XTYPE_MAP[type]
|
210
|
+
# }
|
203
211
|
|
204
212
|
end
|
205
213
|
|
data/lib/netzke/basic_app.rb
CHANGED
@@ -96,8 +96,6 @@ module Netzke
|
|
96
96
|
// Initialize menus (upcoming support for dynamically loaded menus)
|
97
97
|
this.menus = {};
|
98
98
|
|
99
|
-
// Initialize history
|
100
|
-
Ext.History.init();
|
101
99
|
Ext.History.on('change', this.processHistory, this);
|
102
100
|
|
103
101
|
// If we are given a token, load the corresponding widget, otherwise load the last loaded widget
|
@@ -168,9 +166,11 @@ module Netzke
|
|
168
166
|
|
169
167
|
# Besides instantiating ourselves, also instantiate the FeedbackGhost
|
170
168
|
def js_widget_instance
|
171
|
-
|
172
|
-
new Ext.
|
173
|
-
|
169
|
+
%Q{
|
170
|
+
new Ext.netzke.cache['FeedbackGhost']({id:'feedback_ghost'})
|
171
|
+
// Initialize history (can't say why it's not working well inside the appLoaded handler)
|
172
|
+
Ext.History.init();
|
173
|
+
} << super
|
174
174
|
end
|
175
175
|
|
176
176
|
# Interface implementation
|
@@ -7,7 +7,7 @@ module Netzke
|
|
7
7
|
#
|
8
8
|
# JS-class generation
|
9
9
|
#
|
10
|
-
|
10
|
+
module ClassMethods
|
11
11
|
def js_listeners
|
12
12
|
{
|
13
13
|
:afterlayout => {:fn => "this.setResizeEvents".l, :scope => this}
|
@@ -23,8 +23,17 @@ module Netzke
|
|
23
23
|
var regionConfig = config.regions[r] || {};
|
24
24
|
regionConfig.layout = 'fit';
|
25
25
|
regionConfig.region = r;
|
26
|
-
regionConfig.items = [new Ext.
|
26
|
+
regionConfig.items = [new Ext.netzke.cache[config[configName].widgetClassName](config[configName])]
|
27
27
|
items.push(regionConfig);
|
28
|
+
|
29
|
+
// A function to access a region widget (even if the widget gets reloaded, the function will work).
|
30
|
+
// E.g.: getEastWidget()
|
31
|
+
// I love JavaScript
|
32
|
+
this['get'+r.capitalize()+'Widget'] = function(){
|
33
|
+
return this.find('region', r)[0].getWidget()
|
34
|
+
}.createDelegate(this)
|
35
|
+
|
36
|
+
|
28
37
|
};
|
29
38
|
}, this)
|
30
39
|
JS
|
@@ -38,7 +47,13 @@ module Netzke
|
|
38
47
|
end
|
39
48
|
|
40
49
|
def js_extend_properties
|
41
|
-
{
|
50
|
+
{
|
51
|
+
:get_region_widget => <<-JS.l,
|
52
|
+
function(region){
|
53
|
+
return this.find('region', region)[0].getWidget()
|
54
|
+
}
|
55
|
+
JS
|
56
|
+
:set_resize_events => <<-JS.l,
|
42
57
|
function(){
|
43
58
|
this.items.each(function(item, index, length){
|
44
59
|
if (!item.oldSize) item.oldSize = item.getSize();
|
@@ -68,8 +83,8 @@ module Netzke
|
|
68
83
|
JS
|
69
84
|
}
|
70
85
|
end
|
71
|
-
|
72
86
|
end
|
87
|
+
extend ClassMethods
|
73
88
|
|
74
89
|
def initial_aggregatees
|
75
90
|
config[:regions] || {}
|