netzke-basepack-zh 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (268) hide show
  1. data/.autotest +1 -0
  2. data/.travis.yml +11 -0
  3. data/CHANGELOG.rdoc +445 -0
  4. data/LICENSE +1 -0
  5. data/README.md +94 -0
  6. data/Rakefile +44 -0
  7. data/TODO.rdoc +8 -0
  8. data/config/ci/before-travis.sh +28 -0
  9. data/init.rb +1 -0
  10. data/install.rb +1 -0
  11. data/javascripts/basepack.js +139 -0
  12. data/javascripts/xdatetime.js +196 -0
  13. data/lib/generators/netzke/basepack_generator.rb +10 -0
  14. data/lib/generators/netzke/templates/assets/ts-checkbox.gif +0 -0
  15. data/lib/generators/netzke/templates/create_netzke_field_lists.rb +18 -0
  16. data/lib/netzke-basepack.rb +26 -0
  17. data/lib/netzke/active_record.rb +20 -0
  18. data/lib/netzke/active_record/attributes.rb +256 -0
  19. data/lib/netzke/active_record/combobox_options.rb +16 -0
  20. data/lib/netzke/active_record/relation_extensions.rb +37 -0
  21. data/lib/netzke/basepack.rb +45 -0
  22. data/lib/netzke/basepack/accordion_panel.rb +39 -0
  23. data/lib/netzke/basepack/action_column.rb +68 -0
  24. data/lib/netzke/basepack/action_column/javascripts/action_column.js +61 -0
  25. data/lib/netzke/basepack/auth_app.rb +159 -0
  26. data/lib/netzke/basepack/basic_app.rb +7 -0
  27. data/lib/netzke/basepack/border_layout_panel.rb +53 -0
  28. data/lib/netzke/basepack/border_layout_panel/javascripts/border_layout_panel.js +40 -0
  29. data/lib/netzke/basepack/data_accessor.rb +53 -0
  30. data/lib/netzke/basepack/data_adapters/abstract_adapter.rb +164 -0
  31. data/lib/netzke/basepack/data_adapters/active_record_adapter.rb +279 -0
  32. data/lib/netzke/basepack/data_adapters/data_mapper_adapter.rb +264 -0
  33. data/lib/netzke/basepack/data_adapters/sequel_adapter.rb +260 -0
  34. data/lib/netzke/basepack/form_panel.rb +144 -0
  35. data/lib/netzke/basepack/form_panel/fields.rb +208 -0
  36. data/lib/netzke/basepack/form_panel/javascripts/comma_list_cbg.js +51 -0
  37. data/lib/netzke/basepack/form_panel/javascripts/form_panel.js +225 -0
  38. data/lib/netzke/basepack/form_panel/javascripts/misc.js +4 -0
  39. data/lib/netzke/basepack/form_panel/javascripts/n_radio_group.js +43 -0
  40. data/lib/netzke/basepack/form_panel/javascripts/readonly_mode.js +35 -0
  41. data/lib/netzke/basepack/form_panel/services.rb +142 -0
  42. data/lib/netzke/basepack/form_panel/stylesheets/readonly_mode.css +14 -0
  43. data/lib/netzke/basepack/grid_panel.rb +440 -0
  44. data/lib/netzke/basepack/grid_panel/columns.rb +394 -0
  45. data/lib/netzke/basepack/grid_panel/javascripts/advanced_search.js +27 -0
  46. data/lib/netzke/basepack/grid_panel/javascripts/check_column_fix.js +6 -0
  47. data/lib/netzke/basepack/grid_panel/javascripts/edit_in_form.js +51 -0
  48. data/lib/netzke/basepack/grid_panel/javascripts/event_handling.js +179 -0
  49. data/lib/netzke/basepack/grid_panel/javascripts/grid_panel.js +438 -0
  50. data/lib/netzke/basepack/grid_panel/javascripts/misc.js +4 -0
  51. data/lib/netzke/basepack/grid_panel/javascripts/rows-dd.js +281 -0
  52. data/lib/netzke/basepack/grid_panel/record_form_window.rb +41 -0
  53. data/lib/netzke/basepack/grid_panel/services.rb +235 -0
  54. data/lib/netzke/basepack/paging_form_panel.rb +72 -0
  55. data/lib/netzke/basepack/paging_form_panel/javascripts/paging_form_panel.js +76 -0
  56. data/lib/netzke/basepack/panel.rb +11 -0
  57. data/lib/netzke/basepack/query_builder.rb +107 -0
  58. data/lib/netzke/basepack/query_builder/javascripts/query_builder.js +153 -0
  59. data/lib/netzke/basepack/search_panel.rb +79 -0
  60. data/lib/netzke/basepack/search_panel/javascripts/condition_field.js +160 -0
  61. data/lib/netzke/basepack/search_panel/javascripts/search_panel.js +65 -0
  62. data/lib/netzke/basepack/search_window.rb +66 -0
  63. data/lib/netzke/basepack/simple_app.rb +104 -0
  64. data/lib/netzke/basepack/simple_app/javascripts/simple_app.js +64 -0
  65. data/lib/netzke/basepack/simple_app/javascripts/statusbar_ext.js +8 -0
  66. data/lib/netzke/basepack/tab_panel.rb +21 -0
  67. data/lib/netzke/basepack/tab_panel/javascripts/tab_panel.js +11 -0
  68. data/lib/netzke/basepack/version.rb +11 -0
  69. data/lib/netzke/basepack/window.rb +29 -0
  70. data/lib/netzke/basepack/window/javascripts/window.js +20 -0
  71. data/lib/netzke/basepack/wrap_lazy_loaded.rb +28 -0
  72. data/lib/netzke/basepack/wrapper.rb +28 -0
  73. data/lib/netzke/data_mapper.rb +18 -0
  74. data/lib/netzke/data_mapper/attributes.rb +273 -0
  75. data/lib/netzke/data_mapper/combobox_options.rb +11 -0
  76. data/lib/netzke/data_mapper/relation_extensions.rb +38 -0
  77. data/lib/netzke/sequel.rb +18 -0
  78. data/lib/netzke/sequel/attributes.rb +274 -0
  79. data/lib/netzke/sequel/combobox_options.rb +10 -0
  80. data/lib/netzke/sequel/relation_extensions.rb +40 -0
  81. data/lib/tasks/netzke_basepack_tasks.rake +4 -0
  82. data/locales/de.yml +79 -0
  83. data/locales/en.yml +79 -0
  84. data/netzke-basepack.gemspec +306 -0
  85. data/stylesheets/basepack.css +72 -0
  86. data/stylesheets/datetimefield.css +54 -0
  87. data/test/basepack_test_app/.gitignore +6 -0
  88. data/test/basepack_test_app/.rvmrc +1 -0
  89. data/test/basepack_test_app/Gemfile +59 -0
  90. data/test/basepack_test_app/Gemfile.lock +196 -0
  91. data/test/basepack_test_app/Guardfile +46 -0
  92. data/test/basepack_test_app/README +1 -0
  93. data/test/basepack_test_app/Rakefile +7 -0
  94. data/test/basepack_test_app/app/components/author_form.rb +32 -0
  95. data/test/basepack_test_app/app/components/author_grid.rb +3 -0
  96. data/test/basepack_test_app/app/components/book_form.rb +38 -0
  97. data/test/basepack_test_app/app/components/book_form_with_custom_fields.rb +21 -0
  98. data/test/basepack_test_app/app/components/book_form_with_defaults.rb +8 -0
  99. data/test/basepack_test_app/app/components/book_form_with_nested_attributes.rb +18 -0
  100. data/test/basepack_test_app/app/components/book_grid.rb +12 -0
  101. data/test/basepack_test_app/app/components/book_grid_filtering.rb +10 -0
  102. data/test/basepack_test_app/app/components/book_grid_loader.rb +24 -0
  103. data/test/basepack_test_app/app/components/book_grid_with_column_actions.rb +15 -0
  104. data/test/basepack_test_app/app/components/book_grid_with_custom_columns.rb +27 -0
  105. data/test/basepack_test_app/app/components/book_grid_with_default_values.rb +9 -0
  106. data/test/basepack_test_app/app/components/book_grid_with_extra_feedback.rb +8 -0
  107. data/test/basepack_test_app/app/components/book_grid_with_extra_filters.rb +14 -0
  108. data/test/basepack_test_app/app/components/book_grid_with_nested_attributes.rb +13 -0
  109. data/test/basepack_test_app/app/components/book_grid_with_overridden_columns.rb +15 -0
  110. data/test/basepack_test_app/app/components/book_grid_with_paging.rb +10 -0
  111. data/test/basepack_test_app/app/components/book_grid_with_persistence.rb +8 -0
  112. data/test/basepack_test_app/app/components/book_grid_with_scoped_authors.rb +8 -0
  113. data/test/basepack_test_app/app/components/book_grid_with_virtual_attributes.rb +21 -0
  114. data/test/basepack_test_app/app/components/book_paging_form_panel.rb +22 -0
  115. data/test/basepack_test_app/app/components/book_query_builder.rb +8 -0
  116. data/test/basepack_test_app/app/components/book_search_panel.rb +5 -0
  117. data/test/basepack_test_app/app/components/book_search_panel/javascripts/i18n_de.js +6 -0
  118. data/test/basepack_test_app/app/components/book_with_custom_primary_key_grid.rb +10 -0
  119. data/test/basepack_test_app/app/components/books_bound_to_author.rb +10 -0
  120. data/test/basepack_test_app/app/components/double_book_grid.rb +18 -0
  121. data/test/basepack_test_app/app/components/extras/book_presentation.rb +27 -0
  122. data/test/basepack_test_app/app/components/form_without_model.rb +21 -0
  123. data/test/basepack_test_app/app/components/generic_user_form.rb +12 -0
  124. data/test/basepack_test_app/app/components/lockable_book_form.rb +17 -0
  125. data/test/basepack_test_app/app/components/lockable_user_form.rb +7 -0
  126. data/test/basepack_test_app/app/components/paging_form_with_search.rb +40 -0
  127. data/test/basepack_test_app/app/components/simple_accordion.rb +11 -0
  128. data/test/basepack_test_app/app/components/simple_panel.rb +17 -0
  129. data/test/basepack_test_app/app/components/simple_tab_panel.rb +11 -0
  130. data/test/basepack_test_app/app/components/simple_window.rb +10 -0
  131. data/test/basepack_test_app/app/components/simple_wrapper.rb +7 -0
  132. data/test/basepack_test_app/app/components/some_accordion_panel.rb +22 -0
  133. data/test/basepack_test_app/app/components/some_auth_app.rb +32 -0
  134. data/test/basepack_test_app/app/components/some_border_layout.rb +28 -0
  135. data/test/basepack_test_app/app/components/some_simple_app.rb +35 -0
  136. data/test/basepack_test_app/app/components/some_tab_panel.rb +20 -0
  137. data/test/basepack_test_app/app/components/user_form.rb +25 -0
  138. data/test/basepack_test_app/app/components/user_form_with_default_fields.rb +8 -0
  139. data/test/basepack_test_app/app/components/user_grid.rb +8 -0
  140. data/test/basepack_test_app/app/components/user_grid_with_customized_form_fields.rb +18 -0
  141. data/test/basepack_test_app/app/components/window_component_loader.rb +27 -0
  142. data/test/basepack_test_app/app/controllers/application_controller.rb +9 -0
  143. data/test/basepack_test_app/app/controllers/components_controller.rb +10 -0
  144. data/test/basepack_test_app/app/controllers/welcome_controller.rb +9 -0
  145. data/test/basepack_test_app/app/helpers/application_helper.rb +8 -0
  146. data/test/basepack_test_app/app/helpers/embedded_components_helper.rb +2 -0
  147. data/test/basepack_test_app/app/models/address.rb +29 -0
  148. data/test/basepack_test_app/app/models/author.rb +38 -0
  149. data/test/basepack_test_app/app/models/book.rb +49 -0
  150. data/test/basepack_test_app/app/models/book_with_custom_primary_key.rb +26 -0
  151. data/test/basepack_test_app/app/models/role.rb +24 -0
  152. data/test/basepack_test_app/app/models/user.rb +29 -0
  153. data/test/basepack_test_app/app/presenters/forms/generic_user.rb +6 -0
  154. data/test/basepack_test_app/app/views/components/loadable_window.html.erb +9 -0
  155. data/test/basepack_test_app/app/views/components/simple_panel.html.erb +1 -0
  156. data/test/basepack_test_app/app/views/layouts/application.html.erb +12 -0
  157. data/test/basepack_test_app/app/views/layouts/components.html.erb +13 -0
  158. data/test/basepack_test_app/app/views/layouts/nested.html.erb +5 -0
  159. data/test/basepack_test_app/app/views/welcome/index.html.erb +10 -0
  160. data/test/basepack_test_app/config.ru +4 -0
  161. data/test/basepack_test_app/config/application.rb +57 -0
  162. data/test/basepack_test_app/config/boot.rb +13 -0
  163. data/test/basepack_test_app/config/cucumber.yml +8 -0
  164. data/test/basepack_test_app/config/database.yml.sample +41 -0
  165. data/test/basepack_test_app/config/database.yml.travis +15 -0
  166. data/test/basepack_test_app/config/environment.rb +6 -0
  167. data/test/basepack_test_app/config/environments/development.rb +22 -0
  168. data/test/basepack_test_app/config/environments/production.rb +49 -0
  169. data/test/basepack_test_app/config/environments/test.rb +35 -0
  170. data/test/basepack_test_app/config/initializers/backtrace_silencers.rb +7 -0
  171. data/test/basepack_test_app/config/initializers/data_mapper_logging.rb +3 -0
  172. data/test/basepack_test_app/config/initializers/inflections.rb +10 -0
  173. data/test/basepack_test_app/config/initializers/mime_types.rb +5 -0
  174. data/test/basepack_test_app/config/initializers/netzke.rb +9 -0
  175. data/test/basepack_test_app/config/initializers/secret_token.rb +7 -0
  176. data/test/basepack_test_app/config/initializers/sequel.rb +26 -0
  177. data/test/basepack_test_app/config/initializers/session_store.rb +8 -0
  178. data/test/basepack_test_app/config/locales/de.yml +35 -0
  179. data/test/basepack_test_app/config/locales/es.yml +96 -0
  180. data/test/basepack_test_app/config/routes.rb +68 -0
  181. data/test/basepack_test_app/db/development_structure.sql +88 -0
  182. data/test/basepack_test_app/db/migrate/20100914104207_create_users.rb +15 -0
  183. data/test/basepack_test_app/db/migrate/20100914104236_create_roles.rb +13 -0
  184. data/test/basepack_test_app/db/migrate/20101026185816_create_authors.rb +14 -0
  185. data/test/basepack_test_app/db/migrate/20101026190021_create_books.rb +19 -0
  186. data/test/basepack_test_app/db/migrate/20110101143818_create_addresses.rb +17 -0
  187. data/test/basepack_test_app/db/migrate/20110213213050_create_netzke_component_states.rb +20 -0
  188. data/test/basepack_test_app/db/migrate/20110701070052_create_book_with_custom_primary_keys.rb +15 -0
  189. data/test/basepack_test_app/db/migrate/20110901114016_add_last_read_at_to_books.rb +9 -0
  190. data/test/basepack_test_app/db/migrate/20110909071740_add_published_on_to_books.rb +5 -0
  191. data/test/basepack_test_app/db/schema.rb +81 -0
  192. data/test/basepack_test_app/db/seeds.rb +44 -0
  193. data/test/basepack_test_app/features/accordion_panel.feature +12 -0
  194. data/test/basepack_test_app/features/components_in_view.feature +11 -0
  195. data/test/basepack_test_app/features/form_panel.feature +142 -0
  196. data/test/basepack_test_app/features/grid_panel.feature +277 -0
  197. data/test/basepack_test_app/features/grid_panel_filters.feature +73 -0
  198. data/test/basepack_test_app/features/grid_panel_with_custom_primary_key.feature +15 -0
  199. data/test/basepack_test_app/features/grid_sorting.feature +47 -0
  200. data/test/basepack_test_app/features/i18n.feature +18 -0
  201. data/test/basepack_test_app/features/nested_attributes.feature +26 -0
  202. data/test/basepack_test_app/features/paging_form_panel.feature +43 -0
  203. data/test/basepack_test_app/features/search_in_grid.feature +49 -0
  204. data/test/basepack_test_app/features/simple_app.feature +15 -0
  205. data/test/basepack_test_app/features/simple_panel.feature +11 -0
  206. data/test/basepack_test_app/features/step_definitions/accordion_steps.rb +5 -0
  207. data/test/basepack_test_app/features/step_definitions/ext_steps.rb +16 -0
  208. data/test/basepack_test_app/features/step_definitions/form_panel_steps.rb +46 -0
  209. data/test/basepack_test_app/features/step_definitions/generic_steps.rb +44 -0
  210. data/test/basepack_test_app/features/step_definitions/grid_panel_steps.rb +186 -0
  211. data/test/basepack_test_app/features/step_definitions/pickle_steps.rb +100 -0
  212. data/test/basepack_test_app/features/step_definitions/web_steps.rb +219 -0
  213. data/test/basepack_test_app/features/support/env.rb +81 -0
  214. data/test/basepack_test_app/features/support/paths.rb +65 -0
  215. data/test/basepack_test_app/features/support/pickle.rb +24 -0
  216. data/test/basepack_test_app/features/support/selectors.rb +39 -0
  217. data/test/basepack_test_app/features/tab_panel.feature +12 -0
  218. data/test/basepack_test_app/features/validations_in_grid.feature +13 -0
  219. data/test/basepack_test_app/features/virtual_attributes.feature +16 -0
  220. data/test/basepack_test_app/features/window.feature +11 -0
  221. data/test/basepack_test_app/lib/tasks/.gitkeep +0 -0
  222. data/test/basepack_test_app/lib/tasks/cucumber.rake +71 -0
  223. data/test/basepack_test_app/lib/tasks/travis.rake +7 -0
  224. data/test/basepack_test_app/public/404.html +26 -0
  225. data/test/basepack_test_app/public/422.html +26 -0
  226. data/test/basepack_test_app/public/500.html +26 -0
  227. data/test/basepack_test_app/public/favicon.ico +0 -0
  228. data/test/basepack_test_app/public/images/header-deco.gif +0 -0
  229. data/test/basepack_test_app/public/images/rails.png +0 -0
  230. data/test/basepack_test_app/public/javascripts/application.js +2 -0
  231. data/test/basepack_test_app/public/javascripts/controls.js +965 -0
  232. data/test/basepack_test_app/public/javascripts/dragdrop.js +974 -0
  233. data/test/basepack_test_app/public/javascripts/effects.js +1123 -0
  234. data/test/basepack_test_app/public/javascripts/prototype.js +6001 -0
  235. data/test/basepack_test_app/public/javascripts/rails.js +175 -0
  236. data/test/basepack_test_app/public/robots.txt +5 -0
  237. data/test/basepack_test_app/public/stylesheets/.gitkeep +0 -0
  238. data/test/basepack_test_app/script/cucumber +10 -0
  239. data/test/basepack_test_app/script/rails +6 -0
  240. data/test/basepack_test_app/spec/components/form_panel_spec.rb +53 -0
  241. data/test/basepack_test_app/spec/components/grid_panel_spec.rb +10 -0
  242. data/test/basepack_test_app/spec/data_adapter/adapter_spec.rb +68 -0
  243. data/test/basepack_test_app/spec/data_adapter/attributes_spec.rb +56 -0
  244. data/test/basepack_test_app/spec/data_adapter/relation_extensions_spec.rb +125 -0
  245. data/test/basepack_test_app/spec/factories.rb +28 -0
  246. data/test/basepack_test_app/spec/spec_helper.rb +39 -0
  247. data/test/basepack_test_app/test/performance/browsing_test.rb +9 -0
  248. data/test/basepack_test_app/test/test_helper.rb +13 -0
  249. data/test/basepack_test_app/vendor/plugins/.gitkeep +0 -0
  250. data/test/console_with_fixtures.rb +4 -0
  251. data/test/fixtures/books.yml +11 -0
  252. data/test/fixtures/categories.yml +7 -0
  253. data/test/fixtures/cities.yml +21 -0
  254. data/test/fixtures/continents.yml +7 -0
  255. data/test/fixtures/countries.yml +9 -0
  256. data/test/fixtures/genres.yml +9 -0
  257. data/test/fixtures/roles.yml +8 -0
  258. data/test/fixtures/users.yml +11 -0
  259. data/test/schema.rb +10 -0
  260. data/test/test_helper.rb +21 -0
  261. data/test/unit/accordion_panel_test.rb +20 -0
  262. data/test/unit/active_record_basepack_test.rb +54 -0
  263. data/test/unit/fields_configuration_test.rb +18 -0
  264. data/test/unit/grid_panel_test.rb +52 -0
  265. data/test/unit/netzke_basepack_test.rb +4 -0
  266. data/test/unit/tab_panel_test.rb +21 -0
  267. data/uninstall.rb +1 -0
  268. metadata +332 -0
