pwice_grid 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +68 -0
- data/.circleci/run-build-locally.sh +7 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +32 -0
- data/.gitignore +22 -0
- data/.inch.yml +3 -0
- data/.rspec +3 -0
- data/.rubocop.yml +186 -0
- data/Appraisals +11 -0
- data/CHANGELOG.md +758 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +298 -0
- data/MIT-LICENSE +20 -0
- data/README.md +1561 -0
- data/Rakefile +49 -0
- data/SAVED_QUERIES_HOWTO.md +113 -0
- data/app/views/kaminari/wice_grid/_gap.html.erb +1 -0
- data/app/views/kaminari/wice_grid/_next_page.html.erb +1 -0
- data/app/views/kaminari/wice_grid/_page.html.erb +1 -0
- data/app/views/kaminari/wice_grid/_paginator.html.erb +19 -0
- data/app/views/kaminari/wice_grid/_prev_page.html.erb +1 -0
- data/config/locales/cz.yml +40 -0
- data/config/locales/de.yml +42 -0
- data/config/locales/en.yml +42 -0
- data/config/locales/es.yml +42 -0
- data/config/locales/fr.yml +40 -0
- data/config/locales/is.yml +41 -0
- data/config/locales/it.yml +33 -0
- data/config/locales/ja.yml +42 -0
- data/config/locales/nl.yml +40 -0
- data/config/locales/pt-BR.yml +31 -0
- data/config/locales/pt.yml +40 -0
- data/config/locales/ru.yml +40 -0
- data/config/locales/sk.yml +40 -0
- data/config/locales/uk.yml +40 -0
- data/config/locales/zh.yml +40 -0
- data/gemfiles/rails_5.0.gemfile +7 -0
- data/gemfiles/rails_5.0.gemfile.lock +299 -0
- data/gemfiles/rails_5.1.gemfile +7 -0
- data/gemfiles/rails_5.1.gemfile.lock +299 -0
- data/gemfiles/rails_5.2.gemfile +7 -0
- data/gemfiles/rails_5.2.gemfile.lock +307 -0
- data/lib/generators/wice_grid/add_migration_for_serialized_queries_generator.rb +19 -0
- data/lib/generators/wice_grid/install_generator.rb +13 -0
- data/lib/generators/wice_grid/templates/create_wice_grid_serialized_queries.rb +13 -0
- data/lib/generators/wice_grid/templates/wice_grid_config.rb +191 -0
- data/lib/wice/active_record_column_wrapper.rb +122 -0
- data/lib/wice/columns.rb +282 -0
- data/lib/wice/columns/column_action.rb +51 -0
- data/lib/wice/columns/column_boolean.rb +39 -0
- data/lib/wice/columns/column_bootstrap_datepicker.rb +47 -0
- data/lib/wice/columns/column_custom_dropdown.rb +114 -0
- data/lib/wice/columns/column_float.rb +8 -0
- data/lib/wice/columns/column_html5_datepicker.rb +30 -0
- data/lib/wice/columns/column_integer.rb +87 -0
- data/lib/wice/columns/column_jquery_datepicker.rb +48 -0
- data/lib/wice/columns/column_processor_index.rb +22 -0
- data/lib/wice/columns/column_rails_date_helper.rb +40 -0
- data/lib/wice/columns/column_rails_datetime_helper.rb +40 -0
- data/lib/wice/columns/column_range.rb +73 -0
- data/lib/wice/columns/column_string.rb +91 -0
- data/lib/wice/columns/common_date_datetime_mixin.rb +19 -0
- data/lib/wice/columns/common_js_date_datetime_conditions_generator_mixin.rb +38 -0
- data/lib/wice/columns/common_js_date_datetime_mixin.rb +14 -0
- data/lib/wice/columns/common_rails_date_datetime_conditions_generator_mixin.rb +25 -0
- data/lib/wice/columns/common_standard_helper_date_datetime_mixin.rb +21 -0
- data/lib/wice/grid_output_buffer.rb +48 -0
- data/lib/wice/grid_renderer.rb +624 -0
- data/lib/wice/helpers/bs_calendar_helpers.rb +73 -0
- data/lib/wice/helpers/js_calendar_helpers.rb +82 -0
- data/lib/wice/helpers/wice_grid_misc_view_helpers.rb +74 -0
- data/lib/wice/helpers/wice_grid_serialized_queries_view_helpers.rb +94 -0
- data/lib/wice/helpers/wice_grid_view_helpers.rb +719 -0
- data/lib/wice/kaminari_monkey_patching.rb +12 -0
- data/lib/wice/table_column_matrix.rb +64 -0
- data/lib/wice/wice_grid_controller.rb +174 -0
- data/lib/wice/wice_grid_core_ext.rb +145 -0
- data/lib/wice/wice_grid_misc.rb +208 -0
- data/lib/wice/wice_grid_serialized_queries_controller.rb +86 -0
- data/lib/wice/wice_grid_serialized_query.rb +13 -0
- data/lib/wice/wice_grid_spreadsheet.rb +19 -0
- data/lib/wice_grid.rb +702 -0
- data/spec/acceptance_helper.rb +59 -0
- data/spec/features/action_column_request_spec.rb +280 -0
- data/spec/features/adding_rows_request_spec.rb +21 -0
- data/spec/features/all_records_request_spec.rb +18 -0
- data/spec/features/auto_reloads2_request_spec.rb +366 -0
- data/spec/features/auto_reloads3_request_spec.rb +130 -0
- data/spec/features/auto_reloads_request_spec.rb +364 -0
- data/spec/features/basics1_request_spec.rb +11 -0
- data/spec/features/basics2_request_spec.rb +10 -0
- data/spec/features/basics3_request_spec.rb +29 -0
- data/spec/features/basics4_request_spec.rb +19 -0
- data/spec/features/basics5_request_spec.rb +13 -0
- data/spec/features/basics6_request_spec.rb +22 -0
- data/spec/features/blockless_column_definition_spec.rb +27 -0
- data/spec/features/buttons_request_spec.rb +172 -0
- data/spec/features/csv_and_detached_filters_spec.rb +10 -0
- data/spec/features/csv_export_request_spec.rb +13 -0
- data/spec/features/custom_filter_params_request_spec.rb +29 -0
- data/spec/features/custom_filters1_request_spec.rb +136 -0
- data/spec/features/custom_filters2_request_spec.rb +31 -0
- data/spec/features/custom_filters3_request_spec.rb +34 -0
- data/spec/features/custom_filters4_request_spec.rb +13 -0
- data/spec/features/custom_ordering_on_calculated_request_spec.rb +30 -0
- data/spec/features/custom_ordering_request_spec.rb +36 -0
- data/spec/features/custom_ordering_with_arel_request_spec.rb +36 -0
- data/spec/features/custom_ordering_with_proc_request_spec.rb +44 -0
- data/spec/features/custom_ordering_with_ruby_request_spec.rb +30 -0
- data/spec/features/dates_request_spec.rb +56 -0
- data/spec/features/detached_filters_spec.rb +10 -0
- data/spec/features/detached_filters_two_grids_spec.rb +135 -0
- data/spec/features/disable_all_filters_spec.rb +22 -0
- data/spec/features/hiding_checkboxes_in_action_column_request_spec.rb +294 -0
- data/spec/features/integration_with_application_view_request_spec.rb +43 -0
- data/spec/features/integration_with_forms_request_spec.rb +141 -0
- data/spec/features/joining_tables_spec.rb +40 -0
- data/spec/features/localization_request_spec.rb +24 -0
- data/spec/features/many_grids_on_page_request_spec.rb +104 -0
- data/spec/features/negation_request_spec.rb +25 -0
- data/spec/features/no_records_request_spec.rb +26 -0
- data/spec/features/numeric_filters_request_spec.rb +10 -0
- data/spec/features/resultset_processings2_request_spec.rb +27 -0
- data/spec/features/resultset_processings_request_spec.rb +30 -0
- data/spec/features/saved_queries_request_spec.rb +120 -0
- data/spec/features/shared.rb +1005 -0
- data/spec/features/shared_detached_filters.rb +175 -0
- data/spec/features/styling_spec.rb +15 -0
- data/spec/features/two_associations_spec.rb +48 -0
- data/spec/features/upper_pagination_panel_request_spec.rb +23 -0
- data/spec/features/when_filtered_spec.rb +209 -0
- data/spec/fixtures/.gitkeep +0 -0
- data/spec/fixtures/companies.yml +21 -0
- data/spec/fixtures/priorities.yml +31 -0
- data/spec/fixtures/project_roles.yml +25 -0
- data/spec/fixtures/projects.yml +22 -0
- data/spec/fixtures/statuses.yml +55 -0
- data/spec/fixtures/tasks.yml +751 -0
- data/spec/fixtures/tasks_users.yml +2089 -0
- data/spec/fixtures/users.yml +61 -0
- data/spec/fixtures/versions.yml +78 -0
- data/spec/models/company_spec.rb +6 -0
- data/spec/models/priority_spec.rb +6 -0
- data/spec/models/project_spec.rb +11 -0
- data/spec/models/status_spec.rb +6 -0
- data/spec/models/task_spec.rb +12 -0
- data/spec/models/user_project_participation_spec.rb +7 -0
- data/spec/models/user_spec.rb +12 -0
- data/spec/models/version_spec.rb +5 -0
- data/spec/rails_helper.rb +15 -0
- data/spec/schema.rb +8 -0
- data/spec/spec_helper.rb +75 -0
- data/spec/support/active_record.rb +10 -0
- data/spec/support/test_app/Rakefile +3 -0
- data/spec/support/test_app/app/assets/javascripts/application.js +20 -0
- data/spec/support/test_app/app/assets/javascripts/common.js.coffee +6 -0
- data/spec/support/test_app/app/assets/javascripts/jquery.ui.datepicker.locales.js +56 -0
- data/spec/support/test_app/app/assets/stylesheets/adding_rows.scss +3 -0
- data/spec/support/test_app/app/assets/stylesheets/application.scss +46 -0
- data/spec/support/test_app/app/assets/stylesheets/csv_and_detached_filters.scss +3 -0
- data/spec/support/test_app/app/assets/stylesheets/many_grids_on_page.scss +3 -0
- data/spec/support/test_app/app/controllers/action_column_controller.rb +15 -0
- data/spec/support/test_app/app/controllers/adding_rows_controller.rb +14 -0
- data/spec/support/test_app/app/controllers/all_records_controller.rb +14 -0
- data/spec/support/test_app/app/controllers/application_controller.rb +99 -0
- data/spec/support/test_app/app/controllers/auto_reloads2_controller.rb +14 -0
- data/spec/support/test_app/app/controllers/auto_reloads3_controller.rb +20 -0
- data/spec/support/test_app/app/controllers/auto_reloads_controller.rb +14 -0
- data/spec/support/test_app/app/controllers/basics1_controller.rb +6 -0
- data/spec/support/test_app/app/controllers/basics2_controller.rb +6 -0
- data/spec/support/test_app/app/controllers/basics3_controller.rb +6 -0
- data/spec/support/test_app/app/controllers/basics4_controller.rb +6 -0
- data/spec/support/test_app/app/controllers/basics5_controller.rb +6 -0
- data/spec/support/test_app/app/controllers/basics6_controller.rb +11 -0
- data/spec/support/test_app/app/controllers/blockless_column_definition_controller.rb +6 -0
- data/spec/support/test_app/app/controllers/buttons_controller.rb +6 -0
- data/spec/support/test_app/app/controllers/csv_and_detached_filters_controller.rb +13 -0
- data/spec/support/test_app/app/controllers/csv_export_controller.rb +28 -0
- data/spec/support/test_app/app/controllers/custom_filter_params_controller.rb +6 -0
- data/spec/support/test_app/app/controllers/custom_filters1_controller.rb +9 -0
- data/spec/support/test_app/app/controllers/custom_filters2_controller.rb +14 -0
- data/spec/support/test_app/app/controllers/custom_filters3_controller.rb +12 -0
- data/spec/support/test_app/app/controllers/custom_filters4_controller.rb +12 -0
- data/spec/support/test_app/app/controllers/custom_ordering_controller.rb +18 -0
- data/spec/support/test_app/app/controllers/custom_ordering_on_calculated_controller.rb +6 -0
- data/spec/support/test_app/app/controllers/custom_ordering_with_arel_controller.rb +18 -0
- data/spec/support/test_app/app/controllers/custom_ordering_with_proc_controller.rb +11 -0
- data/spec/support/test_app/app/controllers/custom_ordering_with_ruby_controller.rb +6 -0
- data/spec/support/test_app/app/controllers/dates_controller.rb +8 -0
- data/spec/support/test_app/app/controllers/detached_filters_controller.rb +6 -0
- data/spec/support/test_app/app/controllers/detached_filters_two_grids_controller.rb +7 -0
- data/spec/support/test_app/app/controllers/disable_all_filters_controller.rb +6 -0
- data/spec/support/test_app/app/controllers/hiding_checkboxes_in_action_column_controller.rb +13 -0
- data/spec/support/test_app/app/controllers/home_controller.rb +3 -0
- data/spec/support/test_app/app/controllers/integration_with_application_view_controller.rb +16 -0
- data/spec/support/test_app/app/controllers/integration_with_forms_controller.rb +11 -0
- data/spec/support/test_app/app/controllers/joining_tables_controller.rb +11 -0
- data/spec/support/test_app/app/controllers/localization_controller.rb +26 -0
- data/spec/support/test_app/app/controllers/many_grids_on_page_controller.rb +7 -0
- data/spec/support/test_app/app/controllers/negation_controller.rb +14 -0
- data/spec/support/test_app/app/controllers/no_records_controller.rb +8 -0
- data/spec/support/test_app/app/controllers/null_values_controller.rb +10 -0
- data/spec/support/test_app/app/controllers/numeric_filters_controller.rb +6 -0
- data/spec/support/test_app/app/controllers/queries_controller.rb +4 -0
- data/spec/support/test_app/app/controllers/resultset_processings2_controller.rb +29 -0
- data/spec/support/test_app/app/controllers/resultset_processings_controller.rb +30 -0
- data/spec/support/test_app/app/controllers/saved_queries_controller.rb +14 -0
- data/spec/support/test_app/app/controllers/styling_controller.rb +7 -0
- data/spec/support/test_app/app/controllers/tasks_controller.rb +14 -0
- data/spec/support/test_app/app/controllers/two_associations_controller.rb +6 -0
- data/spec/support/test_app/app/controllers/upper_pagination_panel_controller.rb +6 -0
- data/spec/support/test_app/app/controllers/when_filtered_controller.rb +6 -0
- data/spec/support/test_app/app/helpers/application_helper.rb +82 -0
- data/spec/support/test_app/app/mailers/.gitkeep +0 -0
- data/spec/support/test_app/app/models/.gitkeep +0 -0
- data/spec/support/test_app/app/models/company.rb +5 -0
- data/spec/support/test_app/app/models/populate.rb +84 -0
- data/spec/support/test_app/app/models/priority.rb +10 -0
- data/spec/support/test_app/app/models/project.rb +14 -0
- data/spec/support/test_app/app/models/project_role.rb +3 -0
- data/spec/support/test_app/app/models/status.rb +10 -0
- data/spec/support/test_app/app/models/task.rb +11 -0
- data/spec/support/test_app/app/models/to_dropdown_mixin.rb +16 -0
- data/spec/support/test_app/app/models/user.rb +8 -0
- data/spec/support/test_app/app/models/user_project_participation.rb +6 -0
- data/spec/support/test_app/app/models/version.rb +6 -0
- data/spec/support/test_app/app/views/action_column/_grid.html.erb +35 -0
- data/spec/support/test_app/app/views/action_column/index.html.haml +45 -0
- data/spec/support/test_app/app/views/adding_rows/_grid.html.erb +58 -0
- data/spec/support/test_app/app/views/adding_rows/index.html.haml +37 -0
- data/spec/support/test_app/app/views/all_records/_grid.html.erb +30 -0
- data/spec/support/test_app/app/views/all_records/index.html.haml +12 -0
- data/spec/support/test_app/app/views/auto_reloads/_grid.html.erb +32 -0
- data/spec/support/test_app/app/views/auto_reloads/index.html.haml +15 -0
- data/spec/support/test_app/app/views/auto_reloads2/_grid.html.erb +32 -0
- data/spec/support/test_app/app/views/auto_reloads2/index.html.haml +65 -0
- data/spec/support/test_app/app/views/auto_reloads3/_grid.html.erb +25 -0
- data/spec/support/test_app/app/views/auto_reloads3/index.html.haml +78 -0
- data/spec/support/test_app/app/views/basics1/_grid.html.erb +26 -0
- data/spec/support/test_app/app/views/basics1/index.html.haml +13 -0
- data/spec/support/test_app/app/views/basics2/_grid.html.erb +27 -0
- data/spec/support/test_app/app/views/basics2/index.html.haml +12 -0
- data/spec/support/test_app/app/views/basics3/_grid.html.erb +28 -0
- data/spec/support/test_app/app/views/basics3/index.html.haml +13 -0
- data/spec/support/test_app/app/views/basics4/_grid.html.erb +21 -0
- data/spec/support/test_app/app/views/basics4/index.html.haml +12 -0
- data/spec/support/test_app/app/views/basics5/_grid.html.erb +19 -0
- data/spec/support/test_app/app/views/basics5/index.html.haml +12 -0
- data/spec/support/test_app/app/views/basics6/_grid.html.erb +19 -0
- data/spec/support/test_app/app/views/basics6/index.html.haml +23 -0
- data/spec/support/test_app/app/views/blockless_column_definition/_grid.html.erb +19 -0
- data/spec/support/test_app/app/views/blockless_column_definition/index.html.haml +15 -0
- data/spec/support/test_app/app/views/buttons/_grid.html.erb +20 -0
- data/spec/support/test_app/app/views/buttons/index.html.haml +30 -0
- data/spec/support/test_app/app/views/csv_and_detached_filters/_grid.html.erb +23 -0
- data/spec/support/test_app/app/views/csv_and_detached_filters/index.html.haml +58 -0
- data/spec/support/test_app/app/views/csv_export/_projects_grid.html.erb +17 -0
- data/spec/support/test_app/app/views/csv_export/_tasks_grid.html.erb +43 -0
- data/spec/support/test_app/app/views/csv_export/index.html.haml +90 -0
- data/spec/support/test_app/app/views/custom_filter_params/_grid.html.erb +12 -0
- data/spec/support/test_app/app/views/custom_filter_params/index.html.haml +12 -0
- data/spec/support/test_app/app/views/custom_filters1/_g1.html.erb +8 -0
- data/spec/support/test_app/app/views/custom_filters1/_g2.html.erb +9 -0
- data/spec/support/test_app/app/views/custom_filters1/_g3.html.erb +9 -0
- data/spec/support/test_app/app/views/custom_filters1/_g4.html.erb +8 -0
- data/spec/support/test_app/app/views/custom_filters1/index.html.haml +30 -0
- data/spec/support/test_app/app/views/custom_filters2/_grid.html.erb +30 -0
- data/spec/support/test_app/app/views/custom_filters2/index.html.haml +41 -0
- data/spec/support/test_app/app/views/custom_filters3/_grid.html.erb +18 -0
- data/spec/support/test_app/app/views/custom_filters3/index.html.haml +16 -0
- data/spec/support/test_app/app/views/custom_filters4/_grid.html.erb +20 -0
- data/spec/support/test_app/app/views/custom_filters4/index.html.haml +12 -0
- data/spec/support/test_app/app/views/custom_ordering/_grid.html.erb +10 -0
- data/spec/support/test_app/app/views/custom_ordering/index.html.haml +24 -0
- data/spec/support/test_app/app/views/custom_ordering_on_calculated/_grid.html.erb +14 -0
- data/spec/support/test_app/app/views/custom_ordering_on_calculated/index.html.haml +23 -0
- data/spec/support/test_app/app/views/custom_ordering_with_arel/_grid.html.erb +10 -0
- data/spec/support/test_app/app/views/custom_ordering_with_arel/index.html.haml +24 -0
- data/spec/support/test_app/app/views/custom_ordering_with_proc/_grid.html.erb +10 -0
- data/spec/support/test_app/app/views/custom_ordering_with_proc/index.html.haml +21 -0
- data/spec/support/test_app/app/views/custom_ordering_with_ruby/_grid.html.erb +10 -0
- data/spec/support/test_app/app/views/custom_ordering_with_ruby/index.html.haml +23 -0
- data/spec/support/test_app/app/views/dates/_grid.html.erb +25 -0
- data/spec/support/test_app/app/views/dates/index.html.haml +52 -0
- data/spec/support/test_app/app/views/detached_filters/_grid.html.erb +23 -0
- data/spec/support/test_app/app/views/detached_filters/index.html.haml +79 -0
- data/spec/support/test_app/app/views/detached_filters_two_grids/_grid.html.erb +23 -0
- data/spec/support/test_app/app/views/detached_filters_two_grids/index.html.haml +85 -0
- data/spec/support/test_app/app/views/disable_all_filters/_grid.html.erb +21 -0
- data/spec/support/test_app/app/views/disable_all_filters/index.html.haml +14 -0
- data/spec/support/test_app/app/views/hiding_checkboxes_in_action_column/_grid.html.erb +34 -0
- data/spec/support/test_app/app/views/hiding_checkboxes_in_action_column/index.html.haml +32 -0
- data/spec/support/test_app/app/views/integration_with_application_view/_grid.html.erb +27 -0
- data/spec/support/test_app/app/views/integration_with_application_view/index.html.haml +33 -0
- data/spec/support/test_app/app/views/integration_with_forms/_grid.html.erb +23 -0
- data/spec/support/test_app/app/views/integration_with_forms/index.html.haml +18 -0
- data/spec/support/test_app/app/views/joining_tables/_grid.html.erb +23 -0
- data/spec/support/test_app/app/views/joining_tables/index.html.haml +26 -0
- data/spec/support/test_app/app/views/layouts/application.html.haml +61 -0
- data/spec/support/test_app/app/views/localization/_grid.html.erb +36 -0
- data/spec/support/test_app/app/views/localization/index.html.haml +20 -0
- data/spec/support/test_app/app/views/many_grids_on_page/_tasks_grid1.html.erb +12 -0
- data/spec/support/test_app/app/views/many_grids_on_page/_tasks_grid2.html.erb +12 -0
- data/spec/support/test_app/app/views/many_grids_on_page/index.html.haml +26 -0
- data/spec/support/test_app/app/views/negation/_grid.html.erb +30 -0
- data/spec/support/test_app/app/views/negation/index.html.haml +15 -0
- data/spec/support/test_app/app/views/no_records/_empty_grid.html.haml +1 -0
- data/spec/support/test_app/app/views/no_records/_grid1.html.erb +11 -0
- data/spec/support/test_app/app/views/no_records/_grid2.html.erb +9 -0
- data/spec/support/test_app/app/views/no_records/_grid3.html.erb +9 -0
- data/spec/support/test_app/app/views/no_records/index.html.haml +24 -0
- data/spec/support/test_app/app/views/null_values/_grid.html.erb +17 -0
- data/spec/support/test_app/app/views/null_values/index.html.haml +21 -0
- data/spec/support/test_app/app/views/numeric_filters/_grid.html.erb +19 -0
- data/spec/support/test_app/app/views/numeric_filters/index.html.haml +12 -0
- data/spec/support/test_app/app/views/resultset_processings/_grid.html.erb +27 -0
- data/spec/support/test_app/app/views/resultset_processings/index.html.haml +50 -0
- data/spec/support/test_app/app/views/resultset_processings2/_grid.html.erb +27 -0
- data/spec/support/test_app/app/views/resultset_processings2/index.html.haml +48 -0
- data/spec/support/test_app/app/views/saved_queries/_grid.html.erb +30 -0
- data/spec/support/test_app/app/views/saved_queries/index.html.haml +15 -0
- data/spec/support/test_app/app/views/styling/_grid1.html.erb +12 -0
- data/spec/support/test_app/app/views/styling/_grid2.html.erb +31 -0
- data/spec/support/test_app/app/views/styling/index.html.haml +65 -0
- data/spec/support/test_app/app/views/tasks/_grid.html.erb +19 -0
- data/spec/support/test_app/app/views/tasks/index.html.haml +1 -0
- data/spec/support/test_app/app/views/two_associations/_grid.html.erb +13 -0
- data/spec/support/test_app/app/views/two_associations/index.html.haml +13 -0
- data/spec/support/test_app/app/views/upper_pagination_panel/_grid.html.erb +27 -0
- data/spec/support/test_app/app/views/upper_pagination_panel/index.html.haml +14 -0
- data/spec/support/test_app/app/views/when_filtered/_grid.html.erb +19 -0
- data/spec/support/test_app/app/views/when_filtered/index.html.haml +15 -0
- data/spec/support/test_app/bin/rails +4 -0
- data/spec/support/test_app/bin/rake +4 -0
- data/spec/support/test_app/config.ru +5 -0
- data/spec/support/test_app/config/application.rb +70 -0
- data/spec/support/test_app/config/boot.rb +7 -0
- data/spec/support/test_app/config/database.travis.yml +27 -0
- data/spec/support/test_app/config/database.yml +16 -0
- data/spec/support/test_app/config/database.yml.mysql +19 -0
- data/spec/support/test_app/config/database.yml.postgresql +18 -0
- data/spec/support/test_app/config/environment.rb +6 -0
- data/spec/support/test_app/config/environments/development.rb +34 -0
- data/spec/support/test_app/config/environments/production.rb +66 -0
- data/spec/support/test_app/config/environments/test.rb +34 -0
- data/spec/support/test_app/config/initializers/backtrace_silencers.rb +8 -0
- data/spec/support/test_app/config/initializers/inflections.rb +16 -0
- data/spec/support/test_app/config/initializers/mime_types.rb +6 -0
- data/spec/support/test_app/config/initializers/secret_token.rb +12 -0
- data/spec/support/test_app/config/initializers/session_store.rb +9 -0
- data/spec/support/test_app/config/initializers/wice_grid_config.rb +163 -0
- data/spec/support/test_app/config/initializers/wrap_parameters.rb +15 -0
- data/spec/support/test_app/config/locales/en.yml +5 -0
- data/spec/support/test_app/config/locales/wice_grid.yml +550 -0
- data/spec/support/test_app/config/puma.rb +15 -0
- data/spec/support/test_app/config/routes.rb +125 -0
- data/spec/support/test_app/db/migrate/20120224193505_create_tasks.rb +27 -0
- data/spec/support/test_app/db/migrate/20120224193517_create_users.rb +12 -0
- data/spec/support/test_app/db/migrate/20120224193522_create_projects.rb +14 -0
- data/spec/support/test_app/db/migrate/20120224193529_create_priorities.rb +13 -0
- data/spec/support/test_app/db/migrate/20120224193537_create_statuses.rb +13 -0
- data/spec/support/test_app/db/migrate/20120224193543_create_versions.rb +15 -0
- data/spec/support/test_app/db/migrate/20120224193550_create_project_roles.rb +12 -0
- data/spec/support/test_app/db/migrate/20120224193610_create_companies.rb +12 -0
- data/spec/support/test_app/db/migrate/20120224195351_create_user_project_participations.rb +16 -0
- data/spec/support/test_app/db/migrate/20120224195521_add_tasks_users.rb +11 -0
- data/spec/support/test_app/db/migrate/20120610091944_create_wice_grid_serialized_queries.rb +14 -0
- data/spec/support/test_app/db/schema.rb +139 -0
- data/spec/support/test_app/db/seeds.rb +10 -0
- data/spec/support/test_app/lib/ar_fixtures.rb +100 -0
- data/spec/support/test_app/lib/assets/.gitkeep +0 -0
- data/spec/support/test_app/lib/tasks/.gitkeep +0 -0
- data/spec/support/test_app/lib/tasks/ar_fixtures.rake +45 -0
- data/spec/support/test_app/public/404.html +26 -0
- data/spec/support/test_app/public/422.html +26 -0
- data/spec/support/test_app/public/500.html +25 -0
- data/spec/support/test_app/public/favicon.ico +0 -0
- data/spec/support/test_app/public/robots.txt +5 -0
- data/spec/wice/grid_output_buffer_spec.rb +39 -0
- data/spec/wice/table_column_matrix_spec.rb +36 -0
- data/spec/wice/wice_grid_misc_spec.rb +157 -0
- data/spec/wice/wice_grid_spreadsheet_spec.rb +12 -0
- data/vendor/assets/javascripts/wice_grid.js +3 -0
- data/vendor/assets/javascripts/wice_grid_init.js.coffee +351 -0
- data/vendor/assets/javascripts/wice_grid_processor.js.coffee +133 -0
- data/vendor/assets/javascripts/wice_grid_saved_queries_init.js.coffee +104 -0
- data/vendor/assets/stylesheets/wice_grid.scss +81 -0
- data/wice_grid.gemspec +54 -0
- metadata +861 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
module Wice
|
2
|
+
module Columns #:nodoc:
|
3
|
+
class ViewColumnRailsDateHelper < ViewColumn #:nodoc:
|
4
|
+
|
5
|
+
include ActionView::Helpers::DateHelper
|
6
|
+
include Wice::Columns::CommonDateDatetimeMixin
|
7
|
+
include Wice::Columns::CommonStandardDateDatetimeMixin
|
8
|
+
|
9
|
+
def chunk_names #:nodoc:
|
10
|
+
%w(year month day)
|
11
|
+
end
|
12
|
+
|
13
|
+
def do_render(params) #:nodoc:
|
14
|
+
'<div class="date-filter">' +
|
15
|
+
select_date(params[:fr], include_blank: true, prefix: @name1, id: @dom_id) + '<br/>' +
|
16
|
+
select_date(params[:to], include_blank: true, prefix: @name2, id: @dom_id2) +
|
17
|
+
'</div>'
|
18
|
+
end
|
19
|
+
|
20
|
+
# name_and_id_from_options in Rails Date helper does not substitute '.' with '_'
|
21
|
+
# like all other simpler form helpers do. Thus, overriding it here.
|
22
|
+
def name_and_id_from_options(options, type) #:nodoc:
|
23
|
+
options[:name] = (options[:prefix] || DEFAULT_PREFIX) + (options[:discard_type] ? '' : "[#{type}]")
|
24
|
+
options[:id] = options[:name].gsub(/([\[\(])|(\]\[)/, '_').gsub(/[\]\)]/, '').gsub(/\./, '_').gsub(/_+/, '_')
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def has_auto_reloading_calendar? #:nodoc:
|
29
|
+
false
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
class ConditionsGeneratorColumnRailsDateHelper < ConditionsGeneratorColumn #:nodoc:
|
35
|
+
|
36
|
+
include Wice::Columns::CommonRailsDateDatetimeConditionsGeneratorMixin
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Wice
|
2
|
+
module Columns #:nodoc:
|
3
|
+
class ViewColumnRailsDatetimeHelper < ViewColumn #:nodoc:
|
4
|
+
|
5
|
+
include ActionView::Helpers::DateHelper
|
6
|
+
include Wice::Columns::CommonDateDatetimeMixin
|
7
|
+
include Wice::Columns::CommonStandardDateDatetimeMixin
|
8
|
+
|
9
|
+
def chunk_names #:nodoc:
|
10
|
+
%w(year month day hour minute)
|
11
|
+
end
|
12
|
+
|
13
|
+
def do_render(params) #:nodoc:
|
14
|
+
datetime_options = filter_control_options ? filter_control_options.slice(:start_year, :end_year, :max_year_allowed) : {}
|
15
|
+
'<div class="date-filter">' +
|
16
|
+
select_datetime(params[:fr], datetime_options.merge(include_blank: true, prefix: @name1)) + '<br/>' +
|
17
|
+
select_datetime(params[:to], datetime_options.merge(include_blank: true, prefix: @name2)) +
|
18
|
+
'</div>'
|
19
|
+
end
|
20
|
+
|
21
|
+
# name_and_id_from_options in Rails Date helper does not substitute '.' with '_'
|
22
|
+
# like all other simpler form helpers do. Thus, overriding it here.
|
23
|
+
def name_and_id_from_options(options, type) #:nodoc:
|
24
|
+
options[:name] = (options[:prefix] || DEFAULT_PREFIX) + (options[:discard_type] ? '' : "[#{type}]")
|
25
|
+
options[:id] = options[:name].gsub(/([\[\(])|(\]\[)/, '_').gsub(/[\]\)]/, '').gsub(/\./, '_').gsub(/_+/, '_')
|
26
|
+
end
|
27
|
+
|
28
|
+
def has_auto_reloading_calendar? #:nodoc:
|
29
|
+
false
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
class ConditionsGeneratorColumnRailsDatetimeHelper < ConditionsGeneratorColumn #:nodoc:
|
35
|
+
|
36
|
+
include Wice::Columns::CommonRailsDateDatetimeConditionsGeneratorMixin
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Wice
|
2
|
+
module Columns #:nodoc:
|
3
|
+
class ViewColumnRange < ViewColumn #:nodoc:
|
4
|
+
def render_filter_internal(params) #:nodoc:
|
5
|
+
@contains_a_text_input = true
|
6
|
+
|
7
|
+
@query, _, parameter_name, @dom_id = form_parameter_name_id_and_query(fr: '')
|
8
|
+
@query2, _, parameter_name2, @dom_id2 = form_parameter_name_id_and_query(to: '')
|
9
|
+
|
10
|
+
opts1 = { size: 2, id: @dom_id, class: 'form-control input-sm range-start' }
|
11
|
+
opts2 = { size: 2, id: @dom_id2, class: 'form-control input-sm range-end' }
|
12
|
+
|
13
|
+
if auto_reload
|
14
|
+
opts1[:class] += ' auto-reload'
|
15
|
+
opts2[:class] += ' auto-reload'
|
16
|
+
end
|
17
|
+
|
18
|
+
content_tag(
|
19
|
+
:div,
|
20
|
+
text_field_tag(parameter_name, params[:fr], opts1) + text_field_tag(parameter_name2, params[:to], opts2),
|
21
|
+
class: 'form-inline')
|
22
|
+
end
|
23
|
+
|
24
|
+
def yield_declaration_of_column_filter #:nodoc:
|
25
|
+
{
|
26
|
+
templates: [@query, @query2],
|
27
|
+
ids: [@dom_id, @dom_id2]
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def has_auto_reloading_input? #:nodoc:
|
32
|
+
auto_reload
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class ConditionsGeneratorColumnRange < ConditionsGeneratorColumn #:nodoc:
|
37
|
+
def generate_conditions(table_alias, opts) #:nodoc:
|
38
|
+
unless opts.is_a? Hash
|
39
|
+
Wice.log 'invalid parameters for the grid integer filter - must be a hash'
|
40
|
+
return false
|
41
|
+
end
|
42
|
+
conditions = [[]]
|
43
|
+
if opts[:fr]
|
44
|
+
fr_num = ConditionsGeneratorColumnInteger.get_value(opts[:fr])
|
45
|
+
if fr_num
|
46
|
+
conditions[0] << " #{@column_wrapper.alias_or_table_name(table_alias)}.#{@column_wrapper.name} >= ? "
|
47
|
+
conditions << fr_num
|
48
|
+
else
|
49
|
+
opts.delete(:fr)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
if opts[:to]
|
54
|
+
to_num = ConditionsGeneratorColumnInteger.get_value(opts[:to])
|
55
|
+
if to_num
|
56
|
+
conditions[0] << " #{@column_wrapper.alias_or_table_name(table_alias)}.#{@column_wrapper.name} <= ? "
|
57
|
+
conditions << to_num
|
58
|
+
else
|
59
|
+
opts.delete(:to)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
if conditions.size == 1
|
64
|
+
return false
|
65
|
+
end
|
66
|
+
|
67
|
+
conditions[0] = conditions[0].join(' and ')
|
68
|
+
|
69
|
+
conditions
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Wice
|
2
|
+
module Columns #:nodoc:
|
3
|
+
class ViewColumnString < ViewColumn #:nodoc:
|
4
|
+
|
5
|
+
# whether the filter contains a negation checkbox
|
6
|
+
attr_accessor :negation
|
7
|
+
|
8
|
+
# whether the filter contains a negation checkbox and autoreloading is necessary
|
9
|
+
attr_accessor :auto_reloading_input_with_negation_checkbox
|
10
|
+
|
11
|
+
def render_filter_internal(params) #:nodoc:
|
12
|
+
@contains_a_text_input = true
|
13
|
+
css_class = 'form-control input-sm ' + (auto_reload ? 'auto-reload' : '')
|
14
|
+
|
15
|
+
if negation
|
16
|
+
self.auto_reloading_input_with_negation_checkbox = true if auto_reload
|
17
|
+
|
18
|
+
@query, _, parameter_name, @dom_id = form_parameter_name_id_and_query(v: '')
|
19
|
+
@query2, _, parameter_name2, @dom_id2 = form_parameter_name_id_and_query(n: '')
|
20
|
+
|
21
|
+
'<div class="text-filter-container">' +
|
22
|
+
text_field_tag(parameter_name, params[:v], size: 8, id: @dom_id, class: css_class) +
|
23
|
+
if defined?(Wice::Defaults::NEGATION_CHECKBOX_LABEL) && !Wice::ConfigurationProvider.value_for(:NEGATION_CHECKBOX_LABEL).blank?
|
24
|
+
Wice::ConfigurationProvider.value_for(:NEGATION_CHECKBOX_LABEL)
|
25
|
+
else
|
26
|
+
''
|
27
|
+
end +
|
28
|
+
check_box_tag(parameter_name2, '1', (params[:n] == '1'),
|
29
|
+
id: @dom_id2,
|
30
|
+
title: NlMessage['negation_checkbox_title'],
|
31
|
+
class: "negation-checkbox #{css_class}") +
|
32
|
+
'</div>'
|
33
|
+
else
|
34
|
+
@query, _, parameter_name, @dom_id = form_parameter_name_id_and_query('')
|
35
|
+
text_field_tag(parameter_name, (params.blank? ? '' : params), size: 8, id: @dom_id, class: css_class)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def yield_declaration_of_column_filter #:nodoc:
|
40
|
+
if negation
|
41
|
+
{
|
42
|
+
templates: [@query, @query2],
|
43
|
+
ids: [@dom_id, @dom_id2]
|
44
|
+
}
|
45
|
+
else
|
46
|
+
{
|
47
|
+
templates: [@query],
|
48
|
+
ids: [@dom_id]
|
49
|
+
}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def has_auto_reloading_input? #:nodoc:
|
54
|
+
auto_reload
|
55
|
+
end
|
56
|
+
|
57
|
+
def auto_reloading_input_with_negation_checkbox? #:nodoc:
|
58
|
+
self.auto_reloading_input_with_negation_checkbox
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class ConditionsGeneratorColumnString < ConditionsGeneratorColumn #:nodoc:
|
63
|
+
def generate_conditions(table_alias, opts) #:nodoc:
|
64
|
+
if opts.is_a? String
|
65
|
+
string_fragment = opts
|
66
|
+
negation = ''
|
67
|
+
elsif (opts.is_a? Hash) && opts.key?(:v)
|
68
|
+
string_fragment = opts[:v]
|
69
|
+
negation = opts[:n] == '1' ? 'NOT' : ''
|
70
|
+
else
|
71
|
+
Wice.log "invalid parameters for the grid string filter - must be a string: #{opts.inspect} or a Hash with keys :v and :n"
|
72
|
+
return false
|
73
|
+
end
|
74
|
+
if string_fragment.empty?
|
75
|
+
return false
|
76
|
+
end
|
77
|
+
|
78
|
+
string_matching_operator = ::Wice.get_string_matching_operators(@column_wrapper.model)
|
79
|
+
|
80
|
+
comparator = if string_matching_operator == 'CI_LIKE'
|
81
|
+
" #{negation} UPPER(#{@column_wrapper.alias_or_table_name(table_alias)}.#{@column_wrapper.name}) LIKE UPPER(?)"
|
82
|
+
else
|
83
|
+
" #{negation} #{@column_wrapper.alias_or_table_name(table_alias)}.#{@column_wrapper.name} #{string_matching_operator} ?"
|
84
|
+
end
|
85
|
+
|
86
|
+
[ comparator, '%' + string_fragment + '%' ]
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Wice
|
2
|
+
module Columns #:nodoc:
|
3
|
+
module CommonDateDatetimeMixin #:nodoc:
|
4
|
+
|
5
|
+
def render_filter_internal(params) #:nodoc:
|
6
|
+
prepare
|
7
|
+
do_render(params)
|
8
|
+
end
|
9
|
+
|
10
|
+
def yield_declaration_of_column_filter #:nodoc:
|
11
|
+
{
|
12
|
+
templates: @queris_ids.collect { |tuple| tuple[0] },
|
13
|
+
ids: @queris_ids.collect { |tuple| tuple[1] }
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Wice
|
2
|
+
module Columns #:nodoc:
|
3
|
+
module CommonJsDateDatetimeConditionsGeneratorMixin #:nodoc:
|
4
|
+
|
5
|
+
def generate_conditions(table_alias, opts) #:nodoc:
|
6
|
+
|
7
|
+
datetime = @column_type == :datetime || @column_type == :timestamp
|
8
|
+
|
9
|
+
conditions = [[]]
|
10
|
+
if opts[:fr]
|
11
|
+
conditions[0] << " #{@column_wrapper.alias_or_table_name(table_alias)}.#{@column_wrapper.name} >= ? "
|
12
|
+
date = opts[:fr].to_date
|
13
|
+
if datetime
|
14
|
+
date = date.to_datetime
|
15
|
+
end
|
16
|
+
conditions << date
|
17
|
+
end
|
18
|
+
|
19
|
+
if opts[:to]
|
20
|
+
op = '<='
|
21
|
+
date = opts[:to].to_date
|
22
|
+
if datetime
|
23
|
+
date = (date + 1).to_datetime
|
24
|
+
op = '<'
|
25
|
+
end
|
26
|
+
conditions[0] << " #{@column_wrapper.alias_or_table_name(table_alias)}.#{@column_wrapper.name} #{op} ? "
|
27
|
+
conditions << date
|
28
|
+
end
|
29
|
+
|
30
|
+
return false if conditions.size == 1
|
31
|
+
|
32
|
+
conditions[0] = conditions[0].join(' and ')
|
33
|
+
conditions
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Wice
|
2
|
+
module Columns #:nodoc:
|
3
|
+
module CommonJsDateDatetimeMixin #:nodoc:
|
4
|
+
|
5
|
+
def prepare #:nodoc:
|
6
|
+
query, _, @name1, @dom_id = form_parameter_name_id_and_query(fr: '')
|
7
|
+
query2, _, @name2, @dom_id2 = form_parameter_name_id_and_query(to: '')
|
8
|
+
|
9
|
+
@queris_ids = [[query, @dom_id], [query2, @dom_id2]]
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Wice
|
2
|
+
module Columns #:nodoc:
|
3
|
+
module CommonRailsDateDatetimeConditionsGeneratorMixin #:nodoc:
|
4
|
+
|
5
|
+
def generate_conditions(table_alias, opts) #:nodoc:
|
6
|
+
conditions = [[]]
|
7
|
+
if opts[:fr]
|
8
|
+
conditions[0] << " #{@column_wrapper.alias_or_table_name(table_alias)}.#{@column_wrapper.name} >= ? "
|
9
|
+
conditions << opts[:fr].to_date
|
10
|
+
end
|
11
|
+
|
12
|
+
if opts[:to]
|
13
|
+
conditions[0] << " #{@column_wrapper.alias_or_table_name(table_alias)}.#{@column_wrapper.name} <= ? "
|
14
|
+
conditions << (opts[:to].to_date + 1)
|
15
|
+
end
|
16
|
+
|
17
|
+
return false if conditions.size == 1
|
18
|
+
|
19
|
+
conditions[0] = conditions[0].join(' and ')
|
20
|
+
conditions
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Wice
|
2
|
+
module Columns #:nodoc:
|
3
|
+
module CommonStandardDateDatetimeMixin #:nodoc:
|
4
|
+
|
5
|
+
def prepare #:nodoc:
|
6
|
+
x = lambda do|sym|
|
7
|
+
chunk_names.map do|datetime_chunk_name|
|
8
|
+
triple = form_parameter_name_id_and_query(sym => { datetime_chunk_name => '' })
|
9
|
+
[triple[0], triple[3]]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
@queris_ids = x.call(:fr) + x.call(:to)
|
14
|
+
|
15
|
+
_, _, @name1, _ = form_parameter_name_id_and_query(fr: '')
|
16
|
+
_, _, @name2, _ = form_parameter_name_id_and_query(to: '')
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Wice
|
2
|
+
class GridOutputBuffer < String #:nodoc:
|
3
|
+
|
4
|
+
# defines behavior for rendering nonexistent filters.
|
5
|
+
# If return_empty_strings_for_nonexistent_filters is true, a call to render a non existent filter will raise an exception
|
6
|
+
# If return_empty_strings_for_nonexistent_filters is false (CSV mode), no exception will be raised.
|
7
|
+
attr_accessor :return_empty_strings_for_nonexistent_filters
|
8
|
+
|
9
|
+
# initializes a grid output buffer
|
10
|
+
def initialize(*attrs)
|
11
|
+
super(*attrs)
|
12
|
+
@filters = HashWithIndifferentAccess.new
|
13
|
+
end
|
14
|
+
|
15
|
+
# returns HTML code the grid
|
16
|
+
def to_s
|
17
|
+
super.html_safe
|
18
|
+
end
|
19
|
+
|
20
|
+
# stores HTML code for a detached filter
|
21
|
+
def add_filter(detach_with_id, filter_code)
|
22
|
+
raise WiceGridException.new("Detached ID #{detach_with_id} is already used!") if @filters.key? detach_with_id
|
23
|
+
@filters[detach_with_id] = filter_code
|
24
|
+
end
|
25
|
+
|
26
|
+
# returns HTML code for a detached filter
|
27
|
+
def filter_for(detach_with_id)
|
28
|
+
unless @filters.key? detach_with_id
|
29
|
+
if @return_empty_strings_for_nonexistent_filters
|
30
|
+
return ''
|
31
|
+
else
|
32
|
+
raise WiceGridException.new("No filter with Detached ID '#{detach_with_id}'!")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
unless @filters[detach_with_id]
|
37
|
+
raise WiceGridException.new("Filter with Detached ID '#{detach_with_id}' has already been requested once! There cannot be two instances of the same filter on one page")
|
38
|
+
end
|
39
|
+
|
40
|
+
res = @filters[detach_with_id]
|
41
|
+
@filters[detach_with_id] = false
|
42
|
+
res
|
43
|
+
end
|
44
|
+
|
45
|
+
# returns HTML code for a detached filter
|
46
|
+
alias_method :[], :filter_for
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,624 @@
|
|
1
|
+
module Wice
|
2
|
+
|
3
|
+
# Instance of `GridRenderer` is injected into the top level block of the `grid` helper.
|
4
|
+
# `g.column`, `g.action_column` are all examples of methods of `GridRenderer`
|
5
|
+
class GridRenderer
|
6
|
+
include ActionView::Helpers::TagHelper
|
7
|
+
include ActionView::Helpers::CaptureHelper
|
8
|
+
include ActionView::Helpers::TextHelper
|
9
|
+
include ActionView::Helpers::AssetTagHelper
|
10
|
+
include ActionView::Helpers::JavaScriptHelper
|
11
|
+
|
12
|
+
# a Proc object for the after_row block
|
13
|
+
attr_reader :after_row_handler
|
14
|
+
|
15
|
+
# a Proc object for the before_row block
|
16
|
+
attr_reader :before_row_handler
|
17
|
+
|
18
|
+
# a Proc object for the replace_row block
|
19
|
+
attr_reader :replace_row_handler
|
20
|
+
|
21
|
+
# Configuration or a Proc object for the blank_slate block
|
22
|
+
attr_reader :blank_slate_handler
|
23
|
+
|
24
|
+
# a Proc object which returns contents of the last row
|
25
|
+
attr_reader :last_row_handler
|
26
|
+
|
27
|
+
# reference to the WiceGrid instance
|
28
|
+
attr_reader :grid
|
29
|
+
|
30
|
+
# Contents of <caption></caption>
|
31
|
+
attr_reader :kaption
|
32
|
+
|
33
|
+
# HTTP parameter for the order field
|
34
|
+
ORDER_PARAMETER_NAME = 'order'
|
35
|
+
|
36
|
+
# HTTP parameter for the order direction (asc/desc)
|
37
|
+
ORDER_DIRECTION_PARAMETER_NAME = 'order_direction'
|
38
|
+
|
39
|
+
def initialize(grid, view) #:nodoc:
|
40
|
+
@grid = grid
|
41
|
+
@grid.renderer = self
|
42
|
+
@columns = []
|
43
|
+
@columns_table = {}
|
44
|
+
@action_column_present = false
|
45
|
+
@view = view
|
46
|
+
end
|
47
|
+
|
48
|
+
def config #:nodoc:
|
49
|
+
@view.config
|
50
|
+
end
|
51
|
+
|
52
|
+
def controller #:nodoc:
|
53
|
+
@view.controller
|
54
|
+
end
|
55
|
+
|
56
|
+
def add_column(vc) #:nodoc:
|
57
|
+
@columns_table[vc.fully_qualified_attribute_name] = vc if vc.attribute
|
58
|
+
@columns << vc
|
59
|
+
end
|
60
|
+
|
61
|
+
def [](k) #:nodoc:
|
62
|
+
@columns_table[k]
|
63
|
+
end
|
64
|
+
|
65
|
+
def number_of_columns(filter = nil) #:nodoc:
|
66
|
+
filter_columns(filter).size
|
67
|
+
end
|
68
|
+
|
69
|
+
def each_column_label(filter = nil) #:nodoc:
|
70
|
+
filter_columns(filter).each { |col| yield col.name }
|
71
|
+
end
|
72
|
+
|
73
|
+
def column_labels(filter = nil) #:nodoc:
|
74
|
+
filter_columns(filter).collect(&:name)
|
75
|
+
end
|
76
|
+
|
77
|
+
def each_column(filter = nil) #:nodoc:
|
78
|
+
filter_columns(filter).each { |col| yield col }
|
79
|
+
end
|
80
|
+
|
81
|
+
def each_column_aware_of_one_last_one(filter = nil) #:nodoc:
|
82
|
+
cols = filter_columns(filter)
|
83
|
+
cols[0..-2].each { |col| yield col, false }
|
84
|
+
yield cols.last, true
|
85
|
+
end
|
86
|
+
|
87
|
+
def last_column_for_html #:nodoc:
|
88
|
+
filter_columns(:in_html).last
|
89
|
+
end
|
90
|
+
|
91
|
+
def select_for(filter) #:nodoc:
|
92
|
+
filter_columns(filter).select { |col| yield col }
|
93
|
+
end
|
94
|
+
|
95
|
+
def find_one_for(filter) #:nodoc:
|
96
|
+
filter_columns(filter).find { |col| yield col }
|
97
|
+
end
|
98
|
+
|
99
|
+
def each_column_with_attribute #:nodoc:
|
100
|
+
@columns.select(&:attribute).each { |col| yield col }
|
101
|
+
end
|
102
|
+
|
103
|
+
alias_method :each, :each_column
|
104
|
+
include Enumerable
|
105
|
+
|
106
|
+
def csv_export_icon #:nodoc:
|
107
|
+
content_tag(
|
108
|
+
:div,
|
109
|
+
content_tag(:i, '', class: 'fa fa-file-csv'),
|
110
|
+
title: NlMessage['csv_export_tooltip'],
|
111
|
+
class: 'clickable export-to-csv-button'
|
112
|
+
)
|
113
|
+
end
|
114
|
+
|
115
|
+
def pagination_panel(number_of_columns, hide_csv_button) #:nodoc:
|
116
|
+
panel = yield
|
117
|
+
|
118
|
+
render_csv_button = @grid.export_to_csv_enabled && !hide_csv_button
|
119
|
+
|
120
|
+
if panel.nil?
|
121
|
+
if render_csv_button
|
122
|
+
"<tr><td colspan=\"#{number_of_columns}\"></td><td>#{csv_export_icon}</td></tr>"
|
123
|
+
else
|
124
|
+
''
|
125
|
+
end
|
126
|
+
else
|
127
|
+
if render_csv_button
|
128
|
+
"<tr><td colspan=\"#{number_of_columns}\">#{panel}</td><td>#{csv_export_icon}</td></tr>"
|
129
|
+
else
|
130
|
+
"<tr><td colspan=\"#{number_of_columns + 1}\">#{panel}</td></tr>"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# Takes one argument and adds the <caption></caption> tag to the table with the
|
136
|
+
# argument value as the contents of <caption>.
|
137
|
+
def caption(kaption)
|
138
|
+
@kaption = kaption
|
139
|
+
end
|
140
|
+
|
141
|
+
# Adds a column with checkboxes for each record. Useful for actions with multiple records, for example, deleting
|
142
|
+
# selected records. Please note that +action_column+ only creates the checkboxes and the 'Select All' and
|
143
|
+
# 'Deselect All' buttons, and the form itelf as well as processing the parameters should be taken care of
|
144
|
+
# by the application code.
|
145
|
+
#
|
146
|
+
# * <tt>:param_name</tt> - The name of the HTTP parameter.
|
147
|
+
# The complete HTTP parameter is <tt>"#{grid_name}[#{param_name}][]"</tt>.
|
148
|
+
# The default param_name is 'selected'.
|
149
|
+
# * <tt>:html</tt> - a hash of HTML attributes to be included into the <tt>td</tt> tag.
|
150
|
+
# * <tt>:select_all_buttons</tt> - show/hide buttons 'Select All' and 'Deselect All' in the column header.
|
151
|
+
# The default is +true+.
|
152
|
+
# * <tt>:object_property</tt> - a method used to obtain the value for the HTTP parameter. The default is +id+.
|
153
|
+
# * <tt>:html_check_box</tt> - can be used to switch from a real check box to two images. The default is +true+.
|
154
|
+
#
|
155
|
+
# You can hide a certain action checkbox if you add the usual block to +g.action_column+, just like with the
|
156
|
+
# +g.column+ definition. If the block returns +nil+ or +false+ no checkbox will be rendered.
|
157
|
+
|
158
|
+
def action_column(opts = {}, &block)
|
159
|
+
if @action_column_present
|
160
|
+
raise Wice::WiceGridException.new('There can be only one action column in a WiceGrid')
|
161
|
+
end
|
162
|
+
|
163
|
+
options = {
|
164
|
+
param_name: :selected,
|
165
|
+
html: {},
|
166
|
+
select_all_buttons: true,
|
167
|
+
object_property: :id,
|
168
|
+
html_check_box: true
|
169
|
+
}
|
170
|
+
|
171
|
+
opts.assert_valid_keys(options.keys)
|
172
|
+
options.merge!(opts)
|
173
|
+
@action_column_present = true
|
174
|
+
column_processor_klass = Columns.get_view_column_processor(:action)
|
175
|
+
|
176
|
+
@columns << column_processor_klass.new(
|
177
|
+
@grid,
|
178
|
+
options[:html],
|
179
|
+
options[:param_name],
|
180
|
+
options[:select_all_buttons],
|
181
|
+
options[:object_property],
|
182
|
+
options[:html_check_box],
|
183
|
+
@view,
|
184
|
+
block
|
185
|
+
)
|
186
|
+
end
|
187
|
+
|
188
|
+
# Defines everything related to a column in a grid - column name, filtering, rendering cells, etc.
|
189
|
+
#
|
190
|
+
# +column+ is only used inside the block of the +grid+ method. See documentation for the +grid+ method for more details.
|
191
|
+
#
|
192
|
+
# The only parameter is a hash of options. None of them is optional. If no options are supplied, the result will be a
|
193
|
+
# column with no name, no filtering and no sorting.
|
194
|
+
#
|
195
|
+
# * <tt>:name</tt> - Name of the column.
|
196
|
+
# * <tt>:html</tt> - a hash of HTML attributes to be included into the <tt>td</tt> tag.
|
197
|
+
# * <tt>:class</tt> - a shortcut for <tt>html: {class: 'css_class'}</tt>
|
198
|
+
# * <tt>:attribute</tt> - name of a database column (which normally correspond to a model attribute with the
|
199
|
+
# same name). By default the field is assumed to belong to the default table (see documentation for the
|
200
|
+
# +initialize_grid+ method). Parameter <tt>:assoc</tt> (association) allows to specify another joined table. Presence of
|
201
|
+
# this parameter
|
202
|
+
# * adds sorting capabilities by this field
|
203
|
+
# * automatically creates a filter based on the type of the field unless parameter <tt>:filter</tt> is set to false.
|
204
|
+
# The following filters exist for the following types:
|
205
|
+
# * <tt>string</tt> - a text field
|
206
|
+
# * <tt>integer</tt> and <tt>float</tt> - two text fields to specify the range. Both limits or only one
|
207
|
+
# can be specified
|
208
|
+
# * <tt>boolean</tt> - a dropdown list with 'yes', 'no', or '-'. These labels can be changed in
|
209
|
+
# <tt>lib/wice_grid_config.rb</tt>.
|
210
|
+
# * <tt>date</tt> - two sets of standard date dropdown lists so specify the time range.
|
211
|
+
# * <tt>datetime</tt> - two sets of standard datetime dropdown lists so specify the time range. This filter
|
212
|
+
# is far from being user-friendly due to the number of dropdown lists.
|
213
|
+
# * <tt>:filter</tt> - Disables filters when set to false.
|
214
|
+
# This is needed if sorting is required while filters are not.
|
215
|
+
# * <tt>:filter_type</tt> - Using a column filter different from the default filter chosen automatically based on the
|
216
|
+
# data type or the <tt>:custom_filter</tt> argument. See <tt>lib/columns/column_processor_index.rb</tt> for the
|
217
|
+
# list of available filters.
|
218
|
+
# * <tt>:filter_control_options</tt> - Additional options to pass to the filter class to change the filter control
|
219
|
+
# behaviour. Supported options are dependent on the filter used.
|
220
|
+
# This is needed if sorting is required while filters are not.
|
221
|
+
# * <tt>:ordering</tt> - Enable/disable ordering links in the column titles. The default is +true+
|
222
|
+
# (i.e. if <tt>:attribute</tt> is defined, ordering is enabled)
|
223
|
+
# * <tt>:assoc</tt> - Name of the model association. <tt>:attribute</tt> belongs to the table joined via this association.
|
224
|
+
# * <tt>:table_alias</tt> - In case there are two joined assocations both referring to the same table, ActiveRecord
|
225
|
+
# constructs a query where the second join provides an alias for the joined table. Setting <tt>:table_alias</tt>
|
226
|
+
# to this alias will enable WiceGrid to order and filter by columns belonging to different associatiations but
|
227
|
+
# originating from the same table without confusion. See README for an example.
|
228
|
+
# * <tt>:custom_filter</tt> - Allows to construct a custom dropdown filter. Depending on the value of
|
229
|
+
# <tt>:custom_filter</tt> different modes are available:
|
230
|
+
# * array of strings and/or numbers - this is a direct definition of possible values of the dropdown.
|
231
|
+
# Every item will be used both as the value of the select option and as its label.
|
232
|
+
# * Array of two-element arrays - Every first item of the two-element array is used for the label of the select option
|
233
|
+
# while the second element is the value of the select option
|
234
|
+
# * Hash - The keys of the hash become the labels of the generated dropdown list,
|
235
|
+
# while the values will be values of options of the dropdown list:
|
236
|
+
# * <tt>:auto</tt> - a powerful option which populates the dropdown list with all unique values of the field specified by
|
237
|
+
# <tt>:attribute</tt> and <tt>:model</tt>.
|
238
|
+
# <tt>:attribute</tt> throughout all pages. In other words, this runs an SQL query without +offset+ and +limit+
|
239
|
+
# clauses and with <tt>distinct(table.field)</tt> instead of <tt>distinct(*)</tt>
|
240
|
+
# * any other symbol name (method name) - The dropdown list is populated by all unique value returned by the
|
241
|
+
# method with this name sent to <em>all</em> ActiveRecord objects throughout all pages. The main difference
|
242
|
+
# from <tt>:auto</tt> is that this method does not have to be a field in the result set, it is just some
|
243
|
+
# value computed in the method after the database call and ActiveRecord instantiation.
|
244
|
+
#
|
245
|
+
# But here lies the major drawback - this mode requires additional query without +offset+ and +limit+
|
246
|
+
# clauses to instantiate _all_ ActiveRecord objects, and performance-wise it brings all the advantages
|
247
|
+
# of pagination to nothing. Thus, memory- and performance-wise this can be really bad for some queries
|
248
|
+
# and tables and should be used with care.
|
249
|
+
#
|
250
|
+
# If the method returns a atomic value like a string or an integer, it is used for both the value and the
|
251
|
+
# label of the select option element. However, if the retuned value is a two element array, the first element
|
252
|
+
# is used for the option label and the second - for the value.
|
253
|
+
# Read more in README, section 'Custom dropdown filters'
|
254
|
+
# * An array of symbols (method names) - similar to the mode with a single symbol name. The first method name
|
255
|
+
# is sent to the ActiveRecord object if it responds to this method, the second method name is sent to the
|
256
|
+
# returned value unless it is +nil+, and so on. In other words, a single symbol mode is a
|
257
|
+
# case of an array of symbols where the array contains just one element. Thus the warning about the single method name
|
258
|
+
# mode applies here as well.
|
259
|
+
#
|
260
|
+
# If the last method returns a atomic value like a string or an integer, it is used for both the value and the
|
261
|
+
# label of the select option element.
|
262
|
+
# However, if the retuned value is a two element array, the first element is used for the option label and the
|
263
|
+
# second - for the value.
|
264
|
+
# Read more in README, section 'Custom dropdown filters'
|
265
|
+
# * <tt>:sort_by</tt> - allows arbitrary sorting of the results. This option takes a Proc which returns a value to
|
266
|
+
# sort by. When this option is used and sorting on this column is activated, the entire resultset is loaded and
|
267
|
+
# the Proc is passed to Enumerable#sort_by. This can also be used with calculated columns, but an arbitrary
|
268
|
+
# <tt>:attribute</tt> option must be included to provide a request parameter key. Because this option will load
|
269
|
+
# the entire resultset, it should only be used with small resultsets. The <tt>:custom_order</tt> option on grid
|
270
|
+
# initialization should be preferred if possible, as it will perform the sorting in SQL.
|
271
|
+
# * <tt>:boolean_filter_true_label</tt> - overrides the label for <tt>true</tt> in the boolean filter (<tt>wice_grid.boolean_filter_true_label</tt> in <tt>wice_grid.yml</tt>).
|
272
|
+
# * <tt>:boolean_filter_false_label</tt> - overrides the label for <tt>false</tt> in the boolean filter (<tt>wice_grid.boolean_filter_false_label</tt> in <tt>wice_grid.yml</tt>).
|
273
|
+
# * <tt>:allow_multiple_selection</tt> - enables or disables switching between single and multiple selection modes for
|
274
|
+
# custom dropdown boxes. +true+ by default (see +ALLOW_MULTIPLE_SELECTION+ in the configuration file).
|
275
|
+
# * <tt>:filter_all_label</tt> - overrides the default value for <tt>BOOLEAN_FILTER_FALSE_LABEL</tt> ('<tt>--</tt>')
|
276
|
+
# in the config. Has effect in a column with a boolean filter _or_ a custom filter.
|
277
|
+
# * <tt>:detach_with_id</tt> - allows to detach the filter and render it after or before the grid with the
|
278
|
+
# +grid_filter+ helper. The value is an arbitrary unique identifier
|
279
|
+
# of the filter. Read section 'Detached Filters' in README for details.
|
280
|
+
# Has effect in a column with a boolean filter _or_ a custom filter.
|
281
|
+
# * <tt>:in_csv</tt> - When CSV export is enabled, all columns are included into the export. Setting <tt>:in_csv</tt>
|
282
|
+
# to false will prohibit the column from inclusion into the export.
|
283
|
+
# * <tt>:in_html</tt> - When CSV export is enabled and it is needed to use a column for CSV export only and ignore it
|
284
|
+
# in HTML, set this parameter to false.
|
285
|
+
# * <tt>:negation</tt> - turn on/off the negation checkbox in string filters
|
286
|
+
# * <tt>:auto_reload</tt> - a boolean value specifying if a change in a filter triggers reloading of the grid. Works with all
|
287
|
+
# filter types including the JS calendar, the only exception is the standard Rails date/datetime filters.
|
288
|
+
# The default is false. (see +AUTO_RELOAD+ in the configuration file).
|
289
|
+
#
|
290
|
+
# The block parameter is an ActiveRecord instance. This block is called for every ActiveRecord shown, and the return
|
291
|
+
# value of the block is a string which becomes the contents of one table cell, or an array of two elements where
|
292
|
+
# the first element is the cell contents and the second is a hash of HTML attributes to be added for the <tt><td></tt>
|
293
|
+
# tag of the current cell.
|
294
|
+
#
|
295
|
+
# In case of an array output, please note that if you need to define HTML attributes for all <tt><td></tt>'s in a
|
296
|
+
# column, use +html+. Also note that if the method returns a hash with a <tt>:class</tt> or <tt>'class'</tt>
|
297
|
+
# element, it will not overwrite the class defined in +html+, or classes added by the grid itself
|
298
|
+
# (+active-filter+ and +sorted+), instead they will be all concatenated:
|
299
|
+
# <tt><td class="sorted user_class_for_columns user_class_for_this_specific_cell"></tt>
|
300
|
+
#
|
301
|
+
# It is up to the developer to make sure that what in rendered in column cells
|
302
|
+
# corresponds to sorting and filtering specified by parameters <tt>:attribute</tt> and <tt>:model</tt>.
|
303
|
+
|
304
|
+
def column(opts = {}, &block)
|
305
|
+
options = {
|
306
|
+
allow_multiple_selection: ConfigurationProvider.value_for(:ALLOW_MULTIPLE_SELECTION),
|
307
|
+
assoc: nil,
|
308
|
+
attribute: nil,
|
309
|
+
auto_reload: ConfigurationProvider.value_for(:AUTO_RELOAD),
|
310
|
+
boolean_filter_false_label: NlMessage['boolean_filter_false_label'],
|
311
|
+
boolean_filter_true_label: NlMessage['boolean_filter_true_label'],
|
312
|
+
class: nil,
|
313
|
+
custom_filter: nil,
|
314
|
+
detach_with_id: nil,
|
315
|
+
filter: true,
|
316
|
+
filter_all_label: ConfigurationProvider.value_for(:CUSTOM_FILTER_ALL_LABEL),
|
317
|
+
filter_control_options: {},
|
318
|
+
filter_type: nil,
|
319
|
+
html: {},
|
320
|
+
in_csv: true,
|
321
|
+
in_html: true,
|
322
|
+
model: nil, # will throw an exception with instructions
|
323
|
+
name: '',
|
324
|
+
negation: ConfigurationProvider.value_for(:NEGATION_IN_STRING_FILTERS),
|
325
|
+
ordering: true,
|
326
|
+
table_alias: nil,
|
327
|
+
sort_by: nil,
|
328
|
+
}
|
329
|
+
|
330
|
+
opts.assert_valid_keys(options.keys)
|
331
|
+
options.merge!(opts)
|
332
|
+
|
333
|
+
assocs = nil
|
334
|
+
|
335
|
+
if options[:model]
|
336
|
+
raise WiceGridArgumentError.new('Instead of specifying a model of a joined table please use assoc: :name_of_association')
|
337
|
+
end
|
338
|
+
|
339
|
+
unless options[:assoc].nil?
|
340
|
+
|
341
|
+
unless options[:assoc].is_a?(Symbol) ||
|
342
|
+
(options[:assoc].is_a?(Array) && ! options[:assoc].empty? && options[:assoc].all?{ |assoc| assoc.is_a?(Symbol)})
|
343
|
+
|
344
|
+
raise WiceGridArgumentError.new('Option :assoc can only be a symbol or an array of symbols')
|
345
|
+
end
|
346
|
+
|
347
|
+
assocs = options[:assoc].is_a?(Symbol) ? [options[:assoc]] : options[:assoc]
|
348
|
+
|
349
|
+
options[:model] = get_model_from_associations(@grid.klass, assocs)
|
350
|
+
end
|
351
|
+
|
352
|
+
if options[:attribute].nil? && options[:model]
|
353
|
+
raise WiceGridArgumentError.new('Option :assoc is only used together with :attribute')
|
354
|
+
end
|
355
|
+
|
356
|
+
if options[:attribute] && options[:attribute].index('.')
|
357
|
+
raise WiceGridArgumentError.new("Invalid attribute name #{options[:attribute]}. An attribute name must not contain a table name!")
|
358
|
+
end
|
359
|
+
|
360
|
+
|
361
|
+
if options[:class]
|
362
|
+
options[:html] ||= {}
|
363
|
+
Wice::WgHash.add_or_append_class_value!(options[:html], options[:class])
|
364
|
+
options.delete(:class)
|
365
|
+
end
|
366
|
+
|
367
|
+
if block.nil?
|
368
|
+
if !options[:attribute].blank?
|
369
|
+
if assocs.nil?
|
370
|
+
block = ->(obj) { obj.send(options[:attribute]) }
|
371
|
+
else
|
372
|
+
messages = assocs + [ options[:attribute] ]
|
373
|
+
block = ->(obj) { obj.deep_send(*messages) }
|
374
|
+
end
|
375
|
+
else
|
376
|
+
raise WiceGridArgumentError.new(
|
377
|
+
'Missing column block without attribute defined. You can only omit the block if attribute is present.')
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
klass = Columns::ViewColumn
|
382
|
+
if options[:attribute] &&
|
383
|
+
col_type_and_table_name = @grid.declare_column(
|
384
|
+
column_name: options[:attribute],
|
385
|
+
model: options[:model],
|
386
|
+
custom_filter_active: options[:custom_filter],
|
387
|
+
table_alias: options[:table_alias],
|
388
|
+
filter_type: options[:filter_type],
|
389
|
+
assocs: assocs,
|
390
|
+
sort_by: options[:sort_by],
|
391
|
+
)
|
392
|
+
|
393
|
+
# [ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter::Column, String, Boolean]
|
394
|
+
db_column, table_name, main_table = col_type_and_table_name
|
395
|
+
col_type = db_column.type
|
396
|
+
|
397
|
+
if options[:custom_filter]
|
398
|
+
|
399
|
+
custom_filter = if options[:custom_filter] == :auto
|
400
|
+
-> { @grid.distinct_values_for_column(db_column) } # Thank God Ruby has higher order functions!!!
|
401
|
+
|
402
|
+
elsif options[:custom_filter].class == Symbol
|
403
|
+
-> { @grid.distinct_values_for_column_in_resultset([options[:custom_filter]]) }
|
404
|
+
|
405
|
+
elsif options[:custom_filter].class == Hash
|
406
|
+
options[:custom_filter].keys
|
407
|
+
|
408
|
+
options[:custom_filter].to_a
|
409
|
+
|
410
|
+
elsif options[:custom_filter].class == Array
|
411
|
+
if options[:custom_filter].empty?
|
412
|
+
[]
|
413
|
+
elsif Wice::WgEnumerable.all_items_are_of_class(options[:custom_filter], Symbol)
|
414
|
+
-> { @grid.distinct_values_for_column_in_resultset(options[:custom_filter]) }
|
415
|
+
|
416
|
+
elsif Wice::WgEnumerable.all_items_are_of_class(options[:custom_filter], String) || WgEnumerable.all_items_are_of_class(options[:custom_filter], Numeric)
|
417
|
+
options[:custom_filter].map { |i| [i, i] }
|
418
|
+
|
419
|
+
elsif Wice::WgEnumerable.all_items_are_of_class(options[:custom_filter], Array)
|
420
|
+
options[:custom_filter]
|
421
|
+
else
|
422
|
+
raise WiceGridArgumentError.new(
|
423
|
+
':custom_filter can equal :auto, an array of string and/or numbers (direct values for the dropdown), ' \
|
424
|
+
'a homogeneous array of symbols (a sequence of methods to send to AR objects in the result set to ' \
|
425
|
+
'retrieve unique values for the dropdown), a Symbol (a shortcut for a one member array of symbols), ' \
|
426
|
+
'a hash where keys are labels and values are values for the dropdown option, or an array of two-item arrays, ' \
|
427
|
+
'each of which contains the label (first element) and the value (second element) for a dropdown option'
|
428
|
+
)
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
klass = Columns.get_view_column_processor(:custom)
|
433
|
+
elsif options[:filter_type]
|
434
|
+
klass = Columns.get_view_column_processor(options[:filter_type])
|
435
|
+
else
|
436
|
+
|
437
|
+
col_type = case col_type
|
438
|
+
when :date
|
439
|
+
Wice::Defaults::DEFAULT_FILTER_FOR_DATE
|
440
|
+
when :datetime
|
441
|
+
Wice::Defaults::DEFAULT_FILTER_FOR_DATETIME
|
442
|
+
when :timestamp
|
443
|
+
Wice::Defaults::DEFAULT_FILTER_FOR_DATETIME
|
444
|
+
else
|
445
|
+
col_type
|
446
|
+
end
|
447
|
+
|
448
|
+
klass = Columns.get_view_column_processor(col_type)
|
449
|
+
end # custom_filter
|
450
|
+
|
451
|
+
end # attribute
|
452
|
+
|
453
|
+
vc = klass.new(block, options, @grid, table_name, main_table, custom_filter, @view)
|
454
|
+
|
455
|
+
vc.negation = options[:negation] if vc.respond_to? :negation=
|
456
|
+
|
457
|
+
vc.filter_all_label = options[:filter_all_label] if vc.is_a?(Columns.get_view_column_processor(:custom))
|
458
|
+
if vc.is_a?(Columns.get_view_column_processor(:boolean))
|
459
|
+
vc.boolean_filter_true_label = options[:boolean_filter_true_label]
|
460
|
+
vc.boolean_filter_false_label = options[:boolean_filter_false_label]
|
461
|
+
end
|
462
|
+
add_column(vc)
|
463
|
+
end
|
464
|
+
|
465
|
+
def get_model_from_associations(model, assocs) # :nodoc:
|
466
|
+
if assocs.empty?
|
467
|
+
model
|
468
|
+
else
|
469
|
+
head = assocs[0]
|
470
|
+
tail = assocs[1..-1]
|
471
|
+
|
472
|
+
if reflection = model.reflect_on_association(head)
|
473
|
+
next_model = reflection.klass
|
474
|
+
get_model_from_associations(next_model, tail)
|
475
|
+
else
|
476
|
+
raise WiceGridArgumentError.new("Association #{head} not found in #{model}")
|
477
|
+
end
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
481
|
+
# Optional method inside the +grid+ block, to which every ActiveRecord instance is injected, just like +column+.
|
482
|
+
# Unlike +column+, it returns a hash which will be used as HTML attributes for the row with the given ActiveRecord instance.
|
483
|
+
#
|
484
|
+
# Note that if the method returns a hash with a <tt>:class</tt> or <tt>'class'</tt> element, it will not overwrite
|
485
|
+
# classes +even+ and +odd+, instead they will be concatenated: <tt><tr class="even highlighted_row_class_name"></tt>
|
486
|
+
def row_attributes(&block)
|
487
|
+
@row_attributes_handler = block
|
488
|
+
end
|
489
|
+
|
490
|
+
# Can be used to add HTML code (another row, for example) right after each grid row.
|
491
|
+
# Nothing is added if the block return +false+ or +nil+.
|
492
|
+
def after_row(&block)
|
493
|
+
@after_row_handler = block
|
494
|
+
end
|
495
|
+
|
496
|
+
# Can be used to add HTML code (another row, for example) right before each grid row.
|
497
|
+
# Nothing is added if the block return +false+ or +nil+.
|
498
|
+
def before_row(&block)
|
499
|
+
@before_row_handler = block
|
500
|
+
end
|
501
|
+
|
502
|
+
# Can be used to replace the HTML code (for example to make a multi-column spanning row) of a row.
|
503
|
+
# Nothing is replaced if the block return +false+ or +nil+.
|
504
|
+
def replace_row(&block)
|
505
|
+
@replace_row_handler = block
|
506
|
+
end
|
507
|
+
|
508
|
+
# Can be used to add HTML code (calculation results, for example) after all rows.
|
509
|
+
# Nothing is added if the block return +false+ or +nil+.
|
510
|
+
def last_row(&block)
|
511
|
+
@last_row_handler = block
|
512
|
+
end
|
513
|
+
|
514
|
+
# The output of the block submitted to +blank_slate+ is rendered instead of the whole grid if no filters are active
|
515
|
+
# and there are no records to render.
|
516
|
+
# In addition to the block style two other variants are accepted:
|
517
|
+
# * <tt>g.blank_slate "some text to be rendered"</tt>
|
518
|
+
# * <tt>g.blank_slate partial: "partial_name"</tt>
|
519
|
+
def blank_slate(opts = nil, &block)
|
520
|
+
if (opts.is_a?(Hash) && opts.key?(:partial) && block.nil?) || (opts.is_a?(String) && block.nil?)
|
521
|
+
@blank_slate_handler = opts
|
522
|
+
elsif opts.nil? && block
|
523
|
+
@blank_slate_handler = block
|
524
|
+
else
|
525
|
+
raise WiceGridArgumentError.new("blank_slate accepts only a string, a block, or template: 'path_to_template' ")
|
526
|
+
end
|
527
|
+
end
|
528
|
+
|
529
|
+
def get_row_attributes(ar_object) #:nodoc:
|
530
|
+
if @row_attributes_handler
|
531
|
+
row_attributes = @row_attributes_handler.call(ar_object)
|
532
|
+
row_attributes = {} if row_attributes.blank?
|
533
|
+
unless row_attributes.is_a?(Hash)
|
534
|
+
raise WiceGridArgumentError.new("row_attributes block must return a hash containing HTML attributes. The returned value is #{row_attributes.inspect}")
|
535
|
+
end
|
536
|
+
row_attributes
|
537
|
+
else
|
538
|
+
{}
|
539
|
+
end
|
540
|
+
end
|
541
|
+
|
542
|
+
def no_filter_needed? #:nodoc:
|
543
|
+
!@columns.inject(false) { |a, b| a || b.filter_shown? }
|
544
|
+
end
|
545
|
+
|
546
|
+
def no_filter_needed_in_main_table? #:nodoc:
|
547
|
+
!@columns.inject(false) { |a, b| a || b.filter_shown_in_main_table? }
|
548
|
+
end
|
549
|
+
|
550
|
+
def base_link_for_filter(controller, extra_parameters = {}) #:nodoc:
|
551
|
+
new_params = Wice::WgHash.deep_clone controller.params.to_unsafe_h
|
552
|
+
new_params.merge!(extra_parameters)
|
553
|
+
|
554
|
+
if new_params[@grid.name]
|
555
|
+
new_params[@grid.name].delete(:page) # we reset paging here
|
556
|
+
new_params[@grid.name].delete(:f) # no filter for the base url
|
557
|
+
new_params[@grid.name].delete(:foc) # nullify the focus
|
558
|
+
new_params[@grid.name].delete(:q) # and no request for the saved query
|
559
|
+
end
|
560
|
+
|
561
|
+
new_params[:only_path] = false
|
562
|
+
base_link_with_pp_info = omit_empty_query controller.url_for(new_params)
|
563
|
+
|
564
|
+
if new_params[@grid.name]
|
565
|
+
new_params[@grid.name].delete(:pp) # and reset back to pagination if show all mode is on
|
566
|
+
end
|
567
|
+
[base_link_with_pp_info, omit_empty_query(controller.url_for(new_params))]
|
568
|
+
end
|
569
|
+
|
570
|
+
def link_for_export(controller, format, extra_parameters = {}) #:nodoc:
|
571
|
+
new_params = Wice::WgHash.deep_clone controller.params.to_unsafe_h
|
572
|
+
new_params.merge!(extra_parameters)
|
573
|
+
|
574
|
+
new_params[@grid.name] = {} unless new_params[@grid.name]
|
575
|
+
new_params[@grid.name][:export] = format
|
576
|
+
|
577
|
+
new_params[:only_path] = false
|
578
|
+
controller.url_for(new_params)
|
579
|
+
end
|
580
|
+
|
581
|
+
def column_link(column, direction, params, extra_parameters = {}) #:nodoc:
|
582
|
+
column_attribute_name = if column.attribute.index('.') || column.main_table || column.table_alias_or_table_name.nil?
|
583
|
+
column.attribute
|
584
|
+
else
|
585
|
+
column.table_alias_or_table_name + '.' + column.attribute
|
586
|
+
end
|
587
|
+
|
588
|
+
query_params = { @grid.name => {
|
589
|
+
ORDER_PARAMETER_NAME => column_attribute_name,
|
590
|
+
ORDER_DIRECTION_PARAMETER_NAME => direction
|
591
|
+
} }
|
592
|
+
|
593
|
+
cleaned_params = Wice::WgHash.deep_clone params.to_unsafe_h
|
594
|
+
cleaned_params.merge!(extra_parameters)
|
595
|
+
|
596
|
+
cleaned_params.delete(:controller)
|
597
|
+
cleaned_params.delete(:action)
|
598
|
+
|
599
|
+
query_params = Wice::WgHash.rec_merge(cleaned_params, query_params)
|
600
|
+
|
601
|
+
if Rails.version.to_i >= 5
|
602
|
+
'?' + query_params.to_h.to_query
|
603
|
+
else
|
604
|
+
'?' + query_params.to_query
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
608
|
+
protected
|
609
|
+
|
610
|
+
def filter_columns(method_name = nil) #:nodoc:
|
611
|
+
method_name ? @columns.select(&method_name) : @columns
|
612
|
+
end
|
613
|
+
|
614
|
+
def omit_empty_query(url) #:nodoc:
|
615
|
+
# /foo? --> /foo
|
616
|
+
# /foo?grid= --> /foo
|
617
|
+
# /foo?grid=&page=1 --> /foo?page=1
|
618
|
+
# /foo?grid=some_value --> /foo?grid=some_value
|
619
|
+
|
620
|
+
empty_hash_rx = Regexp.new "([&?])#{Regexp.escape @grid.name}=([&?]|$)" # c.f., issue #140
|
621
|
+
url.gsub(empty_hash_rx, '\1').gsub(/\?+$/, '')
|
622
|
+
end
|
623
|
+
end
|
624
|
+
end
|