netzke-basepack 0.3.1 → 0.3.3
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.
- 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] || {}
|