pwice_grid 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (389) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +68 -0
  3. data/.circleci/run-build-locally.sh +7 -0
  4. data/.github/ISSUE_TEMPLATE/bug_report.md +32 -0
  5. data/.gitignore +22 -0
  6. data/.inch.yml +3 -0
  7. data/.rspec +3 -0
  8. data/.rubocop.yml +186 -0
  9. data/Appraisals +11 -0
  10. data/CHANGELOG.md +758 -0
  11. data/Gemfile +3 -0
  12. data/Gemfile.lock +298 -0
  13. data/MIT-LICENSE +20 -0
  14. data/README.md +1561 -0
  15. data/Rakefile +49 -0
  16. data/SAVED_QUERIES_HOWTO.md +113 -0
  17. data/app/views/kaminari/wice_grid/_gap.html.erb +1 -0
  18. data/app/views/kaminari/wice_grid/_next_page.html.erb +1 -0
  19. data/app/views/kaminari/wice_grid/_page.html.erb +1 -0
  20. data/app/views/kaminari/wice_grid/_paginator.html.erb +19 -0
  21. data/app/views/kaminari/wice_grid/_prev_page.html.erb +1 -0
  22. data/config/locales/cz.yml +40 -0
  23. data/config/locales/de.yml +42 -0
  24. data/config/locales/en.yml +42 -0
  25. data/config/locales/es.yml +42 -0
  26. data/config/locales/fr.yml +40 -0
  27. data/config/locales/is.yml +41 -0
  28. data/config/locales/it.yml +33 -0
  29. data/config/locales/ja.yml +42 -0
  30. data/config/locales/nl.yml +40 -0
  31. data/config/locales/pt-BR.yml +31 -0
  32. data/config/locales/pt.yml +40 -0
  33. data/config/locales/ru.yml +40 -0
  34. data/config/locales/sk.yml +40 -0
  35. data/config/locales/uk.yml +40 -0
  36. data/config/locales/zh.yml +40 -0
  37. data/gemfiles/rails_5.0.gemfile +7 -0
  38. data/gemfiles/rails_5.0.gemfile.lock +299 -0
  39. data/gemfiles/rails_5.1.gemfile +7 -0
  40. data/gemfiles/rails_5.1.gemfile.lock +299 -0
  41. data/gemfiles/rails_5.2.gemfile +7 -0
  42. data/gemfiles/rails_5.2.gemfile.lock +307 -0
  43. data/lib/generators/wice_grid/add_migration_for_serialized_queries_generator.rb +19 -0
  44. data/lib/generators/wice_grid/install_generator.rb +13 -0
  45. data/lib/generators/wice_grid/templates/create_wice_grid_serialized_queries.rb +13 -0
  46. data/lib/generators/wice_grid/templates/wice_grid_config.rb +191 -0
  47. data/lib/wice/active_record_column_wrapper.rb +122 -0
  48. data/lib/wice/columns.rb +282 -0
  49. data/lib/wice/columns/column_action.rb +51 -0
  50. data/lib/wice/columns/column_boolean.rb +39 -0
  51. data/lib/wice/columns/column_bootstrap_datepicker.rb +47 -0
  52. data/lib/wice/columns/column_custom_dropdown.rb +114 -0
  53. data/lib/wice/columns/column_float.rb +8 -0
  54. data/lib/wice/columns/column_html5_datepicker.rb +30 -0
  55. data/lib/wice/columns/column_integer.rb +87 -0
  56. data/lib/wice/columns/column_jquery_datepicker.rb +48 -0
  57. data/lib/wice/columns/column_processor_index.rb +22 -0
  58. data/lib/wice/columns/column_rails_date_helper.rb +40 -0
  59. data/lib/wice/columns/column_rails_datetime_helper.rb +40 -0
  60. data/lib/wice/columns/column_range.rb +73 -0
  61. data/lib/wice/columns/column_string.rb +91 -0
  62. data/lib/wice/columns/common_date_datetime_mixin.rb +19 -0
  63. data/lib/wice/columns/common_js_date_datetime_conditions_generator_mixin.rb +38 -0
  64. data/lib/wice/columns/common_js_date_datetime_mixin.rb +14 -0
  65. data/lib/wice/columns/common_rails_date_datetime_conditions_generator_mixin.rb +25 -0
  66. data/lib/wice/columns/common_standard_helper_date_datetime_mixin.rb +21 -0
  67. data/lib/wice/grid_output_buffer.rb +48 -0
  68. data/lib/wice/grid_renderer.rb +624 -0
  69. data/lib/wice/helpers/bs_calendar_helpers.rb +73 -0
  70. data/lib/wice/helpers/js_calendar_helpers.rb +82 -0
  71. data/lib/wice/helpers/wice_grid_misc_view_helpers.rb +74 -0
  72. data/lib/wice/helpers/wice_grid_serialized_queries_view_helpers.rb +94 -0
  73. data/lib/wice/helpers/wice_grid_view_helpers.rb +719 -0
  74. data/lib/wice/kaminari_monkey_patching.rb +12 -0
  75. data/lib/wice/table_column_matrix.rb +64 -0
  76. data/lib/wice/wice_grid_controller.rb +174 -0
  77. data/lib/wice/wice_grid_core_ext.rb +145 -0
  78. data/lib/wice/wice_grid_misc.rb +208 -0
  79. data/lib/wice/wice_grid_serialized_queries_controller.rb +86 -0
  80. data/lib/wice/wice_grid_serialized_query.rb +13 -0
  81. data/lib/wice/wice_grid_spreadsheet.rb +19 -0
  82. data/lib/wice_grid.rb +702 -0
  83. data/spec/acceptance_helper.rb +59 -0
  84. data/spec/features/action_column_request_spec.rb +280 -0
  85. data/spec/features/adding_rows_request_spec.rb +21 -0
  86. data/spec/features/all_records_request_spec.rb +18 -0
  87. data/spec/features/auto_reloads2_request_spec.rb +366 -0
  88. data/spec/features/auto_reloads3_request_spec.rb +130 -0
  89. data/spec/features/auto_reloads_request_spec.rb +364 -0
  90. data/spec/features/basics1_request_spec.rb +11 -0
  91. data/spec/features/basics2_request_spec.rb +10 -0
  92. data/spec/features/basics3_request_spec.rb +29 -0
  93. data/spec/features/basics4_request_spec.rb +19 -0
  94. data/spec/features/basics5_request_spec.rb +13 -0
  95. data/spec/features/basics6_request_spec.rb +22 -0
  96. data/spec/features/blockless_column_definition_spec.rb +27 -0
  97. data/spec/features/buttons_request_spec.rb +172 -0
  98. data/spec/features/csv_and_detached_filters_spec.rb +10 -0
  99. data/spec/features/csv_export_request_spec.rb +13 -0
  100. data/spec/features/custom_filter_params_request_spec.rb +29 -0
  101. data/spec/features/custom_filters1_request_spec.rb +136 -0
  102. data/spec/features/custom_filters2_request_spec.rb +31 -0
  103. data/spec/features/custom_filters3_request_spec.rb +34 -0
  104. data/spec/features/custom_filters4_request_spec.rb +13 -0
  105. data/spec/features/custom_ordering_on_calculated_request_spec.rb +30 -0
  106. data/spec/features/custom_ordering_request_spec.rb +36 -0
  107. data/spec/features/custom_ordering_with_arel_request_spec.rb +36 -0
  108. data/spec/features/custom_ordering_with_proc_request_spec.rb +44 -0
  109. data/spec/features/custom_ordering_with_ruby_request_spec.rb +30 -0
  110. data/spec/features/dates_request_spec.rb +56 -0
  111. data/spec/features/detached_filters_spec.rb +10 -0
  112. data/spec/features/detached_filters_two_grids_spec.rb +135 -0
  113. data/spec/features/disable_all_filters_spec.rb +22 -0
  114. data/spec/features/hiding_checkboxes_in_action_column_request_spec.rb +294 -0
  115. data/spec/features/integration_with_application_view_request_spec.rb +43 -0
  116. data/spec/features/integration_with_forms_request_spec.rb +141 -0
  117. data/spec/features/joining_tables_spec.rb +40 -0
  118. data/spec/features/localization_request_spec.rb +24 -0
  119. data/spec/features/many_grids_on_page_request_spec.rb +104 -0
  120. data/spec/features/negation_request_spec.rb +25 -0
  121. data/spec/features/no_records_request_spec.rb +26 -0
  122. data/spec/features/numeric_filters_request_spec.rb +10 -0
  123. data/spec/features/resultset_processings2_request_spec.rb +27 -0
  124. data/spec/features/resultset_processings_request_spec.rb +30 -0
  125. data/spec/features/saved_queries_request_spec.rb +120 -0
  126. data/spec/features/shared.rb +1005 -0
  127. data/spec/features/shared_detached_filters.rb +175 -0
  128. data/spec/features/styling_spec.rb +15 -0
  129. data/spec/features/two_associations_spec.rb +48 -0
  130. data/spec/features/upper_pagination_panel_request_spec.rb +23 -0
  131. data/spec/features/when_filtered_spec.rb +209 -0
  132. data/spec/fixtures/.gitkeep +0 -0
  133. data/spec/fixtures/companies.yml +21 -0
  134. data/spec/fixtures/priorities.yml +31 -0
  135. data/spec/fixtures/project_roles.yml +25 -0
  136. data/spec/fixtures/projects.yml +22 -0
  137. data/spec/fixtures/statuses.yml +55 -0
  138. data/spec/fixtures/tasks.yml +751 -0
  139. data/spec/fixtures/tasks_users.yml +2089 -0
  140. data/spec/fixtures/users.yml +61 -0
  141. data/spec/fixtures/versions.yml +78 -0
  142. data/spec/models/company_spec.rb +6 -0
  143. data/spec/models/priority_spec.rb +6 -0
  144. data/spec/models/project_spec.rb +11 -0
  145. data/spec/models/status_spec.rb +6 -0
  146. data/spec/models/task_spec.rb +12 -0
  147. data/spec/models/user_project_participation_spec.rb +7 -0
  148. data/spec/models/user_spec.rb +12 -0
  149. data/spec/models/version_spec.rb +5 -0
  150. data/spec/rails_helper.rb +15 -0
  151. data/spec/schema.rb +8 -0
  152. data/spec/spec_helper.rb +75 -0
  153. data/spec/support/active_record.rb +10 -0
  154. data/spec/support/test_app/Rakefile +3 -0
  155. data/spec/support/test_app/app/assets/javascripts/application.js +20 -0
  156. data/spec/support/test_app/app/assets/javascripts/common.js.coffee +6 -0
  157. data/spec/support/test_app/app/assets/javascripts/jquery.ui.datepicker.locales.js +56 -0
  158. data/spec/support/test_app/app/assets/stylesheets/adding_rows.scss +3 -0
  159. data/spec/support/test_app/app/assets/stylesheets/application.scss +46 -0
  160. data/spec/support/test_app/app/assets/stylesheets/csv_and_detached_filters.scss +3 -0
  161. data/spec/support/test_app/app/assets/stylesheets/many_grids_on_page.scss +3 -0
  162. data/spec/support/test_app/app/controllers/action_column_controller.rb +15 -0
  163. data/spec/support/test_app/app/controllers/adding_rows_controller.rb +14 -0
  164. data/spec/support/test_app/app/controllers/all_records_controller.rb +14 -0
  165. data/spec/support/test_app/app/controllers/application_controller.rb +99 -0
  166. data/spec/support/test_app/app/controllers/auto_reloads2_controller.rb +14 -0
  167. data/spec/support/test_app/app/controllers/auto_reloads3_controller.rb +20 -0
  168. data/spec/support/test_app/app/controllers/auto_reloads_controller.rb +14 -0
  169. data/spec/support/test_app/app/controllers/basics1_controller.rb +6 -0
  170. data/spec/support/test_app/app/controllers/basics2_controller.rb +6 -0
  171. data/spec/support/test_app/app/controllers/basics3_controller.rb +6 -0
  172. data/spec/support/test_app/app/controllers/basics4_controller.rb +6 -0
  173. data/spec/support/test_app/app/controllers/basics5_controller.rb +6 -0
  174. data/spec/support/test_app/app/controllers/basics6_controller.rb +11 -0
  175. data/spec/support/test_app/app/controllers/blockless_column_definition_controller.rb +6 -0
  176. data/spec/support/test_app/app/controllers/buttons_controller.rb +6 -0
  177. data/spec/support/test_app/app/controllers/csv_and_detached_filters_controller.rb +13 -0
  178. data/spec/support/test_app/app/controllers/csv_export_controller.rb +28 -0
  179. data/spec/support/test_app/app/controllers/custom_filter_params_controller.rb +6 -0
  180. data/spec/support/test_app/app/controllers/custom_filters1_controller.rb +9 -0
  181. data/spec/support/test_app/app/controllers/custom_filters2_controller.rb +14 -0
  182. data/spec/support/test_app/app/controllers/custom_filters3_controller.rb +12 -0
  183. data/spec/support/test_app/app/controllers/custom_filters4_controller.rb +12 -0
  184. data/spec/support/test_app/app/controllers/custom_ordering_controller.rb +18 -0
  185. data/spec/support/test_app/app/controllers/custom_ordering_on_calculated_controller.rb +6 -0
  186. data/spec/support/test_app/app/controllers/custom_ordering_with_arel_controller.rb +18 -0
  187. data/spec/support/test_app/app/controllers/custom_ordering_with_proc_controller.rb +11 -0
  188. data/spec/support/test_app/app/controllers/custom_ordering_with_ruby_controller.rb +6 -0
  189. data/spec/support/test_app/app/controllers/dates_controller.rb +8 -0
  190. data/spec/support/test_app/app/controllers/detached_filters_controller.rb +6 -0
  191. data/spec/support/test_app/app/controllers/detached_filters_two_grids_controller.rb +7 -0
  192. data/spec/support/test_app/app/controllers/disable_all_filters_controller.rb +6 -0
  193. data/spec/support/test_app/app/controllers/hiding_checkboxes_in_action_column_controller.rb +13 -0
  194. data/spec/support/test_app/app/controllers/home_controller.rb +3 -0
  195. data/spec/support/test_app/app/controllers/integration_with_application_view_controller.rb +16 -0
  196. data/spec/support/test_app/app/controllers/integration_with_forms_controller.rb +11 -0
  197. data/spec/support/test_app/app/controllers/joining_tables_controller.rb +11 -0
  198. data/spec/support/test_app/app/controllers/localization_controller.rb +26 -0
  199. data/spec/support/test_app/app/controllers/many_grids_on_page_controller.rb +7 -0
  200. data/spec/support/test_app/app/controllers/negation_controller.rb +14 -0
  201. data/spec/support/test_app/app/controllers/no_records_controller.rb +8 -0
  202. data/spec/support/test_app/app/controllers/null_values_controller.rb +10 -0
  203. data/spec/support/test_app/app/controllers/numeric_filters_controller.rb +6 -0
  204. data/spec/support/test_app/app/controllers/queries_controller.rb +4 -0
  205. data/spec/support/test_app/app/controllers/resultset_processings2_controller.rb +29 -0
  206. data/spec/support/test_app/app/controllers/resultset_processings_controller.rb +30 -0
  207. data/spec/support/test_app/app/controllers/saved_queries_controller.rb +14 -0
  208. data/spec/support/test_app/app/controllers/styling_controller.rb +7 -0
  209. data/spec/support/test_app/app/controllers/tasks_controller.rb +14 -0
  210. data/spec/support/test_app/app/controllers/two_associations_controller.rb +6 -0
  211. data/spec/support/test_app/app/controllers/upper_pagination_panel_controller.rb +6 -0
  212. data/spec/support/test_app/app/controllers/when_filtered_controller.rb +6 -0
  213. data/spec/support/test_app/app/helpers/application_helper.rb +82 -0
  214. data/spec/support/test_app/app/mailers/.gitkeep +0 -0
  215. data/spec/support/test_app/app/models/.gitkeep +0 -0
  216. data/spec/support/test_app/app/models/company.rb +5 -0
  217. data/spec/support/test_app/app/models/populate.rb +84 -0
  218. data/spec/support/test_app/app/models/priority.rb +10 -0
  219. data/spec/support/test_app/app/models/project.rb +14 -0
  220. data/spec/support/test_app/app/models/project_role.rb +3 -0
  221. data/spec/support/test_app/app/models/status.rb +10 -0
  222. data/spec/support/test_app/app/models/task.rb +11 -0
  223. data/spec/support/test_app/app/models/to_dropdown_mixin.rb +16 -0
  224. data/spec/support/test_app/app/models/user.rb +8 -0
  225. data/spec/support/test_app/app/models/user_project_participation.rb +6 -0
  226. data/spec/support/test_app/app/models/version.rb +6 -0
  227. data/spec/support/test_app/app/views/action_column/_grid.html.erb +35 -0
  228. data/spec/support/test_app/app/views/action_column/index.html.haml +45 -0
  229. data/spec/support/test_app/app/views/adding_rows/_grid.html.erb +58 -0
  230. data/spec/support/test_app/app/views/adding_rows/index.html.haml +37 -0
  231. data/spec/support/test_app/app/views/all_records/_grid.html.erb +30 -0
  232. data/spec/support/test_app/app/views/all_records/index.html.haml +12 -0
  233. data/spec/support/test_app/app/views/auto_reloads/_grid.html.erb +32 -0
  234. data/spec/support/test_app/app/views/auto_reloads/index.html.haml +15 -0
  235. data/spec/support/test_app/app/views/auto_reloads2/_grid.html.erb +32 -0
  236. data/spec/support/test_app/app/views/auto_reloads2/index.html.haml +65 -0
  237. data/spec/support/test_app/app/views/auto_reloads3/_grid.html.erb +25 -0
  238. data/spec/support/test_app/app/views/auto_reloads3/index.html.haml +78 -0
  239. data/spec/support/test_app/app/views/basics1/_grid.html.erb +26 -0
  240. data/spec/support/test_app/app/views/basics1/index.html.haml +13 -0
  241. data/spec/support/test_app/app/views/basics2/_grid.html.erb +27 -0
  242. data/spec/support/test_app/app/views/basics2/index.html.haml +12 -0
  243. data/spec/support/test_app/app/views/basics3/_grid.html.erb +28 -0
  244. data/spec/support/test_app/app/views/basics3/index.html.haml +13 -0
  245. data/spec/support/test_app/app/views/basics4/_grid.html.erb +21 -0
  246. data/spec/support/test_app/app/views/basics4/index.html.haml +12 -0
  247. data/spec/support/test_app/app/views/basics5/_grid.html.erb +19 -0
  248. data/spec/support/test_app/app/views/basics5/index.html.haml +12 -0
  249. data/spec/support/test_app/app/views/basics6/_grid.html.erb +19 -0
  250. data/spec/support/test_app/app/views/basics6/index.html.haml +23 -0
  251. data/spec/support/test_app/app/views/blockless_column_definition/_grid.html.erb +19 -0
  252. data/spec/support/test_app/app/views/blockless_column_definition/index.html.haml +15 -0
  253. data/spec/support/test_app/app/views/buttons/_grid.html.erb +20 -0
  254. data/spec/support/test_app/app/views/buttons/index.html.haml +30 -0
  255. data/spec/support/test_app/app/views/csv_and_detached_filters/_grid.html.erb +23 -0
  256. data/spec/support/test_app/app/views/csv_and_detached_filters/index.html.haml +58 -0
  257. data/spec/support/test_app/app/views/csv_export/_projects_grid.html.erb +17 -0
  258. data/spec/support/test_app/app/views/csv_export/_tasks_grid.html.erb +43 -0
  259. data/spec/support/test_app/app/views/csv_export/index.html.haml +90 -0
  260. data/spec/support/test_app/app/views/custom_filter_params/_grid.html.erb +12 -0
  261. data/spec/support/test_app/app/views/custom_filter_params/index.html.haml +12 -0
  262. data/spec/support/test_app/app/views/custom_filters1/_g1.html.erb +8 -0
  263. data/spec/support/test_app/app/views/custom_filters1/_g2.html.erb +9 -0
  264. data/spec/support/test_app/app/views/custom_filters1/_g3.html.erb +9 -0
  265. data/spec/support/test_app/app/views/custom_filters1/_g4.html.erb +8 -0
  266. data/spec/support/test_app/app/views/custom_filters1/index.html.haml +30 -0
  267. data/spec/support/test_app/app/views/custom_filters2/_grid.html.erb +30 -0
  268. data/spec/support/test_app/app/views/custom_filters2/index.html.haml +41 -0
  269. data/spec/support/test_app/app/views/custom_filters3/_grid.html.erb +18 -0
  270. data/spec/support/test_app/app/views/custom_filters3/index.html.haml +16 -0
  271. data/spec/support/test_app/app/views/custom_filters4/_grid.html.erb +20 -0
  272. data/spec/support/test_app/app/views/custom_filters4/index.html.haml +12 -0
  273. data/spec/support/test_app/app/views/custom_ordering/_grid.html.erb +10 -0
  274. data/spec/support/test_app/app/views/custom_ordering/index.html.haml +24 -0
  275. data/spec/support/test_app/app/views/custom_ordering_on_calculated/_grid.html.erb +14 -0
  276. data/spec/support/test_app/app/views/custom_ordering_on_calculated/index.html.haml +23 -0
  277. data/spec/support/test_app/app/views/custom_ordering_with_arel/_grid.html.erb +10 -0
  278. data/spec/support/test_app/app/views/custom_ordering_with_arel/index.html.haml +24 -0
  279. data/spec/support/test_app/app/views/custom_ordering_with_proc/_grid.html.erb +10 -0
  280. data/spec/support/test_app/app/views/custom_ordering_with_proc/index.html.haml +21 -0
  281. data/spec/support/test_app/app/views/custom_ordering_with_ruby/_grid.html.erb +10 -0
  282. data/spec/support/test_app/app/views/custom_ordering_with_ruby/index.html.haml +23 -0
  283. data/spec/support/test_app/app/views/dates/_grid.html.erb +25 -0
  284. data/spec/support/test_app/app/views/dates/index.html.haml +52 -0
  285. data/spec/support/test_app/app/views/detached_filters/_grid.html.erb +23 -0
  286. data/spec/support/test_app/app/views/detached_filters/index.html.haml +79 -0
  287. data/spec/support/test_app/app/views/detached_filters_two_grids/_grid.html.erb +23 -0
  288. data/spec/support/test_app/app/views/detached_filters_two_grids/index.html.haml +85 -0
  289. data/spec/support/test_app/app/views/disable_all_filters/_grid.html.erb +21 -0
  290. data/spec/support/test_app/app/views/disable_all_filters/index.html.haml +14 -0
  291. data/spec/support/test_app/app/views/hiding_checkboxes_in_action_column/_grid.html.erb +34 -0
  292. data/spec/support/test_app/app/views/hiding_checkboxes_in_action_column/index.html.haml +32 -0
  293. data/spec/support/test_app/app/views/integration_with_application_view/_grid.html.erb +27 -0
  294. data/spec/support/test_app/app/views/integration_with_application_view/index.html.haml +33 -0
  295. data/spec/support/test_app/app/views/integration_with_forms/_grid.html.erb +23 -0
  296. data/spec/support/test_app/app/views/integration_with_forms/index.html.haml +18 -0
  297. data/spec/support/test_app/app/views/joining_tables/_grid.html.erb +23 -0
  298. data/spec/support/test_app/app/views/joining_tables/index.html.haml +26 -0
  299. data/spec/support/test_app/app/views/layouts/application.html.haml +61 -0
  300. data/spec/support/test_app/app/views/localization/_grid.html.erb +36 -0
  301. data/spec/support/test_app/app/views/localization/index.html.haml +20 -0
  302. data/spec/support/test_app/app/views/many_grids_on_page/_tasks_grid1.html.erb +12 -0
  303. data/spec/support/test_app/app/views/many_grids_on_page/_tasks_grid2.html.erb +12 -0
  304. data/spec/support/test_app/app/views/many_grids_on_page/index.html.haml +26 -0
  305. data/spec/support/test_app/app/views/negation/_grid.html.erb +30 -0
  306. data/spec/support/test_app/app/views/negation/index.html.haml +15 -0
  307. data/spec/support/test_app/app/views/no_records/_empty_grid.html.haml +1 -0
  308. data/spec/support/test_app/app/views/no_records/_grid1.html.erb +11 -0
  309. data/spec/support/test_app/app/views/no_records/_grid2.html.erb +9 -0
  310. data/spec/support/test_app/app/views/no_records/_grid3.html.erb +9 -0
  311. data/spec/support/test_app/app/views/no_records/index.html.haml +24 -0
  312. data/spec/support/test_app/app/views/null_values/_grid.html.erb +17 -0
  313. data/spec/support/test_app/app/views/null_values/index.html.haml +21 -0
  314. data/spec/support/test_app/app/views/numeric_filters/_grid.html.erb +19 -0
  315. data/spec/support/test_app/app/views/numeric_filters/index.html.haml +12 -0
  316. data/spec/support/test_app/app/views/resultset_processings/_grid.html.erb +27 -0
  317. data/spec/support/test_app/app/views/resultset_processings/index.html.haml +50 -0
  318. data/spec/support/test_app/app/views/resultset_processings2/_grid.html.erb +27 -0
  319. data/spec/support/test_app/app/views/resultset_processings2/index.html.haml +48 -0
  320. data/spec/support/test_app/app/views/saved_queries/_grid.html.erb +30 -0
  321. data/spec/support/test_app/app/views/saved_queries/index.html.haml +15 -0
  322. data/spec/support/test_app/app/views/styling/_grid1.html.erb +12 -0
  323. data/spec/support/test_app/app/views/styling/_grid2.html.erb +31 -0
  324. data/spec/support/test_app/app/views/styling/index.html.haml +65 -0
  325. data/spec/support/test_app/app/views/tasks/_grid.html.erb +19 -0
  326. data/spec/support/test_app/app/views/tasks/index.html.haml +1 -0
  327. data/spec/support/test_app/app/views/two_associations/_grid.html.erb +13 -0
  328. data/spec/support/test_app/app/views/two_associations/index.html.haml +13 -0
  329. data/spec/support/test_app/app/views/upper_pagination_panel/_grid.html.erb +27 -0
  330. data/spec/support/test_app/app/views/upper_pagination_panel/index.html.haml +14 -0
  331. data/spec/support/test_app/app/views/when_filtered/_grid.html.erb +19 -0
  332. data/spec/support/test_app/app/views/when_filtered/index.html.haml +15 -0
  333. data/spec/support/test_app/bin/rails +4 -0
  334. data/spec/support/test_app/bin/rake +4 -0
  335. data/spec/support/test_app/config.ru +5 -0
  336. data/spec/support/test_app/config/application.rb +70 -0
  337. data/spec/support/test_app/config/boot.rb +7 -0
  338. data/spec/support/test_app/config/database.travis.yml +27 -0
  339. data/spec/support/test_app/config/database.yml +16 -0
  340. data/spec/support/test_app/config/database.yml.mysql +19 -0
  341. data/spec/support/test_app/config/database.yml.postgresql +18 -0
  342. data/spec/support/test_app/config/environment.rb +6 -0
  343. data/spec/support/test_app/config/environments/development.rb +34 -0
  344. data/spec/support/test_app/config/environments/production.rb +66 -0
  345. data/spec/support/test_app/config/environments/test.rb +34 -0
  346. data/spec/support/test_app/config/initializers/backtrace_silencers.rb +8 -0
  347. data/spec/support/test_app/config/initializers/inflections.rb +16 -0
  348. data/spec/support/test_app/config/initializers/mime_types.rb +6 -0
  349. data/spec/support/test_app/config/initializers/secret_token.rb +12 -0
  350. data/spec/support/test_app/config/initializers/session_store.rb +9 -0
  351. data/spec/support/test_app/config/initializers/wice_grid_config.rb +163 -0
  352. data/spec/support/test_app/config/initializers/wrap_parameters.rb +15 -0
  353. data/spec/support/test_app/config/locales/en.yml +5 -0
  354. data/spec/support/test_app/config/locales/wice_grid.yml +550 -0
  355. data/spec/support/test_app/config/puma.rb +15 -0
  356. data/spec/support/test_app/config/routes.rb +125 -0
  357. data/spec/support/test_app/db/migrate/20120224193505_create_tasks.rb +27 -0
  358. data/spec/support/test_app/db/migrate/20120224193517_create_users.rb +12 -0
  359. data/spec/support/test_app/db/migrate/20120224193522_create_projects.rb +14 -0
  360. data/spec/support/test_app/db/migrate/20120224193529_create_priorities.rb +13 -0
  361. data/spec/support/test_app/db/migrate/20120224193537_create_statuses.rb +13 -0
  362. data/spec/support/test_app/db/migrate/20120224193543_create_versions.rb +15 -0
  363. data/spec/support/test_app/db/migrate/20120224193550_create_project_roles.rb +12 -0
  364. data/spec/support/test_app/db/migrate/20120224193610_create_companies.rb +12 -0
  365. data/spec/support/test_app/db/migrate/20120224195351_create_user_project_participations.rb +16 -0
  366. data/spec/support/test_app/db/migrate/20120224195521_add_tasks_users.rb +11 -0
  367. data/spec/support/test_app/db/migrate/20120610091944_create_wice_grid_serialized_queries.rb +14 -0
  368. data/spec/support/test_app/db/schema.rb +139 -0
  369. data/spec/support/test_app/db/seeds.rb +10 -0
  370. data/spec/support/test_app/lib/ar_fixtures.rb +100 -0
  371. data/spec/support/test_app/lib/assets/.gitkeep +0 -0
  372. data/spec/support/test_app/lib/tasks/.gitkeep +0 -0
  373. data/spec/support/test_app/lib/tasks/ar_fixtures.rake +45 -0
  374. data/spec/support/test_app/public/404.html +26 -0
  375. data/spec/support/test_app/public/422.html +26 -0
  376. data/spec/support/test_app/public/500.html +25 -0
  377. data/spec/support/test_app/public/favicon.ico +0 -0
  378. data/spec/support/test_app/public/robots.txt +5 -0
  379. data/spec/wice/grid_output_buffer_spec.rb +39 -0
  380. data/spec/wice/table_column_matrix_spec.rb +36 -0
  381. data/spec/wice/wice_grid_misc_spec.rb +157 -0
  382. data/spec/wice/wice_grid_spreadsheet_spec.rb +12 -0
  383. data/vendor/assets/javascripts/wice_grid.js +3 -0
  384. data/vendor/assets/javascripts/wice_grid_init.js.coffee +351 -0
  385. data/vendor/assets/javascripts/wice_grid_processor.js.coffee +133 -0
  386. data/vendor/assets/javascripts/wice_grid_saved_queries_init.js.coffee +104 -0
  387. data/vendor/assets/stylesheets/wice_grid.scss +81 -0
  388. data/wice_grid.gemspec +54 -0
  389. metadata +861 -0
