netzke-basepack 0.6.3 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. data/CHANGELOG.rdoc +17 -0
  2. data/README.rdoc +1 -1
  3. data/Rakefile +3 -0
  4. data/TODO.rdoc +1 -4
  5. data/features/form_panel.feature +2 -1
  6. data/features/grid_panel.feature +134 -5
  7. data/features/nested_attributes.feature +4 -1
  8. data/features/paging_form_panel.feature +41 -0
  9. data/features/search_in_grid.feature +20 -7
  10. data/features/step_definitions/form_panel_steps.rb +35 -0
  11. data/features/step_definitions/generic_steps.rb +20 -1
  12. data/features/step_definitions/grid_panel_steps.rb +63 -0
  13. data/features/support/env.rb +4 -0
  14. data/features/validations_in_grid.feature +13 -0
  15. data/features/virtual_attributes.feature +5 -9
  16. data/javascripts/basepack.js +21 -650
  17. data/javascripts/datetimefield.js +24 -0
  18. data/lib/generators/netzke/basepack_generator.rb +10 -0
  19. data/{generators/netzke_basepack/templates/public_assets → lib/generators/netzke/templates/assets}/ts-checkbox.gif +0 -0
  20. data/{generators/netzke_basepack → lib/generators/netzke}/templates/create_netzke_field_lists.rb +0 -0
  21. data/lib/netzke-basepack.rb +3 -41
  22. data/lib/netzke/active_record/attributes.rb +17 -21
  23. data/lib/netzke/basepack.rb +6 -1
  24. data/lib/netzke/basepack/data_accessor.rb +166 -0
  25. data/lib/netzke/basepack/form_panel.rb +69 -20
  26. data/lib/netzke/basepack/form_panel/fields.rb +15 -17
  27. data/lib/netzke/basepack/form_panel/javascripts/comma_list_cbg.js +7 -0
  28. data/lib/netzke/basepack/form_panel/javascripts/display_mode.js +6 -0
  29. data/lib/netzke/basepack/form_panel/javascripts/{main.js → form_panel.js} +42 -8
  30. data/lib/netzke/basepack/form_panel/javascripts/n_radio_group.js +24 -7
  31. data/lib/netzke/basepack/form_panel/javascripts/readonly_mode.js +52 -0
  32. data/lib/netzke/basepack/form_panel/services.rb +28 -2
  33. data/lib/netzke/basepack/form_panel/stylesheets/readonly_mode.css +14 -0
  34. data/lib/netzke/basepack/grid_panel.rb +151 -181
  35. data/lib/netzke/basepack/grid_panel/columns.rb +122 -84
  36. data/lib/netzke/basepack/grid_panel/javascripts/advanced_search.js +22 -27
  37. data/lib/netzke/basepack/grid_panel/javascripts/{main.js → grid_panel.js} +182 -108
  38. data/lib/netzke/basepack/grid_panel/record_form_window.rb +7 -2
  39. data/lib/netzke/basepack/grid_panel/services.rb +58 -39
  40. data/lib/netzke/basepack/paging_form_panel.rb +86 -25
  41. data/lib/netzke/basepack/query_builder.rb +105 -0
  42. data/lib/netzke/basepack/query_builder/javascripts/query_builder.js +140 -0
  43. data/lib/netzke/basepack/search_panel.rb +61 -44
  44. data/lib/netzke/basepack/search_panel/javascripts/condition_field.js +153 -0
  45. data/lib/netzke/basepack/search_panel/javascripts/search_panel.js +64 -0
  46. data/lib/netzke/basepack/search_window.rb +64 -0
  47. data/lib/netzke/basepack/simple_app.rb +1 -1
  48. data/lib/netzke/basepack/simple_app/javascripts/{main.js → simple_app.js} +0 -0
  49. data/lib/netzke/basepack/tab_panel.rb +1 -2
  50. data/lib/netzke/basepack/tab_panel/javascripts/{main.js → tab_panel.js} +0 -0
  51. data/lib/netzke/basepack/version.rb +1 -1
  52. data/locales/en.yml +71 -4
  53. data/netzke-basepack.gemspec +47 -22
  54. data/spec/active_record/attributes_spec.rb +6 -6
  55. data/spec/components/form_panel_spec.rb +2 -13
  56. data/stylesheets/datetimefield.css +54 -0
  57. data/test/rails_app/Gemfile +3 -3
  58. data/test/rails_app/Gemfile.lock +67 -57
  59. data/test/rails_app/README +1 -256
  60. data/test/rails_app/app/components/book_form.rb +1 -3
  61. data/test/rails_app/app/components/book_form_with_custom_fields.rb +20 -0
  62. data/test/rails_app/app/components/book_form_with_nested_attributes.rb +18 -0
  63. data/test/rails_app/app/components/book_grid.rb +3 -1
  64. data/test/rails_app/app/components/book_grid_loader.rb +24 -0
  65. data/test/rails_app/app/components/book_grid_with_custom_columns.rb +28 -0
  66. data/test/rails_app/app/components/book_grid_with_default_values.rb +1 -1
  67. data/test/rails_app/app/components/book_grid_with_virtual_attributes.rb +0 -1
  68. data/test/rails_app/app/components/book_paging_form_panel.rb +3 -2
  69. data/test/rails_app/app/components/book_presentation.rb +3 -3
  70. data/test/rails_app/app/components/book_query_builder.rb +8 -0
  71. data/test/rails_app/app/components/book_search_panel.rb +5 -0
  72. data/test/rails_app/app/components/book_search_panel/javascripts/i18n_de.js +6 -0
  73. data/test/rails_app/app/components/double_book_grid.rb +18 -0
  74. data/test/rails_app/app/components/form_without_model.rb +1 -1
  75. data/test/rails_app/app/components/paging_form_with_search.rb +39 -0
  76. data/test/rails_app/app/components/user_grid.rb +1 -1
  77. data/test/rails_app/app/models/author.rb +1 -0
  78. data/test/rails_app/config/application.rb +6 -1
  79. data/test/rails_app/config/database.yml +7 -5
  80. data/test/rails_app/config/environments/test.rb +1 -1
  81. data/test/rails_app/config/locales/de.yml +35 -0
  82. data/test/rails_app/config/locales/es.yml +84 -8
  83. data/test/rails_app/db/migrate/20101026190021_create_books.rb +2 -2
  84. data/test/rails_app/db/migrate/20110213213050_create_netzke_component_states.rb +20 -0
  85. data/test/rails_app/db/schema.rb +2 -18
  86. data/test/rails_app/public/netzke/basepack/ts-checkbox.gif +0 -0
  87. data/test/unit/active_record_basepack_test.rb +1 -1
  88. metadata +46 -45
  89. data/generators/netzke_basepack/netzke_basepack_generator.rb +0 -13
  90. data/lib/netzke/basepack/grid_panel/search_window.rb +0 -56
  91. data/lib/netzke/data_accessor.rb +0 -113
  92. data/lib/netzke/ext.rb +0 -7
  93. data/lib/netzke/fields_configurator.rb +0 -170
  94. data/lib/netzke/json_array_editor.rb +0 -67
  95. data/lib/netzke/masquerade_selector.rb +0 -53
  96. data/test/rails_app/app/components/some_search_panel.rb +0 -34
  97. data/test/rails_app/db/development_structure.sql +0 -93
  98. data/test/rails_app/db/migrate/20100905214933_create_netzke_preferences.rb +0 -16
