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,86 @@
1
+ module Wice
2
+ class <<self
3
+ # Used in routes.rb to define routes to the query processing controller.
4
+ # Parameters:
5
+ # * map - the context of the routes execution (instance of <tt>ActionDispatch::Routing::Mapper</tt>).
6
+ # Normally use +self+ for the first argument: <tt>Wice::define_routes(self, 'queries')</tt>
7
+ # * controller - name of the query processing controller, i.e. <tt>'queries'</tt> if the controller is +QueriesController+ .
8
+ # Read section "Saving Queries How-To" in README for more details.
9
+ def define_routes(map, controller)
10
+ controller = controller.to_s
11
+
12
+ map.post '/wice_grid_serialized_queries/:grid_name',
13
+ to: "#{controller}#create_saved_query",
14
+ as: 'create_serialized_query'
15
+
16
+ map.post '/wice_grid_serialized_queries/:grid_name/:id',
17
+ to: "#{controller}#delete_saved_query",
18
+ as: 'delete_serialized_query'
19
+ end
20
+ end
21
+
22
+ module SerializedQueriesControllerMixin #:nodoc:
23
+ def delete_saved_query #:nodoc:
24
+ init
25
+ if sq = @query_store_model.find_by_id_and_grid_name(params[:id], @grid_name)
26
+ if sq.destroy
27
+ if params[:current]
28
+ @current = @query_store_model.find_by_id_and_grid_name(params[:current], @grid_name)
29
+ end
30
+ @notification_messages = NlMessage['query_deleted_message']
31
+ else
32
+ @error_messages = sq.errors.full_raw_messages.join(' ')
33
+ end
34
+ end
35
+
36
+ render_asyns_result
37
+ end
38
+
39
+ def create_saved_query #:nodoc:
40
+ init
41
+ query_params = if params[@grid_name]
42
+ params[@grid_name]
43
+ else
44
+ {}
45
+ end
46
+ query_params.delete(:page)
47
+
48
+ @saved_query = @query_store_model.new
49
+
50
+ @saved_query.grid_name = @grid_name
51
+ @saved_query.name = params[:query_name]
52
+ @saved_query.query = query_params
53
+
54
+ @saved_query.attributes = extra unless extra.nil?
55
+
56
+ if @saved_query.save
57
+ @grid_title_id = "#{@grid_name}_title"
58
+ @notification_messages = NlMessage['query_saved_message']
59
+ else
60
+ @error_messages = @saved_query.errors.map { |_, msg| msg }.join(' ')
61
+ end
62
+
63
+ render_asyns_result
64
+ end
65
+
66
+ def extra #:nodoc:
67
+ params[:extra].permit! unless params[:extra].nil?
68
+ end
69
+
70
+ protected
71
+
72
+ def render_asyns_result #:nodoc:
73
+ render json: {
74
+ 'error_messages' => @error_messages,
75
+ 'notification_messages' => @notification_messages,
76
+ 'query_list' => render_to_string(inline: '<%=saved_queries_list(@grid_name, @saved_query, controller.extra, @confirm).html_safe%>')
77
+ }
78
+ end
79
+
80
+ def init #:nodoc:
81
+ @query_store_model = ::Wice.get_query_store_model
82
+ @confirm = params[:confirm] == '1' || params[:confirm] == 'true'
83
+ @grid_name = params[:grid_name]
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,13 @@
1
+ class WiceGridSerializedQuery < ActiveRecord::Base #:nodoc:
2
+ serialize :query
3
+
4
+ validates_uniqueness_of :name, scope: :grid_name, on: :create, message: 'A query with this name already exists'
5
+
6
+ validates_presence_of :name, message: 'Please submit the name of the custom query'
7
+
8
+ # returns a list of all serialized queries
9
+ def self.list(name, _controller)
10
+ conditions = { grid_name: name }
11
+ self.where(conditions).to_a
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ require 'csv'
2
+
3
+ module Wice
4
+ class Spreadsheet #:nodoc:
5
+
6
+ #:nodoc:
7
+ attr_reader :tempfile
8
+
9
+ def initialize(name, field_separator, encoding = nil) #:nodoc:
10
+ @tempfile = Tempfile.new(name)
11
+ @tempfile.set_encoding(encoding) unless encoding.blank?
12
+ @csv = CSV.new(@tempfile, col_sep: field_separator)
13
+ end
14
+
15
+ def << (row) #:nodoc:
16
+ @csv << row
17
+ end
18
+ end
19
+ end
data/lib/wice_grid.rb ADDED
@@ -0,0 +1,702 @@
1
+ require 'wice/wice_grid_misc.rb'
2
+ require 'wice/wice_grid_core_ext.rb'
3
+ require 'wice/grid_renderer.rb'
4
+ require 'wice/table_column_matrix.rb'
5
+ require 'wice/active_record_column_wrapper.rb'
6
+ require 'wice/helpers/wice_grid_view_helpers.rb'
7
+ require 'wice/helpers/wice_grid_misc_view_helpers.rb'
8
+ require 'wice/helpers/wice_grid_serialized_queries_view_helpers.rb'
9
+ require 'wice/helpers/wice_grid_view_helpers.rb'
10
+ require 'wice/helpers/bs_calendar_helpers.rb'
11
+ require 'wice/helpers/js_calendar_helpers.rb'
12
+ require 'wice/grid_output_buffer.rb'
13
+ require 'wice/wice_grid_controller.rb'
14
+ require 'wice/wice_grid_spreadsheet.rb'
15
+ require 'wice/wice_grid_serialized_queries_controller.rb'
16
+ require 'wice/columns/column_processor_index.rb'
17
+ require 'wice/columns.rb'
18
+ require 'wice/columns/common_date_datetime_mixin.rb'
19
+ require 'wice/columns/common_standard_helper_date_datetime_mixin.rb'
20
+ require 'wice/columns/common_js_date_datetime_mixin.rb'
21
+ require 'wice/columns/common_js_date_datetime_conditions_generator_mixin.rb'
22
+ require 'wice/columns/common_rails_date_datetime_conditions_generator_mixin.rb'
23
+ require 'kaminari.rb'
24
+
25
+
26
+ ActionController::Base.send(:helper_method, :wice_grid_custom_filter_params)
27
+
28
+ module Wice
29
+
30
+ def self.on_action_view_load #:nodoc:
31
+ ::ActionView::Base.class_eval { include Wice::GridViewHelper }
32
+ [ActionView::Helpers::AssetTagHelper,
33
+ ActionView::Helpers::TagHelper,
34
+ ActionView::Helpers::JavaScriptHelper,
35
+ ActionView::Helpers::FormTagHelper].each do |m|
36
+ JsCalendarHelpers.send(:include, m)
37
+ end
38
+
39
+ Columns.load_column_processors
40
+ require 'wice/wice_grid_serialized_query.rb'
41
+
42
+ # It is here only because of this: https://github.com/amatsuda/kaminari/pull/267
43
+ require 'wice/kaminari_monkey_patching.rb'
44
+
45
+ end
46
+
47
+ class WiceGridEngine < ::Rails::Engine #:nodoc:
48
+ initializer 'wice_grid_railtie.configure_rails_initialization' do |_app|
49
+ ActiveSupport.on_load :action_controller do
50
+ ActionController::Base.send(:include, Wice::Controller)
51
+ end
52
+
53
+ ActiveSupport.on_load :active_record do
54
+ ActiveRecord::ConnectionAdapters::Column.send(:include, ::Wice::WiceGridExtentionToActiveRecordColumn)
55
+ end
56
+
57
+ ActiveSupport.on_load :action_view do
58
+ ::Wice.on_action_view_load
59
+ end
60
+ end
61
+
62
+ initializer 'wice_grid_railtie.configure_rails_assets_precompilation' do |app|
63
+ app.config.assets.precompile << 'icons/grid/*'
64
+ end
65
+ end
66
+
67
+
68
+ # Main class responsible for keeping the state of the grid, building an ActiveRelation, and running queries
69
+ class WiceGrid
70
+ attr_reader :klass, :name, :resultset, :custom_order, :query_store_model #:nodoc:
71
+ attr_reader :ar_options, :status, :export_to_csv_enabled, :csv_file_name, :csv_field_separator, :csv_encoding, :saved_query #:nodoc:
72
+ attr_writer :renderer #:nodoc:
73
+ attr_accessor :output_buffer, :view_helper_finished, :csv_tempfile #:nodoc:
74
+
75
+ # core workflow methods START
76
+
77
+ def initialize(klass_or_relation, controller, opts = {}) #:nodoc:
78
+ @controller = controller
79
+
80
+ @relation = klass_or_relation
81
+ @klass = if @relation.is_a?(Class) && @relation.ancestors.index(ActiveRecord::Base)
82
+ klass_or_relation
83
+ else
84
+ klass_or_relation.klass
85
+ end
86
+
87
+ unless @klass.is_a?(Class) && @klass.ancestors.index(ActiveRecord::Base)
88
+ raise WiceGridArgumentError.new('ActiveRecord model class (second argument) must be a Class derived from ActiveRecord::Base')
89
+ end
90
+
91
+ # validate :with_resultset & :with_paginated_resultset
92
+ [:with_resultset, :with_paginated_resultset].each do |callback_symbol|
93
+ unless [NilClass, Symbol, Proc].index(opts[callback_symbol].class)
94
+ raise WiceGridArgumentError.new(":#{callback_symbol} must be either a Proc or Symbol object")
95
+ end
96
+ end
97
+
98
+ opts[:order_direction] = opts[:order_direction].downcase if opts[:order_direction].is_a?(String)
99
+
100
+ # validate :order_direction
101
+ if opts[:order_direction] && ! (opts[:order_direction] == 'asc' || opts[:order_direction] == :asc || opts[:order_direction] == 'desc' ||
102
+ opts[:order_direction] == :desc)
103
+ raise WiceGridArgumentError.new(":order_direction must be either 'asc' or 'desc'.")
104
+ end
105
+
106
+ begin
107
+ # options that are understood
108
+ @options = {
109
+ conditions: nil,
110
+ csv_file_name: nil,
111
+ csv_field_separator: ConfigurationProvider.value_for(:CSV_FIELD_SEPARATOR),
112
+ csv_encoding: ConfigurationProvider.value_for(:CSV_ENCODING),
113
+ custom_order: {},
114
+ enable_export_to_csv: ConfigurationProvider.value_for(:ENABLE_EXPORT_TO_CSV),
115
+ group: nil,
116
+ include: nil,
117
+ joins: nil,
118
+ name: ConfigurationProvider.value_for(:GRID_NAME),
119
+ order: nil,
120
+ order_direction: ConfigurationProvider.value_for(:ORDER_DIRECTION),
121
+ page: 1,
122
+ page_method_name: ConfigurationProvider.value_for(:PAGE_METHOD_NAME),
123
+ per_page: ConfigurationProvider.value_for(:PER_PAGE),
124
+ saved_query: nil,
125
+ with_paginated_resultset: nil,
126
+ with_resultset: nil,
127
+ use_default_scope: ConfigurationProvider.value_for(:USE_DEFAULT_SCOPE)
128
+ }
129
+ rescue NameError
130
+ raise NameError.new('A constant is missing in wice_grid_config.rb: ' + $ERROR_INFO.message +
131
+ '. This can happen when you upgrade the WiceGrid to a newer version with a new configuration constant. ' \
132
+ 'Add the constant manually or re-run `bundle exec rails g wice_grid:install`.')
133
+ end
134
+ # validate parameters
135
+ opts.assert_valid_keys(@options.keys)
136
+
137
+ @options.merge!(opts)
138
+ @export_to_csv_enabled = @options[:enable_export_to_csv]
139
+ @csv_file_name = @options[:csv_file_name]
140
+ @csv_field_separator = @options[:csv_field_separator]
141
+ @csv_encoding = @options[:csv_encoding]
142
+
143
+ case @name = @options[:name]
144
+ when String
145
+ when Symbol
146
+ @name = @name.to_s
147
+ else
148
+ raise WiceGridArgumentError.new('name of the grid should be a string or a symbol')
149
+ end
150
+ raise WiceGridArgumentError.new('name of the grid can only contain alphanumeruc characters') unless @name =~ /^[a-zA-Z\d_]*$/
151
+
152
+ @table_column_matrix = TableColumnMatrix.new
153
+ @table_column_matrix.default_model_class = @klass
154
+
155
+ @ar_options = {}
156
+ @status = HashWithIndifferentAccess.new
157
+
158
+ if @options[:order]
159
+ @options[:order] = @options[:order].to_s
160
+ @options[:order_direction] = @options[:order_direction].to_s
161
+
162
+ @status[:order_direction] = @options[:order_direction]
163
+ @status[:order] = @options[:order]
164
+
165
+ end
166
+ @status[:per_page] = @options[:per_page]
167
+ @status[:page] = @options[:page]
168
+ @status[:conditions] = @options[:conditions]
169
+ @status[:f] = @options[:f]
170
+
171
+ process_loading_query
172
+ process_params
173
+
174
+ @ar_options_formed = false
175
+ end
176
+
177
+ # A block executed from within the plugin to process records of the current page.
178
+ # The argument to the callback is the array of the records. See the README for more details.
179
+ def with_paginated_resultset(&callback)
180
+ @options[:with_paginated_resultset] = callback
181
+ end
182
+
183
+ # A block executed from within the plugin to process all records browsable through
184
+ # all pages with the current filters. The argument to
185
+ # the callback is a lambda object which returns the list of records when called. See the README for the explanation.
186
+ def with_resultset(&callback)
187
+ @options[:with_resultset] = callback
188
+ end
189
+
190
+ def process_loading_query #:nodoc:
191
+ @saved_query = nil
192
+ if params[name] && params[name][:q]
193
+ @saved_query = load_query(params[name][:q])
194
+ params[name].delete(:q)
195
+ elsif @options[:saved_query]
196
+ if @options[:saved_query].is_a? ActiveRecord::Base
197
+ @saved_query = @options[:saved_query]
198
+ else
199
+ @saved_query = load_query(@options[:saved_query])
200
+ end
201
+ else
202
+ return
203
+ end
204
+
205
+ unless @saved_query.nil?
206
+ params[name] = HashWithIndifferentAccess.new if params[name].blank?
207
+ [:f, :order, :order_direction].each do |key|
208
+ if @saved_query.query[key].blank?
209
+ params[name].delete(key)
210
+ else
211
+ params[name][key] = @saved_query.query[key]
212
+ end
213
+ end
214
+ end
215
+ end
216
+
217
+ def process_params #:nodoc:
218
+ if this_grid_params
219
+ @status.merge!(this_grid_params)
220
+ @status.delete(:export) unless self.export_to_csv_enabled
221
+ end
222
+ end
223
+
224
+ # declare_column(String, ActiveRecord, CustomFilterSpec, nil | string, nil | Boolean)
225
+ def declare_column(
226
+ column_name: nil,
227
+ model: nil,
228
+ custom_filter_active: nil,
229
+ table_alias: nil,
230
+ filter_type: nil,
231
+ assocs: [],
232
+ sort_by: nil) #:nodoc:
233
+
234
+
235
+ @options[:include] = Wice.build_includes(@options[:include], assocs)
236
+
237
+ if model # this is an included table
238
+ column = @table_column_matrix.get_column_by_model_class_and_column_name(model, column_name)
239
+ raise WiceGridArgumentError.new("Column '#{column_name}' is not found in table '#{model.table_name}'!") if column.nil?
240
+ main_table = false
241
+ table_name = model.table_name
242
+ else
243
+ column = @table_column_matrix.get_column_in_default_model_class_by_column_name(column_name)
244
+ # Allow the column to not exist if we're doing a custom sort (calculated field)
245
+ if column.nil? && !sort_by
246
+ raise WiceGridArgumentError.new("Column '#{column_name}' is not found in table '#{@klass.table_name}'! " \
247
+ "If '#{column_name}' belongs to another table you should declare it in :include or :join when initialising " \
248
+ 'the grid, and specify :model in column declaration.')
249
+ end
250
+ main_table = true
251
+ table_name = @table_column_matrix.default_model_class.table_name
252
+ end
253
+
254
+ if column
255
+ conditions_generator = ActiveRecordColumnWrapper.new(column, @status[:f], main_table, table_alias, custom_filter_active, filter_type)
256
+ conditions, current_parameter_name = conditions_generator.wg_initialize_request_parameters
257
+
258
+ if @status[:f] && conditions.blank?
259
+ @status[:f].delete(current_parameter_name)
260
+ end
261
+
262
+ @table_column_matrix.add_condition(column, conditions)
263
+
264
+ # [ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter::Column, String, Boolean]
265
+ [column, table_name, main_table]
266
+ end
267
+ end
268
+
269
+ def form_ar_options(opts = {}) #:nodoc:
270
+ return if @ar_options_formed
271
+ @ar_options_formed = true unless opts[:forget_generated_options]
272
+
273
+ # validate @status[:order_direction]
274
+ @status[:order_direction] = case @status[:order_direction]
275
+ when /desc/i
276
+ 'desc'
277
+ when /asc/i
278
+ 'asc'
279
+ else
280
+ ''
281
+ end
282
+
283
+ # conditions
284
+ # do not delete for a while
285
+ # https://github.com/leikind/wice_grid/issues/144
286
+ # if @table_column_matrix.generated_conditions.size == 0
287
+ # @status.delete(:f)
288
+ # end
289
+
290
+ initial_conditions_active_relation = @klass.where(@status[:conditions])
291
+
292
+ @ar_options[:conditions] =
293
+ @table_column_matrix.conditions.reduce(initial_conditions_active_relation) do |active_relation_accu, cond|
294
+ conditions_active_relation = @klass.where(cond)
295
+ active_relation_accu.merge(conditions_active_relation)
296
+ end
297
+
298
+ # conditions processed
299
+
300
+ if (!opts[:skip_ordering]) && ! @status[:order].blank?
301
+ custom_order = get_custom_order_reference
302
+ if custom_order
303
+ @ar_options[:order] = custom_order
304
+ else
305
+ @ar_options[:order] = arel_column_reference(@status[:order])
306
+ end
307
+ if @ar_options[:order].is_a?(Arel::Attributes::Attribute) || @ar_options[:order].is_a?(Arel::Nodes::SqlLiteral)
308
+ if @status[:order_direction] == 'desc'
309
+ @ar_options[:order] = @ar_options[:order].desc
310
+ else
311
+ @ar_options[:order] = @ar_options[:order].asc
312
+ end
313
+ else
314
+ @ar_options[:order] += " #{@status[:order_direction]}"
315
+ end
316
+ end
317
+
318
+ @ar_options[:joins] = @options[:joins]
319
+ @ar_options[:include] = @options[:include]
320
+ @ar_options[:group] = @options[:group]
321
+
322
+ if self.output_html?
323
+ @ar_options[:per_page] = @status[:per_page]
324
+ @ar_options[:page] = @status[:page]
325
+
326
+ if (show_all_limit = Wice::ConfigurationProvider.value_for(:SHOW_ALL_ALLOWED_UP_TO, strict: false)) && all_record_mode?
327
+ if do_count > show_all_limit # force-reset SHOW-ALL to pagination
328
+ @status[:pp] = nil
329
+ end
330
+ end
331
+
332
+ end
333
+ end
334
+
335
+ def add_references(relation) #:nodoc:
336
+ if @ar_options[:include] && relation.respond_to?(:references)
337
+ # refs = [@ar_options[:include]] unless @ar_options[:include].is_a?(Array)
338
+ relation = relation.references(* @ar_options[:include])
339
+ end
340
+ relation
341
+ end
342
+
343
+ # Apply the sort_by option to the results.
344
+ def apply_sort_by(relation)
345
+ active_sort_by = nil
346
+ @renderer.find_one_for(->(c) {c.attribute == @status[:order]}) {|r| active_sort_by = r.sort_by}
347
+ return relation if !active_sort_by
348
+ relation = relation.sort_by(&active_sort_by)
349
+ relation = relation.reverse if @status[:order_direction] == 'desc'
350
+ return relation
351
+ end
352
+
353
+ # TO DO: what to do with other @ar_options values?
354
+ def read #:nodoc:
355
+ form_ar_options
356
+ use_default_or_unscoped do
357
+ relation = @relation
358
+ .includes(@ar_options[:include])
359
+ .joins(@ar_options[:joins])
360
+ .merge(@ar_options[:conditions])
361
+ relation = relation.group(@ar_options[:group]) if @ar_options[:group].present?
362
+ relation = add_references relation
363
+ relation = apply_sort_by relation
364
+
365
+ # If relation is an Array, it got the sort from apply_sort_by.
366
+ relation = relation.order(@ar_options[:order]) if !relation.is_a?(Array)
367
+
368
+ if !output_csv? && !all_record_mode?
369
+ if relation.is_a?(Array)
370
+ relation = Kaminari.paginate_array(relation, limit: @ar_options[:per_page], offset: @ar_options[:per_page].to_i * (@ar_options[:page].to_i - 1))
371
+ else
372
+ relation = relation
373
+ .send(@options[:page_method_name], @ar_options[:page])
374
+ .per(@ar_options[:per_page])
375
+ end
376
+ end
377
+
378
+ if all_record_mode? && relation.is_a?(Array)
379
+ # This still needs to be a Kaminari object as the paginator will read limit_value.
380
+ relation = Kaminari.paginate_array(relation, limit: relation.count)
381
+ end
382
+
383
+ @resultset = relation
384
+ end
385
+
386
+ invoke_resultset_callbacks
387
+ end
388
+
389
+ # core workflow methods END
390
+
391
+ # Getters
392
+
393
+ def filter_params(view_column) #:nodoc:
394
+ column_name = view_column.attribute_name_fully_qualified_for_all_but_main_table_columns
395
+ if @status[:f] && @status[:f][column_name]
396
+ @status[:f][column_name]
397
+ else
398
+ {}
399
+ end
400
+ end
401
+
402
+ def resultset #:nodoc:
403
+ self.read unless @resultset # database querying is late!
404
+ @resultset
405
+ end
406
+
407
+ def each #:nodoc:
408
+ self.read unless @resultset # database querying is late!
409
+ @resultset.each do |r|
410
+ yield r
411
+ end
412
+ end
413
+
414
+ # Returns true if the current results are ordered by the passed column.
415
+ def ordered_by?(column)
416
+ return nil if @status[:order].blank?
417
+ if column.main_table && ! @status[:order].index('.') || column.table_alias_or_table_name.nil?
418
+ @status[:order] == column.attribute
419
+ else
420
+ @status[:order] == column.table_alias_or_table_name + '.' + column.attribute
421
+ end
422
+ end
423
+
424
+ def ordered_by #:nodoc:
425
+ @status[:order]
426
+ end
427
+
428
+ def order_direction #:nodoc:
429
+ @status[:order_direction]
430
+ end
431
+
432
+ def filtering_on? #:nodoc:
433
+ !@status[:f].blank?
434
+ end
435
+
436
+ def filtered_by #:nodoc:
437
+ @status[:f].nil? ? [] : @status[:f].keys
438
+ end
439
+
440
+ def filtered_by?(view_column) #:nodoc:
441
+ @status[:f].nil? ? false : @status[:f].key?(view_column.attribute_name_fully_qualified_for_all_but_main_table_columns)
442
+ end
443
+
444
+ def get_state_as_parameter_value_pairs(including_saved_query_request = false) #:nodoc:
445
+ res = []
446
+ unless status[:f].blank?
447
+ Wice::WgHash.parameter_names_and_values(status[:f], [name, 'f']).collect do |param_name, value|
448
+ if value.is_a?(Array)
449
+ param_name_ar = param_name + '[]'
450
+ value.each do |v|
451
+ res << [param_name_ar, v]
452
+ end
453
+ else
454
+ res << [param_name, value]
455
+ end
456
+ end
457
+ end
458
+
459
+ if including_saved_query_request && @saved_query
460
+ res << ["#{name}[q]", @saved_query.id]
461
+ end
462
+
463
+ [:order, :order_direction].select do|parameter|
464
+ status[parameter]
465
+ end.collect do |parameter|
466
+ res << ["#{name}[#{parameter}]", status[parameter]]
467
+ end
468
+
469
+ res
470
+ end
471
+
472
+ def count #:nodoc:
473
+ form_ar_options(skip_ordering: true, forget_generated_options: true)
474
+ do_count
475
+ end
476
+
477
+ def do_count #:nodoc:
478
+ @relation
479
+ .all
480
+ .joins(@ar_options[:joins])
481
+ .includes(@ar_options[:include])
482
+ .group(@ar_options[:group])
483
+ .where(@options[:conditions])
484
+ .count
485
+ end
486
+
487
+ alias_method :size, :count
488
+
489
+ def empty? #:nodoc:
490
+ self.count == 0
491
+ end
492
+
493
+ # with this variant we get even those values which do not appear in the resultset
494
+ def distinct_values_for_column(column) #:nodoc:
495
+ column.model.select("distinct #{column.name}").order("#{column.name} asc").collect do|ar|
496
+ ar[column.name]
497
+ end.reject(&:blank?).map { |i| [i, i] }
498
+ end
499
+
500
+ def distinct_values_for_column_in_resultset(messages) #:nodoc:
501
+ uniq_vals = Set.new
502
+
503
+ resultset_without_paging_without_user_filters.each do |ar|
504
+ v = ar.deep_send(*messages)
505
+ uniq_vals << v unless v.nil?
506
+ end
507
+ uniq_vals.to_a.map do|i|
508
+ if i.is_a?(Array) && i.size == 2
509
+ i
510
+ elsif i.is_a?(Hash) && i.size == 1
511
+ i.to_a.flatten
512
+ else
513
+ [i, i]
514
+ end
515
+ end.sort { |a, b| a[0] <=> b[0] }
516
+ end
517
+
518
+ def output_csv? #:nodoc:
519
+ @status[:export] == 'csv'
520
+ end
521
+
522
+ def output_html? #:nodoc:
523
+ @status[:export].blank?
524
+ end
525
+
526
+ def all_record_mode? #:nodoc:
527
+ @status[:pp]
528
+ end
529
+
530
+ def dump_status #:nodoc:
531
+ " params: #{params[name].inspect}\n" + " status: #{@status.inspect}\n" \
532
+ " ar_options #{@ar_options.inspect}\n"
533
+ end
534
+
535
+ # Returns the list of objects browsable through all pages with the current filters.
536
+ # Should only be called after the +grid+ helper.
537
+ def all_pages_records
538
+ raise WiceGridException.new('all_pages_records can only be called only after the grid view helper') unless self.view_helper_finished
539
+ resultset_without_paging_with_user_filters
540
+ end
541
+
542
+ # Returns the list of objects displayed on current page. Should only be called after the +grid+ helper.
543
+ def current_page_records
544
+ raise WiceGridException.new('current_page_records can only be called only after the grid view helper') unless self.view_helper_finished
545
+ @resultset
546
+ end
547
+
548
+ protected
549
+
550
+ def invoke_resultset_callback(callback, argument) #:nodoc:
551
+ case callback
552
+ when Proc
553
+ callback.call(argument)
554
+ when Symbol
555
+ @controller.send(callback, argument)
556
+ end
557
+ end
558
+
559
+ def invoke_resultset_callbacks #:nodoc:
560
+ invoke_resultset_callback(@options[:with_paginated_resultset], @resultset)
561
+ invoke_resultset_callback(@options[:with_resultset], self.active_relation_for_resultset_without_paging_with_user_filters)
562
+ end
563
+
564
+ # If a custom order has been configured, gets the column/function to be ordered by. If no custom order, returns nil.
565
+ def get_custom_order_reference
566
+ # TODO Do we need to distinguish between no custom order and a custom order that defines no ordering? Both return nil.
567
+
568
+ fully_qualified_column_name = complete_column_name(@status[:order])
569
+ custom_order = if @options[:custom_order].key?(fully_qualified_column_name)
570
+ @options[:custom_order][fully_qualified_column_name]
571
+ else
572
+ if view_column = @renderer[fully_qualified_column_name]
573
+ view_column.custom_order
574
+ end
575
+ end
576
+
577
+ return custom_order if custom_order.nil? || custom_order.is_a?(Arel::Attributes::Attribute)
578
+ return custom_order.gsub(/\?/, fully_qualified_column_name) if custom_order.is_a?(String)
579
+ return custom_order.call(fully_qualified_column_name) if custom_order.is_a?(Proc)
580
+ raise WiceGridArgumentError.new("invalid custom order #{custom_order.inspect}")
581
+ end
582
+
583
+ # Returns an Arel::Attributes::Attribute for the passed column reference.
584
+ def arel_column_reference(col_name) #:nodoc:
585
+ if col_name.index('.') # already has a table name
586
+ table_name, col_name = col_name.split('.', 2)
587
+ Arel::Table.new(table_name)[col_name]
588
+ else # add the default table
589
+ @klass.arel_table[col_name]
590
+ end
591
+ end
592
+
593
+ # Returns tablename.columnname for the passed column reference.
594
+ def complete_column_name(col_name)
595
+ return col_name if col_name.index('.') # already has a table name
596
+ return "#{@klass.table_name}.#{col_name}"
597
+ end
598
+
599
+ def params #:nodoc:
600
+ @controller.params
601
+ end
602
+
603
+ def this_grid_params #:nodoc:
604
+ params[name].try(:to_unsafe_h) || params[name]
605
+ end
606
+
607
+ def resultset_without_paging_without_user_filters #:nodoc:
608
+ form_ar_options
609
+
610
+ use_default_or_unscoped do
611
+ relation = @relation.joins(@ar_options[:joins])
612
+ .includes(@ar_options[:include])
613
+ .group(@ar_options[:group])
614
+ .where(@options[:conditions])
615
+
616
+ relation = add_references relation
617
+
618
+ relation
619
+ end
620
+ end
621
+
622
+ # not used right now
623
+ # def count_resultset_without_paging_without_user_filters #:nodoc:
624
+ # form_ar_options
625
+ # @klass.unscoped do
626
+ # @relation.count(
627
+ # joins: @ar_options[:joins],
628
+ # include: @ar_options[:include],
629
+ # group: @ar_options[:group],
630
+ # conditions: @options[:conditions]
631
+ # )
632
+ # end
633
+ # end
634
+
635
+ def resultset_without_paging_with_user_filters #:nodoc:
636
+ active_relation_for_resultset_without_paging_with_user_filters.to_a
637
+ end
638
+
639
+ def active_relation_for_resultset_without_paging_with_user_filters #:nodoc:
640
+ form_ar_options
641
+ relation = nil
642
+
643
+ use_default_or_unscoped do
644
+ relation = @relation
645
+ .joins(@ar_options[:joins])
646
+ .includes(@ar_options[:include])
647
+ .order(@ar_options[:order])
648
+ .merge(@ar_options[:conditions])
649
+
650
+ relation = add_references relation
651
+ end
652
+ relation
653
+ end
654
+
655
+ def load_query(query_id) #:nodoc:
656
+ @query_store_model ||= Wice.get_query_store_model
657
+ query = @query_store_model.find_by_id_and_grid_name(query_id, self.name)
658
+ Wice.log("Query with id #{query_id} for grid '#{self.name}' not found!!!") if query.nil?
659
+ query
660
+ end
661
+
662
+ def use_default_or_unscoped #:nodoc:
663
+ if @options[:use_default_scope]
664
+ yield
665
+ else
666
+ @klass.unscoped { yield }
667
+ end
668
+ end
669
+
670
+ end
671
+
672
+ # routines called from WiceGridExtentionToActiveRecordColumn (ActiveRecord::ConnectionAdapters::Column) or ConditionsGeneratorColumn classes
673
+ module GridTools #:nodoc:
674
+ class << self
675
+ def special_value(str) #:nodoc:
676
+ str =~ /^\s*(not\s+)?null\s*$/i
677
+ end
678
+
679
+ # create a Time instance out of parameters
680
+ def params_2_datetime(par) #:nodoc:
681
+ return nil if par.blank?
682
+ params = [par[:year], par[:month], par[:day], par[:hour], par[:minute]].collect { |v| v.blank? ? nil : v.to_i }
683
+ begin
684
+ Time.local(*params)
685
+ rescue ArgumentError, TypeError
686
+ nil
687
+ end
688
+ end
689
+
690
+ # create a Date instance out of parameters
691
+ def params_2_date(par) #:nodoc:
692
+ return nil if par.blank?
693
+ params = [par[:year], par[:month], par[:day]].collect { |v| v.blank? ? nil : v.to_i }
694
+ begin
695
+ Date.civil(*params)
696
+ rescue ArgumentError, TypeError
697
+ nil
698
+ end
699
+ end
700
+ end
701
+ end
702
+ end