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,8 +0,0 @@
1
- class NetzkeBasepackGenerator < Rails::Generator::NamedBase
2
- def manifest
3
- record do |m|
4
- # m.directory "lib"
5
- # m.template 'README', "README"
6
- end
7
- end
8
- end
@@ -1,7 +0,0 @@
1
- class NetzkeGridGenerator < Rails::Generator::Base
2
- def manifest
3
- record do |m|
4
- m.migration_template 'create_netzke_grid_columns.rb', "db/migrate", {:migration_file_name => "create_netzke_grid_columns"}
5
- end
6
- end
7
- end
@@ -1,21 +0,0 @@
1
- class CreateNetzkeGridColumns < ActiveRecord::Migration
2
- def self.up
3
- create_table :netzke_grid_columns do |t|
4
- t.string :name
5
- t.string :label
6
- t.boolean :read_only
7
- t.integer :position
8
- t.boolean :hidden
9
- t.integer :width
10
- t.string :shows_as, :limit => 32
11
-
12
- t.integer :layout_id
13
-
14
- t.timestamps
15
- end
16
- end
17
-
18
- def self.down
19
- drop_table :netzke_grid_columns
20
- end
21
- end
@@ -1,23 +0,0 @@
1
- class NetzkeGridColumn < ActiveRecord::Base
2
- belongs_to :layout, :class_name => "NetzkeLayout"
3
-
4
- acts_as_list :scope => :layout
5
-
6
- # old?
7
- # def self.create_with_defaults(column_config, klass)
8
- # create(klass.default_column_config(column_config).stringify_values!)
9
- # end
10
-
11
- def self.create_layout_for_widget(widget)
12
- layout = NetzkeLayout.create(:widget_name => widget.id_name, :items_class => self.name, :user_id => NetzkeLayout.user_id)
13
-
14
- columns = Netzke::Column.default_columns_for_widget(widget)
15
-
16
- for c in columns
17
- config_for_create = c.merge(:layout_id => layout.id).stringify_values!
18
- create(config_for_create)
19
- end
20
-
21
- layout
22
- end
23
- end
@@ -1,11 +0,0 @@
1
- module Netzke
2
- class Accordion < Container
3
-
4
- def js_default_config
5
- super.merge({
6
- :layout => 'accordion'
7
- })
8
- end
9
-
10
- end
11
- end
data/lib/netzke/ar_ext.rb DELETED
@@ -1,163 +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 acces (assocs separated by "." or "__"), e.g.: proxy_service.send('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 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 originar 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
-
53
- module ActiveRecordClassMethods
54
- def choices_for(column, query = nil)
55
- if respond_to?("#{column}_choices", query)
56
- # AR class provides the choices itself
57
- send("#{column}_choices")
58
- else
59
- if (assoc_name, *assoc_method = column.split('__')).size > 1
60
- # column is an association column
61
- assoc_method = assoc_method.join('__') # in case we get something like country__continent__name
62
- association = reflect_on_association(assoc_name.to_sym) || raise(NameError, "Association #{assoc_name} not known for class #{name}")
63
- association.klass.choices_for(assoc_method, query)
64
- else
65
- column = assoc_name
66
- if self.column_names.include?(column)
67
- # it's just a column
68
- 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}%'")
69
- records.map{|r| r.send(column)}
70
- else
71
- # it's a "virtual" column - the least effective search
72
- records = self.find(:all).map{|r| r.send(column)}.uniq
73
- query.nil? ? records : records.select{|r| r.send(column).index(/^#{query}/)}
74
- end
75
- end
76
- end
77
- end
78
-
79
- # which columns are to be picked up by grids and forms
80
- def expose_columns(columns, *args)
81
- if columns == :all
82
- write_inheritable_attribute(:exposed_columns, self.column_names.map(&:to_sym))
83
- else
84
- write_inheritable_attribute(:exposed_columns, columns)
85
- end
86
- end
87
-
88
- def exposed_columns
89
- read_inheritable_attribute(:exposed_columns) || write_inheritable_attribute(:exposed_columns, expose_columns(:all) + virtual_columns)
90
- end
91
-
92
- # virtual "columns" that simply correspond to instance methods of an ActiveRecord class
93
- def virtual_column(config)
94
- if config.is_a?(Symbol)
95
- config = {:name => config}
96
- else
97
- config = {:name => config.keys.first}.merge(config.values.first)
98
- end
99
- write_inheritable_attribute(:virtual_columns, (read_inheritable_attribute(:virtual_columns) || []) << config)
100
- end
101
-
102
- def virtual_columns
103
- read_inheritable_attribute(:virtual_columns) || []
104
- end
105
-
106
- def is_virtual_column?(column)
107
- read_inheritable_attribute(:virtual_columns).keys.include?(column)
108
- end
109
-
110
- #
111
- # Used by Netzke::Grid
112
- #
113
-
114
- DEFAULT_COLUMN_WIDTH = 100
115
-
116
- def default_column_config(config)
117
- config = {:name => config} if config.is_a?(Symbol) # optionally we may get only a column name (as Symbol)
118
- type = (columns_hash[config[:name].to_s] && columns_hash[config[:name].to_s].type) || :virtual
119
-
120
- # general config
121
- res = {
122
- :name => config[:name].to_s || "unnamed",
123
- :label => config[:label] || config[:name].to_s.humanize,
124
- :read_only => config[:name] == :id, # make "id" column read-only by default
125
- :hidden => config[:name] == :id, # hide "id" column by default
126
- :width => DEFAULT_COLUMN_WIDTH,
127
- :shows_as => :text_field
128
- }
129
-
130
- case type
131
- when :integer
132
- res[:shows_as] = :number_field
133
- when :boolean
134
- res[:shows_as] = :checkbox
135
- res[:width] = 50
136
- when :date
137
- res[:shows_as] = :date_field
138
- when :datetime
139
- res[:shows_as] = :datetime
140
- when :string
141
- res[:shows_as] = :text_field
142
- end
143
-
144
- res.merge(config) # merge with custom confg (it has the priority)
145
- end
146
-
147
- #
148
- # Used by Netzke::Form
149
- #
150
-
151
- DEFAULT_FIELD_WIDTH = 100
152
- DEFAULT_FIELD_HEIGHT = 50
153
- def default_field_config(config)
154
- # TODO
155
- end
156
-
157
- end
158
- end
159
- end
160
-
161
- ActiveRecord::Base.class_eval do
162
- include Netzke::ActiveRecordExtensions
163
- end
data/lib/netzke/column.rb DELETED
@@ -1,43 +0,0 @@
1
- module Netzke
2
- class Column
3
- def self.default_columns_for_widget(widget)
4
- raise ArgumentError, "No data_class_name specified for widget #{widget.config[:name]}" if widget.config[:data_class_name].nil?
5
-
6
- # layout = NetzkeLayout.create(:widget_name => widget.id_name, :items_class => self.name, :user_id => NetzkeLayout.user_id)
7
-
8
- data_class = widget.config[:data_class_name].constantize
9
-
10
- exposed_columns = normalize_columns(data_class.exposed_columns) # columns exposed from the data class
11
-
12
- columns_from_config = widget.config[:columns] && normalize_columns(widget.config[:columns]) # columns specified in widget's config
13
-
14
- if columns_from_config
15
- # reverse-merge each column hash from config with each column hash from exposed_columns (columns from config have higher priority)
16
- for c in columns_from_config
17
- corresponding_exposed_column = exposed_columns.find{ |k| k[:name] == c[:name] }
18
- c.reverse_merge!(corresponding_exposed_column) if corresponding_exposed_column
19
- end
20
- columns_for_create = columns_from_config
21
- else
22
- # we didn't have columns configured in widget's config, so, use the columns from the data class
23
- columns_for_create = exposed_columns
24
- end
25
-
26
- res = []
27
- for c in columns_for_create
28
- # finally reverse-merge them with the defaults from the data_class
29
- res << data_class.default_column_config(c)
30
- end
31
-
32
- res
33
- end
34
-
35
- protected
36
-
37
- # like this: [:col1, {:name => :col2}, :col3] => [{:name => :col1}, {:name => :col2}, {:name => :col3}]
38
- def self.normalize_columns(items)
39
- items.map{|c| c.is_a?(Symbol) ? {:name => c} : c}
40
- end
41
-
42
- end
43
- end
@@ -1,81 +0,0 @@
1
- module Netzke
2
- #
3
- # Base class for Accordion and TabPanel widgets, it shouldn't be used as a stand-alone class.
4
- #
5
- class Container < Base
6
- def initialize(*args)
7
- super
8
- for item in initial_items do
9
- add_aggregatee item
10
- items << item.keys.first
11
- end
12
- end
13
-
14
- def initial_dependencies
15
- dep = super
16
- for item in items
17
- candidate_dependency = aggregatees[item][:widget_class_name]
18
- dep << candidate_dependency unless dep.include?(candidate_dependency)
19
- end
20
- dep
21
- end
22
-
23
- def js_before_constructor
24
- js_widget_items
25
- end
26
-
27
- def items
28
- @items ||= []
29
- end
30
-
31
- def initial_items
32
- config[:items] || []
33
- end
34
-
35
- def js_widget_items
36
- res = ""
37
- item_aggregatees.each_pair do |k,v|
38
- next if v[:late_aggregation]
39
- res << <<-JS
40
- var #{k.to_js} = new Ext.componentCache['#{v[:widget_class_name]}'](config.#{k.to_js}Config);
41
- JS
42
- end
43
- res
44
- end
45
-
46
- def js_items
47
- items.inject([]) do |a,i|
48
- a << {
49
- :title => i.to_s.humanize,
50
- :layout => 'fit',
51
- :id => i.to_s,
52
- # :id => "#{config[:name]}_#{i.to_s}",
53
- :items => ([i.to_s.to_js.l] if !aggregatees[i][:late_aggregation]),
54
- # these listeners will be different for tab_panel and accordion
55
- :collapsed => !aggregatees[i][:active],
56
- :listeners => {
57
- # :activate => {:fn => "function(p){this.feedback(p.id)}".l, :scope => this},
58
- :expand => {:fn => "this.loadItemWidget".l, :scope => this}
59
- }
60
- }
61
- end
62
- end
63
-
64
- def js_extend_properties
65
- {
66
- # loads widget into the panel if it's not loaded yet
67
- :load_item_widget => <<-JS.l,
68
- function(panel) {
69
- if (!panel.getWidget()) panel.loadWidget(this.id + "__" + panel.id + "__get_widget");
70
- // if (!this.getWidgetByPanel(panel)) this.loadWidget(panel, this.initialConfig[panel.id+'Config'].interface.getWidget);
71
- }
72
- JS
73
- }
74
- end
75
-
76
- protected
77
- def item_aggregatees
78
- aggregatees.delete_if{|k,v| !@items.include?(k)}
79
- end
80
- end
81
- end
data/lib/netzke/grid.rb DELETED
@@ -1,120 +0,0 @@
1
- require 'searchlogic'
2
- module Netzke
3
- #
4
- # Functionality:
5
- # * data operations - get, post, delete, create
6
- # * column resize and move
7
- # * permissions
8
- # * sorting - TODO
9
- # * pagination
10
- # * validation - TODO
11
- # * properties and column configuration
12
- #
13
- class Grid < Base
14
- include GridJsBuilder
15
- include GridInterface
16
- # define connection points between client side and server side of Grid. See implementation of equally named methods in the GridInterface module.
17
- interface :get_data, :post_data, :delete_data, :resize_column, :move_column, :get_cb_choices
18
-
19
- def initial_config
20
- {
21
- :ext_config => {:properties => true, :column_filters => true},
22
- :layout_manager => "NetzkeLayout",
23
- :column_resize => true,
24
- :column_move => true
25
- }
26
- end
27
-
28
- def property_widgets
29
- [{
30
- :columns => {
31
- :widget_class_name => "Grid",
32
- :data_class_name => column_manager_class_name,
33
- :ext_config => {:title => false, :properties => false},
34
- :active => true
35
- }
36
- },{
37
- :general => {
38
- :widget_class_name => "PreferenceGrid",
39
- :host_widget_name => @id_name,
40
- :default_properties => available_permissions.map{ |k| {:name => "permissions.#{k}", :value => @permissions[k.to_sym]}},
41
- :ext_config => {:title => false}
42
- }
43
- }]
44
- end
45
-
46
- ## Data for properties grid
47
- def properties__columns__get_data(params = {})
48
- columns_widget = aggregatee_instance(:properties__columns)
49
-
50
- layout_id = layout_manager_class.by_widget(id_name).id
51
- columns_widget.interface_get_data(params.merge(:filters => {:layout_id => layout_id}))
52
- end
53
-
54
- def properties__general__load_source(params = {})
55
- w = aggregatee_instance(:properties__general)
56
- w.interface_load_source(params)
57
- end
58
-
59
-
60
-
61
- protected
62
-
63
- def layout_manager_class
64
- config[:layout_manager] && config[:layout_manager].constantize
65
- end
66
-
67
- def column_manager_class_name
68
- "NetzkeGridColumn"
69
- end
70
-
71
- def column_manager_class
72
- column_manager_class_name.constantize
73
- rescue NameError
74
- nil
75
- end
76
-
77
- def available_permissions
78
- %w(read update create delete)
79
- end
80
-
81
- public
82
-
83
- # get columns from layout manager
84
- def get_columns
85
- if layout_manager_class
86
- layout = layout_manager_class.by_widget(id_name)
87
- layout ||= column_manager_class.create_layout_for_widget(self)
88
- layout.items_hash # TODO: bad name!
89
- else
90
- Netzke::Column.default_columns_for_widget(self)
91
- end
92
- end
93
-
94
- def tools
95
- [{:id => 'refresh', :on => {:click => 'refreshClick'}}]
96
- end
97
-
98
- def actions
99
- [{
100
- :text => 'Add', :handler => 'add', :disabled => @pref['permissions.create'] == false
101
- },{
102
- :text => 'Edit', :handler => 'edit', :disabled => @pref['permissions.update'] == false
103
- },{
104
- :text => 'Delete', :handler => 'delete', :disabled => @pref['permissions.delete'] == false
105
- },{
106
- :text => 'Apply', :handler => 'submit', :disabled => @pref['permissions.update'] == false && @pref['permissions.create'] == false
107
- }]
108
- end
109
-
110
-
111
-
112
- # Uncomment to enable a menu duplicating the actions
113
- # def js_menus
114
- # [{:text => "config.dataClassName".l, :menu => "config.actions".l}]
115
- # end
116
-
117
- # include ColumnOperations
118
- include PropertiesTool # it will load aggregation with name :properties into a modal window
119
- end
120
- end