@@ -1,113 +0,0 @@
1
- require 'netzke/active_record'
2
-
3
- module Netzke
4
- # This module is included into such data-driven components as GridPanel, FormPanel, etc.
5
- module DataAccessor
6
-
7
- # Returns options for comboboxes in grids/forms
8
- def combobox_options_for_column(column, method_options = {})
9
- query = method_options[:query]
10
-
11
- # First, check if we have options for this column defined in persistent storage
12
- options = column[:combobox_options] && column[:combobox_options].split("\n")
13
- if options
14
- query ? options.select{ |o| o.index(/^#{query}/) }.map{ |el| [el] } : options
15
- else
16
- assoc, assoc_method = assoc_and_assoc_method_for_column(column)
17
-
18
- if assoc
19
- # Options for an asssociation attribute
20
-
21
- relation = assoc.klass.scoped
22
-
23
- relation = relation.extend_with(method_options[:scope]) if method_options[:scope]
24
-
25
- if assoc.klass.column_names.include?(assoc_method)
26
- # apply query
27
- relation = relation.where(:"#{assoc_method}".like => "#{query}%") if query.present?
28
- relation.all.map{ |r| [r.send(assoc_method)] }
29
- else
30
- relation.all.map{ |r| r.send(assoc_method) }.select{ |value| value =~ /^#{query}/ }.map{ |v| [v] }
31
- end
32
-
33
- else
34
- # Options for a non-association attribute
35
- res=data_class.netzke_combo_options_for(column[:name], method_options)
36
-
37
- # ensure it is an array-in-array, as Ext will fail otherwise
38
- raise RuntimeError, "netzke_combo_options_for should return an Array" unless res.kind_of? Array
39
- return [[]] if res.empty?
40
-
41
- unless res.first.kind_of? Array
42
- res=res.map do |v|
43
- [v]
44
- end
45
- end
46
- return res
47
-
48
-
49
- end
50
- end
51
- end
52
-
53
- # Normalize array of attributes
54
- # [:col1, "col2", {:name => :col3}] =>
55
- # [{:name => "col1"}, {:name => "col2"}, {:name => "col3"}]
56
- def normalize_attrs(attrs)
57
- attrs.map{ |a| normalize_attr(a) }
58
- end
59
-
60
- # Normalize an attribute, e.g.:
61
- # :first_name =>
62
- # {:name => "first_name"}
63
- def normalize_attr(a)
64
- a.is_a?(Symbol) || a.is_a?(String) ? {:name => a.to_s} : a.merge(:name => a[:name].to_s)
65
- end
66
-
67
- # Returns association and association method for a column
68
- def assoc_and_assoc_method_for_column(c)
69
- assoc_name, assoc_method = c[:name].split('__')
70
- assoc = data_class.reflect_on_association(assoc_name.to_sym) if assoc_method
71
- [assoc, assoc_method]
72
- end
73
-
74
- def association_attr?(name)
75
- !!name.to_s.index("__")
76
- end
77
-
78
- # Model class
79
- # (We can't memoize this method because at some point we extend it, e.g. in Netzke::DataAccessor)
80
- def data_class
81
- @data_class ||= begin
82
- klass = constantize_class_name("Netzke::ModelExtensions::#{config[:model]}For#{short_component_class_name}") || original_data_class
83
- end
84
- end
85
-
86
- # Model class before model extensions are taken into account
87
- def original_data_class
88
- @original_data_class ||= begin
89
- ::ActiveSupport::Deprecation.warn("data_class_name option is deprecated. Use model instead", caller) if config[:data_class_name]
90
- model_name = config[:model] || config[:data_class_name]
91
- model_name && constantize_class_name(model_name)
92
- end
93
- end
94
-
95
- # whether a column is bound to the primary_key
96
- def primary_key_attr?(a)
97
- data_class && a[:name].to_s == data_class.primary_key
98
- end
99
-
100
- # Mark an attribute as "virtual" by default, when it doesn't reflect a model column, or a model column of an association
101
- def set_default_virtual(c)
102
- if c[:virtual].nil? # sometimes at maybe handy to mark a column as non-virtual forcefully
103
- assoc, assoc_method = get_assoc_and_method(c)
104
- if assoc
105
- c[:virtual] = true if !assoc.klass.column_names.map(&:to_sym).include?(assoc_method.to_sym)
106
- else
107
- c[:virtual] = true if !data_class.column_names.map(&:to_sym).include?(c[:name].to_sym)
108
- end
109
- end
110
- end
111
-
112
- end
113
- end
data/lib/netzke/ext.rb DELETED
@@ -1,7 +0,0 @@
1
- module Netzke
2
- # Ext-related module. Some constants provide meta-information about the Ext.library.
3
- module Ext
4
- FORM_FIELD_XTYPES = %w{ textfield numberfield textarea combobox checkbox xdatetime }
5
- COLUMN_XTYPES = %w{ gridcolumn booleancolumn numbercolumn datecolumn }
6
- end
7
- end
@@ -1,170 +0,0 @@
1
- module Netzke
2
- # == FieldsConfigurator
3
- # Provides dynamic configuring columns/fields for GridPanel and FormPanel.
4
- # Configuration parameters:
5
- # * <tt>:component</tt> - component to configure columns/fields for
6
- class FieldsConfigurator < JsonArrayEditor
7
- api :load_defaults
8
-
9
- def default_config
10
- super.deep_merge({
11
- :name => 'columns',
12
- :ext_config => {
13
- :config_tool => false,
14
- :header => false,
15
- :enable_extended_search => false,
16
- :enable_edit_in_form => false,
17
- :enable_rows_reordering => GridPanel.rows_reordering_available,
18
- :enable_pagination => false
19
- }
20
- })
21
- end
22
-
23
- action :defaults, {:text => 'Restore defaults', :icon => :wand}
24
-
25
- def default_bbar
26
- %w{ add edit apply del }.map(&:action) + "-" + [:defaults.action]
27
- end
28
-
29
- # Default columns for the configurator
30
- def default_columns
31
- [
32
- {:name => "id", :attr_type => :integer, :meta => true},
33
- {:name => "position", :attr_type => :integer, :meta => true},
34
- {:name => "attr_type", :attr_type => :string, :meta => true},
35
- *config[:owner].class.meta_columns.map { |c| c[:name] == "name" ? inject_combo_for_name_column(c) : c }
36
- ]
37
- end
38
-
39
- def self.js_properties
40
- {
41
- :init_component => <<-END_OF_JAVASCRIPT.l,
42
- function(){
43
- #{js_full_class_name}.superclass.initComponent.call(this);
44
-
45
- // Automatically set the correct editor for the default_value column
46
- this.on('beforeedit', function(e){
47
- var column = this.getColumnModel().getColumnById(this.getColumnModel().getColumnId(e.column));
48
- var record = this.getStore().getAt(e.row);
49
-
50
- if (column.dataIndex === "default_value") {
51
- if (record.get("name") === this.pri) {
52
- // Don't allow setting default value for the primary key
53
- column.setEditor(null);
54
- } else {
55
- // Auto set the editor, dependent on the field type
56
- var attrType = record.get("attr_type");
57
- column.setEditor(Ext.create({xtype: this.attrTypeEditorMap[attrType] || "textfield"}));
58
- }
59
- }
60
-
61
- }, this);
62
-
63
- }
64
- END_OF_JAVASCRIPT
65
-
66
- :attr_type_editor_map => {
67
- :integer => "numberfield",
68
- :boolean => "checkbox",
69
- :decimal => "numberfield",
70
- :datetime => "xdatetime",
71
- :date => "datefield",
72
- :string => "textfield"
73
- },
74
-
75
- # Disable the 'gear' tool for now
76
- :on_gear => <<-END_OF_JAVASCRIPT.l,
77
- function(){
78
- this.feedback("You can't configure configurator (yet)");
79
- }
80
- END_OF_JAVASCRIPT
81
-
82
- # we need to provide this function so that the server-side commit would happen
83
- :get_commit_data => <<-END_OF_JAVASCRIPT.l,
84
- function(){
85
- return null; // because our commit data is already at the server
86
- }
87
- END_OF_JAVASCRIPT
88
-
89
- :on_defaults => <<-END_OF_JAVASCRIPT.l,
90
- function(){
91
- Ext.Msg.confirm('Confirm', 'Are you sure?', function(btn){
92
- if (btn == 'yes') {
93
- this.loadDefaults();
94
- }
95
- }, this);
96
- }
97
- END_OF_JAVASCRIPT
98
- }
99
- end
100
-
101
- def load_defaults(params)
102
- # Reload the temp table with default values
103
- data_class.replace_data(default_owner_fields)
104
-
105
- # ... and reflect it in the persistent storage
106
- on_data_changed
107
-
108
- # Update the grid
109
- {:load_store_data => get_data}
110
- end
111
-
112
- # Never show the config tool
113
- def config_tool_needed?
114
- false
115
- end
116
-
117
- private
118
-
119
- # An override
120
- def process_data(data, operation)
121
- if operation == :update
122
- meta_attrs_to_update = data.inject({}) do |r,el|
123
- r.merge({
124
- data_class.find(el["id"]).name => el.reject{ |k,v| k == "id" }
125
- })
126
- end
127
-
128
- res = super
129
-
130
- NetzkeFieldList.update_fields(config[:owner].global_id, meta_attrs_to_update)
131
-
132
- res
133
- else
134
- super
135
- end
136
- end
137
-
138
- # An override
139
- def store_data(data)
140
- NetzkeFieldList.update_list_for_current_authority(config[:owner].global_id, data, config[:owner].data_class.name)
141
- end
142
-
143
- # An override
144
- def initial_data
145
- NetzkeFieldList.read_list(config[:owner].global_id) || default_owner_fields
146
- end
147
-
148
- # Set strict combo for the "name" column, with options of the attributes provided by the data_class
149
- def inject_combo_for_name_column(c)
150
- netzke_attrs = config[:owner].data_class.netzke_attributes.map{ |a| a[:name] }
151
- c.merge(:editor => {:xtype => :combo, :store => netzke_attrs, :force_selection => true})
152
- end
153
-
154
- def default_owner_fields
155
- config[:owner].initial_columns(false).map(&:deebeefy_values)
156
- end
157
-
158
- # This is an override of GridPanel#on_data_changed
159
- def on_data_changed
160
- # Default column settings taken from
161
- defaults_hash = config[:owner].class.meta_columns.inject({}){ |r, c| r.merge!(c[:name] => c[:default_value]) }
162
- stripped_columns = data_class.all_columns.map do |c|
163
- # reject all keys that are 1) same as defaults
164
- c.reject{ |k,v| defaults_hash[k.to_sym].to_s == v.to_s }
165
- end
166
- store_data(stripped_columns)
167
- end
168
-
169
- end
170
- end
@@ -1,67 +0,0 @@
1
- module Netzke
2
- # Abstract GridPanel-based editor for a JSON array of homogenious objects.
3
- # Inherit from it in order to override:
4
- # <tt>store_data</p> - passes the data to be saved (e.g. to the persistant storage)
5
- # <tt>initial_data</p> - should return initial data (e.g. from the persistant storage)
6
- # For an example of an implementation, see Netzke::FieldsConfigurator.
7
- class JsonArrayEditor < GridPanel
8
- def initialize(*args)
9
- super
10
- data_class.configure(:owner => global_id, :columns => dynamic_fields, :initial_data => initial_data)
11
- end
12
-
13
- def data_class
14
- NetzkePersistentArrayAutoModel
15
- end
16
-
17
- # Fields for NetzkePersistentArrayAutoModel (override it)
18
- def dynamic_fields
19
- default_columns.collect do |c|
20
- {
21
- :name => c[:name],
22
- :type => c[:attr_type] == :json ? :text : c[:attr_type], # store :json columns as :text
23
- :default => c[:default_value]
24
- }
25
- end
26
- end
27
-
28
- # Default predifined columns (override if needed)
29
- def default_columns
30
- [{
31
- :name => :id,
32
- :attr_type => :integer
33
- },{
34
- :name => :name,
35
- :attr_type => :string
36
- },{
37
- :name => :position,
38
- :attr_type => :integer
39
- }]
40
- end
41
-
42
- # Don't show the config tool
43
- # def config_tool_needed?
44
- # false
45
- # end
46
-
47
- def before_load
48
- data_class.rebuild_table
49
- super
50
- end
51
-
52
- private
53
- # Override this
54
- def store_data(data); end
55
-
56
- # Override this
57
- def initial_data
58
- []
59
- end
60
-
61
- # This is an override of GridPanel#on_data_changed
62
- def on_data_changed
63
- store_data(data_class.all_columns)
64
- end
65
-
66
- end
67
- end
@@ -1,53 +0,0 @@
1
- module Netzke
2
- class MasqueradeSelector < TabPanel
3
-
4
- def items
5
- @items ||= [{
6
- :name => "roles",
7
- :active => true,
8
- :class_name => "GridPanel",
9
- :model => 'Role',
10
- :columns => [:id, :name],
11
- :ext_config => {
12
- :header => false,
13
- :bbar => ['search']
14
- }
15
- },{
16
- :name => "users",
17
- :preloaded => true,
18
- :class_name => "GridPanel",
19
- :model => 'User',
20
- :ext_config => {
21
- :header => false,
22
- :rows_per_page => 10,
23
- :bbar => ['search']
24
- },
25
- :columns => [:id, :login]
26
- }]
27
- end
28
-
29
- def self.js_properties
30
- {
31
- :after_constructor => <<-END_OF_JAVASCRIPT.l,
32
- function(){
33
- this.items.each(function(tab){
34
- tab.on('add', function(ct, cmp){
35
- cmp.on('rowclick', this.rowclickHandler, this);
36
- }, this);
37
- }, this);
38
- }
39
- END_OF_JAVASCRIPT
40
-
41
- :rowclick_handler => <<-END_OF_JAVASCRIPT.l
42
- function(grid, rowIndex, e){
43
- var mode = grid.id.split("__").pop();
44
- var normMode = mode === 'users' ? 'user' : 'role';
45
- this.masquerade = {};
46
- this.masquerade[normMode] = grid.store.getAt(rowIndex).get('id');
47
- }
48
- END_OF_JAVASCRIPT
49
- }
50
- end
51
-
52
- end
53
- end
@@ -1,34 +0,0 @@
1
- class SomeSearchPanel < Netzke::Basepack::FormPanel
2
- def config
3
- orig = super
4
- {
5
- :model => "User",
6
- :title => "Some Search Panel",
7
- :items => [{:name => :first_name.like}, {:name => :created_at.gt}]
8
- }.deep_merge orig
9
- end
10
-
11
- def normalize_field(f)
12
- f = if f.is_a?(Symbol) || f.is_a?(String)
13
- {:name => f.to_s, :operator => default_operator}
14
- else
15
- search_condition = f[:name]
16
- if search_condition.is_a?(MetaWhere::Column)
17
- {:name => search_condition.column, :operator => search_condition.method}
18
- else
19
- {:name => search_condition.to_s, :operator => default_operator}
20
- end
21
- end
22
-
23
- f[:disabled] = primary_key_attr?(f)
24
-
25
- f = super(f)
26
-
27
- f.merge(:name => [f[:name], "__", f[:operator]].join)
28
- end
29
-
30
- private
31
- def default_operator
32
- "gt"
33
- end
34
- end