netzke-basepack 0.4.2 → 0.5.1

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.
Files changed (62) hide show
  1. data/.autotest +1 -0
  2. data/.gitignore +6 -0
  3. data/{CHANGELOG → CHANGELOG.rdoc} +26 -0
  4. data/README.rdoc +11 -11
  5. data/Rakefile +37 -11
  6. data/TODO.rdoc +8 -0
  7. data/VERSION +1 -0
  8. data/javascripts/basepack.js +71 -28
  9. data/lib/app/models/netzke_auto_column.rb +56 -0
  10. data/lib/netzke-basepack.rb +5 -3
  11. data/lib/netzke/accordion_panel.rb +69 -67
  12. data/lib/netzke/active_record/basepack.rb +104 -0
  13. data/lib/netzke/active_record/data_accessor.rb +33 -0
  14. data/lib/netzke/basic_app.rb +233 -124
  15. data/lib/netzke/border_layout_panel.rb +97 -98
  16. data/lib/netzke/configuration_panel.rb +24 -0
  17. data/lib/netzke/data_accessor.rb +71 -0
  18. data/lib/netzke/ext.rb +6 -0
  19. data/lib/netzke/field_model.rb +1 -1
  20. data/lib/netzke/fields_configurator.rb +62 -37
  21. data/lib/netzke/form_panel.rb +161 -51
  22. data/lib/netzke/form_panel_api.rb +74 -0
  23. data/lib/netzke/form_panel_js.rb +129 -0
  24. data/lib/netzke/grid_panel.rb +385 -80
  25. data/lib/netzke/grid_panel_api.rb +352 -0
  26. data/lib/netzke/grid_panel_extras/javascripts/rows-dd.js +280 -0
  27. data/lib/netzke/grid_panel_js.rb +721 -0
  28. data/lib/netzke/masquerade_selector.rb +53 -0
  29. data/lib/netzke/panel.rb +9 -0
  30. data/lib/netzke/plugins/configuration_tool.rb +121 -0
  31. data/lib/netzke/property_editor.rb +95 -7
  32. data/lib/netzke/property_editor_extras/helper_model.rb +55 -34
  33. data/lib/netzke/search_panel.rb +62 -0
  34. data/lib/netzke/tab_panel.rb +97 -37
  35. data/lib/netzke/table_editor.rb +49 -44
  36. data/lib/netzke/tree_panel.rb +15 -16
  37. data/lib/netzke/wrapper.rb +29 -5
  38. data/netzke-basepack.gemspec +151 -19
  39. data/stylesheets/basepack.css +5 -0
  40. data/test/app_root/app/models/book.rb +1 -1
  41. data/test/app_root/db/migrate/20081222035855_create_netzke_preferences.rb +1 -1
  42. data/test/unit/accordion_panel_test.rb +1 -2
  43. data/test/unit/active_record_basepack_test.rb +54 -0
  44. data/test/unit/grid_panel_test.rb +8 -12
  45. data/test/unit/helper_model_test.rb +30 -0
  46. metadata +69 -78
  47. data/Manifest +0 -86
  48. data/TODO +0 -3
  49. data/lib/app/models/netzke_hash_record.rb +0 -180
  50. data/lib/app/models/netzke_layout_item.rb +0 -11
  51. data/lib/netzke/ar_ext.rb +0 -269
  52. data/lib/netzke/configuration_tool.rb +0 -80
  53. data/lib/netzke/container.rb +0 -77
  54. data/lib/netzke/db_fields.rb +0 -44
  55. data/lib/netzke/fields_configurator_old.rb +0 -62
  56. data/lib/netzke/form_panel_extras/interface.rb +0 -56
  57. data/lib/netzke/form_panel_extras/js_builder.rb +0 -134
  58. data/lib/netzke/grid_panel_extras/interface.rb +0 -206
  59. data/lib/netzke/grid_panel_extras/js_builder.rb +0 -352
  60. data/test/unit/ar_ext_test.rb +0 -53
  61. data/test/unit/netzke_hash_record_test.rb +0 -52
  62. data/test/unit/netzke_layout_item_test.rb +0 -28
