diff --git a/Gemfile b/Gemfile index 285f5b8e..3ec15aca 100644 --- a/Gemfile +++ b/Gemfile @@ -17,9 +17,10 @@ gem "decidim-templates", "~> #{DECIDIM_VERSION}.0" # External Decidim gems gem "decidim-cache_cleaner" gem "decidim-simple_proposal", git: "https://github.com/mainio/decidim-module-simple_proposal", branch: DECIDIM_BRANCH -gem "decidim-decidim_awesome" +# TODO : Port the feature on official decidim-decidim_awesome repository and update this Gemfile +gem "decidim-decidim_awesome", git: "https://github.com/octree-gva/decidim-module-decidim_awesome.git", branch: "feat/awesome_decidim_private_fields" gem "decidim-friendly_signup", git: "https://github.com/OpenSourcePolitics/decidim-module-friendly_signup.git" -gem "decidim-phone_authorization_handler", git: "https://github.com/OpenSourcePolitics/decidim-module_phone_authorization_handler", branch: DECIDIM_BRANCH +gem "decidim-phone_authorization_handler", git: "https://github.com/OpenSourcePolitics/decidim-module_phone_authorization_handler", branch: "0.26/without-exports" gem "decidim-spam_detection" gem "decidim-term_customizer", git: "https://github.com/armandfardeau/decidim-module-term_customizer.git", branch: "fix/precompile-on-docker-0.26" diff --git a/Gemfile.lock b/Gemfile.lock index 03c6883c..4e53b27f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,8 +7,8 @@ GIT GIT remote: https://github.com/OpenSourcePolitics/decidim-module_phone_authorization_handler - revision: 488cc8827845ec1c5266aa499df2ebf9b20e02a3 - branch: release/0.26-stable + revision: f81cb7163cf60ca91bcb7889afb9e18d729d44e4 + branch: 0.26/without-exports specs: decidim-phone_authorization_handler (1.0.0) decidim-core (~> 0.26) @@ -46,6 +46,16 @@ GIT decidim-core (~> 0.26.0) decidim-proposals (~> 0.26.0) +GIT + remote: https://github.com/octree-gva/decidim-module-decidim_awesome.git + revision: 21ce064a26837ba43835621ddb6f6773b14c59e8 + branch: feat/awesome_decidim_private_fields + specs: + decidim-decidim_awesome (0.9.2) + decidim-admin (>= 0.26.0, < 0.28) + decidim-core (>= 0.26.0, < 0.28) + sassc (~> 2.3) + GIT remote: https://github.com/sgruhier/foundation_rails_helper.git revision: bc33600db7a2d16ce3cdc1f8369d0d7e7c4245b5 @@ -331,10 +341,6 @@ GEM decidim-debates (0.26.7) decidim-comments (= 0.26.7) decidim-core (= 0.26.7) - decidim-decidim_awesome (0.9.3) - decidim-admin (>= 0.26.0, < 0.28) - decidim-core (>= 0.26.0, < 0.28) - sassc (~> 2.3) decidim-dev (0.26.7) axe-core-rspec (~> 4.1.0) byebug (~> 11.0) @@ -938,6 +944,7 @@ GEM PLATFORMS arm64-darwin-21 + arm64-darwin-22 x86_64-darwin-21 x86_64-linux @@ -951,7 +958,7 @@ DEPENDENCIES dalli decidim (~> 0.26.0) decidim-cache_cleaner - decidim-decidim_awesome + decidim-decidim_awesome! decidim-dev (~> 0.26.0) decidim-friendly_signup! decidim-phone_authorization_handler! diff --git a/OVERLOADS.md b/OVERLOADS.md index 27aec3fb..a42da3b3 100644 --- a/OVERLOADS.md +++ b/OVERLOADS.md @@ -7,12 +7,6 @@ ## Load decidim-awesome assets only if dependencie is present * `app/views/layouts/decidim/_head.html.erb:33` -## Fix geocoded proposals -* `app/controllers/decidim/proposals/proposals_controller.rb:44` -```ruby - @all_geocoded_proposals = @base_query.geocoded.where.not(latitude: Float::NAN, longitude: Float::NAN) -``` - ## Fix meetings orders in indexes * `app/controllers/decidim/meetings/meetings_controller.rb` * `app/controllers/decidim/meetings/directory/meetings_controller.rb` @@ -175,3 +169,9 @@ d71197d - Add nil safety in migrate task, 2022-04-20 * `lib/decidim/test/promoted_participatory_processes_shared_examples.rb` f12c07d - Bump Develop on 0.25 (#104), 2022-05-10 + +* `app/views/decidim/proposals/proposals/_edit_form_fields.html.erb` +Modified from https://github.com/mainio/decidim-module-simple_proposal/blob/85ddd5f9519dc7d1e325a9776d6d5f134caf5943/app/views/decidim/proposals/proposals/_edit_form_fields.html.erb + +* `app/controllers/concerns/decidim/simple_proposal/proposals_controller_override.rb` +Modified from https://github.com/mainio/decidim-module-simple_proposal/blob/85ddd5f9519dc7d1e325a9776d6d5f134caf5943/app/controllers/concerns/decidim/simple_proposal/proposals_controller_override.rb \ No newline at end of file diff --git a/app/controllers/concerns/decidim/simple_proposal/proposals_controller_override.rb b/app/controllers/concerns/decidim/simple_proposal/proposals_controller_override.rb new file mode 100644 index 00000000..e5ece0d1 --- /dev/null +++ b/app/controllers/concerns/decidim/simple_proposal/proposals_controller_override.rb @@ -0,0 +1,200 @@ +# frozen_string_literal: true + +module Decidim + module SimpleProposal + module ProposalsControllerOverride + extend ActiveSupport::Concern + + included do + def index + if component_settings.participatory_texts_enabled? + @proposals = ::Decidim::Proposals::Proposal + .where(component: current_component, deleted_at: nil) + .published + .not_hidden + .only_amendables + .includes(:category, :scope) + .order(position: :asc) + render "decidim/proposals/proposals/participatory_texts/participatory_text" + else + @base_query = search + .results + .where(deleted_at: nil) + .published + .not_hidden + + @proposals = @base_query.includes(:component, :coauthorships) + @all_geocoded_proposals = @base_query.geocoded + .where.not(latitude: Float::NAN) + .where.not(longitude: Float::NAN) + + @voted_proposals = if current_user + ::Decidim::Proposals::ProposalVote.where( + author: current_user, + proposal: @proposals.pluck(:id) + ).pluck(:decidim_proposal_id) + else + [] + end + @proposals = paginate(@proposals) + @proposals = reorder(@proposals) + end + end + + def new + if proposal_draft.present? + redirect_to edit_draft_proposal_path(proposal_draft, component_id: proposal_draft.component.id, question_slug: proposal_draft.component.participatory_space.slug) + else + enforce_permission_to :create, :proposal + @step = :step_1 + @proposal ||= Decidim::Proposals::Proposal.new(component: current_component) + @form = form_proposal_model + @form.body = translated_proposal_body_template + @form.attachment = form_attachment_new + end + end + + def create + enforce_permission_to :create, :proposal + @step = :step_1 + @form = form(Decidim::Proposals::ProposalForm).from_params(proposal_creation_params) + + @proposal = Decidim::Proposals::Proposal.new(@form.attributes.except( + :user_group_id, + :category_id, + :scope_id, + :has_address, + :attachment, + :body_template, + :suggested_hashtags, + :photos, + :add_photos, + :documents, + :add_documents + ).merge( + component: current_component + )) + user_group = Decidim::UserGroup.find_by( + organization: current_organization, + id: params[:proposal][:user_group_id] + ) + @proposal.add_coauthor(current_user, user_group: user_group) + + # We could set these when creating proposal, but We want to call update because after that proposal becomes persisted + # and it adds coauthor correctly. + @proposal.update(title: { I18n.locale => @form.attributes[:title] }) + @proposal.update( + body: { I18n.locale => @form.attributes[:body] }, + private_body: { I18n.locale => @form.attributes[:private_body] } + ) + + Decidim::Proposals::UpdateProposal.call(@form, current_user, @proposal) do + on(:ok) do |proposal| + flash[:notice] = I18n.t("proposals.update_draft.success", scope: "decidim") + redirect_to "#{Decidim::ResourceLocatorPresenter.new(proposal).path}/preview" + end + + on(:invalid) do + flash.now[:alert] = I18n.t("proposals.update_draft.error", scope: "decidim") + render :new + end + end + end + + # Overridden because of a core bug when the command posts the "invalid" + # signal and when rendering the form. + def update_draft + enforce_permission_to :edit, :proposal, proposal: @proposal + @step = :step_1 + + @form = form_proposal_params + Decidim::Proposals::UpdateProposal.call(@form, current_user, @proposal) do + on(:ok) do |proposal| + flash[:notice] = I18n.t("proposals.update_draft.success", scope: "decidim") + redirect_to "#{Decidim::ResourceLocatorPresenter.new(proposal).path}/preview" + end + + on(:invalid) do + flash.now[:alert] = I18n.t("proposals.update_draft.error", scope: "decidim") + fix_form_photos_and_documents + render :edit_draft + end + end + end + + # On invalid render edit instead of edit_draft + def update + enforce_permission_to :edit, :proposal, proposal: @proposal + + @form = form_proposal_params + + Decidim::Proposals::UpdateProposal.call(@form, current_user, @proposal) do + on(:ok) do |proposal| + flash[:notice] = I18n.t("proposals.update.success", scope: "decidim") + redirect_to Decidim::ResourceLocatorPresenter.new(proposal).path + end + + on(:invalid) do + flash.now[:alert] = I18n.t("proposals.update.error", scope: "decidim") + fix_form_photos_and_documents + render :edit + end + end + end + + private + + def form_proposal_params + form(Decidim::Proposals::ProposalForm).from_params(params) + end + + def default_filter_params + { + search_text: "", + origin: default_filter_origin_params, + activity: "all", + category_id: default_filter_category_params, + state: %w(accepted evaluating state_not_published not_answered rejected), + scope_id: default_filter_scope_params, + related_to: "", + type: "all" + } + end + + def can_show_proposal? + return false if @proposal&.deleted_at.present? + return true if @proposal&.amendable? || current_user&.admin? + + Decidim::Proposals::Proposal.only_visible_emendations_for(current_user, current_component).published.include?(@proposal) + end + + def fix_form_photos_and_documents + return unless @form + + @form.photos = map_attachment_objects(@form.photos) + @form.documents = map_attachment_objects(@form.documents) + end + + # Maps the attachment objects for the proposal form in case there are errors + # on the form when it is being saved. Without this, the form would throw + # an exception because it expects these objects to be Attachment records. + def map_attachment_objects(attachments) + return attachments unless attachments.is_a?(Array) + + attachments.map do |attachment| + if attachment.is_a?(String) || attachment.is_a?(Integer) + Decidim::Attachment.find_by(id: attachment) + else + attachment + end + end + end + + # TODO: Remove after feature/configurable_order_for_proposals is merged! + # def default_order + # "recent" + # end + end + end + end +end diff --git a/app/controllers/decidim/proposals/proposals_controller.rb b/app/controllers/decidim/proposals/proposals_controller.rb deleted file mode 100644 index a54a7344..00000000 --- a/app/controllers/decidim/proposals/proposals_controller.rb +++ /dev/null @@ -1,301 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module Proposals - # Exposes the proposal resource so users can view and create them. - class ProposalsController < Decidim::Proposals::ApplicationController - helper Decidim::WidgetUrlsHelper - helper ProposalWizardHelper - helper ParticipatoryTextsHelper - helper UserGroupHelper - include Decidim::ApplicationHelper - include Flaggable - include Withdrawable - include FormFactory - include FilterResource - include Decidim::Proposals::Orderable - include Paginable - - helper_method :proposal_presenter, :form_presenter - - before_action :authenticate_user!, only: [:new, :create, :complete] - before_action :ensure_is_draft, only: [:compare, :complete, :preview, :publish, :edit_draft, :update_draft, :destroy_draft] - before_action :set_proposal, only: [:show, :edit, :update, :withdraw] - before_action :edit_form, only: [:edit_draft, :edit] - - before_action :set_participatory_text - - def index - if component_settings.participatory_texts_enabled? - @proposals = Decidim::Proposals::Proposal - .where(component: current_component) - .published - .not_hidden - .only_amendables - .includes(:category, :scope) - .order(position: :asc) - render "decidim/proposals/proposals/participatory_texts/participatory_text" - else - @base_query = search - .results - .published - .not_hidden - - @proposals = @base_query.includes(:component, :coauthorships) - @all_geocoded_proposals = @base_query.geocoded.where.not(latitude: Float::NAN, longitude: Float::NAN) - - @voted_proposals = if current_user - ProposalVote.where( - author: current_user, - proposal: @proposals.pluck(:id) - ).pluck(:decidim_proposal_id) - else - [] - end - @proposals = paginate(@proposals) - @proposals = reorder(@proposals) - end - end - - def show - raise ActionController::RoutingError, "Not Found" if @proposal.blank? || !can_show_proposal? - end - - def new - enforce_permission_to :create, :proposal - @step = :step_1 - if proposal_draft.present? - redirect_to edit_draft_proposal_path(proposal_draft, component_id: proposal_draft.component.id, question_slug: proposal_draft.component.participatory_space.slug) - else - @form = form(ProposalWizardCreateStepForm).from_params(body: translated_proposal_body_template) - end - end - - def create - enforce_permission_to :create, :proposal - @step = :step_1 - @form = form(ProposalWizardCreateStepForm).from_params(proposal_creation_params) - - CreateProposal.call(@form, current_user) do - on(:ok) do |proposal| - flash[:notice] = I18n.t("proposals.create.success", scope: "decidim") - - redirect_to "#{Decidim::ResourceLocatorPresenter.new(proposal).path}/compare" - end - - on(:invalid) do - flash.now[:alert] = I18n.t("proposals.create.error", scope: "decidim") - render :new - end - end - end - - def compare - enforce_permission_to :edit, :proposal, proposal: @proposal - @step = :step_2 - @similar_proposals ||= Decidim::Proposals::SimilarProposals - .for(current_component, @proposal) - .all - - if @similar_proposals.blank? - flash[:notice] = I18n.t("proposals.proposals.compare.no_similars_found", scope: "decidim") - redirect_to "#{Decidim::ResourceLocatorPresenter.new(@proposal).path}/complete" - end - end - - def complete - enforce_permission_to :edit, :proposal, proposal: @proposal - @step = :step_3 - - @form = form_proposal_model - - @form.attachment = form_attachment_new - end - - def preview - enforce_permission_to :edit, :proposal, proposal: @proposal - @step = :step_4 - @form = form(ProposalForm).from_model(@proposal) - end - - def publish - enforce_permission_to :edit, :proposal, proposal: @proposal - @step = :step_4 - PublishProposal.call(@proposal, current_user) do - on(:ok) do - flash[:notice] = I18n.t("proposals.publish.success", scope: "decidim") - redirect_to proposal_path(@proposal) - end - - on(:invalid) do - flash.now[:alert] = I18n.t("proposals.publish.error", scope: "decidim") - render :edit_draft - end - end - end - - def edit_draft - @step = :step_3 - enforce_permission_to :edit, :proposal, proposal: @proposal - end - - def update_draft - @step = :step_1 - enforce_permission_to :edit, :proposal, proposal: @proposal - - @form = form_proposal_params - UpdateProposal.call(@form, current_user, @proposal) do - on(:ok) do |proposal| - flash[:notice] = I18n.t("proposals.update_draft.success", scope: "decidim") - redirect_to "#{Decidim::ResourceLocatorPresenter.new(proposal).path}/preview" - end - - on(:invalid) do - flash.now[:alert] = I18n.t("proposals.update_draft.error", scope: "decidim") - render :edit_draft - end - end - end - - def destroy_draft - enforce_permission_to :edit, :proposal, proposal: @proposal - - DestroyProposal.call(@proposal, current_user) do - on(:ok) do - flash[:notice] = I18n.t("proposals.destroy_draft.success", scope: "decidim") - redirect_to new_proposal_path - end - - on(:invalid) do - flash.now[:alert] = I18n.t("proposals.destroy_draft.error", scope: "decidim") - render :edit_draft - end - end - end - - def edit - enforce_permission_to :edit, :proposal, proposal: @proposal - end - - def update - enforce_permission_to :edit, :proposal, proposal: @proposal - - @form = form_proposal_params - UpdateProposal.call(@form, current_user, @proposal) do - on(:ok) do |proposal| - flash[:notice] = I18n.t("proposals.update.success", scope: "decidim") - redirect_to Decidim::ResourceLocatorPresenter.new(proposal).path - end - - on(:invalid) do - flash.now[:alert] = I18n.t("proposals.update.error", scope: "decidim") - render :edit - end - end - end - - def withdraw - enforce_permission_to :withdraw, :proposal, proposal: @proposal - - WithdrawProposal.call(@proposal, current_user) do - on(:ok) do - flash[:notice] = I18n.t("proposals.update.success", scope: "decidim") - redirect_to Decidim::ResourceLocatorPresenter.new(@proposal).path - end - on(:has_supports) do - flash[:alert] = I18n.t("proposals.withdraw.errors.has_supports", scope: "decidim") - redirect_to Decidim::ResourceLocatorPresenter.new(@proposal).path - end - end - end - - private - - def search_klass - ProposalSearch - end - - def default_filter_params - { - search_text: "", - origin: default_filter_origin_params, - activity: "all", - category_id: default_filter_category_params, - state: %w(accepted evaluating state_not_published), - scope_id: default_filter_scope_params, - related_to: "", - type: "all" - } - end - - def default_filter_origin_params - filter_origin_params = %w(citizens meeting) - filter_origin_params << "official" if component_settings.official_proposals_enabled - filter_origin_params << "user_group" if current_organization.user_groups_enabled? - filter_origin_params - end - - def proposal_draft - Proposal.from_all_author_identities(current_user).not_hidden.only_amendables - .where(component: current_component).find_by(published_at: nil) - end - - def ensure_is_draft - @proposal = Proposal.not_hidden.where(component: current_component).find(params[:id]) - redirect_to Decidim::ResourceLocatorPresenter.new(@proposal).path unless @proposal.draft? - end - - def set_proposal - @proposal = Proposal.published.not_hidden.where(component: current_component).find_by(id: params[:id]) - end - - # Returns true if the proposal is NOT an emendation or the user IS an admin. - # Returns false if the proposal is not found or the proposal IS an emendation - # and is NOT visible to the user based on the component's amendments settings. - def can_show_proposal? - return true if @proposal&.amendable? || current_user&.admin? - - Proposal.only_visible_emendations_for(current_user, current_component).published.include?(@proposal) - end - - def proposal_presenter - @proposal_presenter ||= present(@proposal) - end - - def form_proposal_params - form(ProposalForm).from_params(params) - end - - def form_proposal_model - form(ProposalForm).from_model(@proposal) - end - - def form_presenter - @form_presenter ||= present(@form, presenter_class: Decidim::Proposals::ProposalPresenter) - end - - def form_attachment_new - form(AttachmentForm).from_model(Attachment.new) - end - - def edit_form - form_attachment_model = form(AttachmentForm).from_model(@proposal.attachments.first) - @form = form_proposal_model - @form.attachment = form_attachment_model - @form - end - - def set_participatory_text - @participatory_text = Decidim::Proposals::ParticipatoryText.find_by(component: current_component) - end - - def translated_proposal_body_template - translated_attribute component_settings.new_proposal_body_template - end - - def proposal_creation_params - params[:proposal].merge(body_template: translated_proposal_body_template) - end - end - end -end diff --git a/app/views/decidim/devise/passwords/new.html.erb b/app/views/decidim/devise/passwords/new.html.erb index ebf006d7..2857eb58 100644 --- a/app/views/decidim/devise/passwords/new.html.erb +++ b/app/views/decidim/devise/passwords/new.html.erb @@ -34,4 +34,4 @@ - \ No newline at end of file + diff --git a/app/views/decidim/devise/shared/_omniauth_buttons.html.erb b/app/views/decidim/devise/shared/_omniauth_buttons.html.erb index 5679bc78..a3a25bd6 100644 --- a/app/views/decidim/devise/shared/_omniauth_buttons.html.erb +++ b/app/views/decidim/devise/shared/_omniauth_buttons.html.erb @@ -14,7 +14,7 @@ <% if I18n.exists?("decidim.omniauth.france_connect.external.link") %>