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,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