netzke-basepack 0.7.7 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (192) hide show
  1. data/.travis.yml +15 -10
  2. data/{CHANGELOG.rdoc → CHANGELOG.md} +146 -110
  3. data/LICENSE +7 -1
  4. data/README.md +47 -56
  5. data/Rakefile +5 -5
  6. data/config/before-travis.sh +10 -0
  7. data/javascripts/basepack.js +0 -130
  8. data/javascripts/netzkeremotecombo.js +59 -0
  9. data/lib/netzke/basepack.rb +9 -14
  10. data/lib/netzke/basepack/accordion.rb +45 -0
  11. data/lib/netzke/basepack/active_record.rb +12 -0
  12. data/lib/netzke/basepack/active_record/relation_extensions.rb +27 -0
  13. data/lib/netzke/basepack/columns.rb +309 -0
  14. data/lib/netzke/basepack/data_accessor.rb +22 -12
  15. data/lib/netzke/basepack/data_adapters/abstract_adapter.rb +75 -11
  16. data/lib/netzke/basepack/data_adapters/active_record_adapter.rb +154 -49
  17. data/lib/netzke/basepack/fields.rb +162 -0
  18. data/lib/netzke/basepack/form.rb +136 -0
  19. data/lib/netzke/basepack/{form_panel → form}/javascripts/comma_list_cbg.js +0 -1
  20. data/lib/netzke/basepack/{form_panel/javascripts/form_panel.js → form/javascripts/form.js} +20 -26
  21. data/lib/netzke/basepack/{form_panel → form}/javascripts/n_radio_group.js +0 -1
  22. data/lib/netzke/basepack/{form_panel → form}/javascripts/readonly_mode.js +0 -0
  23. data/lib/netzke/basepack/form/services.rb +115 -0
  24. data/lib/netzke/basepack/{form_panel → form}/stylesheets/readonly_mode.css +0 -0
  25. data/lib/netzke/basepack/grid.rb +355 -0
  26. data/lib/netzke/basepack/{grid_panel → grid}/javascripts/advanced_search.js +1 -1
  27. data/lib/netzke/basepack/{grid_panel → grid}/javascripts/check_column_fix.js +0 -0
  28. data/lib/netzke/basepack/{grid_panel → grid}/javascripts/edit_in_form.js +3 -3
  29. data/lib/netzke/basepack/{grid_panel → grid}/javascripts/event_handling.js +5 -2
  30. data/lib/netzke/basepack/{grid_panel/javascripts/grid_panel.js → grid/javascripts/grid.js} +120 -132
  31. data/lib/netzke/basepack/{grid_panel → grid}/javascripts/misc.js +0 -0
  32. data/lib/netzke/basepack/grid/services.rb +216 -0
  33. data/lib/netzke/basepack/item_persistence.rb +44 -0
  34. data/lib/netzke/basepack/item_persistence/events_plugin.rb +47 -0
  35. data/lib/netzke/basepack/{paging_form_panel.rb → paging_form.rb} +24 -30
  36. data/lib/netzke/basepack/{paging_form_panel/javascripts/paging_form_panel.js → paging_form/javascripts/paging_form.js} +2 -4
  37. data/lib/netzke/basepack/query_builder.rb +44 -73
  38. data/lib/netzke/basepack/query_builder/javascripts/query_builder.js +16 -2
  39. data/lib/netzke/basepack/record_form_window.rb +67 -0
  40. data/lib/netzke/basepack/search_panel.rb +22 -24
  41. data/lib/netzke/basepack/search_panel/javascripts/condition_field.js +2 -2
  42. data/lib/netzke/basepack/search_window.rb +47 -53
  43. data/lib/netzke/basepack/simple_app.rb +10 -13
  44. data/lib/netzke/basepack/simple_app/javascripts/simple_app.js +2 -8
  45. data/lib/netzke/basepack/tab_panel.rb +5 -4
  46. data/lib/netzke/basepack/tab_panel/javascripts/tab_panel.js +5 -5
  47. data/lib/netzke/basepack/version.rb +2 -2
  48. data/lib/netzke/basepack/viewport.rb +16 -0
  49. data/lib/netzke/basepack/window.rb +27 -18
  50. data/lib/netzke/basepack/window/javascripts/window.js +7 -1
  51. data/lib/netzke/basepack/wrap_lazy_loaded.rb +18 -18
  52. data/locales/en.yml +40 -24
  53. data/netzke-basepack.gemspec +51 -82
  54. data/stylesheets/basepack.css +0 -41
  55. data/test/basepack_test_app/Gemfile +9 -46
  56. data/test/basepack_test_app/Gemfile.lock +61 -96
  57. data/test/basepack_test_app/app/components/author_form.rb +8 -5
  58. data/test/basepack_test_app/app/components/author_grid.rb +2 -2
  59. data/test/basepack_test_app/app/components/book_form.rb +34 -31
  60. data/test/basepack_test_app/app/components/book_form_with_defaults.rb +6 -7
  61. data/test/basepack_test_app/app/components/book_form_with_file_upload.rb +10 -0
  62. data/test/basepack_test_app/app/components/book_form_with_nested_attributes.rb +5 -6
  63. data/test/basepack_test_app/app/components/book_grid.rb +19 -8
  64. data/test/basepack_test_app/app/components/book_grid_filtering.rb +4 -7
  65. data/test/basepack_test_app/app/components/book_grid_loader.rb +28 -15
  66. data/test/basepack_test_app/app/components/book_grid_with_custom_columns.rb +45 -21
  67. data/test/basepack_test_app/app/components/book_grid_with_default_values.rb +26 -8
  68. data/test/basepack_test_app/app/components/book_grid_with_excluded_columns.rb +11 -0
  69. data/test/basepack_test_app/app/components/book_grid_with_extra_feedback.rb +2 -2
  70. data/test/basepack_test_app/app/components/book_grid_with_extra_filters.rb +7 -6
  71. data/test/basepack_test_app/app/components/book_grid_with_mass_assignment_security.rb +9 -0
  72. data/test/basepack_test_app/app/components/book_grid_with_nested_attributes.rb +9 -9
  73. data/test/basepack_test_app/app/components/book_grid_with_overridden_columns.rb +5 -3
  74. data/test/basepack_test_app/app/components/book_grid_with_paging.rb +6 -8
  75. data/test/basepack_test_app/app/components/book_grid_with_persistence.rb +6 -4
  76. data/test/basepack_test_app/app/components/book_grid_with_scope.rb +6 -0
  77. data/test/basepack_test_app/app/components/book_grid_with_scoped_authors.rb +10 -7
  78. data/test/basepack_test_app/app/components/book_grid_with_virtual_attributes.rb +21 -13
  79. data/test/basepack_test_app/app/components/book_paging_form.rb +21 -0
  80. data/test/basepack_test_app/app/components/book_query_builder.rb +7 -6
  81. data/test/basepack_test_app/app/components/book_with_custom_primary_key_grid.rb +6 -7
  82. data/test/basepack_test_app/app/components/books_bound_to_author.rb +9 -7
  83. data/test/basepack_test_app/app/components/border_layout_panel_with_persistence.rb +12 -0
  84. data/test/basepack_test_app/app/components/double_book_grid.rb +19 -14
  85. data/test/basepack_test_app/app/components/form_without_model.rb +15 -16
  86. data/test/basepack_test_app/app/components/grid_with_initial_sorting.rb +7 -0
  87. data/test/basepack_test_app/app/components/grid_with_inline_data.rb +7 -0
  88. data/test/basepack_test_app/app/components/paging_form_with_search.rb +2 -2
  89. data/test/basepack_test_app/app/components/panel_with_persistent_regions.rb +35 -0
  90. data/test/basepack_test_app/app/components/query_builder.rb +7 -0
  91. data/test/basepack_test_app/app/components/simple_panel.rb +16 -11
  92. data/test/basepack_test_app/app/components/simple_window.rb +7 -6
  93. data/test/basepack_test_app/app/components/some_accordion.rb +18 -0
  94. data/test/basepack_test_app/app/components/some_auth_app.rb +5 -5
  95. data/test/basepack_test_app/app/components/some_border_layout.rb +20 -20
  96. data/test/basepack_test_app/app/components/some_search_panel.rb +6 -0
  97. data/test/basepack_test_app/app/components/some_simple_app.rb +30 -16
  98. data/test/basepack_test_app/app/components/some_tab_panel.rb +18 -15
  99. data/test/basepack_test_app/app/components/user_form.rb +18 -16
  100. data/test/basepack_test_app/app/components/user_form_with_default_fields.rb +5 -6
  101. data/test/basepack_test_app/app/components/user_grid.rb +11 -6
  102. data/test/basepack_test_app/app/components/user_grid_with_customized_form_fields.rb +5 -3
  103. data/test/basepack_test_app/app/components/window_component_loader.rb +25 -21
  104. data/test/basepack_test_app/app/models/address.rb +0 -26
  105. data/test/basepack_test_app/app/models/author.rb +0 -31
  106. data/test/basepack_test_app/app/models/book.rb +1 -42
  107. data/test/basepack_test_app/app/models/book_with_custom_primary_key.rb +1 -23
  108. data/test/basepack_test_app/app/models/role.rb +0 -21
  109. data/test/basepack_test_app/app/models/user.rb +0 -24
  110. data/test/basepack_test_app/app/views/layouts/components.html.erb +1 -1
  111. data/test/basepack_test_app/config/application.rb +1 -1
  112. data/test/basepack_test_app/config/database.yml.travis +2 -6
  113. data/test/basepack_test_app/config/initializers/netzke.rb +1 -6
  114. data/test/basepack_test_app/db/schema.rb +14 -14
  115. data/test/basepack_test_app/features/accordion_panel.feature +2 -2
  116. data/test/basepack_test_app/features/form_panel.feature +7 -7
  117. data/test/basepack_test_app/features/grid_panel.feature +93 -39
  118. data/test/basepack_test_app/features/grid_panel_with_custom_primary_key.feature +2 -1
  119. data/test/basepack_test_app/features/grid_sorting.feature +30 -6
  120. data/test/basepack_test_app/features/paging_form_panel.feature +7 -7
  121. data/test/basepack_test_app/features/persistent_regions.feature +30 -0
  122. data/test/basepack_test_app/features/search_in_grid.feature +5 -5
  123. data/test/basepack_test_app/features/simple_app.feature +6 -7
  124. data/test/basepack_test_app/features/step_definitions/form_panel_steps.rb +1 -1
  125. data/test/basepack_test_app/features/step_definitions/generic_steps.rb +109 -4
  126. data/test/basepack_test_app/features/step_definitions/grid_panel_steps.rb +8 -10
  127. data/test/basepack_test_app/features/step_definitions/window_steps.rb +27 -0
  128. data/test/basepack_test_app/features/tab_panel.feature +1 -1
  129. data/test/basepack_test_app/features/window.feature +17 -0
  130. data/test/unit/accordion_panel_test.rb +2 -2
  131. data/test/unit/grid_panel_test.rb +4 -4
  132. metadata +57 -83
  133. data/TODO.rdoc +0 -8
  134. data/lib/generators/netzke/basepack_generator.rb +0 -10
  135. data/lib/generators/netzke/templates/assets/ts-checkbox.gif +0 -0
  136. data/lib/generators/netzke/templates/create_netzke_field_lists.rb +0 -18
  137. data/lib/netzke/active_record.rb +0 -20
  138. data/lib/netzke/active_record/attributes.rb +0 -259
  139. data/lib/netzke/active_record/combobox_options.rb +0 -16
  140. data/lib/netzke/active_record/relation_extensions.rb +0 -37
  141. data/lib/netzke/basepack/accordion_panel.rb +0 -39
  142. data/lib/netzke/basepack/action_column.rb +0 -68
  143. data/lib/netzke/basepack/action_column/javascripts/action_column.js +0 -61
  144. data/lib/netzke/basepack/auth_app.rb +0 -159
  145. data/lib/netzke/basepack/basic_app.rb +0 -7
  146. data/lib/netzke/basepack/border_layout_panel.rb +0 -53
  147. data/lib/netzke/basepack/border_layout_panel/javascripts/border_layout_panel.js +0 -40
  148. data/lib/netzke/basepack/data_adapters/data_mapper_adapter.rb +0 -264
  149. data/lib/netzke/basepack/data_adapters/sequel_adapter.rb +0 -260
  150. data/lib/netzke/basepack/form_panel.rb +0 -144
  151. data/lib/netzke/basepack/form_panel/fields.rb +0 -208
  152. data/lib/netzke/basepack/form_panel/javascripts/misc.js +0 -4
  153. data/lib/netzke/basepack/form_panel/services.rb +0 -142
  154. data/lib/netzke/basepack/grid_panel.rb +0 -441
  155. data/lib/netzke/basepack/grid_panel/columns.rb +0 -400
  156. data/lib/netzke/basepack/grid_panel/javascripts/rows-dd.js +0 -281
  157. data/lib/netzke/basepack/grid_panel/record_form_window.rb +0 -41
  158. data/lib/netzke/basepack/grid_panel/services.rb +0 -235
  159. data/lib/netzke/basepack/panel.rb +0 -11
  160. data/lib/netzke/basepack/wrapper.rb +0 -28
  161. data/lib/netzke/data_mapper.rb +0 -18
  162. data/lib/netzke/data_mapper/attributes.rb +0 -273
  163. data/lib/netzke/data_mapper/combobox_options.rb +0 -11
  164. data/lib/netzke/data_mapper/relation_extensions.rb +0 -38
  165. data/lib/netzke/sequel.rb +0 -18
  166. data/lib/netzke/sequel/attributes.rb +0 -274
  167. data/lib/netzke/sequel/combobox_options.rb +0 -10
  168. data/lib/netzke/sequel/relation_extensions.rb +0 -40
  169. data/locales/zh-cn.yml +0 -79
  170. data/test/basepack_test_app/app/components/book_form_with_custom_fields.rb +0 -21
  171. data/test/basepack_test_app/app/components/book_grid_with_column_actions.rb +0 -15
  172. data/test/basepack_test_app/app/components/book_grid_with_defaults.rb +0 -6
  173. data/test/basepack_test_app/app/components/book_paging_form_panel.rb +0 -22
  174. data/test/basepack_test_app/app/components/generic_user_form.rb +0 -12
  175. data/test/basepack_test_app/app/components/simple_accordion.rb +0 -11
  176. data/test/basepack_test_app/app/components/simple_tab_panel.rb +0 -11
  177. data/test/basepack_test_app/app/components/simple_wrapper.rb +0 -7
  178. data/test/basepack_test_app/app/components/some_accordion_panel.rb +0 -22
  179. data/test/basepack_test_app/app/presenters/forms/generic_user.rb +0 -6
  180. data/test/basepack_test_app/app/views/components/loadable_window.html.erb +0 -9
  181. data/test/basepack_test_app/app/views/components/simple_panel.html.erb +0 -1
  182. data/test/basepack_test_app/features/components_in_view.feature +0 -11
  183. data/test/basepack_test_app/features/simple_panel.feature +0 -11
  184. data/test/basepack_test_app/features/validations_in_grid.feature +0 -13
  185. data/test/basepack_test_app/features/virtual_attributes.feature +0 -16
  186. data/test/basepack_test_app/spec/components/form_panel_spec.rb +0 -53
  187. data/test/basepack_test_app/spec/components/grid_panel_spec.rb +0 -10
  188. data/test/basepack_test_app/spec/data_adapter/adapter_spec.rb +0 -68
  189. data/test/basepack_test_app/spec/data_adapter/attributes_spec.rb +0 -56
  190. data/test/basepack_test_app/spec/data_adapter/relation_extensions_spec.rb +0 -125
  191. data/test/basepack_test_app/spec/factories.rb +0 -28
  192. data/test/basepack_test_app/spec/spec_helper.rb +0 -39