data/Manifest DELETED
@@ -1,86 +0,0 @@
1
- autotest/discover.rb
2
- CHANGELOG
3
- init.rb
4
- install.rb
5
- javascripts/basepack.js
6
- lib/app/models/netzke_hash_record.rb
7
- lib/app/models/netzke_layout_item.rb
8
- lib/netzke/accordion_panel.rb
9
- lib/netzke/ar_ext.rb
10
- lib/netzke/basic_app.rb
11
- lib/netzke/border_layout_panel.rb
12
- lib/netzke/configuration_tool.rb
13
- lib/netzke/container.rb
14
- lib/netzke/db_fields.rb
15
- lib/netzke/field_model.rb
16
- lib/netzke/fields_configurator.rb
17
- lib/netzke/fields_configurator_old.rb
18
- lib/netzke/form_panel.rb
19
- lib/netzke/form_panel_extras/interface.rb
20
- lib/netzke/form_panel_extras/javascripts/xcheckbox.js
21
- lib/netzke/form_panel_extras/js_builder.rb
22
- lib/netzke/grid_panel.rb
23
- lib/netzke/grid_panel_extras/interface.rb
24
- lib/netzke/grid_panel_extras/javascripts/check-column.js
25
- lib/netzke/grid_panel_extras/javascripts/filters.js
26
- lib/netzke/grid_panel_extras/js_builder.rb
27
- lib/netzke/panel.rb
28
- lib/netzke/property_editor.rb
29
- lib/netzke/property_editor_extras/helper_model.rb
30
- lib/netzke/tab_panel.rb
31
- lib/netzke/table_editor.rb
32
- lib/netzke/tree_panel.rb
33
- lib/netzke/wrapper.rb
34
- lib/netzke-basepack.rb
35
- LICENSE
36
- Manifest
37
- Rakefile
38
- README.rdoc
39
- stylesheets/basepack.css
40
- tasks/netzke_basepack_tasks.rake
41
- test/app_root/app/controllers/application.rb
42
- test/app_root/app/models/book.rb
43
- test/app_root/app/models/category.rb
44
- test/app_root/app/models/city.rb
45
- test/app_root/app/models/continent.rb
46
- test/app_root/app/models/country.rb
47
- test/app_root/app/models/genre.rb
48
- test/app_root/config/boot.rb
49
- test/app_root/config/database.yml
50
- test/app_root/config/environment.rb
51
- test/app_root/config/environments/in_memory.rb
52
- test/app_root/config/environments/mysql.rb
53
- test/app_root/config/environments/postgresql.rb
54
- test/app_root/config/environments/sqlite.rb
55
- test/app_root/config/environments/sqlite3.rb
56
- test/app_root/config/routes.rb
57
- test/app_root/db/migrate/20081222033343_create_books.rb
58
- test/app_root/db/migrate/20081222033440_create_genres.rb
59
- test/app_root/db/migrate/20081222035855_create_netzke_preferences.rb
60
- test/app_root/db/migrate/20081223024935_create_categories.rb
61
- test/app_root/db/migrate/20081223025635_create_countries.rb
62
- test/app_root/db/migrate/20081223025653_create_continents.rb
63
- test/app_root/db/migrate/20081223025732_create_cities.rb
64
- test/app_root/db/migrate/20090102223630_create_netzke_layouts.rb
65
- test/app_root/script/console
66
- test/app_root/vendor/plugins/acts_as_list/init.rb
67
- test/app_root/vendor/plugins/acts_as_list/lib/active_record/acts/list.rb
68
- test/app_root/vendor/plugins/acts_as_list/README
69
- test/console_with_fixtures.rb
70
- test/fixtures/books.yml
71
- test/fixtures/categories.yml
72
- test/fixtures/cities.yml
73
- test/fixtures/continents.yml
74
- test/fixtures/countries.yml
75
- test/fixtures/genres.yml
76
- test/schema.rb
77
- test/test_helper.rb
78
- test/unit/accordion_panel_test.rb
79
- test/unit/ar_ext_test.rb
80
- test/unit/grid_panel_test.rb
81
- test/unit/netzke_basepack_test.rb
82
- test/unit/netzke_hash_record_test.rb
83
- test/unit/netzke_layout_item_test.rb
84
- test/unit/tab_panel_test.rb
85
- TODO
86
- uninstall.rb
data/TODO DELETED
@@ -1,3 +0,0 @@
1
- * GridPanel. Reordering of grid columns may lead to unpredictable results when data from an "outdated" table (e.g. open in another browser) gets submitted. A mechanism is needed to submit updated data along with the field names - as hash (as done is FormPanel), *not* as array.
2
-
3
- * Add status bar to BasicApp
@@ -1,180 +0,0 @@
1
- class NetzkeHashRecord < Hash
2
- include Netzke::ActiveRecordExtensions
3
- #
4
- # Class methods
5
- #
6
- def self.widget=(w)
7
- @@widget = w
8
- reload
9
- end
10
-
11
- def self.widget
12
- @@widget ||= nil
13
- raise "No widget specified for NetzkeHashRecord" if @@widget.nil?
14
- @@widget
15
- end
16
-
17
- def self.data=(data)
18
- @@records = data
19
- save
20
- end
21
-
22
- def self.raw_data=(data)
23
- persistent_config.for_widget(widget) {|p| p[:layout__columns] = data}
24
- end
25
-
26
- def self.columns_hash
27
- @@columns_hash ||= build_columns_hash
28
- end
29
-
30
- def self.push(instance)
31
- records << instance
32
- end
33
-
34
- def self.reload
35
- @@records = build_records
36
- end
37
-
38
- # standard AR operations
39
- def self.all(params = {})
40
- records
41
- end
42
-
43
- def self.count(params = {})
44
- records.size
45
- end
46
-
47
- def self.find(*args)
48
- if args.size == 1
49
- records[args.first.to_i - 1]
50
- else
51
- end
52
- end
53
-
54
- def self.first
55
- records.first
56
- end
57
-
58
- def self.last
59
- records.last
60
- end
61
-
62
- def self.delete(ids)
63
- ids.each do |id|
64
- records.delete_if{|r| r.id == id.to_i}
65
- end
66
- recalculate_ids
67
- save
68
- end
69
-
70
- def self.delete_all
71
- records.clear
72
- save
73
- end
74
-
75
- def self.save
76
- records_without_ids = records.map{ |r| r.reject{ |k,v| k == :id } }
77
- persistent_config.for_widget(widget) {|p| p[:layout__columns] = records_without_ids}
78
- true
79
- end
80
-
81
- def self.column_names
82
- columns_hash.keys.sort{ |x,y| x == "id" ? -1 : 0} # "id"-column should always come first (required by the GridPanel)
83
- end
84
-
85
- def self.reflect_on_all_associations
86
- []
87
- end
88
-
89
- #
90
- # Instance methods
91
- #
92
- def initialize(params = {})
93
- self.replace(params)
94
- end
95
-
96
- def id
97
- self[:id] || self["id"]
98
- end
99
-
100
- def id=(id)
101
- self[:id] = id
102
- end
103
-
104
- def save
105
- if self.id.nil?
106
- self.id = self.class.records.size + 1
107
- self.class.push(self)
108
- else
109
- # nothing to do
110
- end
111
-
112
- self.class.save
113
- end
114
-
115
- def errors
116
- []
117
- end
118
-
119
- private
120
-
121
- def self.persistent_config
122
- @@persistent_config ||= Netzke::Base.persistent_config
123
- end
124
-
125
- def self.records
126
- @@records ||= build_records
127
- end
128
-
129
- def self.build_records
130
- raw_records = persistent_config.for_widget(widget){|p| p[:layout__columns]} || []
131
- records = []
132
- raw_records.each_with_index do |r,i|
133
- own_instance = self.new(r.convert_keys{|k| k.to_sym})
134
- own_instance.merge!(:id => i + 1) # merging with the id
135
- records << own_instance
136
- end
137
- records
138
- end
139
-
140
- def self.recalculate_ids
141
- records.each_with_index { |r, i| r.id = i + 1}
142
- end
143
-
144
- def self.build_columns_hash
145
- res = {}
146
- records.each do |record|
147
- record.keys.each do |k|
148
-
149
- if res[k.to_s].nil?
150
-
151
- # calculate column type
152
- column_type = case record[k].class.to_s
153
- when "TrueClass"
154
- :boolean
155
- when "FalseClass"
156
- :boolean
157
- when "String"
158
- :string
159
- when "Fixnum"
160
- :integer
161
- else
162
- :string
163
- end
164
-
165
- column = {:type => column_type}
166
-
167
- # workaround for the "type" method
168
- class << column
169
- def type
170
- self[:type]
171
- end
172
- end
173
-
174
- res[k.to_s] = column
175
- end
176
- end
177
- end
178
- res
179
- end
180
- end
@@ -1,11 +0,0 @@
1
- class NetzkeLayoutItem < NetzkeHashRecord
2
-
3
- # Moving item
4
- def self.move_item(from, to)
5
- r = records.delete_at(from)
6
- records.insert(to, r)
7
- recalculate_ids
8
- save
9
- end
10
-
11
- end
data/lib/netzke/ar_ext.rb DELETED
@@ -1,269 +0,0 @@
1
- module Netzke
2
- module ActiveRecordExtensions
3
- def self.included(base)
4
- base.extend ActiveRecordClassMethods
5
- end
6
-
7
- #
8
- # Allow nested association access (assocs separated by "." or "__"), e.g.: proxy_service.asset__gui_folder__name
9
- # Example:
10
- # b = Book.first
11
- # b.genre__name = 'Fantasy' => b.genre = Genre.find_by_name('Fantasy')
12
- # NOT IMPLEMENTED (any real use?): b.genre__catalog__name = 'Best sellers' => b.genre_id = b.genre.find_by_catalog_id(Catalog.find_by_name('Best sellers')).id
13
- #
14
-
15
- def method_missing(method, *args, &block)
16
- # if refering to a column, just pass it to the original method_missing
17
- return super if self.class.column_names.include?(method.to_s)
18
-
19
- split = method.to_s.split(/\.|__/)
20
- if split.size > 1
21
- if split.last =~ /=$/
22
- if split.size == 2
23
- # search for association and assign it to self
24
- assoc = self.class.reflect_on_association(split.first.to_sym)
25
- assoc_method = split.last.chop
26
- if assoc
27
- assoc_instance = assoc.klass.send("find_by_#{assoc_method}", *args)
28
- raise ArgumentError, "Couldn't find association #{split.first} by #{assoc_method} '#{args.first}'" unless assoc_instance
29
- self.send("#{split.first}=", assoc_instance)
30
- else
31
- super
32
- end
33
- else
34
- super
35
- end
36
- else
37
- res = self
38
- split.each do |m|
39
- if res.respond_to?(m)
40
- res = res.send(m) unless res.nil?
41
- else
42
- res.nil? ? nil : super
43
- end
44
- end
45
- res
46
- end
47
- else
48
- super
49
- end
50
- end
51
-
52
- def to_array(columns)
53
- res = []
54
- for c in columns
55
- method = c.is_a?(Symbol) ? c : c[:name]
56
- res << send(method)
57
- end
58
- res
59
- end
60
-
61
- module ActiveRecordClassMethods
62
- # next and previous to id records
63
- def next(id)
64
- find(:first, :conditions => ["#{primary_key} > ?", id])
65
- end
66
- def previous(id)
67
- find(:first, :conditions => ["#{primary_key} < ?", id], :order => "#{primary_key} DESC")
68
- end
69
-
70
- # Returns all unique values for a column, filtered by the query
71
- def choices_for(column, query = nil)
72
- if respond_to?("#{column}_choices", query)
73
- # AR class provides the choices itself
74
- send("#{column}_choices")
75
- else
76
- if (assoc_name, *assoc_method = column.split('__')).size > 1
77
- # column is an association column
78
- assoc_method = assoc_method.join('__') # in case we get something like country__continent__name
79
- association = reflect_on_association(assoc_name.to_sym) || raise(NameError, "Association #{assoc_name} not known for class #{name}")
80
- association.klass.choices_for(assoc_method, query)
81
- else
82
- column = assoc_name
83
- if self.column_names.include?(column)
84
- # it's just a column
85
- records = query.nil? ? find_by_sql("select distinct #{column} from #{table_name}") : find_by_sql("select distinct #{column} from #{table_name} where #{column} like '#{query}%'")
86
- records.map{|r| r.send(column)}
87
- else
88
- # it's a "virtual" column - the least effective search
89
- records = self.find(:all).map{|r| r.send(column)}.uniq
90
- query.nil? ? records : records.select{|r| r.index(/^#{query}/)}
91
- end
92
- end
93
- end
94
- end
95
-
96
- # which columns are to be picked up by grids and forms
97
- def expose_columns(*column_configs)
98
- if column_configs.first == :all
99
- write_inheritable_attribute(:exposed_columns, self.column_names.map(&:to_sym))
100
- else
101
- write_inheritable_attribute(:exposed_columns, column_configs)
102
- end
103
- end
104
-
105
- def exposed_columns
106
- read_inheritable_attribute(:exposed_columns) || write_inheritable_attribute(:exposed_columns, expose_columns(:all) + virtual_columns)
107
- end
108
-
109
- # virtual "columns" that simply correspond to instance methods of an ActiveRecord class
110
- def virtual_column(config)
111
- if config.is_a?(Symbol)
112
- config = {:name => config}
113
- else
114
- config = {:name => config.keys.first}.merge(config.values.first)
115
- end
116
- write_inheritable_attribute(:virtual_columns, (read_inheritable_attribute(:virtual_columns) || []) << config)
117
- end
118
-
119
- def virtual_columns
120
- read_inheritable_attribute(:virtual_columns) || []
121
- end
122
-
123
- def is_virtual_column?(column)
124
- read_inheritable_attribute(:virtual_columns).keys.include?(column)
125
- end
126
-
127
- def default_dbfield_config(config, mode = :grid)
128
- config = config.is_a?(Symbol) ? {:name => config} : config.dup
129
-
130
- # detect ActiveRecord column type (if the column is "real") or fall back to :virtual
131
- type = (columns_hash[config[:name].to_s] && columns_hash[config[:name].to_s].type) || :virtual
132
-
133
- res = {
134
- :name => config[:name].to_s || "unnamed",
135
- :label => config[:label] || config[:name].to_s.gsub('__', '_').humanize,
136
- :read_only => config[:name] == :id, # make "id" column read-only by default
137
- :hidden => config[:name] == :id, # hide "id" column by default
138
- :width => mode == :grid ? DEFAULT_COLUMN_WIDTH : DEFAULT_FIELD_WIDTH,
139
- :editor => ext_editor(type)
140
- }
141
-
142
- # for forms fields also set up the height
143
- res.merge!(:height => DEFAULT_FIELD_HEIGHT) if mode == :form
144
-
145
- # detect :assoc__method
146
- if config[:name].to_s.index('__')
147
- assoc_name, method = config[:name].to_s.split('__').map(&:to_sym)
148
- if assoc = reflect_on_association(assoc_name)
149
- assoc_column = assoc.klass.columns_hash[method.to_s]
150
- assoc_method_type = assoc_column.try(:type)
151
- if assoc_method_type
152
- res[:editor] = ext_editor(assoc_method_type) == :checkbox ? :checkbox : :combobox
153
- end
154
- end
155
- end
156
-
157
- # detect association column (e.g. :category_id)
158
- if assoc = reflect_on_all_associations.detect{|a| a.primary_key_name.to_sym == config[:name]}
159
- res[:editor] = :combobox
160
- assoc_method = %w{name title label}.detect{|m| (assoc.klass.instance_methods + assoc.klass.column_names).include?(m) } || assoc.klass.primary_key
161
- res[:name] = "#{assoc.name}__#{assoc_method}"
162
- end
163
-
164
- res[:width] = 50 if res[:editor] == :checkbox # more narrow column for checkboxes
165
-
166
- # merge with the given confg, which has the priority
167
- config.delete(:name) # because we might have changed the name
168
- res.merge(config)
169
- end
170
-
171
- #
172
- # Used by Netzke::GridPanel
173
- #
174
-
175
- DEFAULT_COLUMN_WIDTH = 100
176
-
177
- # identify Ext editor (xtype) for the data type
178
- TYPE_EDITOR_MAP = {
179
- :integer => :numberfield,
180
- :boolean => :checkbox,
181
- :date => :datefield,
182
- :datetime => :xdatetime,
183
- :string => :textfield
184
- }
185
-
186
- # Returns default column config understood by Netzke::GridPanel
187
- # Argument: column name (as Symbol) or column config
188
- def default_column_config(config)
189
- default_dbfield_config(config, :grid)
190
- end
191
-
192
- #
193
- # Used by Netzke::FormPanel
194
- #
195
-
196
- # default configuration as a function of ActivRecord's column type
197
- # DEFAULTS_FOR_FIELD = {
198
- # :integer => {
199
- # :xtype => :numberfield
200
- # },
201
- # :boolean => {
202
- # :xtype => :numberfield
203
- # },
204
- # :date => {
205
- # :xtype => :datefield
206
- # },
207
- # :datetime => {
208
- # :xtype => :xdatetime
209
- # # :date_format => "Y-m-d",
210
- # # :time_format => "H:i",
211
- # # :time_width => 60
212
- # },
213
- # :string => {
214
- # :xtype => :textfield
215
- # }
216
- # }
217
-
218
- XTYPE_MAP = {
219
- :integer => :numberfield,
220
- :boolean => :xcheckbox,
221
- :date => :datefield,
222
- :datetime => :xdatetime,
223
- :string => :textfield
224
- }
225
-
226
- def default_field_config(config)
227
- # default_dbfield_config(config, :form)
228
- config = config.is_a?(Symbol) ? {:name => config} : config.dup
229
-
230
- # detect ActiveRecord column type (if the column is "real") or fall back to :virtual
231
- type = (columns_hash[config[:name].to_s] && columns_hash[config[:name].to_s].type) || :virtual
232
-
233
- common = {
234
- :field_label => config[:name].to_s.gsub('__', '_').humanize,
235
- :hidden => config[:name] == :id,
236
- :xtype => XTYPE_MAP[type] || XTYPE_MAP[:string]
237
- }
238
-
239
- # detect :assoc__method
240
- if config[:name].to_s.index('__')
241
- assoc_name, method = config[:name].to_s.split('__').map(&:to_sym)
242
- if assoc = reflect_on_association(assoc_name)
243
- assoc_column = assoc.klass.columns_hash[method.to_s]
244
- assoc_method_type = assoc_column.try(:type)
245
- if assoc_method_type
246
- common[:xtype] = ext_editor(assoc_method_type) == :checkbox ? :checkbox : :combobox
247
- end
248
- end
249
- end
250
-
251
- common.merge(config)
252
-
253
- # default = DEFAULTS_FOR_FIELD[type] || DEFAULTS_FOR_FIELD[:string] # fallback to plain textfield
254
-
255
- # res = default.merge(common).merge(config)
256
- end
257
-
258
- private
259
- def ext_editor(type)
260
- TYPE_EDITOR_MAP[type] || :textfield # fall back to :text_field
261
- end
262
-
263
- end
264
- end
265
- end
266
-
267
- ActiveRecord::Base.class_eval do
268
- include Netzke::ActiveRecordExtensions
269
- end