decidim-proposals 0.29.1 → 0.30.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/cells/decidim/proposals/highlighted_proposals_for_component/show.erb +12 -12
- 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 +34 -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 +26 -18
- 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 +0 -5
- 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 +6 -2
- data/app/controllers/concerns/decidim/proposals/admin/needs_interpolations.rb +40 -0
- data/app/controllers/decidim/proposals/admin/proposal_answers_controller.rb +50 -2
- 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/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 +11 -40
- 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 +4 -3
- data/app/forms/decidim/proposals/admin/proposal_base_form.rb +3 -31
- data/app/forms/decidim/proposals/admin/proposal_form.rb +12 -7
- data/app/forms/decidim/proposals/admin/proposals_import_form.rb +6 -14
- data/app/forms/decidim/proposals/admin/valuation_assignment_form.rb +4 -1
- 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 +26 -1
- data/app/helpers/decidim/proposals/admin/proposals_helper.rb +0 -1
- data/app/helpers/decidim/proposals/application_helper.rb +23 -14
- 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/jobs/decidim/proposals/admin/proposal_answer_job.rb +20 -0
- data/app/models/decidim/proposals/collaborative_draft.rb +10 -1
- data/app/models/decidim/proposals/proposal.rb +67 -10
- 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 +246 -5
- data/app/permissions/decidim/proposals/admin/permissions.rb +2 -5
- data/app/permissions/decidim/proposals/permissions.rb +46 -3
- 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/collaborative_draft_diff_renderer.rb +22 -0
- data/app/services/decidim/proposals/diff_renderer.rb +2 -0
- data/app/services/decidim/proposals/proposal_builder.rb +2 -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 +16 -23
- 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 +10 -22
- data/app/views/decidim/proposals/admin/proposals/update_attribute.js.erb +1 -1
- data/app/views/decidim/proposals/admin/proposals_imports/new.html.erb +2 -5
- 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/_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 +10 -18
- data/app/views/decidim/proposals/proposals/index.js.erb +12 -0
- data/app/views/decidim/proposals/proposals/participatory_texts/_proposal_vote_button.html.erb +3 -1
- data/app/views/decidim/proposals/proposals/show.html.erb +36 -16
- data/config/locales/ar.yml +19 -75
- data/config/locales/bg.yml +7 -91
- data/config/locales/bn-BD.yml +1 -0
- data/config/locales/bs-BA.yml +87 -0
- data/config/locales/ca.yml +213 -73
- data/config/locales/cs.yml +229 -75
- data/config/locales/de.yml +217 -78
- data/config/locales/el.yml +9 -85
- data/config/locales/en.yml +209 -69
- data/config/locales/es-MX.yml +220 -80
- data/config/locales/es-PY.yml +215 -75
- data/config/locales/es.yml +222 -82
- data/config/locales/eu.yml +293 -147
- data/config/locales/fi-plain.yml +222 -81
- data/config/locales/fi.yml +239 -98
- data/config/locales/fr-CA.yml +119 -90
- data/config/locales/fr.yml +118 -89
- data/config/locales/ga-IE.yml +0 -19
- data/config/locales/gl.yml +9 -47
- data/config/locales/he-IL.yml +7 -0
- data/config/locales/hu.yml +7 -68
- data/config/locales/id-ID.yml +9 -36
- data/config/locales/is-IS.yml +0 -21
- data/config/locales/it.yml +10 -56
- data/config/locales/ja.yml +164 -91
- data/config/locales/lt.yml +9 -86
- data/config/locales/lv.yml +8 -47
- data/config/locales/nl.yml +7 -54
- data/config/locales/no.yml +9 -46
- data/config/locales/pl.yml +7 -91
- data/config/locales/pt-BR.yml +7 -77
- data/config/locales/pt.yml +9 -57
- data/config/locales/ro-RO.yml +17 -63
- data/config/locales/ru.yml +0 -25
- data/config/locales/sk.yml +9 -48
- data/config/locales/sl.yml +0 -4
- data/config/locales/sr-CS.yml +0 -14
- data/config/locales/sv.yml +132 -88
- data/config/locales/tr-TR.yml +9 -54
- data/config/locales/uk.yml +0 -25
- data/config/locales/zh-CN.yml +9 -54
- data/config/locales/zh-TW.yml +9 -87
- 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 +4 -3
- 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 +2 -2
- 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 +30 -25
- data/lib/decidim/api/proposals_type.rb +5 -22
- 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 +15 -29
- data/lib/decidim/proposals/seeds.rb +21 -17
- data/lib/decidim/proposals/test/factories.rb +8 -6
- data/lib/decidim/proposals/version.rb +1 -1
- data/lib/decidim/proposals.rb +4 -0
- metadata +69 -30
- 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/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
@@ -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,15 +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
|
+
}
|
108
|
+
|
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];
|
107
182
|
|
108
|
-
|
109
|
-
|
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
|
+
}
|
110
196
|
}
|
111
197
|
}
|
112
198
|
|
113
|
-
&
|
114
|
-
@apply md:
|
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
|
+
}
|
115
313
|
}
|
116
314
|
}
|
117
315
|
|
@@ -133,3 +331,46 @@
|
|
133
331
|
}
|
134
332
|
}
|
135
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
|
@@ -4,17 +4,20 @@ module Decidim
|
|
4
4
|
module Proposals
|
5
5
|
class Permissions < Decidim::DefaultPermissions
|
6
6
|
def permissions
|
7
|
-
return permission_action unless user
|
8
|
-
|
9
7
|
# Delegate the admin permission checks to the admin permissions class
|
10
8
|
return Decidim::Proposals::Admin::Permissions.new(user, permission_action, context).permissions if permission_action.scope == :admin
|
11
9
|
return permission_action if permission_action.scope != :public
|
12
10
|
|
11
|
+
toggle_allow(!proposal.hidden?) if permission_action.subject == :proposal && permission_action.action == :read
|
12
|
+
return permission_action unless user
|
13
|
+
|
13
14
|
case permission_action.subject
|
14
15
|
when :proposal
|
15
|
-
apply_proposal_permissions(permission_action)
|
16
|
+
apply_proposal_permissions(permission_action) unless permission_action.action == :read
|
16
17
|
when :collaborative_draft
|
17
18
|
apply_collaborative_draft_permissions(permission_action)
|
19
|
+
when :proposal_coauthor_invites
|
20
|
+
apply_proposal_coauthor_invites(permission_action)
|
18
21
|
else
|
19
22
|
permission_action
|
20
23
|
end
|
@@ -158,6 +161,46 @@ module Decidim
|
|
158
161
|
|
159
162
|
toggle_allow(collaborative_draft.created_by?(user))
|
160
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
|
161
204
|
end
|
162
205
|
end
|
163
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
|
@@ -13,9 +13,9 @@ module Decidim
|
|
13
13
|
next if cumulative_value.zero?
|
14
14
|
|
15
15
|
quantity_value = quantity[key] || 0
|
16
|
-
|
16
|
+
taxonomy_id, space_type, space_id, proposal_id = key
|
17
17
|
record = Decidim::Metric.find_or_initialize_by(day: @day.to_s, metric_type: @metric_name,
|
18
|
-
organization: @organization,
|
18
|
+
organization: @organization, decidim_taxonomy_id: taxonomy_id,
|
19
19
|
participatory_space_type: space_type, participatory_space_id: space_id,
|
20
20
|
related_object_type: "Decidim::Proposals::Proposal", related_object_id: proposal_id)
|
21
21
|
record.assign_attributes(cumulative: cumulative_value, quantity: quantity_value)
|
@@ -31,18 +31,18 @@ module Decidim
|
|
31
31
|
components = Decidim::Component.where(participatory_space: retrieve_participatory_spaces).published
|
32
32
|
proposals = Decidim::Proposals::Proposal.where(component: components).not_withdrawn
|
33
33
|
join_components = "INNER JOIN decidim_components ON decidim_components.manifest_name = 'proposals' AND proposals.decidim_component_id = decidim_components.id"
|
34
|
-
|
35
|
-
LEFT OUTER JOIN
|
36
|
-
ON (proposals.id =
|
37
|
-
AND
|
34
|
+
join_taxonomies = <<~EOJOINCATS
|
35
|
+
LEFT OUTER JOIN decidim_taxonomizations
|
36
|
+
ON (proposals.id = decidim_taxonomizations.taxonomizable_id
|
37
|
+
AND decidim_taxonomizations.taxonomizable_type = 'Decidim::Proposals::Proposal')
|
38
38
|
EOJOINCATS
|
39
39
|
@query = Decidim::Endorsement.joins("INNER JOIN decidim_proposals_proposals proposals ON resource_id = proposals.id")
|
40
40
|
.joins(join_components)
|
41
|
-
.joins(
|
41
|
+
.joins(join_taxonomies)
|
42
42
|
.where(resource_id: proposals.pluck(:id))
|
43
43
|
.where(resource_type: Decidim::Proposals::Proposal.name)
|
44
|
-
@query = @query.where(
|
45
|
-
@query = @query.group("
|
44
|
+
@query = @query.where(decidim_endorsements: { created_at: ..end_time })
|
45
|
+
@query = @query.group("decidim_taxonomizations.taxonomy_id",
|
46
46
|
:participatory_space_type,
|
47
47
|
:participatory_space_id,
|
48
48
|
:resource_id)
|
@@ -50,7 +50,7 @@ module Decidim
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def quantity
|
53
|
-
@quantity ||= query.where(
|
53
|
+
@quantity ||= query.where(decidim_endorsements: { created_at: start_time.. }).count
|
54
54
|
end
|
55
55
|
end
|
56
56
|
end
|
@@ -30,17 +30,17 @@ module Decidim
|
|
30
30
|
|
31
31
|
def retrieve_proposals_followers(from_start: false)
|
32
32
|
@proposals_followers ||= Decidim::Follow.where(followable: retrieve_proposals).joins(:user)
|
33
|
-
.where(
|
33
|
+
.where(decidim_follows: { created_at: ..end_time })
|
34
34
|
|
35
|
-
return @proposals_followers.where(
|
35
|
+
return @proposals_followers.where(decidim_follows: { created_at: start_time.. }) if from_start
|
36
36
|
|
37
37
|
@proposals_followers
|
38
38
|
end
|
39
39
|
|
40
40
|
def retrieve_drafts_followers(from_start: false)
|
41
41
|
@drafts_followers ||= Decidim::Follow.where(followable: retrieve_collaborative_drafts).joins(:user)
|
42
|
-
.where(
|
43
|
-
return @drafts_followers.where(
|
42
|
+
.where(decidim_follows: { created_at: ..end_time })
|
43
|
+
return @drafts_followers.where(decidim_follows: { created_at: start_time.. }) if from_start
|
44
44
|
|
45
45
|
@drafts_followers
|
46
46
|
end
|
@@ -41,19 +41,19 @@ module Decidim
|
|
41
41
|
"Decidim::Meetings::Meeting"
|
42
42
|
]
|
43
43
|
})
|
44
|
-
.where(
|
44
|
+
.where(decidim_proposals_proposals: { published_at: ..end_time })
|
45
45
|
.not_withdrawn
|
46
46
|
|
47
|
-
return @proposals.where(
|
47
|
+
return @proposals.where(decidim_proposals_proposals: { published_at: start_time.. }) if from_start
|
48
48
|
|
49
49
|
@proposals
|
50
50
|
end
|
51
51
|
|
52
52
|
def retrieve_votes(from_start: false)
|
53
53
|
@votes ||= Decidim::Proposals::ProposalVote.joins(:proposal).where(proposal: retrieve_proposals).joins(:author)
|
54
|
-
.where(
|
54
|
+
.where(decidim_proposals_proposal_votes: { created_at: ..end_time })
|
55
55
|
|
56
|
-
return @votes.where(
|
56
|
+
return @votes.where(decidim_proposals_proposal_votes: { created_at: start_time.. }) if from_start
|
57
57
|
|
58
58
|
@votes
|
59
59
|
end
|
@@ -61,10 +61,10 @@ module Decidim
|
|
61
61
|
def retrieve_endorsements(from_start: false)
|
62
62
|
@endorsements ||= Decidim::Endorsement.joins("INNER JOIN decidim_proposals_proposals proposals ON resource_id = proposals.id")
|
63
63
|
.where(resource: retrieve_proposals)
|
64
|
-
.where(
|
64
|
+
.where(decidim_endorsements: { created_at: ..end_time })
|
65
65
|
.where(decidim_author_type: "Decidim::UserBaseEntity")
|
66
66
|
|
67
|
-
return @endorsements.where(
|
67
|
+
return @endorsements.where(decidim_endorsements: { created_at: start_time.. }) if from_start
|
68
68
|
|
69
69
|
@endorsements
|
70
70
|
end
|