skozlov-netzke-basepack 0.1.1.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/.autotest +1 -0
  2. data/.gitignore +5 -0
  3. data/LICENSE +2 -19
  4. data/README.rdoc +87 -0
  5. data/Rakefile +28 -12
  6. data/TODO.rdoc +7 -0
  7. data/VERSION +1 -0
  8. data/autotest/discover.rb +3 -0
  9. data/init.rb +0 -1
  10. data/javascripts/basepack.js +839 -49
  11. data/lib/app/models/netzke_auto_column.rb +56 -0
  12. data/lib/netzke/accordion_panel.rb +113 -0
  13. data/lib/netzke/active_record/basepack.rb +104 -0
  14. data/lib/netzke/active_record/data_accessor.rb +21 -0
  15. data/lib/netzke/basic_app.rb +325 -0
  16. data/lib/netzke/border_layout_panel.rb +128 -0
  17. data/lib/netzke/configuration_panel.rb +24 -0
  18. data/lib/netzke/data_accessor.rb +71 -0
  19. data/lib/netzke/ext.rb +6 -0
  20. data/lib/netzke/field_model.rb +131 -0
  21. data/lib/netzke/fields_configurator.rb +95 -0
  22. data/lib/netzke/form_panel.rb +214 -0
  23. data/lib/netzke/form_panel_api.rb +74 -0
  24. data/lib/netzke/form_panel_extras/javascripts/xcheckbox.js +82 -0
  25. data/lib/netzke/form_panel_js.rb +129 -0
  26. data/lib/netzke/grid_panel.rb +442 -0
  27. data/lib/netzke/grid_panel_api.rb +352 -0
  28. data/lib/netzke/grid_panel_extras/javascripts/check-column.js +33 -0
  29. data/{javascripts → lib/netzke/grid_panel_extras/javascripts}/filters.js +0 -0
  30. data/lib/netzke/grid_panel_extras/javascripts/rows-dd.js +280 -0
  31. data/lib/netzke/grid_panel_js.rb +721 -0
  32. data/lib/netzke/panel.rb +13 -0
  33. data/lib/netzke/plugins/configuration_tool.rb +121 -0
  34. data/lib/netzke/property_editor.rb +105 -0
  35. data/lib/netzke/property_editor_extras/helper_model.rb +126 -0
  36. data/lib/netzke/search_panel.rb +62 -0
  37. data/lib/netzke/tab_panel.rb +160 -0
  38. data/lib/netzke/table_editor.rb +118 -0
  39. data/lib/netzke/tree_panel.rb +73 -0
  40. data/lib/netzke/wrapper.rb +42 -0
  41. data/lib/netzke-basepack.rb +9 -15
  42. data/netzke-basepack.gemspec +147 -20
  43. data/stylesheets/basepack.css +26 -0
  44. data/test/app_root/app/models/book.rb +1 -1
  45. data/test/app_root/config/environment.rb +1 -0
  46. data/test/app_root/db/migrate/20081222033440_create_genres.rb +1 -0
  47. data/test/app_root/db/migrate/20081222035855_create_netzke_preferences.rb +1 -1
  48. data/test/app_root/db/migrate/20090102223630_create_netzke_layouts.rb +14 -0
  49. data/test/app_root/vendor/plugins/acts_as_list/README +23 -0
  50. data/test/app_root/vendor/plugins/acts_as_list/init.rb +3 -0
  51. data/test/app_root/vendor/plugins/acts_as_list/lib/active_record/acts/list.rb +256 -0
  52. data/test/test_helper.rb +1 -2
  53. data/test/unit/accordion_panel_test.rb +20 -0
  54. data/test/unit/active_record_basepack_test.rb +54 -0
  55. data/test/unit/grid_panel_test.rb +43 -0
  56. data/test/unit/helper_model_test.rb +30 -0
  57. data/test/unit/netzke_basepack_test.rb +4 -0
  58. data/test/unit/tab_panel_test.rb +21 -0
  59. metadata +96 -72
  60. data/CHANGELOG +0 -14
  61. data/Manifest +0 -65
  62. data/README.mdown +0 -18
  63. data/generators/netzke_basepack/USAGE +0 -8
  64. data/generators/netzke_basepack/netzke_basepack_generator.rb +0 -8
  65. data/generators/netzke_basepack/netzke_grid_generator.rb +0 -7
  66. data/generators/netzke_basepack/templates/create_netzke_grid_columns.rb +0 -21
  67. data/lib/app/models/netzke_grid_column.rb +0 -23
  68. data/lib/netzke/accordion.rb +0 -11
  69. data/lib/netzke/ar_ext.rb +0 -163
  70. data/lib/netzke/column.rb +0 -43
  71. data/lib/netzke/container.rb +0 -81
  72. data/lib/netzke/grid.rb +0 -120
  73. data/lib/netzke/grid_interface.rb +0 -156
  74. data/lib/netzke/grid_js_builder.rb +0 -276
  75. data/lib/netzke/preference_grid.rb +0 -43
  76. data/lib/netzke/properties_tool.rb +0 -66
  77. data/lib/netzke/property_grid.rb +0 -60
  78. data/test/ar_ext_test.rb +0 -39
  79. data/test/column_test.rb +0 -27
  80. data/test/grid_test.rb +0 -43
  81. data/test/netzke_basepack_test.rb +0 -8