@@ -0,0 +1,14 @@
1
+ input.readonly, textarea.readonly {
2
+ background-color: #f5f5f5;
3
+ background-image: none;
4
+ }
5
+
6
+ /*input.readonly, textarea.readonly {
7
+ border: 0 solid #fff;
8
+ background-image: none;
9
+ }
10
+
11
+ label.readonly {
12
+ font-weight: bold;
13
+ }
14
+ */
@@ -0,0 +1,440 @@
1
+ require "netzke/basepack/grid_panel/columns"
2
+ require "netzke/basepack/grid_panel/services"
3
+ # require "netzke/basepack/plugins/configuration_tool"
4
+
5
+ module Netzke
6
+ module Basepack
7
+ # Ext.grid.EditorGridPanel-based component with the following features:
8
+ #
9
+ # * ActiveRecord-model support with automatic column configuration
10
+ # * multi-line CRUD operations - get, post, delete, create
11
+ # * (multe-record) editing and adding records through a form
12
+ # * persistent column resize, move and hide
13
+ # * permissions
14
+ # * sorting
15
+ # * pagination
16
+ # * filtering
17
+ # * advanced search
18
+ # * rows reordering by drag-n-drop, requires acts_as_list on the model
19
+ # * virtual attribute support
20
+ # * (TODO) dynamic configuration of properties and columns
21
+ #
22
+ # == Instance configuration
23
+ # The following config options are supported:
24
+ # * +model+ - name of the ActiveRecord model that provides data to this GridPanel, e.g. "User"
25
+ # * +columns+ - an array of columns to be displayed in the grid; each column may be represented by a symbol (representing the model's attribute name), or a hash (when extra configuration is needed). See the "Columns" section below.
26
+ # * +scope+ - specifies how the data should be filtered.
27
+ # When it's a symbol, it's used as a scope name.
28
+ # When it's a string, it's a SQL statement (passed directly to +where+).
29
+ # When it's a hash, it's a conditions hash (passed directly to +where+).
30
+ # When it's an array, it's expanded into an SQL statement with arguments (passed directly to +where+), e.g.:
31
+ #
32
+ # :scope => ["id > ?", 100])
33
+ #
34
+ # When it's a Proc, it's passed the model class, and is expected to return a ActiveRecord::Relation, e.g.:
35
+ #
36
+ # :scope => { |rel| rel.where(:id.gt => 100).order(:created_at) }
37
+ #
38
+ # * +strong_default_attrs+ - (defaults to {}) a hash of attributes to be merged atop of every created/updated record, e.g. {:role_id => 1}
39
+ # * +enable_column_filters+ - (defaults to true) enable filters in column's context menu
40
+ # * +enable_edit_in_form+ - (defaults to true) provide buttons into the toolbar that activate editing/adding records via a form
41
+ # * +enable_extended_search+ - (defaults to true) provide a button into the toolbar that shows configurable search form
42
+ # * +enable_context_menu+ - (defaults to true) enable rows context menu
43
+ # * +context_menu+ - an array of actions (e.g. [:edit.action, "-", :del.action] - see the Actions section) or +false+ to disable the context menu
44
+ # * +enable_rows_reordering+ - (defaults to false) enable reordering of rows with drag-n-drop; underlying model (specified in +model+) must implement "acts_as_list"-compatible functionality
45
+ # * +enable_pagination+ - (defaults to true) enable pagination
46
+ # * +rows_per_page+ - (defaults to 30) number of rows per page (ignored when +enable_pagination+ is set to +false+)
47
+ # * +load_inline_data+ - (defaults to true) load initial data into the grid right after its instantiation
48
+ # * (TODO) +mode+ - when set to +config+, GridPanel loads in configuration mode
49
+ # * <tt>[add|edit|multi_edit]_search_form_config</tt> - additional configuration for add/edit/multi_edit/search form panel
50
+ # * <tt>[add|edit|multi_edit]_form_window_config</tt> - additional configuration for the window that wrapps up add/edit/multi_edit form panel
51
+ #
52
+ # == Columns
53
+ # Columns are configured by passing an array to the +columns+ option. Each element in the array is either the name of model's (virtual) attribute (in which case the configuration will be fully automatic), or a hash that may contain the following configuration options as keys:
54
+ #
55
+ # * +name+ - (required) name of the column, that may correspond to the model's (virtual) attribute
56
+ # * +read_only+ - a boolean that defines if the cells in the column should be editable
57
+ # * +editable+ - same as +read_only+, but in reverse (takes precedence over +read_only+)
58
+ # * +filterable+ - set to false to disable filtering on this column
59
+ # * +getter+ - a lambda that receives a record as a parameter, and is expected to return a string that will be sent to the cell (can be HTML code), e.g.:
60
+ #
61
+ # :getter => lambda {|r| [r.first_name, r.last_name].join }
62
+ # * +setter+ - a lambda that receives a record as first parameter, and the value passed from the cell as the second parameter, and is expected to modify the record accordingly, e.g.:
63
+ #
64
+ # :setter => lambda { |r,v| r.first_name, r.last_name = v.split(" ") }
65
+ #
66
+ # * +scope+ - the scope for one-to-many association column. Same syntax applies as for scoping out records for the grid itself. See "One-to-many association support" for details.
67
+ #
68
+ # * +sorting_scope+ - the name of the scope used for sorting the column. This can be useful for virtual columns for example. The scope will get one parameter specifying the direction (:asc or :desc). Example:
69
+ #
70
+ # columns => [{ :name => "complete_user_name", :sorting_scope => :sort_user_by_full_name }, ...]
71
+ #
72
+ # class User < ActiveRecord::Base
73
+ # scope :sort_user_by_full_name, lambda { |dir|
74
+ # order("users.first_name #{dir.to_s}, users.last_name #{dir.to_s}")
75
+ # }
76
+ # end
77
+ #
78
+ # * +format+ - the format to display data in case of date and datetime columns, e.g. 'Y-m-d g:i:s'.
79
+ #
80
+ # Besides these options, a column can receive any meaningful config option understood by Ext.grid.column.Column.
81
+ #
82
+ # == One-to-many association support
83
+ # If the model bound to a grid +belongs_to+ another model, GridPanel can display an "assocition column" - where the user can select the associated record from a drop-down box. You can specify which method of the association should be used as the display value for the drop-down box options by using the double-underscore notation on the column name, where the association name is separated from the association method by "__" (double underscore). For example, let's say we have a Book that +belongs_to+ model Author, and Author responds to +first_name+. This way, the book grid can have a column defined as follows:
84
+ #
85
+ # {:name => "author__first_name"}
86
+ #
87
+ # GridPanel will detect it to be an association column, and will use the drop-down box for selecting an author, where the list of authors will be represented by the author's first name.
88
+ #
89
+ # In order to scope out the records displayed in the drop-down box, the +scope+ column option can be used, e.g.:
90
+ #
91
+ # {:name => "author__first_name", :scope => lambda{|relation| relation.where(:popular => true)}}
92
+ #
93
+ # == Add/edit/search forms
94
+ # The forms will by default display the fields that correspond to the configured columns, taking over meaningful configuration options (e.g. +text+ will be converted into +fieldLabel+).
95
+ # You may override the default fields displayed in the forms by overriding the +default_fields_for_forms+ method, which should return an array understood by the +items+ config property of the +FormPanel+. If you need to use a custom class instead of +FormPanel+, you may need to go an extra mile overriding the corresponding GridPanel's child component (e.g. "add_form" or "edit_form").
96
+ #
97
+ # == Actions
98
+ # You can override GridPanel's actions to change their text, icons, and tooltips (see http://api.netzke.org/core/Netzke/Actions.html).
99
+ #
100
+ # GridPanel implements the following actions:
101
+ # * +add+ - inline adding of a record
102
+ # * +del+ - deletion of records
103
+ # * +edit+ - inline editing of a record
104
+ # * +apply+ - applying inline changes
105
+ # * +add_in_form+ - adding a record in a form
106
+ # * +edit_in_form+ - (multi-record) editing in a forrm
107
+ # * +search+ - advanced searching
108
+ #
109
+ # == Class configuration
110
+ #
111
+ # Configuration on this level is effective during the life-time of the application. One place for setting these options are in application.rb, e.g.:
112
+ #
113
+ # config.netzke.basepack.grid_panel.column_filters_available = false
114
+ #
115
+ # These can also be eventually set directly on the component's class:
116
+ #
117
+ # Netzke::Basepack::GridPanel.column_filters_available = false
118
+ #
119
+ # Most of these options influence the amount of JavaScript code that is generated for this component's class, in the way that the less functionality is enabled, the less code is generated.
120
+ #
121
+ # The following class configuration options are available:
122
+ # * +column_filters_available+ - (defaults to true) include code for the filters in the column's context menu
123
+ # * (TODO) +config_tool_available+ - (defaults to true) include code for the configuration tool that launches the configuration panel
124
+ # * +edit_in_form_available+ - (defaults to true) include code for (multi-record) editing and adding records through a form
125
+ # * +extended_search_available+ - (defaults to true) include code for extended configurable search
126
+ class GridPanel < Netzke::Base
127
+ js_base_class "Ext.grid.Panel"
128
+
129
+ class_attribute :columns_attr
130
+
131
+ class_attribute :overridden_columns_attr
132
+ self.overridden_columns_attr = {}
133
+
134
+ # Class-level configuration. These options directly influence the amount of generated
135
+ # javascript code for this component's class. For example, if you don't want filters for the grid,
136
+ # set column_filters_available to false, and the javascript for the filters won't be included at all.
137
+ class_config_option :column_filters_available, true
138
+
139
+ class_config_option :extended_search_available, true
140
+
141
+ class_config_option :edit_in_form_available, true
142
+
143
+ class_config_option :rows_reordering_available, false
144
+
145
+ class_config_option :config_tool_available, false
146
+
147
+ class_config_option :default_instance_config, {
148
+ :enable_edit_in_form => edit_in_form_available,
149
+ :enable_extended_search => extended_search_available,
150
+ :enable_column_filters => column_filters_available,
151
+ :load_inline_data => true,
152
+ :enable_rows_reordering => false, # column drag n drop
153
+ :enable_pagination => true,
154
+ :rows_per_page => 30,
155
+ :tools => %w{ refresh }
156
+ }
157
+
158
+ extend ActiveSupport::Memoizable
159
+
160
+ include self::Services
161
+ include self::Columns
162
+ include Netzke::Basepack::DataAccessor
163
+
164
+ js_mixin :grid_panel, :event_handling
165
+ js_mixin :advanced_search if extended_search_available
166
+ js_mixin :edit_in_form if edit_in_form_available
167
+
168
+ js_translate *%w[are_you_sure confirmation]
169
+
170
+ # JavaScript includes
171
+ ex = Netzke::Core.ext_path.join("examples")
172
+
173
+ js_include(ex.join("ux/CheckColumn.js"))
174
+ js_include :check_column_fix
175
+
176
+ # Includes for column filters
177
+ if column_filters_available
178
+ [
179
+ "ux/grid/menu/ListMenu.js",
180
+ "ux/grid/menu/RangeMenu.js",
181
+ "ux/grid/FiltersFeature.js"
182
+ ].each{ |path| js_include(ex.join(path)) }
183
+
184
+ %w{Boolean Date List Numeric String}.unshift("").each do |f|
185
+ js_include(ex.join"ux/grid/filter/#{f}Filter.js")
186
+ end
187
+ end
188
+
189
+ # Includes for rows reordering
190
+ if rows_reordering_available
191
+ js_include(ex.join("#{File.dirname(__FILE__)}/grid_panel/javascripts/rows-dd.js"))
192
+ end
193
+
194
+ # Allows children classes to simply do
195
+ #
196
+ # model "User"
197
+ delegates_to_dsl :model, :add_form_config, :add_form_window_config, :edit_form_config, :edit_form_window_config, :multi_edit_form_config, :multi_edit_form_window_config
198
+
199
+ # Inject some handy DSL methods into the child classes.
200
+ def self.inherited(base)
201
+ super
202
+
203
+ base.class_eval do
204
+ class << self
205
+ def column(name, config = {})
206
+ columns = self.columns_attr || []
207
+ columns |= [config.merge(:name => name.to_s)]
208
+ self.columns_attr = columns
209
+ end
210
+
211
+ def override_column(name, config)
212
+ columns = self.overridden_columns_attr.dup
213
+ self.overridden_columns_attr = columns.merge(name.to_sym => config)
214
+ end
215
+ end
216
+ end
217
+ end
218
+
219
+ def configuration
220
+ super.tap do |c|
221
+ c[:columns] ||= self.columns_attr
222
+
223
+ # user-passed :override_columns option should get deep_merged with the defaults
224
+ c[:override_columns] = self.overridden_columns_attr.deep_merge(c[:override_columns] || {})
225
+ end
226
+ end
227
+
228
+ def js_config #:nodoc:
229
+ res = super
230
+ res.merge({
231
+ :title => res[:title] || self.class.js_properties[:title] || data_class.name.pluralize,
232
+ :bbar => config.has_key?(:bbar) ? config[:bbar] : default_bbar,
233
+ :context_menu => config.has_key?(:context_menu) ? config[:context_menu] : default_context_menu,
234
+ :columns => columns(:with_meta => true), # columns
235
+ :columns_order => columns_order,
236
+ :model => config[:model], # the model name
237
+ :inline_data => (get_data if config[:load_inline_data]), # inline data (loaded along with the grid panel)
238
+ :pri => data_class.primary_key # table primary key name
239
+ })
240
+ end
241
+
242
+ def get_association_values(record) #:nodoc:
243
+ columns.select{ |c| c[:name].index("__") }.each.inject({}) do |r,c|
244
+ r.merge(c[:name] => record.value_for_attribute(c, true))
245
+ end
246
+ end
247
+
248
+ def get_default_association_values #:nodoc:
249
+ columns.select{ |c| c[:name].index("__") && c[:default_value] }.each.inject({}) do |r,c|
250
+ assoc_name, assoc_method = c[:name].split '__'
251
+ assoc_class = data_adapter.class_for(assoc_name)
252
+ assoc_data_adapter = Netzke::Basepack::DataAdapters::AbstractAdapter.adapter_class(assoc_class).new(assoc_class)
253
+ assoc_instance = assoc_data_adapter.find_record c[:default_value]
254
+ r.merge(c[:name] => assoc_instance.send(assoc_method))
255
+ end
256
+ end
257
+ memoize :get_default_association_values
258
+
259
+ # Override to change the default bottom toolbar
260
+ def default_bbar
261
+ res = %w{ add edit apply del }.map(&:to_sym).map(&:action)
262
+ res << "-" << :add_in_form.action << :edit_in_form.action if config[:enable_edit_in_form]
263
+ res << "-" << :search.action if config[:enable_extended_search]
264
+ res
265
+ end
266
+
267
+ # Override to change the default context menu
268
+ def default_context_menu
269
+ res = %w{ edit del }.map(&:to_sym).map(&:action)
270
+ res << "-" << :edit_in_form.action if config[:enable_edit_in_form]
271
+ res
272
+ end
273
+
274
+ # def configuration_components
275
+ # res = []
276
+ # res << {
277
+ # :persistent_config => true,
278
+ # :name => 'columns',
279
+ # :class_name => "FieldsConfigurator",
280
+ # :active => true,
281
+ # :owner => self
282
+ # }
283
+ # res << {
284
+ # :name => 'general',
285
+ # :class_name => "PropertyEditor",
286
+ # :component => self,
287
+ # :title => false
288
+ # }
289
+ # res
290
+ # end
291
+
292
+ action :add do
293
+ {
294
+ :text => I18n.t('netzke.basepack.grid_panel.actions.add'),
295
+ :tooltip => I18n.t('netzke.basepack.grid_panel.actions.add'),
296
+ :disabled => config[:prohibit_create],
297
+ :handler => "onAddInline", # not following naming conventions here as Ext 4 grid has its own onAdd method
298
+ :icon => :add
299
+ }
300
+ end
301
+
302
+ action :edit do
303
+ {
304
+ :text => I18n.t('netzke.basepack.grid_panel.actions.edit'),
305
+ :tooltip => I18n.t('netzke.basepack.grid_panel.actions.edit'),
306
+ :disabled => true,
307
+ :icon => :table_edit
308
+ }
309
+ end
310
+
311
+ action :del do
312
+ {
313
+ :text => I18n.t('netzke.basepack.grid_panel.actions.del'),
314
+ :tooltip => I18n.t('netzke.basepack.grid_panel.actions.del'),
315
+ :disabled => true,
316
+ :icon => :table_row_delete
317
+ }
318
+ end
319
+
320
+ action :apply do
321
+ {
322
+ :text => I18n.t('netzke.basepack.grid_panel.actions.apply'),
323
+ :tooltip => I18n.t('netzke.basepack.grid_panel.actions.apply'),
324
+ :disabled => config[:prohibit_update] && config[:prohibit_create],
325
+ :icon => :tick
326
+ }
327
+ end
328
+
329
+ action :add_in_form do
330
+ {
331
+ :text => I18n.t('netzke.basepack.grid_panel.actions.add_in_form'),
332
+ :tooltip => I18n.t('netzke.basepack.grid_panel.actions.add_in_form'),
333
+ :icon => :application_form_add
334
+ }
335
+ end
336
+
337
+ action :edit_in_form do
338
+ {
339
+ :text => I18n.t('netzke.basepack.grid_panel.actions.edit_in_form'),
340
+ :tooltip => I18n.t('netzke.basepack.grid_panel.actions.edit_in_form'),
341
+ :disabled => true,
342
+ :icon => :application_form_edit
343
+ }
344
+ end
345
+
346
+ action :search do
347
+ {
348
+ :text => I18n.t('netzke.basepack.grid_panel.actions.search'),
349
+ :tooltip => I18n.t('netzke.basepack.grid_panel.actions.search'),
350
+ :enable_toggle => true,
351
+ :icon => :find
352
+ }
353
+ end
354
+
355
+ component :add_form do
356
+ form_config = {
357
+ :class_name => "Netzke::Basepack::FormPanel",
358
+ :model => config[:model],
359
+ :persistent_config => config[:persistent_config],
360
+ :strong_default_attrs => config[:strong_default_attrs],
361
+ :border => true,
362
+ :bbar => false,
363
+ :prevent_header => true,
364
+ :mode => config[:mode],
365
+ :record => data_class.new(columns_default_values)
366
+ }
367
+
368
+ # Only provide default form fields when no custom class_name is specified for the form
369
+ form_config[:items] = default_fields_for_forms unless config[:add_form_config] && config[:add_form_config][:class_name]
370
+
371
+ {
372
+ :lazy_loading => true,
373
+ :class_name => "Netzke::Basepack::GridPanel::RecordFormWindow",
374
+ :title => "Add #{data_class.model_name.human}",
375
+ :button_align => "right",
376
+ :items => [form_config.deep_merge(config[:add_form_config] || {})]
377
+ }.deep_merge(config[:add_form_window_config] || {})
378
+ end
379
+
380
+ component :edit_form do
381
+ form_config = {
382
+ :class_name => "Netzke::Basepack::FormPanel",
383
+ :model => config[:model],
384
+ :persistent_config => config[:persistent_config],
385
+ :bbar => false,
386
+ :prevent_header => true,
387
+ :mode => config[:mode]
388
+ # :record_id gets assigned by deliver_component dynamically, at the moment of loading
389
+ }
390
+
391
+ # Only provide default form fields when no custom class_name is specified for the form
392
+ form_config[:items] = default_fields_for_forms unless config[:edit_form_config] && config[:edit_form_config][:class_name]
393
+
394
+ {
395
+ :lazy_loading => true,
396
+ :class_name => "Netzke::Basepack::GridPanel::RecordFormWindow",
397
+ :title => "Edit #{data_class.model_name.human}",
398
+ :button_align => "right",
399
+ :items => [form_config.deep_merge(config[:edit_form_config] || {})]
400
+ }.deep_merge(config[:edit_form_window_config] || {})
401
+ end
402
+
403
+ component :multi_edit_form do
404
+ form_config = {
405
+ :class_name => "Netzke::Basepack::FormPanel",
406
+ :multi_edit => true,
407
+ :model => config[:model],
408
+ :persistent_config => config[:persistent_config],
409
+ :bbar => false,
410
+ :prevent_header => true,
411
+ :name => "multi_edit_form0", # we detect multi-edit form submission by its name
412
+ :mode => config[:mode]
413
+ }
414
+
415
+ # Only provide default form fields when no custom class_name is specified for the form
416
+ form_config[:items] = default_fields_for_forms unless config[:multi_edit_form_config] && config[:multi_edit_form_config][:class_name]
417
+
418
+ {
419
+ :lazy_loading => true,
420
+ :class_name => "Netzke::Basepack::GridPanel::RecordFormWindow",
421
+ :title => "Edit #{data_class.model_name.human.pluralize}",
422
+ :button_align => "right",
423
+ :items => [form_config.deep_merge(config[:multi_edit_form_config] || {})]
424
+ }.deep_merge(config[:multi_edit_form_window_config] || {})
425
+ end
426
+
427
+ component :search_form do
428
+ {
429
+ :lazy_loading => true,
430
+ :class_name => "Netzke::Basepack::SearchWindow",
431
+ :model => config[:model],
432
+ :fields => default_fields_for_forms
433
+ }
434
+ end
435
+
436
+ # include ::Netzke::Plugins::ConfigurationTool if config_tool_available # it will load ConfigurationPanel into a modal window
437
+
438
+ end
439
+ end
440
+ end