netzke-basepack 0.1.4.1 → 0.2.0
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 +10 -0
- data/Manifest +13 -8
- data/README.mdown +10 -10
- data/Rakefile +1 -1
- data/css/basepack.css +4 -0
- data/generators/netzke_basepack/netzke_grid_panel_generator.rb +7 -0
- data/generators/netzke_basepack/templates/{create_netzke_grid_columns.rb → create_netzke_grid_panel_columns.rb} +4 -4
- data/javascripts/basepack.js +1 -1
- data/lib/app/models/{netzke_grid_column.rb → netzke_grid_panel_column.rb} +1 -1
- data/lib/netzke-basepack.rb +18 -6
- data/lib/netzke/accordion_panel.rb +73 -0
- data/lib/netzke/ar_ext.rb +51 -25
- data/lib/netzke/border_layout_panel.rb +119 -0
- data/lib/netzke/container.rb +5 -5
- data/lib/netzke/{grid.rb → grid_panel.rb} +30 -25
- data/lib/netzke/{grid_interface.rb → grid_panel_interface.rb} +11 -7
- data/lib/netzke/grid_panel_js_builder.rb +282 -0
- data/lib/netzke/panel.rb +4 -0
- data/lib/netzke/preference_grid.rb +4 -4
- data/lib/netzke/properties_tool.rb +51 -40
- data/lib/netzke/property_grid.rb +3 -3
- data/lib/netzke/wrapper.rb +20 -0
- data/netzke-basepack.gemspec +8 -8
- data/test/app_root/db/migrate/20081222033440_create_genres.rb +1 -0
- data/test/app_root/db/migrate/20081222035855_create_netzke_preferences.rb +1 -1
- data/test/ar_ext_test.rb +10 -2
- data/test/border_layout_panel_test.rb +28 -0
- data/test/{grid_test.rb → grid_panel_test.rb} +5 -4
- data/test/netzke_basepack_test.rb +0 -4
- metadata +26 -17
- data/generators/netzke_basepack/netzke_grid_generator.rb +0 -7
- data/lib/netzke/accordion.rb +0 -11
- data/lib/netzke/grid_js_builder.rb +0 -276
data/lib/netzke/container.rb
CHANGED
@@ -20,7 +20,7 @@ module Netzke
|
|
20
20
|
dep
|
21
21
|
end
|
22
22
|
|
23
|
-
def js_before_constructor
|
23
|
+
def self.js_before_constructor
|
24
24
|
js_widget_items
|
25
25
|
end
|
26
26
|
|
@@ -32,7 +32,7 @@ module Netzke
|
|
32
32
|
config[:items] || []
|
33
33
|
end
|
34
34
|
|
35
|
-
def js_widget_items
|
35
|
+
def self.js_widget_items
|
36
36
|
res = ""
|
37
37
|
item_aggregatees.each_pair do |k,v|
|
38
38
|
next if v[:late_aggregation]
|
@@ -43,7 +43,7 @@ module Netzke
|
|
43
43
|
res
|
44
44
|
end
|
45
45
|
|
46
|
-
def js_items
|
46
|
+
def self.js_items
|
47
47
|
items.inject([]) do |a,i|
|
48
48
|
a << {
|
49
49
|
:title => i.to_s.humanize,
|
@@ -61,7 +61,7 @@ module Netzke
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
-
def js_extend_properties
|
64
|
+
def self.js_extend_properties
|
65
65
|
{
|
66
66
|
# loads widget into the panel if it's not loaded yet
|
67
67
|
:load_item_widget => <<-JS.l,
|
@@ -74,7 +74,7 @@ module Netzke
|
|
74
74
|
end
|
75
75
|
|
76
76
|
protected
|
77
|
-
def item_aggregatees
|
77
|
+
def self.item_aggregatees
|
78
78
|
aggregatees.delete_if{|k,v| !@items.include?(k)}
|
79
79
|
end
|
80
80
|
end
|
@@ -4,42 +4,47 @@ module Netzke
|
|
4
4
|
# Functionality:
|
5
5
|
# * data operations - get, post, delete, create
|
6
6
|
# * column resize and move
|
7
|
+
# * column hide - TODO
|
7
8
|
# * permissions
|
8
9
|
# * sorting
|
9
10
|
# * pagination
|
11
|
+
# * filtering
|
10
12
|
# * properties and column configuration
|
11
13
|
#
|
12
|
-
class
|
13
|
-
include
|
14
|
-
include
|
14
|
+
class GridPanel < Base
|
15
|
+
include GridPanelJsBuilder
|
16
|
+
include GridPanelInterface
|
15
17
|
|
16
|
-
# define connection points between client side and server side of
|
18
|
+
# define connection points between client side and server side of GridPanel. See implementation of equally named methods in the GridPanelInterface module.
|
17
19
|
interface :get_data, :post_data, :delete_data, :resize_column, :move_column, :get_cb_choices
|
18
20
|
|
21
|
+
# default grid configuration
|
19
22
|
def initial_config
|
20
23
|
{
|
21
|
-
:ext_config => {
|
22
|
-
|
23
|
-
|
24
|
-
|
24
|
+
:ext_config => {
|
25
|
+
:config_tool => false,
|
26
|
+
:enable_column_filters => Netzke::Base.config[:grid_panel][:filters],
|
27
|
+
:enable_column_move => true,
|
28
|
+
:enable_column_resize => true,
|
29
|
+
:border => true
|
30
|
+
},
|
31
|
+
:layout_manager => "NetzkeLayout"
|
25
32
|
}
|
26
33
|
end
|
27
34
|
|
28
35
|
def property_widgets
|
29
36
|
[{
|
30
|
-
:
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
}
|
37
|
+
:name => 'columns',
|
38
|
+
:widget_class_name => "GridPanel",
|
39
|
+
:data_class_name => column_manager_class_name,
|
40
|
+
:ext_config => {:title => false, :config_tool => false},
|
41
|
+
:active => true
|
36
42
|
},{
|
37
|
-
:
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
}
|
43
|
+
:name => 'general',
|
44
|
+
:widget_class_name => "PreferenceGrid",
|
45
|
+
:host_widget_name => @id_name,
|
46
|
+
:default_properties => available_permissions.map{ |k| {:name => "permissions.#{k}", :value => @permissions[k.to_sym]}},
|
47
|
+
:ext_config => {:title => false}
|
43
48
|
}]
|
44
49
|
end
|
45
50
|
|
@@ -68,7 +73,7 @@ module Netzke
|
|
68
73
|
end
|
69
74
|
|
70
75
|
def column_manager_class_name
|
71
|
-
"
|
76
|
+
"NetzkeGridPanelColumn"
|
72
77
|
end
|
73
78
|
|
74
79
|
def column_manager_class
|
@@ -101,13 +106,13 @@ module Netzke
|
|
101
106
|
|
102
107
|
def actions
|
103
108
|
[{
|
104
|
-
:text => 'Add', :handler => 'add', :disabled =>
|
109
|
+
:text => 'Add', :handler => 'add', :disabled => !@permissions[:create]
|
105
110
|
},{
|
106
|
-
:text => 'Edit', :handler => 'edit', :disabled =>
|
111
|
+
:text => 'Edit', :handler => 'edit', :disabled => !@permissions[:update]
|
107
112
|
},{
|
108
|
-
:text => 'Delete', :handler => 'delete', :disabled =>
|
113
|
+
:text => 'Delete', :handler => 'delete', :disabled => !@permissions[:delete]
|
109
114
|
},{
|
110
|
-
:text => 'Apply', :handler => 'submit', :disabled =>
|
115
|
+
:text => 'Apply', :handler => 'submit', :disabled => !@permissions[:update] && !@permissions[:create]
|
111
116
|
}]
|
112
117
|
end
|
113
118
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module Netzke::
|
1
|
+
module Netzke::GridPanelInterface
|
2
2
|
def post_data(params)
|
3
3
|
[:create, :update].each do |operation|
|
4
4
|
data = JSON.parse(params.delete("#{operation}d_records".to_sym)) if params["#{operation}d_records".to_sym]
|
@@ -32,16 +32,20 @@ module Netzke::GridInterface
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def resize_column(params)
|
35
|
-
raise "Called interface_resize_column while not configured to do so" unless config[:
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
raise "Called interface_resize_column while not configured to do so" unless config[:ext_config][:enable_column_resize]
|
36
|
+
if layout_manager_class
|
37
|
+
l_item = layout_manager_class.by_widget(id_name).layout_items[params[:index].to_i]
|
38
|
+
l_item.width = params[:size]
|
39
|
+
l_item.save!
|
40
|
+
end
|
39
41
|
{}
|
40
42
|
end
|
41
43
|
|
42
44
|
def move_column(params)
|
43
|
-
raise "Called interface_move_column while not configured to do so" unless config[:
|
44
|
-
layout_manager_class
|
45
|
+
raise "Called interface_move_column while not configured to do so" unless config[:ext_config][:enable_column_move]
|
46
|
+
if layout_manager_class
|
47
|
+
layout_manager_class.by_widget(id_name).move_item(params[:old_index].to_i, params[:new_index].to_i)
|
48
|
+
end
|
45
49
|
{}
|
46
50
|
end
|
47
51
|
|
@@ -0,0 +1,282 @@
|
|
1
|
+
module Netzke::GridPanelJsBuilder
|
2
|
+
def self.included(base)
|
3
|
+
base.extend ClassMethods
|
4
|
+
end
|
5
|
+
|
6
|
+
def js_config
|
7
|
+
res = super
|
8
|
+
# we pass column config at the time of instantiating the JS class
|
9
|
+
res.merge!(:columns => get_columns || config[:columns]) # first try to get columns from DB, then from config
|
10
|
+
res.merge!(:data_class_name => config[:data_class_name])
|
11
|
+
res
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
|
16
|
+
def js_base_class
|
17
|
+
'Ext.grid.EditorGridPanel'
|
18
|
+
end
|
19
|
+
|
20
|
+
def js_bbar
|
21
|
+
<<-JS.l
|
22
|
+
(config.rowsPerPage) ? new Ext.PagingToolbar({
|
23
|
+
pageSize:config.rowsPerPage,
|
24
|
+
items:config.actions,
|
25
|
+
store:ds,
|
26
|
+
emptyMsg:'Empty'}) : config.actions
|
27
|
+
JS
|
28
|
+
end
|
29
|
+
|
30
|
+
def js_default_config
|
31
|
+
super.merge({
|
32
|
+
:store => "ds".l,
|
33
|
+
:cm => "cm".l,
|
34
|
+
:sel_model => "new Ext.grid.RowSelectionModel()".l,
|
35
|
+
:auto_scroll => true,
|
36
|
+
:click_to_edit => 2,
|
37
|
+
:track_mouse_over => true,
|
38
|
+
# :bbar => "config.actions".l,
|
39
|
+
:bbar => js_bbar,
|
40
|
+
:plugins => "plugins".l,
|
41
|
+
|
42
|
+
#custom configs
|
43
|
+
:auto_load_data => true
|
44
|
+
})
|
45
|
+
end
|
46
|
+
|
47
|
+
def js_before_constructor
|
48
|
+
<<-JS
|
49
|
+
var plugins = [];
|
50
|
+
if (!config.columns) this.feedback('No columns defined for grid '+config.id);
|
51
|
+
this.recordConfig = [];
|
52
|
+
Ext.each(config.columns, function(column){this.recordConfig.push({name:column.name})}, this);
|
53
|
+
this.Row = Ext.data.Record.create(this.recordConfig);
|
54
|
+
|
55
|
+
var ds = new Ext.data.Store({
|
56
|
+
proxy: this.proxy = new Ext.data.HttpProxy({url:config.interface.getData}),
|
57
|
+
reader: new Ext.data.ArrayReader({root: "data", totalProperty: "total", successProperty: "succes", id:0}, this.Row),
|
58
|
+
remoteSort: true,
|
59
|
+
listeners:{'loadexception':{
|
60
|
+
fn:this.loadExceptionHandler,
|
61
|
+
scope:this
|
62
|
+
}}
|
63
|
+
});
|
64
|
+
|
65
|
+
this.cmConfig = [];
|
66
|
+
Ext.each(config.columns, function(c){
|
67
|
+
var editor = (c.readOnly || !config.permissions.update) ? null : Ext.netzke.editors[c.editor](c, config);
|
68
|
+
|
69
|
+
this.cmConfig.push({
|
70
|
+
header: c.label || c.name,
|
71
|
+
dataIndex: c.name,
|
72
|
+
hidden: c.hidden,
|
73
|
+
width: c.width,
|
74
|
+
editor: editor,
|
75
|
+
sortable: true
|
76
|
+
})
|
77
|
+
}, this);
|
78
|
+
|
79
|
+
var cm = new Ext.grid.ColumnModel(this.cmConfig);
|
80
|
+
|
81
|
+
this.addEvents("refresh");
|
82
|
+
|
83
|
+
// Filters
|
84
|
+
if (config.enableColumnFilters) {
|
85
|
+
var filters = []
|
86
|
+
Ext.each(config.columns, function(c){
|
87
|
+
filters.push({type:Ext.netzke.filterMap[c.editor], dataIndex:c.name})
|
88
|
+
})
|
89
|
+
var gridFilters = new Ext.grid.GridFilters({filters:filters});
|
90
|
+
plugins.push(gridFilters);
|
91
|
+
}
|
92
|
+
|
93
|
+
JS
|
94
|
+
end
|
95
|
+
|
96
|
+
def js_listeners
|
97
|
+
super.merge({
|
98
|
+
:columnresize => {:fn => "this.onColumnResize".l, :scope => this},
|
99
|
+
:columnmove => {:fn => "this.onColumnMove".l, :scope => this}
|
100
|
+
})
|
101
|
+
end
|
102
|
+
|
103
|
+
def js_extend_properties
|
104
|
+
{
|
105
|
+
:on_widget_load => <<-JS.l,
|
106
|
+
function(){
|
107
|
+
// auto-load
|
108
|
+
if (this.initialConfig.autoLoadData) {
|
109
|
+
// if we have a paging toolbar, load the first page, otherwise
|
110
|
+
if (this.getBottomToolbar().changePage) this.getBottomToolbar().changePage(0); else this.store.load();
|
111
|
+
}
|
112
|
+
}
|
113
|
+
JS
|
114
|
+
|
115
|
+
:load_exception_handler => <<-JS.l,
|
116
|
+
function(proxy, options, response, error){
|
117
|
+
if (response.status == 200 && (responseObject = Ext.decode(response.responseText)) && responseObject.flash){
|
118
|
+
this.feedback(responseObject.flash)
|
119
|
+
} else {
|
120
|
+
if (error){
|
121
|
+
this.feedback(error.message);
|
122
|
+
} else {
|
123
|
+
this.feedback(response.statusText)
|
124
|
+
}
|
125
|
+
}
|
126
|
+
}
|
127
|
+
JS
|
128
|
+
|
129
|
+
:add => <<-JS.l,
|
130
|
+
function(){
|
131
|
+
var rowConfig = {};
|
132
|
+
Ext.each(this.initialConfig.columns, function(c){
|
133
|
+
rowConfig[c.name] = c.defaultValue || ''; // FIXME: if the user is happy with all the defaults, the record won't be 'dirty'
|
134
|
+
}, this);
|
135
|
+
|
136
|
+
var r = new this.Row(rowConfig); // TODO: add default values
|
137
|
+
r.set('id', -r.id); // to distinguish new records by negative values
|
138
|
+
this.stopEditing();
|
139
|
+
this.store.add(r);
|
140
|
+
this.store.newRecords = this.store.newRecords || []
|
141
|
+
this.store.newRecords.push(r);
|
142
|
+
// console.info(this.store.newRecords);
|
143
|
+
this.tryStartEditing(this.store.indexOf(r));
|
144
|
+
}
|
145
|
+
JS
|
146
|
+
|
147
|
+
:edit => <<-JS.l,
|
148
|
+
function(){
|
149
|
+
var row = this.getSelectionModel().getSelected();
|
150
|
+
if (row){
|
151
|
+
this.tryStartEditing(this.store.indexOf(row))
|
152
|
+
}
|
153
|
+
}
|
154
|
+
JS
|
155
|
+
|
156
|
+
# try editing the first editable (not hidden, not read-only) sell
|
157
|
+
:try_start_editing => <<-JS.l,
|
158
|
+
function(row){
|
159
|
+
if (row == null) return;
|
160
|
+
var editableColumns = this.getColumnModel().getColumnsBy(function(columnConfig, index){
|
161
|
+
return !columnConfig.hidden && !!columnConfig.editor;
|
162
|
+
});
|
163
|
+
// console.info(editableColumns);
|
164
|
+
var firstEditableColumn = editableColumns[0];
|
165
|
+
if (firstEditableColumn){
|
166
|
+
this.startEditing(row, firstEditableColumn.id);
|
167
|
+
}
|
168
|
+
}
|
169
|
+
JS
|
170
|
+
|
171
|
+
:delete => <<-JS.l,
|
172
|
+
function() {
|
173
|
+
if (this.getSelectionModel().hasSelection()){
|
174
|
+
Ext.Msg.confirm('Confirm', 'Are you sure?', function(btn){
|
175
|
+
if (btn == 'yes') {
|
176
|
+
var records = []
|
177
|
+
this.getSelectionModel().each(function(r){
|
178
|
+
records.push(r.get('id'));
|
179
|
+
}, this);
|
180
|
+
Ext.Ajax.request({
|
181
|
+
url: this.initialConfig.interface.deleteData,
|
182
|
+
params: {records: Ext.encode(records)},
|
183
|
+
success:function(r){
|
184
|
+
var m = Ext.decode(r.responseText);
|
185
|
+
this.store.reload();
|
186
|
+
// this.loadWithFeedback();
|
187
|
+
this.feedback(m.flash);
|
188
|
+
},
|
189
|
+
scope:this
|
190
|
+
});
|
191
|
+
}
|
192
|
+
}, this);
|
193
|
+
}
|
194
|
+
}
|
195
|
+
JS
|
196
|
+
:submit => <<-JS.l,
|
197
|
+
function(){
|
198
|
+
|
199
|
+
var newRecords = [];
|
200
|
+
if (this.store.newRecords){
|
201
|
+
Ext.each(this.store.newRecords, function(r){
|
202
|
+
newRecords.push(r.getChanges())
|
203
|
+
r.commit() // commit the changes, so that they are not picked up by getModifiedRecords() further down
|
204
|
+
}, this);
|
205
|
+
delete this.store.newRecords;
|
206
|
+
}
|
207
|
+
|
208
|
+
var updatedRecords = [];
|
209
|
+
Ext.each(this.store.getModifiedRecords(),
|
210
|
+
function(record) {
|
211
|
+
var completeRecordData = {};
|
212
|
+
Ext.apply(completeRecordData, Ext.apply(record.getChanges(), {id:record.get('id')}));
|
213
|
+
updatedRecords.push(completeRecordData);
|
214
|
+
},
|
215
|
+
this);
|
216
|
+
|
217
|
+
if (newRecords.length > 0 || updatedRecords.length > 0) {
|
218
|
+
Ext.Ajax.request({
|
219
|
+
url:this.initialConfig.interface.postData,
|
220
|
+
params: {
|
221
|
+
updated_records: Ext.encode(updatedRecords),
|
222
|
+
created_records: Ext.encode(newRecords),
|
223
|
+
filters: this.store.baseParams.filters
|
224
|
+
},
|
225
|
+
success:function(response){
|
226
|
+
var m = Ext.decode(response.responseText);
|
227
|
+
if (m.success) {
|
228
|
+
this.store.reload();
|
229
|
+
// this.loadWithFeedback();
|
230
|
+
this.store.commitChanges();
|
231
|
+
this.feedback(m.flash);
|
232
|
+
} else {
|
233
|
+
this.feedback(m.flash);
|
234
|
+
}
|
235
|
+
},
|
236
|
+
failure:function(response){
|
237
|
+
this.feedback('Bad response from server');
|
238
|
+
},
|
239
|
+
scope:this
|
240
|
+
});
|
241
|
+
}
|
242
|
+
|
243
|
+
}
|
244
|
+
JS
|
245
|
+
|
246
|
+
:refresh_click => <<-JS.l,
|
247
|
+
function() {
|
248
|
+
// console.info(this);
|
249
|
+
// if (this.fireEvent('refresh', this) !== false) this.loadWithFeedback();
|
250
|
+
if (this.fireEvent('refresh', this) !== false) this.store.reload();
|
251
|
+
}
|
252
|
+
JS
|
253
|
+
|
254
|
+
:on_column_resize => <<-JS.l,
|
255
|
+
function(index, size){
|
256
|
+
Ext.Ajax.request({
|
257
|
+
url:this.initialConfig.interface.resizeColumn,
|
258
|
+
params:{
|
259
|
+
index:index,
|
260
|
+
size:size
|
261
|
+
}
|
262
|
+
})
|
263
|
+
}
|
264
|
+
JS
|
265
|
+
|
266
|
+
:on_column_move => <<-JS.l
|
267
|
+
function(oldIndex, newIndex){
|
268
|
+
Ext.Ajax.request({
|
269
|
+
url:this.initialConfig.interface.moveColumn,
|
270
|
+
params:{
|
271
|
+
old_index:oldIndex,
|
272
|
+
new_index:newIndex
|
273
|
+
}
|
274
|
+
})
|
275
|
+
}
|
276
|
+
JS
|
277
|
+
|
278
|
+
}
|
279
|
+
end
|
280
|
+
|
281
|
+
end
|
282
|
+
end
|