pwice_grid 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
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