decidim 0.0.6 → 0.0.7
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 +2 -1
- data/.ruby-version +1 -1
- data/.travis.yml +4 -6
- data/Dockerfile +2 -2
- data/Gemfile +1 -1
- data/Gemfile.lock +48 -48
- data/README.md +6 -1
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_decidim.scss +9 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_variables.scss +7 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/application.scss +2 -19
- data/decidim-admin/app/assets/stylesheets/decidim/admin/extra/_categories.scss +5 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/{_email_preview.scss → extra/_email_preview.scss} +0 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/{_login.scss → extra/_login.scss} +0 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/extra/_select_multiple.scss +3 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/extra/_title_bar.scss +5 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_action-icon.scss +13 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_buttons.scss +44 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_callouts.scss +32 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_cards.scss +36 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_char-counter.scss +20 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_component-counter.scss +17 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_forms.scss +80 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_icons.scss +65 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_layout.scss +67 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_main-nav.scss +41 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_modules.scss +24 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_process-header.scss +11 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_secondary-nav.scss +95 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_table-list.scss +78 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_tabs.scss +49 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_title-bar.scss +32 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_typography.scss +15 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_user-login.scss +23 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/utils/_fontface.scss +27 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/utils/_helpers.scss +25 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/utils/_keyframes.scss +21 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/utils/_mixins.scss +20 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/utils/_settings.scss +590 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/utils/_toggle-expand.scss +8 -0
- data/decidim-admin/app/commands/decidim/admin/create_attachment.rb +13 -4
- data/decidim-admin/app/commands/decidim/admin/update_participatory_process.rb +3 -3
- data/decidim-admin/app/commands/decidim/admin/update_participatory_process_admin.rb +40 -0
- data/decidim-admin/app/controllers/decidim/admin/application_controller.rb +7 -1
- data/decidim-admin/app/controllers/decidim/admin/newsletters_controller.rb +1 -1
- data/decidim-admin/app/controllers/decidim/admin/organization_controller.rb +2 -0
- data/decidim-admin/app/controllers/decidim/admin/participatory_process_user_roles_controller.rb +29 -0
- data/decidim-admin/app/controllers/decidim/admin/participatory_processes_controller.rb +2 -2
- data/decidim-admin/app/controllers/decidim/admin/scopes_controller.rb +2 -0
- data/decidim-admin/app/controllers/decidim/admin/static_pages_controller.rb +2 -0
- data/decidim-admin/app/controllers/decidim/admin/user_groups_controller.rb +3 -1
- data/decidim-admin/app/controllers/decidim/admin/users_controller.rb +1 -1
- data/decidim-admin/app/helpers/decidim/admin/application_helper.rb +8 -0
- data/decidim-admin/app/helpers/decidim/admin/icon_link_helper.rb +30 -0
- data/decidim-admin/app/jobs/decidim/admin/newsletter_job.rb +1 -1
- data/decidim-admin/app/queries/decidim/admin/process_admin_roles_for_process.rb +1 -1
- data/decidim-admin/app/views/decidim/admin/attachments/_form.html.erb +29 -8
- data/decidim-admin/app/views/decidim/admin/attachments/edit.html.erb +3 -5
- data/decidim-admin/app/views/decidim/admin/attachments/index.html.erb +45 -35
- data/decidim-admin/app/views/decidim/admin/attachments/new.html.erb +3 -5
- data/decidim-admin/app/views/decidim/admin/categories/_form.html.erb +18 -10
- data/decidim-admin/app/views/decidim/admin/categories/edit.html.erb +3 -5
- data/decidim-admin/app/views/decidim/admin/categories/index.html.erb +57 -42
- data/decidim-admin/app/views/decidim/admin/categories/new.html.erb +3 -5
- data/decidim-admin/app/views/decidim/admin/dashboard/show.html.erb +6 -3
- data/decidim-admin/app/views/decidim/admin/features/_feature.html.erb +11 -11
- data/decidim-admin/app/views/decidim/admin/features/_form.html.erb +56 -48
- data/decidim-admin/app/views/decidim/admin/features/edit.html.erb +3 -5
- data/decidim-admin/app/views/decidim/admin/features/index.html.erb +21 -19
- data/decidim-admin/app/views/decidim/admin/features/new.html.erb +3 -4
- data/decidim-admin/app/views/decidim/admin/moderations/index.html.erb +71 -61
- data/decidim-admin/app/views/decidim/admin/newsletters/_form.html.erb +7 -1
- data/decidim-admin/app/views/decidim/admin/newsletters/edit.html.erb +10 -8
- data/decidim-admin/app/views/decidim/admin/newsletters/index.html.erb +50 -43
- data/decidim-admin/app/views/decidim/admin/newsletters/new.html.erb +10 -8
- data/decidim-admin/app/views/decidim/admin/newsletters/show.html.erb +20 -12
- data/decidim-admin/app/views/decidim/admin/organization/_form.html.erb +98 -62
- data/decidim-admin/app/views/decidim/admin/organization/edit.html.erb +11 -8
- data/decidim-admin/app/views/decidim/admin/participatory_process_groups/_form.html.erb +4 -4
- data/decidim-admin/app/views/decidim/admin/participatory_process_groups/edit.html.erb +15 -9
- data/decidim-admin/app/views/decidim/admin/participatory_process_groups/index.html.erb +37 -35
- data/decidim-admin/app/views/decidim/admin/participatory_process_groups/new.html.erb +10 -8
- data/decidim-admin/app/views/decidim/admin/participatory_process_steps/_form.html.erb +21 -11
- data/decidim-admin/app/views/decidim/admin/participatory_process_steps/edit.html.erb +3 -4
- data/decidim-admin/app/views/decidim/admin/participatory_process_steps/index.html.erb +60 -51
- data/decidim-admin/app/views/decidim/admin/participatory_process_steps/new.html.erb +4 -5
- data/decidim-admin/app/views/decidim/admin/participatory_process_user_roles/_form.html.erb +23 -0
- data/decidim-admin/app/views/decidim/admin/participatory_process_user_roles/edit.html.erb +7 -0
- data/decidim-admin/app/views/decidim/admin/participatory_process_user_roles/index.html.erb +46 -34
- data/decidim-admin/app/views/decidim/admin/participatory_process_user_roles/new.html.erb +7 -0
- data/decidim-admin/app/views/decidim/admin/participatory_processes/_form.html.erb +103 -72
- data/decidim-admin/app/views/decidim/admin/participatory_processes/edit.html.erb +15 -17
- data/decidim-admin/app/views/decidim/admin/participatory_processes/index.html.erb +52 -43
- data/decidim-admin/app/views/decidim/admin/participatory_processes/new.html.erb +6 -5
- data/decidim-admin/app/views/decidim/admin/scopes/edit.html.erb +9 -7
- data/decidim-admin/app/views/decidim/admin/scopes/index.html.erb +37 -36
- data/decidim-admin/app/views/decidim/admin/scopes/new.html.erb +9 -6
- data/decidim-admin/app/views/decidim/admin/static_pages/_form.html.erb +3 -3
- data/decidim-admin/app/views/decidim/admin/static_pages/edit.html.erb +10 -8
- data/decidim-admin/app/views/decidim/admin/static_pages/index.html.erb +38 -37
- data/decidim-admin/app/views/decidim/admin/static_pages/new.html.erb +10 -8
- data/decidim-admin/app/views/decidim/admin/user_groups/index.html.erb +37 -31
- data/decidim-admin/app/views/decidim/admin/users/_form.html.erb +5 -4
- data/decidim-admin/app/views/decidim/admin/users/index.html.erb +57 -52
- data/decidim-admin/app/views/decidim/admin/users/new.html.erb +10 -7
- data/decidim-admin/app/views/layouts/decidim/admin/_application.html.erb +23 -36
- data/decidim-admin/app/views/layouts/decidim/admin/_callouts_full.html.erb +10 -0
- data/decidim-admin/app/views/layouts/decidim/admin/_language_chooser.html.erb +9 -9
- data/decidim-admin/app/views/layouts/decidim/admin/_main_nav.html.erb +11 -0
- data/decidim-admin/app/views/layouts/decidim/admin/_template_bottom.html.erb +2 -0
- data/decidim-admin/app/views/layouts/decidim/admin/_template_top.html.erb +3 -0
- data/decidim-admin/app/views/layouts/decidim/admin/_title_bar.html.erb +20 -0
- data/decidim-admin/app/views/layouts/decidim/admin/newsletters.erb +14 -0
- data/decidim-admin/app/views/layouts/decidim/admin/pages.html.erb +14 -0
- data/decidim-admin/app/views/layouts/decidim/admin/participatory_process.html.erb +55 -53
- data/decidim-admin/app/views/layouts/decidim/admin/participatory_process_groups.html.erb +14 -0
- data/decidim-admin/app/views/layouts/decidim/admin/participatory_processes.html.erb +14 -0
- data/decidim-admin/app/views/layouts/decidim/admin/settings.html.erb +19 -0
- data/decidim-admin/app/views/layouts/decidim/admin/users.html.erb +21 -0
- data/decidim-admin/config/i18n-tasks.yml +1 -0
- data/decidim-admin/config/locales/ca.yml +77 -22
- data/decidim-admin/config/locales/en.yml +75 -20
- data/decidim-admin/config/locales/es.yml +77 -22
- data/decidim-admin/config/locales/eu.yml +191 -16
- data/decidim-admin/config/locales/fi.yml +0 -29
- data/decidim-admin/config/routes.rb +1 -1
- data/decidim-admin/lib/decidim/admin/test/manage_attachments_examples.rb +11 -11
- data/decidim-admin/spec/commands/deliver_newsletter_spec.rb +4 -1
- data/decidim-admin/spec/commands/update_participatory_process_spec.rb +117 -0
- data/decidim-admin/spec/features/admin_invite_spec.rb +5 -1
- data/decidim-admin/spec/features/admin_manages_feature_permissions_spec.rb +1 -1
- data/decidim-admin/spec/features/admin_manages_features_spec.rb +10 -10
- data/decidim-admin/spec/features/admin_manages_newsletters_spec.rb +11 -9
- data/decidim-admin/spec/features/admin_manages_organization_admins_spec.rb +8 -5
- data/decidim-admin/spec/features/admin_manages_organization_scopes_spec.rb +7 -6
- data/decidim-admin/spec/features/admin_manages_organization_spec.rb +14 -0
- data/decidim-admin/spec/features/admin_manages_participatory_process_groups_spec.rb +6 -6
- data/decidim-admin/spec/features/admin_manages_participatory_processes_spec.rb +27 -5
- data/decidim-admin/spec/features/admin_manages_user_groups_spec.rb +1 -1
- data/decidim-admin/spec/features/participatory_process_admin_manages_participatory_process_admins_spec.rb +2 -2
- data/decidim-admin/spec/features/static_pages_spec.rb +9 -7
- data/decidim-admin/spec/jobs/newsletter_job_spec.rb +2 -0
- data/decidim-admin/spec/queries/process_admin_roles_for_process_spec.rb +4 -3
- data/decidim-admin/spec/shared/manage_process_admins_examples.rb +31 -8
- data/decidim-admin/spec/shared/manage_process_attachments_examples.rb +1 -1
- data/decidim-admin/spec/shared/manage_process_categories_examples.rb +11 -26
- data/decidim-admin/spec/shared/manage_process_steps_examples.rb +8 -23
- data/decidim-admin/spec/shared/manage_processes_examples.rb +5 -33
- data/decidim-admin/spec/support/processes_menu_links_helpers.rb +1 -1
- data/decidim-admin/yarn.lock +4 -0
- data/decidim-api/app/controllers/decidim/api/application_controller.rb +2 -1
- data/decidim-budgets/app/controllers/decidim/budgets/admin/projects_controller.rb +1 -1
- data/decidim-budgets/app/controllers/decidim/budgets/line_items_controller.rb +21 -15
- data/decidim-budgets/app/views/decidim/budgets/admin/projects/_form.html.erb +34 -24
- data/decidim-budgets/app/views/decidim/budgets/admin/projects/edit.html.erb +3 -5
- data/decidim-budgets/app/views/decidim/budgets/admin/projects/index.html.erb +52 -34
- data/decidim-budgets/app/views/decidim/budgets/admin/projects/new.html.erb +4 -5
- data/decidim-budgets/app/views/decidim/budgets/projects/_filters.html.erb +1 -1
- data/decidim-budgets/config/i18n-tasks.yml +1 -0
- data/decidim-budgets/config/locales/ca.yml +5 -0
- data/decidim-budgets/config/locales/en.yml +5 -0
- data/decidim-budgets/config/locales/es.yml +5 -0
- data/decidim-budgets/config/locales/eu.yml +27 -0
- data/decidim-budgets/spec/features/orders_spec.rb +22 -0
- data/decidim-budgets/spec/shared/manage_attachments_examples.rb +1 -1
- data/decidim-budgets/spec/shared/manage_projects_examples.rb +10 -8
- data/decidim-comments/README.md +33 -0
- data/decidim-comments/app/assets/javascripts/decidim/comments/bundle.js +0 -0
- data/decidim-comments/app/assets/javascripts/decidim/comments/comments.js.erb +2 -0
- data/decidim-comments/app/frontend/application/{apollo_client.js → apollo_client.ts} +5 -5
- data/decidim-comments/app/frontend/application/application.component.test.tsx +36 -0
- data/decidim-comments/app/frontend/application/application.component.tsx +37 -0
- data/decidim-comments/app/frontend/application/icon.component.test.tsx +49 -0
- data/decidim-comments/app/frontend/application/icon.component.tsx +35 -0
- data/decidim-comments/app/frontend/comments/{add_comment_form.component.test.jsx → add_comment_form.component.test.tsx} +98 -92
- data/decidim-comments/app/frontend/comments/{add_comment_form.component.jsx → add_comment_form.component.tsx} +152 -153
- data/decidim-comments/app/frontend/comments/{comment.component.test.jsx → comment.component.test.tsx} +59 -71
- data/decidim-comments/app/frontend/comments/{comment.component.jsx → comment.component.tsx} +114 -116
- data/decidim-comments/app/frontend/comments/comment_order_selector.component.test.tsx +21 -0
- data/decidim-comments/app/frontend/comments/comment_order_selector.component.tsx +88 -0
- data/decidim-comments/app/frontend/comments/comment_thread.component.test.tsx +65 -0
- data/decidim-comments/app/frontend/comments/comment_thread.component.tsx +70 -0
- data/decidim-comments/app/frontend/comments/{comments.component.test.jsx → comments.component.test.tsx} +38 -81
- data/decidim-comments/app/frontend/comments/{comments.component.jsx → comments.component.tsx} +49 -63
- data/decidim-comments/app/frontend/comments/down_vote_button.component.test.tsx +39 -0
- data/decidim-comments/app/frontend/comments/down_vote_button.component.tsx +89 -0
- data/decidim-comments/app/frontend/comments/up_vote_button.component.test.tsx +39 -0
- data/decidim-comments/app/frontend/comments/up_vote_button.component.tsx +89 -0
- data/decidim-comments/app/frontend/comments/vote_button.component.tsx +36 -0
- data/decidim-comments/app/frontend/comments/{vote_button_component.test.jsx → vote_button_component.test.tsx} +16 -20
- data/decidim-comments/app/frontend/entry.ts +19 -0
- data/decidim-comments/app/frontend/{comments → fragments}/add_comment_form_commentable.fragment.graphql +1 -1
- data/decidim-comments/app/frontend/{comments → fragments}/add_comment_form_session.fragment.graphql +1 -1
- data/decidim-comments/app/frontend/{comments → fragments}/comment.fragment.graphql +3 -1
- data/decidim-comments/app/frontend/{comments → fragments}/comment_data.fragment.graphql +6 -3
- data/decidim-comments/app/frontend/{comments → fragments}/comment_thread.fragment.graphql +3 -1
- data/decidim-comments/app/frontend/{comments/down_vote.fragment.graphql → fragments/down_vote_button.fragment.graphql} +2 -2
- data/decidim-comments/app/frontend/{comments/up_vote.fragment.graphql → fragments/up_vote_button.fragment.graphql} +2 -2
- data/decidim-comments/app/frontend/{comments/add_comment_form.mutation.graphql → mutations/add_comment.mutation.graphql} +3 -1
- data/decidim-comments/app/frontend/{comments → mutations}/down_vote.mutation.graphql +3 -1
- data/decidim-comments/app/frontend/{comments → mutations}/up_vote.mutation.graphql +3 -1
- data/decidim-comments/app/frontend/{comments → queries}/comments.query.graphql +4 -1
- data/decidim-comments/app/frontend/support/{asset_url.js → asset_url.ts} +1 -1
- data/decidim-comments/app/frontend/support/{generate_comments_data.js → generate_comments_data.ts} +11 -6
- data/decidim-comments/app/frontend/support/{generate_user_data.js → generate_user_data.ts} +2 -2
- data/decidim-comments/app/frontend/support/{generate_user_group_data.js → generate_user_group_data.ts} +2 -2
- data/decidim-comments/app/frontend/support/graphql_transformer.js +32 -0
- data/decidim-comments/app/frontend/support/load_translations.ts +44 -0
- data/decidim-comments/app/frontend/support/{require_all.js → require_all.ts} +1 -1
- data/decidim-comments/app/frontend/support/{resolve_graphql_query.js → resolve_graphql_query.ts} +7 -7
- data/decidim-comments/app/frontend/support/schema.ts +119 -0
- data/decidim-comments/config/locales/eu.yml +29 -5
- data/decidim-dev/Rakefile +2 -0
- data/decidim-dev/config/locales/eu.yml +1 -1
- data/decidim-dev/decidim-dev.gemspec +1 -1
- data/decidim-dev/lib/decidim/dev/test/rspec_support/capybara.rb +1 -4
- data/decidim-dev/lib/decidim/dev/test/rspec_support/feature.rb +1 -0
- data/decidim-dev/lib/decidim/dev/test/rspec_support/helpers.rb +1 -1
- data/decidim-dev/lib/decidim/dev/test/rspec_support/phantomjs_polyfills/phantomjs-shim.js +215 -0
- data/decidim-dev/lib/decidim/dev/test/rspec_support/translation_helpers.rb +1 -1
- data/decidim-dev/lib/generators/decidim/dummy_generator.rb +5 -0
- data/decidim-meetings/app/controllers/decidim/meetings/admin/application_controller.rb +1 -1
- data/decidim-meetings/app/views/decidim/meetings/admin/meeting_closes/_form.html.erb +30 -19
- data/decidim-meetings/app/views/decidim/meetings/admin/meeting_closes/edit.html.erb +3 -5
- data/decidim-meetings/app/views/decidim/meetings/admin/meetings/_form.html.erb +46 -35
- data/decidim-meetings/app/views/decidim/meetings/admin/meetings/edit.html.erb +5 -6
- data/decidim-meetings/app/views/decidim/meetings/admin/meetings/index.html.erb +72 -51
- data/decidim-meetings/app/views/decidim/meetings/admin/meetings/new.html.erb +4 -6
- data/decidim-meetings/app/views/decidim/meetings/meetings/_filters.html.erb +1 -1
- data/decidim-meetings/config/locales/ca.yml +2 -1
- data/decidim-meetings/config/locales/en.yml +2 -1
- data/decidim-meetings/config/locales/es.yml +2 -1
- data/decidim-meetings/config/locales/eu.yml +25 -5
- data/decidim-meetings/config/locales/fi.yml +0 -1
- data/decidim-meetings/spec/shared/manage_attachments_examples.rb +1 -1
- data/decidim-meetings/spec/shared/manage_meetings_examples.rb +18 -16
- data/decidim-pages/app/views/decidim/pages/admin/pages/_form.html.erb +10 -3
- data/decidim-pages/app/views/decidim/pages/admin/pages/edit.html.erb +3 -5
- data/decidim-pages/config/locales/eu.yml +4 -2
- data/decidim-pages/spec/features/admin_spec.rb +1 -1
- data/decidim-proposals/app/controllers/decidim/proposals/admin/proposals_controller.rb +1 -1
- data/decidim-proposals/app/views/decidim/proposals/admin/proposal_answers/edit.html.erb +14 -8
- data/decidim-proposals/app/views/decidim/proposals/admin/proposals/_form.html.erb +28 -20
- data/decidim-proposals/app/views/decidim/proposals/admin/proposals/index.html.erb +60 -43
- data/decidim-proposals/app/views/decidim/proposals/admin/proposals/new.html.erb +3 -5
- data/decidim-proposals/app/views/decidim/proposals/proposals/_filters.html.erb +1 -1
- data/decidim-proposals/config/locales/ca.yml +3 -0
- data/decidim-proposals/config/locales/en.yml +4 -1
- data/decidim-proposals/config/locales/es.yml +3 -0
- data/decidim-proposals/config/locales/eu.yml +42 -19
- data/decidim-proposals/config/locales/fi.yml +0 -1
- data/decidim-proposals/spec/shared/manage_proposals_examples.rb +15 -13
- data/decidim-results/README.md +1 -1
- data/decidim-results/app/controllers/decidim/results/admin/results_controller.rb +1 -1
- data/decidim-results/app/views/decidim/results/admin/results/_form.html.erb +30 -21
- data/decidim-results/app/views/decidim/results/admin/results/edit.html.erb +4 -5
- data/decidim-results/app/views/decidim/results/admin/results/index.html.erb +40 -25
- data/decidim-results/app/views/decidim/results/admin/results/new.html.erb +4 -5
- data/decidim-results/app/views/decidim/results/results/_filters.html.erb +1 -1
- data/decidim-results/config/locales/ca.yml +2 -0
- data/decidim-results/config/locales/en.yml +2 -0
- data/decidim-results/config/locales/es.yml +2 -0
- data/decidim-results/config/locales/eu.yml +22 -4
- data/decidim-results/spec/shared/manage_results_examples.rb +10 -8
- data/decidim-system/config/locales/eu.yml +60 -2
- data/lib/generators/decidim/app_generator.rb +0 -4
- data/lib/generators/decidim/install_generator.rb +0 -4
- data/lib/generators/decidim/templates/README.md.erb +18 -18
- data/package.json +47 -22
- data/tsconfig.json +17 -0
- data/tslint.json +12 -0
- data/webpack.config.js +8 -6
- data/webpack.d.ts +5 -0
- data/yarn.lock +1461 -781
- metadata +119 -83
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_actions.scss +0 -8
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_forms.scss +0 -10
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_foundation_and_overrides.scss +0 -53
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_icons.scss +0 -9
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_layout.scss +0 -27
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_settings.scss +0 -566
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_tables.scss +0 -21
- data/decidim-admin/app/views/layouts/decidim/admin/_login_items.html.erb +0 -8
- data/decidim-admin/app/views/layouts/decidim/admin/_sidebar.html.erb +0 -22
- data/decidim-comments/app/frontend/application/application.component.jsx +0 -37
- data/decidim-comments/app/frontend/application/application.component.test.jsx +0 -33
- data/decidim-comments/app/frontend/application/icon.component.jsx +0 -26
- data/decidim-comments/app/frontend/application/icon.component.test.jsx +0 -53
- data/decidim-comments/app/frontend/comments/comment_order_selector.component.jsx +0 -72
- data/decidim-comments/app/frontend/comments/comment_order_selector.component.test.jsx +0 -20
- data/decidim-comments/app/frontend/comments/comment_thread.component.jsx +0 -75
- data/decidim-comments/app/frontend/comments/comment_thread.component.test.jsx +0 -83
- data/decidim-comments/app/frontend/comments/down_vote_button.component.jsx +0 -98
- data/decidim-comments/app/frontend/comments/down_vote_button.component.test.jsx +0 -48
- data/decidim-comments/app/frontend/comments/featured_comment.component.jsx +0 -23
- data/decidim-comments/app/frontend/comments/featured_comment.component.test.jsx +0 -15
- data/decidim-comments/app/frontend/comments/up_vote_button.component.jsx +0 -98
- data/decidim-comments/app/frontend/comments/up_vote_button.component.test.jsx +0 -48
- data/decidim-comments/app/frontend/comments/vote_button.component.jsx +0 -32
- data/decidim-comments/app/frontend/entry.js +0 -17
- data/decidim-comments/app/frontend/entry.test.js +0 -31
- data/decidim-comments/app/frontend/support/load_translations.js +0 -23
- data/decidim-comments/app/frontend/support/stub_component.js +0 -29
- data/decidim-dev/lib/decidim/dev/test/rspec_support/phantomjs_polyfills/bind-polyfill.js +0 -18
- data/decidim-dev/lib/decidim/dev/test/rspec_support/phantomjs_polyfills/object-assign-polyfill.js +0 -24
- data/karma.conf.js +0 -45
- data/lib/generators/decidim/review_app_generator.rb +0 -53
- data/lib/generators/decidim/templates/app.json.erb +0 -16
@@ -1,184 +1,190 @@
|
|
1
|
-
|
2
|
-
import
|
1
|
+
import { mount, ReactWrapper, shallow } from "enzyme";
|
2
|
+
import * as React from "react";
|
3
3
|
|
4
|
-
import { AddCommentForm }
|
4
|
+
import { AddCommentForm } from "./add_comment_form.component";
|
5
5
|
|
6
|
-
import generateUserData
|
7
|
-
import generateUserGroupData from
|
6
|
+
import generateUserData from "../support/generate_user_data";
|
7
|
+
import generateUserGroupData from "../support/generate_user_group_data";
|
8
|
+
import { loadLocaleTranslations } from "../support/load_translations";
|
8
9
|
|
9
10
|
describe("<AddCommentForm />", () => {
|
10
|
-
let session = null;
|
11
|
+
let session: any = null;
|
11
12
|
const commentable = {
|
12
13
|
id: "1",
|
13
|
-
type: "Decidim::DummyResource"
|
14
|
+
type: "Decidim::DummyResource",
|
14
15
|
};
|
15
|
-
const addCommentStub = () => {
|
16
|
+
const addCommentStub = (): any => {
|
16
17
|
return null;
|
17
|
-
}
|
18
|
+
};
|
18
19
|
|
19
20
|
beforeEach(() => {
|
21
|
+
loadLocaleTranslations("en");
|
20
22
|
session = {
|
21
23
|
user: generateUserData(),
|
22
|
-
verifiedUserGroups: []
|
24
|
+
verifiedUserGroups: [],
|
25
|
+
};
|
26
|
+
window.DecidimComments = {
|
27
|
+
assets: {
|
28
|
+
"icons.svg": "/assets/icons.svg",
|
29
|
+
},
|
23
30
|
};
|
24
31
|
});
|
25
32
|
|
26
33
|
it("should render a div with class add-comment", () => {
|
27
34
|
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
28
|
-
expect(wrapper.find(
|
35
|
+
expect(wrapper.find("div.add-comment")).toBeDefined();
|
29
36
|
});
|
30
37
|
|
31
38
|
it("should have a reference to body textarea", () => {
|
32
39
|
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
33
|
-
expect(wrapper.instance().bodyTextArea).
|
40
|
+
expect((wrapper.instance() as AddCommentForm).bodyTextArea).toBeDefined();
|
34
41
|
});
|
35
42
|
|
36
43
|
it("should initialize with a state property disabled as true", () => {
|
37
44
|
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
38
|
-
expect(wrapper
|
45
|
+
expect(wrapper.state()).toHaveProperty("disabled", true);
|
39
46
|
});
|
40
47
|
|
41
48
|
it("should have a default prop showTitle as true", () => {
|
42
49
|
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
43
|
-
expect(wrapper
|
50
|
+
expect(wrapper.props()).toHaveProperty("showTitle", true);
|
44
51
|
});
|
45
52
|
|
46
53
|
it("should not render the title if prop showTitle is false", () => {
|
47
54
|
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} showTitle={false} />);
|
48
|
-
expect(wrapper.find(
|
55
|
+
expect(wrapper.find("h5.section-heading").exists()).toBeFalsy();
|
49
56
|
});
|
50
57
|
|
51
58
|
it("should have a default prop submitButtonClassName as 'button button--sc'", () => {
|
52
59
|
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
53
|
-
expect(wrapper
|
60
|
+
expect(wrapper.props()).toHaveProperty("submitButtonClassName", "button button--sc");
|
54
61
|
});
|
55
62
|
|
56
63
|
it("should have a default prop maxLength of 1000", () => {
|
57
64
|
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
58
|
-
expect(wrapper
|
65
|
+
expect(wrapper.props()).toHaveProperty("maxLength", 1000);
|
59
66
|
});
|
60
67
|
|
61
|
-
|
62
68
|
it("should use prop submitButtonClassName as a className prop for submit button", () => {
|
63
69
|
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} submitButtonClassName="button small hollow" />);
|
64
|
-
expect(wrapper.find('button[type="submit"]')
|
65
|
-
expect(wrapper.find('button[type="submit"]')
|
66
|
-
expect(wrapper.find('button[type="submit"]')
|
70
|
+
expect(wrapper.find('button[type="submit"]').hasClass("button")).toBeTruthy();
|
71
|
+
expect(wrapper.find('button[type="submit"]').hasClass("small")).toBeTruthy();
|
72
|
+
expect(wrapper.find('button[type="submit"]').hasClass("hollow")).toBeTruthy();
|
67
73
|
});
|
68
74
|
|
69
75
|
it("should enable the submit button if textarea is not blank", () => {
|
70
76
|
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
71
|
-
wrapper.find(
|
77
|
+
wrapper.find("textarea").simulate("change", {
|
72
78
|
target: {
|
73
|
-
value:
|
74
|
-
}
|
79
|
+
value: "This is a comment",
|
80
|
+
},
|
75
81
|
});
|
76
|
-
expect(wrapper.find('button[type="submit"]')).not.
|
82
|
+
expect(wrapper.find('button[type="submit"]').props()).not.toHaveProperty("disabled", true);
|
77
83
|
});
|
78
84
|
|
79
85
|
it("should disable the submit button if textarea is blank", () => {
|
80
86
|
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
81
|
-
wrapper.find(
|
87
|
+
wrapper.find("textarea").simulate("change", {
|
82
88
|
target: {
|
83
|
-
value:
|
84
|
-
}
|
89
|
+
value: "This will be deleted",
|
90
|
+
},
|
85
91
|
});
|
86
|
-
wrapper.find(
|
92
|
+
wrapper.find("textarea").simulate("change", {
|
87
93
|
target: {
|
88
|
-
value:
|
89
|
-
}
|
94
|
+
value: "",
|
95
|
+
},
|
90
96
|
});
|
91
|
-
expect(wrapper.find('button[type="submit"]')).
|
97
|
+
expect(wrapper.find('button[type="submit"]').props()).toHaveProperty("disabled", true);
|
92
98
|
});
|
93
99
|
|
94
100
|
it("should not render a div with class 'opinion-toggle'", () => {
|
95
101
|
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
96
|
-
expect(wrapper.find(
|
102
|
+
expect(wrapper.find(".opinion-toggle").exists()).toBeFalsy();
|
97
103
|
});
|
98
104
|
|
99
105
|
describe("submitting the form", () => {
|
100
|
-
let addComment
|
101
|
-
let onCommentAdded
|
102
|
-
let wrapper
|
103
|
-
let message = null;
|
106
|
+
let addComment: jasmine.Spy;
|
107
|
+
let onCommentAdded: jasmine.Spy ;
|
108
|
+
let wrapper: ReactWrapper<any, {}>;
|
109
|
+
let message: any = null;
|
104
110
|
|
105
111
|
beforeEach(() => {
|
106
|
-
addComment =
|
107
|
-
onCommentAdded =
|
112
|
+
addComment = jasmine.createSpy("addComment");
|
113
|
+
onCommentAdded = jasmine.createSpy("onCommentAdded");
|
108
114
|
wrapper = mount(<AddCommentForm addComment={addComment} session={session} commentable={commentable} onCommentAdded={onCommentAdded} />);
|
109
|
-
message =
|
110
|
-
wrapper.instance().bodyTextArea.value = message;
|
115
|
+
message = "This will be submitted";
|
116
|
+
(wrapper.instance() as AddCommentForm).bodyTextArea.value = message;
|
111
117
|
});
|
112
118
|
|
113
119
|
it("should call addComment prop with the textarea value and state property alignment", () => {
|
114
|
-
wrapper.find(
|
115
|
-
expect(addComment).
|
120
|
+
wrapper.find("form").simulate("submit");
|
121
|
+
expect(addComment).toHaveBeenCalledWith({ body: message, alignment: 0 });
|
116
122
|
});
|
117
123
|
|
118
124
|
it("should reset textarea", () => {
|
119
|
-
wrapper.find(
|
120
|
-
expect(wrapper.find(
|
125
|
+
wrapper.find("form").simulate("submit");
|
126
|
+
expect((wrapper.find("textarea").get(0) as any).value).toBe("");
|
121
127
|
});
|
122
128
|
|
123
129
|
it("should prevent default form submission", () => {
|
124
|
-
const preventDefault =
|
125
|
-
wrapper.find(
|
126
|
-
expect(preventDefault).
|
130
|
+
const preventDefault = jasmine.createSpy("preventDefault");
|
131
|
+
wrapper.find("form").simulate("submit", { preventDefault });
|
132
|
+
expect(preventDefault).toHaveBeenCalled();
|
127
133
|
});
|
128
134
|
|
129
135
|
it("should call the prop onCommentAdded function", () => {
|
130
|
-
wrapper.find(
|
131
|
-
expect(onCommentAdded).
|
136
|
+
wrapper.find("form").simulate("submit");
|
137
|
+
expect(onCommentAdded).toHaveBeenCalled();
|
132
138
|
});
|
133
139
|
});
|
134
140
|
|
135
141
|
it("should initialize state with a property alignment and value 0", () => {
|
136
|
-
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} arguable />);
|
137
|
-
expect(wrapper
|
142
|
+
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} arguable={true} />);
|
143
|
+
expect(wrapper.state()).toHaveProperty("alignment", 0);
|
138
144
|
});
|
139
145
|
|
140
146
|
describe("when receiving an optional prop arguable with value true", () => {
|
141
147
|
it("should render a div with class 'opinion-toggle'", () => {
|
142
|
-
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} arguable />);
|
143
|
-
expect(wrapper.find(
|
148
|
+
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} arguable={true} />);
|
149
|
+
expect(wrapper.find(".opinion-toggle")).toBeDefined();
|
144
150
|
});
|
145
151
|
|
146
152
|
it("should set state alignment to 1 if user clicks ok button and change its class", () => {
|
147
|
-
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} arguable />);
|
148
|
-
wrapper.find(
|
149
|
-
expect(wrapper.find(
|
150
|
-
expect(wrapper
|
153
|
+
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} arguable={true} />);
|
154
|
+
wrapper.find(".opinion-toggle--ok").simulate("click");
|
155
|
+
expect(wrapper.find(".opinion-toggle--ok").hasClass("is-active")).toBeTruthy();
|
156
|
+
expect(wrapper.state()).toHaveProperty("alignment", 1);
|
151
157
|
});
|
152
158
|
|
153
159
|
it("should set state alignment to -11 if user clicks ko button and change its class", () => {
|
154
|
-
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} arguable />);
|
155
|
-
wrapper.find(
|
156
|
-
expect(wrapper.find(
|
157
|
-
expect(wrapper
|
160
|
+
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} arguable={true} />);
|
161
|
+
wrapper.find(".opinion-toggle--ko").simulate("click");
|
162
|
+
expect(wrapper.find(".opinion-toggle--ko").hasClass("is-active")).toBeTruthy();
|
163
|
+
expect(wrapper.state()).toHaveProperty("alignment", -1);
|
158
164
|
});
|
159
165
|
|
160
166
|
describe("submitting the form", () => {
|
161
|
-
let
|
162
|
-
let
|
163
|
-
let message
|
167
|
+
let wrapper: ReactWrapper<any, {}>;
|
168
|
+
let addComment: jasmine.Spy;
|
169
|
+
let message: string;
|
164
170
|
|
165
171
|
beforeEach(() => {
|
166
|
-
addComment =
|
167
|
-
wrapper = mount(<AddCommentForm addComment={addComment} session={session} commentable={commentable} arguable />);
|
168
|
-
message =
|
169
|
-
wrapper.instance().bodyTextArea.value = message;
|
172
|
+
addComment = jasmine.createSpy("addComment");
|
173
|
+
wrapper = mount(<AddCommentForm addComment={addComment} session={session} commentable={commentable} arguable={true} />);
|
174
|
+
message = "This will be submitted";
|
175
|
+
(wrapper.instance() as AddCommentForm).bodyTextArea.value = message;
|
170
176
|
});
|
171
177
|
|
172
178
|
it("should call addComment prop with the state's property alignment", () => {
|
173
|
-
wrapper.find(
|
174
|
-
wrapper.find(
|
175
|
-
expect(addComment).
|
179
|
+
wrapper.find("button.opinion-toggle--ko").simulate("click");
|
180
|
+
wrapper.find("form").simulate("submit");
|
181
|
+
expect(addComment).toHaveBeenCalledWith({ body: message, alignment: -1 });
|
176
182
|
});
|
177
183
|
|
178
184
|
it("should reset the state to its initial state", () => {
|
179
|
-
wrapper.find(
|
180
|
-
wrapper.find(
|
181
|
-
expect(wrapper
|
185
|
+
wrapper.find("button.opinion-toggle--ok").simulate("click");
|
186
|
+
wrapper.find("form").simulate("submit");
|
187
|
+
expect(wrapper.state()).toHaveProperty("alignment", 0);
|
182
188
|
});
|
183
189
|
});
|
184
190
|
});
|
@@ -187,48 +193,48 @@ describe("<AddCommentForm />", () => {
|
|
187
193
|
beforeEach(() => {
|
188
194
|
session.verifiedUserGroups = [
|
189
195
|
generateUserGroupData(),
|
190
|
-
generateUserGroupData()
|
196
|
+
generateUserGroupData(),
|
191
197
|
];
|
192
198
|
});
|
193
199
|
|
194
200
|
it("should have a reference to user_group_id select", () => {
|
195
201
|
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
196
|
-
expect(wrapper.instance().userGroupIdSelect).
|
202
|
+
expect((wrapper.instance() as AddCommentForm).userGroupIdSelect).toBeDefined();
|
197
203
|
});
|
198
204
|
|
199
205
|
it("should render a select with option tags for each verified user group", () => {
|
200
206
|
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
201
|
-
expect(wrapper.find(
|
207
|
+
expect(wrapper.find("select").children("option").length).toBe(3);
|
202
208
|
});
|
203
209
|
|
204
210
|
describe("submitting the form", () => {
|
205
|
-
let addComment
|
206
|
-
let wrapper
|
207
|
-
let message
|
208
|
-
let userGroupId
|
211
|
+
let addComment: jasmine.Spy;
|
212
|
+
let wrapper: ReactWrapper<any, {}>;
|
213
|
+
let message: string;
|
214
|
+
let userGroupId: string;
|
209
215
|
|
210
216
|
beforeEach(() => {
|
211
|
-
addComment =
|
217
|
+
addComment = jasmine.createSpy("addComment");
|
212
218
|
wrapper = mount(<AddCommentForm addComment={addComment} session={session} commentable={commentable} />);
|
213
|
-
message =
|
219
|
+
message = "This will be submitted";
|
214
220
|
userGroupId = session.verifiedUserGroups[1].id;
|
215
|
-
wrapper.instance().bodyTextArea.value = message;
|
216
|
-
wrapper.instance().userGroupIdSelect.value = userGroupId;
|
221
|
+
(wrapper.instance() as AddCommentForm).bodyTextArea.value = message;
|
222
|
+
(wrapper.instance() as AddCommentForm).userGroupIdSelect.value = userGroupId;
|
217
223
|
});
|
218
224
|
|
219
225
|
it("should call addComment prop with the body textarea, alignment and user_group_id select values", () => {
|
220
|
-
wrapper.find(
|
221
|
-
expect(addComment).
|
226
|
+
wrapper.find("form").simulate("submit");
|
227
|
+
expect(addComment).toHaveBeenCalledWith({ body: message, alignment: 0, userGroupId });
|
222
228
|
});
|
223
229
|
|
224
230
|
describe("when user_group_id is blank", () => {
|
225
231
|
beforeEach(() => {
|
226
|
-
wrapper.instance().userGroupIdSelect.value =
|
232
|
+
(wrapper.instance() as AddCommentForm).userGroupIdSelect.value = "";
|
227
233
|
});
|
228
234
|
|
229
235
|
it("should call addComment prop with the body textarea and alignment", () => {
|
230
|
-
wrapper.find(
|
231
|
-
expect(addComment).
|
236
|
+
wrapper.find("form").simulate("submit");
|
237
|
+
expect(addComment).toHaveBeenCalledWith({ body: message, alignment: 0 });
|
232
238
|
});
|
233
239
|
});
|
234
240
|
});
|
@@ -241,7 +247,7 @@ describe("<AddCommentForm />", () => {
|
|
241
247
|
|
242
248
|
it("display a message to sign in or sign up", () => {
|
243
249
|
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
244
|
-
expect(wrapper.find(
|
250
|
+
expect(wrapper.find("span").text()).toContain("sign up");
|
245
251
|
});
|
246
252
|
});
|
247
253
|
});
|
@@ -1,39 +1,69 @@
|
|
1
1
|
/* eslint-disable no-return-assign, react/no-unused-prop-types, max-lines */
|
2
|
-
import
|
3
|
-
import
|
4
|
-
import
|
5
|
-
import
|
6
|
-
|
7
|
-
import
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
import
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
2
|
+
import * as classnames from "classnames";
|
3
|
+
import * as React from "react";
|
4
|
+
import { graphql } from "react-apollo";
|
5
|
+
import * as uuid from "uuid";
|
6
|
+
|
7
|
+
import Icon from "../application/icon.component";
|
8
|
+
|
9
|
+
const { I18n, Translate } = require("react-i18nify");
|
10
|
+
|
11
|
+
import {
|
12
|
+
AddCommentFormCommentableFragment,
|
13
|
+
AddCommentFormSessionFragment,
|
14
|
+
AddCommentMutation,
|
15
|
+
CommentFragment,
|
16
|
+
GetCommentsQuery,
|
17
|
+
} from "../support/schema";
|
18
|
+
|
19
|
+
interface AddCommentFormProps {
|
20
|
+
session: AddCommentFormSessionFragment & {
|
21
|
+
user: any;
|
22
|
+
} | null;
|
23
|
+
commentable: AddCommentFormCommentableFragment;
|
24
|
+
showTitle?: boolean;
|
25
|
+
submitButtonClassName?: string;
|
26
|
+
autoFocus?: boolean;
|
27
|
+
maxLength?: number;
|
28
|
+
arguable?: boolean;
|
29
|
+
addComment?: (data: { body: string, alignment: number, userGroupId?: string }) => void;
|
30
|
+
onCommentAdded?: () => void;
|
31
|
+
}
|
32
|
+
|
33
|
+
interface AddCommentFormState {
|
34
|
+
disabled: boolean;
|
35
|
+
error: boolean;
|
36
|
+
alignment: number;
|
37
|
+
}
|
19
38
|
|
20
39
|
/**
|
21
40
|
* Renders a form to create new comments.
|
22
41
|
* @class
|
23
42
|
* @augments Component
|
24
43
|
*/
|
25
|
-
export class AddCommentForm extends Component {
|
26
|
-
|
44
|
+
export class AddCommentForm extends React.Component<AddCommentFormProps, AddCommentFormState> {
|
45
|
+
public static defaultProps = {
|
46
|
+
showTitle: true,
|
47
|
+
submitButtonClassName: "button button--sc",
|
48
|
+
arguable: false,
|
49
|
+
autoFocus: false,
|
50
|
+
maxLength: 1000,
|
51
|
+
};
|
52
|
+
|
53
|
+
public bodyTextArea: HTMLTextAreaElement;
|
54
|
+
public userGroupIdSelect: HTMLSelectElement;
|
55
|
+
|
56
|
+
constructor(props: AddCommentFormProps) {
|
27
57
|
super(props);
|
28
58
|
|
29
59
|
this.state = {
|
30
60
|
disabled: true,
|
31
61
|
error: false,
|
32
|
-
alignment: 0
|
62
|
+
alignment: 0,
|
33
63
|
};
|
34
64
|
}
|
35
65
|
|
36
|
-
render() {
|
66
|
+
public render() {
|
37
67
|
return (
|
38
68
|
<div className="add-comment">
|
39
69
|
{this._renderHeading()}
|
@@ -49,13 +79,13 @@ export class AddCommentForm extends Component {
|
|
49
79
|
* @private
|
50
80
|
* @returns {Void|DOMElement} - The heading or an empty element
|
51
81
|
*/
|
52
|
-
_renderHeading() {
|
82
|
+
private _renderHeading() {
|
53
83
|
const { showTitle } = this.props;
|
54
84
|
|
55
85
|
if (showTitle) {
|
56
86
|
return (
|
57
87
|
<h5 className="section-heading">
|
58
|
-
{
|
88
|
+
{I18n.t("components.add_comment_form.title")}
|
59
89
|
</h5>
|
60
90
|
);
|
61
91
|
}
|
@@ -68,7 +98,7 @@ export class AddCommentForm extends Component {
|
|
68
98
|
* @private
|
69
99
|
* @returns {Void|DOMElement} - The message or an empty element.
|
70
100
|
*/
|
71
|
-
_renderAccountMessage() {
|
101
|
+
private _renderAccountMessage() {
|
72
102
|
const { session } = this.props;
|
73
103
|
|
74
104
|
if (!session) {
|
@@ -78,7 +108,7 @@ export class AddCommentForm extends Component {
|
|
78
108
|
value="components.add_comment_form.account_message"
|
79
109
|
sign_in_url="/users/sign_in"
|
80
110
|
sign_up_url="/users/sign_up"
|
81
|
-
dangerousHTML
|
111
|
+
dangerousHTML={true}
|
82
112
|
/>
|
83
113
|
</p>
|
84
114
|
);
|
@@ -92,21 +122,23 @@ export class AddCommentForm extends Component {
|
|
92
122
|
* @private
|
93
123
|
* @returns {Void|DOMElement} - The add comment form on an empty element.
|
94
124
|
*/
|
95
|
-
_renderForm() {
|
125
|
+
private _renderForm() {
|
96
126
|
const { session, submitButtonClassName, commentable: { id, type } } = this.props;
|
97
127
|
const { disabled } = this.state;
|
98
128
|
|
99
129
|
if (session) {
|
100
130
|
return (
|
101
|
-
<form onSubmit={
|
131
|
+
<form onSubmit={this.addComment}>
|
102
132
|
{this._renderCommentAs()}
|
103
133
|
<div className="field">
|
104
|
-
<label className="show-for-sr" htmlFor={`add-comment-${type}-${id}`}>{
|
134
|
+
<label className="show-for-sr" htmlFor={`add-comment-${type}-${id}`}>{I18n.t("components.add_comment_form.form.body.label")}</label>
|
105
135
|
{this._renderTextArea()}
|
106
136
|
{this._renderTextAreaError()}
|
107
|
-
<button
|
108
|
-
|
109
|
-
|
137
|
+
<button
|
138
|
+
type="submit"
|
139
|
+
className={submitButtonClassName}
|
140
|
+
disabled={disabled}
|
141
|
+
>
|
110
142
|
{I18n.t("components.add_comment_form.form.submit")}
|
111
143
|
</button>
|
112
144
|
</div>
|
@@ -122,13 +154,13 @@ export class AddCommentForm extends Component {
|
|
122
154
|
* @private
|
123
155
|
* @returns {Void|DOMElement} - The heading or an empty element
|
124
156
|
*/
|
125
|
-
_renderTextArea() {
|
157
|
+
private _renderTextArea() {
|
126
158
|
const { commentable: { id, type }, autoFocus, maxLength } = this.props;
|
127
159
|
const { error } = this.state;
|
128
|
-
const className = classnames({
|
160
|
+
const className = classnames({ "is-invalid-input": error });
|
129
161
|
|
130
|
-
let textAreaProps = {
|
131
|
-
ref: (textarea) => {this.bodyTextArea = textarea},
|
162
|
+
let textAreaProps: any = {
|
163
|
+
ref: (textarea: HTMLTextAreaElement) => {this.bodyTextArea = textarea; },
|
132
164
|
id: `add-comment-${type}-${id}`,
|
133
165
|
className,
|
134
166
|
rows: "4",
|
@@ -136,10 +168,11 @@ export class AddCommentForm extends Component {
|
|
136
168
|
required: "required",
|
137
169
|
pattern: `^(.){0,${maxLength}}$`,
|
138
170
|
placeholder: I18n.t("components.add_comment_form.form.body.placeholder"),
|
139
|
-
onChange: (evt) => this._checkCommentBody(evt.target.value)
|
171
|
+
onChange: (evt: React.ChangeEvent<HTMLTextAreaElement>) => this._checkCommentBody(evt.target.value),
|
140
172
|
};
|
173
|
+
|
141
174
|
if (autoFocus) {
|
142
|
-
textAreaProps.autoFocus =
|
175
|
+
textAreaProps.autoFocus = "autoFocus";
|
143
176
|
}
|
144
177
|
|
145
178
|
return (
|
@@ -152,14 +185,14 @@ export class AddCommentForm extends Component {
|
|
152
185
|
* @private
|
153
186
|
* @returns {Void|DOMElement} - The error or an empty element
|
154
187
|
*/
|
155
|
-
_renderTextAreaError() {
|
188
|
+
private _renderTextAreaError() {
|
156
189
|
const { maxLength } = this.props;
|
157
190
|
const { error } = this.state;
|
158
191
|
|
159
192
|
if (error) {
|
160
193
|
return (
|
161
194
|
<span className="form-error is-visible">
|
162
|
-
{
|
195
|
+
{I18n.t("components.add_comment_form.form.form_error", { length: maxLength })}
|
163
196
|
</span>
|
164
197
|
);
|
165
198
|
}
|
@@ -167,23 +200,29 @@ export class AddCommentForm extends Component {
|
|
167
200
|
return null;
|
168
201
|
}
|
169
202
|
|
203
|
+
private setAlignment = (alignment: number) => {
|
204
|
+
return () => {
|
205
|
+
this.setState({ alignment });
|
206
|
+
};
|
207
|
+
}
|
208
|
+
|
170
209
|
/**
|
171
210
|
* Render opinion buttons or not based on the arguable prop
|
172
211
|
* @private
|
173
212
|
* @returns {Void|DOMElement} - Returns nothing or a wrapper with buttons
|
174
213
|
*/
|
175
|
-
_renderOpinionButtons() {
|
214
|
+
private _renderOpinionButtons() {
|
176
215
|
const { session, arguable } = this.props;
|
177
216
|
const { alignment } = this.state;
|
178
|
-
const buttonClassName = classnames(
|
179
|
-
const okButtonClassName = classnames(buttonClassName,
|
180
|
-
|
217
|
+
const buttonClassName = classnames("button", "tiny", "button--muted");
|
218
|
+
const okButtonClassName = classnames(buttonClassName, "opinion-toggle--ok", {
|
219
|
+
"is-active": alignment === 1,
|
181
220
|
});
|
182
|
-
const koButtonClassName = classnames(buttonClassName,
|
183
|
-
|
221
|
+
const koButtonClassName = classnames(buttonClassName, "opinion-toggle--ko", {
|
222
|
+
"is-active": alignment === -1,
|
184
223
|
});
|
185
|
-
const neutralButtonClassName = classnames(buttonClassName,
|
186
|
-
|
224
|
+
const neutralButtonClassName = classnames(buttonClassName, "opinion-toggle--meh", {
|
225
|
+
"is-active": alignment === 0,
|
187
226
|
});
|
188
227
|
|
189
228
|
if (session && arguable) {
|
@@ -191,19 +230,19 @@ export class AddCommentForm extends Component {
|
|
191
230
|
<div className="opinion-toggle button-group">
|
192
231
|
<button
|
193
232
|
className={okButtonClassName}
|
194
|
-
onClick={
|
233
|
+
onClick={this.setAlignment(1)}
|
195
234
|
>
|
196
235
|
<Icon iconExtraClassName="" name="icon-thumb-up" />
|
197
236
|
</button>
|
198
237
|
<button
|
199
238
|
className={neutralButtonClassName}
|
200
|
-
onClick={
|
239
|
+
onClick={this.setAlignment(0)}
|
201
240
|
>
|
202
|
-
{
|
241
|
+
{I18n.t("components.add_comment_form.opinion.neutral")}
|
203
242
|
</button>
|
204
243
|
<button
|
205
244
|
className={koButtonClassName}
|
206
|
-
onClick={
|
245
|
+
onClick={this.setAlignment(-1)}
|
207
246
|
>
|
208
247
|
<Icon iconExtraClassName="" name="icon-thumb-down" />
|
209
248
|
</button>
|
@@ -214,34 +253,39 @@ export class AddCommentForm extends Component {
|
|
214
253
|
return null;
|
215
254
|
}
|
216
255
|
|
256
|
+
private setUserGroupIdSelect = (select: HTMLSelectElement) => {this.userGroupIdSelect = select; };
|
257
|
+
|
217
258
|
/**
|
218
259
|
* Render a select with an option for each user's verified group
|
219
260
|
* @private
|
220
261
|
* @returns {Void|DOMElement} - Returns nothing or a form field.
|
221
262
|
*/
|
222
|
-
_renderCommentAs() {
|
263
|
+
private _renderCommentAs() {
|
223
264
|
const { session, commentable: { id, type } } = this.props;
|
224
|
-
const { user, verifiedUserGroups } = session;
|
225
265
|
|
226
|
-
if (
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
266
|
+
if (session) {
|
267
|
+
const { user, verifiedUserGroups } = session;
|
268
|
+
|
269
|
+
if (verifiedUserGroups.length > 0) {
|
270
|
+
return (
|
271
|
+
<div className="field">
|
272
|
+
<label htmlFor={`add-comment-${type}-${id}-user-group-id`}>
|
273
|
+
{I18n.t("components.add_comment_form.form.user_group_id.label")}
|
274
|
+
</label>
|
275
|
+
<select
|
276
|
+
ref={this.setUserGroupIdSelect}
|
277
|
+
id={`add-comment-${type}-${id}-user-group-id`}
|
278
|
+
>
|
279
|
+
<option value="">{user.name}</option>
|
280
|
+
{
|
281
|
+
verifiedUserGroups.map((userGroup) => (
|
282
|
+
<option key={userGroup.id} value={userGroup.id}>{userGroup.name}</option>
|
283
|
+
))
|
284
|
+
}
|
285
|
+
</select>
|
286
|
+
</div>
|
287
|
+
);
|
288
|
+
}
|
245
289
|
}
|
246
290
|
|
247
291
|
return null;
|
@@ -253,9 +297,9 @@ export class AddCommentForm extends Component {
|
|
253
297
|
* @param {string} body - The comment's body
|
254
298
|
* @returns {Void} - Returns nothing
|
255
299
|
*/
|
256
|
-
_checkCommentBody(body) {
|
300
|
+
private _checkCommentBody(body: string) {
|
257
301
|
const { maxLength } = this.props;
|
258
|
-
this.setState({ disabled: body ===
|
302
|
+
this.setState({ disabled: body === "", error: body === "" || (maxLength !== undefined && body.length > maxLength) });
|
259
303
|
}
|
260
304
|
|
261
305
|
/**
|
@@ -265,20 +309,22 @@ export class AddCommentForm extends Component {
|
|
265
309
|
* @param {DOMEvent} evt - The form's submission event
|
266
310
|
* @returns {Void} - Returns nothing
|
267
311
|
*/
|
268
|
-
|
312
|
+
private addComment = (evt: React.FormEvent<HTMLFormElement>) => {
|
269
313
|
const { alignment } = this.state;
|
270
314
|
const { addComment, onCommentAdded } = this.props;
|
271
|
-
let addCommentParams = { body: this.bodyTextArea.value, alignment };
|
315
|
+
let addCommentParams: { body: string, alignment: number, userGroupId?: string } = { body: this.bodyTextArea.value, alignment };
|
272
316
|
|
273
317
|
evt.preventDefault();
|
274
318
|
|
275
|
-
if (this.userGroupIdSelect && this.userGroupIdSelect.value !==
|
319
|
+
if (this.userGroupIdSelect && this.userGroupIdSelect.value !== "") {
|
276
320
|
addCommentParams.userGroupId = this.userGroupIdSelect.value;
|
277
321
|
}
|
278
322
|
|
279
|
-
addComment
|
323
|
+
if (addComment) {
|
324
|
+
addComment(addCommentParams);
|
325
|
+
}
|
280
326
|
|
281
|
-
this.bodyTextArea.value =
|
327
|
+
this.bodyTextArea.value = "";
|
282
328
|
this.setState({ alignment: 0 });
|
283
329
|
|
284
330
|
if (onCommentAdded) {
|
@@ -287,80 +333,33 @@ export class AddCommentForm extends Component {
|
|
287
333
|
}
|
288
334
|
}
|
289
335
|
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
user: PropTypes.shape({
|
294
|
-
name: PropTypes.string.isRequired
|
295
|
-
}),
|
296
|
-
verifiedUserGroups: PropTypes.arrayOf(
|
297
|
-
PropTypes.shape({
|
298
|
-
name: PropTypes.string.isRequired
|
299
|
-
})
|
300
|
-
).isRequired
|
301
|
-
}),
|
302
|
-
commentable: PropTypes.shape({
|
303
|
-
id: PropTypes.string.isRequired,
|
304
|
-
type: PropTypes.string.isRequired
|
305
|
-
}),
|
306
|
-
showTitle: PropTypes.bool.isRequired,
|
307
|
-
submitButtonClassName: PropTypes.string.isRequired,
|
308
|
-
onCommentAdded: PropTypes.func,
|
309
|
-
arguable: PropTypes.bool,
|
310
|
-
autoFocus: PropTypes.bool,
|
311
|
-
maxLength: PropTypes.number.isRequired
|
312
|
-
};
|
313
|
-
|
314
|
-
AddCommentForm.defaultProps = {
|
315
|
-
onCommentAdded: function() {},
|
316
|
-
showTitle: true,
|
317
|
-
submitButtonClassName: 'button button--sc',
|
318
|
-
arguable: false,
|
319
|
-
autoFocus: false,
|
320
|
-
maxLength: 1000
|
321
|
-
};
|
322
|
-
|
323
|
-
AddCommentForm.fragments = {
|
324
|
-
session: gql`
|
325
|
-
${addCommentFormSessionFragment}
|
326
|
-
`,
|
327
|
-
commentable: gql`
|
328
|
-
${addCommentFormCommentableFragment}
|
329
|
-
`
|
330
|
-
};
|
331
|
-
|
332
|
-
const AddCommentFormWithMutation = graphql(gql`
|
333
|
-
${addCommentMutation}
|
334
|
-
${commentThreadFragment}
|
335
|
-
${commentFragment}
|
336
|
-
${commentDataFragment}
|
337
|
-
${upVoteFragment}
|
338
|
-
${downVoteFragment}
|
339
|
-
`, {
|
336
|
+
const addCommentMutation = require("../mutations/add_comment.mutation.graphql");
|
337
|
+
|
338
|
+
const AddCommentFormWithMutation = graphql(addCommentMutation, {
|
340
339
|
props: ({ ownProps, mutate }) => ({
|
341
|
-
addComment: ({ body, alignment, userGroupId }) => mutate({
|
340
|
+
addComment: ({ body, alignment, userGroupId }: { body: string, alignment: number, userGroupId: string }) => mutate({
|
342
341
|
variables: {
|
343
342
|
commentableId: ownProps.commentable.id,
|
344
343
|
commentableType: ownProps.commentable.type,
|
345
344
|
body,
|
346
345
|
alignment,
|
347
|
-
userGroupId
|
346
|
+
userGroupId,
|
348
347
|
},
|
349
348
|
optimisticResponse: {
|
350
349
|
commentable: {
|
351
|
-
__typename:
|
350
|
+
__typename: "CommentableMutation",
|
352
351
|
addComment: {
|
353
|
-
__typename:
|
352
|
+
__typename: "Comment",
|
354
353
|
id: uuid(),
|
355
354
|
sgid: uuid(),
|
356
355
|
type: "Decidim::Comments::Comment",
|
357
356
|
createdAt: new Date().toISOString(),
|
358
357
|
body,
|
359
|
-
alignment
|
358
|
+
alignment,
|
360
359
|
author: {
|
361
|
-
__typename:
|
360
|
+
__typename: "User",
|
362
361
|
name: ownProps.session.user.name,
|
363
|
-
avatarUrl: ownProps.session.user.avatarUrl
|
362
|
+
avatarUrl: ownProps.session.user.avatarUrl,
|
364
363
|
},
|
365
364
|
comments: [],
|
366
365
|
hasComments: false,
|
@@ -369,32 +368,32 @@ const AddCommentFormWithMutation = graphql(gql`
|
|
369
368
|
upVoted: false,
|
370
369
|
downVotes: 0,
|
371
370
|
downVoted: false,
|
372
|
-
alreadyReported: false
|
373
|
-
}
|
374
|
-
}
|
371
|
+
alreadyReported: false,
|
372
|
+
},
|
373
|
+
},
|
375
374
|
},
|
376
375
|
updateQueries: {
|
377
|
-
GetComments: (prev, { mutationResult: { data } }) => {
|
376
|
+
GetComments: (prev: GetCommentsQuery, { mutationResult: { data } }: { mutationResult: { data: AddCommentMutation }}) => {
|
378
377
|
const { id, type } = ownProps.commentable;
|
379
|
-
const newComment = data.commentable.addComment;
|
378
|
+
const newComment = data.commentable && data.commentable.addComment;
|
380
379
|
let comments = [];
|
381
380
|
|
382
|
-
const commentReducer = (comment) => {
|
381
|
+
const commentReducer = (comment: CommentFragment): CommentFragment => {
|
383
382
|
const replies = comment.comments || [];
|
384
383
|
|
385
|
-
if (comment.id === id) {
|
384
|
+
if (newComment && comment.id === id) {
|
386
385
|
return {
|
387
386
|
...comment,
|
388
387
|
hasComments: true,
|
389
388
|
comments: [
|
390
389
|
...replies,
|
391
|
-
newComment
|
392
|
-
]
|
390
|
+
newComment,
|
391
|
+
],
|
393
392
|
};
|
394
393
|
}
|
395
394
|
return {
|
396
395
|
...comment,
|
397
|
-
comments: replies.map(commentReducer)
|
396
|
+
comments: replies.map(commentReducer),
|
398
397
|
};
|
399
398
|
};
|
400
399
|
|
@@ -403,7 +402,7 @@ const AddCommentFormWithMutation = graphql(gql`
|
|
403
402
|
} else {
|
404
403
|
comments = [
|
405
404
|
...prev.commentable.comments,
|
406
|
-
newComment
|
405
|
+
newComment,
|
407
406
|
];
|
408
407
|
}
|
409
408
|
|
@@ -411,13 +410,13 @@ const AddCommentFormWithMutation = graphql(gql`
|
|
411
410
|
...prev,
|
412
411
|
commentable: {
|
413
412
|
...prev.commentable,
|
414
|
-
comments
|
415
|
-
}
|
413
|
+
comments,
|
414
|
+
},
|
416
415
|
};
|
417
|
-
}
|
418
|
-
}
|
419
|
-
})
|
420
|
-
})
|
416
|
+
},
|
417
|
+
},
|
418
|
+
}),
|
419
|
+
}),
|
421
420
|
})(AddCommentForm);
|
422
421
|
|
423
422
|
export default AddCommentFormWithMutation;
|