decidim-proposals 0.29.3 → 0.30.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/cells/decidim/proposals/highlighted_proposals_for_component/show.erb +13 -1
- data/app/cells/decidim/proposals/highlighted_proposals_for_component_cell.rb +1 -1
- data/app/cells/decidim/proposals/participatory_text_proposal_cell.rb +1 -1
- data/app/cells/decidim/proposals/proposal_g/show.erb +13 -0
- data/app/cells/decidim/proposals/proposal_g_cell.rb +13 -0
- data/app/cells/decidim/proposals/proposal_history_cell.rb +107 -0
- data/app/cells/decidim/proposals/proposal_l/show.erb +37 -0
- data/app/cells/decidim/proposals/proposal_l_cell.rb +9 -0
- data/app/cells/decidim/proposals/proposal_metadata_cell.rb +2 -2
- data/app/cells/decidim/proposals/proposal_vote/show.erb +75 -0
- data/app/cells/decidim/proposals/proposal_vote_cell.rb +43 -0
- data/app/commands/decidim/proposals/accept_coauthorship.rb +62 -0
- data/app/commands/decidim/proposals/admin/assign_proposals_to_valuator.rb +14 -0
- data/app/commands/decidim/proposals/admin/create_proposal.rb +6 -14
- data/app/commands/decidim/proposals/admin/create_proposal_note.rb +20 -11
- data/app/commands/decidim/proposals/admin/import_proposals.rb +60 -7
- data/app/commands/decidim/proposals/admin/merge_proposals.rb +2 -2
- data/app/commands/decidim/proposals/admin/proposal_notes_methods.rb +48 -0
- data/app/commands/decidim/proposals/admin/reply_proposal_note.rb +92 -0
- data/app/commands/decidim/proposals/admin/split_proposals.rb +2 -2
- data/app/commands/decidim/proposals/admin/update_proposal.rb +10 -16
- data/app/commands/decidim/proposals/admin/update_proposal_taxonomies.rb +34 -0
- data/app/commands/decidim/proposals/cancel_coauthorship.rb +32 -0
- data/app/commands/decidim/proposals/create_collaborative_draft.rb +1 -2
- data/app/commands/decidim/proposals/create_proposal.rb +1 -2
- data/app/commands/decidim/proposals/invite_coauthor.rb +45 -0
- data/app/commands/decidim/proposals/publish_collaborative_draft.rb +1 -2
- data/app/commands/decidim/proposals/reject_coauthorship.rb +54 -0
- data/app/commands/decidim/proposals/update_collaborative_draft.rb +1 -2
- data/app/commands/decidim/proposals/update_proposal.rb +1 -2
- data/app/controllers/concerns/decidim/proposals/admin/filterable.rb +5 -1
- data/app/controllers/concerns/decidim/proposals/admin/needs_interpolations.rb +40 -0
- data/app/controllers/decidim/proposals/admin/proposal_answers_controller.rb +46 -5
- data/app/controllers/decidim/proposals/admin/proposal_notes_controller.rb +18 -0
- data/app/controllers/decidim/proposals/admin/proposals_controller.rb +41 -85
- data/app/controllers/decidim/proposals/admin/proposals_imports_controller.rb +2 -2
- data/app/controllers/decidim/proposals/collaborative_drafts_controller.rb +2 -4
- data/app/controllers/decidim/proposals/invite_coauthors_controller.rb +87 -0
- data/app/controllers/decidim/proposals/proposals_controller.rb +7 -32
- data/app/controllers/decidim/proposals/versions_controller.rb +1 -1
- data/app/events/decidim/proposals/accepted_coauthorship_event.rb +8 -0
- data/app/events/decidim/proposals/admin/proposal_assigned_to_valuator_event.rb +27 -0
- data/app/events/decidim/proposals/admin/proposal_note_created_event.rb +5 -0
- data/app/events/decidim/proposals/coauthor_accepted_invite_event.rb +49 -0
- data/app/events/decidim/proposals/coauthor_invited_event.rb +45 -0
- data/app/events/decidim/proposals/coauthor_rejected_invite_event.rb +8 -0
- data/app/events/decidim/proposals/rejected_coauthorship_event.rb +8 -0
- data/app/events/decidim/proposals/update_proposal_taxonomies_event.rb +9 -0
- data/app/forms/decidim/proposals/admin/proposal_answer_form.rb +16 -0
- data/app/forms/decidim/proposals/admin/proposal_base_form.rb +3 -31
- data/app/forms/decidim/proposals/admin/proposal_form.rb +11 -6
- data/app/forms/decidim/proposals/admin/proposals_import_form.rb +0 -5
- data/app/forms/decidim/proposals/collaborative_draft_form.rb +0 -8
- data/app/forms/decidim/proposals/proposal_form.rb +5 -32
- data/app/helpers/decidim/proposals/admin/proposal_bulk_actions_helper.rb +25 -0
- data/app/helpers/decidim/proposals/admin/proposals_helper.rb +0 -1
- data/app/helpers/decidim/proposals/application_helper.rb +23 -15
- data/app/helpers/decidim/proposals/collaborative_draft_helper.rb +7 -7
- data/app/helpers/decidim/proposals/map_helper.rb +0 -18
- data/app/helpers/decidim/proposals/proposal_votes_helper.rb +15 -2
- data/app/helpers/decidim/proposals/proposals_helper.rb +3 -1
- data/app/jobs/decidim/proposals/admin/proposal_answer_job.rb +20 -0
- data/app/models/decidim/proposals/collaborative_draft.rb +13 -3
- data/app/models/decidim/proposals/proposal.rb +71 -5
- data/app/models/decidim/proposals/proposal_note.rb +11 -0
- data/app/models/decidim/proposals/proposal_state.rb +1 -1
- data/app/packs/entrypoints/decidim_proposals.js +1 -0
- data/app/packs/entrypoints/decidim_proposals_geocoding.js +2 -0
- data/app/packs/src/decidim/proposals/admin/proposals.js +16 -1
- data/app/packs/src/decidim/proposals/exit_handler.js +73 -0
- data/app/packs/stylesheets/decidim/proposals/proposals.scss +248 -3
- data/app/permissions/decidim/proposals/admin/permissions.rb +2 -5
- data/app/permissions/decidim/proposals/permissions.rb +42 -0
- data/app/presenters/decidim/proposals/admin_log/proposal_presenter.rb +1 -1
- data/app/presenters/decidim/proposals/proposal_presenter.rb +1 -1
- data/app/queries/decidim/proposals/filtered_proposals.rb +2 -2
- data/app/queries/decidim/proposals/metrics/accepted_proposals_metric_manage.rb +2 -2
- data/app/queries/decidim/proposals/metrics/endorsements_metric_manage.rb +10 -10
- data/app/queries/decidim/proposals/metrics/proposal_followers_metric_measure.rb +4 -4
- data/app/queries/decidim/proposals/metrics/proposal_participants_metric_measure.rb +6 -6
- data/app/queries/decidim/proposals/metrics/proposals_metric_manage.rb +6 -6
- data/app/queries/decidim/proposals/metrics/votes_metric_manage.rb +6 -6
- data/app/services/decidim/proposals/proposal_builder.rb +1 -2
- data/app/views/decidim/proposals/admin/proposal_notes/_form.html.erb +3 -3
- data/app/views/decidim/proposals/admin/proposal_notes/_proposal_note.html.erb +28 -0
- data/app/views/decidim/proposals/admin/proposal_notes/_proposal_note_reply.html.erb +9 -0
- data/app/views/decidim/proposals/admin/proposal_notes/_proposal_notes.html.erb +4 -28
- data/app/views/decidim/proposals/admin/proposal_states/_form.html.erb +1 -1
- data/app/views/decidim/proposals/admin/proposals/_actions.html.erb +21 -0
- data/app/views/decidim/proposals/admin/proposals/_bulk-actions.html.erb +3 -2
- data/app/views/decidim/proposals/admin/proposals/_form.html.erb +17 -24
- data/app/views/decidim/proposals/admin/proposals/_proposal-tr.html.erb +12 -28
- data/app/views/decidim/proposals/admin/proposals/_proposals-thead.html.erb +45 -0
- data/app/views/decidim/proposals/admin/proposals/bulk_actions/_apply_answer_template.html.erb +22 -0
- data/app/views/decidim/proposals/admin/proposals/bulk_actions/_dropdown.html.erb +15 -11
- data/app/views/decidim/proposals/admin/proposals/bulk_actions/_taxonomy_change.html.erb +23 -0
- data/app/views/decidim/proposals/admin/proposals/index.html.erb +17 -48
- data/app/views/decidim/proposals/admin/proposals/manage_trash.html.erb +18 -0
- data/app/views/decidim/proposals/admin/proposals/publish_answers.js.erb +1 -1
- data/app/views/decidim/proposals/admin/proposals/show.html.erb +14 -26
- data/app/views/decidim/proposals/admin/proposals/update_attribute.js.erb +1 -1
- data/app/views/decidim/proposals/admin/proposals_imports/new.html.erb +0 -3
- data/app/views/decidim/proposals/collaborative_drafts/_collaborative_actions.html.erb +9 -0
- data/app/views/decidim/proposals/collaborative_drafts/_collaborative_draft_aside.html.erb +0 -15
- data/app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb +4 -6
- data/app/views/decidim/proposals/collaborative_drafts/index.html.erb +6 -2
- data/app/views/decidim/proposals/collaborative_drafts/show.html.erb +27 -11
- data/app/views/decidim/proposals/proposal_votes/update_buttons_and_counters.js.erb +29 -9
- data/app/views/decidim/proposals/proposals/_actions.html.erb +4 -7
- data/app/views/decidim/proposals/proposals/_edit_form_fields.html.erb +17 -22
- data/app/views/decidim/proposals/proposals/_exit_modal.html.erb +17 -0
- data/app/views/decidim/proposals/proposals/_notification_alert_box.html.erb +1 -0
- data/app/views/decidim/proposals/proposals/_proposal_actions.html.erb +19 -0
- data/app/views/decidim/proposals/proposals/_proposal_aside.html.erb +9 -32
- data/app/views/decidim/proposals/proposals/_proposal_voting_rules.html.erb +33 -0
- data/app/views/decidim/proposals/proposals/_proposals.html.erb +1 -1
- data/app/views/decidim/proposals/proposals/_remaining_votes_count.html.erb +2 -2
- data/app/views/decidim/proposals/proposals/_remaining_votes_notification.html.erb +12 -0
- data/app/views/decidim/proposals/proposals/_update_proposal_voting_rules.html.erb +6 -0
- data/app/views/decidim/proposals/proposals/_vote_button.html.erb +12 -8
- data/app/views/decidim/proposals/proposals/_votes_count.html.erb +2 -1
- data/app/views/decidim/proposals/proposals/_voting_rules.html.erb +1 -7
- data/app/views/decidim/proposals/proposals/index.html.erb +3 -18
- data/app/views/decidim/proposals/proposals/index.js.erb +1 -1
- data/app/views/decidim/proposals/proposals/participatory_texts/_proposal_vote_button.html.erb +3 -1
- data/app/views/decidim/proposals/proposals/show.html.erb +35 -15
- data/config/locales/ar.yml +15 -73
- data/config/locales/bg.yml +12 -89
- data/config/locales/bs-BA.yml +2 -13
- data/config/locales/ca.yml +209 -84
- data/config/locales/cs.yml +210 -81
- data/config/locales/de.yml +213 -89
- data/config/locales/el.yml +12 -84
- data/config/locales/en.yml +206 -81
- data/config/locales/es-MX.yml +213 -88
- data/config/locales/es-PY.yml +213 -88
- data/config/locales/es.yml +214 -89
- data/config/locales/eu.yml +288 -164
- data/config/locales/fi-plain.yml +213 -87
- data/config/locales/fi.yml +213 -87
- data/config/locales/fr-CA.yml +116 -97
- data/config/locales/fr.yml +116 -97
- data/config/locales/ga-IE.yml +1 -21
- data/config/locales/gl.yml +8 -45
- data/config/locales/hu.yml +12 -68
- data/config/locales/id-ID.yml +9 -43
- data/config/locales/is-IS.yml +0 -19
- data/config/locales/it.yml +11 -77
- data/config/locales/ja.yml +165 -106
- data/config/locales/lt.yml +13 -85
- data/config/locales/lv.yml +10 -52
- data/config/locales/nl.yml +10 -59
- data/config/locales/no.yml +10 -44
- data/config/locales/pl.yml +11 -88
- data/config/locales/pt-BR.yml +9 -74
- data/config/locales/pt.yml +10 -56
- data/config/locales/ro-RO.yml +12 -72
- data/config/locales/ru.yml +0 -23
- data/config/locales/sk.yml +10 -52
- data/config/locales/sr-CS.yml +2 -14
- data/config/locales/sv.yml +127 -86
- data/config/locales/tr-TR.yml +10 -53
- data/config/locales/uk.yml +0 -23
- data/config/locales/zh-CN.yml +10 -53
- data/config/locales/zh-TW.yml +12 -86
- data/db/migrate/20171220084719_add_published_at_to_proposals.rb +1 -1
- data/db/migrate/20181016132225_add_organization_as_author.rb +1 -1
- data/db/migrate/20200120215928_move_proposal_endorsements_to_core_endorsements.rb +1 -1
- data/db/migrate/20200827154156_add_commentable_counter_cache_to_proposals.rb +3 -3
- data/db/migrate/20210310102839_add_followable_counter_cache_to_proposals.rb +1 -1
- data/db/migrate/20240110203504_create_default_proposal_states.rb +1 -1
- data/db/migrate/20240404202756_add_valuation_assignments_count_to_decidim_proposals_proposals.rb +1 -1
- data/db/migrate/20240617091140_add_email_on_assigned_proposals_to_users.rb +7 -0
- data/db/migrate/20240617170052_add_parent_relation_to_decidim_proposal_notes.rb +7 -0
- data/db/migrate/20240828103755_add_deleted_at_to_decidim_proposals_proposals.rb +8 -0
- data/decidim-proposals.gemspec +1 -1
- data/lib/decidim/api/functions/proposal_finder_helper.rb +12 -0
- data/lib/decidim/api/functions/proposal_list_helper.rb +12 -0
- data/lib/decidim/api/proposal_type.rb +17 -25
- data/lib/decidim/api/proposals_type.rb +4 -19
- data/lib/decidim/proposals/admin_engine.rb +12 -3
- data/lib/decidim/proposals/admin_filter.rb +3 -6
- data/lib/decidim/proposals/component.rb +4 -5
- data/lib/decidim/proposals/download_your_data_proposal_serializer.rb +15 -0
- data/lib/decidim/proposals/engine.rb +5 -0
- data/lib/decidim/proposals/import/proposal_creator.rb +4 -4
- data/lib/decidim/proposals/proposal_serializer.rb +12 -29
- data/lib/decidim/proposals/seeds.rb +21 -17
- data/lib/decidim/proposals/test/factories.rb +2 -1
- data/lib/decidim/proposals/version.rb +1 -1
- data/lib/decidim/proposals.rb +4 -0
- data/lib/tasks/proposals/upgrade/decidim_proposals_upgrade_tasks.rake +0 -22
- metadata +65 -34
- data/app/commands/decidim/proposals/admin/update_proposal_category.rb +0 -70
- data/app/commands/decidim/proposals/admin/update_proposal_scope.rb +0 -75
- data/app/events/decidim/proposals/admin/update_proposal_category_event.rb +0 -11
- data/app/events/decidim/proposals/admin/update_proposal_scope_event.rb +0 -11
- data/app/jobs/decidim/proposals/admin/import_proposals_job.rb +0 -91
- data/app/mailers/decidim/proposals/admin/import_proposals_mailer.rb +0 -30
- data/app/views/decidim/proposals/admin/import_proposals_mailer/notify_failure.html.erb +0 -1
- data/app/views/decidim/proposals/admin/import_proposals_mailer/notify_success.html.erb +0 -2
- data/app/views/decidim/proposals/admin/proposals/bulk_actions/_recategorize.html.erb +0 -15
- data/app/views/decidim/proposals/admin/proposals/bulk_actions/_scope-change.html.erb +0 -21
- data/app/views/decidim/proposals/collaborative_drafts/_actions.html.erb +0 -7
- data/config/locales/ca-IT.yml +0 -945
@@ -7,6 +7,7 @@ module Decidim
|
|
7
7
|
include Decidim::Resourceable
|
8
8
|
include Decidim::Coauthorable
|
9
9
|
include Decidim::HasComponent
|
10
|
+
include Decidim::Taxonomizable
|
10
11
|
include Decidim::ScopableResource
|
11
12
|
include Decidim::HasReference
|
12
13
|
include Decidim::HasCategory
|
@@ -28,6 +29,7 @@ module Decidim
|
|
28
29
|
include Decidim::TranslatableResource
|
29
30
|
include Decidim::TranslatableAttributes
|
30
31
|
include Decidim::FilterableResource
|
32
|
+
include Decidim::SoftDeletable
|
31
33
|
|
32
34
|
def assign_state(token)
|
33
35
|
proposal_state = Decidim::Proposals::ProposalState.where(component:, token:).first
|
@@ -301,6 +303,11 @@ module Decidim
|
|
301
303
|
state == "evaluating"
|
302
304
|
end
|
303
305
|
|
306
|
+
# Public: Overrides the `reported_content_url` Reportable concern method.
|
307
|
+
def reported_content_url
|
308
|
+
ResourceLocatorPresenter.new(self).url
|
309
|
+
end
|
310
|
+
|
304
311
|
# Returns the presenter for this author, to be used in the views.
|
305
312
|
# Required by ResourceRenderer.
|
306
313
|
def presenter
|
@@ -398,13 +405,21 @@ module Decidim
|
|
398
405
|
end
|
399
406
|
|
400
407
|
def self.ransackable_scopes(_auth_object = nil)
|
401
|
-
[:with_any_origin, :with_any_state, :state_eq, :voted_by, :coauthored_by, :related_to, :
|
408
|
+
[:with_any_origin, :with_any_state, :state_eq, :voted_by, :coauthored_by, :related_to, :with_any_taxonomies, :valuator_role_ids_has]
|
402
409
|
end
|
403
410
|
|
404
411
|
# Create i18n ransackers for :title and :body.
|
405
412
|
# Create the :search_text ransacker alias for searching from both of these.
|
406
413
|
ransacker_i18n_multi :search_text, [:title, :body]
|
407
414
|
|
415
|
+
def self.ransackable_attributes(_auth_object = nil)
|
416
|
+
%w(id_string search_text title body is_emendation comments_count proposal_votes_count published_at proposal_notes_count)
|
417
|
+
end
|
418
|
+
|
419
|
+
def self.ransackable_associations(_auth_object = nil)
|
420
|
+
%w(taxonomies proposal_state)
|
421
|
+
end
|
422
|
+
|
408
423
|
ransacker :state_published do
|
409
424
|
Arel.sql("CASE
|
410
425
|
WHEN EXISTS (
|
@@ -450,7 +465,7 @@ module Decidim
|
|
450
465
|
end
|
451
466
|
|
452
467
|
def self.export_serializer
|
453
|
-
Decidim::Proposals::
|
468
|
+
Decidim::Proposals::DownloadYourDataProposalSerializer
|
454
469
|
end
|
455
470
|
|
456
471
|
def self.download_your_data_images(user)
|
@@ -467,8 +482,18 @@ module Decidim
|
|
467
482
|
return true if draft?
|
468
483
|
return true if component.settings.proposal_edit_time == "infinite"
|
469
484
|
|
470
|
-
|
471
|
-
|
485
|
+
time_value, time_unit = component.settings.edit_time
|
486
|
+
|
487
|
+
limit_time = case time_unit
|
488
|
+
when "minutes"
|
489
|
+
updated_at + time_value.minutes
|
490
|
+
when "hours"
|
491
|
+
updated_at + time_value.hours
|
492
|
+
else
|
493
|
+
updated_at + time_value.days
|
494
|
+
end
|
495
|
+
|
496
|
+
Time.current < limit_time
|
472
497
|
end
|
473
498
|
|
474
499
|
def process_amendment_state_change!
|
@@ -481,10 +506,51 @@ module Decidim
|
|
481
506
|
end
|
482
507
|
end
|
483
508
|
|
509
|
+
def user_has_actions?(user)
|
510
|
+
return false if authors.include?(user)
|
511
|
+
return false if user&.blocked?
|
512
|
+
return false if user&.deleted?
|
513
|
+
return false unless user&.confirmed?
|
514
|
+
|
515
|
+
true
|
516
|
+
end
|
517
|
+
|
518
|
+
def actions_for_comment(comment, current_user)
|
519
|
+
return if comment.commentable != self
|
520
|
+
return unless authors.include?(current_user)
|
521
|
+
return unless user_has_actions?(comment.author)
|
522
|
+
|
523
|
+
if coauthor_invitations_for(comment.author).any?
|
524
|
+
[
|
525
|
+
{
|
526
|
+
label: I18n.t("decidim.proposals.actions.cancel_coauthor_invitation"),
|
527
|
+
url: EngineRouter.main_proxy(component).cancel_proposal_invite_coauthors_path(proposal_id: id, id: comment.author.id),
|
528
|
+
icon: "user-forbid-line",
|
529
|
+
method: :delete,
|
530
|
+
data: { confirm: I18n.t("decidim.proposals.actions.cancel_coauthor_invitation_confirm") }
|
531
|
+
}
|
532
|
+
]
|
533
|
+
else
|
534
|
+
[
|
535
|
+
{
|
536
|
+
label: I18n.t("decidim.proposals.actions.mark_as_coauthor"),
|
537
|
+
url: EngineRouter.main_proxy(component).proposal_invite_coauthors_path(proposal_id: id, id: comment.author.id),
|
538
|
+
icon: "user-add-line",
|
539
|
+
method: :post,
|
540
|
+
data: { confirm: I18n.t("decidim.proposals.actions.mark_as_coauthor_confirm") }
|
541
|
+
}
|
542
|
+
]
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
def coauthor_invitations_for(user)
|
547
|
+
Decidim::Notification.where(event_class: "Decidim::Proposals::CoauthorInvitedEvent", resource: self, user:)
|
548
|
+
end
|
549
|
+
|
484
550
|
private
|
485
551
|
|
486
552
|
def copied_from_other_component?
|
487
|
-
linked_resources(:proposals,
|
553
|
+
linked_resources(:proposals, %w(splitted_from_component merged_from_component copied_from_component)).any?
|
488
554
|
end
|
489
555
|
end
|
490
556
|
end
|
@@ -9,12 +9,23 @@ module Decidim
|
|
9
9
|
|
10
10
|
belongs_to :proposal, foreign_key: "decidim_proposal_id", class_name: "Decidim::Proposals::Proposal", counter_cache: true
|
11
11
|
belongs_to :author, foreign_key: "decidim_author_id", class_name: "Decidim::User"
|
12
|
+
has_many :replies, foreign_key: "parent_id", class_name: "Decidim::Proposals::ProposalNote", inverse_of: :parent, dependent: :destroy
|
13
|
+
belongs_to :parent, class_name: "Decidim::Proposals::ProposalNote", inverse_of: :replies, optional: true
|
12
14
|
|
15
|
+
scope :not_reply, -> { where(parent_id: nil) }
|
13
16
|
default_scope { order(created_at: :asc) }
|
14
17
|
|
15
18
|
def self.log_presenter_class_for(_log)
|
16
19
|
Decidim::Proposals::AdminLog::ProposalNotePresenter
|
17
20
|
end
|
21
|
+
|
22
|
+
def reply?
|
23
|
+
parent.present?
|
24
|
+
end
|
25
|
+
|
26
|
+
def formatted_body
|
27
|
+
Decidim::ContentProcessor.render_without_format(body)
|
28
|
+
end
|
18
29
|
end
|
19
30
|
end
|
20
31
|
end
|
@@ -38,7 +38,7 @@ module Decidim
|
|
38
38
|
protected
|
39
39
|
|
40
40
|
def generate_token
|
41
|
-
self.token = ensure_unique_token(translated_attribute(title).parameterize(separator: "_"))
|
41
|
+
self.token = ensure_unique_token(token.presence || translated_attribute(title).parameterize(separator: "_"))
|
42
42
|
end
|
43
43
|
|
44
44
|
def ensure_unique_token(token)
|
@@ -13,13 +13,20 @@ $(() => {
|
|
13
13
|
return $(".table-list [data-published-state=false] .js-check-all-proposal:checked").length
|
14
14
|
}
|
15
15
|
|
16
|
+
const selectedProposalsAllowsAnswerCount = function() {
|
17
|
+
return $(".table-list [data-allow-answer=true] .js-check-all-proposal:checked").length
|
18
|
+
}
|
19
|
+
|
16
20
|
const selectedProposalsCountUpdate = function() {
|
17
21
|
const selectedProposals = selectedProposalsCount();
|
18
22
|
const selectedProposalsNotPublishedAnswer = selectedProposalsNotPublishedAnswerCount();
|
23
|
+
const allowAnswerProposals = selectedProposalsAllowsAnswerCount();
|
24
|
+
|
19
25
|
if (selectedProposals === 0) {
|
20
26
|
$("#js-selected-proposals-count").text("")
|
21
27
|
$("#js-assign-proposals-to-valuator-actions").addClass("hide");
|
22
28
|
$("#js-unassign-proposals-from-valuator-actions").addClass("hide");
|
29
|
+
$("#js-taxonomy-change-proposals-actions").addClass("hide");
|
23
30
|
} else {
|
24
31
|
$("#js-selected-proposals-count").text(selectedProposals);
|
25
32
|
}
|
@@ -36,6 +43,13 @@ $(() => {
|
|
36
43
|
} else {
|
37
44
|
$('button[data-action="publish-answers"]').parent().hide();
|
38
45
|
}
|
46
|
+
|
47
|
+
if (allowAnswerProposals > 0) {
|
48
|
+
$('button[data-action="apply-answer-template"]').parent().show();
|
49
|
+
$("#js-form-apply-answer-template-number").text(allowAnswerProposals);
|
50
|
+
} else {
|
51
|
+
$('button[data-action="apply-answer-template"]').parent().hide();
|
52
|
+
}
|
39
53
|
}
|
40
54
|
|
41
55
|
const showBulkActionsButton = function() {
|
@@ -91,7 +105,8 @@ $(() => {
|
|
91
105
|
let action = $(e.target).data("action");
|
92
106
|
const panelActions = [
|
93
107
|
"assign-proposals-to-valuator",
|
94
|
-
"unassign-proposals-from-valuator"
|
108
|
+
"unassign-proposals-from-valuator",
|
109
|
+
"taxonomy-change-proposals"
|
95
110
|
];
|
96
111
|
|
97
112
|
if (!action) {
|
@@ -0,0 +1,73 @@
|
|
1
|
+
const allowExitFrom = (el) => {
|
2
|
+
if (el.id === "exit-proposal-notification-link" || el.classList.contains("no-modal")) {
|
3
|
+
return true;
|
4
|
+
}
|
5
|
+
|
6
|
+
return false;
|
7
|
+
};
|
8
|
+
|
9
|
+
document.addEventListener("DOMContentLoaded", () => {
|
10
|
+
const exitNotification = document.getElementById("exit-proposal-notification");
|
11
|
+
const exitLink = document.getElementById("exit-proposal-notification-link");
|
12
|
+
if (!exitLink) {
|
13
|
+
return;
|
14
|
+
}
|
15
|
+
const defaultExitUrl = exitLink.href;
|
16
|
+
const defaultExitLinkText = exitLink.textContent;
|
17
|
+
const signOutPath = window.Decidim.config.get("sign_out_path");
|
18
|
+
let exitLinkText = defaultExitLinkText;
|
19
|
+
|
20
|
+
if (!exitNotification) {
|
21
|
+
// Do not apply when not inside the voting pipeline
|
22
|
+
return;
|
23
|
+
}
|
24
|
+
|
25
|
+
const openExitNotification = (url, method = null) => {
|
26
|
+
if (method && method !== "get") {
|
27
|
+
exitLink.setAttribute("data-method", method);
|
28
|
+
} else {
|
29
|
+
exitLink.removeAttribute("data-method");
|
30
|
+
}
|
31
|
+
|
32
|
+
exitLink.setAttribute("href", url);
|
33
|
+
exitLink.textContent = exitLinkText;
|
34
|
+
window.Decidim.currentDialogs["exit-proposal-notification"].open();
|
35
|
+
};
|
36
|
+
|
37
|
+
const handleClicks = (link) => {
|
38
|
+
link.addEventListener("click", (event) => {
|
39
|
+
exitLinkText = defaultExitLinkText;
|
40
|
+
|
41
|
+
if (
|
42
|
+
!allowExitFrom(link) &&
|
43
|
+
((window.Decidim.currentDialogs["exit-proposal-notification"].dialog.querySelector("[data-dialog-container]")).dataset.minimumVotesReached !== "true") &&
|
44
|
+
((window.Decidim.currentDialogs["exit-proposal-notification"].dialog.querySelector("[data-dialog-container]")).dataset.minimumVotesCount > 0)
|
45
|
+
) {
|
46
|
+
event.preventDefault();
|
47
|
+
openExitNotification(link.getAttribute("href"), link.dataset.method);
|
48
|
+
}
|
49
|
+
});
|
50
|
+
};
|
51
|
+
|
52
|
+
document.querySelectorAll("a").forEach(handleClicks);
|
53
|
+
// Custom handling for the header sign-out link
|
54
|
+
const signOutLink = document.querySelector(`[href='${signOutPath}']`);
|
55
|
+
if (signOutLink) {
|
56
|
+
signOutLink.addEventListener("click", (event) => {
|
57
|
+
event.preventDefault();
|
58
|
+
event.stopPropagation();
|
59
|
+
|
60
|
+
exitLinkText = signOutLink.textContent;
|
61
|
+
openExitNotification(signOutLink.getAttribute("href"), signOutLink.dataset.method);
|
62
|
+
});
|
63
|
+
}
|
64
|
+
|
65
|
+
// Custom handling for links that open the exit notification dialog
|
66
|
+
const dialogOpenLinks = document.querySelectorAll("a[data-dialog-open='exit-proposal-notification']");
|
67
|
+
dialogOpenLinks.forEach((link) => {
|
68
|
+
link.addEventListener("click", () => {
|
69
|
+
exitLinkText = defaultExitLinkText;
|
70
|
+
openExitNotification(defaultExitUrl);
|
71
|
+
});
|
72
|
+
});
|
73
|
+
});
|
@@ -103,11 +103,213 @@
|
|
103
103
|
}
|
104
104
|
|
105
105
|
&__grid-text-title {
|
106
|
-
@apply flex justify-between flex-row md:flex-col
|
106
|
+
@apply flex justify-between items-start gap-y-2 flex-row md:flex-col lg:flex-row;
|
107
107
|
}
|
108
108
|
|
109
|
-
&__list-
|
110
|
-
|
109
|
+
&__list-list {
|
110
|
+
.card__proposals-item {
|
111
|
+
@apply border-l-4 rounded-[10px] md:rounded-md border-[#F5F5F5] hover:border-tertiary focus-visible:border-tertiary flex flex-col md:items-center md:flex-row md:justify-between min-h-0 md:min-h-[127px] lg:min-h-[83px];
|
112
|
+
|
113
|
+
.card__list {
|
114
|
+
@apply border-none md:flex-1 md:items-center mb-2.5 md:mb-0;
|
115
|
+
|
116
|
+
&-metadata {
|
117
|
+
@apply gap-y-1 md:flex md:flex-row md:items-center md:gap-x-2 md:mt-0.5;
|
118
|
+
|
119
|
+
& > div {
|
120
|
+
@apply md:pl-0 md:pr-2;
|
121
|
+
}
|
122
|
+
}
|
123
|
+
}
|
124
|
+
|
125
|
+
.card__proposals-votes {
|
126
|
+
@apply flex md:flex-col lg:flex-row bg-[#F5F5F5] justify-around md:flex-[0.6] lg:flex-[0.8] items-center md:items-stretch lg:items-center lg:min-w-[196px] h-[68px] md:h-auto lg:h-[68px];
|
127
|
+
|
128
|
+
button {
|
129
|
+
@apply bg-[var(--secondary)];
|
130
|
+
|
131
|
+
&[disabled] {
|
132
|
+
@apply opacity-50 text-white border-current cursor-not-allowed;
|
133
|
+
}
|
134
|
+
}
|
135
|
+
|
136
|
+
&-limited {
|
137
|
+
@apply flex flex-col p-0 md:p-2 lg:p-0 md:flex-row md:flex-wrap lg:flex-col lg:flex-nowrap flex-1 md:flex-none lg:flex-1 justify-center;
|
138
|
+
|
139
|
+
.proposals__aside-progress {
|
140
|
+
@apply flex flex-col w-[80%] items-center md:order-1 lg:order-none md:flex-[1_1_100%] lg:flex-none;
|
141
|
+
}
|
142
|
+
|
143
|
+
.progress-bar {
|
144
|
+
&__units {
|
145
|
+
@apply md:order-none;
|
146
|
+
}
|
147
|
+
|
148
|
+
&__number {
|
149
|
+
span {
|
150
|
+
@apply text-sm;
|
151
|
+
}
|
152
|
+
}
|
153
|
+
}
|
154
|
+
}
|
155
|
+
|
156
|
+
&-unlimited {
|
157
|
+
@apply flex flex-row flex-1 lg:flex-1 justify-center md:flex-none;
|
158
|
+
|
159
|
+
.progress-bar__number {
|
160
|
+
span {
|
161
|
+
@apply text-xl;
|
162
|
+
}
|
163
|
+
}
|
164
|
+
}
|
165
|
+
|
166
|
+
.progress-bar {
|
167
|
+
&__number {
|
168
|
+
@apply flex justify-center items-center mx-1;
|
169
|
+
|
170
|
+
span {
|
171
|
+
@apply leading-6 font-semibold #{!important};
|
172
|
+
}
|
173
|
+
}
|
174
|
+
|
175
|
+
&__units {
|
176
|
+
@apply text-sm leading-[22px] mx-1;
|
177
|
+
}
|
178
|
+
}
|
179
|
+
|
180
|
+
&-container {
|
181
|
+
@apply flex-1 md:w-full md:flex-none p-2 lg:p-0 lg:m-3 lg:w-[164px];
|
182
|
+
|
183
|
+
button {
|
184
|
+
@apply text-sm leading-[18px] font-semibold py-1;
|
185
|
+
}
|
186
|
+
}
|
187
|
+
|
188
|
+
&-hidden {
|
189
|
+
@apply md:flex-none;
|
190
|
+
|
191
|
+
.card__proposals-votes-container {
|
192
|
+
@apply md:flex-none md:w-[130px] lg:w-[164px] lg:p-0;
|
193
|
+
}
|
194
|
+
}
|
195
|
+
}
|
196
|
+
}
|
197
|
+
}
|
198
|
+
|
199
|
+
&__grid-grid {
|
200
|
+
@apply md:gap-4;
|
201
|
+
|
202
|
+
.card__proposals-item {
|
203
|
+
@apply flex flex-col justify-between border-solid border-[#D3D5D9] border rounded;
|
204
|
+
|
205
|
+
.card__grid {
|
206
|
+
@apply mb-2.5 md:mb-0 flex-1 justify-between;
|
207
|
+
|
208
|
+
box-shadow: none !important;
|
209
|
+
|
210
|
+
&-text {
|
211
|
+
@apply justify-end lg:gap-y-8;
|
212
|
+
}
|
213
|
+
|
214
|
+
&-metadata {
|
215
|
+
@apply mt-0 md:flex md:flex-row;
|
216
|
+
|
217
|
+
> :first-child {
|
218
|
+
flex: 1 !important;
|
219
|
+
}
|
220
|
+
|
221
|
+
> :not(:first-child) {
|
222
|
+
@apply border-r border-[#D3D5D9];
|
223
|
+
}
|
224
|
+
|
225
|
+
& > div {
|
226
|
+
@apply px-2 md:px-2;
|
227
|
+
}
|
228
|
+
}
|
229
|
+
}
|
230
|
+
|
231
|
+
.card__proposals-votes {
|
232
|
+
@apply flex bg-[#F5F5F5EE] justify-around items-center px-4 h-[68px];
|
233
|
+
|
234
|
+
button {
|
235
|
+
@apply bg-[var(--secondary)];
|
236
|
+
|
237
|
+
&[disabled] {
|
238
|
+
@apply opacity-50 text-white border-current cursor-not-allowed;
|
239
|
+
}
|
240
|
+
}
|
241
|
+
|
242
|
+
&-limited {
|
243
|
+
@apply flex flex-col lg:items-start flex-1 md:mr-4 lg:mr-0;
|
244
|
+
|
245
|
+
.proposals__aside-progress {
|
246
|
+
@apply flex flex-col-reverse w-[80%] items-center;
|
247
|
+
}
|
248
|
+
|
249
|
+
.progress-bar {
|
250
|
+
&__number {
|
251
|
+
@apply lg:w-[80%];
|
252
|
+
|
253
|
+
span {
|
254
|
+
@apply text-sm;
|
255
|
+
}
|
256
|
+
}
|
257
|
+
|
258
|
+
&__units {
|
259
|
+
@apply flex justify-center w-[80%];
|
260
|
+
}
|
261
|
+
}
|
262
|
+
}
|
263
|
+
|
264
|
+
&-unlimited {
|
265
|
+
@apply flex flex-row flex-1 lg:flex-1 md:flex-none md:mr-4 lg:mr-0;
|
266
|
+
|
267
|
+
.progress-bar__number {
|
268
|
+
span {
|
269
|
+
@apply text-xl;
|
270
|
+
}
|
271
|
+
}
|
272
|
+
}
|
273
|
+
|
274
|
+
.progress-bar {
|
275
|
+
&__number {
|
276
|
+
@apply flex justify-center items-center;
|
277
|
+
|
278
|
+
span {
|
279
|
+
@apply leading-6 font-semibold #{!important};
|
280
|
+
}
|
281
|
+
}
|
282
|
+
|
283
|
+
&__units {
|
284
|
+
@apply text-sm leading-[22px] mx-1;
|
285
|
+
}
|
286
|
+
}
|
287
|
+
|
288
|
+
&-container {
|
289
|
+
@apply flex-1 lg:w-[164px] lg:flex-none;
|
290
|
+
|
291
|
+
button {
|
292
|
+
@apply text-sm leading-[18px] font-semibold py-1;
|
293
|
+
|
294
|
+
.already-voted-icon {
|
295
|
+
@apply w-4 h-4;
|
296
|
+
}
|
297
|
+
}
|
298
|
+
}
|
299
|
+
|
300
|
+
&-hidden {
|
301
|
+
@apply md:justify-end;
|
302
|
+
|
303
|
+
.card__proposals-votes-container {
|
304
|
+
@apply md:flex-none md:w-[130px] lg:w-[164px];
|
305
|
+
|
306
|
+
button {
|
307
|
+
@apply md:px-0 lg:px-6;
|
308
|
+
}
|
309
|
+
}
|
310
|
+
}
|
311
|
+
}
|
312
|
+
}
|
111
313
|
}
|
112
314
|
}
|
113
315
|
|
@@ -129,3 +331,46 @@
|
|
129
331
|
}
|
130
332
|
}
|
131
333
|
}
|
334
|
+
|
335
|
+
#proposal-voting-rules {
|
336
|
+
[id="dropdown-menu-proposal-voting-rules"] {
|
337
|
+
&[aria-hidden="true"] {
|
338
|
+
@apply hidden;
|
339
|
+
}
|
340
|
+
}
|
341
|
+
|
342
|
+
[data-target="dropdown-menu-proposal-voting-rules"] {
|
343
|
+
@apply w-full flex items-center justify-between gap-2 p-2 first-of-type:[&>svg]:block last-of-type:[&>svg]:hidden;
|
344
|
+
|
345
|
+
& > span {
|
346
|
+
@apply hidden font-semibold text-secondary;
|
347
|
+
|
348
|
+
&:only-of-type,
|
349
|
+
&.is-active {
|
350
|
+
@apply flex items-center gap-2 [&_svg]:fill-current;
|
351
|
+
}
|
352
|
+
}
|
353
|
+
|
354
|
+
> svg {
|
355
|
+
@apply w-6 h-6 flex-none text-secondary fill-current;
|
356
|
+
}
|
357
|
+
|
358
|
+
&[aria-expanded="false"] > svg:last-of-type,
|
359
|
+
&[aria-expanded="true"] > svg:first-of-type {
|
360
|
+
@apply hidden;
|
361
|
+
}
|
362
|
+
|
363
|
+
&[aria-expanded="true"] > svg:last-of-type,
|
364
|
+
&[aria-expanded="false"] > svg:first-of-type {
|
365
|
+
@apply block;
|
366
|
+
}
|
367
|
+
}
|
368
|
+
}
|
369
|
+
|
370
|
+
.layout-item-complementary {
|
371
|
+
@apply container grid grid-cols-1 lg:grid-cols-12;
|
372
|
+
|
373
|
+
.item_voting_rules {
|
374
|
+
@apply lg:col-start-2 lg:col-span-10;
|
375
|
+
}
|
376
|
+
}
|
@@ -30,11 +30,8 @@ module Decidim
|
|
30
30
|
# time limit.
|
31
31
|
allow! if permission_action.subject == :proposal && permission_action.action == :edit && admin_edition_is_available?
|
32
32
|
|
33
|
-
# Every user allowed by the space can update the
|
34
|
-
allow! if permission_action.subject == :
|
35
|
-
|
36
|
-
# Every user allowed by the space can update the scope of the proposal
|
37
|
-
allow! if permission_action.subject == :proposal_scope && permission_action.action == :update
|
33
|
+
# Every user allowed by the space can update the taxonomy of the proposal
|
34
|
+
allow! if permission_action.subject == :proposal_taxonomy && permission_action.action == :update
|
38
35
|
|
39
36
|
# Every user allowed by the space can import proposals from another_component
|
40
37
|
allow! if permission_action.subject == :proposals && permission_action.action == :import
|
@@ -16,6 +16,8 @@ module Decidim
|
|
16
16
|
apply_proposal_permissions(permission_action) unless permission_action.action == :read
|
17
17
|
when :collaborative_draft
|
18
18
|
apply_collaborative_draft_permissions(permission_action)
|
19
|
+
when :proposal_coauthor_invites
|
20
|
+
apply_proposal_coauthor_invites(permission_action)
|
19
21
|
else
|
20
22
|
permission_action
|
21
23
|
end
|
@@ -159,6 +161,46 @@ module Decidim
|
|
159
161
|
|
160
162
|
toggle_allow(collaborative_draft.created_by?(user))
|
161
163
|
end
|
164
|
+
|
165
|
+
def apply_proposal_coauthor_invites(permission_action)
|
166
|
+
return toggle_allow(false) unless coauthor
|
167
|
+
return toggle_allow(false) unless proposal
|
168
|
+
|
169
|
+
case permission_action.action
|
170
|
+
when :invite
|
171
|
+
toggle_allow(valid_coauthor? && !notification_already_sent?)
|
172
|
+
when :cancel
|
173
|
+
toggle_allow(valid_coauthor? && notification_already_sent?)
|
174
|
+
when :accept, :decline
|
175
|
+
toggle_allow(can_be_coauthor?)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def coauthor
|
180
|
+
context.fetch(:coauthor, nil)
|
181
|
+
end
|
182
|
+
|
183
|
+
def notification_already_sent?
|
184
|
+
@notification_already_sent ||= proposal.coauthor_invitations_for(coauthor).any?
|
185
|
+
end
|
186
|
+
|
187
|
+
def coauthor_in_comments?
|
188
|
+
@coauthor_in_comments ||= proposal.comments.where(author: coauthor).any?
|
189
|
+
end
|
190
|
+
|
191
|
+
def valid_coauthor?
|
192
|
+
return false unless proposal.authors.include?(user)
|
193
|
+
return false unless proposal.user_has_actions?(coauthor)
|
194
|
+
|
195
|
+
coauthor_in_comments?
|
196
|
+
end
|
197
|
+
|
198
|
+
def can_be_coauthor?
|
199
|
+
return false unless user == coauthor
|
200
|
+
return false unless proposal.user_has_actions?(coauthor)
|
201
|
+
|
202
|
+
notification_already_sent?
|
203
|
+
end
|
162
204
|
end
|
163
205
|
end
|
164
206
|
end
|
@@ -40,7 +40,7 @@ module Decidim
|
|
40
40
|
def title(links: false, extras: true, html_escape: false, all_locales: false)
|
41
41
|
return unless proposal
|
42
42
|
|
43
|
-
super
|
43
|
+
super(proposal.title, links, html_escape, all_locales, extras:)
|
44
44
|
end
|
45
45
|
|
46
46
|
def id_and_title(links: false, extras: true, html_escape: false)
|
@@ -28,8 +28,8 @@ module Decidim
|
|
28
28
|
# by a range of dates.
|
29
29
|
def query
|
30
30
|
proposals = Decidim::Proposals::Proposal.where(component: @components)
|
31
|
-
proposals = proposals.where(
|
32
|
-
proposals = proposals.where(
|
31
|
+
proposals = proposals.where(created_at: @start_at..) if @start_at.present?
|
32
|
+
proposals = proposals.where(created_at: ..@end_at) if @end_at.present?
|
33
33
|
proposals
|
34
34
|
end
|
35
35
|
end
|
@@ -18,13 +18,13 @@ module Decidim
|
|
18
18
|
end
|
19
19
|
@query = Decidim::Proposals::Proposal.where(component: visible_components_from_spaces(spaces)).joins(:component)
|
20
20
|
.left_outer_joins(:category)
|
21
|
-
@query = @query.where(
|
21
|
+
@query = @query.where(decidim_proposals_proposals: { created_at: ..end_time }).accepted
|
22
22
|
@query = @query.group("decidim_categorizations.id", :participatory_space_type, :participatory_space_id)
|
23
23
|
@query
|
24
24
|
end
|
25
25
|
|
26
26
|
def quantity
|
27
|
-
@quantity ||= query.where(
|
27
|
+
@quantity ||= query.where(decidim_proposals_proposals: { created_at: start_time.. }).count
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|