decidim 0.0.1.alpha9 → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of decidim might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.babelrc +16 -0
- data/.codeclimate.yml +16 -2
- data/.eslintignore +11 -0
- data/.eslintrc.json +275 -11
- data/.gitattributes +1 -0
- data/.gitignore +8 -0
- data/.hound.yml +2 -4
- data/.rubocop.yml +8 -4
- data/.ruby-version +1 -1
- data/.travis.yml +7 -8
- data/Dockerfile +16 -5
- data/Gemfile +4 -6
- data/Gemfile.lock +148 -70
- data/{LICENSE.txt → LICENSE-AGPLv3.txt} +42 -0
- data/README.md +28 -10
- data/Rakefile +53 -2
- data/codecov.yml +14 -6
- data/crowdin.yaml +1 -2
- data/decidim-admin/README.md +33 -8
- data/decidim-admin/Rakefile +0 -25
- data/decidim-admin/app/assets/javascripts/decidim/admin/application.js.es6 +17 -10
- data/decidim-admin/app/assets/javascripts/decidim/admin/sort_steps.js.es6 +20 -11
- data/decidim-admin/app/assets/javascripts/decidim/admin/tab_focus.js.es6 +22 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_forms.scss +10 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_layout.scss +11 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_tables.scss +4 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/application.scss +8 -2
- data/decidim-admin/app/commands/decidim/admin/activate_participatory_process_step.rb +1 -1
- data/decidim-admin/app/commands/decidim/admin/create_category.rb +44 -0
- data/decidim-admin/app/commands/decidim/admin/create_feature.rb +48 -0
- data/decidim-admin/app/commands/decidim/admin/create_participatory_process.rb +3 -6
- data/decidim-admin/app/commands/decidim/admin/create_participatory_process_admin.rb +51 -0
- data/decidim-admin/app/commands/decidim/admin/create_participatory_process_attachment.rb +44 -0
- data/decidim-admin/app/commands/decidim/admin/create_participatory_process_step.rb +3 -3
- data/decidim-admin/app/commands/decidim/admin/create_scope.rb +38 -0
- data/decidim-admin/app/commands/decidim/admin/create_static_page.rb +40 -0
- data/decidim-admin/app/commands/decidim/admin/destroy_category.rb +36 -0
- data/decidim-admin/app/commands/decidim/admin/destroy_feature.rb +39 -0
- data/decidim-admin/app/commands/decidim/admin/publish_participatory_process.rb +1 -1
- data/decidim-admin/app/commands/decidim/admin/reorder_participatory_process_steps.rb +5 -2
- data/decidim-admin/app/commands/decidim/admin/unpublish_participatory_process.rb +1 -1
- data/decidim-admin/app/commands/decidim/admin/update_category.rb +48 -0
- data/decidim-admin/app/commands/decidim/admin/update_organization.rb +49 -0
- data/decidim-admin/app/commands/decidim/admin/update_participatory_process.rb +2 -2
- data/decidim-admin/app/commands/decidim/admin/update_participatory_process_attachment.rb +49 -0
- data/decidim-admin/app/commands/decidim/admin/update_participatory_process_step.rb +1 -1
- data/decidim-admin/app/commands/decidim/admin/update_scope.rb +43 -0
- data/decidim-admin/app/commands/decidim/admin/update_static_page.rb +45 -0
- data/decidim-admin/app/constraints/decidim/admin/organization_dashboard_constraint.rb +5 -1
- data/decidim-admin/app/controllers/decidim/admin/application_controller.rb +8 -0
- data/decidim-admin/app/controllers/decidim/admin/categories_controller.rb +90 -0
- data/decidim-admin/app/controllers/decidim/admin/concerns/participatory_process_admin.rb +31 -0
- data/decidim-admin/app/controllers/decidim/admin/features_controller.rb +74 -0
- data/decidim-admin/app/controllers/decidim/admin/organization_controller.rb +40 -0
- data/decidim-admin/app/controllers/decidim/admin/participatory_process_attachments_controller.rb +84 -0
- data/decidim-admin/app/controllers/decidim/admin/participatory_process_publications_controller.rb +2 -7
- data/decidim-admin/app/controllers/decidim/admin/participatory_process_step_activations_controller.rb +6 -8
- data/decidim-admin/app/controllers/decidim/admin/participatory_process_step_ordering_controller.rb +2 -4
- data/decidim-admin/app/controllers/decidim/admin/participatory_process_steps_controller.rb +13 -11
- data/decidim-admin/app/controllers/decidim/admin/participatory_process_user_roles_controller.rb +54 -0
- data/decidim-admin/app/controllers/decidim/admin/participatory_processes_controller.rb +11 -6
- data/decidim-admin/app/controllers/decidim/admin/scopes_controller.rb +79 -0
- data/decidim-admin/app/controllers/decidim/admin/static_pages_controller.rb +94 -0
- data/decidim-admin/app/forms/decidim/admin/category_form.rb +37 -0
- data/decidim-admin/app/forms/decidim/admin/feature_form.rb +16 -0
- data/decidim-admin/app/forms/decidim/admin/organization_form.rb +31 -0
- data/decidim-admin/app/forms/decidim/admin/participatory_process_attachment_form.rb +19 -0
- data/decidim-admin/app/forms/decidim/admin/participatory_process_form.rb +4 -7
- data/decidim-admin/app/forms/decidim/admin/participatory_process_step_form.rb +12 -2
- data/decidim-admin/app/forms/decidim/admin/participatory_process_user_role_form.rb +15 -0
- data/decidim-admin/app/forms/decidim/admin/scope_form.rb +24 -0
- data/decidim-admin/app/forms/decidim/admin/static_page_form.rb +30 -0
- data/decidim-admin/app/helpers/decidim/admin/application_helper.rb +1 -0
- data/decidim-admin/app/helpers/decidim/admin/aria_selected_link_to_helper.rb +28 -0
- data/decidim-admin/app/helpers/decidim/admin/attributes_display_helper.rb +13 -5
- data/decidim-admin/app/models/decidim/admin/abilities/admin_user.rb +34 -0
- data/decidim-admin/app/models/decidim/admin/abilities/base.rb +19 -0
- data/decidim-admin/app/models/decidim/admin/abilities/participatory_process_admin.rb +51 -0
- data/decidim-admin/app/models/decidim/admin/participatory_process_user_role.rb +14 -0
- data/decidim-admin/app/queries/decidim/admin/manageable_participatory_processes_for_user.rb +41 -0
- data/decidim-admin/app/queries/decidim/admin/process_admin_roles_for_process.rb +35 -0
- data/decidim-admin/app/views/decidim/admin/categories/_form.html.erb +12 -0
- data/decidim-admin/app/views/decidim/admin/categories/edit.html.erb +9 -0
- data/decidim-admin/app/views/decidim/admin/categories/index.html.erb +44 -0
- data/decidim-admin/app/views/decidim/admin/categories/new.html.erb +9 -0
- data/decidim-admin/app/views/decidim/admin/categories/show.html.erb +14 -0
- data/decidim-admin/app/views/decidim/admin/features/_feature.html.erb +20 -0
- data/decidim-admin/app/views/decidim/admin/features/_form.html.erb +3 -0
- data/decidim-admin/app/views/decidim/admin/features/index.html.erb +23 -0
- data/decidim-admin/app/views/decidim/admin/features/new.html.erb +9 -0
- data/decidim-admin/app/views/decidim/admin/organization/_form.html.erb +23 -0
- data/decidim-admin/app/views/decidim/admin/organization/edit.html.erb +11 -0
- data/decidim-admin/app/views/decidim/admin/participatory_process_attachments/_form.html.erb +11 -0
- data/decidim-admin/app/views/decidim/admin/participatory_process_attachments/edit.html.erb +9 -0
- data/decidim-admin/app/views/decidim/admin/participatory_process_attachments/index.html.erb +37 -0
- data/decidim-admin/app/views/decidim/admin/participatory_process_attachments/new.html.erb +9 -0
- data/decidim-admin/app/views/decidim/admin/participatory_process_attachments/show.html.erb +25 -0
- data/decidim-admin/app/views/decidim/admin/participatory_process_steps/_form.html.erb +2 -2
- data/decidim-admin/app/views/decidim/admin/participatory_process_steps/edit.html.erb +1 -3
- data/decidim-admin/app/views/decidim/admin/participatory_process_steps/{_table.html.erb → index.html.erb} +15 -11
- data/decidim-admin/app/views/decidim/admin/participatory_process_steps/new.html.erb +1 -3
- data/decidim-admin/app/views/decidim/admin/participatory_process_steps/show.html.erb +1 -4
- data/decidim-admin/app/views/decidim/admin/participatory_process_user_roles/index.html.erb +34 -0
- data/decidim-admin/app/views/decidim/admin/participatory_processes/_form.html.erb +2 -2
- data/decidim-admin/app/views/decidim/admin/participatory_processes/edit.html.erb +13 -3
- data/decidim-admin/app/views/decidim/admin/participatory_processes/index.html.erb +5 -14
- data/decidim-admin/app/views/decidim/admin/participatory_processes/show.html.erb +19 -36
- data/decidim-admin/app/views/decidim/admin/scopes/_form.html.erb +3 -0
- data/decidim-admin/app/views/decidim/admin/scopes/edit.html.erb +11 -0
- data/decidim-admin/app/views/decidim/admin/scopes/index.html.erb +38 -0
- data/decidim-admin/app/views/decidim/admin/scopes/new.html.erb +11 -0
- data/decidim-admin/app/views/decidim/admin/static_pages/_form.html.erb +13 -0
- data/decidim-admin/app/views/decidim/admin/static_pages/edit.html.erb +11 -0
- data/decidim-admin/app/views/decidim/admin/static_pages/index.html.erb +40 -0
- data/decidim-admin/app/views/decidim/admin/static_pages/new.html.erb +11 -0
- data/decidim-admin/app/views/decidim/admin/static_pages/show.html.erb +22 -0
- data/decidim-admin/app/views/layouts/decidim/admin/_application.html.erb +40 -0
- data/decidim-admin/app/views/layouts/decidim/admin/_sidebar.html.erb +5 -2
- data/decidim-admin/app/views/layouts/decidim/admin/application.html.erb +3 -40
- data/decidim-admin/app/views/layouts/decidim/admin/participatory_process.html.erb +54 -0
- data/decidim-admin/config/i18n-tasks.yml +3 -2
- data/decidim-admin/config/locales/ca.yml +138 -6
- data/decidim-admin/config/locales/en.yml +191 -13
- data/decidim-admin/config/locales/es.yml +139 -7
- data/decidim-admin/config/routes.rb +23 -1
- data/decidim-admin/db/migrate/20161102144648_add_admin_participatory_process_user_roles.rb +15 -0
- data/decidim-admin/db/seeds.rb +21 -0
- data/decidim-admin/decidim-admin.gemspec +6 -11
- data/decidim-admin/lib/decidim/admin.rb +1 -0
- data/decidim-admin/lib/decidim/admin/engine.rb +10 -3
- data/decidim-admin/lib/decidim/admin/features.rb +10 -0
- data/decidim-admin/lib/decidim/admin/features/base_controller.rb +33 -0
- data/decidim-admin/spec/commands/create_category_spec.rb +61 -0
- data/decidim-admin/spec/commands/create_feature_spec.rb +60 -0
- data/decidim-admin/spec/commands/create_participatory_process_admin_spec.rb +42 -0
- data/decidim-admin/spec/commands/create_participatory_process_spec.rb +37 -0
- data/decidim-admin/spec/commands/create_scope_spec.rb +24 -0
- data/decidim-admin/spec/commands/create_static_page_spec.rb +42 -0
- data/decidim-admin/spec/commands/destroy_category_spec.rb +46 -0
- data/decidim-admin/spec/commands/destroy_feature_spec.rb +31 -0
- data/decidim-admin/spec/commands/update_category_spec.rb +64 -0
- data/decidim-admin/spec/commands/update_organization_spec.rb +73 -0
- data/decidim-admin/spec/commands/update_scope_spec.rb +24 -0
- data/decidim-admin/spec/commands/update_static_page_spec.rb +50 -0
- data/decidim-admin/spec/controllers/static_pages_controller_spec.rb +50 -0
- data/decidim-admin/spec/factories.rb +8 -0
- data/decidim-admin/spec/features/admin_invite_spec.rb +6 -2
- data/decidim-admin/spec/features/admin_manages_features_spec.rb +75 -0
- data/decidim-admin/spec/features/admin_manages_organization_scopes_spec.rb +80 -0
- data/decidim-admin/spec/features/admin_manages_organization_spec.rb +38 -0
- data/decidim-admin/spec/features/admin_manages_participatory_process_admins_spec.rb +10 -0
- data/decidim-admin/spec/features/admin_manages_participatory_process_attachments_spec.rb +10 -0
- data/decidim-admin/spec/features/admin_manages_participatory_process_categories_spec.rb +18 -0
- data/decidim-admin/spec/features/admin_manages_participatory_process_steps_spec.rb +10 -0
- data/decidim-admin/spec/features/admin_manages_participatory_processes_spec.rb +95 -0
- data/decidim-admin/spec/features/participatory_process_admin_manages_participatory_process_admins_spec.rb +27 -0
- data/decidim-admin/spec/features/participatory_process_admin_manages_participatory_process_attachments_spec.rb +13 -0
- data/decidim-admin/spec/features/participatory_process_admin_manages_participatory_process_steps_spec.rb +12 -0
- data/decidim-admin/spec/features/participatory_process_admin_manages_participatory_processes_spec.rb +36 -0
- data/decidim-admin/spec/features/process_admin_manages_participatory_process_categories_spec.rb +20 -0
- data/decidim-admin/spec/features/static_pages_spec.rb +120 -0
- data/decidim-admin/spec/forms/category_form_spec.rb +94 -0
- data/decidim-admin/spec/forms/organization_form_spec.rb +60 -0
- data/decidim-admin/spec/forms/participatory_process_form_spec.rb +19 -6
- data/decidim-admin/spec/forms/participatory_process_step_form_spec.rb +21 -1
- data/decidim-admin/spec/forms/participatory_process_user_role_form_spec.rb +29 -0
- data/decidim-admin/spec/forms/scope_form_spec.rb +60 -0
- data/decidim-admin/spec/forms/static_page_form_spec.rb +97 -0
- data/decidim-admin/spec/helpers/aria_selected_link_to_helper_spec.rb +46 -0
- data/decidim-admin/spec/models/abilities/admin_user_spec.rb +62 -0
- data/decidim-admin/spec/models/abilities/participatory_process_admin_spec.rb +50 -0
- data/decidim-admin/spec/models/participatory_process_user_role_spec.rb +21 -0
- data/decidim-admin/spec/queries/manageable_participatory_processes_for_user_spec.rb +30 -0
- data/decidim-admin/spec/queries/process_admin_roles_for_process_spec.rb +17 -0
- data/decidim-admin/spec/shared/manage_process_admins_examples.rb +56 -0
- data/decidim-admin/spec/shared/manage_process_attachments_examples.rb +105 -0
- data/decidim-admin/spec/shared/manage_process_categories_examples.rb +129 -0
- data/decidim-admin/spec/shared/manage_process_steps_examples.rb +153 -0
- data/decidim-admin/spec/shared/manage_processes_examples.rb +139 -0
- data/decidim-admin/spec/shared/participatory_admin_shared_context.rb +19 -0
- data/decidim-admin/spec/spec_helper.rb +4 -0
- data/decidim-admin/spec/support/processes_menu_links_helpers.rb +12 -0
- data/decidim-admin/spec/views/decidim/static_pages/_form.html.erb_spec.rb +35 -0
- data/decidim-admin/vendor/assets/javascripts/html.sortable.js +691 -0
- data/decidim-api/README.md +11 -10
- data/decidim-api/Rakefile +0 -25
- data/decidim-api/app/assets/config/decidim_api_manifest.js +1 -0
- data/decidim-api/app/assets/javascripts/decidim/api/docs.js.es6 +23 -0
- data/decidim-api/app/controllers/decidim/api/documentation_controller.rb +10 -0
- data/decidim-api/app/controllers/decidim/api/queries_controller.rb +3 -2
- data/decidim-api/app/views/decidim/api/documentation/show.html.erb +10 -0
- data/decidim-api/app/views/layouts/decidim/api/documentation.html.erb +9 -0
- data/decidim-api/config/routes.rb +4 -3
- data/decidim-api/decidim-api.gemspec +6 -9
- data/decidim-api/lib/decidim/api.rb +7 -0
- data/decidim-api/lib/decidim/api/engine.rb +14 -0
- data/decidim-api/lib/decidim/api/graphiql-initial-query.txt +11 -0
- data/decidim-api/{app/schemas → lib}/decidim/api/schema.rb +1 -0
- data/decidim-api/lib/decidim/api/test/type_context.rb +41 -0
- data/decidim-api/{app/types/decidim/api/localized_string_type.rb → lib/decidim/api/types/localized_string.rb} +1 -1
- data/decidim-api/lib/decidim/api/types/mutation.rb +10 -0
- data/decidim-api/lib/decidim/api/types/query.rb +10 -0
- data/decidim-api/{app/types/decidim/api/translated_field_type.rb → lib/decidim/api/types/translated_field.rb} +2 -2
- data/decidim-api/spec/factories.rb +1 -0
- data/decidim-api/spec/features/documentation_spec.rb +22 -0
- data/decidim-api/spec/features/graphiql_spec.rb +22 -0
- data/decidim-api/spec/types/localized_string_type_spec.rb +2 -1
- data/decidim-api/spec/types/mutation_type_spec.rb +38 -0
- data/decidim-api/spec/types/query_type_spec.rb +2 -1
- data/decidim-api/spec/types/translated_field_type_spec.rb +2 -1
- data/decidim-api/vendor/assets/javascripts/decidim/api/graphql-docs.js +3518 -0
- data/decidim-api/vendor/assets/javascripts/decidim/api/react-dom.js +42 -0
- data/decidim-api/vendor/assets/javascripts/decidim/api/react.js +20595 -0
- data/decidim-comments/.gitignore +2 -0
- data/decidim-comments/Gemfile +6 -0
- data/decidim-comments/README.md +42 -0
- data/decidim-comments/Rakefile +2 -0
- data/decidim-comments/app/assets/config/decidim_comments_manifest.js +1 -0
- data/decidim-comments/app/assets/javascripts/decidim/comments/bundle.js +0 -0
- data/decidim-comments/app/assets/javascripts/decidim/comments/comments.js.erb +8 -0
- data/decidim-comments/app/commands/decidim/comments/create_comment.rb +40 -0
- data/decidim-comments/app/forms/decidim/comments/comment_form.rb +16 -0
- data/decidim-comments/app/frontend/application/apollo_client.js +16 -0
- data/decidim-comments/app/frontend/application/application.component.jsx +37 -0
- data/decidim-comments/app/frontend/application/application.component.test.jsx +33 -0
- data/decidim-comments/app/frontend/application/icon.component.jsx +21 -0
- data/decidim-comments/app/frontend/application/icon.component.test.jsx +43 -0
- data/decidim-comments/app/frontend/comments/add_comment_form.component.jsx +250 -0
- data/decidim-comments/app/frontend/comments/add_comment_form.component.test.jsx +173 -0
- data/decidim-comments/app/frontend/comments/add_comment_form.mutation.graphql +8 -0
- data/decidim-comments/app/frontend/comments/comment.component.jsx +202 -0
- data/decidim-comments/app/frontend/comments/comment.component.test.jsx +125 -0
- data/decidim-comments/app/frontend/comments/comment.fragment.graphql +12 -0
- data/decidim-comments/app/frontend/comments/comment_data.fragment.graphql +11 -0
- data/decidim-comments/app/frontend/comments/comment_order_selector.component.jsx +28 -0
- data/decidim-comments/app/frontend/comments/comment_order_selector.component.test.jsx +9 -0
- data/decidim-comments/app/frontend/comments/comment_thread.component.jsx +64 -0
- data/decidim-comments/app/frontend/comments/comment_thread.component.test.jsx +71 -0
- data/decidim-comments/app/frontend/comments/comment_thread.fragment.graphql +9 -0
- data/decidim-comments/app/frontend/comments/comments.component.jsx +139 -0
- data/decidim-comments/app/frontend/comments/comments.component.test.jsx +106 -0
- data/decidim-comments/app/frontend/comments/comments.query.graphql +10 -0
- data/decidim-comments/app/frontend/comments/featured_comment.component.jsx +23 -0
- data/decidim-comments/app/frontend/comments/featured_comment.component.test.jsx +15 -0
- data/decidim-comments/app/frontend/entry.js +24 -0
- data/decidim-comments/app/frontend/entry.test.js +29 -0
- data/decidim-comments/app/frontend/support/asset_url.js +11 -0
- data/decidim-comments/app/frontend/support/generate_comments_data.js +29 -0
- data/decidim-comments/app/frontend/support/generate_current_user_data.js +13 -0
- data/decidim-comments/app/frontend/support/load_translations.js +23 -0
- data/decidim-comments/app/frontend/support/require_all.js +10 -0
- data/decidim-comments/app/frontend/support/resolve_graphql_query.js +37 -0
- data/decidim-comments/app/frontend/support/stub_component.js +29 -0
- data/decidim-comments/app/helpers/decidim/comments/comments_helper.rb +51 -0
- data/decidim-comments/app/models/decidim/comments/comment.rb +55 -0
- data/decidim-comments/app/types/decidim/comments/add_comment_type.rb +12 -0
- data/decidim-comments/app/types/decidim/comments/author_type.rb +15 -0
- data/decidim-comments/app/types/decidim/comments/comment_type.rb +28 -0
- data/decidim-comments/bin/rails +14 -0
- data/decidim-comments/config/i18n-tasks.yml +124 -0
- data/decidim-comments/config/locales/ca.yml +35 -0
- data/decidim-comments/config/locales/en.yml +36 -0
- data/decidim-comments/config/locales/es.yml +35 -0
- data/decidim-comments/db/migrate/20161130143508_create_comments.rb +11 -0
- data/decidim-comments/db/migrate/20161214082645_add_depth_to_comments.rb +5 -0
- data/decidim-comments/db/migrate/20161216102820_add_alignment_to_comments.rb +5 -0
- data/decidim-comments/db/seeds.rb +11 -0
- data/decidim-comments/decidim-comments.gemspec +25 -0
- data/decidim-comments/lib/decidim/comments.rb +10 -0
- data/decidim-comments/lib/decidim/comments/engine.rb +34 -0
- data/decidim-comments/lib/decidim/comments/mutation_extensions.rb +36 -0
- data/decidim-comments/lib/decidim/comments/query_extensions.rb +33 -0
- data/decidim-comments/package.json +21 -0
- data/decidim-comments/spec/commands/create_comment_spec.rb +64 -0
- data/decidim-comments/spec/factories.rb +9 -0
- data/decidim-comments/spec/features/comments_spec.rb +97 -0
- data/decidim-comments/spec/forms/comment_form_spec.rb +48 -0
- data/decidim-comments/spec/helpers/comments_helper_spec.rb +48 -0
- data/decidim-comments/spec/models/comment_spec.rb +64 -0
- data/decidim-comments/spec/spec_helper.rb +2 -0
- data/decidim-comments/spec/support/dummy.rb +20 -0
- data/decidim-comments/spec/types/author_type_spec.rb +21 -0
- data/decidim-comments/spec/types/comment_type_spec.rb +51 -0
- data/decidim-comments/spec/types/query_type_spec.rb +49 -0
- data/decidim-dev/decidim-dev.gemspec +11 -7
- data/decidim-dev/lib/decidim/common_rake.rb +20 -6
- data/decidim-dev/lib/decidim/dummy_authorization_handler.rb +9 -2
- data/decidim-dev/lib/decidim/test/base_spec_helper.rb +25 -6
- data/decidim-dev/lib/decidim/test/i18n_spec.rb +1 -1
- data/decidim-dev/lib/decidim/test/rspec_support/capybara.rb +66 -5
- data/decidim-dev/lib/decidim/test/rspec_support/database_cleaner.rb +2 -2
- data/decidim-dev/lib/decidim/test/rspec_support/feature.rb +22 -0
- data/decidim-dev/lib/decidim/test/rspec_support/feature_context.rb +44 -0
- data/decidim-dev/lib/decidim/test/rspec_support/helpers.rb +42 -0
- data/decidim-dev/lib/decidim/test/rspec_support/translation_helpers.rb +63 -0
- data/decidim-dev/spec/support/Exampledocument.docx +0 -0
- data/decidim-dev/spec/support/Exampledocument.odt +0 -0
- data/decidim-dev/spec/support/Exampledocument.pdf +0 -0
- data/decidim-dev/spec/support/avatar.svg +14 -0
- data/decidim-dev/spec/support/malicious.jpg +0 -0
- data/decidim-meetings/.gitignore +7 -0
- data/decidim-meetings/README.md +23 -0
- data/decidim-meetings/Rakefile +2 -0
- data/decidim-meetings/app/commands/decidim/meetings/admin/create_meeting.rb +40 -0
- data/decidim-meetings/app/commands/decidim/meetings/admin/update_meeting.rb +44 -0
- data/decidim-meetings/app/controllers/decidim/meetings/admin/application_controller.rb +14 -0
- data/decidim-meetings/app/controllers/decidim/meetings/admin/meetings_controller.rb +69 -0
- data/decidim-meetings/app/controllers/decidim/meetings/application_controller.rb +13 -0
- data/decidim-meetings/app/controllers/decidim/meetings/meetings_controller.rb +24 -0
- data/decidim-meetings/app/forms/decidim/meetings/admin/meeting_form.rb +30 -0
- data/decidim-meetings/app/models/decidim/meetings/application_record.rb +9 -0
- data/decidim-meetings/app/models/decidim/meetings/meeting.rb +12 -0
- data/decidim-meetings/app/views/decidim/meetings/admin/meetings/_form.html.erb +32 -0
- data/decidim-meetings/app/views/decidim/meetings/admin/meetings/edit.html.erb +9 -0
- data/decidim-meetings/app/views/decidim/meetings/admin/meetings/index.html.erb +39 -0
- data/decidim-meetings/app/views/decidim/meetings/admin/meetings/new.html.erb +9 -0
- data/decidim-meetings/app/views/decidim/meetings/meetings/_address_details.html.erb +5 -0
- data/decidim-meetings/app/views/decidim/meetings/meetings/index.html.erb +30 -0
- data/decidim-meetings/app/views/decidim/meetings/meetings/show.html.erb +39 -0
- data/decidim-meetings/bin/rails +14 -0
- data/decidim-meetings/config/i18n-tasks.yml +4 -0
- data/decidim-meetings/config/locales/ca.yml +44 -0
- data/decidim-meetings/config/locales/en.yml +45 -0
- data/decidim-meetings/config/locales/es.yml +44 -0
- data/decidim-meetings/db/migrate/20161130121354_create_meetings.rb +18 -0
- data/decidim-meetings/decidim-meetings.gemspec +21 -0
- data/decidim-meetings/lib/decidim/meetings.rb +11 -0
- data/decidim-meetings/lib/decidim/meetings/admin.rb +9 -0
- data/decidim-meetings/lib/decidim/meetings/admin_engine.rb +22 -0
- data/decidim-meetings/lib/decidim/meetings/feature.rb +42 -0
- data/decidim-meetings/lib/decidim/meetings/list_engine.rb +16 -0
- data/decidim-meetings/spec/commands/create_meeting_spec.rb +38 -0
- data/decidim-meetings/spec/commands/update_meeting_spec.rb +36 -0
- data/decidim-meetings/spec/factories.rb +16 -0
- data/decidim-meetings/spec/features/admin_manages_meetings_spec.rb +16 -0
- data/decidim-meetings/spec/features/explore_meetings_spec.rb +54 -0
- data/decidim-meetings/spec/features/process_admin_manages_meetings_spec.rb +17 -0
- data/decidim-meetings/spec/forms/meeting_form_spec.rb +115 -0
- data/decidim-meetings/spec/models/meeting_spec.rb +10 -0
- data/decidim-meetings/spec/shared/admin_shared_context.rb +9 -0
- data/decidim-meetings/spec/shared/manage_meetings_examples.rb +118 -0
- data/decidim-meetings/spec/spec_helper.rb +2 -0
- data/decidim-pages/.gitignore +3 -0
- data/decidim-pages/README.md +24 -0
- data/decidim-pages/Rakefile +2 -0
- data/decidim-pages/app/commands/decidim/pages/admin/update_page.rb +39 -0
- data/decidim-pages/app/commands/decidim/pages/create_page.rb +21 -0
- data/decidim-pages/app/commands/decidim/pages/destroy_page.rb +17 -0
- data/decidim-pages/app/controllers/decidim/pages/admin/application_controller.rb +13 -0
- data/decidim-pages/app/controllers/decidim/pages/admin/pages_controller.rb +35 -0
- data/decidim-pages/app/controllers/decidim/pages/application_controller.rb +16 -0
- data/decidim-pages/app/forms/decidim/pages/admin/page_form.rb +17 -0
- data/decidim-pages/app/helpers/decidim/pages/application_helper.rb +10 -0
- data/decidim-pages/app/models/decidim/pages/application_record.rb +9 -0
- data/decidim-pages/app/models/decidim/pages/page.rb +12 -0
- data/decidim-pages/app/views/decidim/pages/admin/pages/_form.html.erb +5 -0
- data/decidim-pages/app/views/decidim/pages/admin/pages/edit.html.erb +9 -0
- data/decidim-pages/app/views/decidim/pages/application/show.html.erb +16 -0
- data/decidim-pages/bin/rails +14 -0
- data/decidim-pages/config/i18n-tasks.yml +4 -0
- data/decidim-pages/config/locales/ca.yml +19 -0
- data/decidim-pages/config/locales/en.yml +20 -0
- data/decidim-pages/config/locales/es.yml +19 -0
- data/decidim-pages/db/migrate/20161116121353_create_decidim_pages.rb +11 -0
- data/decidim-pages/db/migrate/20161214150429_add_commentable_to_pages.rb +5 -0
- data/decidim-pages/decidim-pages.gemspec +21 -0
- data/decidim-pages/lib/decidim/pages.rb +12 -0
- data/decidim-pages/lib/decidim/pages/admin.rb +9 -0
- data/decidim-pages/lib/decidim/pages/admin_engine.rb +21 -0
- data/decidim-pages/lib/decidim/pages/engine.rb +15 -0
- data/decidim-pages/lib/decidim/pages/feature.rb +41 -0
- data/decidim-pages/lib/tasks/decidim/pages_tasks.rake +1 -0
- data/decidim-pages/spec/commands/create_page_spec.rb +46 -0
- data/decidim-pages/spec/commands/destroy_page_spec.rb +24 -0
- data/decidim-pages/spec/commands/update_page_spec.rb +57 -0
- data/decidim-pages/spec/factories.rb +10 -0
- data/decidim-pages/spec/features/admin_spec.rb +71 -0
- data/decidim-pages/spec/features/page_show_spec.rb +67 -0
- data/decidim-pages/spec/forms/page_form_spec.rb +63 -0
- data/decidim-pages/spec/models/page_spec.rb +18 -0
- data/decidim-pages/spec/spec_helper.rb +2 -0
- data/decidim-proposals/.gitignore +3 -0
- data/decidim-proposals/README.md +24 -0
- data/decidim-proposals/Rakefile +2 -0
- data/decidim-proposals/app/commands/decidim/proposals/admin/create_proposal.rb +43 -0
- data/decidim-proposals/app/commands/decidim/proposals/create_proposal.rb +42 -0
- data/decidim-proposals/app/controllers/decidim/proposals/admin/application_controller.rb +14 -0
- data/decidim-proposals/app/controllers/decidim/proposals/admin/proposals_controller.rb +37 -0
- data/decidim-proposals/app/controllers/decidim/proposals/application_controller.rb +13 -0
- data/decidim-proposals/app/controllers/decidim/proposals/proposals_controller.rb +41 -0
- data/decidim-proposals/app/forms/decidim/proposals/admin/proposal_form.rb +38 -0
- data/decidim-proposals/app/forms/decidim/proposals/proposal_form.rb +37 -0
- data/decidim-proposals/app/helpers/decidim/proposals/application_helper.rb +10 -0
- data/decidim-proposals/app/models/decidim/proposals/application_record.rb +9 -0
- data/decidim-proposals/app/models/decidim/proposals/proposal.rb +53 -0
- data/decidim-proposals/app/services/decidim/proposals/proposal_search.rb +36 -0
- data/decidim-proposals/app/views/decidim/proposals/admin/proposals/_form.html.erb +19 -0
- data/decidim-proposals/app/views/decidim/proposals/admin/proposals/index.html.erb +34 -0
- data/decidim-proposals/app/views/decidim/proposals/admin/proposals/new.html.erb +9 -0
- data/decidim-proposals/app/views/decidim/proposals/proposals/_proposal.html.erb +34 -0
- data/decidim-proposals/app/views/decidim/proposals/proposals/index.html.erb +23 -0
- data/decidim-proposals/app/views/decidim/proposals/proposals/new.html.erb +40 -0
- data/decidim-proposals/app/views/decidim/proposals/proposals/show.html.erb +37 -0
- data/decidim-proposals/bin/rails +14 -0
- data/decidim-proposals/config/i18n-tasks.yml +4 -0
- data/decidim-proposals/config/locales/ca.yml +46 -0
- data/decidim-proposals/config/locales/en.yml +47 -0
- data/decidim-proposals/config/locales/es.yml +46 -0
- data/decidim-proposals/db/migrate/20161212110850_create_decidim_proposals.rb +14 -0
- data/decidim-proposals/decidim-proposals.gemspec +22 -0
- data/decidim-proposals/lib/decidim/proposals.rb +12 -0
- data/decidim-proposals/lib/decidim/proposals/admin.rb +9 -0
- data/decidim-proposals/lib/decidim/proposals/admin_engine.rb +20 -0
- data/decidim-proposals/lib/decidim/proposals/engine.rb +18 -0
- data/decidim-proposals/lib/decidim/proposals/feature.rb +35 -0
- data/decidim-proposals/spec/commands/decidim/proposals/create_proposal_spec.rb +58 -0
- data/decidim-proposals/spec/factories.rb +18 -0
- data/decidim-proposals/spec/features/admin_manages_proposals_spec.rb +16 -0
- data/decidim-proposals/spec/features/process_admin_manages_proposals_spec.rb +17 -0
- data/decidim-proposals/spec/features/proposals_spec.rb +117 -0
- data/decidim-proposals/spec/forms/decidim/proposals/proposal_form_spec.rb +104 -0
- data/decidim-proposals/spec/lib/decidim/proposals/feature_spec.rb +31 -0
- data/decidim-proposals/spec/models/decidim/proposals/proposal_spec.rb +30 -0
- data/decidim-proposals/spec/services/decidim/proposals/proposal_search_spec.rb +62 -0
- data/decidim-proposals/spec/shared/admin_shared_context.rb +11 -0
- data/decidim-proposals/spec/shared/manage_proposals_examples.rb +40 -0
- data/decidim-proposals/spec/spec_helper.rb +2 -0
- data/decidim-system/Rakefile +0 -25
- data/decidim-system/app/assets/javascripts/decidim/system/application.js.es6 +6 -5
- data/decidim-system/app/assets/stylesheets/decidim/system/application.scss +7 -2
- data/decidim-system/app/commands/decidim/system/create_admin.rb +1 -1
- data/decidim-system/app/commands/decidim/system/create_default_pages.rb +43 -0
- data/decidim-system/app/commands/decidim/system/register_organization.rb +4 -2
- data/decidim-system/app/commands/decidim/system/update_admin.rb +1 -1
- data/decidim-system/app/commands/decidim/system/update_organization.rb +1 -2
- data/decidim-system/app/controllers/decidim/system/admins_controller.rb +4 -4
- data/decidim-system/app/controllers/decidim/system/application_controller.rb +1 -0
- data/decidim-system/app/controllers/decidim/system/organizations_controller.rb +4 -4
- data/decidim-system/app/forms/decidim/system/admin_form.rb +1 -1
- data/decidim-system/app/forms/decidim/system/register_organization_form.rb +6 -5
- data/decidim-system/app/forms/decidim/system/update_organization_form.rb +1 -3
- data/decidim-system/app/helpers/decidim/system/application_helper.rb +2 -0
- data/decidim-system/app/views/decidim/system/organizations/edit.html.erb +0 -4
- data/decidim-system/app/views/decidim/system/organizations/new.html.erb +23 -3
- data/decidim-system/config/i18n-tasks.yml +3 -1
- data/decidim-system/config/locales/ca.yml +15 -10
- data/decidim-system/config/locales/en.yml +6 -0
- data/decidim-system/config/locales/es.yml +11 -6
- data/decidim-system/db/seeds.rb +5 -2
- data/decidim-system/decidim-system.gemspec +6 -10
- data/decidim-system/lib/decidim/system/engine.rb +7 -2
- data/decidim-system/spec/commands/decidim/system/create_default_pages_spec.rb +30 -0
- data/decidim-system/spec/commands/decidim/system/register_organization_spec.rb +9 -3
- data/decidim-system/spec/features/organizations_spec.rb +4 -3
- data/decidim.gemspec +7 -8
- data/docs/features_and_components.md +45 -0
- data/docs/how_to_create_a_plugin.md +183 -0
- data/jsconfig.json +3 -0
- data/karma.conf.js +43 -0
- data/lib/decidim.rb +4 -0
- data/lib/generators/decidim/app_builder.rb +2 -0
- data/lib/generators/decidim/demo_generator.rb +27 -0
- data/lib/generators/decidim/docker_generator.rb +65 -0
- data/lib/generators/decidim/install_generator.rb +4 -25
- data/lib/generators/decidim/templates/Dockerfile.dev.erb +21 -0
- data/lib/generators/decidim/templates/app.json.erb +4 -1
- data/lib/generators/decidim/templates/initializer.rb +3 -0
- data/package.json +53 -8
- data/run_ci.sh +3 -0
- data/webpack.config.js +66 -0
- data/yarn.lock +4665 -456
- metadata +437 -35
- data/decidim-admin/LICENSE.txt +0 -619
- data/decidim-admin/app/models/decidim/admin/abilities/admin.rb +0 -21
- data/decidim-admin/spec/features/manage_participatory_process_steps_spec.rb +0 -151
- data/decidim-admin/spec/features/manage_participatory_processes_spec.rb +0 -227
- data/decidim-admin/spec/models/abilities/admin_spec.rb +0 -25
- data/decidim-admin/vendor/assets/javascripts/html.sortable.min.js +0 -2
- data/decidim-api/LICENSE.txt +0 -619
- data/decidim-api/app/types/decidim/api/process_step_type.rb +0 -26
- data/decidim-api/app/types/decidim/api/process_type.rb +0 -18
- data/decidim-api/app/types/decidim/api/query_type.rb +0 -19
- data/decidim-api/spec/schemas/schema_spec.rb +0 -38
- data/decidim-api/spec/support/type_helpers.rb +0 -46
- data/decidim-api/spec/types/process_step_type_spec.rb +0 -50
- data/decidim-api/spec/types/process_type_spec.rb +0 -39
- data/decidim-system/LICENSE.txt +0 -619
@@ -0,0 +1,153 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
RSpec.shared_examples "manage process steps examples" do
|
3
|
+
let(:active) { false }
|
4
|
+
let!(:process_step) do
|
5
|
+
create(
|
6
|
+
:participatory_process_step,
|
7
|
+
participatory_process: participatory_process,
|
8
|
+
active: active
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
before do
|
13
|
+
switch_to_host(organization.host)
|
14
|
+
login_as user, scope: :user
|
15
|
+
visit decidim_admin.participatory_process_path(participatory_process)
|
16
|
+
click_link "Steps"
|
17
|
+
end
|
18
|
+
|
19
|
+
it "displays all fields from a single participatory process" do
|
20
|
+
within "#steps table" do
|
21
|
+
click_link translated(process_step.title)
|
22
|
+
end
|
23
|
+
|
24
|
+
within "dl" do
|
25
|
+
expect(page).to have_content(stripped translated(process_step.title, locale: :en))
|
26
|
+
expect(page).to have_content(stripped translated(process_step.title, locale: :es))
|
27
|
+
expect(page).to have_content(stripped translated(process_step.title, locale: :ca))
|
28
|
+
expect(page).to have_content(stripped translated(process_step.short_description, locale: :en))
|
29
|
+
expect(page).to have_content(stripped translated(process_step.short_description, locale: :es))
|
30
|
+
expect(page).to have_content(stripped translated(process_step.short_description, locale: :ca))
|
31
|
+
expect(page).to have_content(stripped translated(process_step.description, locale: :en))
|
32
|
+
expect(page).to have_content(stripped translated(process_step.description, locale: :es))
|
33
|
+
expect(page).to have_content(stripped translated(process_step.description, locale: :ca))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "creates a new participatory_process" do
|
38
|
+
find("#steps .actions .new").click
|
39
|
+
|
40
|
+
within ".new_participatory_process_step" do
|
41
|
+
fill_in_i18n(
|
42
|
+
:participatory_process_step_title,
|
43
|
+
"#title-tabs",
|
44
|
+
en: "My participatory process step",
|
45
|
+
es: "Mi fase de proceso participativo",
|
46
|
+
ca: "La meva fase de procés participatiu"
|
47
|
+
)
|
48
|
+
fill_in_i18n_editor(
|
49
|
+
:participatory_process_step_short_description,
|
50
|
+
"#short_description-tabs",
|
51
|
+
en: "Short description",
|
52
|
+
es: "Descripción corta",
|
53
|
+
ca: "Descripció curta"
|
54
|
+
)
|
55
|
+
fill_in_i18n_editor(
|
56
|
+
:participatory_process_step_description,
|
57
|
+
"#description-tabs",
|
58
|
+
en: "A longer description",
|
59
|
+
es: "Descripción más larga",
|
60
|
+
ca: "Descripció més llarga"
|
61
|
+
)
|
62
|
+
fill_in :participatory_process_step_start_date, with: 1.months.ago
|
63
|
+
fill_in :participatory_process_step_end_date, with: 2.months.from_now
|
64
|
+
|
65
|
+
find("*[type=submit]").click
|
66
|
+
end
|
67
|
+
|
68
|
+
within ".flash" do
|
69
|
+
expect(page).to have_content("successfully")
|
70
|
+
end
|
71
|
+
|
72
|
+
within "#steps table" do
|
73
|
+
expect(page).to have_content("My participatory process step")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it "updates a participatory_process_step" do
|
78
|
+
within "#steps" do
|
79
|
+
within find("tr", text: translated(process_step.title)) do
|
80
|
+
click_link "Edit"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
within ".edit_participatory_process_step" do
|
85
|
+
fill_in_i18n(
|
86
|
+
:participatory_process_step_title,
|
87
|
+
"#title-tabs",
|
88
|
+
en: "My new title",
|
89
|
+
es: "Mi nuevo título",
|
90
|
+
ca: "El meu nou títol"
|
91
|
+
)
|
92
|
+
|
93
|
+
find("*[type=submit]").click
|
94
|
+
end
|
95
|
+
|
96
|
+
within ".flash" do
|
97
|
+
expect(page).to have_content("successfully")
|
98
|
+
end
|
99
|
+
|
100
|
+
within "#steps table" do
|
101
|
+
expect(page).to have_content("My new title")
|
102
|
+
click_link("My new title")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "deleting a participatory process step" do
|
107
|
+
let!(:process_step2) { create(:participatory_process_step, participatory_process: participatory_process) }
|
108
|
+
|
109
|
+
before do
|
110
|
+
visit current_path
|
111
|
+
end
|
112
|
+
|
113
|
+
it "deletes a participatory_process_step" do
|
114
|
+
within find("tr", text: translated(process_step2.title)) do
|
115
|
+
click_link "Destroy"
|
116
|
+
end
|
117
|
+
|
118
|
+
within ".flash" do
|
119
|
+
expect(page).to have_content("successfully")
|
120
|
+
end
|
121
|
+
|
122
|
+
within "#steps table" do
|
123
|
+
expect(page).to_not have_content(translated(process_step2.title))
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context "activating a step" do
|
129
|
+
it "activates a step" do
|
130
|
+
within find("tr", text: translated(process_step.title)) do
|
131
|
+
click_link "Activate"
|
132
|
+
end
|
133
|
+
|
134
|
+
within find("tr", text: translated(process_step.title)) do
|
135
|
+
expect(page).to have_content("Deactivate")
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context "deactivating a step" do
|
141
|
+
let(:active) { true }
|
142
|
+
|
143
|
+
it "deactivates a step" do
|
144
|
+
within find("tr", text: translated(process_step.title)) do
|
145
|
+
click_link "Deactivate"
|
146
|
+
end
|
147
|
+
|
148
|
+
within find("tr", text: translated(process_step.title)) do
|
149
|
+
expect(page).to have_content("Activate")
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
RSpec.shared_examples "manage processes examples" do
|
3
|
+
context "previewing processes" do
|
4
|
+
context "when the process is unpublished" do
|
5
|
+
let!(:participatory_process) { create(:participatory_process, :unpublished, organization: organization) }
|
6
|
+
|
7
|
+
it "allows the user to preview the unpublished process" do
|
8
|
+
within find("tr", text: translated(participatory_process.title)) do
|
9
|
+
click_link "Preview"
|
10
|
+
end
|
11
|
+
|
12
|
+
expect(current_path).to eq decidim.participatory_process_path(participatory_process)
|
13
|
+
expect(page).to have_content(translated(participatory_process.title))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when the process is published" do
|
18
|
+
let!(:participatory_process) { create(:participatory_process, organization: organization) }
|
19
|
+
|
20
|
+
it "allows the user to preview the unpublished process" do
|
21
|
+
within find("tr", text: translated(participatory_process.title)) do
|
22
|
+
click_link "Preview"
|
23
|
+
end
|
24
|
+
|
25
|
+
expect(current_path).to eq decidim.participatory_process_path(participatory_process)
|
26
|
+
expect(page).to have_content(translated(participatory_process.title))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "displays all fields from a single participatory process" do
|
32
|
+
within "table" do
|
33
|
+
click_link participatory_process.title["en"]
|
34
|
+
end
|
35
|
+
|
36
|
+
within "dl" do
|
37
|
+
expect(page).to have_content(stripped translated(participatory_process.title, locale: :en))
|
38
|
+
expect(page).to have_content(stripped translated(participatory_process.title, locale: :es))
|
39
|
+
expect(page).to have_content(stripped translated(participatory_process.title, locale: :ca))
|
40
|
+
expect(page).to have_content(stripped translated(participatory_process.subtitle, locale: :en))
|
41
|
+
expect(page).to have_content(stripped translated(participatory_process.subtitle, locale: :es))
|
42
|
+
expect(page).to have_content(stripped translated(participatory_process.subtitle, locale: :ca))
|
43
|
+
expect(page).to have_content(stripped translated(participatory_process.short_description, locale: :en))
|
44
|
+
expect(page).to have_content(stripped translated(participatory_process.short_description, locale: :es))
|
45
|
+
expect(page).to have_content(stripped translated(participatory_process.short_description, locale: :ca))
|
46
|
+
expect(page).to have_content(stripped translated(participatory_process.description, locale: :en))
|
47
|
+
expect(page).to have_content(stripped translated(participatory_process.description, locale: :es))
|
48
|
+
expect(page).to have_content(stripped translated(participatory_process.description, locale: :ca))
|
49
|
+
expect(page).to have_content(participatory_process.hashtag)
|
50
|
+
expect(page).to have_content(participatory_process.slug)
|
51
|
+
expect(page).to have_xpath("//img[@src=\"#{participatory_process.hero_image.url}\"]")
|
52
|
+
expect(page).to have_xpath("//img[@src=\"#{participatory_process.banner_image.url}\"]")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it "updates an participatory_process" do
|
57
|
+
click_link translated(participatory_process.title)
|
58
|
+
click_processes_menu_link "Settings"
|
59
|
+
|
60
|
+
within ".edit_participatory_process" do
|
61
|
+
fill_in_i18n(
|
62
|
+
:participatory_process_title,
|
63
|
+
"#title-tabs",
|
64
|
+
en: "My new title",
|
65
|
+
es: "Mi nuevo título",
|
66
|
+
ca: "El meu nou títol"
|
67
|
+
)
|
68
|
+
attach_file :participatory_process_banner_image, image3_path
|
69
|
+
|
70
|
+
find("*[type=submit]").click
|
71
|
+
end
|
72
|
+
|
73
|
+
within ".flash" do
|
74
|
+
expect(page).to have_content("successfully")
|
75
|
+
end
|
76
|
+
|
77
|
+
within "table" do
|
78
|
+
expect(page).to have_content("My new title")
|
79
|
+
click_link("My new title")
|
80
|
+
end
|
81
|
+
|
82
|
+
within "dl" do
|
83
|
+
expect(page).to_not have_css("img[src*='#{image2_filename}']")
|
84
|
+
expect(page).to have_css("img[src*='#{image3_filename}']")
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context "publishing a process" do
|
89
|
+
let!(:participatory_process) { create(:participatory_process, :unpublished, organization: organization) }
|
90
|
+
|
91
|
+
before do
|
92
|
+
click_link translated(participatory_process.title)
|
93
|
+
click_processes_menu_link "Settings"
|
94
|
+
end
|
95
|
+
|
96
|
+
it "publishes the process" do
|
97
|
+
click_link "Publish"
|
98
|
+
expect(page).to have_content("published successfully")
|
99
|
+
expect(page).to have_content("Unpublish")
|
100
|
+
expect(current_path).to eq decidim_admin.edit_participatory_process_path(participatory_process)
|
101
|
+
|
102
|
+
participatory_process.reload
|
103
|
+
expect(participatory_process).to be_published
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "unpublishing a process" do
|
108
|
+
let!(:participatory_process) { create(:participatory_process, organization: organization) }
|
109
|
+
|
110
|
+
before do
|
111
|
+
click_link translated(participatory_process.title)
|
112
|
+
click_processes_menu_link "Settings"
|
113
|
+
end
|
114
|
+
|
115
|
+
it "unpublishes the process" do
|
116
|
+
click_link "Unpublish"
|
117
|
+
expect(page).to have_content("unpublished successfully")
|
118
|
+
expect(page).to have_content("Publish")
|
119
|
+
expect(current_path).to eq decidim_admin.edit_participatory_process_path(participatory_process)
|
120
|
+
|
121
|
+
participatory_process.reload
|
122
|
+
expect(participatory_process).not_to be_published
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "when there are multiple organizations in the system" do
|
127
|
+
let!(:external_participatory_process) { create(:participatory_process) }
|
128
|
+
|
129
|
+
before do
|
130
|
+
visit decidim_admin.participatory_processes_path
|
131
|
+
end
|
132
|
+
|
133
|
+
it "doesn't let the admin manage processes form other organizations" do
|
134
|
+
within "table" do
|
135
|
+
expect(page).to_not have_content(external_participatory_process.title)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
RSpec.shared_context "participatory process admin" do
|
2
|
+
let(:organization) { create(:organization) }
|
3
|
+
let!(:user) { create(:user, :admin, :confirmed, organization: organization) }
|
4
|
+
let(:participatory_process) { create(:participatory_process, organization: organization) }
|
5
|
+
let(:process_admin) { create :user, :confirmed, organization: organization }
|
6
|
+
let!(:user_role) { create :participatory_process_user_role, user: process_admin, participatory_process: participatory_process }
|
7
|
+
let(:image1_filename) { "city.jpeg" }
|
8
|
+
let(:image1_path) do
|
9
|
+
File.join(File.dirname(__FILE__), "..", "..", "..", "decidim-dev", "spec", "support", image1_filename)
|
10
|
+
end
|
11
|
+
let(:image2_filename) { "city2.jpeg" }
|
12
|
+
let(:image2_path) do
|
13
|
+
File.join(File.dirname(__FILE__), "..", "..", "..", "decidim-dev", "spec", "support", image2_filename)
|
14
|
+
end
|
15
|
+
let(:image3_filename) { "city3.jpeg" }
|
16
|
+
let(:image3_path) do
|
17
|
+
File.join(File.dirname(__FILE__), "..", "..", "..", "decidim-dev", "spec", "support", image3_filename)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# A collection of methods to help dealing with processes menu links.
|
3
|
+
module ProcessesMenuLinksHelpers
|
4
|
+
# Clicks a link in the submenu of a participatory process navigation.
|
5
|
+
#
|
6
|
+
# text - a String with the name of the link that will be clicked
|
7
|
+
def click_processes_menu_link(text)
|
8
|
+
within ".row .tabs.vertical" do
|
9
|
+
click_link text
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
describe "decidim/admin/static_pages/_form" do
|
5
|
+
subject { render }
|
6
|
+
|
7
|
+
let(:form) do
|
8
|
+
Decidim::FormBuilder.new(
|
9
|
+
:static_page,
|
10
|
+
Decidim::Admin::StaticPageForm.new(slug: slug),
|
11
|
+
view,
|
12
|
+
{}
|
13
|
+
)
|
14
|
+
end
|
15
|
+
let(:ability) do
|
16
|
+
Decidim::Admin::Abilities::AdminUser.new(build(:user, :admin))
|
17
|
+
end
|
18
|
+
|
19
|
+
before do
|
20
|
+
view.extend CanCan::ControllerAdditions
|
21
|
+
allow(view).to receive(:form).and_return(form)
|
22
|
+
allow(view).to receive(:current_ability).and_return(ability)
|
23
|
+
end
|
24
|
+
|
25
|
+
context "with a default static page" do
|
26
|
+
let(:slug) { Decidim::StaticPage::DEFAULT_PAGES.sample }
|
27
|
+
it { is_expected.to_not include("slug") }
|
28
|
+
end
|
29
|
+
|
30
|
+
context "with a normal static page" do
|
31
|
+
let(:slug) { "foo" }
|
32
|
+
it { is_expected.to include("slug") }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,691 @@
|
|
1
|
+
;(function(root, factory) {
|
2
|
+
if (typeof define === 'function' && define.amd) {
|
3
|
+
define([], factory);
|
4
|
+
} else if (typeof exports === 'object') {
|
5
|
+
module.exports = factory();
|
6
|
+
} else {
|
7
|
+
root.sortable = factory();
|
8
|
+
}
|
9
|
+
}(this, function() {
|
10
|
+
/*
|
11
|
+
* HTML5 Sortable library
|
12
|
+
* https://github.com/voidberg/html5sortable
|
13
|
+
*
|
14
|
+
* Original code copyright 2012 Ali Farhadi.
|
15
|
+
* This version is mantained by Alexandru Badiu <andu@ctrlz.ro> & Lukas Oppermann <lukas@vea.re>
|
16
|
+
* jQuery-independent implementation by Nazar Mokrynskyi <nazar@mokrynskyi.com>
|
17
|
+
*
|
18
|
+
* Released under the MIT license.
|
19
|
+
*/
|
20
|
+
'use strict';
|
21
|
+
/*
|
22
|
+
* variables global to the plugin
|
23
|
+
*/
|
24
|
+
var dragging;
|
25
|
+
var draggingHeight;
|
26
|
+
var placeholders = [];
|
27
|
+
var sortables = [];
|
28
|
+
/**
|
29
|
+
* Get or set data on element
|
30
|
+
* @param {Element} element
|
31
|
+
* @param {string} key
|
32
|
+
* @param {*} value
|
33
|
+
* @return {*}
|
34
|
+
*/
|
35
|
+
var _data = function(element, key, value) {
|
36
|
+
if (value === undefined) {
|
37
|
+
return element && element.h5s && element.h5s.data && element.h5s.data[key];
|
38
|
+
} else {
|
39
|
+
element.h5s = element.h5s || {};
|
40
|
+
element.h5s.data = element.h5s.data || {};
|
41
|
+
element.h5s.data[key] = value;
|
42
|
+
}
|
43
|
+
};
|
44
|
+
/**
|
45
|
+
* Remove data from element
|
46
|
+
* @param {Element} element
|
47
|
+
*/
|
48
|
+
var _removeData = function(element) {
|
49
|
+
if (element.h5s) {
|
50
|
+
delete element.h5s.data;
|
51
|
+
}
|
52
|
+
};
|
53
|
+
/**
|
54
|
+
* Cross-browser shortcut for actual `Element.matches` method,
|
55
|
+
* which has vendor prefix in older browsers
|
56
|
+
*/
|
57
|
+
var matches;
|
58
|
+
switch (true) {
|
59
|
+
case 'matches' in window.Element.prototype:
|
60
|
+
matches = 'matches';
|
61
|
+
break;
|
62
|
+
case 'mozMatchesSelector' in window.Element.prototype:
|
63
|
+
matches = 'mozMatchesSelector';
|
64
|
+
break;
|
65
|
+
case 'msMatchesSelector' in window.Element.prototype:
|
66
|
+
matches = 'msMatchesSelector';
|
67
|
+
break;
|
68
|
+
case 'webkitMatchesSelector' in window.Element.prototype:
|
69
|
+
matches = 'webkitMatchesSelector';
|
70
|
+
break;
|
71
|
+
}
|
72
|
+
/**
|
73
|
+
* Filter only wanted nodes
|
74
|
+
* @param {Array|NodeList} nodes
|
75
|
+
* @param {Array/string} wanted
|
76
|
+
* @returns {Array}
|
77
|
+
*/
|
78
|
+
var _filter = function(nodes, wanted) {
|
79
|
+
if (!wanted) {
|
80
|
+
return Array.prototype.slice.call(nodes);
|
81
|
+
}
|
82
|
+
var result = [];
|
83
|
+
for (var i = 0; i < nodes.length; ++i) {
|
84
|
+
if (typeof wanted === 'string' && nodes[i][matches](wanted)) {
|
85
|
+
result.push(nodes[i]);
|
86
|
+
}
|
87
|
+
if (wanted.indexOf(nodes[i]) !== -1) {
|
88
|
+
result.push(nodes[i]);
|
89
|
+
}
|
90
|
+
}
|
91
|
+
return result;
|
92
|
+
};
|
93
|
+
/**
|
94
|
+
* @param {Array|Element} element
|
95
|
+
* @param {Array|string} event
|
96
|
+
* @param {Function} callback
|
97
|
+
*/
|
98
|
+
var _on = function(element, event, callback) {
|
99
|
+
if (element instanceof Array) {
|
100
|
+
for (var i = 0; i < element.length; ++i) {
|
101
|
+
_on(element[i], event, callback);
|
102
|
+
}
|
103
|
+
return;
|
104
|
+
}
|
105
|
+
element.addEventListener(event, callback);
|
106
|
+
element.h5s = element.h5s || {};
|
107
|
+
element.h5s.events = element.h5s.events || {};
|
108
|
+
element.h5s.events[event] = callback;
|
109
|
+
};
|
110
|
+
/**
|
111
|
+
* @param {Array|Element} element
|
112
|
+
* @param {Array|string} event
|
113
|
+
*/
|
114
|
+
var _off = function(element, event) {
|
115
|
+
if (element instanceof Array) {
|
116
|
+
for (var i = 0; i < element.length; ++i) {
|
117
|
+
_off(element[i], event);
|
118
|
+
}
|
119
|
+
return;
|
120
|
+
}
|
121
|
+
if (element.h5s && element.h5s.events && element.h5s.events[event]) {
|
122
|
+
element.removeEventListener(event, element.h5s.events[event]);
|
123
|
+
delete element.h5s.events[event];
|
124
|
+
}
|
125
|
+
};
|
126
|
+
/**
|
127
|
+
* @param {Array|Element} element
|
128
|
+
* @param {string} attribute
|
129
|
+
* @param {*} value
|
130
|
+
*/
|
131
|
+
var _attr = function(element, attribute, value) {
|
132
|
+
if (element instanceof Array) {
|
133
|
+
for (var i = 0; i < element.length; ++i) {
|
134
|
+
_attr(element[i], attribute, value);
|
135
|
+
}
|
136
|
+
return;
|
137
|
+
}
|
138
|
+
element.setAttribute(attribute, value);
|
139
|
+
};
|
140
|
+
/**
|
141
|
+
* @param {Array|Element} element
|
142
|
+
* @param {string} attribute
|
143
|
+
*/
|
144
|
+
var _removeAttr = function(element, attribute) {
|
145
|
+
if (element instanceof Array) {
|
146
|
+
for (var i = 0; i < element.length; ++i) {
|
147
|
+
_removeAttr(element[i], attribute);
|
148
|
+
}
|
149
|
+
return;
|
150
|
+
}
|
151
|
+
element.removeAttribute(attribute);
|
152
|
+
};
|
153
|
+
/**
|
154
|
+
* @param {Element} element
|
155
|
+
* @returns {{left: *, top: *}}
|
156
|
+
*/
|
157
|
+
var _offset = function(element) {
|
158
|
+
var rect = element.getClientRects()[0];
|
159
|
+
return {
|
160
|
+
left: rect.left + window.scrollX,
|
161
|
+
top: rect.top + window.scrollY
|
162
|
+
};
|
163
|
+
};
|
164
|
+
/*
|
165
|
+
* remove event handlers from items
|
166
|
+
* @param {Array|NodeList} items
|
167
|
+
*/
|
168
|
+
var _removeItemEvents = function(items) {
|
169
|
+
_off(items, 'dragstart');
|
170
|
+
_off(items, 'dragend');
|
171
|
+
_off(items, 'selectstart');
|
172
|
+
_off(items, 'dragover');
|
173
|
+
_off(items, 'dragenter');
|
174
|
+
_off(items, 'drop');
|
175
|
+
};
|
176
|
+
/*
|
177
|
+
* Remove event handlers from sortable
|
178
|
+
* @param {Element} sortable a single sortable
|
179
|
+
*/
|
180
|
+
var _removeSortableEvents = function(sortable) {
|
181
|
+
_off(sortable, 'dragover');
|
182
|
+
_off(sortable, 'dragenter');
|
183
|
+
_off(sortable, 'drop');
|
184
|
+
};
|
185
|
+
/*
|
186
|
+
* Attach ghost to dataTransfer object
|
187
|
+
* @param {Event} original event
|
188
|
+
* @param {object} ghost-object with item, x and y coordinates
|
189
|
+
*/
|
190
|
+
var _attachGhost = function(event, ghost) {
|
191
|
+
// this needs to be set for HTML5 drag & drop to work
|
192
|
+
event.dataTransfer.effectAllowed = 'move';
|
193
|
+
event.dataTransfer.setData('text', '');
|
194
|
+
|
195
|
+
// check if setDragImage method is available
|
196
|
+
if (event.dataTransfer.setDragImage) {
|
197
|
+
event.dataTransfer.setDragImage(ghost.draggedItem, ghost.x, ghost.y);
|
198
|
+
}
|
199
|
+
};
|
200
|
+
/**
|
201
|
+
* _addGhostPos clones the dragged item and adds it as a Ghost item
|
202
|
+
* @param {Event} event - the event fired when dragstart is triggered
|
203
|
+
* @param {object} ghost - .draggedItem = Element
|
204
|
+
*/
|
205
|
+
var _addGhostPos = function(event, ghost) {
|
206
|
+
if (!ghost.x) {
|
207
|
+
ghost.x = parseInt(event.pageX - _offset(ghost.draggedItem).left);
|
208
|
+
}
|
209
|
+
if (!ghost.y) {
|
210
|
+
ghost.y = parseInt(event.pageY - _offset(ghost.draggedItem).top);
|
211
|
+
}
|
212
|
+
return ghost;
|
213
|
+
};
|
214
|
+
/**
|
215
|
+
* _makeGhost decides which way to make a ghost and passes it to attachGhost
|
216
|
+
* @param {Element} draggedItem - the item that the user drags
|
217
|
+
*/
|
218
|
+
var _makeGhost = function(draggedItem) {
|
219
|
+
return {
|
220
|
+
draggedItem: draggedItem
|
221
|
+
};
|
222
|
+
};
|
223
|
+
/**
|
224
|
+
* _getGhost constructs ghost and attaches it to dataTransfer
|
225
|
+
* @param {Event} event - the original drag event object
|
226
|
+
* @param {Element} draggedItem - the item that the user drags
|
227
|
+
*/
|
228
|
+
// TODO: could draggedItem be replaced by event.target in all instances
|
229
|
+
var _getGhost = function(event, draggedItem) {
|
230
|
+
// add ghost item & draggedItem to ghost object
|
231
|
+
var ghost = _makeGhost(draggedItem);
|
232
|
+
// attach ghost position
|
233
|
+
ghost = _addGhostPos(event, ghost);
|
234
|
+
// attach ghost to dataTransfer
|
235
|
+
_attachGhost(event, ghost);
|
236
|
+
};
|
237
|
+
/*
|
238
|
+
* Remove data from sortable
|
239
|
+
* @param {Element} sortable a single sortable
|
240
|
+
*/
|
241
|
+
var _removeSortableData = function(sortable) {
|
242
|
+
_removeData(sortable);
|
243
|
+
_removeAttr(sortable, 'aria-dropeffect');
|
244
|
+
};
|
245
|
+
/*
|
246
|
+
* Remove data from items
|
247
|
+
* @param {Array|Element} items
|
248
|
+
*/
|
249
|
+
var _removeItemData = function(items) {
|
250
|
+
_removeAttr(items, 'aria-grabbed');
|
251
|
+
_removeAttr(items, 'draggable');
|
252
|
+
_removeAttr(items, 'role');
|
253
|
+
};
|
254
|
+
/*
|
255
|
+
* Check if two lists are connected
|
256
|
+
* @param {Element} curList
|
257
|
+
* @param {Element} destList
|
258
|
+
*/
|
259
|
+
var _listsConnected = function(curList, destList) {
|
260
|
+
if (curList === destList) {
|
261
|
+
return true;
|
262
|
+
}
|
263
|
+
if (_data(curList, 'connectWith') !== undefined) {
|
264
|
+
return _data(curList, 'connectWith') === _data(destList, 'connectWith');
|
265
|
+
}
|
266
|
+
return false;
|
267
|
+
};
|
268
|
+
var _getHandles = function(items, handle) {
|
269
|
+
var result = [];
|
270
|
+
var handles;
|
271
|
+
if (!handle) {
|
272
|
+
return items;
|
273
|
+
}
|
274
|
+
for (var i = 0; i < items.length; ++i) {
|
275
|
+
handles = items[i].querySelectorAll(handle);
|
276
|
+
result = result.concat(Array.prototype.slice.call(handles));
|
277
|
+
}
|
278
|
+
return result;
|
279
|
+
};
|
280
|
+
/*
|
281
|
+
* Destroy the sortable
|
282
|
+
* @param {Element} sortableElement a single sortable
|
283
|
+
*/
|
284
|
+
var _destroySortable = function(sortableElement) {
|
285
|
+
var opts = _data(sortableElement, 'opts') || {};
|
286
|
+
var items = _filter(sortableElement.children, opts.items);
|
287
|
+
var handles = _getHandles(items, opts.handle);
|
288
|
+
// remove event handlers & data from sortable
|
289
|
+
_removeSortableEvents(sortableElement);
|
290
|
+
_removeSortableData(sortableElement);
|
291
|
+
// remove event handlers & data from items
|
292
|
+
_off(handles, 'mousedown');
|
293
|
+
_removeItemEvents(items);
|
294
|
+
_removeItemData(items);
|
295
|
+
};
|
296
|
+
/*
|
297
|
+
* Enable the sortable
|
298
|
+
* @param {Element} sortableElement a single sortable
|
299
|
+
*/
|
300
|
+
var _enableSortable = function(sortableElement) {
|
301
|
+
var opts = _data(sortableElement, 'opts');
|
302
|
+
var items = _filter(sortableElement.children, opts.items);
|
303
|
+
var handles = _getHandles(items, opts.handle);
|
304
|
+
_attr(sortableElement, 'aria-dropeffect', 'move');
|
305
|
+
_attr(handles, 'draggable', 'true');
|
306
|
+
// IE FIX for ghost
|
307
|
+
// can be disabled as it has the side effect that other events
|
308
|
+
// (e.g. click) will be ignored
|
309
|
+
var spanEl = (document || window.document).createElement('span');
|
310
|
+
if (typeof spanEl.dragDrop === 'function' && !opts.disableIEFix) {
|
311
|
+
_on(handles, 'mousedown', function() {
|
312
|
+
if (items.indexOf(this) !== -1) {
|
313
|
+
this.dragDrop();
|
314
|
+
} else {
|
315
|
+
var parent = this.parentElement;
|
316
|
+
while (items.indexOf(parent) === -1) {
|
317
|
+
parent = parent.parentElement;
|
318
|
+
}
|
319
|
+
parent.dragDrop();
|
320
|
+
}
|
321
|
+
});
|
322
|
+
}
|
323
|
+
};
|
324
|
+
/*
|
325
|
+
* Disable the sortable
|
326
|
+
* @param {Element} sortableElement a single sortable
|
327
|
+
*/
|
328
|
+
var _disableSortable = function(sortableElement) {
|
329
|
+
var opts = _data(sortableElement, 'opts');
|
330
|
+
var items = _filter(sortableElement.children, opts.items);
|
331
|
+
var handles = _getHandles(items, opts.handle);
|
332
|
+
_attr(sortableElement, 'aria-dropeffect', 'none');
|
333
|
+
_attr(handles, 'draggable', 'false');
|
334
|
+
_off(handles, 'mousedown');
|
335
|
+
};
|
336
|
+
/*
|
337
|
+
* Reload the sortable
|
338
|
+
* @param {Element} sortableElement a single sortable
|
339
|
+
* @description events need to be removed to not be double bound
|
340
|
+
*/
|
341
|
+
var _reloadSortable = function(sortableElement) {
|
342
|
+
var opts = _data(sortableElement, 'opts');
|
343
|
+
var items = _filter(sortableElement.children, opts.items);
|
344
|
+
var handles = _getHandles(items, opts.handle);
|
345
|
+
// remove event handlers from items
|
346
|
+
_removeItemEvents(items);
|
347
|
+
_off(handles, 'mousedown');
|
348
|
+
// remove event handlers from sortable
|
349
|
+
_removeSortableEvents(sortableElement);
|
350
|
+
};
|
351
|
+
/**
|
352
|
+
* Get position of the element relatively to its sibling elements
|
353
|
+
* @param {Element} element
|
354
|
+
* @returns {number}
|
355
|
+
*/
|
356
|
+
var _index = function(element) {
|
357
|
+
if (!element.parentElement) {
|
358
|
+
return 0;
|
359
|
+
}
|
360
|
+
return Array.prototype.indexOf.call(element.parentElement.children, element);
|
361
|
+
};
|
362
|
+
/**
|
363
|
+
* Whether element is in DOM
|
364
|
+
* @param {Element} element
|
365
|
+
* @returns {boolean}
|
366
|
+
*/
|
367
|
+
var _attached = function(element) {
|
368
|
+
return !!element.parentNode;
|
369
|
+
};
|
370
|
+
/**
|
371
|
+
* Convert HTML string into DOM element
|
372
|
+
* @param {Element|string} html
|
373
|
+
* @returns {Element}
|
374
|
+
*/
|
375
|
+
var _html2element = function(html) {
|
376
|
+
if (typeof html !== 'string') {
|
377
|
+
return html;
|
378
|
+
}
|
379
|
+
var div = document.createElement('div');
|
380
|
+
div.innerHTML = html;
|
381
|
+
return div.firstChild;
|
382
|
+
};
|
383
|
+
/**
|
384
|
+
* Insert before target
|
385
|
+
* @param {Element} target
|
386
|
+
* @param {Element} element
|
387
|
+
*/
|
388
|
+
var _before = function(target, element) {
|
389
|
+
target.parentElement.insertBefore(
|
390
|
+
element,
|
391
|
+
target
|
392
|
+
);
|
393
|
+
};
|
394
|
+
/**
|
395
|
+
* Insert after target
|
396
|
+
* @param {Element} target
|
397
|
+
* @param {Element} element
|
398
|
+
*/
|
399
|
+
var _after = function(target, element) {
|
400
|
+
target.parentElement.insertBefore(
|
401
|
+
element,
|
402
|
+
target.nextElementSibling
|
403
|
+
);
|
404
|
+
};
|
405
|
+
/**
|
406
|
+
* Detach element from DOM
|
407
|
+
* @param {Element} element
|
408
|
+
*/
|
409
|
+
var _detach = function(element) {
|
410
|
+
if (element.parentNode) {
|
411
|
+
element.parentNode.removeChild(element);
|
412
|
+
}
|
413
|
+
};
|
414
|
+
/**
|
415
|
+
* Make native event that can be dispatched afterwards
|
416
|
+
* @param {string} name
|
417
|
+
* @param {object} detail
|
418
|
+
* @returns {CustomEvent}
|
419
|
+
*/
|
420
|
+
var _makeEvent = function(name, detail) {
|
421
|
+
var e = document.createEvent('Event');
|
422
|
+
if (detail) {
|
423
|
+
e.detail = detail;
|
424
|
+
}
|
425
|
+
e.initEvent(name, false, true);
|
426
|
+
return e;
|
427
|
+
};
|
428
|
+
/**
|
429
|
+
* @param {Element} sortableElement
|
430
|
+
* @param {CustomEvent} event
|
431
|
+
*/
|
432
|
+
var _dispatchEventOnConnected = function(sortableElement, event) {
|
433
|
+
sortables.forEach(function(target) {
|
434
|
+
if (_listsConnected(sortableElement, target)) {
|
435
|
+
target.dispatchEvent(event);
|
436
|
+
}
|
437
|
+
});
|
438
|
+
};
|
439
|
+
/*
|
440
|
+
* Public sortable object
|
441
|
+
* @param {Array|NodeList} sortableElements
|
442
|
+
* @param {object|string} options|method
|
443
|
+
*/
|
444
|
+
var sortable = function(sortableElements, options) {
|
445
|
+
|
446
|
+
var method = String(options);
|
447
|
+
|
448
|
+
options = (function(options) {
|
449
|
+
var result = {
|
450
|
+
connectWith: false,
|
451
|
+
placeholder: null,
|
452
|
+
// dragImage can be null or a Element
|
453
|
+
dragImage: null,
|
454
|
+
disableIEFix: false,
|
455
|
+
placeholderClass: 'sortable-placeholder',
|
456
|
+
draggingClass: 'sortable-dragging',
|
457
|
+
hoverClass: false
|
458
|
+
};
|
459
|
+
for (var option in options) {
|
460
|
+
result[option] = options[option];
|
461
|
+
}
|
462
|
+
return result;
|
463
|
+
})(options);
|
464
|
+
|
465
|
+
if (typeof sortableElements === 'string') {
|
466
|
+
sortableElements = document.querySelectorAll(sortableElements);
|
467
|
+
}
|
468
|
+
|
469
|
+
if (sortableElements instanceof window.Element) {
|
470
|
+
sortableElements = [sortableElements];
|
471
|
+
}
|
472
|
+
|
473
|
+
sortableElements = Array.prototype.slice.call(sortableElements);
|
474
|
+
|
475
|
+
/* TODO: maxstatements should be 25, fix and remove line below */
|
476
|
+
/*jshint maxstatements:false */
|
477
|
+
sortableElements.forEach(function(sortableElement) {
|
478
|
+
|
479
|
+
if (/enable|disable|destroy/.test(method)) {
|
480
|
+
sortable[method](sortableElement);
|
481
|
+
return;
|
482
|
+
}
|
483
|
+
|
484
|
+
// get options & set options on sortable
|
485
|
+
options = _data(sortableElement, 'opts') || options;
|
486
|
+
_data(sortableElement, 'opts', options);
|
487
|
+
// reset sortable
|
488
|
+
_reloadSortable(sortableElement);
|
489
|
+
// initialize
|
490
|
+
var items = _filter(sortableElement.children, options.items);
|
491
|
+
var index;
|
492
|
+
var startParent;
|
493
|
+
var placeholder = options.placeholder;
|
494
|
+
if (!placeholder) {
|
495
|
+
placeholder = document.createElement(
|
496
|
+
/^ul|ol$/i.test(sortableElement.tagName) ? 'li' : 'div'
|
497
|
+
);
|
498
|
+
}
|
499
|
+
placeholder = _html2element(placeholder);
|
500
|
+
placeholder.classList.add.apply(
|
501
|
+
placeholder.classList,
|
502
|
+
options.placeholderClass.split(' ')
|
503
|
+
);
|
504
|
+
|
505
|
+
// setup sortable ids
|
506
|
+
if (!sortableElement.getAttribute('data-sortable-id')) {
|
507
|
+
var id = sortables.length;
|
508
|
+
sortables[id] = sortableElement;
|
509
|
+
_attr(sortableElement, 'data-sortable-id', id);
|
510
|
+
_attr(items, 'data-item-sortable-id', id);
|
511
|
+
}
|
512
|
+
|
513
|
+
_data(sortableElement, 'items', options.items);
|
514
|
+
placeholders.push(placeholder);
|
515
|
+
if (options.connectWith) {
|
516
|
+
_data(sortableElement, 'connectWith', options.connectWith);
|
517
|
+
}
|
518
|
+
|
519
|
+
_enableSortable(sortableElement);
|
520
|
+
_attr(items, 'role', 'option');
|
521
|
+
_attr(items, 'aria-grabbed', 'false');
|
522
|
+
|
523
|
+
// Mouse over class
|
524
|
+
if (options.hoverClass) {
|
525
|
+
var hoverClass = 'sortable-over';
|
526
|
+
if (typeof options.hoverClass === 'string') {
|
527
|
+
hoverClass = options.hoverClass;
|
528
|
+
}
|
529
|
+
|
530
|
+
_on(items, 'mouseenter', function() {
|
531
|
+
this.classList.add(hoverClass);
|
532
|
+
});
|
533
|
+
_on(items, 'mouseleave', function() {
|
534
|
+
this.classList.remove(hoverClass);
|
535
|
+
});
|
536
|
+
}
|
537
|
+
|
538
|
+
// Handle drag events on draggable items
|
539
|
+
_on(items, 'dragstart', function(e) {
|
540
|
+
e.stopImmediatePropagation();
|
541
|
+
|
542
|
+
if (options.dragImage) {
|
543
|
+
_attachGhost(e, {
|
544
|
+
draggedItem: options.dragImage,
|
545
|
+
x: 0,
|
546
|
+
y: 0
|
547
|
+
});
|
548
|
+
console.log('WARNING: dragImage option is deprecated' +
|
549
|
+
' and will be removed in the future!');
|
550
|
+
} else {
|
551
|
+
// add transparent clone or other ghost to cursor
|
552
|
+
_getGhost(e, this);
|
553
|
+
}
|
554
|
+
// cache selsection & add attr for dragging
|
555
|
+
this.classList.add(options.draggingClass);
|
556
|
+
dragging = this;
|
557
|
+
_attr(dragging, 'aria-grabbed', 'true');
|
558
|
+
// grab values
|
559
|
+
index = _index(dragging);
|
560
|
+
draggingHeight = parseInt(window.getComputedStyle(dragging).height);
|
561
|
+
startParent = this.parentElement;
|
562
|
+
// dispatch sortstart event on each element in group
|
563
|
+
_dispatchEventOnConnected(sortableElement, _makeEvent('sortstart', {
|
564
|
+
item: dragging,
|
565
|
+
placeholder: placeholder,
|
566
|
+
startparent: startParent
|
567
|
+
}));
|
568
|
+
});
|
569
|
+
// Handle drag events on draggable items
|
570
|
+
_on(items, 'dragend', function() {
|
571
|
+
var newParent;
|
572
|
+
if (!dragging) {
|
573
|
+
return;
|
574
|
+
}
|
575
|
+
// remove dragging attributes and show item
|
576
|
+
dragging.classList.remove(options.draggingClass);
|
577
|
+
_attr(dragging, 'aria-grabbed', 'false');
|
578
|
+
dragging.style.display = dragging.oldDisplay;
|
579
|
+
delete dragging.oldDisplay;
|
580
|
+
|
581
|
+
placeholders.forEach(_detach);
|
582
|
+
newParent = this.parentElement;
|
583
|
+
_dispatchEventOnConnected(sortableElement, _makeEvent('sortstop', {
|
584
|
+
item: dragging,
|
585
|
+
startparent: startParent
|
586
|
+
}));
|
587
|
+
if (index !== _index(dragging) || startParent !== newParent) {
|
588
|
+
_dispatchEventOnConnected(sortableElement, _makeEvent('sortupdate', {
|
589
|
+
item: dragging,
|
590
|
+
index: _filter(newParent.children, _data(newParent, 'items'))
|
591
|
+
.indexOf(dragging),
|
592
|
+
oldindex: items.indexOf(dragging),
|
593
|
+
elementIndex: _index(dragging),
|
594
|
+
oldElementIndex: index,
|
595
|
+
startparent: startParent,
|
596
|
+
endparent: newParent
|
597
|
+
}));
|
598
|
+
}
|
599
|
+
dragging = null;
|
600
|
+
draggingHeight = null;
|
601
|
+
});
|
602
|
+
// Handle drop event on sortable & placeholder
|
603
|
+
// TODO: REMOVE placeholder?????
|
604
|
+
_on([sortableElement, placeholder], 'drop', function(e) {
|
605
|
+
var visiblePlaceholder;
|
606
|
+
if (!_listsConnected(sortableElement, dragging.parentElement)) {
|
607
|
+
return;
|
608
|
+
}
|
609
|
+
|
610
|
+
e.preventDefault();
|
611
|
+
e.stopPropagation();
|
612
|
+
visiblePlaceholder = placeholders.filter(_attached)[0];
|
613
|
+
_after(visiblePlaceholder, dragging);
|
614
|
+
dragging.dispatchEvent(_makeEvent('dragend'));
|
615
|
+
});
|
616
|
+
|
617
|
+
// Handle dragover and dragenter events on draggable items
|
618
|
+
var onDragOverEnter = function(e) {
|
619
|
+
if (!_listsConnected(sortableElement, dragging.parentElement)) {
|
620
|
+
return;
|
621
|
+
}
|
622
|
+
|
623
|
+
e.preventDefault();
|
624
|
+
e.stopPropagation();
|
625
|
+
e.dataTransfer.dropEffect = 'move';
|
626
|
+
if (items.indexOf(this) !== -1) {
|
627
|
+
var thisHeight = parseInt(window.getComputedStyle(this).height);
|
628
|
+
var placeholderIndex = _index(placeholder);
|
629
|
+
var thisIndex = _index(this);
|
630
|
+
if (options.forcePlaceholderSize) {
|
631
|
+
placeholder.style.height = draggingHeight + 'px';
|
632
|
+
}
|
633
|
+
|
634
|
+
// Check if `this` is bigger than the draggable. If it is, we have to define a dead zone to prevent flickering
|
635
|
+
if (thisHeight > draggingHeight) {
|
636
|
+
// Dead zone?
|
637
|
+
var deadZone = thisHeight - draggingHeight;
|
638
|
+
var offsetTop = _offset(this).top;
|
639
|
+
if (placeholderIndex < thisIndex &&
|
640
|
+
e.pageY < offsetTop + deadZone) {
|
641
|
+
return;
|
642
|
+
}
|
643
|
+
if (placeholderIndex > thisIndex &&
|
644
|
+
e.pageY > offsetTop + thisHeight - deadZone) {
|
645
|
+
return;
|
646
|
+
}
|
647
|
+
}
|
648
|
+
|
649
|
+
if (dragging.oldDisplay === undefined) {
|
650
|
+
dragging.oldDisplay = dragging.style.display;
|
651
|
+
}
|
652
|
+
dragging.style.display = 'none';
|
653
|
+
if (placeholderIndex < thisIndex) {
|
654
|
+
_after(this, placeholder);
|
655
|
+
} else {
|
656
|
+
_before(this, placeholder);
|
657
|
+
}
|
658
|
+
// Intentionally violated chaining, it is more complex otherwise
|
659
|
+
placeholders
|
660
|
+
.filter(function(element) {return element !== placeholder;})
|
661
|
+
.forEach(_detach);
|
662
|
+
} else {
|
663
|
+
if (placeholders.indexOf(this) === -1 &&
|
664
|
+
!_filter(this.children, options.items).length) {
|
665
|
+
placeholders.forEach(_detach);
|
666
|
+
this.appendChild(placeholder);
|
667
|
+
}
|
668
|
+
}
|
669
|
+
};
|
670
|
+
_on(items.concat(sortableElement), 'dragover', onDragOverEnter);
|
671
|
+
_on(items.concat(sortableElement), 'dragenter', onDragOverEnter);
|
672
|
+
});
|
673
|
+
|
674
|
+
return sortableElements;
|
675
|
+
};
|
676
|
+
|
677
|
+
sortable.destroy = function(sortableElement) {
|
678
|
+
_destroySortable(sortableElement);
|
679
|
+
};
|
680
|
+
|
681
|
+
sortable.enable = function(sortableElement) {
|
682
|
+
_enableSortable(sortableElement);
|
683
|
+
};
|
684
|
+
|
685
|
+
sortable.disable = function(sortableElement) {
|
686
|
+
_disableSortable(sortableElement);
|
687
|
+
};
|
688
|
+
|
689
|
+
|
690
|
+
return sortable;
|
691
|
+
}));
|