@@ -0,0 +1,12 @@
1
+ # Ugly monkey-patching Kaminari (https://github.com/amatsuda/kaminari/pull/267)
2
+ module Kaminari #:nodoc:
3
+ module Helpers #:nodoc:
4
+ class Tag #:nodoc:
5
+ def page_url_for(page) #:nodoc:
6
+ current_page_params_as_query_string = @param_name.to_s + '=' + (page <= 1 ? nil : page).to_s
7
+ current_page_params_as_hash = Rack::Utils.parse_nested_query(current_page_params_as_query_string)
8
+ @template.url_for Wice::WgHash.rec_merge(@params, current_page_params_as_hash).symbolize_keys
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,64 @@
1
+ module Wice
2
+
3
+ # a matrix for all declared columns
4
+ class TableColumnMatrix < Hash #:nodoc:
5
+
6
+ # a structure to hold generates Arels for all column filters
7
+ attr_reader :generated_conditions
8
+
9
+ # init a matrix of all columns
10
+ def initialize #:nodoc:
11
+ super
12
+ @generated_conditions = []
13
+ @by_table_names = HashWithIndifferentAccess.new
14
+ end
15
+
16
+ # add an Arel for a column
17
+ def add_condition(column, conditions)
18
+ @generated_conditions << [column, conditions] unless conditions.blank?
19
+ end
20
+
21
+ # returns a list of all Arels
22
+ def conditions
23
+ @generated_conditions.collect { |_, cond| cond }
24
+ end
25
+
26
+ # returns Arels for one model
27
+ alias_method :get, :[]
28
+
29
+ # returns the main ActiveRecord model class
30
+ attr_reader :default_model_class
31
+
32
+ # sets the main ActiveRecord model class
33
+ def default_model_class=(model) #:nodoc:
34
+ init_columns_of_table(model) unless key?(model)
35
+ @default_model_class = model
36
+ end
37
+
38
+ # returns Arels for one model
39
+ def [](model) #:nodoc:
40
+ init_columns_of_table(model) unless key?(model)
41
+ get(model)
42
+ end
43
+
44
+ def get_column_by_model_class_and_column_name(model_class, column_name) #:nodoc:
45
+ self[model_class][column_name]
46
+ end
47
+
48
+ def get_column_in_default_model_class_by_column_name(column_name) #:nodoc:
49
+ if @default_model_class.nil?
50
+ raise WiceGridException.new("Cannot search for this column(#{column_name}) in a default model(#{@default_model_class}) as the default model is not set")
51
+ end
52
+
53
+ self[@default_model_class][column_name]
54
+ end
55
+
56
+ def init_columns_of_table(model) #:nodoc:
57
+ self[model] = HashWithIndifferentAccess.new(model.columns.index_by(&:name))
58
+ @by_table_names[model.table_name] = self[model]
59
+ self[model].each_value { |c| c.model = model }
60
+ end
61
+
62
+ alias_method :<<, :init_columns_of_table
63
+ end
64
+ end
@@ -0,0 +1,174 @@
1
+ module Wice
2
+ module Controller #:nodoc:
3
+ def self.included(base) #:nodoc:
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ module ClassMethods #:nodoc:
8
+ # Used to add query processing action methods into a controller.
9
+ # Read section "Saving Queries How-To" in README for more details.
10
+ def save_wice_grid_queries
11
+ include Wice::SerializedQueriesControllerMixin
12
+ end
13
+ end
14
+
15
+ protected
16
+
17
+ attr_accessor :wice_grid_instances #:nodoc:
18
+
19
+ # Creates a grid object to be used in the view. This is the <i>main</i> model, and the underlying table is the default table -
20
+ # if in other parameters a column name is mentioned without the name of the table, this table is implied.
21
+ # Just like in an ordinary ActiveRecord <tt>find</tt> you can use <tt>:joins</tt>, <tt>:include</tt>, and <tt>:conditions</tt>.
22
+ #
23
+ # The first parameter is an ActiveRecord class name or an ActiveRecord::Relation instance. The generated ActiveRecord call will use it as the
24
+ # receiver of the <tt>paginate</tt> method: <tt>klass.paginate(...)</tt>
25
+ #
26
+ # The second parameters is a hash of parameters:
27
+ # * <tt>:joins</tt> - ActiveRecord <tt>:joins</tt> option.
28
+ # * <tt>:include</tt> - ActiveRecord <tt>:include</tt> option.
29
+ # The value of `:include` can be an array of association names `include: [:category, :users, :status]`,
30
+ # If you need to join tables to joined tables, use hashes: `include: [:category, {users: :group}, :status]`
31
+ # * <tt>:conditions</tt> - ActiveRecord <tt>:conditions</tt> option.
32
+ # * <tt>:per_page</tt> - Number of rows per one page. The default is 10.
33
+ # * <tt>:page</tt> - The page to show when rendering the grid for the first time. The default is one, naturally.
34
+ # * <tt>:order</tt> - Name of the column to sort by. Can be of a short form (just the name of the column) if this
35
+ # is a column of the main table (the table of the main ActiveRecord model, the first parameter of <tt>initialize_grid</tt>),
36
+ # or a fully qualified name with the name of the table.
37
+ # * <tt>:order_direction</tt> - <tt>:asc</tt> for ascending or <tt>:desc</tt> for descending. The default is <tt>:asc</tt>.
38
+ # * <tt>:name</tt> - name of the grid. Only needed if there is a second grid on a page. The name serves as the base name for
39
+ # HTTP parametes, DOM IDs, etc. The shorter the name, the shorter the GET request is. The name can only contain alphanumeruc characters.
40
+ # * <tt>:enable_export_to_csv</tt> - <Enable export of the table to CSV. Read the How-To to learn what else is needed to enable CSV export.
41
+ # * <tt>:csv_file_name</tt> - Name of the exported CSV file. If the parameter is missing, the name of the grid will be used instead.
42
+ # * <tt>:csv_field_separator</tt> - field separator for CSV files. The default is defined in +CSV_FIELD_SEPARATOR+ in the config file.
43
+ # * <tt>:custom_order</tt> - used for overriding the ORDER BY clause with custom sql code (for example, using an SQL
44
+ # function). A Hash with keys of the fully qualified names of database columns and with values that specify the
45
+ # ordering to be used, without specifying the direction (no ASC or DESC). The values of this Hash can any String
46
+ # of SQL that can be passed to the ActiveRecord order clause, an instance of Arel::Attributes::Attribute, or a
47
+ # Proc that receives the fully qualified column name and returns a String or Arel::Attributes::Attribute. See
48
+ # section 'Custom Ordering' in the README.
49
+ # * <tt>:saved_query</tt> - id of the saved query or the query object itself to load initially.
50
+ # Read section "Saving Queries How-To" in README for more details.
51
+ # * <tt>:after</tt> - defined a name of a controller method which would be called by the grid after all user input has been processed,
52
+ # with a single parameter which is a Proc object. Once called, the object returns a list of all records of the current selection
53
+ # throughout all pages. See section "Integration With The Application" in the README.
54
+ # * <tt>:select</tt> - ActiveRecord <tt>:select</tt> option. Please do not forget that <tt>:select</tt> is ignored
55
+ # when <tt>:include</tt> is present. It is unlikely you would need <tt>:select</tt> with WiceGrid, but if you do,
56
+ # use it with care :)
57
+ # * <tt>:group</tt> - ActiveRecord <tt>:group</tt> option. Use it if you are sure you know what you are doing :)
58
+ # * <tt>:with_paginated_resultset</tt> - a callback executed from within the plugin to process records of the current page.
59
+ # Can be a lambda object or a controller method name (symbol). The argument to the callback is the array of the records.
60
+ # * <tt>:with_resultset</tt> - a callback executed from within the plugin to process all records browsable through
61
+ # all pages with the current filters. Can be a lambda object or a controller method name (symbol). The argument to
62
+ # the callback is a lambda object which returns the list of records when called. See the README for the explanation.
63
+ #
64
+ # Defaults for parameters <tt>:per_page</tt>, <tt>:order_direction</tt>, and <tt>:name</tt>
65
+ # can be changed in <tt>lib/wice_grid_config.rb</tt>, this is convenient if you want to set a project wide setting
66
+ # without having to repeat it for every grid instance.
67
+
68
+ def initialize_grid(klass, opts = {})
69
+ wg = WiceGrid.new(klass, self, opts)
70
+ self.wice_grid_instances = [] if self.wice_grid_instances.nil?
71
+ self.wice_grid_instances << wg
72
+ wg
73
+ end
74
+
75
+ # +export_grid_if_requested+ is a controller method which should be called at the end of each action containing grids with enabled
76
+ # CSV export.
77
+ #
78
+ # CSV export will only work if each WiceGrid helper is placed in a partial of its own (requiring it from the master template
79
+ # of course for the usual flow).
80
+ # +export_grid_if_requested+ intercepts CSV export requests and evaluates the corresponding partial with the required grid helper.
81
+ # By default for each grid +export_grid_if_requested+ will look for a partial
82
+ # whose name follows the following pattern:
83
+ #
84
+ # _GRID_NAME_grid.html.erb
85
+ #
86
+ # For example, a grid named +orders+ is supposed to be found in a template called <tt>_orders_grid.html.erb</tt>,
87
+ # Remember that the default name of grids is +grid+.
88
+ #
89
+ # This convention can be easily overridden by supplying a hash parameter to +export_grid_if_requested+ where each key is the name of
90
+ # a grid, and the value is the name of the template (like it is specified for +render+, i.e. without '_' and extensions):
91
+ #
92
+ # export_grid_if_requested('grid' => 'orders', 'grid2' => 'invoices')
93
+ #
94
+ # If the request is not a CSV export request, the method does nothing and returns +false+, if it is a CSV export request,
95
+ # the method returns +true+.
96
+ #
97
+ # If the action has no explicit +render+ call, it's OK to just place +export_grid_if_requested+ as the last line of the action. Otherwise,
98
+ # to avoid double rendering, use the return value of the method to conditionally call your +render+ :
99
+ #
100
+ # export_grid_if_requested || render(action: 'index')
101
+ #
102
+ # It's also possible to supply a block which will be called if no CSV export is requested:
103
+ #
104
+ # export_grid_if_requested do
105
+ # render(action: 'index')
106
+ # end
107
+
108
+ def export_grid_if_requested(opts = {})
109
+ grid = self.wice_grid_instances.detect(&:output_csv?)
110
+
111
+ if grid
112
+ template_name = opts[grid.name] || opts[grid.name.intern]
113
+ template_name ||= grid.name + '_grid'
114
+ temp_filename = render_to_string(partial: template_name)
115
+ temp_filename = temp_filename.strip
116
+ filename = (grid.csv_file_name || grid.name) + '.csv'
117
+ grid.csv_tempfile.close
118
+ send_file temp_filename, filename: filename, type: "text/csv; charset=#{get_output_encoding grid.csv_encoding}"
119
+ grid.csv_tempfile = nil
120
+ true
121
+ else
122
+ yield if block_given?
123
+ false
124
+ end
125
+ end
126
+
127
+ # +wice_grid_custom_filter_params+ generates HTTP parameters understood by WiceGrid custom filters.
128
+ # Combined with Rails route helpers it allows to generate links leading to
129
+ # grids with pre-selected custom filters.
130
+ #
131
+ # Parameters:
132
+ # * <tt>:grid_name</tt> - The name of the grid. Just like parameter <tt>:name</tt> of
133
+ # <tt>initialize_grid</tt>, the parameter is optional, and when absent, the name
134
+ # <tt>'grid'</tt> is assumed
135
+ # * <tt>:attribute</tt> and <tt>:model</tt> - should be the same as <tt>:attribute</tt> and
136
+ # <tt>:model</tt> of the column declaration with the target custom filter.
137
+ # * <tt>:value</tt> - the value of the column filter.
138
+ def wice_grid_custom_filter_params(opts = {})
139
+ options = {
140
+ grid_name: 'grid',
141
+ attribute: nil,
142
+ model: nil,
143
+ value: nil
144
+ }
145
+ options.merge!(opts)
146
+
147
+ [:attribute, :value].each do |key|
148
+ raise ::Wice::WiceGridArgumentError.new("wice_grid_custom_filter_params: :#{key} is a mandatory argument") unless options[key]
149
+ end
150
+
151
+ attr_name = if options[:model]
152
+ unless options[:model].nil?
153
+ options[:model] = options[:model].constantize if options[:model].is_a? String
154
+ raise Wice::WiceGridArgumentError.new('Option :model can be either a class or a string instance') unless options[:model].is_a? Class
155
+ end
156
+ options[:model].table_name + '.' + options[:attribute]
157
+ else
158
+ options[:attribute]
159
+ end
160
+
161
+ { "#{options[:grid_name]}[f][#{attr_name}][]" => options[:value] }
162
+ end
163
+
164
+ private
165
+
166
+ def get_output_encoding(csv_encoding)
167
+ if csv_encoding.blank?
168
+ 'utf-8'
169
+ else
170
+ csv_encoding.split(':').first
171
+ end
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,145 @@
1
+ module Wice
2
+ module WgHash #:nodoc:
3
+ class << self #:nodoc:
4
+ # if there's a hash of hashes, the original structure and the
5
+ # returned structure should not contain any shared deep hashes
6
+ def deep_clone(hash) #:nodoc:
7
+ cloned = hash.clone
8
+ cloned.keys.each do |k|
9
+ if cloned[k].is_a?(Hash)
10
+ cloned[k] = Wice::WgHash.deep_clone cloned[k]
11
+ end
12
+ end
13
+ cloned
14
+ end
15
+
16
+ # Used to modify options submitted to view helpers. If there is no :klass option,
17
+ # it will be added, if there is, the css class name will be appended to the existing
18
+ # class name(s)
19
+ def add_or_append_class_value!(hash, klass_value, prepend = false) #:nodoc:
20
+ if hash.key?('class')
21
+ hash[:class] = hash['class']
22
+ hash.delete('class')
23
+ end
24
+
25
+ hash[:class] = if hash.key?(:class)
26
+ if prepend
27
+ "#{klass_value} #{hash[:class]}"
28
+ else
29
+ "#{hash[:class]} #{klass_value}"
30
+ end
31
+ else
32
+ klass_value
33
+ end
34
+
35
+ hash
36
+ end
37
+
38
+ # Used mostly for submitting options to view helpers, that is, like this:
39
+ # content_tag(:th, col_link, Wice::WgHash.make_hash(:class, css_class))
40
+ # In some it is important that if the value is empty, no option
41
+ # is submitted at all. Thus, there's a check for an empty value
42
+ def make_hash(key, value) #:nodoc:
43
+ value.blank? ? {} : { key => value }
44
+ end
45
+
46
+ # A deep merge of two hashes.
47
+ # That is, if both hashes have the same key and the values are hashes, these two hashes should also be merged.
48
+ # Used for merging two sets of params.
49
+ def rec_merge(hash, other) #:nodoc:
50
+ res = hash.clone
51
+ other.each do |key, other_value|
52
+ value = res[key]
53
+ if value.is_a?(Hash) && other_value.is_a?(Hash)
54
+ res[key] = rec_merge value, other_value
55
+ else
56
+ res[key] = other_value
57
+ end
58
+ end
59
+ res
60
+ end
61
+
62
+ # Used to transform a traditional params hash
63
+ # into an array of two element arrays where element zero is a parameter name as it appears in HTTP requests,
64
+ # and the first element is the value:
65
+ # { a: { b: 3, c: 4, d: { e: 5 }} }.parameter_names_and_values #=> [["a[d][e]", 5], ["a[b]", 3], ["a[c]", 4]]
66
+ # The parameter is an optional array of parameter names to prepend:
67
+ # { a: { b: 3, c: 4, d: { e: 5 }} }.parameter_names_and_values(['foo', 'baz']) #=>
68
+ # [["foo[baz][a][d][e]", 5], ["foo[baz][a][b]", 3], ["foo[baz][a][c]", 4]]
69
+ def parameter_names_and_values(hash, initial = []) #:nodoc:
70
+ res = []
71
+ recursively_gather_finite_non_hash_values_with_key_path(hash, res, [])
72
+ res.collect do |parameter_struct|
73
+ parameter_struct[0] = initial + parameter_struct[0]
74
+ [Wice::WgArray.to_parameter_name(parameter_struct[0]), parameter_struct[1]]
75
+ end
76
+ end
77
+
78
+ protected
79
+
80
+ def recursively_gather_finite_non_hash_values_with_key_path(hash, res, stack = []) #:nodoc:
81
+ hash.each do |key, value|
82
+ if value.is_a?(Hash)
83
+ recursively_gather_finite_non_hash_values_with_key_path(value, res, stack + [key])
84
+ else
85
+ res << [stack + [key], value]
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ module WgEnumerable #:nodoc:
93
+ # Used to check the validity of :custom_filter parameter of column
94
+ def self.all_items_are_of_class(enumerable, klass) #:nodoc:
95
+ return false if enumerable.empty?
96
+ enumerable.inject(true) { |memo, o| (o.is_a? klass) && memo }
97
+ end
98
+ end
99
+
100
+ module WgArray #:nodoc:
101
+ # Only used by Hash#parameter_names_and_values
102
+ # Transforms ['foo', 'bar', 'baz'] to 'foo[bar][baz]'
103
+ def self.to_parameter_name(array) #:nodoc:
104
+ array[0].to_s + (array[1..-1] || []).collect { |k| '[' + k.to_s + ']' }.join('')
105
+ end
106
+ end
107
+ end
108
+
109
+ # tag_options is a Rails views private method that takes a hash op options for
110
+ # an HTM hash and produces a string ready to be added to the tag.
111
+ # Here we are changing its visibility in order to be able to use it.
112
+ module ActionView #:nodoc:
113
+ module Helpers #:nodoc:
114
+ module TagHelper #:nodoc:
115
+ def public_tag_options(options, escape = true) #:nodoc:
116
+ if respond_to?(:tag_options, true)
117
+ tag_options(options, escape)
118
+ else
119
+ tag_builder.tag_options(options, escape)
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ module WGObjectExtensions #:nodoc:
127
+ # takes a list of messages, sends message 1 to self, then message 2 is sent to the result of the first message, ans so on
128
+ # returns nil as soon as the current receiver does not respond to such a message
129
+ def deep_send(*messages) #:nodoc:
130
+ obj = self
131
+ messages.each do |message|
132
+ if obj.respond_to? message
133
+ obj = obj.send(message)
134
+ else
135
+ return nil
136
+ end
137
+ # return obj if obj.nil?
138
+ end
139
+ obj
140
+ end
141
+ end
142
+
143
+ class Object #:nodoc:
144
+ include WGObjectExtensions
145
+ end
@@ -0,0 +1,208 @@
1
+ module Wice
2
+ class << self
3
+
4
+ # a flag storing whether the saved query class is a valid storage for saved queries
5
+ @@model_validated = false
6
+
7
+ def assoc_list_to_hash(assocs) #:nodoc:
8
+ head = assocs[0]
9
+ tail = assocs[1..-1]
10
+
11
+ if tail.blank?
12
+ head
13
+ elsif tail.size == 1
14
+ {head => tail[0]}
15
+ else
16
+ {head => assoc_list_to_hash(tail)}
17
+ end
18
+ end
19
+
20
+ def build_includes(existing_includes, new_assocs) #:nodoc:
21
+ new_includes = if new_assocs.blank?
22
+ existing_includes
23
+ else
24
+ existing_includes = if existing_includes.is_a?(Symbol)
25
+ [existing_includes]
26
+ elsif existing_includes.nil?
27
+ []
28
+ else
29
+ existing_includes
30
+ end
31
+
32
+ assocs_as_hash = assoc_list_to_hash(new_assocs)
33
+ build_includes_int(existing_includes, assocs_as_hash)
34
+ end
35
+
36
+ if new_includes.is_a?(Array) && new_includes.size == 1
37
+ new_includes[0]
38
+ else
39
+ new_includes
40
+ end
41
+ end
42
+
43
+ def build_includes_int(includes, assocs) #:nodoc:
44
+ if includes.is_a?(Array)
45
+ build_includes_includes_is_array(includes, assocs)
46
+ elsif includes.is_a?(Hash)
47
+ build_includes_includes_is_hash(includes, assocs)
48
+ end
49
+ end
50
+
51
+ # TODO: refactor
52
+ def build_includes_includes_is_hash(includes, assocs) #:nodoc:
53
+
54
+ includes_key = includes.keys[0]
55
+ includes_value = includes.values[0]
56
+
57
+ if assocs.is_a?(Hash)
58
+ assocs_key = assocs.keys[0]
59
+ assocs_value = assocs.values[0]
60
+
61
+ if includes_value.is_a?(Symbol) && includes_value == assocs_key
62
+ {includes_key => assocs}
63
+ elsif includes_value.is_a?(Hash)
64
+ if includes_value.keys[0] == assocs_key
65
+ if includes_value.values[0] == assocs_value
66
+ {includes_key => assocs}
67
+ else
68
+ {includes_key => [includes_value.values[0], assocs_value]}
69
+ end
70
+ end
71
+ end
72
+ elsif includes_value == assocs
73
+ {includes_key => assocs}
74
+ else
75
+ includes
76
+ end
77
+ end
78
+
79
+ def build_includes_includes_is_array(includes, assocs) #:nodoc:
80
+
81
+ hash_keys = Hash[
82
+ *(
83
+ includes
84
+ .each_with_index
85
+ .to_a
86
+ .select{ |e, _idx| e.is_a?(Hash)}
87
+ .map{ |hash, idx| [ hash.keys[0], idx ] }
88
+ .flatten
89
+ )
90
+ ]
91
+
92
+ key_to_search, finished = if assocs.is_a?(Hash)
93
+ [assocs.keys[0], false]
94
+ else
95
+ [assocs, true]
96
+ end
97
+
98
+ if idx = includes.index(key_to_search)
99
+ if finished # [:a, :b, :c] vs :a
100
+ includes
101
+ else # [:a, :b, :c] vs {:a => x}
102
+ includes[idx] = assocs
103
+ includes
104
+ end
105
+
106
+ elsif hash_keys.key?(key_to_search)
107
+ if finished # [{a: :x}, :b, :c, :d, :e] vs :a
108
+ includes
109
+ else
110
+ hash_idx = hash_keys[key_to_search]
111
+ assocs_value = assocs[key_to_search]
112
+ includes[hash_idx] = build_includes_int(includes[hash_idx], assocs_value)
113
+ includes
114
+ end
115
+
116
+ else # [:a, :b, :c] vs :x
117
+ # [:a, :b, :c] vs {:x => y}
118
+ includes + [assocs]
119
+ end
120
+
121
+ end
122
+
123
+ # checks whether the class is a valid storage for saved queries
124
+ def validate_query_model(query_store_model) #:nodoc:
125
+ unless query_store_model.respond_to?(:list)
126
+ raise ::Wice::WiceGridArgumentError.new("Model for saving queries #{query_store_model.class.name} is invalid - there is no class method #list defined")
127
+ end
128
+ arit = query_store_model.method(:list).arity
129
+ unless arit == 2
130
+ raise ::Wice::WiceGridArgumentError.new("Method list in the model for saving queries #{query_store_model.class.name} has wrong arity - it should be 2 instead of #{arit}")
131
+ end
132
+ @@model_validated = true
133
+ end
134
+
135
+ # Retrieves and constantizes (if needed ) the Query Store model
136
+ def get_query_store_model #:nodoc:
137
+ query_store_model = Wice::ConfigurationProvider.value_for(:QUERY_STORE_MODEL)
138
+ query_store_model = query_store_model.constantize if query_store_model.is_a? String
139
+ raise ::Wice::WiceGridArgumentError.new('Defaults::QUERY_STORE_MODEL must be an ActiveRecord class or a string which can be constantized to an ActiveRecord class') unless query_store_model.is_a? Class
140
+ validate_query_model(query_store_model) unless @@model_validated
141
+ query_store_model
142
+ end
143
+
144
+ def get_string_matching_operators(model) #:nodoc:
145
+ if defined?(Wice::Defaults::STRING_MATCHING_OPERATORS) && (ops = Wice::ConfigurationProvider.value_for(:STRING_MATCHING_OPERATORS)) &&
146
+ ops.is_a?(Hash) && (str_matching_operator = ops[model.connection.class.to_s])
147
+ str_matching_operator
148
+ else
149
+ Wice::ConfigurationProvider.value_for(:STRING_MATCHING_OPERATOR)
150
+ end
151
+ end
152
+
153
+ def deprecated_call(old_name, new_name, opts) #:nodoc:
154
+ if opts[old_name] && !opts[new_name]
155
+ opts[new_name] = opts[old_name]
156
+ opts.delete(old_name)
157
+ STDERR.puts "WiceGrid: Parameter :#{old_name} is deprecated, use :#{new_name} instead!"
158
+ end
159
+ end
160
+
161
+ def log(message) #:nodoc:
162
+ ActiveRecord::Base.logger.info('WiceGrid: ' + message) if ActiveRecord::Base.logger
163
+ end
164
+ end
165
+
166
+ module NlMessage #:nodoc:
167
+ class << self
168
+ def [](key) #:nodoc:
169
+ I18n.t(key, scope: 'wice_grid')
170
+ end
171
+ end
172
+ end
173
+
174
+ module ConfigurationProvider #:nodoc:
175
+ class << self
176
+ def value_for(key, strict: true) #:nodoc:
177
+ if Wice::Defaults.const_defined?(key)
178
+ Wice::Defaults.const_get(key)
179
+ else
180
+ if strict
181
+ raise WiceGridMissingConfigurationConstantException.new("Could not find constant #{key} in the configuration file!" \
182
+ ' It is possible that the version of WiceGrid you are using is newer than the installed configuration file in config/initializers. ' \
183
+ "Constant Wice::Defaults::#{key} is missing and you need to add it manually to wice_grid_config.rb or run the generator task=:\n" \
184
+ ' rails g wice_grid:install')
185
+ end # else nil
186
+ end
187
+ end
188
+ end
189
+ end
190
+
191
+ module Defaults #:nodoc:
192
+ end
193
+
194
+ module ExceptionsMixin #:nodoc:
195
+ def initialize(str) #:nodoc:
196
+ super('WiceGrid: ' + str)
197
+ end
198
+ end
199
+ class WiceGridArgumentError < ArgumentError #:nodoc:
200
+ include ExceptionsMixin
201
+ end
202
+ class WiceGridException < Exception #:nodoc:
203
+ include ExceptionsMixin
204
+ end
205
+ class WiceGridMissingConfigurationConstantException < Exception #:nodoc:
206
+ include ExceptionsMixin
207
+ end
208
+ end