@@ -1,400 +0,0 @@
1
- module Netzke
2
- module Basepack
3
- class GridPanel < Netzke::Base
4
- module Columns
5
- extend ActiveSupport::Concern
6
- extend ActiveSupport::Memoizable
7
-
8
- # module ClassMethods
9
- # # Columns to be displayed by the FieldConfigurator, "meta-columns". Each corresponds to a configuration
10
- # # option for each column in the grid.
11
- # def meta_columns
12
- # [
13
- # # Whether the column will be present in the grid, also in :hidden or :meta state. The value for this column will
14
- # # always be sent to/from the JS grid to the server
15
- # {:name => "included", :attr_type => :boolean, :width => 40, :header => "Incl", :default_value => true},
16
- #
17
- # # The name of the column. May be any accessible method or attribute of the data_class.
18
- # {:name => "name", :attr_type => :string, :width => 200},
19
- #
20
- # # The header for the column.
21
- # {:name => "label", :attr_type => :string, :width => 200, :header => "Header"},
22
- #
23
- # # The default value of this column. Is used when a new row in the grid gets created.
24
- # {:name => "default_value", :attr_type => :string, :width => 200},
25
- #
26
- # # Options for drop-downs
27
- # {:name => "combobox_options", :attr_type => :string, :editor => :textarea, :width => 200},
28
- #
29
- # # Whether the column is editable in the grid.
30
- # {:name => "read_only", :attr_type => :boolean, :header => "R/O", :tooltip => "Read-only"},
31
- #
32
- # # Whether the column will be in the hidden state (hide/show columns from the column menu, if it's enabled).
33
- # {:name => "hidden", :attr_type => :boolean},
34
- #
35
- # # Whether the column should have "grid filters" enabled
36
- # # (see here: http://www.extjs.com/deploy/dev/examples/grid-filtering/grid-filter-local.html)
37
- # {:name => "with_filters", :attr_type => :boolean, :default_value => true, :header => "Filters"},
38
- #
39
- # #
40
- # # Below some rarely used parameters, hidden by default (you can always un-hide them from the column menu).
41
- # #
42
- #
43
- # # The column's width
44
- # {:name => "width", :attr_type => :integer, :hidden => true},
45
- #
46
- # # Whether the column should be hideable
47
- # {:name => "hideable", :attr_type => :boolean, :default_value => true, :hidden => true},
48
- #
49
- # # Whether the column should be sortable (why change it? normally it's hardcoded)
50
- # {:name => "sortable", :attr_type => :boolean, :default_value => true, :hidden => true},
51
- # ]
52
- # end
53
- #
54
- # end
55
-
56
- # Normalized columns for the grid, e.g.:
57
- # [{:name => :id, :hidden => true, ...}, {:name => :name, :editable => false, ...}, ...]
58
- # Possible options:
59
- # * +with_excluded+ - when set to true, also excluded columns will be returned (handy for dynamic column configuration)
60
- # * +with_meta+ - when set to true, the meta column will be included as the last column
61
- def columns(options = {})
62
- [].tap do |cols|
63
- if loaded_columns = load_columns
64
- filter_out_excluded_columns(loaded_columns) unless options[:with_excluded]
65
- cols.concat(reverse_merge_equally_named_columns(loaded_columns, initial_columns(options[:with_excluded])))
66
- else
67
- cols.concat(initial_columns(options[:with_excluded]))
68
- end
69
-
70
- append_meta_column(cols) if options[:with_meta]
71
- end
72
- end
73
-
74
- memoize :columns
75
-
76
- def append_meta_column(cols)
77
- cols << {}.tap do |c|
78
- c.merge!(
79
- :name => "meta",
80
- :meta => true,
81
- :getter => lambda do |r|
82
- meta_data(r)
83
- end
84
- )
85
- c[:default_value] = meta_default_data if meta_default_data.present?
86
- end
87
- end
88
-
89
- # default_value for the meta column; used when a new record is being created in the grid
90
- def meta_default_data
91
- get_default_association_values.present? ? { :association_values => get_default_association_values.literalize_keys } : {}
92
- end
93
-
94
- # Override it when you need extra meta data to be passed through the meta column
95
- def meta_data(r)
96
- { :association_values => get_association_values(r).literalize_keys }
97
- end
98
-
99
- # Columns as a hash, for easier access to a specific column
100
- def columns_hash
101
- @columns_hash ||= columns.inject({}){|r,c| r.merge(c[:name].to_sym => c)}
102
- end
103
-
104
- # Columns that we fall back to when neither persistent columns, nor configured columns are present.
105
- # If there's a model-level field configuration, it's being used.
106
- # Otherwise the defaults straight from the ActiveRecord model ("netzke_attributes").
107
- # Override this method if you want to provide a fix set of columns in your subclass.
108
- def default_columns
109
- @default_columns ||= load_model_level_attrs || data_class.netzke_attributes
110
- end
111
-
112
- def set_default_attr_type(c)
113
- c[:attr_type] ||= association_attr?(c) ? :integer : data_adapter.attr_type(c.name)
114
- end
115
-
116
- # Columns that were overridden with :override_columns config option.
117
- def overridden_default_columns
118
- if config[:override_columns].present?
119
- result = []
120
- default_columns.each do |col|
121
- result << col.merge(config[:override_columns][col[:name].to_sym] || {})
122
- end
123
- result
124
- else
125
- default_columns
126
- end
127
- end
128
-
129
- # Columns that represent a smart merge of default_columns and columns passed during the configuration.
130
- def initial_columns(with_excluded = false)
131
- # Normalize here, as from the config we can get symbols (names) instead of hashes
132
- columns_from_config = config[:columns] && normalize_attrs(config[:columns])
133
-
134
- if columns_from_config
135
- # automatically add a column that reflects the primary key (unless specified in the config)
136
- columns_from_config.insert(0, {:name => data_class.primary_key.to_s}) unless columns_from_config.any?{ |c| c[:name] == data_class.primary_key }
137
-
138
- # reverse-merge each column hash from config with each column hash from exposed_attributes
139
- # (columns from config have higher priority)
140
- for c in columns_from_config
141
- corresponding_default_column = overridden_default_columns.find{ |k| k[:name] == c[:name] }
142
- c.reverse_merge!(corresponding_default_column) if corresponding_default_column
143
- end
144
- columns_for_create = columns_from_config
145
- else
146
- # we didn't have columns configured in component's config, so, use the columns from the data class
147
- columns_for_create = overridden_default_columns
148
- end
149
-
150
- filter_out_excluded_columns(columns_for_create) unless with_excluded
151
-
152
- # Make the column config complete with the defaults.
153
- # Note: dup is needed to avoid modifying original hashes.
154
- columns_for_create.map { |c| c.dup.tap { |c| augment_column_config c } }
155
- end
156
-
157
- memoize :initial_columns
158
-
159
- private
160
-
161
- # Based on initial column config, e.g.:
162
- #
163
- # {:name=>"author__name", :attr_type=>:string}
164
- #
165
- # augment it with additional configuration params, e.g.:
166
- #
167
- # {:name=>"author__name", :attr_type=>:string, :editor=>{:xtype=>:netzkeremotecombo}, :assoc=>true, :virtual=>true, :header=>"Author name", :editable=>true, :sortable=>false, :filterable=>false}
168
- #
169
- # It may be handy to override it.
170
- def augment_column_config(c)
171
- # note: the order of these calls is important, as consequent calls may depend on the result of previous ones
172
- set_default_xtype(c)
173
- set_default_virtual(c)
174
- set_default_text(c)
175
- set_default_editable(c)
176
- set_default_editor(c)
177
- set_default_width(c)
178
- set_default_hidden(c)
179
- set_default_sortable(c)
180
- set_default_filterable(c)
181
- c[:assoc] = association_attr?(c)
182
- end
183
-
184
- def set_default_xtype(c)
185
- return if c[:renderer] || c[:editor] # if user set those manually, we don't mess with column xtype
186
- c[:xtype] ||= attr_type_to_xtype_map[c[:attr_type]]
187
- end
188
-
189
- def set_default_text(c)
190
- c[:text] ||= c[:label] || data_class.human_attribute_name(c[:name])
191
- end
192
-
193
- def set_default_editor(c)
194
- # if shouldn't be editable, don't set any default editor; also, specifying xtype takes care of the editor
195
- return if c[:read_only] || c[:editable] == false
196
-
197
- if association_attr?(c)
198
- set_default_association_editor(c)
199
- else
200
- c[:editor] ||= editor_for_attr_type(c[:attr_type])
201
- end
202
-
203
- end
204
-
205
- def set_default_width(c)
206
- c[:width] ||= 50 if c[:attr_type] == :boolean
207
- c[:width] ||= 150 if c[:attr_type] == :datetime
208
- end
209
-
210
- def set_default_hidden(c)
211
- c[:hidden] = true if primary_key_attr?(c) && c[:hidden].nil?
212
- end
213
-
214
- def set_default_editable(c)
215
- if c[:editable].nil?
216
- c[:editable] = is_editable_column?(c)
217
- end
218
- end
219
-
220
- def set_default_sortable(c)
221
- # this *has* to be set to false if we don't want the column to be sortable (it's sortable by default in Ext)
222
- c[:sortable] = !(c[:virtual] && !c[:sorting_scope]) if c[:sortable].nil?
223
- end
224
-
225
- def set_default_filterable(c)
226
- c[:filterable] = !c[:virtual] if c[:filterable].nil?
227
- end
228
-
229
-
230
- # Detects an association column and sets up the proper editor.
231
- def set_default_association_editor(c)
232
- assoc, assoc_method = c[:name].split('__')
233
- return unless assoc
234
-
235
- assoc_method_type = data_adapter.get_assoc_property_type assoc, assoc_method
236
-
237
- # if association column is boolean, display a checkbox (or alike), otherwise - a combobox (or alike)
238
- if c[:nested_attribute]
239
- c[:editor] ||= editor_for_attr_type(assoc_method_type)
240
- else
241
- c[:editor] ||= assoc_method_type == :boolean ? editor_for_attr_type(:boolean) : editor_for_association
242
- end
243
- end
244
-
245
- # If the column should be editable
246
- def is_editable_column?(c)
247
- not_editable_if = primary_key_attr?(c)
248
- not_editable_if ||= c[:virtual] && !association_attr?(c[:name])
249
- not_editable_if ||= c[:read_only]
250
-
251
- editable_if = data_class.column_names.include?(c[:name])
252
- editable_if ||= data_class.instance_methods.map(&:to_s).include?("#{c[:name]}=")
253
- editable_if ||= association_attr?(c[:name])
254
-
255
- editable_if && !not_editable_if
256
- end
257
-
258
- def initial_columns_order
259
- columns.map do |c|
260
- {
261
- :name => c[:name],
262
- :width => c[:width],
263
- :hidden => c[:hidden]
264
- }
265
- end
266
- end
267
-
268
- def columns_order
269
- if config[:persistence]
270
- update_state(:columns_order, initial_columns_order) if columns_have_changed?
271
- state[:columns_order] || initial_columns_order
272
- else
273
- initial_columns_order
274
- end
275
- end
276
-
277
- def columns_have_changed?
278
- init_column_names = initial_columns_order.map{ |c| c[:name].to_s }.sort
279
- stored_column_names = (state[:columns_order] || initial_columns_order).map{ |c| c[:name].to_s }.sort
280
- init_column_names != stored_column_names
281
- end
282
-
283
- def filter_out_excluded_columns(cols)
284
- cols.reject!{ |c| c[:included] == false }
285
- end
286
-
287
- # Stores modified columns in persistent storage
288
- def save_columns!
289
- # NetzkeFieldList.update_list_for_current_authority(global_id, columns(false), original_data_class.name) if persistent_config_enabled?
290
- end
291
-
292
- def load_columns
293
- # NetzkeFieldList.read_list(global_id) if persistent_config_enabled?
294
- end
295
-
296
- def load_model_level_attrs
297
- # NetzkeModelAttrList.read_list(data_class.name) if persistent_config_enabled?
298
- end
299
-
300
- # Column editor config for attribute type.
301
- def editor_for_attr_type(type)
302
- {:xtype => attr_type_to_editor_xtype_map[type] || :textfield}
303
- end
304
-
305
- # Column editor config for one-to-many association
306
- def editor_for_association
307
- {:xtype => :netzkeremotecombo}
308
- end
309
-
310
- # Hash that maps a column type to the editor xtype. Override if you want different editors.
311
- def attr_type_to_editor_xtype_map
312
- {
313
- :integer => :numberfield,
314
- :boolean => :checkbox,
315
- :date => :datefield,
316
- :datetime => :xdatetime,
317
- :text => :textarea,
318
- :string => :textfield
319
- }
320
- end
321
-
322
- def attr_type_to_xtype_map
323
- {
324
- # :integer => :numbercolumn, # don't like the default formatter
325
- :boolean => :checkcolumn,
326
- :date => :datecolumn,
327
- #:datetime => :datecolumn # TODO: replace with datetimepicker
328
- }
329
- end
330
-
331
- # Default fields that will be displayed in the Add/Edit/Search forms
332
- # When overriding this method, keep in mind that the fields inside the layout must be expanded (each field represented by a hash, not just a symbol)
333
- def default_fields_for_forms
334
- selected_columns = columns.select do |c|
335
- data_class.column_names.include?(c[:name]) ||
336
- data_class.instance_methods.include?("#{c[:name]}=") ||
337
- association_attr?(c[:name])
338
- end
339
-
340
- selected_columns.map do |c|
341
- field_config = {
342
- :name => c[:name],
343
- :field_label => c[:text] || c[:header],
344
- :read_only => c[:read_only],
345
- :editable => c[:editable]
346
- }
347
-
348
- # scopes for combobox options
349
- field_config[:scopes] = c[:editor][:scopes] if c[:editor].is_a?(Hash)
350
-
351
- field_config.merge!(c[:editor] || {})
352
-
353
- field_config
354
- end
355
- end
356
-
357
- # default_fields_for_forms extended with default values (for new-record form)
358
- # def default_fields_for_forms_with_default_values
359
- # res = default_fields_for_forms.dup
360
- # each_attr_in(res) do |a|
361
- # attr_name = a[:name].to_sym
362
- # a[:value] = a[:default_value] || columns_hash[attr_name].try(:fetch, :default_value, nil) || data_class.netzke_attribute_hash[attr_name].try(:fetch, :default_value, nil)
363
- # end
364
- # res
365
- # end
366
-
367
- def columns_default_values
368
- columns.inject({}) do |r,c|
369
- assoc_name, assoc_method = c[:name].split '__'
370
- if c[:default_value].nil?
371
- r
372
- else
373
- if assoc_method
374
- r.merge(data_adapter.foreign_key_for(assoc_name) || data_adapter.foreign_key_for(assoc_name) => c[:default_value])
375
- else
376
- r.merge(c[:name] => c[:default_value])
377
- end
378
- end
379
- end
380
- end
381
-
382
- # Recursively traversess items (an array) and yields each found field (a hash with :name set)
383
- def each_attr_in(items)
384
- items.each do |item|
385
- if item.is_a?(Hash)
386
- each_attr_in(item[:items]) if item[:items].is_a?(Array)
387
- yield(item) if item[:name]
388
- end
389
- end
390
- end
391
-
392
- # Receives 2 arrays of columns. Merges the missing config from the +source+ into +dest+, matching columns by name
393
- def reverse_merge_equally_named_columns(dest, source)
394
- dest.each{ |dc| dc.reverse_merge!(source.detect{ |sc| sc[:name] == dc[:name] } || {}) }
395
- end
396
-
397
- end
398
- end
399
- end
400
- end
@@ -1,281 +0,0 @@
1
- Ext.namespace('Ext.ux.dd');
2
-
3
- Ext.ux.dd.GridDragDropRowOrder = Ext.extend(Ext.util.Observable,
4
- {
5
- copy: false,
6
-
7
- scrollable: false,
8
-
9
- constructor : function(config)
10
- {
11
- Ext.ux.dd.GridDragDropRowOrder.superclass.constructor.call(this);
12
- if (config)
13
- Ext.apply(this, config);
14
-
15
- this.addEvents(
16
- {
17
- beforerowmove: true,
18
- afterrowmove: true,
19
- beforerowcopy: true,
20
- afterrowcopy: true
21
- });
22
- },
23
-
24
- init : function (grid)
25
- {
26
- this.grid = grid;
27
- grid.enableDragDrop = true;
28
-
29
- grid.on({
30
- render: { fn: this.onGridRender, scope: this, single: true }
31
- });
32
- },
33
-
34
- onGridRender : function (grid)
35
- {
36
- var self = this;
37
-
38
- this.target = new Ext.dd.DropTarget(grid.getEl(),
39
- {
40
- ddGroup: grid.ddGroup || 'GridDD',
41
- grid: grid,
42
- gridDropTarget: this,
43
-
44
- notifyDrop: function(dd, e, data)
45
- {
46
- // Remove drag lines. The 'if' condition prevents null error when drop occurs without dragging out of the selection area
47
- if (this.currentRowEl)
48
- {
49
- this.currentRowEl.removeClass('grid-row-insert-below');
50
- this.currentRowEl.removeClass('grid-row-insert-above');
51
- }
52
-
53
- // determine the row
54
- var t = Ext.lib.Event.getTarget(e);
55
- var rindex = this.grid.getView().findRowIndex(t);
56
- if (rindex === false || rindex == data.rowIndex)
57
- {
58
- return false;
59
- }
60
- // fire the before move/copy event
61
- if (this.gridDropTarget.fireEvent(self.copy ? 'beforerowcopy' : 'beforerowmove', this.gridDropTarget, data.rowIndex, rindex, data.selections, 123) === false)
62
- {
63
- return false;
64
- }
65
-
66
- // update the store
67
- var ds = this.grid.getStore();
68
-
69
- // Changes for multiselction by Spirit
70
- var selections = new Array();
71
- var keys = ds.data.keys;
72
- for (var key in keys)
73
- {
74
- for (var i = 0; i < data.selections.length; i++)
75
- {
76
- if (keys[key] == data.selections[i].id)
77
- {
78
- // Exit to prevent drop of selected records on itself.
79
- if (rindex == key)
80
- {
81
- return false;
82
- }
83
- selections.push(data.selections[i]);
84
- }
85
- }
86
- }
87
-
88
- // fix rowindex based on before/after move
89
- if (rindex > data.rowIndex && this.rowPosition < 0)
90
- {
91
- rindex--;
92
- }
93
- if (rindex < data.rowIndex && this.rowPosition > 0)
94
- {
95
- rindex++;
96
- }
97
-
98
- // fix rowindex for multiselection
99
- if (rindex > data.rowIndex && data.selections.length > 1)
100
- {
101
- rindex = rindex - (data.selections.length - 1);
102
- }
103
-
104
- // we tried to move this node before the next sibling, we stay in place
105
- if (rindex == data.rowIndex)
106
- {
107
- return false;
108
- }
109
-
110
- // fire the before move/copy event
111
- /* dupe - does it belong here or above???
112
- if (this.gridDropTarget.fireEvent(self.copy ? 'beforerowcopy' : 'beforerowmove', this.gridDropTarget, data.rowIndex, rindex, data.selections, 123) === false)
113
- {
114
- return false;
115
- }
116
- */
117
-
118
- if (!self.copy)
119
- {
120
- for (var i = 0; i < data.selections.length; i++)
121
- {
122
- ds.remove(ds.getById(data.selections[i].id));
123
- }
124
- }
125
-
126
- for (var i = selections.length - 1; i >= 0; i--)
127
- {
128
- var insertIndex = rindex;
129
- ds.insert(insertIndex, selections[i]);
130
- }
131
-
132
- // re-select the row(s)
133
- var sm = this.grid.getSelectionModel();
134
- if (sm)
135
- {
136
- sm.selectRecords(data.selections);
137
- }
138
-
139
- // console.info(this.gridDropTarget);
140
-
141
- // fire the after move/copy event
142
- this.gridDropTarget.fireEvent(self.copy ? 'afterrowcopy' : 'afterrowmove', this.gridDropTarget, data.rowIndex, rindex, data.selections);
143
- return true;
144
- },
145
-
146
- notifyOver: function(dd, e, data)
147
- {
148
- // WIP: todo - rewrite Ext.lib call to Ext 4
149
- var t = Ext.lib.Event.getTarget(e);
150
- var rindex = this.grid.getView().findRowIndex(t);
151
-
152
- // Similar to the code in notifyDrop. Filters for selected rows and quits function if any one row matches the current selected row.
153
- var ds = this.grid.getStore();
154
- var keys = ds.data.keys;
155
- for (var key in keys)
156
- {
157
- for (var i = 0; i < data.selections.length; i++)
158
- {
159
- if (keys[key] == data.selections[i].id)
160
- {
161
- if (rindex == key)
162
- {
163
- if (this.currentRowEl)
164
- {
165
- this.currentRowEl.removeClass('grid-row-insert-below');
166
- this.currentRowEl.removeClass('grid-row-insert-above');
167
- }
168
- return this.dropNotAllowed;
169
- }
170
- }
171
- }
172
- }
173
-
174
- // If on first row, remove upper line. Prevents negative index error as a result of rindex going negative.
175
- if (rindex < 0 || rindex === false)
176
- {
177
- this.currentRowEl.removeClass('grid-row-insert-above');
178
- return this.dropNotAllowed;
179
- }
180
-
181
- try
182
- {
183
- var currentRow = this.grid.getView().getRow(rindex);
184
- // Find position of row relative to page (adjusting for grid's scroll position)
185
- var resolvedRow = new Ext.Element(currentRow).getY() - this.grid.getView().scroller.dom.scrollTop;
186
- var rowHeight = currentRow.offsetHeight;
187
-
188
- // Cursor relative to a row. -ve value implies cursor is above the row's middle and +ve value implues cursor is below the row's middle.
189
- this.rowPosition = e.getPageY() - resolvedRow - (rowHeight/2);
190
-
191
- // Clear drag line.
192
- if (this.currentRowEl)
193
- {
194
- this.currentRowEl.removeClass('grid-row-insert-below');
195
- this.currentRowEl.removeClass('grid-row-insert-above');
196
- }
197
-
198
- if (this.rowPosition > 0)
199
- {
200
- // If the pointer is on the bottom half of the row.
201
- this.currentRowEl = new Ext.Element(currentRow);
202
- this.currentRowEl.addClass('grid-row-insert-below');
203
- }
204
- else
205
- {
206
- // If the pointer is on the top half of the row.
207
- if (rindex - 1 >= 0)
208
- {
209
- var previousRow = this.grid.getView().getRow(rindex - 1);
210
- this.currentRowEl = new Ext.Element(previousRow);
211
- this.currentRowEl.addClass('grid-row-insert-below');
212
- }
213
- else
214
- {
215
- // If the pointer is on the top half of the first row.
216
- this.currentRowEl.addClass('grid-row-insert-above');
217
- }
218
- }
219
- }
220
- catch (err)
221
- {
222
- console.warn(err);
223
- rindex = false;
224
- }
225
- return (rindex === false)? this.dropNotAllowed : this.dropAllowed;
226
- },
227
-
228
- notifyOut: function(dd, e, data)
229
- {
230
- // Remove drag lines when pointer leaves the gridView.
231
- if (this.currentRowEl)
232
- {
233
- this.currentRowEl.removeClass('grid-row-insert-above');
234
- this.currentRowEl.removeClass('grid-row-insert-below');
235
- }
236
- }
237
- });
238
-
239
- if (this.targetCfg)
240
- {
241
- Ext.apply(this.target, this.targetCfg);
242
- }
243
-
244
- if (this.scrollable)
245
- {
246
- Ext.dd.ScrollManager.register(grid.getView().getEditorParent());
247
- grid.on({
248
- beforedestroy: this.onBeforeDestroy,
249
- scope: this,
250
- single: true
251
- });
252
- }
253
- },
254
-
255
- getTarget: function()
256
- {
257
- return this.target;
258
- },
259
-
260
- getGrid: function()
261
- {
262
- return this.grid;
263
- },
264
-
265
- getCopy: function()
266
- {
267
- return this.copy ? true : false;
268
- },
269
-
270
- setCopy: function(b)
271
- {
272
- this.copy = b ? true : false;
273
- },
274
-
275
- onBeforeDestroy : function (grid)
276
- {
277
- // if we previously registered with the scroll manager, unregister
278
- // it (if we don't it will lead to problems in IE)
279
- Ext.dd.ScrollManager.unregister(grid.getView().getEditorParent());
280
- }
281
- });