@@ -1,156 +0,0 @@
1
- module Netzke::GridInterface
2
- def post_data(params)
3
- [:create, :update].each do |operation|
4
- data = JSON.parse(params.delete("#{operation}d_records".to_sym)) if params["#{operation}d_records".to_sym]
5
- process_data(data, operation) if !data.nil?
6
- end
7
- {:success => true, :flash => @flash}
8
- end
9
-
10
- def get_data(params = {})
11
- if @permissions[:read]
12
- records = get_records(params)
13
- {:data => records, :total => records.total_records}
14
- else
15
- flash :error => "You don't have permissions to read data"
16
- {:success => false, :flash => @flash}
17
- end
18
- end
19
-
20
- def delete_data(params = {})
21
- if @permissions[:delete]
22
- record_ids = JSON.parse(params.delete(:records))
23
- klass = config[:data_class_name].constantize
24
- klass.delete(record_ids)
25
- flash :notice => "Deleted #{record_ids.size} record(s)"
26
- success = true
27
- else
28
- flash :error => "You don't have permissions to delete data"
29
- success = false
30
- end
31
- {:success => success, :flash => @flash}
32
- end
33
-
34
- def resize_column(params)
35
- raise "Called interface_resize_column while not configured to do so" unless config[:column_resize]
36
- l_item = layout_manager_class.by_widget(id_name).layout_items[params[:index].to_i]
37
- l_item.width = params[:size]
38
- l_item.save!
39
- {}
40
- end
41
-
42
- def move_column(params)
43
- raise "Called interface_move_column while not configured to do so" unless config[:column_move]
44
- layout_manager_class.by_widget(id_name).move_item(params[:old_index].to_i, params[:new_index].to_i)
45
- {}
46
- end
47
-
48
- # Return the choices for the column
49
- def get_cb_choices(params)
50
- column = params[:column]
51
- query = params[:query]
52
-
53
- {:data => config[:data_class_name].constantize.choices_for(column, query).map{|s| [s]}}
54
- end
55
-
56
-
57
- protected
58
-
59
- # operation => :update || :create
60
- def process_data(data, operation)
61
- if @permissions[operation]
62
- klass = config[:data_class_name].constantize
63
- modified_records = 0
64
- data.each do |record_hash|
65
- record = operation == :create ? klass.create : klass.find(record_hash.delete('id'))
66
- logger.debug { "!!! record: #{record.inspect}" }
67
- success = true
68
- exception = nil
69
-
70
- # process all attirubutes for the same record (OPTIMIZE: we can use update_attributes separately for regular attributes to speed things up)
71
- record_hash.each_pair do |k,v|
72
- begin
73
- record.send("#{k}=",v)
74
- rescue ArgumentError => exc
75
- flash :error => exc.message
76
- success = false
77
- break
78
- end
79
- end
80
-
81
- # try to save
82
- modified_records += 1 if success && record.save
83
-
84
- # flash eventual errors
85
- record.errors.each_full do |msg|
86
- flash :error => msg
87
- end
88
-
89
- flash :notice => "#{operation.to_s.capitalize}d #{modified_records} records"
90
- end
91
- else
92
- flash :error => "You don't have permissions to #{operation} data"
93
- end
94
- end
95
-
96
- # get records
97
- def get_records(params)
98
- search_params = normalize_params(params)
99
- raise ArgumentError, "No data_class_name specified for widget '#{config[:name]}'" if !config[:data_class_name]
100
- records = config[:data_class_name].constantize.all(search_params.clone) # clone needed as searchlogic removes :conditions key from the hash
101
- output_array = []
102
- records.each do |r|
103
- r_array = []
104
- self.get_columns.each do |column|
105
- r_array << r.send(column[:name])
106
- end
107
- output_array << r_array
108
- end
109
-
110
- # add total_entries accessor to the result
111
- class << output_array
112
- attr :total_records, true
113
- end
114
- total_records_count = config[:data_class_name].constantize.count(search_params)
115
- output_array.total_records = total_records_count
116
-
117
- output_array
118
- end
119
-
120
- def convert_filters(column_filter)
121
- res = {}
122
- column_filter.each_pair do |k,v|
123
- field = v["field"]
124
- case v["data"]["type"]
125
- when "string"
126
- field << "_contains"
127
- when "numeric"
128
- field << "_#{v["data"]["comparison"]}"
129
- end
130
- value = v["data"]["value"]
131
- res.merge!({field => value})
132
- end
133
- res
134
- end
135
-
136
- # make params understandable to searchlogic
137
- def normalize_params(params)
138
- # filters
139
- conditions = params[:filter] && convert_filters(params[:filter])
140
-
141
- normalized_conditions = {}
142
- conditions && conditions.each_pair do |k, v|
143
- assoc, method = k.split('__')
144
- normalized_conditions.merge!(method.nil? ? {assoc => v} : {assoc => {method => v}})
145
- end
146
-
147
- # sorting
148
- order_by = if params[:sort]
149
- assoc, method = params[:sort].split('__')
150
- method.nil? ? assoc : {assoc => method}
151
- end
152
-
153
- page = params[:start].to_i/params[:limit].to_i + 1 if params[:limit]
154
- {:per_page => params[:limit], :page => page, :order_by => order_by, :order_as => params[:dir], :conditions => normalized_conditions}
155
- end
156
- end
@@ -1,276 +0,0 @@
1
- module Netzke::GridJsBuilder
2
- def js_base_class
3
- 'Ext.grid.EditorGridPanel'
4
- end
5
-
6
- def js_bbar
7
- <<-JS.l
8
- (config.rowsPerPage) ? new Ext.PagingToolbar({
9
- pageSize:config.rowsPerPage,
10
- items:config.actions,
11
- store:ds,
12
- emptyMsg:'Empty'}) : config.actions
13
- JS
14
- end
15
-
16
- def js_default_config
17
- super.merge({
18
- :store => "ds".l,
19
- :cm => "cm".l,
20
- :sel_model => "new Ext.grid.RowSelectionModel()".l,
21
- :auto_scroll => true,
22
- :click_to_edit => 2,
23
- :track_mouse_over => true,
24
- # :bbar => "config.actions".l,
25
- :bbar => js_bbar,
26
- :plugins => "plugins".l,
27
-
28
- #custom configs
29
- :auto_load_data => true
30
- })
31
- end
32
-
33
- def js_before_constructor
34
- <<-JS
35
- var plugins = [];
36
- if (!config.columns) this.feedback('No columns defined for grid '+config.id);
37
- this.recordConfig = [];
38
- Ext.each(config.columns, function(column){this.recordConfig.push({name:column.name})}, this);
39
- this.Row = Ext.data.Record.create(this.recordConfig);
40
-
41
- var ds = new Ext.data.Store({
42
- proxy: this.proxy = new Ext.data.HttpProxy({url:config.interface.getData}),
43
- reader: new Ext.data.ArrayReader({root: "data", totalProperty: "total", successProperty: "succes", id:0}, this.Row),
44
- remoteSort: true,
45
- listeners:{'loadexception':{
46
- fn:this.loadExceptionHandler,
47
- scope:this
48
- }}
49
- });
50
-
51
- this.cmConfig = [];
52
- Ext.each(config.columns, function(c){
53
- var editor = c.readOnly ? null : Ext.netzke.editors[c.showsAs](c, config);
54
-
55
- this.cmConfig.push({
56
- header: c.label || c.name,
57
- dataIndex: c.name,
58
- hidden: c.hidden,
59
- width: c.width,
60
- editor: editor,
61
- sortable: true
62
- })
63
- }, this);
64
-
65
- var cm = new Ext.grid.ColumnModel(this.cmConfig);
66
-
67
- this.addEvents("refresh");
68
-
69
- // Filters
70
- if (config.columnFilters) {
71
- var filters = []
72
- Ext.each(config.columns, function(c){
73
- filters.push({type:Ext.netzke.filterMap[c.showsAs], dataIndex:c.name})
74
- })
75
- var gridFilters = new Ext.grid.GridFilters({filters:filters});
76
- plugins.push(gridFilters);
77
- }
78
-
79
- JS
80
- end
81
-
82
- def js_config
83
- res = super
84
- # we pass column config at the time of instantiating the JS class
85
- res.merge!(:columns => get_columns || config[:columns]) # first try to get columns from DB, then from config
86
- res.merge!(:data_class_name => config[:data_class_name])
87
- res
88
- end
89
-
90
- def js_listeners
91
- super.merge({
92
- :columnresize => (config[:column_resize] ? {:fn => "this.onColumnResize".l, :scope => this} : nil),
93
- :columnmove => (config[:column_move] ? {:fn => "this.onColumnMove".l, :scope => this} : nil)
94
- })
95
- end
96
-
97
-
98
- def js_extend_properties
99
- {
100
- :on_widget_load => <<-JS.l,
101
- function(){
102
- // auto-load
103
- if (this.initialConfig.autoLoadData) {
104
- // if we have a paging toolbar, load the first page, otherwise
105
- if (this.getBottomToolbar().changePage) this.getBottomToolbar().changePage(0); else this.store.load();
106
- }
107
- }
108
- JS
109
-
110
- :load_exception_handler => <<-JS.l,
111
- function(proxy, options, response, error){
112
- if (response.status == 200 && (responseObject = Ext.decode(response.responseText)) && responseObject.flash){
113
- this.feedback(responseObject.flash)
114
- } else {
115
- if (error){
116
- this.feedback(error.message);
117
- } else {
118
- this.feedback(response.statusText)
119
- }
120
- }
121
- }
122
- JS
123
-
124
- :add => <<-JS.l,
125
- function(){
126
- var rowConfig = {};
127
- Ext.each(this.initialConfig.columns, function(c){
128
- rowConfig[c.name] = c.defaultValue || ''; // FIXME: if the user is happy with all the defaults, the record won't be 'dirty'
129
- }, this);
130
-
131
- var r = new this.Row(rowConfig); // TODO: add default values
132
- r.set('id', -r.id); // to distinguish new records by negative values
133
- this.stopEditing();
134
- this.store.add(r);
135
- this.store.newRecords = this.store.newRecords || []
136
- this.store.newRecords.push(r);
137
- // console.info(this.store.newRecords);
138
- this.tryStartEditing(this.store.indexOf(r));
139
- }
140
- JS
141
-
142
- :edit => <<-JS.l,
143
- function(){
144
- var row = this.getSelectionModel().getSelected();
145
- if (row){
146
- this.tryStartEditing(this.store.indexOf(row))
147
- }
148
- }
149
- JS
150
-
151
- # try editing the first editable (not hidden, not read-only) sell
152
- :try_start_editing => <<-JS.l,
153
- function(row){
154
- if (row == null) return;
155
- var editableColumns = this.getColumnModel().getColumnsBy(function(columnConfig, index){
156
- return !columnConfig.hidden && !!columnConfig.editor;
157
- });
158
- // console.info(editableColumns);
159
- var firstEditableColumn = editableColumns[0];
160
- if (firstEditableColumn){
161
- this.startEditing(row, firstEditableColumn.id);
162
- }
163
- }
164
- JS
165
-
166
- :delete => <<-JS.l,
167
- function() {
168
- if (this.getSelectionModel().hasSelection()){
169
- Ext.Msg.confirm('Confirm', 'Are you sure?', function(btn){
170
- if (btn == 'yes') {
171
- var records = []
172
- this.getSelectionModel().each(function(r){
173
- records.push(r.get('id'));
174
- }, this);
175
- Ext.Ajax.request({
176
- url: this.initialConfig.interface.deleteData,
177
- params: {records: Ext.encode(records)},
178
- success:function(r){
179
- var m = Ext.decode(r.responseText);
180
- this.store.reload();
181
- // this.loadWithFeedback();
182
- this.feedback(m.flash);
183
- },
184
- scope:this
185
- });
186
- }
187
- }, this);
188
- }
189
- }
190
- JS
191
- :submit => <<-JS.l,
192
- function(){
193
-
194
- var newRecords = [];
195
- if (this.store.newRecords){
196
- Ext.each(this.store.newRecords, function(r){
197
- newRecords.push(r.getChanges())
198
- r.commit() // commit the changes, so that they are not picked up by getModifiedRecords() further down
199
- }, this);
200
- delete this.store.newRecords;
201
- }
202
-
203
- var updatedRecords = [];
204
- Ext.each(this.store.getModifiedRecords(),
205
- function(record) {
206
- var completeRecordData = {};
207
- Ext.apply(completeRecordData, Ext.apply(record.getChanges(), {id:record.get('id')}));
208
- updatedRecords.push(completeRecordData);
209
- },
210
- this);
211
-
212
- if (newRecords.length > 0 || updatedRecords.length > 0) {
213
- Ext.Ajax.request({
214
- url:this.initialConfig.interface.postData,
215
- params: {
216
- updated_records: Ext.encode(updatedRecords),
217
- created_records: Ext.encode(newRecords),
218
- filters: this.store.baseParams.filters
219
- },
220
- success:function(response){
221
- var m = Ext.decode(response.responseText);
222
- if (m.success) {
223
- this.store.reload();
224
- // this.loadWithFeedback();
225
- this.store.commitChanges();
226
- this.feedback(m.flash);
227
- } else {
228
- this.feedback(m.flash);
229
- }
230
- },
231
- failure:function(response){
232
- this.feedback('Bad response from server');
233
- },
234
- scope:this
235
- });
236
- }
237
-
238
- }
239
- JS
240
-
241
- :refresh_click => <<-JS.l,
242
- function() {
243
- // console.info(this);
244
- // if (this.fireEvent('refresh', this) !== false) this.loadWithFeedback();
245
- if (this.fireEvent('refresh', this) !== false) this.store.reload();
246
- }
247
- JS
248
-
249
- :on_column_resize => <<-JS.l,
250
- function(index, size){
251
- // var column = this.getColumnModel().getDataIndex(index);
252
- Ext.Ajax.request({
253
- url:this.initialConfig.interface.resizeColumn,
254
- params:{
255
- index:index,
256
- size:size
257
- }
258
- })
259
- }
260
- JS
261
-
262
- :on_column_move => <<-JS.l
263
- function(oldIndex, newIndex){
264
- Ext.Ajax.request({
265
- url:this.initialConfig.interface.moveColumn,
266
- params:{
267
- old_index:oldIndex,
268
- new_index:newIndex
269
- }
270
- })
271
- }
272
- JS
273
-
274
- }
275
- end
276
- end
@@ -1,43 +0,0 @@
1
- module Netzke
2
- # GUI for Preference class
3
- class PreferenceGrid < PropertyGrid
4
- def initialize(*args)
5
- super
6
- config[:default_properties] ||= []
7
- NetzkePreference.custom_field = config[:host_widget_name]
8
-
9
- # Create default properties
10
- config[:default_properties].each do |p|
11
- NetzkePreference[p[:name]] = p[:value] if NetzkePreference[p[:name]].nil?
12
- end
13
- end
14
-
15
- def load_source(params = {})
16
- # config[:data_class_name] = 'NetzkePreference'
17
- config[:conditions] ||= {}
18
-
19
- data_class = NetzkePreference
20
- records = data_class.find(:all, :conditions => {:custom_field => config[:host_widget_name]})
21
-
22
- NetzkePreference.custom_field = config[:host_widget_name]
23
-
24
- source = {}
25
- records.each do |r|
26
- source.merge!(r.name => NetzkePreference[r.name])
27
- end
28
-
29
- {:source => source}
30
- end
31
-
32
- def submit_source(params = {})
33
- data = JSON.parse(params[:data])
34
- NetzkePreference.custom_field = config[:host_widget_name]
35
- data.each_pair do |k,v|
36
- NetzkePreference[k.underscore] = v
37
- end
38
-
39
- {:success => true, :flash => @flash}
40
- end
41
-
42
- end
43
- end