From 58069b35a3642ca98990fa617363f6f04362cd70 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 2 Oct 2017 16:24:53 +0200 Subject: [PATCH 001/211] Remove Poll White/Null/Total Results models, tables, specs and references --- .rubocop_todo.yml | 6 - app/models/poll/null_result.rb | 23 - app/models/poll/total_result.rb | 23 - app/models/poll/white_result.rb | 23 - ...47_remove_poll_white_null_total_results.rb | 16 + db/schema.rb | 51 +- knapsack_rspec_report.json | 449 +++++++++--------- spec/factories.rb | 15 - spec/models/poll/null_result_spec.rb | 70 --- spec/models/poll/total_result_spec.rb | 70 --- spec/models/poll/white_result_spec.rb | 70 --- 11 files changed, 242 insertions(+), 574 deletions(-) delete mode 100644 app/models/poll/null_result.rb delete mode 100644 app/models/poll/total_result.rb delete mode 100644 app/models/poll/white_result.rb create mode 100644 db/migrate/20171002133547_remove_poll_white_null_total_results.rb delete mode 100644 spec/models/poll/null_result_spec.rb delete mode 100644 spec/models/poll/total_result_spec.rb delete mode 100644 spec/models/poll/white_result_spec.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index f8d4bb811..072caad09 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -283,10 +283,7 @@ Lint/ParenthesesAsGroupedExpression: # Cop supports --auto-correct. Lint/StringConversionInInterpolation: Exclude: - - 'app/models/poll/null_result.rb' - 'app/models/poll/partial_result.rb' - - 'app/models/poll/white_result.rb' - - 'app/models/poll/total_result.rb' # Offense count: 15 # Cop supports --auto-correct. @@ -533,10 +530,7 @@ Style/MutableConstant: - 'app/models/activity.rb' - 'app/models/budget/reclassified_vote.rb' - 'app/models/legislation/draft_version.rb' - - 'app/models/poll/null_result.rb' - 'app/models/poll/partial_result.rb' - - 'app/models/poll/white_result.rb' - - 'app/models/poll/total_result.rb' - 'app/models/proposal.rb' - 'app/models/signature_sheet.rb' - 'app/models/site_customization/content_block.rb' diff --git a/app/models/poll/null_result.rb b/app/models/poll/null_result.rb deleted file mode 100644 index d10fe3cb0..000000000 --- a/app/models/poll/null_result.rb +++ /dev/null @@ -1,23 +0,0 @@ -class Poll::NullResult < ActiveRecord::Base - - VALID_ORIGINS = %w{web booth} - - belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' - belongs_to :booth_assignment - belongs_to :officer_assignment - - validates :author, presence: true - validates :origin, inclusion: {in: VALID_ORIGINS} - - scope :by_author, ->(author_id) { where(author_id: author_id) } - - before_save :update_logs - - def update_logs - if amount_changed? && amount_was.present? - self.amount_log += ":#{amount_was.to_s}" - self.officer_assignment_id_log += ":#{officer_assignment_id_was.to_s}" - self.author_id_log += ":#{author_id_was.to_s}" - end - end -end diff --git a/app/models/poll/total_result.rb b/app/models/poll/total_result.rb deleted file mode 100644 index 2df01929e..000000000 --- a/app/models/poll/total_result.rb +++ /dev/null @@ -1,23 +0,0 @@ -class Poll::TotalResult < ActiveRecord::Base - - VALID_ORIGINS = %w{web booth} - - belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' - belongs_to :booth_assignment - belongs_to :officer_assignment - - validates :author, presence: true - validates :origin, inclusion: {in: VALID_ORIGINS} - - scope :by_author, ->(author_id) { where(author_id: author_id) } - - before_save :update_logs - - def update_logs - if amount_changed? && amount_was.present? - self.amount_log += ":#{amount_was.to_s}" - self.officer_assignment_id_log += ":#{officer_assignment_id_was.to_s}" - self.author_id_log += ":#{author_id_was.to_s}" - end - end -end diff --git a/app/models/poll/white_result.rb b/app/models/poll/white_result.rb deleted file mode 100644 index a4a4e5a4d..000000000 --- a/app/models/poll/white_result.rb +++ /dev/null @@ -1,23 +0,0 @@ -class Poll::WhiteResult < ActiveRecord::Base - - VALID_ORIGINS = %w{web booth} - - belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' - belongs_to :booth_assignment - belongs_to :officer_assignment - - validates :author, presence: true - validates :origin, inclusion: {in: VALID_ORIGINS} - - scope :by_author, ->(author_id) { where(author_id: author_id) } - - before_save :update_logs - - def update_logs - if amount_changed? && amount_was.present? - self.amount_log += ":#{amount_was.to_s}" - self.officer_assignment_id_log += ":#{officer_assignment_id_was.to_s}" - self.author_id_log += ":#{author_id_was.to_s}" - end - end -end diff --git a/db/migrate/20171002133547_remove_poll_white_null_total_results.rb b/db/migrate/20171002133547_remove_poll_white_null_total_results.rb new file mode 100644 index 000000000..5fff82ef3 --- /dev/null +++ b/db/migrate/20171002133547_remove_poll_white_null_total_results.rb @@ -0,0 +1,16 @@ +class RemovePollWhiteNullTotalResults < ActiveRecord::Migration + def change + remove_index :poll_null_results, column: [:booth_assignment_id] + remove_index :poll_null_results, column: [:officer_assignment_id] + + remove_index :poll_white_results, column: [:booth_assignment_id] + remove_index :poll_white_results, column: [:officer_assignment_id] + + remove_index :poll_total_results, column: [:booth_assignment_id] + remove_index :poll_total_results, column: [:officer_assignment_id] + + drop_table :poll_null_results + drop_table :poll_total_results + drop_table :poll_white_results + end +end diff --git a/db/schema.rb b/db/schema.rb index e859a487f..b852190f0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20171002122312) do +ActiveRecord::Schema.define(version: 20171002133547) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -613,21 +613,6 @@ ActiveRecord::Schema.define(version: 20171002122312) do t.string "location" end - create_table "poll_null_results", force: :cascade do |t| - t.integer "author_id" - t.integer "amount" - t.string "origin" - t.date "date" - t.integer "booth_assignment_id" - t.integer "officer_assignment_id" - t.text "amount_log", default: "" - t.text "officer_assignment_id_log", default: "" - t.text "author_id_log", default: "" - end - - add_index "poll_null_results", ["booth_assignment_id"], name: "index_poll_null_results_on_booth_assignment_id", using: :btree - add_index "poll_null_results", ["officer_assignment_id"], name: "index_poll_null_results_on_officer_assignment_id", using: :btree - create_table "poll_officer_assignments", force: :cascade do |t| t.integer "booth_assignment_id" t.integer "officer_id" @@ -724,21 +709,6 @@ ActiveRecord::Schema.define(version: 20171002122312) do add_index "poll_shifts", ["booth_id"], name: "index_poll_shifts_on_booth_id", using: :btree add_index "poll_shifts", ["officer_id"], name: "index_poll_shifts_on_officer_id", using: :btree - create_table "poll_total_results", force: :cascade do |t| - t.integer "author_id" - t.integer "amount" - t.string "origin" - t.date "date" - t.integer "booth_assignment_id" - t.integer "officer_assignment_id" - t.text "amount_log", default: "" - t.text "officer_assignment_id_log", default: "" - t.text "author_id_log", default: "" - end - - add_index "poll_total_results", ["booth_assignment_id"], name: "index_poll_total_results_on_booth_assignment_id", using: :btree - add_index "poll_total_results", ["officer_assignment_id"], name: "index_poll_total_results_on_officer_assignment_id", using: :btree - create_table "poll_voters", force: :cascade do |t| t.string "document_number" t.string "document_type" @@ -761,21 +731,6 @@ ActiveRecord::Schema.define(version: 20171002122312) do add_index "poll_voters", ["poll_id"], name: "index_poll_voters_on_poll_id", using: :btree add_index "poll_voters", ["user_id"], name: "index_poll_voters_on_user_id", using: :btree - create_table "poll_white_results", force: :cascade do |t| - t.integer "author_id" - t.integer "amount" - t.string "origin" - t.date "date" - t.integer "booth_assignment_id" - t.integer "officer_assignment_id" - t.text "amount_log", default: "" - t.text "officer_assignment_id_log", default: "" - t.text "author_id_log", default: "" - end - - add_index "poll_white_results", ["booth_assignment_id"], name: "index_poll_white_results_on_booth_assignment_id", using: :btree - add_index "poll_white_results", ["officer_assignment_id"], name: "index_poll_white_results_on_officer_assignment_id", using: :btree - create_table "polls", force: :cascade do |t| t.string "name" t.datetime "starts_at" @@ -1135,8 +1090,6 @@ ActiveRecord::Schema.define(version: 20171002122312) do add_foreign_key "organizations", "users" add_foreign_key "poll_answers", "poll_questions", column: "question_id" add_foreign_key "poll_booth_assignments", "polls" - add_foreign_key "poll_null_results", "poll_booth_assignments", column: "booth_assignment_id" - add_foreign_key "poll_null_results", "poll_officer_assignments", column: "officer_assignment_id" add_foreign_key "poll_officer_assignments", "poll_booth_assignments", column: "booth_assignment_id" add_foreign_key "poll_partial_results", "poll_booth_assignments", column: "booth_assignment_id" add_foreign_key "poll_partial_results", "poll_officer_assignments", column: "officer_assignment_id" @@ -1148,8 +1101,6 @@ ActiveRecord::Schema.define(version: 20171002122312) do add_foreign_key "poll_recounts", "poll_booth_assignments", column: "booth_assignment_id" add_foreign_key "poll_recounts", "poll_officer_assignments", column: "officer_assignment_id" add_foreign_key "poll_voters", "polls" - add_foreign_key "poll_white_results", "poll_booth_assignments", column: "booth_assignment_id" - add_foreign_key "poll_white_results", "poll_officer_assignments", column: "officer_assignment_id" add_foreign_key "proposals", "communities" add_foreign_key "users", "geozones" add_foreign_key "valuators", "users" diff --git a/knapsack_rspec_report.json b/knapsack_rspec_report.json index 595276b2b..5f1fc06b5 100644 --- a/knapsack_rspec_report.json +++ b/knapsack_rspec_report.json @@ -1,226 +1,227 @@ { - "spec/helpers/comments_helper_spec.rb": 0.010898828506469727, - "spec/controllers/graphql_controller_spec.rb": 0.7817962169647217, - "spec/controllers/concerns/has_orders_spec.rb": 0.09597063064575195, - "spec/features/officing/results_spec.rb": 2.6492855548858643, - "spec/models/poll/question_spec.rb": 0.09519433975219727, - "spec/features/organizations_spec.rb": 1.9025108814239502, - "spec/models/legislation/process_spec.rb": 0.09253501892089844, - "spec/lib/acts_as_paranoid_aliases_spec.rb": 0.2438969612121582, - "spec/features/officing_spec.rb": 1.4767742156982422, - "spec/lib/age_spec.rb": 0.0006227493286132812, - "spec/models/proposal_spec.rb": 5.535696983337402, - "spec/models/abilities/administrator_spec.rb": 2.2431821823120117, - "spec/models/poll/final_recount_spec.rb": 0.1787703037261963, - "spec/lib/graph_ql/query_type_creator_spec.rb": 0.012041091918945312, - "spec/models/verification/management/email_spec.rb": 0.06403493881225586, - "spec/models/flag_spec.rb": 0.46442556381225586, - "spec/features/tags/budget_investments_spec.rb": 23.748523235321045, - "spec/features/campaigns_spec.rb": 1.3289697170257568, - "spec/features/admin/activity_spec.rb": 7.763890743255615, - "spec/features/polls/questions_spec.rb": 2.61055326461792, - "spec/features/polls/polls_spec.rb": 2.313369035720825, - "spec/features/home_spec.rb": 0.9780440330505371, - "spec/models/poll/partial_result_spec.rb": 0.3302469253540039, - "spec/models/lock_spec.rb": 0.09437012672424316, - "spec/lib/graph_ql/api_types_creator_spec.rb": 0.0069005489349365234, - "spec/helpers/users_helper_spec.rb": 0.3229796886444092, - "spec/lib/local_census_spec.rb": 0.011091947555541992, - "spec/helpers/text_helper_spec.rb": 0.0005347728729248047, - "spec/customization_engine_spec.rb": 1.3630127906799316, - "spec/models/legislation/answer_spec.rb": 0.6906075477600098, - "spec/models/budget/ballot/line_spec.rb": 0.5054352283477783, - "spec/features/admin/proposals_spec.rb": 1.6710176467895508, - "spec/features/proposal_ballots_spec.rb": 0.3399386405944824, - "spec/models/site_customization/content_block_spec.rb": 0.014521121978759766, - "spec/features/admin/site_customization/content_blocks_spec.rb": 1.2890841960906982, - "spec/models/site_customization/page_spec.rb": 0.011090993881225586, - "spec/features/verification/email_spec.rb": 1.0991628170013428, - "spec/models/proposal_notification_spec.rb": 0.2569601535797119, - "spec/features/registration_form_spec.rb": 0.7285032272338867, - "spec/features/communities_spec.rb": 1.7133822441101074, - "spec/features/admin/moderators_spec.rb": 1.2922589778900146, - "spec/helpers/geozones_helper_spec.rb": 0.09812736511230469, - "spec/features/welcome_spec.rb": 1.5019774436950684, - "spec/controllers/comments_controller_spec.rb": 0.36508607864379883, - "spec/features/admin/legislation/questions_spec.rb": 3.81538724899292, - "spec/controllers/users/registrations_controller_spec.rb": 0.018311023712158203, - "spec/features/comments/debates_spec.rb": 12.265411615371704, - "spec/features/users_spec.rb": 11.05901050567627, - "spec/models/budget/group_spec.rb": 0.04957008361816406, - "spec/features/admin/poll/questions_spec.rb": 1.9041199684143066, - "spec/helpers/admin_helper_spec.rb": 0.00651097297668457, - "spec/models/abilities/organization_spec.rb": 0.24821996688842773, - "spec/features/moderation/comments_spec.rb": 6.318082332611084, - "spec/features/admin/poll/polls_spec.rb": 8.88325023651123, - "spec/models/activity_spec.rb": 0.9704892635345459, - "spec/features/verification/level_two_verification_spec.rb": 0.421832799911499, - "spec/models/poll/officer_assignment_spec.rb": 0.029267072677612305, - "spec/features/admin/verifications_spec.rb": 0.507885217666626, - "spec/mailers/mailer_spec.rb": 0.07406282424926758, - "spec/models/legislation/draft_version_spec.rb": 0.025011777877807617, - "spec/models/budget/investment_spec.rb": 9.084597826004028, - "spec/features/proposals_spec.rb": 183.71455550193787, - "spec/features/tags_spec.rb": 2.949070453643799, - "spec/features/tags/debates_spec.rb": 4.345250368118286, - "spec/features/admin/geozones_spec.rb": 1.935765027999878, - "spec/features/admin/feature_flags_spec.rb": 0.8357558250427246, - "spec/models/user_spec.rb": 2.436626434326172, - "spec/features/moderation/debates_spec.rb": 6.05112886428833, - "spec/models/legislation/annotation_spec.rb": 0.21427702903747559, - "spec/features/comments/proposals_spec.rb": 32.52879500389099, - "spec/controllers/legislation/answers_controller_spec.rb": 0.3481717109680176, - "spec/features/verification/sms_spec.rb": 1.2817349433898926, - "spec/features/admin/budget_investments_spec.rb": 16.1332266330719, - "spec/features/notifications_spec.rb": 14.857182264328003, - "spec/lib/tag_sanitizer_spec.rb": 0.0005936622619628906, - "spec/controllers/admin/api/stats_controller_spec.rb": 0.3948392868041992, - "spec/features/comments/topics_spec.rb": 29.646622896194458, - "spec/models/debate_spec.rb": 5.2278876304626465, - "spec/lib/email_digests_spec.rb": 0.6660604476928711, - "spec/models/abilities/everyone_spec.rb": 0.06328749656677246, - "spec/features/direct_messages_spec.rb": 1.3006987571716309, - "spec/features/debates_spec.rb": 28.736626386642456, - "spec/models/setting_spec.rb": 0.07938265800476074, - "spec/models/legislation/question_option_spec.rb": 0.058206796646118164, - "spec/models/verification/management/document_spec.rb": 0.013574600219726562, - "spec/models/poll/booth_spec.rb": 0.07824325561523438, - "spec/features/admin/legislation/draft_versions_spec.rb": 3.750009059906006, - "spec/features/admin/poll/officers_spec.rb": 1.4151291847229004, - "spec/features/moderation_spec.rb": 1.9578778743743896, - "spec/features/legislation/questions_spec.rb": 1.7689197063446045, - "spec/features/officing/residence_spec.rb": 0.971078634262085, - "spec/models/follow_spec.rb": 0.12199592590332031, - "spec/lib/census_api_spec.rb": 0.0019702911376953125, - "spec/models/tag_cloud_spec.rb": 1.5725350379943848, - "spec/models/budget_spec.rb": 0.2335052490234375, - "spec/features/management/localization_spec.rb": 1.1911811828613281, - "spec/features/legislation/draft_versions_spec.rb": 8.151643514633179, - "spec/models/budget/heading_spec.rb": 0.09901237487792969, - "spec/models/poll/poll_spec.rb": 0.46999382972717285, - "spec/models/custom/residence_spec.rb": 0.050164222717285156, - "spec/models/notification_spec.rb": 0.39408183097839355, - "spec/features/budgets/ballots_spec.rb": 27.406018257141113, - "spec/mailers/devise_mailer_spec.rb": 0.16486406326293945, - "spec/features/admin/debates_spec.rb": 1.546919345855713, - "spec/features/valuation/budgets_spec.rb": 0.2552778720855713, - "spec/models/abilities/common_spec.rb": 6.724466562271118, - "spec/models/residence_spec.rb": 0.24986696243286133, - "spec/features/officing/voters_spec.rb": 2.954087257385254, - "spec/models/vote_spec.rb": 1.3241477012634277, - "spec/lib/migrate_spending_proposals_to_investments_spec.rb": 1.1774518489837646, - "spec/controllers/management/users_controller_spec.rb": 0.007733821868896484, - "spec/helpers/proposals_helper_spec.rb": 0.21885180473327637, - "spec/features/ckeditor_spec.rb": 0.7726309299468994, - "spec/lib/census_caller_spec.rb": 0.009332895278930664, - "spec/features/tracks_spec.rb": 2.7082908153533936, - "spec/features/admin/budgets_spec.rb": 4.468225002288818, - "spec/features/admin/valuators_spec.rb": 1.3326430320739746, - "spec/features/admin/banners_spec.rb": 3.302579164505005, - "spec/features/account_spec.rb": 2.30243182182312, - "spec/features/budgets/budgets_spec.rb": 1.0318260192871094, - "spec/models/poll/answer_spec.rb": 0.11362218856811523, - "spec/features/comments/budget_investments_spec.rb": 16.92409658432007, - "spec/features/budgets/results_spec.rb": 2.589841365814209, - "spec/features/valuation_spec.rb": 2.126727819442749, - "spec/features/stats_spec.rb": 0.8516559600830078, - "spec/features/admin/poll/booths_spec.rb": 1.766916275024414, - "spec/models/legislation/process/phase_spec.rb": 0.0886683464050293, - "spec/models/budget/investment/milestone_spec.rb": 0.1419520378112793, - "spec/models/letter_spec.rb": 0.08197903633117676, - "spec/features/admin/stats_spec.rb": 3.6946730613708496, - "spec/models/identity_spec.rb": 0.004762887954711914, - "spec/features/verification/letter_spec.rb": 1.7480952739715576, - "spec/models/topic_spec.rb": 0.30414509773254395, - "spec/features/users_auth_spec.rb": 7.242254257202148, - "spec/lib/acts_as_taggable_on_spec.rb": 0.7477433681488037, - "spec/features/official_positions_spec.rb": 1.9427640438079834, - "spec/features/admin/newsletters_spec.rb": 0.22768402099609375, - "spec/features/admin/hidden_users_spec.rb": 1.4156956672668457, - "spec/features/comments/legislation_annotations_spec.rb": 18.616747856140137, - "spec/features/admin/site_customization/pages_spec.rb": 1.0219447612762451, - "spec/models/poll/shift_spec.rb": 0.2051677703857422, - "spec/models/geozone_spec.rb": 0.12972474098205566, - "spec/helpers/verification_helper_spec.rb": 0.0009250640869140625, - "spec/lib/cache_spec.rb": 0.06447911262512207, - "spec/features/verification/verification_path_spec.rb": 1.2300751209259033, - "spec/features/sessions_spec.rb": 0.3665180206298828, - "spec/controllers/management/base_controller_spec.rb": 0.019928932189941406, - "spec/features/verification/verified_user_spec.rb": 0.787623405456543, - "spec/models/direct_message_spec.rb": 0.49156641960144043, - "spec/features/admin/tags_spec.rb": 1.045637845993042, - "spec/features/admin/comments_spec.rb": 3.4312756061553955, - "spec/features/moderation/users_spec.rb": 1.1841027736663818, - "spec/models/budget/reclassified_vote_spec.rb": 0.22663235664367676, - "spec/features/admin/organizations_spec.rb": 3.4465878009796143, - "spec/features/proposal_notifications_spec.rb": 4.40612268447876, - "spec/features/emails_spec.rb": 13.047018051147461, - "spec/controllers/debates_controller_spec.rb": 0.3078582286834717, - "spec/features/budgets/investments_spec.rb": 126.55784440040588, - "spec/features/verification/residence_spec.rb": 1.8894774913787842, - "spec/models/abilities/moderator_spec.rb": 2.7029502391815186, - "spec/helpers/votes_helper_spec.rb": 0.363523006439209, - "spec/features/tags/proposals_spec.rb": 8.272820949554443, - "spec/models/signature_spec.rb": 1.6858570575714111, - "spec/models/legislation/process/publication_spec.rb": 0.0707387924194336, - "spec/models/community_spec.rb": 0.13965797424316406, - "spec/models/sms_spec.rb": 0.024147987365722656, - "spec/lib/graphql_spec.rb": 3.7293970584869385, - "spec/lib/tasks/communities_spec.rb": 0.17484474182128906, - "spec/features/management/proposals_spec.rb": 4.549585580825806, - "spec/models/document_spec.rb": 1.2667145729064941, - "spec/features/site_customization/content_blocks_spec.rb": 0.3020951747894287, - "spec/features/localization_spec.rb": 0.5679850578308105, - "spec/models/signature_sheet_spec.rb": 0.7970001697540283, - "spec/features/budgets/votes_spec.rb": 4.38911509513855, - "spec/features/verification/level_three_verification_spec.rb": 1.2754230499267578, - "spec/features/admin/users_spec.rb": 0.3584918975830078, - "spec/models/abilities/valuator_spec.rb": 1.1300320625305176, - "spec/models/officing/residence_spec.rb": 0.3599817752838135, - "spec/features/admin/officials_spec.rb": 0.940401554107666, - "spec/features/admin/settings_spec.rb": 0.37268495559692383, - "spec/models/ahoy/data_source_spec.rb": 0.04887723922729492, - "spec/helpers/settings_helper_spec.rb": 0.020088911056518555, - "spec/models/budget/result_spec.rb": 0.7962813377380371, - "spec/models/poll/null_result_spec.rb": 0.17995309829711914, - "spec/models/valuator_spec.rb": 0.02411341667175293, - "spec/lib/manager_authenticator_spec.rb": 0.0031435489654541016, - "spec/lib/tasks/settings_spec.rb": 0.07562613487243652, - "spec/controllers/legislation/annotations_controller_spec.rb": 0.712010383605957, - "spec/models/comment_spec.rb": 1.7274408340454102, - "spec/features/comments/legislation_questions_spec.rb": 15.219935894012451, - "spec/features/admin_spec.rb": 1.1390578746795654, - "spec/features/admin/poll/booth_assigments_spec.rb": 3.737426280975342, - "spec/controllers/pages_controller_spec.rb": 0.3043200969696045, - "spec/features/admin/administrators_spec.rb": 2.7916433811187744, - "spec/models/poll/total_result_spec.rb": 0.549537181854248, - "spec/features/management/managed_users_spec.rb": 4.38576078414917, - "spec/models/poll/officer_spec.rb": 0.49225711822509766, - "spec/features/user_invites_spec.rb": 0.21891093254089355, - "spec/helpers/application_helper_spec.rb": 0.13661718368530273, - "spec/features/management/account_spec.rb": 0.9717822074890137, - "spec/features/management/document_verifications_spec.rb": 1.0395607948303223, - "spec/features/admin/site_customization/images_spec.rb": 1.2623581886291504, - "spec/models/organization_spec.rb": 0.16587495803833008, - "spec/features/management/email_verifications_spec.rb": 0.46370506286621094, - "spec/features/legislation/processes_spec.rb": 3.2473270893096924, - "spec/features/admin/managers_spec.rb": 1.1836414337158203, - "spec/models/legislation/question_spec.rb": 0.4404168128967285, - "spec/features/management/budget_investments_spec.rb": 7.179029703140259, - "spec/features/admin/signature_sheets_spec.rb": 1.4004056453704834, - "spec/features/admin/poll/shifts_spec.rb": 2.6800806522369385, - "spec/i18n_spec.rb": 58.107173204422, - "spec/features/site_customization/custom_pages_spec.rb": 0.454498291015625, - "spec/features/admin/legislation/processes_spec.rb": 3.3492519855499268, - "spec/features/votes_spec.rb": 16.538654088974, - "spec/features/admin/budget_investment_milestones_spec.rb": 1.3747622966766357, - "spec/models/poll/white_result_spec.rb": 0.23045921325683594, - "spec/controllers/management/sessions_controller_spec.rb": 0.06758952140808105, - "spec/features/management/users_spec.rb": 2.044326066970825, - "spec/controllers/concerns/has_filters_spec.rb": 0.275907039642334, - "spec/features/moderation/proposals_spec.rb": 5.00596022605896, - "spec/lib/wysiwyg_sanitizer_spec.rb": 0.0016448497772216797, - "spec/models/budget/ballot_spec.rb": 0.6595156192779541, - "spec/models/poll/voter_spec.rb": 0.2982313632965088, - "spec/features/valuation/budget_investments_spec.rb": 6.490516185760498 + "spec/models/setting_spec.rb": 0.07869887351989746, + "spec/features/admin/managers_spec.rb": 5.029380798339844, + "spec/features/management/managed_users_spec.rb": 3.1642160415649414, + "spec/features/admin/poll/booths_spec.rb": 1.4152588844299316, + "spec/features/admin/comments_spec.rb": 3.889301061630249, + "spec/helpers/admin_helper_spec.rb": 0.005057334899902344, + "spec/models/abilities/moderator_spec.rb": 2.3274271488189697, + "spec/controllers/admin/api/stats_controller_spec.rb": 0.4249396324157715, + "spec/features/admin/organizations_spec.rb": 3.339292049407959, + "spec/features/admin/newsletters_spec.rb": 0.2460641860961914, + "spec/helpers/geozones_helper_spec.rb": 0.08249163627624512, + "spec/lib/graph_ql/api_types_creator_spec.rb": 0.006573915481567383, + "spec/features/emails_spec.rb": 18.91256046295166, + "spec/features/admin/hidden_users_spec.rb": 1.3854436874389648, + "spec/features/welcome_spec.rb": 1.1956276893615723, + "spec/features/sessions_spec.rb": 0.3943772315979004, + "spec/models/custom/residence_spec.rb": 0.07002687454223633, + "spec/models/poll/booth_spec.rb": 0.05489993095397949, + "spec/models/direct_message_spec.rb": 0.3973381519317627, + "spec/features/valuation/budget_investments_spec.rb": 7.6013023853302, + "spec/models/map_location_spec.rb": 0.12476563453674316, + "spec/models/budget/heading_spec.rb": 0.09248590469360352, + "spec/models/user_spec.rb": 2.9006423950195312, + "spec/features/admin/site_customization/content_blocks_spec.rb": 1.6733989715576172, + "spec/mailers/mailer_spec.rb": 0.08513784408569336, + "spec/models/site_customization/page_spec.rb": 0.015056133270263672, + "spec/features/management/budget_investments_spec.rb": 8.112786293029785, + "spec/features/admin/activity_spec.rb": 12.442089080810547, + "spec/features/registration_form_spec.rb": 1.0509357452392578, + "spec/controllers/legislation/annotations_controller_spec.rb": 0.8151364326477051, + "spec/lib/census_caller_spec.rb": 0.018165111541748047, + "spec/features/users_auth_spec.rb": 6.5102221965789795, + "spec/features/tags/proposals_spec.rb": 10.001718521118164, + "spec/features/account_spec.rb": 2.2510504722595215, + "spec/features/admin/users_spec.rb": 0.4342050552368164, + "spec/lib/cache_spec.rb": 0.057682037353515625, + "spec/features/valuation_spec.rb": 1.3436784744262695, + "spec/models/budget/investment_spec.rb": 12.89230751991272, + "spec/lib/migrate_spending_proposals_to_investments_spec.rb": 0.904367208480835, + "spec/helpers/settings_helper_spec.rb": 0.02300858497619629, + "spec/helpers/application_helper_spec.rb": 0.09152626991271973, + "spec/models/legislation/draft_version_spec.rb": 0.020322084426879883, + "spec/models/legislation/question_spec.rb": 0.3402721881866455, + "spec/models/document_spec.rb": 1.3238348960876465, + "spec/models/poll/question_spec.rb": 0.12588191032409668, + "spec/features/admin/poll/polls_spec.rb": 11.77881646156311, + "spec/lib/manager_authenticator_spec.rb": 0.006296873092651367, + "spec/features/admin/debates_spec.rb": 1.688420295715332, + "spec/features/moderation/debates_spec.rb": 5.343512773513794, + "spec/controllers/debates_controller_spec.rb": 0.40573883056640625, + "spec/models/tag_cloud_spec.rb": 1.6984672546386719, + "spec/models/budget/investment/milestone_spec.rb": 0.15051603317260742, + "spec/models/proposal_notification_spec.rb": 0.2914905548095703, + "spec/features/budgets/investments_spec.rb": 93.5263159275055, + "spec/i18n_spec.rb": 96.26275777816772, + "spec/models/community_spec.rb": 0.16270899772644043, + "spec/controllers/graphql_controller_spec.rb": 0.5831413269042969, + "spec/models/legislation/annotation_spec.rb": 0.16232728958129883, + "spec/lib/acts_as_taggable_on_spec.rb": 0.5747356414794922, + "spec/lib/census_api_spec.rb": 0.0021581649780273438, + "spec/features/moderation/comments_spec.rb": 6.70704984664917, + "spec/models/poll/voter_spec.rb": 0.32018303871154785, + "spec/features/proposal_notifications_spec.rb": 3.906450033187866, + "spec/models/budget/result_spec.rb": 0.8468267917633057, + "spec/helpers/users_helper_spec.rb": 0.25751638412475586, + "spec/features/valuation/budgets_spec.rb": 0.2564871311187744, + "spec/controllers/users/registrations_controller_spec.rb": 0.022383689880371094, + "spec/controllers/management/base_controller_spec.rb": 0.06711888313293457, + "spec/features/admin/officials_spec.rb": 0.893528938293457, + "spec/features/comments/topics_spec.rb": 29.998314142227173, + "spec/features/users_spec.rb": 11.885858297348022, + "spec/models/topic_spec.rb": 0.27634167671203613, + "spec/models/follow_spec.rb": 0.1256728172302246, + "spec/lib/local_census_spec.rb": 0.005529880523681641, + "spec/features/verification/sms_spec.rb": 1.5214743614196777, + "spec/helpers/comments_helper_spec.rb": 0.010879278182983398, + "spec/models/valuator_spec.rb": 0.02650904655456543, + "spec/features/proposal_ballots_spec.rb": 0.3937220573425293, + "spec/features/proposals_spec.rb": 142.48229122161865, + "spec/features/legislation/processes_spec.rb": 2.863476514816284, + "spec/features/ckeditor_spec.rb": 0.8433480262756348, + "spec/models/letter_spec.rb": 0.0695810317993164, + "spec/features/admin/budget_investments_spec.rb": 18.484699964523315, + "spec/models/officing/residence_spec.rb": 0.3402073383331299, + "spec/controllers/concerns/has_orders_spec.rb": 0.1844041347503662, + "spec/features/admin/legislation/processes_spec.rb": 4.020649433135986, + "spec/features/management/users_spec.rb": 2.288966178894043, + "spec/lib/tasks/communities_spec.rb": 0.15353775024414062, + "spec/models/abilities/organization_spec.rb": 0.24793481826782227, + "spec/features/polls/polls_spec.rb": 2.591568946838379, + "spec/features/communities_spec.rb": 1.6137127876281738, + "spec/models/legislation/process/phase_spec.rb": 0.07121586799621582, + "spec/features/officing_spec.rb": 0.979363203048706, + "spec/features/site_customization/custom_pages_spec.rb": 0.5588700771331787, + "spec/features/comments/legislation_questions_spec.rb": 14.133169889450073, + "spec/features/organizations_spec.rb": 0.46280837059020996, + "spec/controllers/legislation/answers_controller_spec.rb": 0.39082813262939453, + "spec/models/image_spec.rb": 7.636544466018677, + "spec/features/management/account_spec.rb": 1.150636911392212, + "spec/models/abilities/common_spec.rb": 5.959435701370239, + "spec/features/comments/debates_spec.rb": 13.69457721710205, + "spec/models/poll/shift_spec.rb": 0.19109749794006348, + "spec/features/site_customization/content_blocks_spec.rb": 0.3058288097381592, + "spec/models/poll/recount_spec.rb": 0.1983809471130371, + "spec/features/verification/level_two_verification_spec.rb": 0.4596068859100342, + "spec/features/verification/level_three_verification_spec.rb": 1.456559658050537, + "spec/lib/tasks/settings_spec.rb": 0.04654407501220703, + "spec/features/admin/budget_investment_milestones_spec.rb": 1.3974273204803467, + "spec/features/management/localization_spec.rb": 1.1653187274932861, + "spec/features/admin/tags_spec.rb": 1.0751111507415771, + "spec/features/officing/results_spec.rb": 1.2672057151794434, + "spec/features/admin/poll/booth_assigments_spec.rb": 4.1742753982543945, + "spec/models/poll/officer_assignment_spec.rb": 0.024514198303222656, + "spec/controllers/management/sessions_controller_spec.rb": 0.07244610786437988, + "spec/features/admin/signature_sheets_spec.rb": 1.4268932342529297, + "spec/models/debate_spec.rb": 4.550540924072266, + "spec/features/comments/proposals_spec.rb": 25.726442337036133, + "spec/models/poll/partial_result_spec.rb": 0.32181620597839355, + "spec/features/admin/legislation/draft_versions_spec.rb": 3.4613990783691406, + "spec/models/budget_spec.rb": 0.14807415008544922, + "spec/models/sms_spec.rb": 0.018825769424438477, + "spec/features/admin/proposals_spec.rb": 1.837270975112915, + "spec/models/geozone_spec.rb": 0.11852264404296875, + "spec/features/admin/banners_spec.rb": 3.0584604740142822, + "spec/models/legislation/process/publication_spec.rb": 0.06270265579223633, + "spec/lib/graph_ql/query_type_creator_spec.rb": 0.009456157684326172, + "spec/features/moderation_spec.rb": 1.001516342163086, + "spec/features/campaigns_spec.rb": 0.8359789848327637, + "spec/features/admin/verifications_spec.rb": 0.6421175003051758, + "spec/features/localization_spec.rb": 0.756089448928833, + "spec/features/admin/poll/questions_spec.rb": 41.59848093986511, + "spec/features/tags/debates_spec.rb": 3.4022486209869385, + "spec/helpers/text_helper_spec.rb": 0.0006229877471923828, + "spec/features/admin/moderators_spec.rb": 1.3467354774475098, + "spec/models/flag_spec.rb": 0.5202171802520752, + "spec/mailers/devise_mailer_spec.rb": 0.2588930130004883, + "spec/features/user_invites_spec.rb": 0.18819189071655273, + "spec/features/legislation/draft_versions_spec.rb": 9.352471828460693, + "spec/features/home_spec.rb": 3.0868682861328125, + "spec/features/budgets/results_spec.rb": 2.4918482303619385, + "spec/features/budgets/votes_spec.rb": 4.285862922668457, + "spec/features/comments/budget_investments_spec.rb": 16.1397545337677, + "spec/features/admin/stats_spec.rb": 2.678718090057373, + "spec/features/polls/questions_spec.rb": 2.594414472579956, + "spec/features/admin/poll/shifts_spec.rb": 4.629284143447876, + "spec/helpers/votes_helper_spec.rb": 0.31733107566833496, + "spec/models/ahoy/data_source_spec.rb": 0.04695439338684082, + "spec/models/residence_spec.rb": 0.20260858535766602, + "spec/features/admin_spec.rb": 0.6963987350463867, + "spec/controllers/comments_controller_spec.rb": 0.2683417797088623, + "spec/lib/age_spec.rb": 0.0007379055023193359, + "spec/models/legislation/answer_spec.rb": 0.14532899856567383, + "spec/features/tags_spec.rb": 3.0131027698516846, + "spec/features/admin/valuators_spec.rb": 1.0099408626556396, + "spec/models/notification_spec.rb": 0.37938618659973145, + "spec/views/welcome/index.html.erb_spec.rb": 0.1471250057220459, + "spec/customization_engine_spec.rb": 1.5587348937988281, + "spec/models/poll/officer_spec.rb": 0.2980079650878906, + "spec/features/budgets/ballots_spec.rb": 25.24861741065979, + "spec/controllers/concerns/has_filters_spec.rb": 0.1412961483001709, + "spec/features/moderation/proposals_spec.rb": 5.947849273681641, + "spec/features/management/document_verifications_spec.rb": 0.9574480056762695, + "spec/features/legislation/questions_spec.rb": 1.605849027633667, + "spec/models/proposal_spec.rb": 5.872406482696533, + "spec/models/legislation/question_option_spec.rb": 0.0395960807800293, + "spec/features/budgets/budgets_spec.rb": 0.8722023963928223, + "spec/lib/email_digests_spec.rb": 0.440814733505249, + "spec/features/official_positions_spec.rb": 1.5717194080352783, + "spec/features/officing/residence_spec.rb": 0.9819045066833496, + "spec/features/officing/voters_spec.rb": 2.078903913497925, + "spec/features/direct_messages_spec.rb": 1.6070659160614014, + "spec/models/abilities/everyone_spec.rb": 0.059804677963256836, + "spec/lib/acts_as_paranoid_aliases_spec.rb": 0.33096909523010254, + "spec/features/debates_spec.rb": 32.84718298912048, + "spec/features/votes_spec.rb": 18.217467069625854, + "spec/models/activity_spec.rb": 1.0154414176940918, + "spec/controllers/pages_controller_spec.rb": 0.19468045234680176, + "spec/features/admin/feature_flags_spec.rb": 0.726452112197876, + "spec/models/signature_sheet_spec.rb": 0.6403882503509521, + "spec/features/admin/poll/officers_spec.rb": 1.2912020683288574, + "spec/models/lock_spec.rb": 0.08562397956848145, + "spec/helpers/proposals_helper_spec.rb": 0.17275524139404297, + "spec/features/tags/budget_investments_spec.rb": 14.154245615005493, + "spec/models/vote_spec.rb": 0.9258472919464111, + "spec/features/admin/site_customization/pages_spec.rb": 1.0365827083587646, + "spec/features/moderation/users_spec.rb": 1.3000907897949219, + "spec/features/comments/legislation_annotations_spec.rb": 19.67066717147827, + "spec/features/admin/legislation/questions_spec.rb": 4.043334007263184, + "spec/models/comment_spec.rb": 1.6633994579315186, + "spec/features/admin/site_customization/images_spec.rb": 1.2299704551696777, + "spec/models/abilities/valuator_spec.rb": 1.1985805034637451, + "spec/models/organization_spec.rb": 0.12121891975402832, + "spec/models/budget/ballot_spec.rb": 0.6403298377990723, + "spec/lib/wysiwyg_sanitizer_spec.rb": 0.0018651485443115234, + "spec/features/stats_spec.rb": 0.8169982433319092, + "spec/models/poll/answer_spec.rb": 0.13266730308532715, + "spec/features/admin/settings_spec.rb": 3.1228368282318115, + "spec/features/verification/verification_path_spec.rb": 1.1146795749664307, + "spec/controllers/management/users_controller_spec.rb": 0.004178762435913086, + "spec/models/direct_upload_spec.rb": 1.1311051845550537, + "spec/features/management/email_verifications_spec.rb": 0.3727388381958008, + "spec/models/abilities/administrator_spec.rb": 2.355985164642334, + "spec/models/budget/ballot/line_spec.rb": 0.49976515769958496, + "spec/features/verification/letter_spec.rb": 1.5464122295379639, + "spec/features/notifications_spec.rb": 19.54401397705078, + "spec/features/admin/administrators_spec.rb": 1.7901337146759033, + "spec/models/signature_spec.rb": 1.5397937297821045, + "spec/models/identity_spec.rb": 0.0023458003997802734, + "spec/models/verification/management/document_spec.rb": 0.017922163009643555, + "spec/models/legislation/process_spec.rb": 0.09648776054382324, + "spec/models/budget/group_spec.rb": 0.049637794494628906, + "spec/models/verification/management/email_spec.rb": 0.057023048400878906, + "spec/helpers/verification_helper_spec.rb": 0.0009088516235351562, + "spec/features/verification/residence_spec.rb": 2.2246382236480713, + "spec/features/tracks_spec.rb": 2.320988178253174, + "spec/lib/tag_sanitizer_spec.rb": 0.0005729198455810547, + "spec/features/admin/budgets_spec.rb": 4.4486541748046875, + "spec/models/site_customization/content_block_spec.rb": 0.010473012924194336, + "spec/features/verification/email_spec.rb": 0.5266687870025635, + "spec/models/budget/reclassified_vote_spec.rb": 0.19786882400512695, + "spec/features/management/proposals_spec.rb": 4.107697486877441, + "spec/models/poll/poll_spec.rb": 0.38217735290527344, + "spec/features/admin/geozones_spec.rb": 1.561723232269287, + "spec/lib/graphql_spec.rb": 3.063258647918701, + "spec/features/verification/verified_user_spec.rb": 0.8179008960723877 } \ No newline at end of file diff --git a/spec/factories.rb b/spec/factories.rb index 30159f85a..93f00d27a 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -554,21 +554,6 @@ FactoryGirl.define do answer { question.valid_answers.sample } end - factory :poll_white_result, class: 'Poll::WhiteResult' do - association :author, factory: :user - origin { 'web' } - end - - factory :poll_null_result, class: 'Poll::NullResult' do - association :author, factory: :user - origin { 'web' } - end - - factory :poll_total_result, class: 'Poll::TotalResult' do - association :author, factory: :user - origin { 'web' } - end - factory :poll_recount, class: 'Poll::Recount' do association :author, factory: :user origin { 'web' } diff --git a/spec/models/poll/null_result_spec.rb b/spec/models/poll/null_result_spec.rb deleted file mode 100644 index 746b48377..000000000 --- a/spec/models/poll/null_result_spec.rb +++ /dev/null @@ -1,70 +0,0 @@ -require 'rails_helper' - -describe Poll::NullResult do - - describe "logging changes" do - it "should update amount_log if amount changes" do - null_result = create(:poll_null_result, amount: 33) - - expect(null_result.amount_log).to eq("") - - null_result.amount = 33 - null_result.save - null_result.amount = 32 - null_result.save - null_result.amount = 34 - null_result.save - - expect(null_result.amount_log).to eq(":33:32") - end - - it "should update officer_assignment_id_log if amount changes" do - null_result = create(:poll_null_result, amount: 33) - - expect(null_result.amount_log).to eq("") - expect(null_result.officer_assignment_id_log).to eq("") - - null_result.amount = 33 - null_result.officer_assignment = create(:poll_officer_assignment, id: 101) - null_result.save - - null_result.amount = 32 - null_result.officer_assignment = create(:poll_officer_assignment, id: 102) - null_result.save - - null_result.amount = 34 - null_result.officer_assignment = create(:poll_officer_assignment, id: 103) - null_result.save - - expect(null_result.amount_log).to eq(":33:32") - expect(null_result.officer_assignment_id_log).to eq(":101:102") - end - - it "should update author_id if amount changes" do - null_result = create(:poll_null_result, amount: 33) - - expect(null_result.amount_log).to eq("") - expect(null_result.author_id_log).to eq("") - - author_A = create(:poll_officer).user - author_B = create(:poll_officer).user - author_C = create(:poll_officer).user - - null_result.amount = 33 - null_result.author_id = author_A.id - null_result.save! - - null_result.amount = 32 - null_result.author_id = author_B.id - null_result.save! - - null_result.amount = 34 - null_result.author_id = author_C.id - null_result.save! - - expect(null_result.amount_log).to eq(":33:32") - expect(null_result.author_id_log).to eq(":#{author_A.id}:#{author_B.id}") - end - end - -end \ No newline at end of file diff --git a/spec/models/poll/total_result_spec.rb b/spec/models/poll/total_result_spec.rb deleted file mode 100644 index baa877227..000000000 --- a/spec/models/poll/total_result_spec.rb +++ /dev/null @@ -1,70 +0,0 @@ -require 'rails_helper' - -describe Poll::TotalResult do - - describe "logging changes" do - it "should update amount_log if amount changes" do - total_result = create(:poll_total_result, amount: 33) - - expect(total_result.amount_log).to eq("") - - total_result.amount = 33 - total_result.save - total_result.amount = 32 - total_result.save - total_result.amount = 34 - total_result.save - - expect(total_result.amount_log).to eq(":33:32") - end - - it "should update officer_assignment_id_log if amount changes" do - total_result = create(:poll_total_result, amount: 33) - - expect(total_result.amount_log).to eq("") - expect(total_result.officer_assignment_id_log).to eq("") - - total_result.amount = 33 - total_result.officer_assignment = create(:poll_officer_assignment, id: 101) - total_result.save - - total_result.amount = 32 - total_result.officer_assignment = create(:poll_officer_assignment, id: 102) - total_result.save - - total_result.amount = 34 - total_result.officer_assignment = create(:poll_officer_assignment, id: 103) - total_result.save - - expect(total_result.amount_log).to eq(":33:32") - expect(total_result.officer_assignment_id_log).to eq(":101:102") - end - - it "should update author_id if amount changes" do - total_result = create(:poll_total_result, amount: 33) - - expect(total_result.amount_log).to eq("") - expect(total_result.author_id_log).to eq("") - - author_A = create(:poll_officer).user - author_B = create(:poll_officer).user - author_C = create(:poll_officer).user - - total_result.amount = 33 - total_result.author_id = author_A.id - total_result.save! - - total_result.amount = 32 - total_result.author_id = author_B.id - total_result.save! - - total_result.amount = 34 - total_result.author_id = author_C.id - total_result.save! - - expect(total_result.amount_log).to eq(":33:32") - expect(total_result.author_id_log).to eq(":#{author_A.id}:#{author_B.id}") - end - end - -end diff --git a/spec/models/poll/white_result_spec.rb b/spec/models/poll/white_result_spec.rb deleted file mode 100644 index 687c4ebe1..000000000 --- a/spec/models/poll/white_result_spec.rb +++ /dev/null @@ -1,70 +0,0 @@ -require 'rails_helper' - -describe Poll::WhiteResult do - - describe "logging changes" do - it "should update amount_log if amount changes" do - white_result = create(:poll_white_result, amount: 33) - - expect(white_result.amount_log).to eq("") - - white_result.amount = 33 - white_result.save - white_result.amount = 32 - white_result.save - white_result.amount = 34 - white_result.save - - expect(white_result.amount_log).to eq(":33:32") - end - - it "should update officer_assignment_id_log if amount changes" do - white_result = create(:poll_white_result, amount: 33) - - expect(white_result.amount_log).to eq("") - expect(white_result.officer_assignment_id_log).to eq("") - - white_result.amount = 33 - white_result.officer_assignment = create(:poll_officer_assignment, id: 21) - white_result.save - - white_result.amount = 32 - white_result.officer_assignment = create(:poll_officer_assignment, id: 22) - white_result.save - - white_result.amount = 34 - white_result.officer_assignment = create(:poll_officer_assignment, id: 23) - white_result.save - - expect(white_result.amount_log).to eq(":33:32") - expect(white_result.officer_assignment_id_log).to eq(":21:22") - end - - it "should update author_id if amount changes" do - white_result = create(:poll_white_result, amount: 33) - - expect(white_result.amount_log).to eq("") - expect(white_result.author_id_log).to eq("") - - author_A = create(:poll_officer).user - author_B = create(:poll_officer).user - author_C = create(:poll_officer).user - - white_result.amount = 33 - white_result.author_id = author_A.id - white_result.save! - - white_result.amount = 32 - white_result.author_id = author_B.id - white_result.save! - - white_result.amount = 34 - white_result.author_id = author_C.id - white_result.save! - - expect(white_result.amount_log).to eq(":33:32") - expect(white_result.author_id_log).to eq(":#{author_A.id}:#{author_B.id}") - end - end - -end \ No newline at end of file From 63cbe2f7c115e5602cd8f73bbc2f9029b8e38759 Mon Sep 17 00:00:00 2001 From: Manuel Lucena Date: Tue, 3 Oct 2017 18:25:22 +0200 Subject: [PATCH 002/211] 20171003 - [WIP] Functionality and tests for polls comments --- app/controllers/polls_controller.rb | 5 + app/helpers/flags_helper.rb | 2 +- app/models/comment.rb | 2 +- app/models/comment_notifier.rb | 1 + app/models/poll.rb | 5 +- app/views/polls/questions/show.html.erb | 92 +++++++++++++++++++ app/views/polls/show.html.erb | 6 +- app/views/shared/_comments.html.erb | 31 +++++++ ...71003143034_add_comments_count_to_polls.rb | 7 ++ db/schema.rb | 3 + spec/features/polls/polls_spec.rb | 33 +++++++ 11 files changed, 183 insertions(+), 4 deletions(-) create mode 100644 app/views/polls/questions/show.html.erb create mode 100644 app/views/shared/_comments.html.erb create mode 100644 db/migrate/20171003143034_add_comments_count_to_polls.rb diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index 41a038b46..289a33be3 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -1,8 +1,10 @@ class PollsController < ApplicationController + include CommentableActions load_and_authorize_resource has_filters %w{current expired incoming} + has_orders %w{most_voted newest oldest}, only: :show ::Poll::Answer # trigger autoload @@ -13,6 +15,9 @@ class PollsController < ApplicationController def show @questions = @poll.questions.for_render.sort_for_list + @commentable = @poll + @comment_tree = CommentTree.new(@commentable, params[:page], @current_order) + @answers_by_question_id = {} poll_answers = ::Poll::Answer.by_question(@poll.question_ids).by_author(current_user.try(:id)) poll_answers.each do |answer| diff --git a/app/helpers/flags_helper.rb b/app/helpers/flags_helper.rb index b5ba67f41..9983b34ae 100644 --- a/app/helpers/flags_helper.rb +++ b/app/helpers/flags_helper.rb @@ -12,7 +12,7 @@ module FlagsHelper def flagged?(flaggable) if flaggable.is_a? Comment - @comment_flags[flaggable.id] + @comment_flags[flaggable.id] unless flaggable.commentable_type == "Poll" else Flag.flagged?(current_user, flaggable) end diff --git a/app/models/comment.rb b/app/models/comment.rb index 8b68e11ad..37fa9b630 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -3,7 +3,7 @@ class Comment < ActiveRecord::Base include HasPublicAuthor include Graphqlable - COMMENTABLE_TYPES = %w(Debate Proposal Budget::Investment Poll::Question Legislation::Question Legislation::Annotation Topic).freeze + COMMENTABLE_TYPES = %w(Debate Proposal Budget::Investment Poll::Question Legislation::Question Legislation::Annotation Topic Poll).freeze acts_as_paranoid column: :hidden_at include ActsAsParanoidAliases diff --git a/app/models/comment_notifier.rb b/app/models/comment_notifier.rb index 68b350e6b..600009a23 100644 --- a/app/models/comment_notifier.rb +++ b/app/models/comment_notifier.rb @@ -22,6 +22,7 @@ class CommentNotifier end def email_on_comment? + return false if @comment.commentable.is_a?(Poll) commentable_author = @comment.commentable.author commentable_author != @author && commentable_author.email_on_comment? end diff --git a/app/models/poll.rb b/app/models/poll.rb index 84349bf0b..60b6d1406 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -1,6 +1,7 @@ class Poll < ActiveRecord::Base include Imageable - + acts_as_paranoid column: :hidden_at + include ActsAsParanoidAliases has_many :booth_assignments, class_name: "Poll::BoothAssignment" has_many :booths, through: :booth_assignments has_many :partial_results, through: :booth_assignments @@ -9,8 +10,10 @@ class Poll < ActiveRecord::Base has_many :officer_assignments, through: :booth_assignments has_many :officers, through: :officer_assignments has_many :questions + has_many :comments, as: :commentable has_and_belongs_to_many :geozones + belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' validates :name, presence: true diff --git a/app/views/polls/questions/show.html.erb b/app/views/polls/questions/show.html.erb new file mode 100644 index 000000000..f8d12c59d --- /dev/null +++ b/app/views/polls/questions/show.html.erb @@ -0,0 +1,92 @@ +<% provide :title do %><%= @question.title %><% end %> + +
+
+
+ <%= back_link_to %> + +

<%= @question.title %>

+ + <% if @question.proposal.present? %> +
+ <%= link_to t('poll_questions.show.original_proposal'), @question.proposal %> +
+ <% end %> + + <% if can? :answer, @question %> + <%= link_to t('poll_questions.show.answer_this_question'), + @question.poll, + class: 'large button' %> + <% else %> + <%= render 'polls/reasons_for_not_answering', poll: @question.poll %> + <% end %> +
+ +
+

+ + <%= t('poll_questions.show.author') %> + +
+ <% if @question.author_visible_name.present? %> + <%= @question.author_visible_name %> + <% else %> + <%= link_to @question.author.name, @question.author %> + <% end %> + +

+ +

+ + <%= t('poll_questions.show.poll') %> + +
+ <%= link_to @question.poll.name, @question.poll %> +

+ +

+ + <%= t('poll_questions.show.dates_title') %> + +
+ <%= poll_dates(@question.poll) %> +

+
+
+
+ +<% if @question.video_url.present? %> +
+
+ +
+
+ +<% end %> + +
+
+

<%= t('poll_questions.show.more_info') %>

+ <%= @question.description %> +
+
+ +
+ <%= render "polls/questions/filter_subnav" %> + +
+ <%= render "shared/comments" %> +
+ +
+ <%= render 'documents/documents', + documents: @question.documents, + max_documents_allowed: Poll::Question.max_documents_allowed %> +
+
diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index b632fac55..ae334568c 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -79,6 +79,10 @@ <% end %> - + + +
+ <%= render "shared/comments" %> +
diff --git a/app/views/shared/_comments.html.erb b/app/views/shared/_comments.html.erb new file mode 100644 index 000000000..db097a7c4 --- /dev/null +++ b/app/views/shared/_comments.html.erb @@ -0,0 +1,31 @@ +<% cache [locale_and_user_status, @current_order, commentable_cache_key(@commentable), @comment_tree.comments, @comment_tree.comment_authors, @commentable.comments_count, @comment_flags] do %> +
+
+
+

+ <%= t("shared.comments.title") %> + (<%= @commentable.comments_count %>) +

+ + <%= render 'shared/wide_order_selector', i18n_namespace: "comments" %> + + <% if user_signed_in? %> + <%= render 'comments/form', {commentable: @commentable, parent_id: nil, toggeable: false} %> + <% else %> +
+ +
+ <%= t("shared.comments.login_to_comment", + signin: link_to(t("votes.signin"), new_user_session_path), + signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %> +
+ <% end %> + + <% @comment_tree.root_comments.each do |comment| %> + <%= render 'comments/comment', comment: comment %> + <% end %> + <%= paginate @comment_tree.root_comments %> +
+
+
+<% end %> diff --git a/db/migrate/20171003143034_add_comments_count_to_polls.rb b/db/migrate/20171003143034_add_comments_count_to_polls.rb new file mode 100644 index 000000000..675acae3f --- /dev/null +++ b/db/migrate/20171003143034_add_comments_count_to_polls.rb @@ -0,0 +1,7 @@ +class AddCommentsCountToPolls < ActiveRecord::Migration + def change + add_column :polls, :comments_count, :integer, default: 0 + add_column :polls, :author_id, :integer + add_column :polls, :hidden_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index dbbd3ec46..d393716e6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -792,6 +792,9 @@ ActiveRecord::Schema.define(version: 20171004151553) do t.boolean "geozone_restricted", default: false t.text "summary" t.text "description" + t.integer "comments_count", default: 0 + t.integer "author_id" + t.datetime "hidden_at" end add_index "polls", ["starts_at", "ends_at"], name: "index_polls_on_starts_at_and_ends_at", using: :btree diff --git a/spec/features/polls/polls_spec.rb b/spec/features/polls/polls_spec.rb index 22b90740a..1c18e752d 100644 --- a/spec/features/polls/polls_spec.rb +++ b/spec/features/polls/polls_spec.rb @@ -256,5 +256,38 @@ feature 'Polls' do expect(page).to have_link('Han Solo') end + scenario 'User can write comments' do + create(:comment, commentable: poll) + + visit poll_path(poll) + + expect(page).to have_css('.comment', count: 1) + + comment = Comment.last + within first('.comment') do + expect(page).to have_content comment.user.name + expect(page).to have_content I18n.l(comment.created_at, format: :datetime) + expect(page).to have_content comment.body + end + end + + scenario 'user can reply to comment' do + oliver = create(:user, username: 'Oliver Atom') + benji = create(:user, username: 'Benji Prince') + create(:comment, commentable: poll, user: oliver) + + login_as(oliver) + visit poll_path(poll) + + expect(page).to have_content oliver.username + end + + scenario 'user can upvote a comment' do + + end + + scenario 'user can downvote a comment' do + + end end end From c3d7d47c3f24de2ffa90edbb66f3b42d6704946d Mon Sep 17 00:00:00 2001 From: Manuel Lucena Date: Wed, 4 Oct 2017 15:23:24 +0200 Subject: [PATCH 003/211] 20171004 - Refactored specs for polls comments On branch mlucena-poll-comments Changes to be committed: modified: app/views/comments/show.html.erb modified: spec/features/polls/polls_spec.rb --- app/views/comments/show.html.erb | 2 +- spec/features/polls/polls_spec.rb | 52 ++++++++++++++++++++++++++++--- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/app/views/comments/show.html.erb b/app/views/comments/show.html.erb index a779d1dfa..ce76633a0 100644 --- a/app/views/comments/show.html.erb +++ b/app/views/comments/show.html.erb @@ -1,7 +1,7 @@
<%= back_link_to commentable_path(@comment), - t("comments.show.return_to_commentable") + @comment.commentable.title %> + t("comments.show.return_to_commentable") + @comment.commentable.title unless @comment != "Poll" %>
diff --git a/spec/features/polls/polls_spec.rb b/spec/features/polls/polls_spec.rb index 1c18e752d..76932558b 100644 --- a/spec/features/polls/polls_spec.rb +++ b/spec/features/polls/polls_spec.rb @@ -271,23 +271,67 @@ feature 'Polls' do end end - scenario 'user can reply to comment' do + scenario 'user b can access to comments from user a' do oliver = create(:user, username: 'Oliver Atom') benji = create(:user, username: 'Benji Prince') create(:comment, commentable: poll, user: oliver) - login_as(oliver) + login_as(benji) visit poll_path(poll) expect(page).to have_content oliver.username end - scenario 'user can upvote a comment' do + scenario 'user b can reply to comments from user a', :js do + koji = create(:user, username: 'Koji Kabuto') + sayaka = create(:user, username: 'Sayaka') + comment = create(:comment, commentable: poll, user: koji) + login_as(sayaka) + visit poll_path(poll) + + click_link "Reply" + + within "#js-comment-form-comment_#{comment.id}" do + fill_in "comment-body-comment_#{comment.id}", with: 'MAZINGER!!.' + click_button 'Publish reply' + end + + within "#comment_#{comment.id}" do + expect(page).to have_content 'MAZINGER!!.' + end + + expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true) end - scenario 'user can downvote a comment' do + scenario 'user can upvote a comment', :js do + goku = create(:user, username: 'Goku') + vegeta = create(:user, username: 'Vegeta') + comment = create(:comment, commentable: poll, user: goku) + login_as(vegeta) + visit poll_path(poll) + + within("#comment_#{comment.id}_votes") do + find('.in_favor a').click + + expect(page).to have_content "1 vote" + end + end + + scenario 'user can downvote a comment', :js do + doraemon = create(:user, username: 'Doraemon') + nobita = create(:user, username: 'Nobi Nobita') + comment = create(:comment, commentable: poll, user: doraemon) + + login_as(nobita) + visit poll_path(poll) + + within("#comment_#{comment.id}_votes") do + find('.against a').click + + expect(page).to have_content "1 vote" + end end end end From 8277e3cc2b7c332d2bd009adf8220759ded683bb Mon Sep 17 00:00:00 2001 From: Manuel Lucena Date: Thu, 5 Oct 2017 18:24:16 +0200 Subject: [PATCH 004/211] removed obsolete polls questions view --- app/views/polls/questions/show.html.erb | 92 ------------------------- app/views/polls/show.html.erb | 2 - 2 files changed, 94 deletions(-) delete mode 100644 app/views/polls/questions/show.html.erb diff --git a/app/views/polls/questions/show.html.erb b/app/views/polls/questions/show.html.erb deleted file mode 100644 index f8d12c59d..000000000 --- a/app/views/polls/questions/show.html.erb +++ /dev/null @@ -1,92 +0,0 @@ -<% provide :title do %><%= @question.title %><% end %> - -
-
-
- <%= back_link_to %> - -

<%= @question.title %>

- - <% if @question.proposal.present? %> -
- <%= link_to t('poll_questions.show.original_proposal'), @question.proposal %> -
- <% end %> - - <% if can? :answer, @question %> - <%= link_to t('poll_questions.show.answer_this_question'), - @question.poll, - class: 'large button' %> - <% else %> - <%= render 'polls/reasons_for_not_answering', poll: @question.poll %> - <% end %> -
- -
-

- - <%= t('poll_questions.show.author') %> - -
- <% if @question.author_visible_name.present? %> - <%= @question.author_visible_name %> - <% else %> - <%= link_to @question.author.name, @question.author %> - <% end %> - -

- -

- - <%= t('poll_questions.show.poll') %> - -
- <%= link_to @question.poll.name, @question.poll %> -

- -

- - <%= t('poll_questions.show.dates_title') %> - -
- <%= poll_dates(@question.poll) %> -

-
-
-
- -<% if @question.video_url.present? %> -
-
- -
-
- -<% end %> - -
-
-

<%= t('poll_questions.show.more_info') %>

- <%= @question.description %> -
-
- -
- <%= render "polls/questions/filter_subnav" %> - -
- <%= render "shared/comments" %> -
- -
- <%= render 'documents/documents', - documents: @question.documents, - max_documents_allowed: Poll::Question.max_documents_allowed %> -
-
diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index ae334568c..a67aca798 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -79,8 +79,6 @@ <% end %> - -
<%= render "shared/comments" %>
From ba9814cd85ac324ace35040bfff6da053a7e5181 Mon Sep 17 00:00:00 2001 From: decabeza Date: Mon, 9 Oct 2017 13:01:39 +0200 Subject: [PATCH 005/211] shows videos on polls answers --- app/views/polls/show.html.erb | 16 ++++++++++++++++ config/locales/en/general.yml | 1 + config/locales/es/general.yml | 1 + 3 files changed, 18 insertions(+) diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index 19daf5e35..b7877aa51 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -125,6 +125,22 @@ <% end %> <% end %> + + <% if answer.videos.present? %> + + <% end %> <% end %> diff --git a/config/locales/en/general.yml b/config/locales/en/general.yml index 413a6abf8..6c3356b6d 100644 --- a/config/locales/en/general.yml +++ b/config/locales/en/general.yml @@ -495,6 +495,7 @@ en: read_more: "Read more about %{answer}" read_less: "Read less about %{answer}" participate_in_other_polls: Participate in other polls + videos: "External video" poll_questions: create_question: "Create question" default_valid_answers: "Yes, No" diff --git a/config/locales/es/general.yml b/config/locales/es/general.yml index b8747406b..5f756bbdd 100644 --- a/config/locales/es/general.yml +++ b/config/locales/es/general.yml @@ -495,6 +495,7 @@ es: read_more: "Leer más sobre %{answer}" read_less: "Leer menos sobre %{answer}" participate_in_other_polls: Participar en otras votaciones + videos: "Vídeo externo" poll_questions: create_question: "Crear pregunta para votación" default_valid_answers: "Sí, No" From f23073bb286984b05edd1d90f2817cde5fbe79be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Mon, 9 Oct 2017 13:12:44 +0200 Subject: [PATCH 006/211] Fixed already voted message in poll show --- app/views/polls/show.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index 19daf5e35..d626f4f11 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -39,7 +39,7 @@ <% else %> - <% if current_user && !@poll.votable_by?(current_user) %> + <% if current_user && @poll.votable_by?(current_user) %>
<%= t("polls.show.already_voted_in_web") %>
From 3fc3f9e88e76542b832e53aa3814a015d8ef9b99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Mon, 9 Oct 2017 17:42:13 +0200 Subject: [PATCH 007/211] Fixed condition --- app/views/polls/show.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index d626f4f11..c9796b836 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -39,7 +39,7 @@ <% else %> - <% if current_user && @poll.votable_by?(current_user) %> + <% unless current_user && @poll.votable_by?(current_user) %>
<%= t("polls.show.already_voted_in_web") %>
From 07f74cf6e5339539164a76f92a611114b593b918 Mon Sep 17 00:00:00 2001 From: decabeza Date: Mon, 9 Oct 2017 19:40:16 +0200 Subject: [PATCH 008/211] improves layout for admin polls index --- app/views/admin/poll/polls/_poll.html.erb | 4 ++-- app/views/admin/poll/polls/index.html.erb | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/views/admin/poll/polls/_poll.html.erb b/app/views/admin/poll/polls/_poll.html.erb index b65ce3e71..5ec63b6b5 100644 --- a/app/views/admin/poll/polls/_poll.html.erb +++ b/app/views/admin/poll/polls/_poll.html.erb @@ -7,7 +7,7 @@ <%= l poll.starts_at.to_date %> - <%= l poll.ends_at.to_date %> - + <%= link_to t("admin.actions.edit"), edit_admin_poll_path(poll), class: "button hollow" %> @@ -15,4 +15,4 @@ admin_poll_path(poll), class: "button hollow" %> - \ No newline at end of file + diff --git a/app/views/admin/poll/polls/index.html.erb b/app/views/admin/poll/polls/index.html.erb index 5bd310e54..791ec4876 100644 --- a/app/views/admin/poll/polls/index.html.erb +++ b/app/views/admin/poll/polls/index.html.erb @@ -5,11 +5,11 @@ class: "button success float-right" %> <% if @polls.any? %> - +
- + <%= render @polls %> @@ -19,4 +19,4 @@
<%= t("admin.polls.index.no_polls") %>
-<% end %> \ No newline at end of file +<% end %> From 80298a2746ff3c43d76cd0743cb2ff560bda58f5 Mon Sep 17 00:00:00 2001 From: decabeza Date: Mon, 9 Oct 2017 19:42:10 +0200 Subject: [PATCH 009/211] improves admin poll header --- app/assets/stylesheets/layout.scss | 4 +++ .../admin/poll/polls/_poll_header.html.erb | 30 ++++++++++++------- config/locales/en/admin.yml | 1 + config/locales/es/admin.yml | 1 + 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index efa0454db..160819795 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -155,6 +155,10 @@ a { margin-bottom: $line-height; } +.margin-left { + margin-left: $line-height; +} + .margin-right { margin-right: $line-height; } diff --git a/app/views/admin/poll/polls/_poll_header.html.erb b/app/views/admin/poll/polls/_poll_header.html.erb index a88dd03ee..2b1ade5fb 100644 --- a/app/views/admin/poll/polls/_poll_header.html.erb +++ b/app/views/admin/poll/polls/_poll_header.html.erb @@ -1,17 +1,25 @@ -<%= link_to t("admin.actions.edit"), +<%= link_to t("admin.polls.edit.title"), edit_admin_poll_path(@poll), class: "button hollow float-right" %>

<%= @poll.name %>

-
- - (<%= l @poll.starts_at.to_date %> - <%= l @poll.ends_at.to_date %>) - -<% if @poll.geozone_restricted %> -  •  - - <%= @poll.geozones.pluck(:name).to_sentence %> - -<% end %> \ No newline at end of file + +
+ +
+
+ <%= t("admin.polls.index.dates") %> +
+ <%= l @poll.starts_at.to_date %> - <%= l @poll.ends_at.to_date %> +
+ + <% if @poll.geozone_restricted %> +
+ <%= t("admin.polls.index.geozone_restricted") %> +
+ <%= @poll.geozones.pluck(:name).to_sentence %> +
+ <% end %> +
diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 442c93727..8c3b3c944 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -552,6 +552,7 @@ en: create: "Create poll" name: "Name" dates: "Dates" + geozone_restricted: "Restricted to districts" new: title: "New poll" submit_button: "Create poll" diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 5b6393b1b..a4f400427 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -552,6 +552,7 @@ es: create: "Crear votación" name: "Nombre" dates: "Fechas" + geozone_restricted: "Restringida a los distritos" new: title: "Nueva votación" submit_button: "Crear votación" From 36d39503e8ff88754d38980b2732a0166f1171e6 Mon Sep 17 00:00:00 2001 From: decabeza Date: Mon, 9 Oct 2017 19:42:53 +0200 Subject: [PATCH 010/211] improves admin poll questions show --- app/views/admin/poll/questions/show.html.erb | 6 +++--- config/locales/en/admin.yml | 3 ++- config/locales/es/admin.yml | 3 ++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/views/admin/poll/questions/show.html.erb b/app/views/admin/poll/questions/show.html.erb index 5baabeafe..52c4f3276 100644 --- a/app/views/admin/poll/questions/show.html.erb +++ b/app/views/admin/poll/questions/show.html.erb @@ -1,6 +1,6 @@ <%= back_link_to %> -<%= link_to t('shared.edit'), edit_admin_question_path(@question), +<%= link_to t('admin.questions.show.edit_question'), edit_admin_question_path(@question), class: "button hollow float-right" %>
@@ -8,7 +8,7 @@

- <%= t("admin.questions.show.title") %> + <%= t("admin.questions.show.question") %>
<%= @question.title %>

@@ -35,7 +35,7 @@ <%= t('admin.questions.show.valid_answers') %> <%= link_to t("admin.questions.show.add_answer"), new_admin_question_answer_path(@question), - class: "button hollow float-right" %> + class: "button float-right" %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 8c3b3c944..6a30235e0 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -595,7 +595,8 @@ en: show: proposal: Original proposal author: Author - title: Title + question: Question + edit_question: Edit question valid_answers: Valid answers add_answer: Add answer video_url: External video diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index a4f400427..9d4af1e81 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -595,7 +595,8 @@ es: show: proposal: Propuesta ciudadana original author: Autor - title: Título + question: Pregunta + edit_question: Editar pregunta valid_answers: Respuestas válidas add_answer: Añadir respuesta video_url: Video externo From 9dc8a0fb344cb3112ddd87df48ad13d35439a055 Mon Sep 17 00:00:00 2001 From: decabeza Date: Mon, 9 Oct 2017 19:44:12 +0200 Subject: [PATCH 011/211] fixes questions table with long links on description --- app/views/admin/poll/questions/show.html.erb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/views/admin/poll/questions/show.html.erb b/app/views/admin/poll/questions/show.html.erb index 52c4f3276..697843d0d 100644 --- a/app/views/admin/poll/questions/show.html.erb +++ b/app/views/admin/poll/questions/show.html.erb @@ -49,21 +49,21 @@ <% @question.question_answers.each do |answer| %>
- - - + + - - - <% @question.question_answers.each do |answer| %> - - - - - - - - <% end %> + + <% @question.question_answers.each do |answer| %> + + + + + + + + <% end %> +
<%= t("admin.polls.index.name") %> <%= t("admin.polls.index.dates") %><%= t("admin.actions.actions") %><%= t("admin.actions.actions") %>
<%= link_to answer.title, admin_answer_path(answer) %><%= answer.description %> + <%= link_to answer.title, admin_answer_path(answer) %><%= answer.description %> (<%= answer.images.count %>)
<%= link_to t("admin.questions.show.answers.images_list"), admin_answer_images_path(answer) %>
+ (<%= answer.documents.count rescue 0 %>)
<%= link_to t("admin.questions.show.answers.documents_list"), admin_answer_documents_path(answer) %>
+ (<%= answer.videos.count %>)
<%= link_to t("admin.questions.show.answers.video_list"), From 471860ea415444f099abc8386283b9cbf1602d08 Mon Sep 17 00:00:00 2001 From: decabeza Date: Mon, 9 Oct 2017 19:44:58 +0200 Subject: [PATCH 012/211] puts content on a table for polls questions answers show --- .../poll/questions/answers/show.html.erb | 41 +++++++++---------- config/locales/en/admin.yml | 1 + config/locales/es/admin.yml | 1 + 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/app/views/admin/poll/questions/answers/show.html.erb b/app/views/admin/poll/questions/answers/show.html.erb index e6e0244a0..83249f606 100644 --- a/app/views/admin/poll/questions/answers/show.html.erb +++ b/app/views/admin/poll/questions/answers/show.html.erb @@ -1,6 +1,6 @@ <%= back_link_to %> -<%= link_to t('shared.edit'), edit_admin_answer_path(@answer), +<%= link_to t("admin.answers.show.edit"), edit_admin_answer_path(@answer), class: "button hollow float-right" %>
<%= t("admin.questions.show.answers.videos") %>
<%= link_to answer.title, admin_answer_path(answer) %><%= answer.description %> - (<%= answer.images.count %>) -
- <%= link_to t("admin.questions.show.answers.images_list"), - admin_answer_images_path(answer) %> -
- (<%= answer.documents.count rescue 0 %>) -
- <%= link_to t("admin.questions.show.answers.documents_list"), - admin_answer_documents_path(answer) %> -
- (<%= answer.videos.count %>) -
- <%= link_to t("admin.questions.show.answers.video_list"), - admin_answer_videos_path(answer) %> -
<%= link_to answer.title, admin_answer_path(answer) %><%= answer.description %> + (<%= answer.images.count %>) +
+ <%= link_to t("admin.questions.show.answers.images_list"), + admin_answer_images_path(answer) %> +
+ (<%= answer.documents.count rescue 0 %>) +
+ <%= link_to t("admin.questions.show.answers.documents_list"), + admin_answer_documents_path(answer) %> +
+ (<%= answer.videos.count %>) +
+ <%= link_to t("admin.questions.show.answers.video_list"), + admin_answer_videos_path(answer) %> +
<% if @question.video_url.present? %> diff --git a/config/routes.rb b/config/routes.rb index 83b5754d7..1fb74aa53 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -306,6 +306,7 @@ Rails.application.routes.draw do resources :videos, controller: 'questions/answers/videos' get :documents, to: 'questions/answers#documents' end + post '/answers/order_answers', to: 'questions/answers#order_answers' end end diff --git a/db/migrate/20171010143623_add_given_order_to_poll_question_answers.rb b/db/migrate/20171010143623_add_given_order_to_poll_question_answers.rb new file mode 100644 index 000000000..6161e55e4 --- /dev/null +++ b/db/migrate/20171010143623_add_given_order_to_poll_question_answers.rb @@ -0,0 +1,5 @@ +class AddGivenOrderToPollQuestionAnswers < ActiveRecord::Migration + def change + add_column :poll_question_answers, :given_order, :integer, default: 1 + end +end diff --git a/db/schema.rb b/db/schema.rb index 9adba12b1..b9a1524ab 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20171006145053) do +ActiveRecord::Schema.define(version: 20171010143623) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -680,6 +680,7 @@ ActiveRecord::Schema.define(version: 20171006145053) do t.string "title" t.text "description" t.integer "question_id" + t.integer "given_order", default: 1 end add_index "poll_question_answers", ["question_id"], name: "index_poll_question_answers_on_question_id", using: :btree From 943c1f23af529dff41e2826387120afe393904dd Mon Sep 17 00:00:00 2001 From: iagirre Date: Tue, 10 Oct 2017 13:28:49 +0200 Subject: [PATCH 023/211] Spects added to test the order of answers. Default order for question_answers set. --- .../poll/questions/answers_controller.rb | 9 +++---- app/models/poll/question.rb | 2 +- app/models/poll/question/answer.rb | 16 +++++++++---- .../poll/questions/answers/answers_spec.rb | 24 +++++++++++++++++-- spec/features/polls/answers_spec.rb | 6 +++-- spec/features/polls/polls_spec.rb | 24 +++++++++++++++++++ 6 files changed, 67 insertions(+), 14 deletions(-) diff --git a/app/controllers/admin/poll/questions/answers_controller.rb b/app/controllers/admin/poll/questions/answers_controller.rb index a2490475b..7261adc9f 100644 --- a/app/controllers/admin/poll/questions/answers_controller.rb +++ b/app/controllers/admin/poll/questions/answers_controller.rb @@ -9,6 +9,7 @@ class Admin::Poll::Questions::AnswersController < Admin::Poll::BaseController def create @answer = ::Poll::Question::Answer.new(answer_params) + @answer.set_order if @answer.save redirect_to admin_question_path(@answer.question), @@ -37,12 +38,12 @@ class Admin::Poll::Questions::AnswersController < Admin::Poll::BaseController @documents = @answer.documents render 'admin/poll/questions/answers/documents' - end - + end + def order_answers ::Poll::Question::Answer.order_answers(params[:ordered_list]) - #redirect_to admin_question_path(params[:question_id]) - render :nothing => true + # redirect_to admin_question_path(params[:question_id]) + render nothing: true end private diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb index e6ef482a9..efcaf4635 100644 --- a/app/models/poll/question.rb +++ b/app/models/poll/question.rb @@ -10,7 +10,7 @@ class Poll::Question < ActiveRecord::Base has_many :comments, as: :commentable has_many :answers, class_name: 'Poll::Answer' - has_many :question_answers, class_name: 'Poll::Question::Answer' + has_many :question_answers, -> { order 'given_order asc' }, class_name: 'Poll::Question::Answer' has_many :partial_results belongs_to :proposal diff --git a/app/models/poll/question/answer.rb b/app/models/poll/question/answer.rb index ba7fe366a..a7aa3339a 100644 --- a/app/models/poll/question/answer.rb +++ b/app/models/poll/question/answer.rb @@ -1,5 +1,5 @@ class Poll::Question::Answer < ActiveRecord::Base - include Galleryable + include Galleryable include Documentable documentable max_documents_allowed: 3, max_file_size: 3.megabytes, @@ -14,12 +14,18 @@ class Poll::Question::Answer < ActiveRecord::Base def description super.try :html_safe end - + def self.order_answers(ordered_array) ordered_array.each_with_index do |answer_id, order| - answer = self.find(answer_id) + answer = find(answer_id) answer.update_attribute(:given_order, (order + 1)) - answer.save - end + answer.save + end + end + + def set_order + last_position = Poll::Question::Answer.where(question_id: question_id).maximum("given_order") || 0 + next_position = last_position + 1 + update_attribute(:given_order, next_position) end end diff --git a/spec/features/admin/poll/questions/answers/answers_spec.rb b/spec/features/admin/poll/questions/answers/answers_spec.rb index 66918c4d8..48c2017f4 100644 --- a/spec/features/admin/poll/questions/answers/answers_spec.rb +++ b/spec/features/admin/poll/questions/answers/answers_spec.rb @@ -4,7 +4,7 @@ feature 'Answers' do background do admin = create(:administrator) - login_as (admin.user) + login_as admin.user end scenario 'Create' do @@ -24,9 +24,27 @@ feature 'Answers' do expect(page).to have_content(description) end + scenario 'Create second answer and place after the first one' do + question = create(:poll_question) + answer = create(:poll_question_answer, title: 'First', question: question, given_order: 1) + title = 'Second' + description = "Description" + + visit admin_question_path(question) + click_link 'Add answer' + + fill_in 'poll_question_answer_title', with: title + fill_in 'poll_question_answer_description', with: description + + click_button 'Save' + + expect(page.body.index('First')).to be < page.body.index('Second') + end + scenario 'Update' do question = create(:poll_question) - answer = create(:poll_question_answer, question: question, title: "Answer title") + answer = create(:poll_question_answer, question: question, title: "Answer title", given_order: 1) + answer2 = create(:poll_question_answer, question: question, title: "Another title", given_order: 2) visit admin_answer_path(answer) @@ -46,6 +64,8 @@ feature 'Answers' do expect(page).to have_content(new_title) expect(page).to_not have_content(old_title) + + expect(page.body.index(new_title)).to be < page.body.index(answer2.title) end end diff --git a/spec/features/polls/answers_spec.rb b/spec/features/polls/answers_spec.rb index f7dfd4d38..368597830 100644 --- a/spec/features/polls/answers_spec.rb +++ b/spec/features/polls/answers_spec.rb @@ -9,13 +9,15 @@ feature 'Answers' do scenario "Index" do question = create(:poll_question) - answer1 = create(:poll_question_answer, question: question) - answer2 = create(:poll_question_answer, question: question) + answer1 = create(:poll_question_answer, question: question, given_order: 1) + answer2 = create(:poll_question_answer, question: question, given_order: 2) visit admin_question_path(question) expect(page).to have_css(".poll_question_answer", count: 2) + expect(page.body.index(answer1.title)).to be < page.body.index(answer2.title) + within("#poll_question_answer_#{answer1.id}") do expect(page).to have_content answer1.title expect(page).to have_content answer1.description diff --git a/spec/features/polls/polls_spec.rb b/spec/features/polls/polls_spec.rb index 9fdb07255..fc21e1e5f 100644 --- a/spec/features/polls/polls_spec.rb +++ b/spec/features/polls/polls_spec.rb @@ -78,6 +78,30 @@ feature 'Polls' do expect(page).to have_content(proposal_question.title) end + scenario "Question answers appear in the given order" do + question = create(:poll_question, poll: poll) + answer1 = create(:poll_question_answer, title: 'First', question: question, given_order: 1) + answer2 = create(:poll_question_answer, title: 'Second', question: question, given_order: 2) + + visit poll_path(poll) + + within("div#poll_question_#{question.id}") do + expect(page.body.index(answer1.title)).to be < page.body.index(answer2.title) + end + end + + scenario "More info answers appear in the given order" do + question = create(:poll_question, poll: poll) + answer1 = create(:poll_question_answer, title: 'First', question: question, given_order: 1) + answer2 = create(:poll_question_answer, title: 'Second', question: question, given_order: 2) + + visit poll_path(poll) + + within('div.poll-more-info-answers') do + expect(page.body.index(answer1.title)).to be < page.body.index(answer2.title) + end + end + scenario 'Non-logged in users' do question = create(:poll_question, poll: poll) answer1 = create(:poll_question_answer, question: question, title: 'Han Solo') From 44474e76865dfd48f623784824e9ced0f9ebf7f2 Mon Sep 17 00:00:00 2001 From: iagirre Date: Tue, 10 Oct 2017 13:58:06 +0200 Subject: [PATCH 024/211] Deleted a forgotten comment --- app/controllers/admin/poll/questions/answers_controller.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controllers/admin/poll/questions/answers_controller.rb b/app/controllers/admin/poll/questions/answers_controller.rb index 7261adc9f..4e420575f 100644 --- a/app/controllers/admin/poll/questions/answers_controller.rb +++ b/app/controllers/admin/poll/questions/answers_controller.rb @@ -42,7 +42,6 @@ class Admin::Poll::Questions::AnswersController < Admin::Poll::BaseController def order_answers ::Poll::Question::Answer.order_answers(params[:ordered_list]) - # redirect_to admin_question_path(params[:question_id]) render nothing: true end From 644d09ebd2426073addf1631bfab5bee62f34931 Mon Sep 17 00:00:00 2001 From: iagirre Date: Wed, 11 Oct 2017 09:42:52 +0200 Subject: [PATCH 025/211] PR comments applied and poll_question_answer default name changed in factory. --- .../admin/poll/questions/answers_controller.rb | 1 - app/models/poll/question/answer.rb | 16 ++++++++++------ spec/factories.rb | 4 ++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/app/controllers/admin/poll/questions/answers_controller.rb b/app/controllers/admin/poll/questions/answers_controller.rb index 4e420575f..bef176a22 100644 --- a/app/controllers/admin/poll/questions/answers_controller.rb +++ b/app/controllers/admin/poll/questions/answers_controller.rb @@ -9,7 +9,6 @@ class Admin::Poll::Questions::AnswersController < Admin::Poll::BaseController def create @answer = ::Poll::Question::Answer.new(answer_params) - @answer.set_order if @answer.save redirect_to admin_question_path(@answer.question), diff --git a/app/models/poll/question/answer.rb b/app/models/poll/question/answer.rb index a7aa3339a..7514b85a4 100644 --- a/app/models/poll/question/answer.rb +++ b/app/models/poll/question/answer.rb @@ -10,6 +10,9 @@ class Poll::Question::Answer < ActiveRecord::Base has_many :videos, class_name: 'Poll::Question::Answer::Video' validates :title, presence: true + validates :given_order, presence: true, uniqueness: { scope: :question_id } + + before_validation :set_order, on: :create def description super.try :html_safe @@ -17,15 +20,16 @@ class Poll::Question::Answer < ActiveRecord::Base def self.order_answers(ordered_array) ordered_array.each_with_index do |answer_id, order| - answer = find(answer_id) - answer.update_attribute(:given_order, (order + 1)) - answer.save + find(answer_id).update_attribute(:given_order, (order + 1)) end end def set_order - last_position = Poll::Question::Answer.where(question_id: question_id).maximum("given_order") || 0 - next_position = last_position + 1 - update_attribute(:given_order, next_position) + next_position = self.class.last_position(question_id) + 1 + self.given_order = next_position + end + + def self.last_position(question_id) + where(question_id: question_id).maximum("given_order") || 0 end end diff --git a/spec/factories.rb b/spec/factories.rb index a28471efc..69aa92c62 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -503,8 +503,8 @@ FactoryGirl.define do factory :poll_question_answer, class: 'Poll::Question::Answer' do association :question, factory: :poll_question - sequence(:title) { |n| "Question title #{n}" } - sequence(:description) { |n| "Question description #{n}" } + sequence(:title) { |n| "Answer title #{n}" } + sequence(:description) { |n| "Answer description #{n}" } end factory :poll_booth, class: 'Poll::Booth' do From 34c278db749de473386784a1731e7b803337f80f Mon Sep 17 00:00:00 2001 From: Bertocq Date: Wed, 11 Oct 2017 12:05:20 +0200 Subject: [PATCH 026/211] Small fixes for Poll Question Answer ordering --- app/controllers/polls_controller.rb | 1 + app/models/poll/question/answer.rb | 5 ++--- app/views/polls/show.html.erb | 6 +++--- .../features/admin/poll/questions/answers/answers_spec.rb | 4 ++-- spec/features/polls/answers_spec.rb | 6 +++--- spec/features/polls/polls_spec.rb | 8 ++++---- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index 7f8fc8e4d..18b9add0f 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -15,6 +15,7 @@ class PollsController < ApplicationController def show @questions = @poll.questions.for_render.sort_for_list @token = poll_voter_token(@poll, current_user) + @poll_questions_answers = Poll::Question::Answer.where(question: @poll.questions) @answers_by_question_id = {} poll_answers = ::Poll::Answer.by_question(@poll.question_ids).by_author(current_user.try(:id)) diff --git a/app/models/poll/question/answer.rb b/app/models/poll/question/answer.rb index 7514b85a4..ccbcf1abd 100644 --- a/app/models/poll/question/answer.rb +++ b/app/models/poll/question/answer.rb @@ -25,11 +25,10 @@ class Poll::Question::Answer < ActiveRecord::Base end def set_order - next_position = self.class.last_position(question_id) + 1 - self.given_order = next_position + self.given_order = self.class.last_position(question_id) + 1 end def self.last_position(question_id) - where(question_id: question_id).maximum("given_order") || 0 + where(question_id: question_id).maximum('given_order') || 0 end end diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index d9d871249..177d5e66d 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -79,7 +79,7 @@
- <% @poll.questions.map(&:question_answers).flatten.each do |answer| %> + <% @poll_questions_answers.each do |answer| %>
@@ -128,7 +128,7 @@
<% end %>
- +
@@ -138,4 +138,4 @@
<%= render "comments" %>
- \ No newline at end of file + diff --git a/spec/features/admin/poll/questions/answers/answers_spec.rb b/spec/features/admin/poll/questions/answers/answers_spec.rb index 48c2017f4..8514f2f26 100644 --- a/spec/features/admin/poll/questions/answers/answers_spec.rb +++ b/spec/features/admin/poll/questions/answers/answers_spec.rb @@ -43,8 +43,8 @@ feature 'Answers' do scenario 'Update' do question = create(:poll_question) - answer = create(:poll_question_answer, question: question, title: "Answer title", given_order: 1) - answer2 = create(:poll_question_answer, question: question, title: "Another title", given_order: 2) + answer = create(:poll_question_answer, question: question, title: "Answer title", given_order: 2) + answer2 = create(:poll_question_answer, question: question, title: "Another title", given_order: 1) visit admin_answer_path(answer) diff --git a/spec/features/polls/answers_spec.rb b/spec/features/polls/answers_spec.rb index 368597830..32b5732a0 100644 --- a/spec/features/polls/answers_spec.rb +++ b/spec/features/polls/answers_spec.rb @@ -9,8 +9,8 @@ feature 'Answers' do scenario "Index" do question = create(:poll_question) - answer1 = create(:poll_question_answer, question: question, given_order: 1) - answer2 = create(:poll_question_answer, question: question, given_order: 2) + answer1 = create(:poll_question_answer, question: question, given_order: 2) + answer2 = create(:poll_question_answer, question: question, given_order: 1) visit admin_question_path(question) @@ -56,4 +56,4 @@ feature 'Answers' do true end -end \ No newline at end of file +end diff --git a/spec/features/polls/polls_spec.rb b/spec/features/polls/polls_spec.rb index fc21e1e5f..90deca711 100644 --- a/spec/features/polls/polls_spec.rb +++ b/spec/features/polls/polls_spec.rb @@ -80,8 +80,8 @@ feature 'Polls' do scenario "Question answers appear in the given order" do question = create(:poll_question, poll: poll) - answer1 = create(:poll_question_answer, title: 'First', question: question, given_order: 1) - answer2 = create(:poll_question_answer, title: 'Second', question: question, given_order: 2) + answer1 = create(:poll_question_answer, title: 'First', question: question, given_order: 2) + answer2 = create(:poll_question_answer, title: 'Second', question: question, given_order: 1) visit poll_path(poll) @@ -92,8 +92,8 @@ feature 'Polls' do scenario "More info answers appear in the given order" do question = create(:poll_question, poll: poll) - answer1 = create(:poll_question_answer, title: 'First', question: question, given_order: 1) - answer2 = create(:poll_question_answer, title: 'Second', question: question, given_order: 2) + answer1 = create(:poll_question_answer, title: 'First', question: question, given_order: 2) + answer2 = create(:poll_question_answer, title: 'Second', question: question, given_order: 1) visit poll_path(poll) From 811c348f0f8f4d984ed8f195abe06b2a39b92efb Mon Sep 17 00:00:00 2001 From: decabeza Date: Wed, 11 Oct 2017 19:36:23 +0200 Subject: [PATCH 027/211] hides edit booth button when available filter --- app/views/admin/poll/booths/_booth.html.erb | 3 ++- config/locales/en/admin.yml | 1 + config/locales/es/admin.yml | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/admin/poll/booths/_booth.html.erb b/app/views/admin/poll/booths/_booth.html.erb index 921361c4a..6bef50aae 100644 --- a/app/views/admin/poll/booths/_booth.html.erb +++ b/app/views/admin/poll/booths/_booth.html.erb @@ -10,7 +10,8 @@ <%= link_to t("admin.booths.booth.shifts"), new_admin_booth_shift_path(booth), class: "button hollow" %> - <%= link_to t("admin.actions.edit"), + <% else %> + <%= link_to t("admin.booths.booth.edit"), edit_admin_booth_path(booth), class: "button hollow" %> <% end %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 442c93727..69f388887 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -664,6 +664,7 @@ en: location: "Location" booth: shifts: "Manage shifts" + edit: "Edit booth" officials: edit: destroy: Remove 'Official' status diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 5b6393b1b..dca6c123f 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -666,6 +666,7 @@ es: location: "Ubicación" booth: shifts: "Asignar turnos" + edit: "Editar urna" officials: edit: destroy: Eliminar condición de 'Cargo Público' From 7a58b49851ce79b2032aa9b4e989fc9abe345d85 Mon Sep 17 00:00:00 2001 From: decabeza Date: Wed, 11 Oct 2017 20:14:25 +0200 Subject: [PATCH 028/211] updates specs --- spec/features/admin/poll/booths_spec.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/features/admin/poll/booths_spec.rb b/spec/features/admin/poll/booths_spec.rb index 22b77b397..4eeb81cb6 100644 --- a/spec/features/admin/poll/booths_spec.rb +++ b/spec/features/admin/poll/booths_spec.rb @@ -60,6 +60,7 @@ feature 'Admin booths' do expect(page).to have_content booth_for_current_poll.name expect(page).to have_content booth_for_incoming_poll.name expect(page).to_not have_content booth_for_expired_poll.name + expect(page).to_not have_link "Edit booth" end scenario 'Show' do @@ -91,10 +92,11 @@ feature 'Admin booths' do booth = create(:poll_booth) assignment = create(:poll_booth_assignment, poll: poll, booth: booth) - visit available_admin_booths_path + visit admin_booths_path within("#booth_#{booth.id}") do - click_link "Edit" + expect(page).to_not have_link "Manage shifts" + click_link "Edit booth" end fill_in "poll_booth_name", with: "Next booth" From 3a20a6bc2a9383bfb9804f0629376dcd6dda0376 Mon Sep 17 00:00:00 2001 From: decabeza Date: Wed, 11 Oct 2017 20:16:38 +0200 Subject: [PATCH 029/211] adds margin to read more answer description link --- app/views/polls/show.html.erb | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index 177d5e66d..0a56ba237 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -96,17 +96,19 @@
<%= safe_html_with_links simple_format(answer.description) %>
- - <%= t("polls.show.read_more", answer: answer.title) %> - - - <%= t("polls.show.read_less", answer: answer.title) %> - + <% end %> From cdddddd9723b54ca7c9df9a36ce9394ed6fa5320 Mon Sep 17 00:00:00 2001 From: decabeza Date: Thu, 12 Oct 2017 19:10:12 +0200 Subject: [PATCH 030/211] removes example images --- .../images/custom/example_horizontal.jpg | Bin 129663 -> 0 bytes app/assets/images/custom/example_vertical.jpg | Bin 116481 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 app/assets/images/custom/example_horizontal.jpg delete mode 100644 app/assets/images/custom/example_vertical.jpg diff --git a/app/assets/images/custom/example_horizontal.jpg b/app/assets/images/custom/example_horizontal.jpg deleted file mode 100644 index 634e432ace6aea808d7bded07ef4e0c36593a456..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 129663 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 TfaqF=wG>n@1DYtJsSp3zz}yzF diff --git a/app/assets/images/custom/example_vertical.jpg b/app/assets/images/custom/example_vertical.jpg deleted file mode 100644 index 11743cc18d870045af2ced8d6fc0c9523bd47777..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 116481 zcmagG1z1#F*FHY92+}3p9fFi}2+YvkT~b50D4^2PB_fD)4c&-sz0Zn!-D@4LC$ASkBr@K%)*uiB!V0jflk8+UhSAucXQH%>E4Cvz)K3nwU-x0y2+H|GN`kchaqvzdjxl{>Y$ z)e~DsQQDu4&9v0EmZG#ed`b_LoTaU7Y{9;+RvNy_nijtH7LP1x#l@&ayoJ1>&QL3N zGiqdr?|R_*JQOl~k#vom{P``8fGGEVv&EQVTrd zce+5s-Q;`#_3EQks`XP>LUT z2EXS%cCzq*S~p>m3l*jmm;7TL2?M zxSj^R0%6{{a|itnCOSGMF2-F9TtaM2Ol(3De0)NDd=g?j0^oy3OiV^jNlr#gPtU|e zPtW)8;X^**KOcm97#R1k?%`lz;SgY9V-XPG;Ns#CP!JFh5)e=@kP-tQQU+=|N=iyP zYG!5z24-d+o(DWUf94Bcw}5c(AcGJ`kq~G>h`0zyxCqznpmyN?P!JIQbpgO{L?mPs zR5aiq62gC+xjlgcLPS79L_$GELqyT7H*FC6b@F`=p6y)ztA9);b4%Yxt*tab92Cw5yM$nK~*=~K!5;IkO3vA$w&YTdKGjl z9RB_975sJGn^P<-HW_%~`trY5_}6*3Sn%!s-#iQ8o;e8V|G8<9x|)In1IK?XEE@$_ zE%>g1nmj8Q#HuMZ%DS#iQ?Xa@u&Ii)EY8j<2r55dmXSv*%$dkY)VTEEvANOHf?#SH zUBMl}gY12mQ5kC6zi#MO=eaScTGlsJ6zo#W13=IjE*;s3dE_`TdHqxz7HJmScxJvcL4i!nRPVx%HF65W}loC&Jv@Qzi{ z;f!`N3=x&_u!uFE+Btu5X46q~O_eQXjET+As{hV@r5)N`8|xn$JJBwLBp&qP!T48d zS!#~%(O4@#2@cr`GPtRy3KgpkAM)S?k7v-9T9z#N7HWrB3oEG+7O=_^<&u)-{=G;4 zSODBe;A*W3`Z^cR0%&PmQU(gJWr%7DG7@;_qGJt?hfa?u>Q{ZX^7{txRQQ+E=Ly%BSk4HNe1iBk8jG&FnDTC?Q z-9sI~Dn;7zR!{SuZMRp+M-?0N(Qk( zd43FCDJ(DeOrNf&8(PrBP2p;E1*XO$eo3mt$Y*SyZiwBbkEHHN(t54rviRwh=g=8R z(YU@>GR(}r^i;-5hT-!XLiTjEB%$^5)Y#Y45p--AlN3t73ORy#q_a5R8scjC66vv7 z@zpH%`Y2>nYr6DSRUDt$X}T0*x5u{Fs(vZvf15a!#mAD1E1iRxnJ}zc_mAcMUiR-j zzcCoV|DXffB>`8@yMWokcQJtBRz3gA|NPnM8xv=~(P9a>0|NxW_fabV?qKu*A;88G zQp*G1{_%tGvwu07oEs;Dp^W&J<#Ui8uhbTb0g_FVMr2LuST;itBv>Z@;J#H8J!7x- z82!`eSDJO)vJWi|x^Z8+`l!)i=(E|56MWvqS?H<8z@d~vWST2qwf8CK9wGP+DZ>j0 zCM|b?ZQLoNqN9K3e4y0mxhsYs<1Y4oUAMA}QAN#-TurD`H=^c@tPf+mzMyG6lK*HS zb8N#^zuv8ZwW-L!(U*SwqaUWB8rxzQmXI;{(0a+#C)_HE2Sa3Hf93u18@RWQ#zksa3eZ5OJ2@U)+H0A~BAioOHiROx)L0u(OJ+(0L znaM`%iV@UK#6gG!#4`2Hik-3q@`SIeM~I5Bl$R-#Mk<#KbT7t$8^u4vJp z8*GGj%+HM~jWxS_6aykwgWOiO&-|p0vp9TF`6=mBR267fb5HuC9mf*hlWt$m^^J<0 zC>5zcGtllD`EuvkC&r|{?QrMrTztPYt9Qmvl)&G+6OGrSerY|8erDF6%^Edp-`szA zKXs{X{}KMoIW+X}Z4I2%QfR6#vZRVx}5_W66j#{o@3 z5q82>kwUd38Rn{Nx~bzLlCmE94KSkse-k68kg~B4+KOD?9;H+@(*b>3pn3S9vlj8% zcj>(1G z+ken6!TtpT%DFNUJ$k(QV_BLANq&i(+h{^ef1B)GDKu!KN{=L_gP?%Fb4K6HzE?u* zPHS~QE$P957eN<`&aZb-Bj`5i<@Fm+-`8Gsy{|9)1f9*LDBviauv@zn&n+z_QivZt zf3F%p7^gn1%GTWvx+92cUHB8TcXF?N`mH7x&Ao+H!Q;EZ#+gLy!7k*X`%c~t4%xc` zM1_50{c)%!2tju{3sGll$H06BCe79HnI%GFwpwlayZ-p2t-rjs>RhIhwfgJ@tAFx0 zhD;>4RGD?}Lm=814c;2ZZndqhv7xAR%h=_`SwK$LLF!`r;63yalXF8v&NT$ zbZOs7bC9_48gz8ENu)IL(?UBjv92LqxX`TvT&$dwuL~1qppTM5Z<4N?@FFnV77{H5 z6HL98Apz;14RNvAPoJlXz0;T|`8F%#oM0Sg`ZV=kv(F`yL0I{*yNZfVKCRmUvb{z{15St2w zYJ5gFvyf)n6%tX@jK`oPIr0*IgEe>lQ-~P6Ue_*}V%_b1(RTk+gt?#5TZ{?uHL>@U zvig{B~m1*q%N$#<zWBs4^{Lj<6YEoklTWflHa(2q<)IF=QSu>VEm&=KHW?*&8Jg8 z<_#2s-ge25qdf%U+s{NY7s=~?3DbF+O#W@td|<`^mEFg2ds|C0=OPb*FfiKNKh=eC zHI-PQRg2ytH~G78kvT6BY9E+xdSNN&RC5QFy@@GLUNR2nk!{^G*@A)fEl=Xk#7z5L zC%ntx21Y3eJqD#AD^aJ6K)JC9A0b%}xHXFX%eze3N(fmhPvjg1mWc4_=;;!%I5FA1 zY?PPX5ULPp=k#%`&O8;3q}f@-Gw{-GA)eVQ3o(I}UcRY3yEsAoNqfvwBAJF#Ynj7Y zj}ZI=QOd#Q8vcUhvB>q3a&e#7u?JCXuPnT0jQMFhXA={8C9Ca@N^)KO>L?%Lw>fY2 z{xG?-EL`WQttt}faa_bzZQ|iue}#E)4RZBP_uS*%T=?u0nVp9V(SIiez)7jc0BpH& zlkzOKH^BcdW%vtGGb6?&!6D8q+5{Bu2GRpiQWK7l@cyTk{;j~ez<5n~TJu-PhUYpr zIRT*Egw%jK1^|D>5*h*7i0@DoaVGVX((E{7!@HRaVuD6f?}i^|k44*xph#+GZ#`p3 zdmF|Z!yPW{LsK8u*0Bq7i_RaNbfJr?CYE2n2IYJXA+b@Dj5)5~6Btq4XtE~*;a+8T zy@;+U^YnDCPtJ3Sz@NuCKTB3*=3}ziF0AyROpDUXjv@23H>@!+>K~XXSrn!qpeRK1 zSyJta6t+-`(G3ptYmqDimB|PQrOsuJ2G@$Y90-(XjzookpQ!}6zb2x_cOQZ1SVc3WE|8Y zijIBGt)&M+R&rQ-hvX@g$I0(;Ou-rylSLQPCz075SdD^TG5fRG>iAaQf=Hn>!T|-Fl=yKW$@FCq5Am{D zYlxNGV;r!VIWP6Z2bH@uk=-)}n}oebbMMUE5?;#kCt%6NKixQWIx}g>wX?1FQ}neZ z*pP3O6C8mkXXmps+yH4ALgXL-`~HV={8ygx8wTHu2QoEvAXEF3t^j!O#bY36c?BrI z|HxSYPXdM(QlMilkn1#=hqc+1)*d>b2`Y);hG}xoDbKG9!)=A>vwQ@$xnHkxD~NSBDw~7zcpED5{$nF z*`qXyR2NVx>@o(qwW&W#w9-CnPQmJNm3idLr0_I)SeC1$WceE8KJMw1Q)Xz47Kch) zCjREVg^q;9I~v#51Q>BLFx8|9B_%!Mv4tlGF*Vb17s^}@Gmps0%2jx1I(2vYey)lh z84^nshuCw3(nW55tp9WkN=P@abZemGG~_s>9QP0J z@J|GV`>b0!;ZMp2q$dF10R+06Avdf-Rf6U}{_IbF0#A?I(Pap#0GYpi*lpD0fL}v> z6yQ8q!FTmpYy#B7<<+!hbQe_gO$&%>Gg-Sb@^Hb4)EZB@C&I|o!WWu4N zgW9ar8i7V)VNtT3<@ZJGz|CUzn>ro8ti%fr$d7N+I^4?`!y><+I-I2Aj8plwHb09$ zvW&SQ;a7l{tks^O3t>Bn@pUQG3fT?(8rv2sv~M5=bN0N7ow@JTY;KcrbwI(&E?QAG zm5dev(zVSa_1Z*S?qZ)4XP@1MD$h3*bF{k^*3B9`qy;a=6r*E=4mlF5;6F4_hg9ot z^gaFo@qOd@O{=nSCy{8RN4fYt3%%~xQvD*jI)Ux9(z*goPvR<*19!53(2KhPa-Egu z@9I@-mJ)*Y`}n{5kdZmoIwmx+P&~13B$Ej2p;PyhT}rcmd|9+n_b{tz_>|z$Os)3? zR<1N=IsdS+?Wm^at{4 zv3f?wA?lKga!7fsZ72@qR&QR7r0nt+W$n0#-78{_it^wm0)Mk)kN_dnh7k>Yvg=XI z_=d<9Q{3VmIAXjx{#JI*zAEdpgf%E?p3waJ;_`~M0R^SCjsYQZ0H@QlYKm&>TBo>2 z{w{s)6E$<2e#Su`x7hvKmLVRN_H^lN&vmv6Cudp8v?X5Ee5WX#k)MP%ZK@Q=#MOsa z&_wBp7;r4|QyU^_S3VHZQNWFY#nWq8=DZeMqq0F$AIRhGElxKotb+brA**xwT52DU z!r_pT=c+bXDvbx8F%+!}Xt6Isl>1fv#iN*xJcI%D)fKc+1r_i-Nx6?I)U0f?^uE$n zm*`l&avn+3N}}O;U`o2!-;}YJp972f;<4dn4Rck8J+~|33hTm$XuG-GSYauFV9ER#rMnXbWA_xu;&~FGQ00w}8s0{*e=q&^FFH!PeG~pja0Z-8YmxBLas zd=jUFlZR4a*6Oiy;qs2>N-m++#(C-mR=-KD4wHSnXz_?}1&*z^&rv-GO!`nxWhGh1<_rA(^X4DK9dQbZ-ZPgFY zu-(10l*~l^v2c(yg58oeHBG7JvigH?2`3RIZmM*XQJ6sEygIgZ;>)itlgpNt%DqLk zCU`r|R0(9iHs2HKjERhxJbd2_H7;a=zUy&f+4~M5W6|t%a?WxQAR=|F7C>S|hw(lj z*sF*E(+9~QPHR#KXb2T8im{wPIN==t^ZsuD_{IU}Mb4fDWEh&2mk4JoIO?Ci@p3){{+^n0D+y8NnnrOLh@<;4u^ z=3Z9e;_|z(a1oDD6j`^rIA~57QnUxuol9jPl5NGqCmDmBz(CJ&XP$L#%DE)O!F@Z` zv0$pSqnRE$J2hBWIANz5CI2bSgYNSSANsgEggLP>(LUOX&#Kahhwe)=+6QQ&6A#$6t_nXEE+krM2t}Z5misQzOJs|aCP-4k(1(~py_(JL4jr6J=&5J>$7ZOhi8dy#l6vAxf$Qg+;^Uxyatgv zirwJFx-JV=R?!1oEE8VW3@iUv|Nq;?7LowBD?gSjxsuQoU|h-(VL~TYG`fmj7%s zYROYpY&8!|lno#C9x*olwx&V;yCNd&kb+Cmk%kGCBLeTeR$Am_hcA+o=D#K!k=+QZ z8x1Tv8j0*C#4wDHE^%|WJbzHR4E|(K8i#53R@)X-u3Mg`i07o@-QQbPkCWp;lWwP| zQ15ET-G!BE4Tgzp_2TfK0g)N-J^#8JJchqQ`CrWb-~Q(>)(1`z!TpuIJ}5f}sEO#y1D;6% zA|;a<7mmXLluH5u_w!ecW3fz7kbc3DwNO9D*7$;1@NWIf)hlc?c5v9z{br zybm4LnwaBo()D+^5-As^2#9{M8PNB{rl%TNSSNb?>g*rpi^|5p+Q?hmr0L|J@T@xRVE^i;S3w!SHd30~`A(S1+#|d3jyw*BxkFVEdD4ZjssVTbTT;i1iIo z^|6c{Lw@dAv*;lEUWW1Uo?JZnbMqbCmsLj57^gMYpsJB5VX(Qo3yzg)Z{Jyn4anBb zOaZ?mc2r-`LN^22n06Gq?euQ5`dLzmX5Or=t>)0n>ajBQiu>@)9d`8nK6jzNHKHEl%a zn)>Mb3DV7qEV&xSWYBrn;=+_gTweM!;Q3J1tyVWihKuv)D>uYjUTLbL1Uyt=4VE^C zKAkq=w42EDef~tlw$k;9gCB|HEFCvJ*}T;3ixPKCTk}o5`F=ur<5Uc>VJ;}=-6)Lb zm-afem|#&hWFsjHWR2})=8V1WL7)3XGd;!oR$8?+2~#^^dK^;*M#Q>2+vD=3p5s%6 zu&g25^@)}bW1^2LpSb+<(V}80VX{a35QE*wH>8`Y2S<4 zKBs9t3V*&t<3weQZ^ftkAE6vy!oIC@xL8y|kUlJRbI>V~;a-FC?sFWCVXON>8zwZv zb(ta+%`_Mp`JHR)thVd2{Z=-N^IE$jVOYW>i_*VZ-^z)t5T2d@hz^zL4;kSy8{A7Ly>g_;gE zOA~CNf{{xDN?E+ax$4OCYz8gEM0N02M}xVgnhGACEI*NGZp+DDBq%?!{`WvL-Aj?h zv+$wruW`qq4Ewa&TB_XA$nn`v6S~J+KMkHk2P5J+5AN-Gks3AiXyp$JNsb?Vsrc5) zo#7T45>Y;U2k(Scwy)BYQoFEc%y&+|VcDwNd_U0Ax_YNSJ0|IZzc7g^J+PaMm!G!F zcSq!M^a9iCQsfmjNhe0l;x%Z4TO3ksv|X(OHi^a`+iJAT-Kn(Bb05TtWw7qhEyu{I zsS4#K`c9w6E*bAFREj&*^l2lWMqex)XWce_O((l+w=^VlRBK~y*07JiM;9hymy)u9 zVzPqgI9NxJe7( zE956zSm2-s$UgxJ`lezAFFf4v&F~@_P*7sNVeEjs0$#WHuax6Y`ha-rxa0$XtOQ6Q z7&t&Tg*<={0o+(sB0b8##l=5d9Ng!?=K*PR0kyswL_wR{IWOmd#&~u6LS_;>b6o~3 zkhk2m;J(j(sgfw}OXn|nBY1Z#Bs4r{^hhs6)GH$9Ct1Fpp$YjcU4x97t=!o;GrR0w z{c7s+&|O!PBO+h=$*w9}v+}f(Dz|dCO^NrUqO-hfCeOVg{d`Yj_B~%cSEqQ`VM@}M z0i6S3?f2V7HScNr@miWBn600nM35P|Po!5@qUB-g_KjVPKeX(Pz+@G$?QAy)qnp(w z8I1VR*bYI^{a7qQJsmTAv=+CViw0i*QkX|GiwFArT_m`Fd`I0rgyUyatjeVU^f`;G zAdj{3+>+Mw*&K$xYY;xtVboPd2vV`dPL!4!35T5U*Du}jR~*ps za)oFEO-VJN!lio8OL_!96||;6D5W}`W9Qp!g*!GDuNse=cUG{JmVueT_JfpvTt1cUHr;MI;yn>`H%R~wA-Fn4mXG^Gac%x zM{apHPDcDf(L2%%Pqx}uQTmW` zf54UUc(~6|oSTkJYe}0s?i@hH_zKPj-|;%=9ZQx$MQvFyu$V zKXY3qSnr5bZ50~OU5%B%(wdSOj5oZuO9e!9rZ~Y!dA&8YLB)BYL}g1`#g6YO#)-BQ zY{XwQFexT>xssQ&)$5J&b=1!Ym@Q~7=plX(+>JB*NmHze(BW_aoi(h3kxUu(Jzs!) z$vY4#txCgrLvPN}L@@nEX(MY1rV>nIVfk!#a*eR@qRl_|&0}H4vrz|$EYD&jM2^O0 z{mQ7lc4NLdMR|f?BBFyJ*tA|V(r8DRc4Be!N6)1$S$g2dhj4(eeiG>+m2#&q?jX=Ls5IBPxei^wE*XU#oaZPOXe8O5L6<%-wT- zrjpk;QZY}dkVx8jT(c}f+PGq#t|zpk^qjGNUY~KajoL^u2K9KGANI>3(!`04T(ko} zcgN#Vp*%unqcZgk*ACDQ09N@x3qTJz+5R8IKEPkV^P(H-Apu_J|3i<$ea^q+KOjRM z-pK%@L_pCR?oR*;f`LF4&anbC1RMbUmlFX9{F^!|;6&6V7SuUpS!H15qVl@wVzkAX zKP#fxB~Hh*7IcJsdFxfX2GZn4jHWY7ySp4WwK$=4C0gKfN5x(T#a6zFOTiYVwF1*M zjk#yPf=VE(v}WP!*Y9UPIp+rGAHBydHt96qibiy zUoa!tat?PX#%sBK_gJ`oMX*6jSiCldeYJeHMV)4TjW?A{z1MgObBvmL)){Ahm>x3H z{;2${zFv(RaRS#-V`b-Z(OY{$3qgEu5>kGk8uK)37UnkVhRsyqn=IsgytO{=#p%GG zhdh!>!KMN85TVSXXL&7f73s;IarwjOH32}ziRl*>6D2=!-}YbeD$RM8hwY@8@-xxd z;Dg{0tAcL|Wz7ajy^*PyNZ>dXo^O9zq*!G}(QS=hb z9ZyGCr;{{6AB`}DJ)~!}u7!(M@QVk!JaV8DEhhACM;Y_OoL-(moKi}wI0{out*^MU z%E|yqg4mw3mQo<*M=z8n^WwAmha${-nHd(}CGNd=xIdBTcv$>;Y<*$hikl;6;RnObwf;~*VA2*3qBo02DzDqZ*S6a z!7T!JJq~aqFOQxUv@3&@dXpbu#G67J1NqW|86!iX5*&+|6f!UE7c2~quR(z-+8)Q% z*Ps=?R;Wpszy_uoD;t3cN6kaTzAD6};D!;J?!>)JPu7k8UvDVB2ZWtAa;ad+3O~|% zR-RzQJLNPfqxsog*Ibga!GS72!g2Te{@WEwImzyT6W<<%VYvPz_lq-=9 z12Hr;vY1^LOZ#}N?yXz|hct?1n0%aa`h(|38q}=H*|U#r^nYkrD`-t>^GC3wPAzhg zkxgGpJQd!knEDlMLRMQfQsKMrdqCSS%OZe?Dn%8JJ*~B*>X`Rw%+pj{DMk|QYEg{% zg4(Tc0p$eC-^lnQ^_TOdym*q8fY$;HbnCn`#bBXef;W1o-RGSbLtVY2XOL-%&PMRW zlue~c;Iw`Gw?6$a+up_3`byHPKC9a7lRi8a%8gc`+h)g6OKKDL8=O(IayZLUwf*e| zF@inBc%nsyO1|E%#fj;DgTnj*3UW*ULScqse*Tw2f#*bjxs^X`C%ozDcZCM%gZbO_ z{2B8P#ST=?v-1&$AOK}Qe8Xz~&ZlmxH8=1Da5Df+g9BihYHAi+7CSY>aNoB!d3T%S zD=h7`lONAq%2RgCbWIYBtEXx=OEjm%3w#f};#eST{Af{|;MaHjruIZ|f}^K7aMt%p z;gWkjb;lRe^3@g!!;23o(F5Bszb!-Mh%uM*jlAVXAN(`(9|!I_Wm~j$jy13A*P~tN zI%8#vp6Y&sWi0yX>o+RbCUE=8GGcHaWQFOQ@(Qq-3Kw$P^81bNLV<( zz+|%X;8zihpim#iq2a&$`n{%y4V_`AkZVl+FmL_Cn%BQ{R*+&qW6BZkt-{2%&}{q< zr0EoiDf|~<-(U+k+%xW~3as~(UsN~vy{R*LFz`s?S4}?s=JzEiI$w!R2|1yHj^(^g z%kxMDZ~woOHd^Pvp|ZV!(ud%qOz=*e!1 z5{r=%N-bgKWoCGatkB2tP4tm!ud~K%QxedGSt(4NG=H&A4Zd&IbE&M@J&f^9Hh}NY z$*ZFHd8UBm{ls^$Qy1aV&au?2M6MUY{tiw=KV3_;)65;JhC&FNxo`trPsEq6@*6NS6b zQ#Q+-bj3pUYmjo*Yg`5VE`m=6DCP#A?4%pa>Ft0TV&0RtT4w2|5*j^zVp5xjP zavfZI1<2v3>_2{zCydmASSb)^_DFGO)$3e?Quxu{@U>!Mw?lK^H7}zPa~p%WiffUWQn{|30_R*Dc}9rt0t6l-fe$RkIg&J1Z<}TT{{$Z{0n~Nw014Cw025^v2Q0|n<4@4c)ry`q zqROSVrFjDjNulS)x*T*BBOI_1oUmADPWawNR~AXeTyE|F3g@?v-^m|*R+k#zcwE(7 zm!9abMj!v-J8zl>jo(#%Ngu)ES+4@-3ZZl|sd3vc$(;PjEH8Pt+Ph~sr4nbxP~9I| zgJ1B_1Z$J!#Y{WTxkrj9c2!Ji;)@8X_tHsyL1gVdc0|y`ts@yeURo5`D%7B$Bq*M) zRERjYtJ894nRjZP6REn&w4?1iFoti0 zLaS|OI~i& zliOv`M)Sjn+FOt|h_Z6kMK7@L<0PX=AO^|rvP z^o=`{-n_;GIt!Ot3iN%9LrC}AEtQKz9PXI)M-gomp9y)=rOed~ZV2}au#9>^xmf$XVLyraEXv(#D~V0Bq(UA_B;rUS1h=R`Bd>8D?k?VXOF z>z7BbH&00 z6Mobl@geIll6*8+Rv|7 zkL^tGYW#eI5E=)iCJ@8JMtW|1UKx`ujV_YXHKyutaPO-L^aNu%h>W$4+$-PL;P7LP zw@f*s`RR_>Pdoo7iMBHFT>5MGxnq<)Ss%EQTY_v_Jl73UyuHs(qr+nN#mbv`9Ti27 zKA+7hWUThbzGq@^3@XM7`N?ru(yuaGsIr-xzuMhYGrwH(dLSnwuDyIT4FaSw4*;tL zjOoTE;aSM<22Xg$-EF7&ZBNN}C zCji=zfpiIO%0N%@T&jWwJ%;|9G*1WP)N}gaNB1px1l4fQIXBA zcCvev3%7Hs@Kc4@wM+P|)lB z+K0M?LWs>#XSjKTYhyo+M7~dGm?f?;;(KYnRsqb&p6RkyLqZS=V8J&I?O68JIr14idw6g zZD+jhEZ4mEbGOWPMf?$7b!{VGBZT*uPyM3jvlo`nzOI~(h0O(hcw$bw*wStf6*0Pk=xWT+tDTIxKOyO?@b|#UCh&|s(2L9 z>+ENy)MfhhGV$xu5A)@giY?|6&bu3IgL!IA;0yhyEY1xdPrK}bWl*QH%xjOMP>WJA zQgYLg7y4^pGiT|qT;f#l1kE3n1ZP;XDqT6wq1Nj?lT4{#v3S<=G#(m9k=p?=dUUKE zOk7Chb5ZhvG?VXG9;;}QwA{NSp~|5`txj=-8t=YngEQ}&Gd%PDigwSrg^}b?-La6) z26Sqg(TMfqQOwNt*mjpKzKCEa9n?oZaHsAxs=weUFc5_|DDNVyZ1|tM3D0Wdd<`^fgHJ zQmVXRU;dJb!CZacp((*|O_Fi0Rn6p#Z8g+idf&3{{?{MoC5p7IRUWIb0VS;?Vp$3u zG(V}c$v$_HWyu2RxkoypL%wzEXS7fQ3_82zPQEE`C!{JJ8+1+Uuo6$AaLIfjBmJ6c zW40ollJ_lNV3t`bOBX5})m6Mz>-0XBK9&ML=ubpAA@vJNrQm}}wSW51;kKr#wDwmF z{bRlW5pnxo$PJtD4?}sACft&fzpeCtun$07z6q}IYbgBgcZa|G0hDHM%=9k2%mSD` z3ee<}3q~^H$|T^IRdF1vZJ*$^FF3sWbD&##K<8pC+2tBU_=(CVmkQ?hd?{xm%@`~4 zHN8LiK6YR5;_-!X?`lJ`j>CnQcUUy}nqJit$3ZK(4a4YB551lR5N>H1#$|QrhnlXZ z+nAom&I0+lC>kme*y!dPQm^1CnNQhrb^rwuV%~N! z`X$$R*-PFxtB;BIx)!Nwa#p(>iAD1 z=>{&PQ|pzz&10yzrQ)Jl34l zQ$jjZxr#S#-{-A(OyU!fz!nn|o7|A5=YY?Zx{^fX+!n#{N;Sd$UNFYOhR*psvADwR2aKPR8mAyw2RX8zW zy8r2xZN#RGaqh1lz43eCc_W)caRqA+LGvV&Uk+-XJP-ExIzD0?kIh94?Y(|d=plKA z($f_X@l#;Q(W1-^=EHMv{wf&L!%F6B=PN{@mgK68u|+y+HGr;Nx~?YPl1q-yU&}w^ zkEd&T_*14LlRbr~%%jZ3P7O7h#u;DqMo?hwfJ> zOk|jlSl3eQJ-7xDI9!9Y9tpK4eWTZ@y?j`A!RwS+lBd~&c0h}Kz}&W7{pi4%iOe;V zSp0~1o7ZiKXUd(~l1p|Ypo`a@Zfe{KBf{^VsfQC-(O)=E{O!vtg|#V9O4J5DUu8z{ zHK;b;-sR2}--$`PXlH?lku*xJi-dQ4J$89r^tPX!ecafP;I7{t?@dQmKc93T5uV2b z!lf`{ zs_iAl9^p_lgHzV5|LkdFQOLT_ zAgWa4G%4RlrjL_TjpSmbVX=t3?bJ!#Ybw1zDz}PxhKj`T^C(6NcS(280yws0%WKW@ zY7E|qL~@AOv?KKwuB$5`gl&0Hx$o0vrcw=t^%{aTiwwe$4V2G&vJd?tLKHUCJVYL+ z@jl1P<1^FvVJ121Jde#JF_m>7x4g7nB8I*%M5T&_V2L=wyg+Zdw)9cQHd;gvxA<#X z4>e{;-I%M|aPQbc2e*Qwl0o#t{)4iL2RzyB-9{CU9iHA=sd9}lzkd2Lu+ z9P!Md(4kN`p!ocVc^YQ0IQ%5dJ@Ks}J^&nxHE(0mpV;>M{SSDJUxGk=_y%;slS;U$ z!}|#SrQrXm#Qp!Jn?Nn@)>iK_=X|)K+;6-7m?hx7_wY~%r{Nua#Zwq&9QF>Wpf}?9UB*DuSGz5^>zkx zMOr*f_UsQkNL%_VQVk>XjLD>RC<0SN1p9HyG+Z5~Jx=VkrfjX#d6vtY=NTH6h)_6< zBifUbUojM{iJx&gQH?;ZuuqHlRg5glJ#rJ}wB~5!L^k?=uO>{~a5|+)8VU z7mP;VBPhgrm*on46Yx41MRLKRpC-s4^(@xarv`}*?mzWXm@c`r!Q)KCc(4|2w!D!<`U2=lIql)51|%qsVkRKSh4`y+Pe*bJWz@Ewi~5jryjb&Mv2|EMhPG!s z$>g5#p5{L7r5gRc`aA48!JE&T5+j|8^V+ufJcdaZeXfi}Ccj}L_p0l5ej4icQisri zabnH0mgbGTG}ep8_KqVs{a7C>y3b|pP@b>6<(C03tCut;ChQ@T{_Ki1^5dR4}H&5NpUNlzUb7 zzAo_+nJeAy+aFD&Pn6h;b4b$c^Dy7^_hjh?i@!>L-u9*PneZ6T1J_O>y=f%8B#ZqA z-=9VLt|xy6n?m!cFR915@`bqGyrjd2Xy}HnqBdfCuV`o&*BHDPd!@&Fq7%L{`r}eA zl2cr-o97;*1v~UKv3}eN!h0}C6HhY*5hQYj9NR0FOfeS5FK2vjR30dC0PMK@=4}?Z zMZv@Jt!3SYR3He$VI|@}l`^1{2Ox)l9z<{gVBr9_1iZ6++t&-Hjc)4le-Tc9N9Al3 z;O*TT(LnU4hWicxsb&KOG*x&T(9JdAIqsnfxCJ)iGH|@3fai^Zk`jHmRVrL6vF@~d z&XA^Dijh~J5?J#5hnCEE59xwS(_wLl<`E-JpJ3S|=LVU|c9Pw*I+JO`Rm(w62+sp+ z#Bp-shKr5t#!mS=RWA8-3Z#ug=S->tG6`Jq7=~xVYxjP(r2@qxZ`39v3a%Y!O z-B)%`B2;?NHOQyLj%P)wsk!A7I|qF+P*aas_twL6U$h9E{iffl8Q=8{LM63v4JwRm zmSa|Pg%JJ9t7$^&c@wD`JLu+bMAK=dI*tFWeVlUHam+VwTi_da*4G8!5SfjAgTD6I zpwO>aPo}kWvOT~u%k3!=bViX-H0RRCx(YUG2q#y)2@66O`QjDrnoB#L%&NW1+li}I zkmY^0tX^_LexV1obkk~GcswUj9vhVl!X@A6o@n$0#6C|Q*OtrkeSC5ck*;2+)?J2>$i_ul6nF>G!povQed?jAMN-EJdI7QWVirp-3S#a6MH zU{P^JXinU*mvp^+RY=#Rp4CNgDjeE zyM(RO-K*tYcZ3c3)O=twcG-SO@qH_(KT>L42W7*BVj=K94qhhQCYU!b-v5r!zhAe$ zdGiP`z&}LqKNgG!fbAPN9t*clz~}+0IPO&taPa2D4fXq*K4SeHf^RVOtu^PsGu~H# zMZ-(ttT)B17{aNA?t!&8ixT<}litTh5Juxc4;QU9v7}(FwKs*@!+1MsAM~Pzg{R5} zZLYP%=!(l(E@N>i}q4`*<|JZ^XUVm{I>#-?9`+UI55T^9SY1XfWiMQmKJ>-bufvVB!*{m|J2*`sh3Zq+`ncsS5teI z?M~NJJZG2)@bT1uU4^UN|7MYSJc1o z8cw^oU7N@&zk%AI9|xhgWc~boj}XkHcb`&z{UgtO(6$N(@=JpU;-Sx{qRn~8=FZ)+ z?=(uKOB;MGgN*D=U-DScyN>$Zv$8fT#3u-ck@-y--ML)mgH?TKNY&LJ!|dKat!l>5 za5JXQc5X5mwxzxA>k-?$7QZ0g(iKuRjyWJE_!do_6S0A>ReQTsIi3Kl7vo^cXVPGg zR^o0sD5ok?9D~{=a<6)7wyUPLYsOi7>{Mw9+w|TMIl(7vl$?bdhbe;dZ2UE%YK78OKw-YEoaSb zt7z7;_`DsSOMqq5>JgT|Q^NV^l!c{z!B}6a=I$OyCVa<#O5uPSX!V#)@7=P(sgkC} zW9W)O-0$t#;5e(zjm>S}V?4{(_&=T_9A6k%xLr$uw)^ zlzWgj5bX8tr_DRrV&2`U6Yc!iEZpKJ`CKoX59t}#Wqg1 z$#3-39C_)ly=I0PuvWTyN6=uvKK-!SqPR@xF%1!?*ju^i;h&uUSvvVS54F9X7;Tl{ z8|^pd?&wgUU32?5yjAdt9L4<>56(0$l^$-f{HgY9Q0ViaFNG5s9#JX8>TNEj_mxht z8^+HC!?#L+BXs@ZMH8AL|7yqmM5sm*qGlom@t2R`3*3dszl^l z>#0%={Li8aGx#^(^9LZKXj@nji@t2smp8Ej{>K3jUE$RlAnxA$I|MvRP^P5#ArVvl`>~ab=qCV{mLi)FW!k@L`*=T`3tpIgtpg0gmEc zm(>I*Zi*z`D@`8-kDUv2@ha2QDNk~w!h}9-_yxSJ;5gdrbK6yA6K#@7KCc*LCDFBA zuvV4hws>Zb;59idPg0KV28*6hFB_(OIrkB!{N_B)QcByq2kEm&Es(r^P*FW9u$cU& zn1ScT8QB%Q)2e%~p=D?5d}9l7sJt1cYrSZ(74rRkO49Sib(dZK2cl2LGA;_DHzdq_ zNIPK9$xDqmxeE5IkbM3>vfeVP%I^CD1rb3)K%~1Hq&ua%^U&Shp@1}pZlt@LLr6%c zGzc8JBn70)`=IadfA1Lg10Q&53>agtJ=a`w&W*Hp0txKMIIH1dvf8ozv8I&&B}719ONEPZ9+4IKToBOn4K#EW=ON`|+i3SC+h7O+Uck zdgtZ%n|#fBw=he>Y69kS0%wo{n)_kUw+TN`gsF?F1f?W&F69p6*L=HB=KPrp*T(jH zouRr|@I}Xb0T+Yn$*_V!%}rtyd6TN2W-t|4?2BJ4u|USj9(1cV#yw~9&TWN-oBlPT z)tYTDQ#Fwvi2riFdG|9JD_7}KfrmQld+^tEKT?808uUWIA~!pIOx?;hUv4jCm6XNO zHyNhq!WVPk`vL-G8V(~M+3zXXbKek$Up0xt=>2(xKXgeVF8|}BN(@XoEW;|#k+8X4 z0?CKL&bkh{S=aZh`8-DvyR4c}=BuU?1XSMn7QNL3x>Se3_P~BXz_sfA4Zyh1K_-8r zasFF@e+3^&jn5n7zoq?8kouRF0{AB2X}}q717PHT<5J51gUJ7rn*9sWd3N9ar}6l2 z0n`57L!YmIeqPwm($#0E40}3qCbZL>KZe*sem(y*a>3lSK-H~%dNzH|A*(-p`vIA$ zWv%(^PiMHs1+4=a&ppf=6@+=4c8z)sPI|`vUpA%=)x-xi=^2k&6x3{sQr}aAm;xZ<B;S{rbg#Hgj#0wYR1484cZbsCfjTe z${3okHw&cW&uo6T;38*iSZ)f)0JEM`X`=U?6MT9>=UCn@ule)LLHdrz3+eLCm>np?QYL3sF)o3R-p(13+=<UtCtiFXSzkiNr%Uc z(UMaVCnLN7SM6TO*D541q;_xlP~JH6%2-veEI-rb&BqD#Yx^l2ZCiH69mDCBfZnI6 zn1W!sKQNs9w=CKbj6V{BO~1)(e)PDUx%KW1Q;EL!jQu?`*EZBS)&e>|!?-Lft8w-@ zm#@0lHH@-aFAgKeg(?sXc-j!j{w8XA8D5=@X%Oksw)BE3knLTJgx*hnn^0M|^!|o6 zo2_;$N~Ed#ljggF(N@EZF0#jlhi3U58Y)ZVUaN5HKQP6#*>ZBueOeOSC2bbQzw2Bw z@Eio#bmD&4W0TJ%&vx+7ITH?<{03;WG7P8?p{+zJQN`=SsdPqOYqO<@d=Daq9vkTLyBAZ-ngyz_&~{jZEL0vT-AM0+4uYL2Ok zy=zrYjR#9U9BviVC6Shx2h5*bqLgBq#}pZQ$KX=WV)UCPF2*8E#$!yD%_6UuM!KU& z$~)K@-pS=ob=L}ZE^T*wn9MLwWWkaihWl+w60ihC>%Ux3Bpj|vS-&`E9gZQsJKJ=; z=qz~UCmroEVu$w{=jCCMkk>nD<0S3)_0-hPuK?9z@xAqQ!gusdls^Z|zWy(n1E0>N?CSeL(h`wMhmeNT*y-sFbI@ zT?{`ilq9*`mSIlXu%I*AuUXA$Sp)|X5pZ4K2>dN$6D(7X6cPE643h%u&$}`Z`t&T7 z_}jH6MAC`?y7a$J82|wP6`KM=^}pm)-2W7)fY<_fi|*ON_qWIXzo(y9H?UnlSC{A6 z>oauzJI4V&2~2wa8}0yH_1|d{;Lir?f_mD`Z?g$v0pv~{ZF<^W1(+iN#>%6RfxhTb zb|<)0Z-Efc*oc`rOS|ZHi=8^`m<2E*HWI=rC-y5seJ+xn8)AVloZ;bh?HE#G=_U&* zd0%hjPS*lO$+mORAuYjkxfw;t%Ygz7fvq!?z?`JK`dwV7#~+{0FdpEJJJ7#{hMklC zUQ0^!dP43g!o4Od=8xE9`3N@9FNpOC|v~j(zZtWB(Z?xMZ18vor=A7O+ z@Y23>?)U>^PI2jw$>1Pg8ZH>qL?D37&^0SYLBiI&mR~3}c5CXtb($5>rVd7mWr8p` z8E+!oH{M_rWcp$>4~D4BdE+w(`6TTG2`=OimJtD(E$k656g8@92Yf+^| z`5Xqytd$S&cwVpHd3AN+QEIqo=s?iv7-ZysQ0Cyg+LX{52{DIF-Mc&1IQ@M#C04*c zSUnfF^65zPe*R`|s;)bM4G+H$Lz`o&Y|y>)6ACyhy4m%k5NpvN7=I~8tBUL(=R3M@ z>r@M?6?)#`9F)!-LnrGt5ShWj-V8^UZZ>Up7I-LpH9w1$OI!U-Mmj46 zD!9+4YE0AZv~CvMzziYu1>3PjD4*NvHspHMZ@Gg5Q)tYt%j(ol%Tuc9+5M&$o zaH6@XD4|U$rN~jILSJRqt%=Km@J5Fvmhae2Xp@xRUenXi5pe*+PK zz}^kSu>H?^@=v$6h8Ap98yJpTa88@K^H4NRo|Ph^D(G{3L^FX07HU;#@S zFw_368h;@=`n$jITy+w-Q8#mHd4Lyh+%3$eW}6LzDo4Cdi*z~VqlZ`bT}n9}kB~MB zw?2L|;eN&OM%|yYBXFjc<lEsx-f|bR2g8FdgWf;axMjsZ6ffRwW0#xCbqJUV|&G zM?%L*uvMnECkia-Rklr4Yotq4Xrxxhj@-+GmRH`_b4g%h6@Tpm1xq6{yuEg=-6egX z>&ZDRJR~w;l#)(P8k2g(CGpGF_6QFAerv&Xr@O{EzO=~ujCnNvou@a5JO&;dHlvfC zUHqe%QF{#BCw)f?m(?==u7S%!a$kGoBc?ON1^mua^}FOSu8W+Xf;&BR(HG63LvxKY z7D#CWWr&&Q`G+@}D$WDnB!8XF8%SDtt5G=HzD0(us^mDs=G3(`eup@M2$OV0?6z{e zQwH;b+v!?U0}!d|Y2f1&9=P%?QN;yut{yvnBGqtCWMr4Fz>UM6t)+&xs$!Ofso+rHo2bAHzL7WNN6iw8Fdl*034A`sd zxYS`8wqu}8!#+ZLI$c*vy|aW|AsxN`lL!+Dx?&dvNm+#wL4~n7QQeThcPl@pQ(<%G zRqF%^6Ryns<=BxxYoy9_M6^xnhGzVM4Ez~>KgCrs*<^v6)%^bbvk3~ER*mMY-CC!% z0d-i@p@$za;WDjHquD|ORYz~i!ap>~)`1bCkGToM`GP_BoU>~mOBAV!_qBV)RqfYQ zh9iv>CWl5%&zoc(wn`dc*eJRfnmR}9TFJGC#BhPU+}QjI8y0eFU)R~vKBAFs3SvrB zv@^8k$_>TS4hS|lHbM#A_x`CZ^kC$J6%?U4y|zN`Z~sK_3)V#M`K)7|;nK#J0YrTT>*i%3?c zt1Wtl#Lq}@Crg0Ie*Wm};rALzgKAZOdBvt_oU*NCBOEq{Tcw+-YXzri2}(8&RXVK? z7HUHarC6Y}-n_=3K3`k7St2agO}lW-#X2;6Fn6FnE_;C1Xhf(Ve}`P`s&i5!x_a_+ z!poGt6z+d}|Nn;vSN=Qk{#!Ku)d^C-;`WRp{v*tRw*J2YLiv9;{wAUURf+A{bMlu8 z_%{qI`^%jJB?U0`M*@MPMZhFmR`*#M-bl(|Iz7XvFQ)3%_$D`oLSx18XtnO(THMy1 zCk%CC=6c5g|PN1=Kvcy?Sfyo?gHL zfh-MGX5~zI*20~Z%#kd;Fk$&?A$~{~v54)GE%OQk^_n(KYg74j4JR{S^7&2}Jh9cB zMzR|rvt#bf0?n756*E^43+P}v=afQ3=KMol6h;jCg7-E?~u|7$k3^X>P2X7&Zrv)NMM3SD72_vr91Y>Y2N z7|o3R`BQe=tw>{7>tMtQvD9hH#7Mcxw+$8+4l7qZk|?7pu{@y5J6D7@cZ9-8t#~P{ zrK%JPLW}_;&Dr5Uw|dT%sA{f1Z5`?Uq=X;lUao;1Na4WgBIYw_@Nn*1(Qsqkys-Qr zQeDfw9B55&M4kn(25wmGPvNZiIRt-T2KAh45noLs;zy|k!b>+7dT2UaABRonrwzT~byHyM+ys($UzqVq87>*iJoeWwcG53jwIh{%4RAVVI zwjjAr!&qA4#diFKYIE4~D7US4@1JocKt)E^ku zkzuEV6*V>cG56*iR?b|${5;fX8UAL_&+bzMmss22Jeb z{xQki{rX5VOhv8R?rG`4RDNc!rLYK5TO(U6sl>P{90QNBMm7}(>BS1cspKoUj~-QH zjLE|=a4t*1%OG#oUaR9l|6!b>D3NH1mI@b$@k!Zx*TTWXk)$U>WFl#fpP@I+wH=|K zonKWbVNbG*ZkzTDLfYzLBpYZ%2^dg+ifZCxD4TCq2ByE`Ir)y~f*#q{qy$gJFE=7KZp8pWie zba@%lHKRD%&p%chi-WB)@zrw2`Sv6X2V}-M5@h+M?pEEmEy%?c;C-&U0W_ke zvn*aGoR)gBwg(^q8BGPknzA;U%z(VmjM&Rf!jIuvOa^&;C*)R5Grw_~TYjlr2+xo# znAALe4L!*T>@s)T7^y6Hphy)W88?gwmY@O>&4Fm0XO>YF=s0lQ-6s}pu{}~>HQr9Jip5IU!(Nw<_9QB*}r1)=g#TB3(qnf zSzTBOzBtv%QuQ0OoxLqyt{3X9Cs2AMID4{oL}8@RA`Z;Z^i^h=zCrKsb_sM!k2s`{ zDXGZ0e_-Bc3l+?6K|;?=xHmRYy6P+4etu5Gj+aU)yiv@*{*ANYGf(-8i|>a)?KjQx zHPy%QM?EcOsu1bPQe>mAF!(IBF1b9kcFf*-ZE3^<$7S2RYEu!dTg#d@C@BS7E%=$l zFOjtBAlN4YbPyvbQ*mnP9~hk%{MhLZ`D3|Y!LJ9=^G#+4FTm(b_wc21`cc-VCAGQ@ zY#kq_jr?Po#vjCAd~;lOz%npYzvz2O1NON8WZAnByI@XpwQf*s~a~1WEzEje`HI3p= z80P%`O$5WiECf@Js59eMhTb$vtd*QQrV5!;D^z{Pn%dFgNk|KjYl!CRYX;Qp>(;vi zBgw*GJ>S%W#aM`p4MvZ-4?o*$${YkzS%n`xPp=k|Z%Fd%iXJs729aO0ZmYtPoo4Zn z9AfQHzqGH(!>;^Z5DcD0@25XO@}qn>u#q?ch{iT;iCiu?y2-^{!xW+*Z>7GEW>m zM<%@xQdxC{vACkxcfb_!9tf6GXk-{8o_gdg?pZHGow&1BF_Us9M0;BdeZBQG0xruK zo+_*$e~o^kIg2r-A(R*Ku1;{4Lls$$1Ua}k>ryJ;f=|&IM8H+(Y-q*V#3B1r?W8%! zUPA$Q(|b^5-&>Gbha&nmjTdo%%h(rVbIBJMuv|qBD1yUWTXo-URW(9-Qfc7LL$!DG zPivRSUF+^g<)*ek0z9=5t7PyWJgOdOHgs2)OEb2p7!*>Rdk{i+&awW$q<(amwq`Su z(j)y)-txLU-JXaDgIcE%y@5*6)|0^-`j`LG2*55wi@}&;vL+ae!O`)Ubd&D zqyBh(LY*^v-&C}g5(z4-vQPgZBLL0(|6C7=3IqIROs0)aKijej7;*$D9pf2W@P+-$?F7gZks2Se44#7-?e%rSSDyVj>&E-~+uc27FwR>#3wwT9VZ#-Ilf zki~iNAmFI!}|Rlcrz%BZv&_q5dz-bB_HB$;TJr-UWwZOI1N*|ZI(8@&u4;d#*; z<}WiHQsTOZnUmjetl_SY%3#T&me)TVOr-ZcTJ}lzB~DY5?bR&m`_&nGdxqu>#pTR% z2oiYvM`be(Yc7cbMK3vmWD6848-r!%a50-&Fu@2EbnFq@e1ZX{i!2;1dJl$?M2Qn+PM3Qf5%V|kw^TrMT7Y4_?S`yFINuMs|+3)^@C z0@j)Kz*%f_6e>2x?KCw5|b=`D~=52M3P_oquJar6?3W~ zy7OpPmg;xpLd}t20ve)u_cw)Jfx9eMT12xxW{(7v+a1{(!54wk+&Gr=b3x!bu3oCY$p_OE?NbKLUHxI_Jp3RIJ`enn z5e1CK{o1Rta$ejg9d?QHENu_ZNRL;ZX$8a{#8xBG=e;Vk>uUFf?OUZq%4AtLo` z8!!AC{a<=Nr}jQeEST+0H7xFOjZ5uA%W5fTx?WE0SM)w zZ$M>zrlI~*bo@2%0eI{`b){2b(YxpD&(G{rf>daKU|vTnjVzCMHQVN*wBs6VyAW1s z`(thOTj<~0vL%FLxOsztnu zPG{y`aX?gA<CK35g3_eo?bii4@?5njX3xT zyLbZ(wB>7r{9x>wO}!8|5FLdps$=E+n$$4JZ9lPSNHI2zcz$}(mVcdHp(+a< z#Vp~bK|p3Zaqj)~=D@=kI}(cIZ?=#t@$=+UR3Y>Dl9}TYo!Lc>nExBr(Mwe!v9E#y1<;BH7af&yDnb-oohaJQ%*Gr17)^LDTbmi7>_eWh=$o;T5;Z)u z`1li$=^Fs;?y=QJ& zoigJAzx~yemdLLI;)YRyGdPQAA{}oculZsetUdo+u@wxM_+lBGyeZKA zrWpIsPPIg2lokv*%~{m5`!=~2KBvU0;vFQC8^w*3u~B4ykcTa#XDXYgWfdoLI@I0z2B76XAhoCUa9{pp54c@jlHaZ$7}?FGwm$$#Q^yxz z;HVrUU=lpqJf>wvkfXLN>eJ|W*koH@Oo&y1? zC1^m#*F!U+@m{F4Krt5(i*T5=(rGbCo*%N|;{!rxgy%Ie%Jp!0N8m(g10K#-evd{p zfzG6eykR^JF$NiS2 z#G=uG?+wnY>#|s+@L23*_{ka5y!pq*6eI@(%$_gUdmjQ0q%=v0_{)*W#;_k4C8W5x zgk+P3BB%`pmDlv8Gb5Ug{o!Tm0$caSG>Ai{#@vM^FQ64)_09^L0@d7S!a}<2U01Yb z1l0&5Foad!Swq}>vRJOY9vCLmlUr-lMlh(fK;~^2`S*MaB8*U`^5dEIm!ae`?l}o2n zfl|rg3=%oVu7R4h^UaeK(I@Ka8TJ`{eB+N4BeoAy3C-6|cMJ%nKDO-d7)*0!B@=MS z=bZ@JvjmrPN@vC(O>S+s1iS`WVWlSKJIIxj(H>$vSYBH#j^M-ek^bSI`nuZZTBDgH zAI1podGSwb*$8e~)Mz9@Aj=zZgj-u+n0OuDdwcO+#J2Bq@I;8SQB&3`cX{kLdWaqv=w? zF@#7Fczk`WQLkkRn&B$Cu5vRwt0hI?roM|Dx)v!l#$#I~JQ4KJj z%9ivM`5v@bRaWNE(okJBZTbX%ru9UQ(!OWNIrPV1+hoXZ(L|RGI365XYuEM1VFq>P z#BywNBn%X#S-VKKy*bm=mxz4dvZJEM$HO>X|C{zAklgLaYMa13l2gini=NR&lu<`^ z0`}o2VZj^Y)RUb0jODsz1?4|5a>RGL?0kJ``i4~Nkc?=&f_2J>&~r4OHQDC*Wn1-; z6Af9vm@n~ssd}%a#u%b5Nj^L>5FTm#foYC=GC{kw3+UBPqBJud%!)z$tu8b(F5SiK zra7@qdy;0EGTawD~JZWO@e&)JULm{yjaY5twWM zIavVsgr&0wWKbzZO~7!Y6zJAvfebFdx+;WdmTeZw+PZC2&M#B;D*6fWO8~A)0Kd(i zVs9c10}1X6OtEo$7)aDlteK0|VDMW!9Zj9=h4}vN<(qf&nWS&agWDCw=8EdeKD#hF z+QjeUOA$JY=b4I{!__*Kyf}2n#+iRm7#D!yahg=cCWX2P!zg zt>T8rv8-0dZ_C3!5O;;i9?HyFRJWpp`dYIfhQ^~BD|B51L2dA$tS@}&1w(w|Y-=rf zN}zUgU@(Cn)79M0B{uOKFKnKJ`8UXQ$l#2Qjv#^3uluONRt^VV4ZZU%pAt@p0|_hK zhQ^ss3YW-NRctZG#{CQYtfeOgsHX}KH8QRWuOxXlW=T(>c``E>l!%#gJ~NEo+w26! zFs!Z0JEAd8RB+DHBL0g{x}?fY;JpoFnDQ#cMqS;yMESffH}{yVY(F5|4xK%Vu$JL2)^PS6TxvF;?{U2)iT8Wnki+f7lQ{ zC5B}pOCFj!!qtp@2HUT!Xbc?cRd^>4$GXf!^sJ*U(h6h1ZE3OT`ibP>8dzyW1{TjF zxpl1)c+FVud+Rd@ai-}b!x0wj7zq`uC>`v%n8=LvL+&d_gv$5Z6#>y59-Yj0FuovW zMZF~Jxf#nYL8$3RcYBA3Zx|27earFHRPrYM5h&_0o1FKyA7{+IaK)xG4MIMs4@XiD zKcG5qrz!37>8us|Dc7-% z_D^4t`;z!-!~8un(@PYigd4UUx_I0=wd!aD3QZLouQ^fn=2dJ@l=l=j7J z3$J5VH1a0TM^>-2(F*5dRqq8y$5G@_Naw}p7r7Wt65yveDSyj|MyM-OLiw-~1;sR* zcNW3B-x6j*yHyt1X!Fq~^YJrYYGcSjQuP%V4~VtzwoJ>ktEb7&3BW@{3zaz~_HV{eA;$qV&XN^D|3PYyZ zpQ2)#YZ8iz(=McEWHe)#aiuvc(ErJ zN-iF9nB?u43vW`tg6%;QReY4%=YL?>`miHa1-1#{h*1Q;9#$YYWi{(*5qwsruNY~#OT4-A0-lntW-n795~s3C$RNW*j2wOz@WEmxT=w-s;N96w04 za|04g6p@eKVMk?TrvdWEtk7EnBI&N4Xiv1bzQ=D>d`$Uw9!qnYpq4X=9CCZCSG!j( zSZF$|>7MjhFaxIxlp|siMGp)?^$E5DwU5n>CqciH){iB%^#D`g#i%;JXewd z2~ADpa@(S=W~^k&QbY`l$3AW#h0~Fh3KI!(YWd|aB_oVX)k)?$;72$^-L-Vu3zKh%gO-t+E|E&vKpUWH75U|x8sSd2xGxRkk(@G?1KOw~B6 zxu+F`qEC%8tbF=$qV4>v*sZVA56OE(=(DNnU80E;qKe5h?A6>%s>ZrXi``!Rillmb z5-ZfP&$VpbiFIp<$vP1K+G7q>gRS1x7tq!kf|!Cko6Yt#($Sh)^HM)++s`Ywc=9!U zchH+;%hGLQxzG`vuhY%i+p1Nryq4&nVpf7%9 zva?x|E%F82hbn|+L4zclEf8yOj6rwKdG^7@IE`_Et4U@Qy8Kvy-q32 zr7YJp-s)9Rnaus^uz;8%zEqT9;5u*vs{6SswT*O1%+f7|0UGZZ1*0&YvCur4(ot9pt+`s-|#)RYVyjzX`h!XpG` zfn}lX%cF1=e^K0`ju~7dY~3Iy*R{s`vPOLUp2UidFWdzCXVtC?UTWLx9|UO4aKDdJ zwR|=wX7JS0o!lofAuh2mH_f1KJk4oS3>vJRuOKys)K^_>pOY2YNU23!xTQ>_d!>fb zJT@)1lFgp;X|lOd_5kk6n*Mt6pQZ^Ixv%bnX*@mY8xCH-^cNm)RU-^{;EBqDkl=sG zSoDeq+gA#y8l#JGd^1%|0WUwPBMIt#`tt!QLC_~x|?5-Y#GMHvhm8Diw>sWQP* zTK#Bm>6S00HrQxk9>d>A8UjTful7Q*HJ#(OXWxXro@2W>E{GJQ!1zp{1QJFO|p5 zfRWUq?=6G)k|dW;jFmxc?24m{5|`$yX#Fvhxj3B772`svV!A;$Rm+Vo<)-dcpq9x_ zou*k^>=c)@o~iF^Z3z7#9xj^$K5qms+`)(fHyY87;umRJcCn1h$DK#-2s~-;ZLN%q z8BHi~&6Kg!4;T@=tNjlB>w2eCpbrXX%QkI$=6QQ2s?-@h*KvnO)0r9Hom1_5y@Tej zJhk$pQ7ESwy{32nz|hCm7shb-R!`=>fe9F?uh(oUh<+@zcSx>$WW6HRiC$EQ%Y5i* z5BcS)wjmLBTUWurXx92N*x^+NhdBCvjpqf&9~d(H`%0;cU!~0w81NNR>;k!)KC;IL zb)j7$S=GLIKEbmMbR+#Se_(u_iSJJ4ag(B8okw-G27^RBzywRM_w-TZnu?VL|xU^5iv|d z?G0(EI^-t3K|4iSjgYe%81GTaZT*Bt*0p}GfE)C^q%pQSl}3jQh}07nwUIZ>@-H|n zvx@9cKGxK6Cm;VoH;L(01zO=>A zwqTHy;w9ltnMtvl>jw3b%X}LYG*oW_-XzoMW`uM!ZfJBcX_a-@RdstS1kRpzChKaG z{T5a($5wM>4O=DT{Doybv}Q50tg_uB#u}>(d-}Ufo*k_c+0t!ry@cw6@5q9=87WnZ zwPSuub_ewjXDU8#9mIv3r;#J$Y~B}uH}_16bWWRiWQC@_>utnc)hQ+sHivP~gs}sm zP~?`sv)ciNG*6nuJ!*Q0$4GmIvKI&)-qHV0}Yvnp+DMy`cD1 z)r|KHn{5yDSBA3&@3ly#b|@z-qnGRJJ3atd!EPv7t}a>z_r>? z3z6A(gA{IxHRs>QmiQV&Scl^hm$L(j+RMc zAJ(sJUxv)YJRxp1Kf+@AOr6anCnFw`C5Ea?Ln*IZyRQNR8}1%|dRHJgU*TxKqoQ>A8$&gPG00hjWIi*s>*dTyG%`<)ayJ^h7Z(^TG}{(B{) z@ZWWVVNgz0?_ki&Gd_L?{pb?gyv<5pEd#<)@-vXiU@CIKshPTpgq_**ZUpRKK(5rt zg{t~(ah@w)2q#n;Yyu(&~Tlh<{^Cfj6Fi7kg1{ zge;LrV^Vt4^fXeUAwE$d@s>XO3P)Ij zI4=&O5rO~}M_66%9BJD3&vQ*XTQfe=fIF@td=rySBxz8T#7%3|^3%)f)%4y`H8794 zU1aB=;LvkYUC_Eu}{ds}wqBwxUbl4NvCQS$^P z%&5%$#etfj*T;ROb|@?A&NHY@WS2VR5$SQ43#CU>N}C-zBas zYS^`jy51|$+QRuRFG`C*_(UW_AMZ4D+<2T%IJPD>6jp4ZR-DCkTNfI5`KX1{QEMvx z4hqyy`m-6qB{RyhB&#f@@=XI@m0r*pdf|{D8JXI9JC_FaQtS8r;**zL7~b;eB+sWao_ zWz>$EY|Sb+@@V>01pac^txyx)a2UGGB_@8;JWk%=jKR+{#v_$d|7-s0IwSuM0R z`)H|+B{CYbqGBSSE`%I17~ATeo^e!*U--#o=YGqiL1gATiPx4E*~PxTJ7g)oJc1&4 zJ=B{h>-xFoFKrDHJ*nw~5UH|Eoa{s)&bKp3Dt!p8FQHn&gP>(7vD=3ZF`+W@+1^;t>rh6 zUQ+U;+eaixYj1mv5+r=)O!c%OUiz8uG-^7ba>R*Up{HXuqd*aTVb;!WDT!_RmZ$_g z*PO9mG#0_8Ni$`R1CIF=-w#ag6EB7m%UD#x?UKr3^qic$Fjx6)GcN@ann7}J8yZnt zLS8Ow2$Z*4pKy+-ymKTX;jz>~&K-`(ROkzF5GU41pK+NBdbyv1Kw0hw?a{d491=cE3A)ho|~0-#jO{C^J(eai)O z9cBNO=Kl$j{~cg#O=ktrSI?&3`%&W-9mb;ygy^$qw zS@~Gr0s;YT3rGAXvDZ{yH=?x*&2!jp$1m&H%7aW)HJV5)13%4y|%h?`-o6pNA!P;ubX5KZS>5yf8Tc-Q=@K-D$_+(8^x z{H9_iJ+fNt?N`Yy)qt)N4A*$v1-%v$eeYF(Il?B4vj2{o88ajQZ79L65zQ#~t;n8D zP3`ig;Yv9OZ$E;I{gbMO?eCXFbbF25QwC10G4W)p6GhD@j^&s1drB}eev9Zsy7#)! zH>u^m+y{pKN*~VrATK>;eZYu(Irh%)@50I&15HL4fqaKgULGeMHY6&$->@G($4G1v zvp)hvQiV^Ct)>oNr=_?OT(54VB;*bDx-A!)+UC%U@5R`YKW;)h?leNa_YIrgd1D>t zDcd<7aq8Gc2JO3X`1s^Wx-?TRL+N|zo#8grPt8c#mgT^T$wotrBAfgN(C8)Kw0H1! z%&$wSQ2Ye!)gs`J{2K?nR$Ar=IHdFYN@2h}_)#<^COd=8=1{bj;3ZT;cS0tAx+oH4 zf_I2(#2~=P;mD=jn>5xuZNZ1 zNV?Q#y>9o8_Llh{zvUfn)7MCFZwZsk!guKH>`(`tv5KZ}W2#;qYeyw6yO*n(m~C=Q zZs&n}2n++Sh~0%{{X5jKS}};82yBZEwYE(fZO2ZW)3wOCTwrEj39d)(3F_k+DvMHu z>o`Y-ZcD#Kf~J*=kL?b@Qr~@|yQve+2{(<44tHE{Z6TBjX^GOrZM44;Z8~g~icS_J zTyEnKZac4;(GrwOICYzt)o%Deeo$fy(_Ou>$|Aq7&wdM1HIW>U9!;m{8iVtn89LpP zD%FOF4b?TkOCkiqYpa($>YPzi5V}czl)GePPmZE%9$J#%!Pers)poJ@Y0{O%OC&X8 zV2#rE*+0*(^0Ng+y1?;Cjcj;uK(DKwxj|8$ykT9oRMqQV9(I$|CyV|j^hDB;rLIx??sMvXNF+%;>tKnHU1ZR^rN0YE z&&d)K$>aRXo4)%LHZ&@&MK^}u4}s~T8b5S zcXxNU;skehcZ!uFh2jJ)P+WpT(BkgyR=l{o^iQAn`%jYV%1O@l+H1~xjGO+zQ#yNe zNemO}^U^>`-)lvLPwfk}rdne(TD3&uua0TG&2@|ATspDsAZh(7qKLSTJDxID6W5eP{s@B#_aK2Xs+ zM;Bjix!qCIhYM^Xsc7Q8kDkfF9{v8&d!&PYv*zwuNXE)@AwEpH*lh#+$5+qI%B#Yz z&s`e4-?y+b#_bSv>&CO{pQkQpZLf-1(W5&8Pl#x-ZFLv3h-I{%TtA39#;-YpCVEN} zh^?3k%{uC+kNjT@^8a_e{iAdtfPbm+|3BOM_J0=w=nY{Gq|u|UWUmOlF#Lzy!$H6Q z$L3D|7aj`vSF|EecX+sOvqQHHLVO7K|7_pXg14yBZR|Eh#d-UKn(S8VFTkh&PNxWV zuT&5qkOPzNo3X0_-X9!Nnc_!fZ1nc#r8c{wMhd=}N^}p1KRR?2Pph8fTCIqBz15#Q;(F$ipB$Oi739=gR3<-{LSw@`!OuxW}qT-7fxx@I~Pay0?* z|AriF%i!`FHhw@)(SHq#Rmwm?PvcISsC^h(HXqMBE9JQF_{2CSe~sIf%|GjbcG6-1 z$vQ5Zb?LLea(k(w@Cx45O*hY%B@5`o@II}pZK2CPGGyS0-o-cPSmA7EIRMDD$V9l;_#eK}o1Po`|s|gJz_RUb#Lr0$9)Fyku~@qqf}{rH-)lZ4~~9 zpB+%lLS2N7YAHY?V`r?TQu8cHPn8EMpRl={12K6W<4fMMZJ2# zYm6sfX{7wn>L}Q2l77f3M246FYhAV?;-(&+BZ>Z!No4$j%9EaAEXispu<(S!bMGp; zZpP1*EzK)w<)i0p0|{e?Je2^1st5f6-XxO5>aYcCEj0vz&#QcD=x04cTzDnAoADuBFUeDn++h8+R(q znFP|393kA0ELlv+HnQKREdX+`8g*+F95<{&7!ydC2>_Tx8^>R*`Q`xAe)2oEfcU-6u7bvk*Pfgz5mwPi}&6(yOrN16N5#Hgph zrwM}5!|T2fzp6%K@f^xqs!weR+4$_dXU$uhic%a+F#PW2gB6`rql5yc@vH<|gVd@7 zR%Yh!nVDuTQMWW#%7Yl0#L7LtI~T-FkMXt;XY9g%Q3%>!@b-Mok>6WX3a>vzC(v}EDWfxpUgwc|9QaR%OD^b}pU zONI~jSD7VO&758iYll{JG{ltzft%O3gIh(O>wJ~0CTa1MpdU2%hYg{ofw!Z|=G=RC zWXIq@g44O$Zb3}BeiwZsCfbZRA;A^F>_%11tPlL|loX(BOiSVS^ja?;w7;U$3XOF+ z_v>7eZ-+wG3hEo{+&N6dFfO<1jY-pQ2yZApd)xTZ;|8z9}nw|f*zWHy- z^M7$JYA6TDOG>9dJkY}z!Q15OV3ZPo2FkEcW22~ZKNxoAlAj?v#k6M}Br&qnT5Cvh z%G4Wm>4WZnAcmz8N!bejNYMXa189Lf6j1+P!r&jQ4y!urhp}@zreMV@Z)Pf{f6iFHH{HRd?ta{&q!P4j$g$*jjV`aQpo-c(d{ z`3~4FY91<8)5r;~p0z#$stWz3ilIG16`OtS*`pd{N}l;AV^wDZ`)9t-7M_}sL_nVS8D>#K^bZd9(hRmXM|;m5;Uw)UeX{*Dr2B$8 zR@irZ3F!&m(Q}z%B)s;jflfO4Zo!Zvdug?b|B`fM<P1zG#I4dwCJiP{_KTw0k{#Xnz-S_^41xkd+s*mXCE*}=y1qaNP=;4tpy7a2mtd(N1EYm~$PAUwK z&9OtBCveiBeZ6VkUM^I7GlCEJdxLt1#+>dClFn(EjTZ0CKYZxzUwOLNJFjFmZi-L; z+E+{?Ww8|S7qDu$sg`!j>HH&?y;P_2C?vbqse`DA- zHP>!cv9GMLsW1c<_m@PK2hm)I#tM+88Qz#UDBh>1@$yQ&0OdP@@fvFXk&%&hIm(_W zN9%!SK&jK#x=9ofNK0DIz}Fa=k@~DDvXY+lS5f;lZwUK8# z@DsBy7n-3W?3k8(ukwN*E=l{XupK;!1?}GDBSB7ek}t(TDkXP9nN-mkE3+T_Y7uG1 zk)J@()(}PEAR}CAJ!e9Yy@(^-Z-*;NF1MdfbMg7^GgyQu|y%RdfM)=C6cAbw=)T4^#r z!ml*1&_(0bd}dq_eptq6FbgB4d0*R9Gheq{!~u`P!~u_==BY$2^lN>AUdX8#<7OH} zoUKZ7xoEFIxrEi7A@6nfxv`9WGK~s~(x)+g3_QtoLKYU0#2Frd?xY%rexN-Y8gw+X zXjh!HkRTQ3C3dQf^z;p+L*u)|dK@*)k9znd0pYgNmIElkbN#H{bEp=JvSe*qoCV2c zJEBa2gG{L92TFAbqd~7MQkItei6Qt6)(+h%KVopyEzS>sc6xS$>g7AXr61q@=*LRL z{N>)q>UoLb7VPEh`BF5|znqLu)E~vW(hF^RG1)RK(f-p8#m6>sw*APx<-Q@tdM9mf zzfo9dKbdG{F~JB>%*X_G!&g=5kG&KA1m|vi~zN{7d9fLuaP{Au9mr-s_7r z^aCcSVAj3WTGQN$bH=^f;(TL;LDsP0OY^+>R-n@^9_CO|u3$SbWM-2Xl z$Nc-dMa92>&4JCYT%WNs8y2oEBRMTSZqVz%o^43Q9`|O!CB1j^*+sb|IvNz~F5A|X zm({9+55yU{w>J4EUY*~#GiAXK(eXug54r??8NSe{UsUTrUUoA*ornG4s!pqpyoeMz zbCWJbeR~5-SzWx7_eUvg3}$uu*pGVZo&YV&VMx!mCJvuY_vC8c#BYB^epAcI^v;ZH zIlQm#VjPQUR(2LQznHaP=+yy`Z+L<}jXOG)0L2Aj6$o)#NE6{O?;GvpkGS`|m#wpn zKaCNMH;;;CyS4kC%RbLjDP;i-GqvG~Sh@m(ja0tE;{v?r%#=fkQ5owo-$7r+QZ<~k zl{%x&O4Acu>?L=J)JBlza)=od5u%)r5{cplKtEr?0UHtoq}YXMM8J z=n9FaVk5b{++9XtO5{Q6=-OGFit!%TIffTLntutwdq?l16}M*iGK{KW4!86 zB9%~S?3dCOA^DE5R2!E|ae$Dc&Yi-Js|b$zF!d?>J&R`QMt&vw@nK6X3=m+)SPXCWkJuHGav=X)@u z;T6((C<{YexV5*N=wiR9BF9tRbpPAnjt%7ee0d3`R|}2 zC5AX@X3g06$Xrrk#$v=$^3eo~O~>l1k7&az1B;K!#wnSqW5$P;D>v!f*O%l+_(>Kj zND9o3#RI?BJ~|*4-~7l)n-8DN`aV_1+}QZ@?88nX#BJ5}|UAN}b;})?T01{Bp2eE8?^gaNlsL>KfTwI|Rox ze01;Si29*Hna5uJTK^j%!8rMSYU_uGx0Nrl4QfL4X6Bi1$Jv3a<%{<7nqx&q-~flN zGY%R(lsZIhc%LuKQof)Ds%14#Zw%G!=;94o$>z?jHJw$hK(W?Ox)>7XdEqS&N`auJ z{hhiNtK|eu^C8ivFxScxXr9|V4dR~-Q5k6@q$N>6rZzTK9Nv>h!etpX@gcOlSq|BYnTS>*0 zyfJVy0?%S?sHo^gqwp`lNY3B_ZPsqsV}v!dmkH;F@pVvXOrdt7VZkQwm zJaw8<8_35;^RVPvs0Qocka%8Vh_Q9hbydt>Z{W&DEO&z=ZOgN=BW0ni(RhD>U1A#0 zQY%vU;mhX}d_0dKurqHPnOC)Diz}PH!FRkE3V;bnZl5u+lyKp5pb3H+A@3+>1SrytuQv=tz0ESPkYcMYBTJH5+wLk3) z;J=XL*|`2vwJyn42u}oM#o|h@yxTRjL0Fh}`YjHbb9I)Tlp=Ff zZoGW$Hp&^9?dpQAgOXQ72x#(;!lN(kAge*mI0D*NLC%4qxCJp!!`G3bI-sO8AN68i zyMyop?#>V7jo)`mb2*+;=epXYY}z@#pT~CM-==tDZ-G$<;kP=tdzD1eg({~W z4z8sm&JOQ-{}d>fw1sa&$Tb4i9pcu0pfD9yHX977oQUd!9`xs8YE>?n z;zps(v@5}NO;1!0=Szb}IPtEX1vW1gsSgEW6tGs9z6fGQ@|-75Z4n?etvpg$LHnTA z;u#oLRIAn5C+G@6k#FeMp|2CfmW9vPUY6VBfc7ws# z_2W(w!#cIbceL`J!Ej!a$BlWOwcV{98)-Zm*ek>^bPH`nwVMe=BoowMznvbP3LfOQ zh8B%D=l|T;i2PYZRYr?O_I#*Z3aVG>&Gb0J`fe#I9yLNm6~>^RSNinMs#kYivCdgr zgIS`}th9J225ZhunF&XM!it&I(Xk!GKkKKjXpoNEpw7ERpImHBgv!gq@*zhs5QyUU z;nD?8i3rvX%j9PuNK`1us14}}TBMj{l{}+9>K`^co{_Y?RBbo03ME*XoTl_zNCc)2 zXQ>IYWeK$MuBiemSo#u;1jHxgTnNF!lAOxTwtjDS5v|-_aZ&x$b&4~_MXKruBzQDa zM?cBJSlj~{fdmg4P0V5o-Lyn$~)gH>;Z88&r%Y9@>veSTrERsgU!C_H<+g{3Zy!Gj7(s zx~eTfNv^&6Avb806~)+FUzal2sxIK}=+K{iCt5=ffkv>BF>yv-)zoMjdv+vsYVIz| zE_W|5hOjJdW~rS<2m8E8NAgwlDvshzs!Wx|w9?CfIx8}hXQ9B&LMu`Ha7C^HuFwDz zS0ni6h1Ozmci1Jv5SNpZTjc&w?#ukNSRdV(SpHWW2gXyG^5kDZC1hM=v&NRHwV`qm z4j(l~#lg*<~t&xN8j4)u)+!c`scPMbWzYbh5-O1)G)Q$u+bMdk^gM&tWxw2CIpH76Zx3%{6eLgkiO>6X7qRDK5X7|{A{bq{@bR@WIL zibQqtx}VdyO4eUEl;XcO_pHyRGU1sE65`e3_ZT{wsrxA0UC^3r#k+MiN07nZ&#mWH zHfTn3g_V>FuNxduTYO7}xQxO$^oyW+u;E<~*o#el&vGYMkpBUG?H$U(qqB=X>n4@^ zG19}8081|6jMtUmL~`mh_c-?Pp6u3l@3}HD&%4UVf!cP1!~R$1Y!B3l0jK4UJmD$X zr8>66Y^4<{v1!@4bEbnRaNie|d|jLrO@6^Jsm?8rzT~4|%PMHAK7-7idDoy;I=pGc zZ3vg9!@{^T)cpL-V56zudLiaqKpzTY-KYvfN39?K&o&H#a#+#OMy>px|26Iu{x4~d z1XbcOA|=2i%#T$d4$|3Oe{|!mMO+5?$dfK%n~sT;sAFvCRc3wjTUV-YZ=Z6XL|8D<{Dr%cYyJW?J|pk9 zcVnjv*?0}luP_xp#5=8u)NFN~xY_~^H$glNuJ?D0kwSXk-~e(Y=&VOAVTU^i<_%W` zg+3dNXEi%+25u)wJf8JT$X{4WOUf(X^kb}5%p`dF=9JPe1mcRO>NGUDWe5dA6SaK3 zDhfM!ds!}Z*hvakhyXXaayyJ8`#S8}_?A5@$4$M_Kf7s;sY^eW8oL$D?D09Z* zgx;9)1)(7R!&;xxe>g)?VLnAp{Iogp40}RIFpY9&O#j{7<0mKQE}jBhF}f0qh^Y#W zkb?LTcp2^^?Lqq-A0Fr#PunOb+XRRqV=VqnJlU)K7+3!HRx8Zob^tU-b)=ZdV$*R0EhC*o9^Ku-@B z1tC-;MM-)JMu7J5Q+qJ4@#l79Vv982T{wk3Cs=WX51wEnZG7`v|ADIX%WiU7&{^oaEV>X-N$U+BCBAfE%!pd!3a(PwxGxu7h6)94; z%bXG3@Ie2F3|?a5x3$6Et&Z&#lVza)_b#a_xIg05#rz`uV3obh(%D(>sW4q>}WPE zxAcSsqj?&bdz?do1_#S&(v3OvKqS-@1#Qubi_`*ZO;K+7*kvHfdhK> zfZ%J+t3m}4FRa=RfPh*vvq$9n_S@RrUAj*rr0zmdMHIhAFSTc#kH#Ylwu1L!0bj&s z2dboLB$QHA*zbav9xwp|KxWdJ^>*jzC&4Ut?`HtMlt(qG+9VOv> zE?HuaCkE{+_!L)^1tcJ=^^19li(SqIv-k|Gl-lO|Tj{M17ONUw)N#hSKL+r(lkgL# zr^OxW4Wj3r+i|7!n!_fOY}m`b58)o~;379J;+>Xli)c6}&Qk}|%k9b1q7^DMxvkdQ ztp?mJ>MK|jfJRSivHF^3TiHcOi9nM; zm7{0Kav1!8S#?8m*sk%pqUj61utT5^<4Y^gFu9Jw)Ph^v1W;$qQyaY~Ei>6rwU_`A zm>d9)x^FKJ(-*gLCMYy;CGZ`Le5Cb-4HCfEJ`%kFju^bh)1LRsD007Y=fr(a2n;{z zf8SB~IwNPpnE%M}J+&{9P+-b8Rc6)2`Ha}XBd_kQx)cFuu@Cc(oRp>KHjC6S!M~nY z29Ol02%`O+Z)Z`>xPN-Z?`e`0J$k}3Y+W_7dDtTEv>p&`W=?ooQXj4~WAR0$ZJuTs ziW^y~JFrA&>8=^HR_))kz)DlbPjWE?Ug&>F{VhaJTTcdhUJcM%jm{Ri-7p(L@)BlcIS0H#4n9&tAGJbNF!0hSsAP!up$knt_3K!*` zZh6;R)>t4}qONwc(H5UZxwD*~sS1)U-F|6fDsMi({8gzAs$=u9E1kLa;V4}Lz^36LJVwVv+;)+-^SA{&y~R{4ORe8-tvbaxBuoYyMLIqqI(OGKCq zRhSPHI7fM94^&)ui8fXkNOEX!MtkS$TYkZz8hsF;BX+nDn>vx|^Y7 zPF~BqvrbkX!Zs&m+HMvwYK#o!b2*I=JlZ657{&tw?}<#BK1-dFpP}jH-gZ z)Fs#GGDNT3-<|&hgKgF9*Z=Jf{&Tv>AQ3^g3{a|5QJ)doVD%sEPrYh~u&uhm159Nn z!IE`YB84M0UXdM2k=^A0V3~3^7qT9;k@eL1HiddvRI?gEhJlF6KR_Cs))+Ol?NQt< z>=llHgH3H5X5E%H)~t?bi+q8W7KlBB)1Oc@JL=I7%e~p)`5liaDXZ{sMj|(->K;f& zcX!E$Cqzh+_tc;7~YFX$t%XxmnfI(>sd; z_evXUu`%$d${zMo@=upg4r~=742tuvPyjhyYt3V5Qa(w$ zKHw}$sgGK!n}i8@{h7Iany>m^$6IaS4f ztB!AkZV^P`0Utmnvb;P1on2W7WkpynAy^OzPlY^gWF#o>b8+ktIVMh|>2AQWw(^c* z{wo>M=9uqr5FcE8d9*-8E>-rV7FTu!>QenjmI1Jej;k7rS*4f7PtOCPOxn9Mp0N2= zm&BytPeu8(Bk;qxv-+zfM=P3L12=Wb84b{~fdrYTsW2H&{BXo@Y_+fk5u^G`6m?zc zW?E=H^~hyNp~`<(6w24-1h0O%+rg! zqsqe<^W>dgG-1U{ecmJ`42PsKaKODbfhM>}^XsMw{6nqM%*b8qG<3-cejpZ8(;YM% z=Ag$YJZ+!{ydxyC6@l<6giVmp5x*o`IrC1pAc)nK4fWT#lf-Qkdeep904pa|B`4?n z3DKLYSvq){yj)xwhpiqt)+dt$E?6EfOD5)?soTQ8#gJ7L$Bb^GakF|WY`3T>uk2M< zLGV5Wi_O<7ZhTB^YA~KY+^p0;94na*wD%^D+DbrxRhGwVgqY0kjvt}ieLrQcz>d=i zKB|}v>h)gW*ir6eQGWJ)JH}LIGpZ&dA%H9vtRHoNK0YT#0IpVu=Yne9`#TIRpqzj^ zdZ2;B9MX~6dFMcvxB^WSI*AvuS0G|Vmd&T{WiVGUhA`YHzS^G79KmlqcV%21i%xhb zjlqw<7jDWc`1z+YJ|Y2_J|gTNU)!_Y+p~QNc{M2eB!B5d=<_S0@;3$=EpZ+QSNZoc zAC~n7wm~E;P=p5JE*NI#G##Tqc;47ac#Ye9EjDledgYHB1o>V0K)DExZB>qZm3TW| zC{eOf$%<}IqqBiH_ z?DlLnXMW9Z7i<{}CR`dn^xBV?8zZW*aW>Y>y~ymo`OfkZM%%l;{ui+KVPSkY?M9Cr z8J$rn`GvMtge8&v50_&gc;AV#H%zu2(k*{iNmkzZ&4zO#cReq4 zQ)MwsybfC-A98w?M@kNzvX%M~hRxGpfq!$ce;|){+hu+^vfWn@q|@VQ_WIbxTDo{}2Ye~~g zpoMSANB(>50>M*IF=*MFx>j#>+gsjP-rG+X$y>#)qs1*p_m)Sv+`;WniBc&EPqa^(`wa<0+~) z#pNAMN?1#GJq7M>CQ(P($hjnoe&$3YdA)C#kUNAGpO=l1%|Ggiq5&U25U4B~NnEls zox-`6Y7+;)WUBHb+QB5^^L5O%4>hJX5iMrL(}0skb%3#QqVj)+_7{R^5rp+>ZXNel zIIT8qw7vK2@mF8pYLOGcF=}C5sad8fd3z?DWsqQ^cX(D~sc; zdbZ$-`~=GN4vZ$31Qk)vanWWF^mMb+294ZQ1u!gEdg|?;f>Vjaf~m^Q$)S@ZX#XTs`<61ax1)$GAGZnBYvQyxqIGtTGsG^*y4!yM`*NA}(VtOJG;W=nE$RuZ2(e*x_S{VIa=D z*6gAL!w=Sgh_tfAE=v;=hYx2@c5Kl_%4bn>J*8fvVd3dCq9!2fP41~nYFE}Ds3wO@ zyOPa&O)27SCo*?gt~}Ge0VeUkEn)@F{sM@{TyzaBppQYh^pURnkf4#?L+8$MS7Ml- z^(^rnt!z5IE)`d-8MC32qFD#L9Kl^DY3MaXXfKO8VW5Jpr&d4 zE0u&1iVZ%IWeX=HvQ}uF9$2uX_kzMe!IFWn@QU03(O}7SHr7M*=bsij*3UoO_L-xR zqHMcDL{0j8L0+=b0^%`C6wFW&fHDKMR)*rA5nq#3kiVr@o!h9|jJ@zDl>2LcK#;|# z+3B>h$I^-PxJLmp;nDTw{Dr&Od^3N`V(h8^WdF_eNZt$N4v&0MnfJ8biAH#=&Um#v zWnx1HMU#NetqBIv%W&*ZX*<2OMJ`8^UWFGV5@R4^&XuC?hvdjdPDAA6z8o)E$Ih8P zN>1S@Ur8inLp_e=PNjYS=I5cWtFmbYmzHS^yTtQpn#HX#&rU{KR=-W-@hR_o*Gxj2 zsh0b6s1Bg`QzB(8l zjnJyFf$5U7Ip0~KIjLFh?Cz8!Mpgf4E3oJa8zWpjjwBS#OR9SSMVU3OsS3tJTc5}H z=MjXHF@mw2I`UWCAkLM^Rz?nOGIXe^B6pik?PxAH8@i}8b65^JE6X<%mabmS3Z^*u zw(F24w>z^FBlmC=)``r8OMUqU+91H?C_v2%Cs* zLweDxcrdCpZNI#z8G4IYSkgC?8uX*sQ9Q>@g^h5dU)8Cj{D5h8=hZRLWFpd+i*cA) zgQkC7O8)D!vKwjfpZc4QpJ(EZhN(7#ASgVuY1M+$`QhwTD9yUoczA{T^O~E0P}QdW zJ$-)VQL92c)Qq*_29+UVQ#)Zd=Kn;3ZYIl-BsDZvV*b^hFe&`EqD0SZNd<4v$F$fUyjjy zfv8fzz;tCd>^<0jx59SJNy!uEK>h*)`$)WVQ40;%6lejP@KlD&M|!-Fco>`i*tH4G zRe%a&XDz~zP?GBivKvz*0?3hv(;5r>m6WZLQQNiL1;VgGy=7t6^DBN^@Q+8eetg$H zj2LoO6|IsOhQc8vvfyewK+?Ay?cgWoU1?>}Llg7SF={8C`F&pFw(^UkC3Uua1C%R*j|L|3^34(XSy|#{HLfLQr`+{H_C2p_$TGYRpriN~dC|ieXb9EE?Iv zKkuC6`lG6Fy0NI#V$NrgD>*rBU$J}9yu}L6@IkrX(}@L?*(b~c?pTzidHcsw?L zQRdVMlaZwk@28i&BGo@kx8hYi8{Tn`b|m?pmuDekVk(6cTFdDUJvs{u_(&wTcVSqy z`PE3DX?$wABxdx;loR3A*H~VGJ&-lQ;Q0~h2ckgG`mMsRs@Q}vSotC0pphyo0k>+g z_F!0M)xUsPC||+$7vS=kazpe>wsXUL ze%askQN-QuSN|8`&sruNHyWN7F<;oUUPn?p?NTB08(E&0uBz7a0nv>+4)uQlBT}<^ z@oL8{07Kj*<%Y{)=mK+^E?8%T@59*T(#kzN1SYNEF+IVH0z^dMk?~2w(Gw1`bhV@L zd)LXLHuc0&3sF_29rRO24^qd`~*C@rZVoI&aCFj#aBai z%*z?c^lR~(kI=*SgaVvl{sQ`eSprl?$+u?Q>bnyk5+;hYh+H)S%84spgimv;N1|Qm zQzg6rSPr?UZH!>l)WMQsP<6jH!nt;G<*7?{$+uNm>i7c5tqkGZaSM_rCvBnTw?iJO z>GK1rTt-|g0RW5_?|bxB!(oxWT#+$_5qSQyT1br%!?`{zrT>u2= zpze!v%dF?h6`6fz{NuSwM~9hM@3XS|k_DgQkZzFzwUrtUJ{M8l70z%@dzfh(P0bnErKV1m=~;7} z!E@(!xk-ceP@S{C(~KaYhIgTEf9_}~^^i`R>^mVPlGR-&N1^xS4^m^dv_j!dNlHi> z5`?hTWLBTD1F&J>+>a+!AIfEpb^AV=Cv1kFK0C-JRVKX*S7!vKC2}V3Ge}*=3LcS#*-UsIbV_crb#X6AcpVd2knc7t&{%ldq&6zN$0m|wrr$tpY z%kwe#R_-|;!Xfy_5O#J!{u8NzbeaoJ=F7d$JX&s)+s`DNL`$^i`6>Zq1H~#r{f@Kq zal7h7BIYO&KCh!ks-{V@E&mgL8fXL58g%?(<=#$)<|tZt{fUj}o66q8Dkx-j#Q~~2 zVa~BrlZhf_5zx*afH(z30BNgADub?qLQ^I@3gA%d`QODZh4kUxnMeSATK&s}DZ;8& zL)xlqE(Hn03RRzsOLE*tp;T$dAiRP#Vw&d6NEnj=X`B)Ky2vH#W z5~<|gVs2wLv#fK;Je0f-4S(jAeP$5s+m$$-GazN3i7scg2-_KQXUZr;=(F)drtD3&0^8IpY zSQMEO7Vtpdemb_PUA9-mQ<|67R8%ctoiNhUNuM#^K<1Df-GI}<+zy?a8*^od*k#O&GFU%)RNcC zTy>DX<}8wbJNA?`x|se(h4oo7dUNo5KXsPGN}+BXWzW27wWn}g9;3B+-D3m~0`J9I zwS_CR;G=KeUCA}mwwDilVi8E%Cr2F|A*X(Bw7FL%0;GmUHYw`)(!c+bcvOW|d-4{j zz2_hqgn2f<-5TC{GOmjvA+DzmJ}U-qfoiyUoJvb+6stKmR;3o?<%*8_pZl z+;ngMSbH{6+RnJy6>UtviT|aqpTG)mSaXIL)#Rld!)%2UQ%da}hm(AmmMds8kfX7^ z$H&`fRQP;s^(r*w3d1WkB=x5#?rZ#S{ZWz2?IuXlq<5^7CT(-=-cZvty>VJgci2(- zlC_13F83$i$|zo{c&HSTY)>I|CM&DZ#uRtHr6VbTh-T2Ed zx`>un3qwv=#bSfEM)-)2PEl|*I#%oRw3YVyJh(ivAUBz#Rf{#-m<$;=TE@JbbptDq zsiFIee8K49Sw#*T!kHaq9gGl|spw`ce3&4Kf|OjUX`}KojWM2O;6~Ha99kSOQ**|~ zW*=GHVWa9IU$wt&A{t4v7{X~``Obn@*s47b8_4Xa^8*)-G0rCA1ZU1GE;Sy3JAHSL zex2YuTddZ4Rj&#$D^#64-3N0O;al=(f!^TJafSez)c-dzcU?n!?)WwTyM!@jgeWo@2RE4e=~5&U4~BB105S&m3;#yONG-_>by#zYW^3NxvW0|`@Qs$>866EymZiJV z#k{?qIYu`Bc?>gv=zg6WjD2{6v(061j*H9j;T zL$VTVz+CWz*;tyj>fUY{<1*tZVsni;VgEJKWi$;$4ZPi>>l*3M7CvV`0b) zmq^12oK_3_fX1rChUCR5Zy8M_ff|K4+*g)UB_mI^c+{Ci+CLsp%!7zebvT!a^!>KC zbR0G{Lk%-5-$VKa$gR%uXpmB#T6ZOwy;cKZYPI^JWGn{H0E@vqM?kB|k#X{tzG6+_ zuAaB!eW7{49Zwl%2ZH^n+o2d|&Zp4zZ;Ni!b9SO_hHI}2!hZo(V3ZUe+m+u{9Y;oq zkpA&_LdL9NUxCvyxPnB8#y8$U(*;-~uL3+4&X2BW{P7Ly`I^jDBbvC@h(-}DG0sN6 z*e05;CtnK~rUX8yy79z=h%s=kvI5ToC7!^Bf^^$fY0-?xtIbp5RKEgwgz=O2I@4hA zT;U%9Lb_MrrFC>#JK^T}D`Gbc2J(Po|1y94-Mai#i_F?@@m%9X@0WghF)z$?9UH|V z=5sl9$V6hJ(M;?=vE9!91?+BQ_x%NI+_G^*Vt)_4VZGL;`zBVlelyTSywD;0L(@Ju z^W0_0gFO-*R-Tz^=(>=2Xw5+7)xo3mc7Ad&i;&no-yC4Rnhtmm0ogAd87K9NC4OCI z7QK#%{|m?r8c`6jB{xb>ckTKW>QXB?pXoeu44-94a@uslsr~-|@IVj0YOfp3RIkNS zyT8W+6Az+wHP#F%Bqwc}NbUyFU`Fw3zWoo?bK7tzIbK9te{|EI)qQ^>NECngQ5HWF zx}rILvB|opo;}GQ*S4#Cw_jDTWAnD9>4uM%Yx!0Ok4SatbeAOuagp2XsZ-E%ai1|4 zv;-~nkyL+|da7e-CXsLW=l=kNnvyR`b)1G9@*}zYPVN3$#@*Fd9^)GS07{c(+y4Ol z86Wzb7l)#Ha%(qHu=XPV0KCSR{{R~FqG=~lxg38sG4%>({{Zv+fSaYvQT#EM`q)%$ z=$O#ivl#yX3}Anl);8|3zyAQ)Z~Zhht_y$v05bmos^x*vy%QhJnZN%4#lQQDPW?Zi zOad_Te`!~Hdp1L(M%R!`Z&=bZ$dBK z-R_vv#$TaVhCb_lLbtY0f+z+X0b@azX0_Hcre2w-R#rJqWUS@2u-}F$6 z`JbZKh8_O^{4d(n_3HkR<%9nK@|XT9nSD3WYzT{wY>)o{6+JyW(YfP~bdUc49cKHS zFY{&jnpHLVYC<}vrBD9=u%G_`hQIMti=F91{{ZY~`=9-FY}qxWF5mKP{h0^UYdBzIGg&vU z_S@|>C+Hzw4JY@BtgUXDENHDxjIi+fQM4mxf949V{WH>%n~ajb{w2TOTACh-iIMY5 zHT#%-t5V77Yz?bh^sm zBmAvRo73^D_%ewd=nvG@T3&@ZpUItlq!s$FSFTKphjISu38Vb1pZ@?7>oDsEVvf%f zui0G>rZIYkG*d^O+vMB|w(Zwlr=4=+3$8{#DX@bBGCs!dGwGWR54m z;;&@&-nWaNG;08Sb&-`E#@sn-q*EK!omqeVnGg0{eYG{VNK0aRa+D#Wv#uH zP5E5fyB+HFPmxWnCYmpmqjY7s5*TVZHC5?ZM=i^FYa2%^M&We? zs34vLjb6dR>Z{TEWYJ2q!zhF-a*G8lthze*t?o5Lqr)~lnSx{p>zcuo8-clRq0_di zvNv{})zW;p@#aQ8P@3~KBqwROCfeGd6GgjdJ6rG_55Uyfo0}GIF8*f5*hd@K@T^#4 z^%I~+!hDF>e9oaQ{ifP0(8X+Oj@d6vX@0vZ{pK0fosz9>X8I{LAySh_N#kSjCe^2o zLhc7!o)wpmi{->qDtNKWErf3%k;b>Rqu*AdpAQuf7Mg9h7g+qY*I$}qzg1;y__8PM z+uhgy08XyU=CmsDWUE`2%@@?t`^R-icETi#5w=9Kjvq3U?BP{9<|Mh@J)lCW=;6lw zFKdf^HKmu4DaCn4JVr1#T1gqnuundf7@5NS8R<ByUi|VKawQH{Vp7i6{aAW7-|jA z;N!xGqAf98h7iYc5w$Mha3MSEU#rFBWF)xa8M0K_Ws%iFf12g%f%RD91 zc{{#gYx1!=S2th-b4qR!{Ww@MS&k<&2c3BT51;1r1uxx?VA4pQ&&Y5=T(wSuPBjgSX|qk zVERq`&YjgUE__HD-MTW$>h4Zap(ejjjGD_m10Ei~#! z)-eKXm|FJOKpI<-AF`v54;w2F9(fmZxKi#$2FxsPYxWRoJPxA-*#7{hlm6=siBv1A zBM-ZOtFog^*)VbZ?lFlKT{}bgev4JA?^dE!s`Mh%t?KIaO&UF7EDjKJ0(@DlRK+sl$Jyg$tz?) z0+0syj+}e>RIo~1xGcfOjD(OuJ=K^p3reSU#w-CM;1D&diII;fF}1|#NLdtH>H8`k z>hYGo;$c1-60<(>`HjZpT=Eq-V$rD7+WU>kCad{@2w6a}HWM$(eZPd"&xOPvR_ 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 Date: Thu, 12 Oct 2017 19:12:53 +0200 Subject: [PATCH 031/211] removes unused old images and styles --- app/assets/images/ballot.gif | Bin 7187 -> 0 bytes app/assets/images/ballot_tiny.gif | Bin 2570 -> 0 bytes app/assets/stylesheets/participation.scss | 27 ---------------------- 3 files changed, 27 deletions(-) delete mode 100644 app/assets/images/ballot.gif delete mode 100644 app/assets/images/ballot_tiny.gif diff --git a/app/assets/images/ballot.gif b/app/assets/images/ballot.gif deleted file mode 100644 index 18cf0717f8fd19ee65b7e1deefb24a85db7f9de1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7187 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 C)3qZ2 diff --git a/app/assets/stylesheets/participation.scss b/app/assets/stylesheets/participation.scss index 5fefd8c53..a887d83de 100644 --- a/app/assets/stylesheets/participation.scss +++ b/app/assets/stylesheets/participation.scss @@ -1478,33 +1478,6 @@ } } -.featured-proposals-ballot-banner, -.sucessfull-proposals-banner { - background: #2d3e50 image-url('ballot_tiny.gif') no-repeat; - background-position: 75% 0; - position: relative; - - @include breakpoint(medium) { - margin-left: 0 !important; - margin-right: 0 !important; - } - - @include breakpoint(large) { - background: #2d3e50 image-url('ballot.gif') no-repeat; - background-position: 90% 0; - } - - h2, - a:hover h2 { - color: #ffd200 !important; - } - - p { - color: #fff; - } -} - -.sucessfull-proposals-banner, .successful .panel { .icon-successful { From 560ff7c51de83251b0555bf6801c00bbc82eab16 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 13 Oct 2017 12:40:42 +0200 Subject: [PATCH 032/211] does not use custom implementation to disable submit button --- .../javascripts/prevent_double_submission.js.coffee | 10 ++++++---- app/views/officing/voters/_can_vote.html.erb | 4 +++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/prevent_double_submission.js.coffee b/app/assets/javascripts/prevent_double_submission.js.coffee index 2a4ef9c5e..abb8f8314 100644 --- a/app/assets/javascripts/prevent_double_submission.js.coffee +++ b/app/assets/javascripts/prevent_double_submission.js.coffee @@ -22,11 +22,13 @@ App.PreventDoubleSubmission = initialize: -> $('form').on('submit', (event) -> - buttons = $(this).find(':button, :submit') - App.PreventDoubleSubmission.disable_buttons(buttons) + unless event.target.id == "new_officing_voter" + buttons = $(this).find(':button, :submit') + App.PreventDoubleSubmission.disable_buttons(buttons) ).on('ajax:success', -> - buttons = $(this).find(':button, :submit') - App.PreventDoubleSubmission.reset_buttons(buttons) + unless event.target.id == "new_officing_voter" + buttons = $(this).find(':button, :submit') + App.PreventDoubleSubmission.reset_buttons(buttons) ) false diff --git a/app/views/officing/voters/_can_vote.html.erb b/app/views/officing/voters/_can_vote.html.erb index 27c5e9dbc..b953946ce 100644 --- a/app/views/officing/voters/_can_vote.html.erb +++ b/app/views/officing/voters/_can_vote.html.erb @@ -5,7 +5,9 @@
- <%= form_for @user, as: :voter, url: officing_voters_path, method: :post, remote: true do |f| %> + <%= form_for @user, as: :voter, url: officing_voters_path, + method: :post, remote: true, + html: { id: "new_officing_voter" } do |f| %> <%= f.hidden_field :poll_id, value: poll.id %> <%= f.hidden_field :user_id, value: @user.id %> <%= f.submit t("officing.voters.show.submit"), class: "button success expanded" %> From cd6cf3bda11f3615853a1ffcd0c9e2d47d2cce13 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 13 Oct 2017 12:41:33 +0200 Subject: [PATCH 033/211] uses default rails helper to disable submit button --- app/views/officing/voters/_can_vote.html.erb | 4 +++- config/locales/en/officing.yml | 2 ++ config/locales/es/officing.yml | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/views/officing/voters/_can_vote.html.erb b/app/views/officing/voters/_can_vote.html.erb index b953946ce..b5c9663ac 100644 --- a/app/views/officing/voters/_can_vote.html.erb +++ b/app/views/officing/voters/_can_vote.html.erb @@ -10,7 +10,9 @@ html: { id: "new_officing_voter" } do |f| %> <%= f.hidden_field :poll_id, value: poll.id %> <%= f.hidden_field :user_id, value: @user.id %> - <%= f.submit t("officing.voters.show.submit"), class: "button success expanded" %> + <%= f.submit t("officing.voters.show.submit"), + class: "button success expanded", + data: { disable_with: t("officing.voters.can_vote.submit_disable_with") } %> <% end %>
diff --git a/config/locales/en/officing.yml b/config/locales/en/officing.yml index 378b87b15..e51e03510 100644 --- a/config/locales/en/officing.yml +++ b/config/locales/en/officing.yml @@ -64,3 +64,5 @@ en: error_already_voted: Has already participated in this poll submit: Confirm vote success: "Vote introduced!" + can_vote: + submit_disable_with: "WAIT, confirming vote" diff --git a/config/locales/es/officing.yml b/config/locales/es/officing.yml index 354b59710..c23b42568 100644 --- a/config/locales/es/officing.yml +++ b/config/locales/es/officing.yml @@ -64,3 +64,5 @@ es: error_already_voted: "Ya ha participado en esta votación." submit: Confirmar voto success: "¡Voto introducido!" + can_vote: + submit_disable_with: "ESPERA, confirmando voto" \ No newline at end of file From c097cf236cedd9713500e665532a00cc3bf7e5cd Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 13 Oct 2017 12:41:43 +0200 Subject: [PATCH 034/211] updates specs --- spec/features/polls/voter_spec.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/spec/features/polls/voter_spec.rb b/spec/features/polls/voter_spec.rb index 256807928..41886653b 100644 --- a/spec/features/polls/voter_spec.rb +++ b/spec/features/polls/voter_spec.rb @@ -51,8 +51,12 @@ feature "Voter" do expect(page).to have_content poll.name - first(:button, "Confirm vote").click - expect(page).to have_content "Vote introduced!" + within("#poll_#{poll.id}") do + click_button("Confirm vote") + expect(page).to_not have_button("Confirm vote") + expect(page).to have_button('WAIT, confirming vote', disabled: true) + expect(page).to have_content "Vote introduced!" + end expect(Poll::Voter.count).to eq(1) expect(Poll::Voter.first.origin).to eq("booth") From ecf95c4ea3554a24c2d843b81a4fc558820c72eb Mon Sep 17 00:00:00 2001 From: Bertocq Date: Fri, 13 Oct 2017 12:16:20 +0200 Subject: [PATCH 035/211] Add slug to Polls on dev seed rake --- db/dev_seeds.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index 31902bad9..eae15973c 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -525,12 +525,14 @@ puts " ✅" print "Active Polls" (1..3).each do |i| poll = Poll.create(name: "Active Poll #{i}", + slug: "active-poll-#{i}", starts_at: 1.month.ago, ends_at: 1.month.from_now, geozone_restricted: false) end (1..5).each do |i| poll = Poll.create(name: "Active Poll #{i}", + slug: "active-poll-#{i}", starts_at: 1.month.ago, ends_at: 1.month.from_now, geozone_restricted: true, @@ -540,12 +542,14 @@ end puts " ✅" print "Upcoming Poll" poll = Poll.create(name: "Upcoming Poll", + slug: "upcoming-poll", starts_at: 1.month.from_now, ends_at: 2.months.from_now) puts " ✅" print "Expired Poll" poll = Poll.create(name: "Expired Poll", + slug: "expired-poll", starts_at: 2.months.ago, ends_at: 1.month.ago) From 916f9ba40bd65c26aadd19632099568130bf4524 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Fri, 13 Oct 2017 12:44:55 +0200 Subject: [PATCH 036/211] Correctly query and order poll question answers for description block --- app/controllers/polls_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index 18b9add0f..338f72cc4 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -15,7 +15,7 @@ class PollsController < ApplicationController def show @questions = @poll.questions.for_render.sort_for_list @token = poll_voter_token(@poll, current_user) - @poll_questions_answers = Poll::Question::Answer.where(question: @poll.questions) + @poll_questions_answers = Poll::Question::Answer.where(question: @poll.questions).where.not(description: "").order(:given_order) @answers_by_question_id = {} poll_answers = ::Poll::Answer.by_question(@poll.question_ids).by_author(current_user.try(:id)) From 386fe785c7c88793a89ae6ce2f258c0c8468bf03 Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 13 Oct 2017 14:16:21 +0200 Subject: [PATCH 037/211] improves text and layouts for officing voters views --- app/assets/stylesheets/admin.scss | 1 + app/views/officing/voters/_voted.html.erb | 10 ++---- app/views/officing/voters/new.html.erb | 39 +++++++++++++++++------ config/locales/en/officing.yml | 6 ++-- config/locales/es/officing.yml | 8 +++-- 5 files changed, 43 insertions(+), 21 deletions(-) diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index 8f6912716..85997aecd 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -605,6 +605,7 @@ table { .callout { height: $line-height * 2; line-height: $line-height * 2; + margin: 0; padding: 0 $line-height / 2; } } diff --git a/app/views/officing/voters/_voted.html.erb b/app/views/officing/voters/_voted.html.erb index edd098403..49d1523a6 100644 --- a/app/views/officing/voters/_voted.html.erb +++ b/app/views/officing/voters/_voted.html.erb @@ -1,7 +1,3 @@ -
-
-
- <%= t("officing.voters.show.success") %> -
-
-
+ + <%= t("officing.voters.show.success") %> + diff --git a/app/views/officing/voters/new.html.erb b/app/views/officing/voters/new.html.erb index 0f8fa2958..212a9d8f8 100644 --- a/app/views/officing/voters/new.html.erb +++ b/app/views/officing/voters/new.html.erb @@ -7,7 +7,8 @@ <%= t("officing.voters.new.table_poll") %> - <%= t("officing.voters.new.table_actions") %> + <%= t("officing.voters.new.table_status") %> + <%= t("officing.voters.new.table_actions") %> @@ -16,15 +17,35 @@ <%= poll.name %> - - <% if poll.votable_by?(@user) %> - <%= render "can_vote", poll: poll %> - <% else %> - <%= render "already_voted" %> - <% end %> - + <% if poll.votable_by?(@user) %> + +

+ <%= t("officing.voters.show.can_vote") %> +

+ + + <%= form_for @user, as: :voter, url: officing_voters_path, + method: :post, remote: true, + html: { id: "new_officing_voter" } do |f| %> + <%= f.hidden_field :poll_id, value: poll.id %> + <%= f.hidden_field :user_id, value: @user.id %> + <%= f.submit t("officing.voters.show.submit"), + class: "button success", + data: { disable_with: t("officing.voters.can_vote.submit_disable_with") } %> + <% end %> + + <% else %> + +

+ <%= t("officing.voters.show.error_already_voted") %> +

+ + + <%= t("officing.voters.show.no_actions") %> + + <% end %> <% end %> -<% end %> \ No newline at end of file +<% end %> diff --git a/config/locales/en/officing.yml b/config/locales/en/officing.yml index e51e03510..bb9ef6bd2 100644 --- a/config/locales/en/officing.yml +++ b/config/locales/en/officing.yml @@ -58,11 +58,13 @@ en: new: title: Polls table_poll: Poll - table_actions: Polls status + table_status: Polls status + table_actions: Actions show: can_vote: Can vote error_already_voted: Has already participated in this poll + no_actions: There is no available actions submit: Confirm vote success: "Vote introduced!" can_vote: - submit_disable_with: "WAIT, confirming vote" + submit_disable_with: "Wait, confirming vote..." diff --git a/config/locales/es/officing.yml b/config/locales/es/officing.yml index c23b42568..86d6982fc 100644 --- a/config/locales/es/officing.yml +++ b/config/locales/es/officing.yml @@ -58,11 +58,13 @@ es: new: title: Votaciones table_poll: Votación - table_actions: Estado de las votaciones + table_status: Estado de las votaciones + table_actions: Acciones show: can_vote: Puede votar - error_already_voted: "Ya ha participado en esta votación." + error_already_voted: "Ya ha participado en esta votación" + no_actions: No hay acciones disponibles submit: Confirmar voto success: "¡Voto introducido!" can_vote: - submit_disable_with: "ESPERA, confirmando voto" \ No newline at end of file + submit_disable_with: "Espera, confirmando voto..." \ No newline at end of file From 5540f130e1b9b0b50c20961e8724075c9b808d1d Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 13 Oct 2017 14:16:33 +0200 Subject: [PATCH 038/211] removes unused partials --- .../officing/voters/_already_voted.html.erb | 7 ------- app/views/officing/voters/_can_vote.html.erb | 18 ------------------ 2 files changed, 25 deletions(-) delete mode 100644 app/views/officing/voters/_already_voted.html.erb delete mode 100644 app/views/officing/voters/_can_vote.html.erb diff --git a/app/views/officing/voters/_already_voted.html.erb b/app/views/officing/voters/_already_voted.html.erb deleted file mode 100644 index 1476913f9..000000000 --- a/app/views/officing/voters/_already_voted.html.erb +++ /dev/null @@ -1,7 +0,0 @@ -
-
-
- <%= t("officing.voters.show.error_already_voted") %> -
-
-
diff --git a/app/views/officing/voters/_can_vote.html.erb b/app/views/officing/voters/_can_vote.html.erb deleted file mode 100644 index b5c9663ac..000000000 --- a/app/views/officing/voters/_can_vote.html.erb +++ /dev/null @@ -1,18 +0,0 @@ -
-
-
- <%= t("officing.voters.show.can_vote") %> -
-
-
- <%= form_for @user, as: :voter, url: officing_voters_path, - method: :post, remote: true, - html: { id: "new_officing_voter" } do |f| %> - <%= f.hidden_field :poll_id, value: poll.id %> - <%= f.hidden_field :user_id, value: @user.id %> - <%= f.submit t("officing.voters.show.submit"), - class: "button success expanded", - data: { disable_with: t("officing.voters.can_vote.submit_disable_with") } %> - <% end %> -
-
From f94a3763920a2e93c33ddafbcb17cb280dbd51e1 Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 13 Oct 2017 14:16:46 +0200 Subject: [PATCH 039/211] updates text on specs --- spec/features/polls/voter_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/polls/voter_spec.rb b/spec/features/polls/voter_spec.rb index 41886653b..334696768 100644 --- a/spec/features/polls/voter_spec.rb +++ b/spec/features/polls/voter_spec.rb @@ -54,7 +54,7 @@ feature "Voter" do within("#poll_#{poll.id}") do click_button("Confirm vote") expect(page).to_not have_button("Confirm vote") - expect(page).to have_button('WAIT, confirming vote', disabled: true) + expect(page).to have_button('Wait, confirming vote...', disabled: true) expect(page).to have_content "Vote introduced!" end From 54068ce7cbdbebcb4bb148d2049ed152cb96500f Mon Sep 17 00:00:00 2001 From: iagirre Date: Fri, 13 Oct 2017 14:35:14 +0200 Subject: [PATCH 040/211] When answer 2 more info expand is clicked, it expands on top of the first one, not below. Same if the expand is clicked for the first answer --- app/assets/javascripts/polls.js.coffee | 16 ++++++++++++++++ app/views/polls/show.html.erb | 3 +-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/polls.js.coffee b/app/assets/javascripts/polls.js.coffee index 5cf792ce2..ac2c759ba 100644 --- a/app/assets/javascripts/polls.js.coffee +++ b/app/assets/javascripts/polls.js.coffee @@ -26,3 +26,19 @@ App.Polls = token_message.html(token_message.html() + "
" + @token + ""); token_message.show() false + + $(".zoom-link").on "click", (event) -> + element = event.target + answer = $(element).closest('div.answer') + + if $(answer).hasClass('medium-6') + $(answer).removeClass("medium-6"); + $(answer).addClass("answer-divider"); + unless $(answer).hasClass('first') + $(answer).insertBefore($(answer).prev('div.answer')); + else + $(answer).addClass("medium-6"); + $(answer).removeClass("answer-divider"); + unless $(answer).hasClass('first') + $(answer).insertAfter($(answer).next('div.answer')); + diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index d9d871249..f66973acd 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -80,8 +80,7 @@
<% @poll.questions.map(&:question_answers).flatten.each do |answer| %> -
+
<% if answer.description.present? %>

<%= answer.title %>

From 2c6c320fa1c3684f9e82535ed8253b2637710171 Mon Sep 17 00:00:00 2001 From: iagirre Date: Fri, 13 Oct 2017 14:35:14 +0200 Subject: [PATCH 041/211] When answer 2 more info expand is clicked, it expands on top of the first one, not below. Same if the expand is clicked for the first answer --- app/assets/javascripts/polls.js.coffee | 16 ++++++++++++++++ app/views/polls/show.html.erb | 3 +-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/polls.js.coffee b/app/assets/javascripts/polls.js.coffee index 5cf792ce2..ac2c759ba 100644 --- a/app/assets/javascripts/polls.js.coffee +++ b/app/assets/javascripts/polls.js.coffee @@ -26,3 +26,19 @@ App.Polls = token_message.html(token_message.html() + "
" + @token + ""); token_message.show() false + + $(".zoom-link").on "click", (event) -> + element = event.target + answer = $(element).closest('div.answer') + + if $(answer).hasClass('medium-6') + $(answer).removeClass("medium-6"); + $(answer).addClass("answer-divider"); + unless $(answer).hasClass('first') + $(answer).insertBefore($(answer).prev('div.answer')); + else + $(answer).addClass("medium-6"); + $(answer).removeClass("answer-divider"); + unless $(answer).hasClass('first') + $(answer).insertAfter($(answer).next('div.answer')); + diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index 0a56ba237..4489cd226 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -80,8 +80,7 @@
<% @poll_questions_answers.each do |answer| %> -
+
<% if answer.description.present? %>

<%= answer.title %>

From 6b721e7750559bcd73ccc854a5deb86267a3a71b Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 13 Oct 2017 14:40:39 +0200 Subject: [PATCH 042/211] moves table content to partials --- .../officing/voters/_already_voted.html.erb | 8 ++++++ app/views/officing/voters/_can_vote.html.erb | 16 ++++++++++++ app/views/officing/voters/new.html.erb | 26 ++----------------- 3 files changed, 26 insertions(+), 24 deletions(-) create mode 100644 app/views/officing/voters/_already_voted.html.erb create mode 100644 app/views/officing/voters/_can_vote.html.erb diff --git a/app/views/officing/voters/_already_voted.html.erb b/app/views/officing/voters/_already_voted.html.erb new file mode 100644 index 000000000..1af002b3f --- /dev/null +++ b/app/views/officing/voters/_already_voted.html.erb @@ -0,0 +1,8 @@ + +

+ <%= t("officing.voters.show.error_already_voted") %> +

+ + + <%= t("officing.voters.show.no_actions") %> + diff --git a/app/views/officing/voters/_can_vote.html.erb b/app/views/officing/voters/_can_vote.html.erb new file mode 100644 index 000000000..c179f854b --- /dev/null +++ b/app/views/officing/voters/_can_vote.html.erb @@ -0,0 +1,16 @@ + +

+ <%= t("officing.voters.show.can_vote") %> +

+ + + <%= form_for @user, as: :voter, url: officing_voters_path, + method: :post, remote: true, + html: { id: "new_officing_voter" } do |f| %> + <%= f.hidden_field :poll_id, value: poll.id %> + <%= f.hidden_field :user_id, value: @user.id %> + <%= f.submit t("officing.voters.show.submit"), + class: "button success", + data: { disable_with: t("officing.voters.can_vote.submit_disable_with") } %> + <% end %> + diff --git a/app/views/officing/voters/new.html.erb b/app/views/officing/voters/new.html.erb index 212a9d8f8..a6ab32d33 100644 --- a/app/views/officing/voters/new.html.erb +++ b/app/views/officing/voters/new.html.erb @@ -18,31 +18,9 @@ <%= poll.name %> <% if poll.votable_by?(@user) %> - -

- <%= t("officing.voters.show.can_vote") %> -

- - - <%= form_for @user, as: :voter, url: officing_voters_path, - method: :post, remote: true, - html: { id: "new_officing_voter" } do |f| %> - <%= f.hidden_field :poll_id, value: poll.id %> - <%= f.hidden_field :user_id, value: @user.id %> - <%= f.submit t("officing.voters.show.submit"), - class: "button success", - data: { disable_with: t("officing.voters.can_vote.submit_disable_with") } %> - <% end %> - + <%= render "can_vote", poll: poll %> <% else %> - -

- <%= t("officing.voters.show.error_already_voted") %> -

- - - <%= t("officing.voters.show.no_actions") %> - + <%= render "already_voted" %> <% end %> <% end %> From 99471a3d156bddacf0ee427a2470576f8444233a Mon Sep 17 00:00:00 2001 From: Bertocq Date: Fri, 13 Oct 2017 14:42:43 +0200 Subject: [PATCH 043/211] Comment out slug assignment until Poll slug feature is ported back from madrid's fork --- db/dev_seeds.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index eae15973c..6b80a0ec5 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -525,14 +525,14 @@ puts " ✅" print "Active Polls" (1..3).each do |i| poll = Poll.create(name: "Active Poll #{i}", - slug: "active-poll-#{i}", + # slug: "active-poll-#{i}", starts_at: 1.month.ago, ends_at: 1.month.from_now, geozone_restricted: false) end (1..5).each do |i| poll = Poll.create(name: "Active Poll #{i}", - slug: "active-poll-#{i}", + # slug: "active-poll-#{i}", starts_at: 1.month.ago, ends_at: 1.month.from_now, geozone_restricted: true, @@ -542,14 +542,14 @@ end puts " ✅" print "Upcoming Poll" poll = Poll.create(name: "Upcoming Poll", - slug: "upcoming-poll", + # slug: "upcoming-poll", starts_at: 1.month.from_now, ends_at: 2.months.from_now) puts " ✅" print "Expired Poll" poll = Poll.create(name: "Expired Poll", - slug: "expired-poll", + # slug: "expired-poll", starts_at: 2.months.ago, ends_at: 1.month.ago) From 234d4d3f54cb1825218347987387f9144b0e67a3 Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 13 Oct 2017 14:45:30 +0200 Subject: [PATCH 044/211] hides can vote callout when voted --- app/views/officing/voters/_can_vote.html.erb | 2 +- app/views/officing/voters/create.js.erb | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/views/officing/voters/_can_vote.html.erb b/app/views/officing/voters/_can_vote.html.erb index c179f854b..0d01f97fe 100644 --- a/app/views/officing/voters/_can_vote.html.erb +++ b/app/views/officing/voters/_can_vote.html.erb @@ -1,5 +1,5 @@ -

+

<%= t("officing.voters.show.can_vote") %>

diff --git a/app/views/officing/voters/create.js.erb b/app/views/officing/voters/create.js.erb index ee280faa2..964987a87 100644 --- a/app/views/officing/voters/create.js.erb +++ b/app/views/officing/voters/create.js.erb @@ -1 +1,2 @@ -$("#<%= dom_id(@poll) %> #actions").html('<%= j render("voted") %>'); \ No newline at end of file +$("#<%= dom_id(@poll) %> #actions").html('<%= j render("voted") %>'); +$("#can_vote_callout").hide(); From 200db22cbbf2d6269b7bc85b8329882a43c724b7 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 13 Oct 2017 15:15:54 +0200 Subject: [PATCH 045/211] only update the poll that was just voted --- app/views/officing/voters/create.js.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/officing/voters/create.js.erb b/app/views/officing/voters/create.js.erb index 964987a87..3837f017e 100644 --- a/app/views/officing/voters/create.js.erb +++ b/app/views/officing/voters/create.js.erb @@ -1,2 +1,2 @@ $("#<%= dom_id(@poll) %> #actions").html('<%= j render("voted") %>'); -$("#can_vote_callout").hide(); +$("#<%= dom_id(@poll) %> #can_vote_callout").hide(); \ No newline at end of file From 540e12a3ac690c919f04a616fb7ad0f3f8785c38 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Fri, 13 Oct 2017 16:47:47 +0200 Subject: [PATCH 046/211] Add RECOUNT_DURATION Poll constant for recount period duration --- app/helpers/shifts_helper.rb | 5 ++++- app/models/poll.rb | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/helpers/shifts_helper.rb b/app/helpers/shifts_helper.rb index dc9f97a91..7c2d5c1b3 100644 --- a/app/helpers/shifts_helper.rb +++ b/app/helpers/shifts_helper.rb @@ -5,7 +5,10 @@ module ShiftsHelper end def shift_recount_scrutiny_dates(polls) - date_options(polls.map(&:ends_at).map(&:to_date).sort.inject([]) { |total, date| total << (date..date + 1.week).to_a }.flatten.uniq) + dates = polls.map(&:ends_at).map(&:to_date).sort.inject([]) do |total, date| + total << (date..date + Poll::RECOUNT_DURATION).to_a + end + date_options(dates.flatten.uniq) end def date_options(dates) diff --git a/app/models/poll.rb b/app/models/poll.rb index 8675ce49a..c572a4765 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -2,6 +2,9 @@ class Poll < ActiveRecord::Base include Imageable acts_as_paranoid column: :hidden_at include ActsAsParanoidAliases + + RECOUNT_DURATION = 1.week + has_many :booth_assignments, class_name: "Poll::BoothAssignment" has_many :booths, through: :booth_assignments has_many :partial_results, through: :booth_assignments From ca2d9a1d688ac24656d1be57eb01a1992b0489ae Mon Sep 17 00:00:00 2001 From: Bertocq Date: Fri, 13 Oct 2017 16:48:25 +0200 Subject: [PATCH 047/211] Add recounting Poll scope with trait and spec --- app/models/poll.rb | 1 + spec/factories.rb | 5 +++++ spec/models/poll/poll_spec.rb | 16 ++++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/app/models/poll.rb b/app/models/poll.rb index c572a4765..41d4a9ab9 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -25,6 +25,7 @@ class Poll < ActiveRecord::Base scope :current, -> { where('starts_at <= ? and ? <= ends_at', Date.current.beginning_of_day, Date.current.beginning_of_day) } scope :incoming, -> { where('? < starts_at', Date.current.beginning_of_day) } scope :expired, -> { where('ends_at < ?', Date.current.beginning_of_day) } + scope :recounting, -> { Poll.where(ends_at: (Date.current.beginning_of_day - RECOUNT_DURATION)..Date.current.beginning_of_day) } scope :published, -> { where('published = ?', true) } scope :by_geozone_id, ->(geozone_id) { where(geozones: {id: geozone_id}.joins(:geozones)) } diff --git a/spec/factories.rb b/spec/factories.rb index 69aa92c62..b1c5ff329 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -489,6 +489,11 @@ FactoryGirl.define do ends_at { 15.days.ago } end + trait :recounting do + starts_at { 1.month.ago } + ends_at { Date.current } + end + trait :published do published true end diff --git a/spec/models/poll/poll_spec.rb b/spec/models/poll/poll_spec.rb index 5083d7439..dba964928 100644 --- a/spec/models/poll/poll_spec.rb +++ b/spec/models/poll/poll_spec.rb @@ -76,6 +76,22 @@ describe :poll do end end + describe "#recounting" do + it "returns polls in recount & scrutiny phase" do + current = create(:poll, :current) + incoming = create(:poll, :incoming) + expired = create(:poll, :expired) + recounting = create(:poll, :recounting) + + recounting_polls = Poll.recounting + + expect(recounting_polls).to_not include(current) + expect(recounting_polls).to_not include(incoming) + expect(recounting_polls).to_not include(expired) + expect(recounting_polls).to include(recounting) + end + end + describe "answerable_by" do let(:geozone) {create(:geozone) } From 9146d68c5342fc358cf52d3bd7bcf8b2345b35fe Mon Sep 17 00:00:00 2001 From: Bertocq Date: Fri, 13 Oct 2017 16:53:03 +0200 Subject: [PATCH 048/211] Add current_or_recounting_or_incoming method to Poll model --- app/models/poll.rb | 4 ++++ spec/models/poll/poll_spec.rb | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/app/models/poll.rb b/app/models/poll.rb index 41d4a9ab9..5c65b688f 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -51,6 +51,10 @@ class Poll < ActiveRecord::Base current + incoming end + def self.current_or_recounting_or_incoming + current + recounting + incoming + end + def answerable_by?(user) user.present? && user.level_two_or_three_verified? && diff --git a/spec/models/poll/poll_spec.rb b/spec/models/poll/poll_spec.rb index dba964928..bfb5881f2 100644 --- a/spec/models/poll/poll_spec.rb +++ b/spec/models/poll/poll_spec.rb @@ -92,6 +92,22 @@ describe :poll do end end + describe "#current_or_recounting_or_incoming" do + it "returns current or recounting or incoming polls" do + current = create(:poll, :current) + incoming = create(:poll, :incoming) + expired = create(:poll, :expired) + recounting = create(:poll, :recounting) + + current_or_recounting_or_incoming = Poll.current_or_recounting_or_incoming + + expect(current_or_recounting_or_incoming).to include(current) + expect(current_or_recounting_or_incoming).to include(recounting) + expect(current_or_recounting_or_incoming).to include(incoming) + expect(current_or_recounting_or_incoming).to_not include(expired) + end + end + describe "answerable_by" do let(:geozone) {create(:geozone) } From 79c8c2f826dc53eb4ca1219c65d8efc4f36f9c57 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Fri, 13 Oct 2017 16:55:40 +0200 Subject: [PATCH 049/211] Add scope on shift creation date ranges to current/recounting/incoming polls, plus cover with test --- app/views/admin/poll/shifts/_form.html.erb | 4 ++-- spec/features/admin/poll/shifts_spec.rb | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/views/admin/poll/shifts/_form.html.erb b/app/views/admin/poll/shifts/_form.html.erb index 1a13edf45..4004a949b 100644 --- a/app/views/admin/poll/shifts/_form.html.erb +++ b/app/views/admin/poll/shifts/_form.html.erb @@ -24,12 +24,12 @@
<%= select 'shift[date]', 'vote_collection_date', - options_for_select(shift_vote_collection_dates(@booth.polls)), + options_for_select(shift_vote_collection_dates(@booth.polls.current_or_incoming)), { prompt: t("admin.poll_shifts.new.select_date"), label: false }, class: 'js-shift-vote-collection-dates' %> <%= select 'shift[date]', 'recount_scrutiny_date', - options_for_select(shift_recount_scrutiny_dates(@booth.polls)), + options_for_select(shift_recount_scrutiny_dates(@booth.polls.current_or_recounting_or_incoming)), { prompt: t("admin.poll_shifts.new.select_date"), label: false }, class: 'js-shift-recount-scrutiny-dates', diff --git a/spec/features/admin/poll/shifts_spec.rb b/spec/features/admin/poll/shifts_spec.rb index 2ac290216..edefd0844 100644 --- a/spec/features/admin/poll/shifts_spec.rb +++ b/spec/features/admin/poll/shifts_spec.rb @@ -35,7 +35,8 @@ feature 'Admin shifts' do create(:poll, :incoming) poll = create(:poll, :current) booth = create(:poll_booth) - assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + create(:poll_booth_assignment, poll: poll, booth: booth) + create(:poll_booth_assignment, poll: create(:poll, :expired), booth: booth) officer = create(:poll_officer) vote_collection_dates = (poll.starts_at.to_date..poll.ends_at.to_date).to_a.map { |date| I18n.l(date, format: :long) } recount_scrutiny_dates = (poll.ends_at.to_date..poll.ends_at.to_date + 1.week).to_a.map { |date| I18n.l(date, format: :long) } From 16f499d5fd732578bc5fd138b97659da9d7c5eb7 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Fri, 13 Oct 2017 17:19:11 +0200 Subject: [PATCH 050/211] Force shift dates to start on current date at minimun --- app/helpers/shifts_helper.rb | 6 ++++-- spec/features/admin/poll/shifts_spec.rb | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/helpers/shifts_helper.rb b/app/helpers/shifts_helper.rb index 7c2d5c1b3..5c99bad66 100644 --- a/app/helpers/shifts_helper.rb +++ b/app/helpers/shifts_helper.rb @@ -6,7 +6,8 @@ module ShiftsHelper def shift_recount_scrutiny_dates(polls) dates = polls.map(&:ends_at).map(&:to_date).sort.inject([]) do |total, date| - total << (date..date + Poll::RECOUNT_DURATION).to_a + initial_date = date < Date.current ? Date.current : date + total << (initial_date..date + Poll::RECOUNT_DURATION).to_a end date_options(dates.flatten.uniq) end @@ -16,7 +17,8 @@ module ShiftsHelper end def start_date(polls) - polls.map(&:starts_at).min.to_date + start_date = polls.map(&:starts_at).min.to_date + start_date < Date.current ? Date.current : start_date end def end_date(polls) diff --git a/spec/features/admin/poll/shifts_spec.rb b/spec/features/admin/poll/shifts_spec.rb index edefd0844..7512d8b6d 100644 --- a/spec/features/admin/poll/shifts_spec.rb +++ b/spec/features/admin/poll/shifts_spec.rb @@ -38,7 +38,7 @@ feature 'Admin shifts' do create(:poll_booth_assignment, poll: poll, booth: booth) create(:poll_booth_assignment, poll: create(:poll, :expired), booth: booth) officer = create(:poll_officer) - vote_collection_dates = (poll.starts_at.to_date..poll.ends_at.to_date).to_a.map { |date| I18n.l(date, format: :long) } + vote_collection_dates = (Date.current..poll.ends_at.to_date).to_a.map { |date| I18n.l(date, format: :long) } recount_scrutiny_dates = (poll.ends_at.to_date..poll.ends_at.to_date + 1.week).to_a.map { |date| I18n.l(date, format: :long) } visit available_admin_booths_path @@ -53,14 +53,14 @@ feature 'Admin shifts' do expect(page).to have_select('shift_date_vote_collection_date', options: ["Select day", *vote_collection_dates]) expect(page).not_to have_select('shift_date_recount_scrutiny_date') - select I18n.l(poll.starts_at.to_date, format: :long), from: 'shift_date_vote_collection_date' + select I18n.l(Date.current, format: :long), from: 'shift_date_vote_collection_date' click_button "Add shift" expect(page).to have_content "Shift added" within("#shifts") do expect(page).to have_css(".shift", count: 1) - expect(page).to have_content(I18n.l(poll.starts_at.to_date, format: :long)) + expect(page).to have_content(I18n.l(Date.current, format: :long)) expect(page).to have_content("Collect Votes") expect(page).to have_content(officer.name) end From 36a1e4a37671bc0afbffb44f3f1ba53877efe0e6 Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 13 Oct 2017 17:41:09 +0200 Subject: [PATCH 051/211] fixes admin polls index table --- app/views/admin/poll/polls/index.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/poll/polls/index.html.erb b/app/views/admin/poll/polls/index.html.erb index 791ec4876..487f0fa54 100644 --- a/app/views/admin/poll/polls/index.html.erb +++ b/app/views/admin/poll/polls/index.html.erb @@ -7,7 +7,7 @@ <% if @polls.any? %> - + From bf5021c6a506a3e193b25634b447b7c3bd1239ec Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 13 Oct 2017 18:11:41 +0200 Subject: [PATCH 052/211] changes back link to available booths when manage shifts --- app/views/admin/poll/shifts/new.html.erb | 2 +- spec/features/admin/poll/booths_spec.rb | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/views/admin/poll/shifts/new.html.erb b/app/views/admin/poll/shifts/new.html.erb index b975c40a9..4e0665ea2 100644 --- a/app/views/admin/poll/shifts/new.html.erb +++ b/app/views/admin/poll/shifts/new.html.erb @@ -1,4 +1,4 @@ -<%= back_link_to admin_booths_path %> +<%= back_link_to available_admin_booths_path %>

<%= @booth.name %>

diff --git a/spec/features/admin/poll/booths_spec.rb b/spec/features/admin/poll/booths_spec.rb index 4eeb81cb6..1aa487b26 100644 --- a/spec/features/admin/poll/booths_spec.rb +++ b/spec/features/admin/poll/booths_spec.rb @@ -113,4 +113,18 @@ feature 'Admin booths' do end end + scenario "Back link go back to available list when manage shifts" do + poll = create(:poll, :current) + booth = create(:poll_booth) + assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + + visit available_admin_booths_path + + within("#booth_#{booth.id}") do + click_link "Manage shifts" + end + + click_link "Go back" + expect(current_path).to eq(available_admin_booths_path) + end end From f2d99d6747027f3c12ff860ea0d1c82ea8f671eb Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 13 Oct 2017 18:39:13 +0200 Subject: [PATCH 053/211] searches for officers assigned to a poll --- .../poll/officer_assignments_controller.rb | 4 +- .../poll/officer_assignments/index.html.erb | 2 +- .../admin/poll/officer_assignments_spec.rb | 68 +++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 spec/features/admin/poll/officer_assignments_spec.rb diff --git a/app/controllers/admin/poll/officer_assignments_controller.rb b/app/controllers/admin/poll/officer_assignments_controller.rb index fd62df8b3..7532362a7 100644 --- a/app/controllers/admin/poll/officer_assignments_controller.rb +++ b/app/controllers/admin/poll/officer_assignments_controller.rb @@ -25,7 +25,9 @@ class Admin::Poll::OfficerAssignmentsController < Admin::Poll::BaseController def search_officers load_search - @officers = User.joins(:poll_officer).search(@search).order(username: :asc) + + poll_officers = User.where(id: @poll.officers.pluck(:user_id)) + @officers = poll_officers.search(@search).order(username: :asc) respond_to do |format| format.js diff --git a/app/views/admin/poll/officer_assignments/index.html.erb b/app/views/admin/poll/officer_assignments/index.html.erb index f27f6b2ae..04e296980 100644 --- a/app/views/admin/poll/officer_assignments/index.html.erb +++ b/app/views/admin/poll/officer_assignments/index.html.erb @@ -11,7 +11,7 @@ <%= t("admin.poll_officer_assignments.index.no_officers") %> <% else %> -
<%= t("admin.polls.index.name") %><%= t("admin.polls.index.name") %> <%= t("admin.polls.index.dates") %> <%= t("admin.actions.actions") %>
+
diff --git a/spec/features/admin/poll/officer_assignments_spec.rb b/spec/features/admin/poll/officer_assignments_spec.rb new file mode 100644 index 000000000..20be138b9 --- /dev/null +++ b/spec/features/admin/poll/officer_assignments_spec.rb @@ -0,0 +1,68 @@ +require 'rails_helper' + +feature 'Officer Assignments' do + + background do + admin = create(:administrator) + login_as(admin.user) + end + + scenario "Index" do + poll = create(:poll) + booth = create(:poll_booth) + + officer1 = create(:poll_officer) + officer2 = create(:poll_officer) + officer3 = create(:poll_officer) + + booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + officer_assignment = create(:poll_officer_assignment, booth_assignment: booth_assignment, officer: officer1) + + booth_assignment_2 = create(:poll_booth_assignment, poll: poll) + officer_assignment_2 = create(:poll_officer_assignment, booth_assignment: booth_assignment_2, officer: officer2) + + visit admin_poll_path(poll) + + click_link 'Officers (2)' + + within('#officer_assignments') do + expect(page).to have_content officer1.name + expect(page).to have_content officer2.name + expect(page).to_not have_content officer3.name + end + end + + scenario "Search", :js do + poll = create(:poll) + booth = create(:poll_booth) + + user1 = create(:user, username: "John Snow") + user2 = create(:user, username: "John Silver") + user3 = create(:user, username: "John Edwards") + + officer1 = create(:poll_officer, user: user1) + officer2 = create(:poll_officer, user: user2) + officer3 = create(:poll_officer, user: user3) + + booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + officer_assignment = create(:poll_officer_assignment, booth_assignment: booth_assignment, officer: officer1) + + booth_assignment_2 = create(:poll_booth_assignment, poll: poll) + officer_assignment_2 = create(:poll_officer_assignment, booth_assignment: booth_assignment_2, officer: officer2) + + visit admin_poll_path(poll) + + click_link 'Officers (2)' + + fill_in "search-officers", with: "John" + click_button "Search" + + within('#search-officers-results') do + expect(page).to have_content officer1.name + expect(page).to have_content officer2.name + expect(page).to_not have_content officer3.name + end + end + + +end \ No newline at end of file From 96bd8cec003d8b8e96b6123d1205007b8df64cbd Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 13 Oct 2017 18:54:26 +0200 Subject: [PATCH 054/211] fixes styles on admin legislation processes subnav --- .../legislation/processes/_subnav.html.erb | 38 ++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/app/views/admin/legislation/processes/_subnav.html.erb b/app/views/admin/legislation/processes/_subnav.html.erb index 97640c4f4..f8e9bba56 100644 --- a/app/views/admin/legislation/processes/_subnav.html.erb +++ b/app/views/admin/legislation/processes/_subnav.html.erb @@ -1,11 +1,31 @@ From 2e6072ef19c372c880a439f9e1c2bb109308f6a0 Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 13 Oct 2017 18:54:48 +0200 Subject: [PATCH 055/211] adds missing icons on admin menu --- app/assets/fonts/icons.eot | Bin 12528 -> 14024 bytes app/assets/fonts/icons.svg | 5 +++++ app/assets/fonts/icons.ttf | Bin 12372 -> 13868 bytes app/assets/fonts/icons.woff | Bin 9352 -> 10236 bytes app/assets/stylesheets/icons.scss | 20 ++++++++++++++++++++ app/views/admin/_menu.html.erb | 6 ++++-- 6 files changed, 29 insertions(+), 2 deletions(-) diff --git a/app/assets/fonts/icons.eot b/app/assets/fonts/icons.eot index 5564a5c62a83883cf5911bcc08931452d8ca3931..53439b28145908023bc4579be8476a0643412c40 100644 GIT binary patch delta 2085 zcmZuyO>7%Q6n?Wmv+LbBcH-T2+9vg1;?OvD)7ai^o1dmtC~_r;#7`k@C1f0@L9v}Q zN!w6W7=c7{s06J~sN$y*l@JmLs3-^iE`UN*E=6!jT5*X47gP>Z;^OdT>^LdH(aya0 zy>H&k`}Sq_es;M?mu-Mv`wF$C_0sjpDbm67Rb5EWr07!2F#M`Fw z*$H>-;xxwA@Uf>5kow4PxYj_wbE>$oSk@oV5CWedaJev(%NE5K4q^fo{nv}x#aXxl zpJRMK`oU7Rn1A)Bmq!8ieSp}R*_ru;Z$3&c0VLb;P%A)?h0o;m()#nB!M{Nl5CHg< zzWv4Kys?VRE{>}pK#~*KA`T@4*jU|I6}ot;TC6ro9617?fxB{#JWE0qTevn}!gO8u z2TTS2wAWXDhaNjlJ4k?sg(hIzNoa-O0Gxmes2ux+pbrj1mU}@^IEL#gJH@wl9OhnQ zaP}WKI50Rgd}!q6ZE=(|89x|RbICHS%K$gM^7Zbrn{ml1mf`{*bU+WJF!>X35{hsU z-hg)ib+%K{utE*1-?3BO(J(dqR)4f%S!hK#nCy3=4Qe+dDAZ(RyT)NTkkg1*{bk4Y zr}=t?b`Ydu*kvF6GGuSA%qOG!C)(Fr^QfcBovOOTT*s1)bF=S)^1%hg4&{{ z@3wR;IF65j_FuZ*>_Ncm(Q+8p%gD=NOw$-~Ro6UTO}9MFdQL-7XIa)bTd##mTMWHK zCAE50)ntW|k|I;a(>2ZQ_E?=bR!bhs@{p@;w|0=9!Dys>t#&wlJXo&np)K;$S^845 zUf;=@sUJ#T@@NS1W8W@eHcj`G_(p$h1*S6!l{Gb^%CbzK-b(U)^%yUR++tO;mMuXS zxk^^SjeP{9yzM19wqtk*RcN?7x|c-LDaS@7NyfAWEt3x!*Oa6wZHgvMxneyRdSWCK zF!2}Y@SCQ;BVgQhQQY5k*9Z*7dU|5mS|V$Ap^IRY}4M z)``XOsqRSvsi1Pa&6 zRI5#+nTLGVeGyx9Z%gdb=28QBW^Y;r;5JZ6#lGE9xV6wpAsFkN?+e zC{X#hcTaa1X6u)}gayA_w`I`b>$*)5|D{sx4Rw#=os1s_$%UT+4Jvh81`BS~ZHoAh zm80>KWMAdIcrT8(0BC7y zZ^zwgrQL>3|E;uljZfaZ*1NRp6=2kWzJ=nLdv)_R{|RkPu1t}FVT+%P-A>+H^lMXf z>x$V!;VFgNlV#6M?#=E2^xx#Se0QpXIXtIbHJB*5{#b1A?h=q>0#T}ztF`o|Z#3<{ z!=~mS2)Wj0muD_-$^C+*Q2;*wxj*{vY`5qc3-m5%Z~_Mv6i5d&v|H_#77J2!Y@OW* zlsulnl3&F+Vats6@FY8>S*>^&@tRDv5r=^Vp50JoRPsZ(fN9Q4eKwB44e*A53)!zf zkSk8qLUv&A@R6KS8%=#kG?J0WeR4RpyWWFRSi?XBk3t-Qg_j{Vsee-Sjg3^gnWBR= zL=g+Ij^pSLu|c1EA&y`N7DH@Oe}@TpD6?i2nDELa`8{U|6sDe3j+>L-KO-% + + + + + diff --git a/app/assets/fonts/icons.ttf b/app/assets/fonts/icons.ttf index 6af0797fb5fe1f6a0dee2d96adbaa03fea58f23c..3bd8e9decc304003e191744344212d5645d1b714 100644 GIT binary patch delta 2128 zcmZuyO>7%Q6n?Wmv+Ld1j^o{RN|X98acCT;X>9Md%}>)R6uGDbK`EqE0^>MM75}73 z+M24WD?l^{B%nS)RZu00IDmwxXeAJE0aPNml%Gpd#HA8k5FDt)#o^6*=>N* z?AVt8|I{4yKbt_QS{EuI(pJk#OxTa(S|Z z*}Cxuj0OAO;Y5Cg8soYH1i;Ng3$WD$l)|tZj>1`Fjy+)*fPIj)wGc?Q4dZI(xi`1$ zv$f`6?b^L(Xn16F@7VPLew?&u-)MDx$^Q3GHD3iRuh&HZUv)VwxUf zuxgosv>h+ePJ&Q$o6H}zLv7Wv0pW-P2qQvoB3OiJ`80_}!;x6pmok&#!GKXRwyBC1 zQYwnN%}|xlB>pv&|58sD{_0<`gulEX%5mRvWI; z20|@SL9Snt6;Yz3B#D&aR7G*Sy+#*~^^(^xyyTMGt?aS)pfyvz)YzOl8LBqcP%8HB z40Xw)Ix87vXH)8uS3#q_?e9vMO;Noid!gSq9J3jTii(_(MNy=OHtD6qVGA+$Zs6-<@u^l9qPFW^0Niw=IZ0Pooam@&d)GjH)j4R%I zwl_{PK^>o9XF%5jok8u6i{kpOJ6dog-rF0;*5X;abKUlW7EA;9F*{40#M~OK2H1=z zPvb<#LyQx2kC12t2Luff1|1@Z(IxDTA)+@R>6Do^al@ko2Rm1zb!^%0oooG}P$;;g zKNuRjJ0)^F6{dJjutbi_^Ax2##|su;<@wvlXQnOqPnV_>j^jn4RZ%=XuOzhV{*JAh z9uR4)eGGXg5Q_9ASk_}>-F7sc5_pai_$kU;DCGr?$IRF8SjIhmEh=h)rg~dF9WDiF zX_IByv@_Wx|;mP|!iR_hm3S+1f$pvB!vV+CHA%`*h$6omxK0g{)PXnMI2^HgiKdZ-&P5Ft}xm5eK?-8=ICM5cB97sG_dpQv%`)ltd&MIVx43iNu zO7>n4_5VRkC6_JaP8G6?<#`1^=80l6X-+X delta 606 zcmZ3Jb0wjkfsuiMftR6yftew|%`L>Y!r*)v1A~DDP*ld<#np`=i-8TumjLn={Dbw4 z{7=Q~XJBBA0P@3D3OgB+-kmzbL>WZ8R|fk6kTpE0i>zqrJN=P6K1w*}~^ zF0ki-9{k&Wq%EG`<|_j?6HtzU;p)$6!4TSITJZmOK&3)p2@VE`JkTtl7)XU46T|;^ z|KBkQfsF!*zyJ$a#Fk+b1NUSn#&AZ1$+H+|djeewQ~<&a1PmA)84|&4b}*lDav#&o$@<28+zjRxmR8m_AkobZ%r184{8Ss11rNED4Ugmn_(A}%?1>|H2IsMqPi1<7RVheoIqD_F-(B6SsBC_ z7D3r;K=EUfFB%C?4m9$ZJljZn@^Pck$+E@@jJA{QjH@;uGJeN6`I)J_x((297NBb& UK?U*}!x`H}=Rq_gT&D#C04sucU;qFB diff --git a/app/assets/fonts/icons.woff b/app/assets/fonts/icons.woff index 7f8f3c95e81bff9ad949c7b630da7ecfa6e4e196..0ac7f8f19cfa02f884464c3f30b0cf2f98865ef2 100644 GIT binary patch literal 10236 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 diff --git a/app/assets/stylesheets/icons.scss b/app/assets/stylesheets/icons.scss index 96eb10a0d..dc59d1118 100644 --- a/app/assets/stylesheets/icons.scss +++ b/app/assets/stylesheets/icons.scss @@ -268,3 +268,23 @@ .icon-search-minus::before { content: '\35'; } + +.icon-calculator::before { + content: "\36"; +} + +.icon-map-marker::before { + content: "\37"; +} + +.icon-user-plus::before { + content: "\38"; +} + +.icon-file-text-o::before { + content: "\39"; +} + +.icon-file-text::before { + content: "\21"; +} diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 21dc7cffb..f2af2c116 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -136,7 +136,7 @@ <% if feature?(:legislation) %>
  • "> <%= link_to admin_legislation_processes_path do %> - + <%= t("admin.menu.legislation") %> <% end %>
  • @@ -156,7 +156,7 @@
  • - + <%= t("admin.menu.title_site_customization") %>
      "> <%= link_to admin_geozones_path do %> + <%= t('admin.menu.geozones') %> <% end %> @@ -185,6 +186,7 @@ <% if feature?(:signature_sheets) %>
    • "> <%= link_to admin_signature_sheets_path do %> + <%= t("admin.menu.signature_sheets") %> <% end %>
    • From 127ae893fcefe2df55253209c8d28c23575115a2 Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 13 Oct 2017 18:55:14 +0200 Subject: [PATCH 056/211] replaces polls and budgets help icons to add consistency --- app/assets/images/help/help_icon_budgets.png | Bin 2273 -> 1456 bytes app/assets/images/help/help_icon_polls.png | Bin 2051 -> 1683 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/app/assets/images/help/help_icon_budgets.png b/app/assets/images/help/help_icon_budgets.png index fc5e3022fc45e78cb6742678c93cc5e9ec580faf..f986a939c54fb097dcb50d96900b9f61a8cb3117 100644 GIT binary patch delta 633 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 Date: Fri, 13 Oct 2017 18:58:58 +0200 Subject: [PATCH 057/211] removes unnecessary helper for welcome page --- app/helpers/welcome_helper.rb | 4 ---- app/views/welcome/index.html.erb | 5 ++--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/app/helpers/welcome_helper.rb b/app/helpers/welcome_helper.rb index 9f8c8c13e..fe1c5f450 100644 --- a/app/helpers/welcome_helper.rb +++ b/app/helpers/welcome_helper.rb @@ -55,8 +55,4 @@ module WelcomeHelper end end - def highlight_background - (feature?("user.recommendations") && current_user) ? "highlight" : "" - end - end diff --git a/app/views/welcome/index.html.erb b/app/views/welcome/index.html.erb index 0ea0f748d..e27f4436e 100644 --- a/app/views/welcome/index.html.erb +++ b/app/views/welcome/index.html.erb @@ -22,12 +22,12 @@ <%= render "recommended", recommended_debates: @recommended_debates, recommended_proposals: @recommended_proposals %> +
      <% end %> <% cache [locale_and_user_status, @featured_debates, @featured_proposals, 'featured'] do %>
      - -
      +

      <%= t("welcome.debates.title") %>

      @@ -47,6 +47,5 @@
      -
      <% end %> From ae74e1ba07ddc7bacfbc8bbd05a18d19e70229d6 Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 13 Oct 2017 19:31:02 +0200 Subject: [PATCH 058/211] improves admin tags layout --- app/views/admin/tags/index.html.erb | 33 +++++++++++++++-------------- config/locales/en/admin.yml | 5 +++-- config/locales/es/admin.yml | 5 +++-- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/app/views/admin/tags/index.html.erb b/app/views/admin/tags/index.html.erb index f22321f38..787fad46a 100644 --- a/app/views/admin/tags/index.html.erb +++ b/app/views/admin/tags/index.html.erb @@ -1,39 +1,40 @@

      <%= t("admin.tags.index.add_tag") %>

      <%= form_for(@tag, url: admin_tags_path, as: :tag) do |f| %> - -
      -
      - <%= f.label :name, t("admin.tags.name.placeholder") %> - <%= f.text_field :name, placeholder: t("admin.tags.name.placeholder"), label: false %> -
      - +
      + <%= f.label :name, t("admin.tags.name.placeholder") %> + <%= f.text_field :name, placeholder: t("admin.tags.name.placeholder"), label: false %>
      <%= f.submit(t("admin.tags.create"), class: "button success") %> - <% end %> -

      <%= t("admin.tags.index.title") %>: <%= page_entries_info @tags %>

      +
      +

      <%= t("admin.tags.index.title") %>: <%= page_entries_info @tags %>

  • <%= t("admin.poll_officer_assignments.index.table_name") %> <%= t("admin.poll_officer_assignments.index.table_email") %>
    + + + + + <% @tags.each do |tag| %> - + <% end %> +
    <%= t("admin.tags.index.title") %><%= t("admin.actions.actions") %>
    + <%= form_for(tag, url: admin_tag_path(tag), as: :tag, - html: { id: "edit_tag_#{tag.id}", class: "text-right"}) do |f| %> + html: { id: "edit_tag_#{tag.id}"}) do |f| %> - - <%= tag.name %> - - - <%= link_to t("admin.tags.destroy"), admin_tag_path(tag), method: :delete, class: "button hollow alert on-hover" %> + <%= tag.name %> <% end %> + <%= link_to t("admin.tags.destroy"), admin_tag_path(tag), method: :delete, class: "button hollow alert" %> +
    <%= paginate @tags %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index dfe92305d..cf1f83a2a 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -901,11 +901,12 @@ en: total: Total proposals_with_notifications: Proposals with notifications tags: - create: Create Topic - destroy: Destroy Topic + create: Create topic + destroy: Destroy topic index: add_tag: Add a new proposal topic title: Proposal topics + topic: Topic name: placeholder: Type the name of the topic users: diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 289546bab..a4a377854 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -903,11 +903,12 @@ es: total: Total proposals_with_notifications: Propuestas con notificaciones tags: - create: Crear Tema - destroy: Eliminar Tema + create: Crear tema + destroy: Eliminar tema index: add_tag: Añade un nuevo tema de propuesta title: Temas de propuesta + topic: Tema name: placeholder: Escribe el nombre del tema users: From d91388b2b3464c3c4b524607a48a0fd7245e82c3 Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 13 Oct 2017 20:57:19 +0200 Subject: [PATCH 059/211] improves layout and unifies design of admin moderated content --- app/views/admin/comments/index.html.erb | 68 ++++++++++------- app/views/admin/debates/index.html.erb | 68 ++++++++++------- app/views/admin/hidden_users/index.html.erb | 62 ++++++++------- app/views/admin/proposals/index.html.erb | 84 ++++++++++++--------- config/locales/en/admin.yml | 8 ++ config/locales/es/admin.yml | 8 ++ 6 files changed, 182 insertions(+), 116 deletions(-) diff --git a/app/views/admin/comments/index.html.erb b/app/views/admin/comments/index.html.erb index 75493857c..e07487bcf 100644 --- a/app/views/admin/comments/index.html.erb +++ b/app/views/admin/comments/index.html.erb @@ -2,34 +2,46 @@ <%= render 'shared/filter_subnav', i18n_namespace: "admin.comments.index" %> -

    <%= page_entries_info @comments %>

    +<% if @comments.any? %> +

    <%= page_entries_info @comments %>

    - - <% @comments.each do |comment| %> - - - + + <% end %> + +
    - <%= text_with_links comment.body %>
    - <% if comment.commentable.hidden? %> - (<%= t("admin.comments.index.hidden_#{comment.commentable_type.downcase}") %>: <%= comment.commentable.title %>) - <% else %> - <%= link_to comment.commentable.title, comment.commentable %> - <% end %> -
    - <%= link_to t("admin.actions.restore"), - restore_admin_comment_path(comment, request.query_parameters), - method: :put, - data: { confirm: t("admin.actions.confirm") }, - class: "button hollow on-hover-block" %> - <% unless comment.confirmed_hide? %> - <%= link_to t("admin.actions.confirm_hide"), - confirm_hide_admin_comment_path(comment, request.query_parameters), + + + + + + + <% @comments.each do |comment| %> + + + - - <% end %> -
    <%= t("admin.shared.description") %><%= t("admin.shared.actions") %>
    + <%= text_with_links comment.body %>
    + <% if comment.commentable.hidden? %> + (<%= t("admin.comments.index.hidden_#{comment.commentable_type.downcase}") %>: <%= comment.commentable.title %>) + <% else %> + <%= link_to comment.commentable.title, comment.commentable %> + <% end %> +
    + <%= link_to t("admin.actions.restore"), + restore_admin_comment_path(comment, request.query_parameters), method: :put, - class: "button hollow warning on-hover-block" %> - <% end %> -
    + data: { confirm: t("admin.actions.confirm") }, + class: "button hollow warning" %> + <% unless comment.confirmed_hide? %> + <%= link_to t("admin.actions.confirm_hide"), + confirm_hide_admin_comment_path(comment, request.query_parameters), + method: :put, + class: "button" %> + <% end %> +
    -<%= paginate @comments %> + <%= paginate @comments %> +<% else %> +
    + <%= t("admin.comments.index.no_hidden_comments") %> +
    +<% end %> diff --git a/app/views/admin/debates/index.html.erb b/app/views/admin/debates/index.html.erb index 987aa6e72..7715e1032 100644 --- a/app/views/admin/debates/index.html.erb +++ b/app/views/admin/debates/index.html.erb @@ -2,33 +2,47 @@ <%= render 'shared/filter_subnav', i18n_namespace: "admin.debates.index" %> -

    <%= page_entries_info @debates %>

    +<% if @debates.any? %> +

    <%= page_entries_info @debates %>

    - - <% @debates.each do |debate| %> - - - + + <% end %> + +
    - <%= debate.title %> -
    -
    - <%= debate.description %> -
    -
    - <%= link_to t("admin.actions.restore"), - restore_admin_debate_path(debate, request.query_parameters), - method: :put, - data: { confirm: t("admin.actions.confirm") }, - class: "button hollow on-hover" %> - <% unless debate.confirmed_hide? %> - <%= link_to t("admin.actions.confirm_hide"), - confirm_hide_admin_debate_path(debate, request.query_parameters), + + + + + + + + <% @debates.each do |debate| %> + + + + - - <% end %> -
    <%= t("admin.shared.title") %><%= t("admin.shared.description") %><%= t("admin.shared.actions") %>
    + <%= debate.title %> + +
    + <%= debate.description %> +
    +
    + <%= link_to t("admin.actions.restore"), + restore_admin_debate_path(debate, request.query_parameters), method: :put, - class: "button hollow warning on-hover" %> - <% end %> -
    + data: { confirm: t("admin.actions.confirm") }, + class: "button hollow warning" %> + <% unless debate.confirmed_hide? %> + <%= link_to t("admin.actions.confirm_hide"), + confirm_hide_admin_debate_path(debate, request.query_parameters), + method: :put, + class: "button" %> + <% end %> +
    -<%= paginate @debates %> + <%= paginate @debates %> +<% else %> +
    + <%= t("admin.debates.index.no_hidden_debates") %> +
    +<% end %> diff --git a/app/views/admin/hidden_users/index.html.erb b/app/views/admin/hidden_users/index.html.erb index 21bf016e4..6bcea253c 100644 --- a/app/views/admin/hidden_users/index.html.erb +++ b/app/views/admin/hidden_users/index.html.erb @@ -2,32 +2,42 @@ <%= render 'shared/filter_subnav', i18n_namespace: "admin.hidden_users.index" %> -

    <%= page_entries_info @users %>

    +<% if @users.any? %> +

    <%= page_entries_info @users %>

    - -<% @users.each do |user| %> - - +
    -

    <%= link_to user.name, admin_hidden_user_path(user) %>

    -
    + + + + + + <% @users.each do |user| %> + + - - + + + <% end %> + +
    <%= t("admin.hidden_users.index.user") %><%= t("admin.shared.actions") %>
    +

    <%= link_to user.name, admin_hidden_user_path(user) %>

    +
    - <%= link_to t("admin.actions.restore"), - restore_admin_hidden_user_path(user, request.query_parameters), - method: :put, - data: { confirm: t("admin.actions.confirm") }, - class: "button hollow on-hover" %> - <% unless user.confirmed_hide? %> - <%= link_to t("admin.actions.confirm_hide"), - confirm_hide_admin_hidden_user_path(user, request.query_parameters), - method: :put, - class: "button hollow warning on-hover" %> - <% end %> -
    + <%= link_to t("admin.actions.restore"), + restore_admin_hidden_user_path(user, request.query_parameters), + method: :put, + data: { confirm: t("admin.actions.confirm") }, + class: "button hollow warning" %> + <% unless user.confirmed_hide? %> + <%= link_to t("admin.actions.confirm_hide"), + confirm_hide_admin_hidden_user_path(user, request.query_parameters), + method: :put, + class: "button" %> + <% end %> +
    + + <%= paginate @users %> +<% else %> +
    + <%= t("admin.hidden_users.index.no_hidden_users") %> +
    <% end %> - - -<%= paginate @users %> - - diff --git a/app/views/admin/proposals/index.html.erb b/app/views/admin/proposals/index.html.erb index d929843b1..ba161ce77 100644 --- a/app/views/admin/proposals/index.html.erb +++ b/app/views/admin/proposals/index.html.erb @@ -2,41 +2,55 @@ <%= render 'shared/filter_subnav', i18n_namespace: "admin.proposals.index" %> -

    <%= page_entries_info @proposals %>

    +<% if @proposals.any? %> +

    <%= page_entries_info @proposals %>

    - - <% @proposals.each do |proposal| %> - - - + + <% end %> + +
    - <%= proposal.title %> -
    -
    -

    <%= proposal.summary %>

    - <%= proposal.description %> - <% if proposal.external_url.present? %> -

    <%= text_with_links proposal.external_url %>

    - <% end %> - <% if proposal.video_url.present? %> -

    <%= text_with_links proposal.video_url %>

    - <% end %> -

    <%= proposal.question %>

    -
    -
    - <%= link_to t("admin.actions.restore"), - restore_admin_proposal_path(proposal, request.query_parameters), - method: :put, - data: { confirm: t("admin.actions.confirm") }, - class: "button hollow on-hover-block" %> - <% unless proposal.confirmed_hide? %> - <%= link_to t("admin.actions.confirm_hide"), - confirm_hide_admin_proposal_path(proposal, request.query_parameters), + + + + + + + + <% @proposals.each do |proposal| %> + + + + - - <% end %> -
    <%= t("admin.shared.title") %><%= t("admin.shared.description") %><%= t("admin.shared.actions") %>
    + <%= proposal.title %> + +
    +

    <%= proposal.summary %>

    + <%= proposal.description %> + <% if proposal.external_url.present? %> +

    <%= text_with_links proposal.external_url %>

    + <% end %> + <% if proposal.video_url.present? %> +

    <%= text_with_links proposal.video_url %>

    + <% end %> +

    <%= proposal.question %>

    +
    +
    + <%= link_to t("admin.actions.restore"), + restore_admin_proposal_path(proposal, request.query_parameters), method: :put, - class: "button hollow warning on-hover-block" %> - <% end %> -
    + data: { confirm: t("admin.actions.confirm") }, + class: "button hollow warning" %> + <% unless proposal.confirmed_hide? %> + <%= link_to t("admin.actions.confirm_hide"), + confirm_hide_admin_proposal_path(proposal, request.query_parameters), + method: :put, + class: "button" %> + <% end %> +
    -<%= paginate @proposals %> + <%= paginate @proposals %> +<% else %> +
    + <%= t("admin.proposals.index.no_hidden_proposals") %> +
    +<% end %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index cf1f83a2a..87bbb6685 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -213,6 +213,7 @@ en: hidden_debate: Hidden debate hidden_proposal: Hidden proposal title: Hidden comments + no_hidden_comments: There is no hidden comments. dashboard: index: back: Go back to %{org} @@ -226,6 +227,7 @@ en: with_confirmed_hide: Confirmed without_confirmed_hide: Pending title: Hidden debates + no_hidden_debates: There is no hidden debates. hidden_users: index: filter: Filter @@ -234,6 +236,8 @@ en: with_confirmed_hide: Confirmed without_confirmed_hide: Pending title: Hidden users + user: User + no_hidden_users: There is no hidden users. show: email: 'Email:' hidden_at: 'Hidden at:' @@ -715,6 +719,7 @@ en: with_confirmed_hide: Confirmed without_confirmed_hide: Pending title: Hidden proposals + no_hidden_proposals: There is no hidden proposals. settings: flash: updated: Value updated @@ -757,6 +762,9 @@ en: placeholder: Search user by name or email search_results: "Search results" no_search_results: "No results found." + actions: Actions + title: Title + description: Description spending_proposals: index: geozone_filter_all: All zones diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index a4a377854..d1a24b314 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -213,6 +213,7 @@ es: hidden_debate: Debate oculto hidden_proposal: Propuesta oculta title: Comentarios ocultos + no_hidden_comments: No hay comentarios ocultos. dashboard: index: back: Volver a %{org} @@ -226,6 +227,7 @@ es: with_confirmed_hide: Confirmados without_confirmed_hide: Pendientes title: Debates ocultos + no_hidden_debates: No hay debates ocultos. hidden_users: index: filter: Filtro @@ -234,6 +236,8 @@ es: with_confirmed_hide: Confirmados without_confirmed_hide: Pendientes title: Usuarios bloqueados + user: Usuario + no_hidden_users: No hay uusarios bloqueados. show: email: 'Email:' hidden_at: 'Bloqueado:' @@ -717,6 +721,7 @@ es: with_confirmed_hide: Confirmadas without_confirmed_hide: Pendientes title: Propuestas ocultas + no_hidden_proposals: No hay propuestas ocultas. settings: flash: updated: Valor actualizado @@ -759,6 +764,9 @@ es: placeholder: Buscar usuario por nombre o email search_results: "Resultados de la búsqueda" no_search_results: "No se han encontrado resultados." + actions: Acciones + title: "Título" + description: "Descripción" spending_proposals: index: geozone_filter_all: Todos los ámbitos de actuación From b52abfb9221513ffdd1906640e24b867794f9784 Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 13 Oct 2017 21:00:45 +0200 Subject: [PATCH 060/211] uses correct i18n key --- app/views/admin/tags/index.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/tags/index.html.erb b/app/views/admin/tags/index.html.erb index 787fad46a..c60ddaa0f 100644 --- a/app/views/admin/tags/index.html.erb +++ b/app/views/admin/tags/index.html.erb @@ -14,7 +14,7 @@ - + From 1da787e2fff3bfbe7748a07b43a71fa83b96cd6d Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 13 Oct 2017 21:01:23 +0200 Subject: [PATCH 061/211] fixes lint warnings using single quoted on icons.scss --- app/assets/stylesheets/icons.scss | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/icons.scss b/app/assets/stylesheets/icons.scss index dc59d1118..b9f2735b4 100644 --- a/app/assets/stylesheets/icons.scss +++ b/app/assets/stylesheets/icons.scss @@ -270,21 +270,21 @@ } .icon-calculator::before { - content: "\36"; + content: '\36'; } .icon-map-marker::before { - content: "\37"; + content: '\37'; } .icon-user-plus::before { - content: "\38"; + content: '\38'; } .icon-file-text-o::before { - content: "\39"; + content: '\39'; } .icon-file-text::before { - content: "\21"; + content: '\21'; } From 99e609769507ffe46fee1ac2c6c6466aed9e0c51 Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 13 Oct 2017 21:32:19 +0200 Subject: [PATCH 062/211] updates admin tags specs --- app/views/admin/tags/index.html.erb | 2 +- spec/features/admin/tags_spec.rb | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/views/admin/tags/index.html.erb b/app/views/admin/tags/index.html.erb index c60ddaa0f..55e51a8ac 100644 --- a/app/views/admin/tags/index.html.erb +++ b/app/views/admin/tags/index.html.erb @@ -29,7 +29,7 @@ <%= tag.name %> <% end %> - diff --git a/spec/features/admin/tags_spec.rb b/spec/features/admin/tags_spec.rb index dd9c38c6b..8ff205852 100644 --- a/spec/features/admin/tags_spec.rb +++ b/spec/features/admin/tags_spec.rb @@ -23,7 +23,7 @@ feature 'Admin tags' do within("form.new_tag") do fill_in "tag_name", with: 'important issues' - click_button 'Create Topic' + click_button 'Create topic' end visit admin_tags_path @@ -39,8 +39,8 @@ feature 'Admin tags' do expect(page).to have_content @tag1.name expect(page).to have_content tag2.name - within("#edit_tag_#{tag2.id}") do - click_link 'Destroy Topic' + within("#tag_#{tag2.id}") do + click_link 'Destroy topic' end visit admin_tags_path @@ -58,8 +58,8 @@ feature 'Admin tags' do expect(page).to have_content @tag1.name expect(page).to have_content tag2.name - within("#edit_tag_#{tag2.id}") do - click_link 'Destroy Topic' + within("#tag_#{tag2.id}") do + click_link 'Destroy topic' end visit admin_tags_path @@ -81,7 +81,7 @@ feature 'Admin tags' do within("form.new_tag") do fill_in "tag_name", with: "wow_category" - click_button 'Create Topic' + click_button 'Create topic' end expect(ActsAsTaggableOn::Tag.category.where(name: "wow_category")).to exist From 45f73aa1baff8e995ade7f58c7988f95f1e6b00e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Mon, 16 Oct 2017 12:22:54 +0200 Subject: [PATCH 063/211] Excluded officer shift dates from each task date range --- app/helpers/shifts_helper.rb | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/helpers/shifts_helper.rb b/app/helpers/shifts_helper.rb index dc9f97a91..ec1b342c4 100644 --- a/app/helpers/shifts_helper.rb +++ b/app/helpers/shifts_helper.rb @@ -1,15 +1,15 @@ module ShiftsHelper def shift_vote_collection_dates(polls) - date_options((start_date(polls)..end_date(polls))) + date_options((start_date(polls)..end_date(polls)), 0) end def shift_recount_scrutiny_dates(polls) - date_options(polls.map(&:ends_at).map(&:to_date).sort.inject([]) { |total, date| total << (date..date + 1.week).to_a }.flatten.uniq) + date_options(polls.map(&:ends_at).map(&:to_date).sort.inject([]) { |total, date| total << (date..date + 1.week).to_a }.flatten.uniq, 1) end - def date_options(dates) - dates.map { |date| [l(date, format: :long), l(date)] } + def date_options(dates, task_id) + dates.reject { |date| officer_shifts(task_id).include?(date) }.map { |date| [l(date, format: :long), l(date)] } end def start_date(polls) @@ -24,4 +24,9 @@ module ShiftsHelper officers.collect { |officer| [officer.name, officer.id] } end + private + + def officer_shifts(task_id) + @officer.shifts.where(task: task_id).map(&:date) + end end From c9a3bcc65a7539ba6fbb0477a04e7d367923b4ab Mon Sep 17 00:00:00 2001 From: decabeza Date: Mon, 16 Oct 2017 13:14:15 +0200 Subject: [PATCH 064/211] adds admin polls answer video specs --- spec/features/polls/answers_spec.rb | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/spec/features/polls/answers_spec.rb b/spec/features/polls/answers_spec.rb index f7dfd4d38..54890610e 100644 --- a/spec/features/polls/answers_spec.rb +++ b/spec/features/polls/answers_spec.rb @@ -39,6 +39,31 @@ feature 'Answers' do expect(page).to have_content "Adding more trees, creating a play area..." end + + scenario 'Add video to answer' do + question = create(:poll_question) + answer1 = create(:poll_question_answer, question: question) + answer2 = create(:poll_question_answer, question: question) + + visit admin_question_path(question) + + within("#poll_question_answer_#{answer1.id}") do + click_link "Video list" + end + + click_link "Add video" + + fill_in "poll_question_answer_video_title", with: "Awesome project video" + fill_in "poll_question_answer_video_url", with: "https://www.youtube.com/watch?v=123" + + click_button "Save" + + within("#poll_question_answer_video_#{answer1.id}") do + expect(page).to have_content "Awesome project video" + expect(page).to have_content "https://www.youtube.com/watch?v=123" + end + end + pending "Update" pending "Destroy" From 279adaa00d19f108366025c96cda857bc390e842 Mon Sep 17 00:00:00 2001 From: decabeza Date: Mon, 16 Oct 2017 13:14:44 +0200 Subject: [PATCH 065/211] starts with polls show answers with video specs --- spec/features/polls/polls_spec.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/spec/features/polls/polls_spec.rb b/spec/features/polls/polls_spec.rb index 9fdb07255..96787bc9e 100644 --- a/spec/features/polls/polls_spec.rb +++ b/spec/features/polls/polls_spec.rb @@ -65,6 +65,19 @@ feature 'Polls' do let(:geozone) { create(:geozone) } let(:poll) { create(:poll, summary: "Summary", description: "Description") } + scenario 'Show answers with videos' do + question = create(:poll_question, poll: poll) + answer1 = create(:poll_question_answer, question: question, title: 'Chewbacca') + answer2 = create(:poll_question_answer, question: question, title: 'Han Solo', + video_title: "Awesome project video", + video_url: "https://www.youtube.com/watch?v=123") + + + visit poll_path(poll) + + + end + scenario 'Lists questions from proposals as well as regular ones' do normal_question = create(:poll_question, poll: poll) proposal_question = create(:poll_question, poll: poll, proposal: create(:proposal)) From a6d533a76750c86aa2a7ab623bcf01a5a9b8891c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Mon, 16 Oct 2017 13:47:10 +0200 Subject: [PATCH 066/211] Helper improvements --- app/helpers/shifts_helper.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/helpers/shifts_helper.rb b/app/helpers/shifts_helper.rb index ec1b342c4..f8cfe8cd4 100644 --- a/app/helpers/shifts_helper.rb +++ b/app/helpers/shifts_helper.rb @@ -1,15 +1,19 @@ module ShiftsHelper def shift_vote_collection_dates(polls) - date_options((start_date(polls)..end_date(polls)), 0) + date_options((start_date(polls)..end_date(polls)), Poll::Shift.tasks[:vote_collection]) end def shift_recount_scrutiny_dates(polls) - date_options(polls.map(&:ends_at).map(&:to_date).sort.inject([]) { |total, date| total << (date..date + 1.week).to_a }.flatten.uniq, 1) + date_options(polls.map(&:ends_at).map(&:to_date).sort.inject([]) { |total, date| total << (date..date + 1.week).to_a }.flatten.uniq, Poll::Shift.tasks[:recount_scrutiny]) end def date_options(dates, task_id) - dates.reject { |date| officer_shifts(task_id).include?(date) }.map { |date| [l(date, format: :long), l(date)] } + valid_dates(dates, task_id).map { |date| [l(date, format: :long), l(date)] } + end + + def valid_dates(dates, task_id) + dates.reject { |date| officer_shifts(task_id).include?(date) } end def start_date(polls) From 7d22b386b947baaca82982fe45526671df69c8cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Mon, 16 Oct 2017 16:08:15 +0200 Subject: [PATCH 067/211] Added tests --- spec/factories.rb | 8 +++++++ spec/features/admin/poll/shifts_spec.rb | 31 +++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/spec/factories.rb b/spec/factories.rb index 69aa92c62..ba7c910ba 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -531,6 +531,14 @@ FactoryGirl.define do association :booth, factory: :poll_booth association :officer, factory: :poll_officer date Date.current + + trait :vote_collection_task do + task 0 + end + + trait :recount_scrutiny_task do + task 1 + end end factory :poll_voter, class: 'Poll::Voter' do diff --git a/spec/features/admin/poll/shifts_spec.rb b/spec/features/admin/poll/shifts_spec.rb index 2ac290216..4864d63d8 100644 --- a/spec/features/admin/poll/shifts_spec.rb +++ b/spec/features/admin/poll/shifts_spec.rb @@ -91,6 +91,37 @@ feature 'Admin shifts' do end end + scenario "Vote Collection Shift and Recount & Scrutiny Shift don't include already assigned dates to officer", :js do + poll = create(:poll, :current) + booth = create(:poll_booth) + assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + officer = create(:poll_officer) + + shift1 = create(:poll_shift, :vote_collection_task, officer: officer, booth: booth, date: Time.zone.today) + shift2 = create(:poll_shift, :recount_scrutiny_task, officer: officer, booth: booth, date: Time.zone.tomorrow) + + vote_collection_dates = (poll.starts_at.to_date..poll.ends_at.to_date).to_a + .reject { |date| date == Time.zone.today } + .map { |date| I18n.l(date, format: :long) } + recount_scrutiny_dates = (poll.ends_at.to_date..poll.ends_at.to_date + 1.week).to_a + .reject { |date| date == Time.zone.tomorrow } + .map { |date| I18n.l(date, format: :long) } + + visit available_admin_booths_path + + within("#booth_#{booth.id}") do + click_link "Manage shifts" + end + + fill_in "search", with: officer.email + click_button "Search" + click_link "Edit shifts" + + expect(page).to have_select('shift_date_vote_collection_date', options: ["Select day", *vote_collection_dates]) + select "Recount & Scrutiny", from: 'shift_task' + expect(page).to have_select('shift_date_recount_scrutiny_date', options: ["Select day", *recount_scrutiny_dates]) + end + scenario "Error on create", :js do poll = create(:poll, :current) booth = create(:poll_booth) From c2dcad79b3243eefc56deca7cfe0a152cd36b966 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 16 Oct 2017 17:14:40 +0200 Subject: [PATCH 068/211] adds video spec --- spec/factories.rb | 6 ++++++ spec/features/polls/polls_spec.rb | 9 +++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/spec/factories.rb b/spec/factories.rb index a28471efc..cf3b8f88a 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -507,6 +507,12 @@ FactoryGirl.define do sequence(:description) { |n| "Question description #{n}" } end + factory :poll_answer_video, class: 'Poll::Question::Answer::Video' do + association :answer, factory: :poll_question_answer + title "Sample video title" + url "http://sample-video-url.org" + end + factory :poll_booth, class: 'Poll::Booth' do sequence(:name) { |n| "Booth #{n}" } sequence(:location) { |n| "Street #{n}" } diff --git a/spec/features/polls/polls_spec.rb b/spec/features/polls/polls_spec.rb index 96787bc9e..2793fafdf 100644 --- a/spec/features/polls/polls_spec.rb +++ b/spec/features/polls/polls_spec.rb @@ -67,15 +67,12 @@ feature 'Polls' do scenario 'Show answers with videos' do question = create(:poll_question, poll: poll) - answer1 = create(:poll_question_answer, question: question, title: 'Chewbacca') - answer2 = create(:poll_question_answer, question: question, title: 'Han Solo', - video_title: "Awesome project video", - video_url: "https://www.youtube.com/watch?v=123") - + answer = create(:poll_question_answer, question: question, title: 'Chewbacca') + video = create(:poll_answer_video, answer: answer, title: "Awesome project video", url: "https://www.youtube.com/watch?v=123") visit poll_path(poll) - + expect(page).to have_link("Awesome project video", href: "https://www.youtube.com/watch?v=123") end scenario 'Lists questions from proposals as well as regular ones' do From 78cc09cc5ab622353a84249b79e734f5b2be85b7 Mon Sep 17 00:00:00 2001 From: iagirre Date: Mon, 16 Oct 2017 17:25:04 +0200 Subject: [PATCH 069/211] Controllers and models to see the polls stats. Routes related also added. --- app/controllers/polls/stats_controller.rb | 20 +++++++++ app/models/abilities/everyone.rb | 1 + app/models/poll/stats.rb | 36 +++++++++++++++ app/views/polls/show.html.erb | 2 + app/views/polls/stats/show.html.erb | 53 +++++++++++++++++++++++ config/routes.rb | 2 + 6 files changed, 114 insertions(+) create mode 100644 app/controllers/polls/stats_controller.rb create mode 100644 app/models/poll/stats.rb create mode 100644 app/views/polls/stats/show.html.erb diff --git a/app/controllers/polls/stats_controller.rb b/app/controllers/polls/stats_controller.rb new file mode 100644 index 000000000..4d6a40ff3 --- /dev/null +++ b/app/controllers/polls/stats_controller.rb @@ -0,0 +1,20 @@ +class Polls::StatsController < ApplicationController + + before_action :load_poll + load_and_authorize_resource :poll + + def show + authorize! :read_stats, @poll + @stats = load_stats + end + + private + + def load_stats + Poll::Stats.new(@poll).generate + end + + def load_poll + @poll = Poll.find_by(id: params[:id]) + end +end \ No newline at end of file diff --git a/app/models/abilities/everyone.rb b/app/models/abilities/everyone.rb index 3004ca8ad..73f3220ab 100644 --- a/app/models/abilities/everyone.rb +++ b/app/models/abilities/everyone.rb @@ -23,6 +23,7 @@ module Abilities can [:read], Legislation::Question can [:create], Legislation::Answer can [:search, :comments, :read, :create, :new_comment], Legislation::Annotation + can :read_stats, Poll end end end diff --git a/app/models/poll/stats.rb b/app/models/poll/stats.rb new file mode 100644 index 000000000..823724ade --- /dev/null +++ b/app/models/poll/stats.rb @@ -0,0 +1,36 @@ +class Poll + class Stats + + def initialize(poll) + @poll = poll + end + + def generate + stats = %w[total_participants total_participants_web total_participants_booth] + stats.map { |stat_name| [stat_name.to_sym, send(stat_name)] }.to_h + end + + private + + def total_participants + stats_cache('total_participants') { voters.uniq.count } + end + + def total_participants_web + stats_cache('total_participants_web') { voters.where(origin: 'web').count } + end + + def total_participants_booth + stats_cache('total_participants_booth') { voters.where(origin: 'booth').count } + end + + def voters + stats_cache('voters') { @poll.voters } + end + + def stats_cache(key, &block) + Rails.cache.fetch("polls_stats/#{@poll.id}/#{key}/v7", &block) + end + + end +end \ No newline at end of file diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index 0a56ba237..2c541305d 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -28,6 +28,8 @@ + + <%= link_to "Estadísticas", custom_poll_stats_path(@poll.id) %>
    diff --git a/app/views/polls/stats/show.html.erb b/app/views/polls/stats/show.html.erb new file mode 100644 index 000000000..6018708c9 --- /dev/null +++ b/app/views/polls/stats/show.html.erb @@ -0,0 +1,53 @@ +<% cache [@stats] do %> + <% provide :title do %> + <%= t("polls.stats.page_title", poll: @poll.name) %> + <% end %> + <% provide :social_media_meta_tags do %> + <%= render "shared/social_media_meta_tags", + social_url: poll_url(@poll), + social_title: @poll.name, + social_description: @poll.description %> + <% end %> + +
    +
    +
    +
    + <%= back_link_to polls_path %> +

    <%= t("polls.stats.title") %>
    <%= @poll.name %>

    +
    +
    +
    + + +
    +
    +
    + <%= t("polls.stats.total_participants") %> +

    + <%= @stats[:total_participants] %> +

    +
    <%= t("admin.tags.index.title") %><%= t("admin.tags.index.topic") %> <%= t("admin.actions.actions") %>
    + <%= link_to t("admin.tags.destroy"), admin_tag_path(tag), method: :delete, class: "button hollow alert" %>
    + + + + + + + + + + + + +
    WebBooth
    <%= @stats[:total_participants_web] %><%= @stats[:total_participants_booth] %>
    + + <%= t("polls.stats.total_votes") %> +

    + <%= @stats[:total_votes] %> +

    +
    +
    +
    +
    +<% end %> \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 1fb74aa53..e9ae237f0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -112,6 +112,8 @@ Rails.application.routes.draw do get :search, on: :collection end + get "polls/:id/stats", to: "polls/stats#show", as: 'custom_poll_stats' + resources :polls, only: [:show, :index] do resources :questions, controller: 'polls/questions', shallow: true do post :answer, on: :member From 1812c0330e9e5eb84cd856c8d15abfa29b49862e Mon Sep 17 00:00:00 2001 From: decabeza Date: Mon, 16 Oct 2017 18:37:00 +0200 Subject: [PATCH 070/211] replaces video url on poll answer factories --- spec/factories.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/factories.rb b/spec/factories.rb index cf3b8f88a..db24002ae 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -510,7 +510,7 @@ FactoryGirl.define do factory :poll_answer_video, class: 'Poll::Question::Answer::Video' do association :answer, factory: :poll_question_answer title "Sample video title" - url "http://sample-video-url.org" + url "https://youtu.be/nhuNb0XtRhQ" end factory :poll_booth, class: 'Poll::Booth' do From 580c57e71bf0a9b5db2bb6611a52e4daac8ba265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Mon, 16 Oct 2017 19:02:27 +0200 Subject: [PATCH 071/211] Added officing tests Added new tests to officing section to ensure that multiple sessions (different users) can be initialized at the same time without crashing. --- spec/features/officing_spec.rb | 39 +++++++++++++++++++++++++++++++++- spec/sessions_helper.rb | 8 +++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 spec/sessions_helper.rb diff --git a/spec/features/officing_spec.rb b/spec/features/officing_spec.rb index aff3eac4e..897a26107 100644 --- a/spec/features/officing_spec.rb +++ b/spec/features/officing_spec.rb @@ -1,4 +1,5 @@ require 'rails_helper' +require 'sessions_helper' feature 'Poll Officing' do let(:user) { create(:user) } @@ -106,4 +107,40 @@ feature 'Poll Officing' do expect(page).to_not have_css('#moderation_menu') end -end \ No newline at end of file + scenario 'Officing dashboard available for multiple sessions' do + user1 = create(:user) + user2 = create(:user) + officer1 = create(:poll_officer, user: user1) + officer2 = create(:poll_officer, user: user2) + + in_browser(:one) do + login_as user1 + visit officing_root_path + end + + in_browser(:two) do + login_as user2 + visit officing_root_path + end + + in_browser(:one) do + page.should have_content("Here you can validate user documents and store voting results") + + visit new_officing_residence_path + page.should have_content("Validate document") + + visit final_officing_polls_path + page.should have_content("Polls ready for final recounting") + end + + in_browser(:two) do + page.should have_content("Here you can validate user documents and store voting results") + + visit new_officing_residence_path + page.should have_content("Validate document") + + visit final_officing_polls_path + page.should have_content("Polls ready for final recounting") + end + end +end diff --git a/spec/sessions_helper.rb b/spec/sessions_helper.rb new file mode 100644 index 000000000..fc3fcc2f0 --- /dev/null +++ b/spec/sessions_helper.rb @@ -0,0 +1,8 @@ +def in_browser(name) + old_session = Capybara.session_name + + Capybara.session_name = name + yield + + Capybara.session_name = old_session +end From 3ec12cfad7f0a0d263c52cc5b6efb903ec962e55 Mon Sep 17 00:00:00 2001 From: decabeza Date: Mon, 16 Oct 2017 19:39:06 +0200 Subject: [PATCH 072/211] removes box shadow for off canvas content --- app/assets/stylesheets/layout.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index 160819795..ecb58d2f1 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -372,6 +372,10 @@ a { display: table-cell; } +.off-canvas-content { + box-shadow: none; +} + // 02. Header // ---------- From 92dbb4fb73b5166a6378ca82d33637e0205f2507 Mon Sep 17 00:00:00 2001 From: decabeza Date: Mon, 16 Oct 2017 19:39:29 +0200 Subject: [PATCH 073/211] removes unnecessary close button for admin menu --- app/views/layouts/admin.html.erb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/views/layouts/admin.html.erb b/app/views/layouts/admin.html.erb index c0e36ba0e..351c04b76 100644 --- a/app/views/layouts/admin.html.erb +++ b/app/views/layouts/admin.html.erb @@ -18,10 +18,6 @@
    - -
    <%= side_menu %>
    From 0b5eed090e8b680074d49ff6a439d43316e613a5 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 16 Oct 2017 19:54:07 +0200 Subject: [PATCH 074/211] Fix no-answer scenario for question valid answers --- app/models/poll/question.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb index efcaf4635..90e528bd0 100644 --- a/app/models/poll/question.rb +++ b/app/models/poll/question.rb @@ -40,7 +40,7 @@ class Poll::Question < ActiveRecord::Base end def valid_answers - (super.try(:split, ',').compact || []).map(&:strip) + (super.try(:split, ',')&.compact || []).map(&:strip) end def copy_attributes_from_proposal(proposal) From e1e9b431d79f2d0540db6e1a862b887b388c7abe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Mon, 16 Oct 2017 20:10:49 +0200 Subject: [PATCH 075/211] Added tests --- spec/features/polls/voter_spec.rb | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/spec/features/polls/voter_spec.rb b/spec/features/polls/voter_spec.rb index 256807928..409bcd09d 100644 --- a/spec/features/polls/voter_spec.rb +++ b/spec/features/polls/voter_spec.rb @@ -41,6 +41,27 @@ feature "Voter" do expect(Poll::Voter.first.origin).to eq("web") end + scenario "Voting via web as unverified user", :js do + poll = create(:poll) + + question = create(:poll_question, poll: poll) + answer1 = create(:poll_question_answer, question: question, title: 'Yes') + answer2 = create(:poll_question_answer, question: question, title: 'No') + + user = create(:user, :incomplete_verification) + + login_as user + visit poll_path(poll) + + within("#poll_question_#{question.id}_answers") do + expect(page).to_not have_link('Yes') + expect(page).to_not have_link('No') + end + + expect(page).to have_content("You must verify your account in order to answer") + expect(page).to_not have_content("You have already participated in this poll. If you vote again it will be overwritten") + end + scenario "Voting in booth", :js do user = create(:user, :in_census) From c24fab427e04f90f26be9cd426293cbe85c61b6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Tue, 17 Oct 2017 10:20:36 +0200 Subject: [PATCH 076/211] Completed tests --- spec/features/officing_spec.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/spec/features/officing_spec.rb b/spec/features/officing_spec.rb index 897a26107..2a54bbff1 100644 --- a/spec/features/officing_spec.rb +++ b/spec/features/officing_spec.rb @@ -108,11 +108,18 @@ feature 'Poll Officing' do end scenario 'Officing dashboard available for multiple sessions' do + poll = create(:poll) + booth = create(:poll_booth) + booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + user1 = create(:user) user2 = create(:user) officer1 = create(:poll_officer, user: user1) officer2 = create(:poll_officer, user: user2) + officer_assignment_1 = create(:poll_officer_assignment, booth_assignment: booth_assignment, officer: officer1) + officer_assignment_2 = create(:poll_officer_assignment, booth_assignment: booth_assignment, officer: officer2) + in_browser(:one) do login_as user1 visit officing_root_path From 68e09e8a9a1880d6e5850cef23696aa00c476119 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Tue, 17 Oct 2017 12:16:09 +0200 Subject: [PATCH 077/211] Fix vote collection date expectations --- spec/features/admin/poll/shifts_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/admin/poll/shifts_spec.rb b/spec/features/admin/poll/shifts_spec.rb index 6f027fad3..35df2e20e 100644 --- a/spec/features/admin/poll/shifts_spec.rb +++ b/spec/features/admin/poll/shifts_spec.rb @@ -101,7 +101,7 @@ feature 'Admin shifts' do shift1 = create(:poll_shift, :vote_collection_task, officer: officer, booth: booth, date: Time.zone.today) shift2 = create(:poll_shift, :recount_scrutiny_task, officer: officer, booth: booth, date: Time.zone.tomorrow) - vote_collection_dates = (poll.starts_at.to_date..poll.ends_at.to_date).to_a + vote_collection_dates = (Date.current..poll.ends_at.to_date).to_a .reject { |date| date == Time.zone.today } .map { |date| I18n.l(date, format: :long) } recount_scrutiny_dates = (poll.ends_at.to_date..poll.ends_at.to_date + 1.week).to_a From c8568d16aa00bfaa47a6e7f9b29ce3c5b0b45367 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Tue, 17 Oct 2017 13:13:51 +0200 Subject: [PATCH 078/211] Fix wrongful expectation on add video to answer scenario --- spec/features/polls/answers_spec.rb | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/spec/features/polls/answers_spec.rb b/spec/features/polls/answers_spec.rb index 88b7e28aa..8bb87c94e 100644 --- a/spec/features/polls/answers_spec.rb +++ b/spec/features/polls/answers_spec.rb @@ -2,20 +2,20 @@ require 'rails_helper' feature 'Answers' do + let(:question) { create(:poll_question) } + let(:admin) { create(:administrator) } + background do - admin = create(:administrator) login_as(admin.user) end scenario "Index" do - question = create(:poll_question) answer1 = create(:poll_question_answer, question: question, given_order: 2) answer2 = create(:poll_question_answer, question: question, given_order: 1) visit admin_question_path(question) expect(page).to have_css(".poll_question_answer", count: 2) - expect(page.body.index(answer1.title)).to be < page.body.index(answer2.title) within("#poll_question_answer_#{answer1.id}") do @@ -25,8 +25,6 @@ feature 'Answers' do end scenario "Create" do - question = create(:poll_question) - visit admin_question_path(question) click_link "Add answer" @@ -35,15 +33,12 @@ feature 'Answers' do click_button "Save" expect(page).to have_content "Answer created successfully" - expect(page).to have_css(".poll_question_answer", count: 1) expect(page).to have_content "¿Would you like to reform Central Park?" expect(page).to have_content "Adding more trees, creating a play area..." end - scenario 'Add video to answer' do - question = create(:poll_question) answer1 = create(:poll_question_answer, question: question) answer2 = create(:poll_question_answer, question: question) @@ -60,7 +55,7 @@ feature 'Answers' do click_button "Save" - within("#poll_question_answer_video_#{answer1.id}") do + within("#poll_question_answer_video_#{answer1.videos.last.id}") do expect(page).to have_content "Awesome project video" expect(page).to have_content "https://www.youtube.com/watch?v=123" end From 58f57bc15b0ab88536e60fe987228dea3568b8d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Tue, 17 Oct 2017 13:16:46 +0200 Subject: [PATCH 079/211] Added poll method `voted_in_web?` --- app/models/poll.rb | 4 ++++ app/views/polls/show.html.erb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/models/poll.rb b/app/models/poll.rb index 84349bf0b..cd91db884 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -65,6 +65,10 @@ class Poll < ActiveRecord::Base Poll::Voter.where(poll: self, user: user, origin: "booth").exists? end + def voted_in_web?(user) + Poll::Voter.where(poll: self, user: user, origin: "web").exists? + end + def date_range unless starts_at.present? && ends_at.present? && starts_at <= ends_at errors.add(:starts_at, I18n.t('errors.messages.invalid_date_range')) diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index c9796b836..b81ee2c7a 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -39,7 +39,7 @@
    <% else %> - <% unless current_user && @poll.votable_by?(current_user) %> + <% if current_user && @poll.voted_in_web?(current_user) %>
    <%= t("polls.show.already_voted_in_web") %>
    From 712151b395d576cfcc775227af9d3f54f3977a88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Tue, 17 Oct 2017 13:17:20 +0200 Subject: [PATCH 080/211] Tests improvements --- spec/features/polls/voter_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/polls/voter_spec.rb b/spec/features/polls/voter_spec.rb index 409bcd09d..21e73e238 100644 --- a/spec/features/polls/voter_spec.rb +++ b/spec/features/polls/voter_spec.rb @@ -54,8 +54,8 @@ feature "Voter" do visit poll_path(poll) within("#poll_question_#{question.id}_answers") do - expect(page).to_not have_link('Yes') - expect(page).to_not have_link('No') + expect(page).to_not have_link('Yes', href: "/questions/#{question.id}/answer?answer=Yes&token=") + expect(page).to_not have_link('No', href: "/questions/#{question.id}/answer?answer=No&token=") end expect(page).to have_content("You must verify your account in order to answer") From 548fd03ac8afcdd85e07b494dc05eac029679651 Mon Sep 17 00:00:00 2001 From: decabeza Date: Tue, 17 Oct 2017 13:25:09 +0200 Subject: [PATCH 081/211] fixes admin login items menu on mobile size --- app/views/layouts/_header.html.erb | 2 +- app/views/shared/_admin_login_items.html.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/layouts/_header.html.erb b/app/views/layouts/_header.html.erb index 304c5c954..fff3e3977 100644 --- a/app/views/layouts/_header.html.erb +++ b/app/views/layouts/_header.html.erb @@ -28,7 +28,7 @@
    -

    -
    +
    diff --git a/app/views/admin/poll/results/_result.html.erb b/app/views/admin/poll/results/_result.html.erb index 074c26ebf..64da2c9b2 100644 --- a/app/views/admin/poll/results/_result.html.erb +++ b/app/views/admin/poll/results/_result.html.erb @@ -1,8 +1,8 @@ - - - + + + @@ -20,8 +20,8 @@
    <%= t("admin.results.index.table_whites") %><%= t("admin.results.index.table_nulls") %><%= t("admin.results.index.table_total") %><%= t("admin.results.result.table_whites") %><%= t("admin.results.result.table_nulls") %><%= t("admin.results.result.table_total") %>
    - - + + diff --git a/app/views/admin/poll/results/_results_by_booth.html.erb b/app/views/admin/poll/results/_results_by_booth.html.erb index 3c240f8d3..8778a7434 100644 --- a/app/views/admin/poll/results/_results_by_booth.html.erb +++ b/app/views/admin/poll/results/_results_by_booth.html.erb @@ -1,8 +1,8 @@
    <%= t("admin.results.index.table_answer") %><%= t("admin.results.index.table_votes") %><%= t("admin.results.result.table_answer") %><%= t("admin.results.result.table_votes") %>
    - - + + @@ -10,8 +10,9 @@ <% end %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 87bbb6685..2b6f2988e 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -537,6 +537,7 @@ en: no_officers: "There are no officers for this booth" recounts: "Recounts" recounts_list: "Recount list for this booth" + results: "Results" date: "Date" count_final: "Final recount (by officer)" count_by_system: "Votes (automatic)" @@ -647,11 +648,16 @@ en: index: title: "Results" no_results: "There are no results" + result: table_whites: "Totally blank ballots" table_nulls: "Invalid ballots" table_total: "Total ballots" table_answer: Answer table_votes: Votes + results_by_booth: + booth: Booth + results: Results + see_results: See results booths: index: title: "List of booths" diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 0aa73ffb2..26e2d18dc 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -537,6 +537,7 @@ es: no_officers: "No hay presidentes de mesa para esta urna" recounts: "Recuentos" recounts_list: "Lista de recuentos de esta urna" + results: "Resultados" date: "Fecha" count_final: "Recuento final (presidente de mesa)" count_by_system: "Votos (automático)" @@ -649,11 +650,16 @@ es: index: title: "Resultados" no_results: "No hay resultados" + result: table_whites: Papeletas totalmente en blanco table_nulls: Papeletas nulas table_total: Papeletas totales table_answer: Respuesta table_votes: Votos + results_by_booth: + booth: Urna + results: Resultados + see_results: Ver resultados booths: index: title: "Lista de urnas" From 0499fb6fefd197b745a87d5fa371cdcd89a25187 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 18 Oct 2017 20:48:44 +0200 Subject: [PATCH 134/211] highlights result's tab --- app/views/admin/poll/booth_assignments/show.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/poll/booth_assignments/show.html.erb b/app/views/admin/poll/booth_assignments/show.html.erb index c69631dee..71938cce5 100644 --- a/app/views/admin/poll/booth_assignments/show.html.erb +++ b/app/views/admin/poll/booth_assignments/show.html.erb @@ -20,7 +20,7 @@
  • <%= link_to t("admin.poll_booth_assignments.show.recounts"), "#tab-recounts" %>
  • -
  • +
  • <%= link_to t("admin.poll_booth_assignments.show.results"), "#tab-results" %>
  • From 6a697bd6d0e07310d90dc3a6206cb2ae849a7acb Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 18 Oct 2017 20:50:46 +0200 Subject: [PATCH 135/211] adds specs --- .../admin/poll/booth_assigments_spec.rb | 86 +++++++++++++++++++ spec/features/admin/poll/polls_spec.rb | 37 ++++++++ 2 files changed, 123 insertions(+) diff --git a/spec/features/admin/poll/booth_assigments_spec.rb b/spec/features/admin/poll/booth_assigments_spec.rb index 77881efaa..b527170d2 100644 --- a/spec/features/admin/poll/booth_assigments_spec.rb +++ b/spec/features/admin/poll/booth_assigments_spec.rb @@ -126,5 +126,91 @@ feature 'Admin booths assignments' do end end + scenario 'Results' do + poll = create(:poll) + booth_assignment = create(:poll_booth_assignment, poll: poll) + + question_1 = create(:poll_question, poll: poll) + create(:poll_question_answer, title: 'Yes', question: question_1) + create(:poll_question_answer, title: 'No', question: question_1) + + question_2 = create(:poll_question, poll: poll) + create(:poll_question_answer, title: 'Today', question: question_2) + create(:poll_question_answer, title: 'Tomorrow', question: question_2) + + create(:poll_partial_result, + booth_assignment: booth_assignment, + question: question_1, + answer: 'Yes', + amount: 11) + + create(:poll_partial_result, + booth_assignment: booth_assignment, + question: question_1, + answer: 'No', + amount: 4) + + create(:poll_partial_result, + booth_assignment: booth_assignment, + question: question_2, + answer: 'Today', + amount: 5) + + create(:poll_partial_result, + booth_assignment: booth_assignment, + question: question_2, + answer: 'Tomorrow', + amount: 6) + + create(:poll_recount, + booth_assignment: booth_assignment, + white_amount: 21, + null_amount: 44, + total_amount: 66) + + visit admin_poll_booth_assignment_path(poll, booth_assignment) + + click_link 'Results' + + expect(page).to have_content(question_1.title) + + within("#question_#{question_1.id}_0_result") do + expect(page).to have_content("Yes") + expect(page).to have_content(11) + end + + within("#question_#{question_1.id}_1_result") do + expect(page).to have_content("No") + expect(page).to have_content(4) + end + + expect(page).to have_content(question_2.title) + + within("#question_#{question_2.id}_0_result") do + expect(page).to have_content("Today") + expect(page).to have_content(5) + end + + within("#question_#{question_2.id}_1_result") do + expect(page).to have_content("Tomorrow") + expect(page).to have_content(6) + end + + within('#white_results') { expect(page).to have_content('21') } + within('#null_results') { expect(page).to have_content('44') } + within('#total_results') { expect(page).to have_content('66') } + end + + scenario "No results" do + poll = create(:poll) + booth_assignment = create(:poll_booth_assignment, poll: poll) + + visit admin_poll_booth_assignment_path(poll, booth_assignment) + + click_link "Results" + + expect(page).to have_content "There are no results" + end + end end diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb index 9c2d3fcf1..2a2d26ea5 100644 --- a/spec/features/admin/poll/polls_spec.rb +++ b/spec/features/admin/poll/polls_spec.rb @@ -311,6 +311,43 @@ feature 'Admin polls' do within('#null_results') { expect(page).to have_content('44') } within('#total_results') { expect(page).to have_content('66') } end + + scenario "Link to results by booth" do + poll = create(:poll) + booth_assignment1 = create(:poll_booth_assignment, poll: poll) + booth_assignment2 = create(:poll_booth_assignment, poll: poll) + + question = create(:poll_question, poll: poll) + create(:poll_question_answer, title: 'Yes', question: question) + create(:poll_question_answer, title: 'No', question: question) + + create(:poll_partial_result, + booth_assignment: booth_assignment1, + question: question, + answer: 'Yes', + amount: 5) + + create(:poll_partial_result, + booth_assignment: booth_assignment2, + question: question, + answer: 'Yes', + amount: 6) + + visit admin_poll_path(poll) + + click_link "Results" + + expect(page).to have_link("See results", count: 2) + + within("#booth_assignment_#{booth_assignment1.id}_result") do + click_link "See results" + end + + expect(page).to have_content booth_assignment1.booth.name + expect(page).to have_content "Results" + expect(page).to have_content "Yes" + expect(page).to have_content "5" + end end end From fcbcca3b6002b02212861d60c210f04b00353682 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 18 Oct 2017 22:21:47 +0200 Subject: [PATCH 136/211] sorts booths by name --- app/views/admin/poll/results/_results_by_booth.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/poll/results/_results_by_booth.html.erb b/app/views/admin/poll/results/_results_by_booth.html.erb index 8778a7434..4e2a8bcae 100644 --- a/app/views/admin/poll/results/_results_by_booth.html.erb +++ b/app/views/admin/poll/results/_results_by_booth.html.erb @@ -6,7 +6,7 @@
    - <% @poll.booth_assignments.each do |booth_assignment| %> + <% @poll.booth_assignments.sort_by {|ba| ba.booth.name }.each do |booth_assignment| %>
    UrnaResultados<%= t("admin.results.results_by_booth.booth") %><%= t("admin.results.results_by_booth.results") %>
    <%= booth_assignment.booth.name %> - <%= link_to "See results", - admin_poll_booth_assignment_path(@poll, booth_assignment, anchor: "tab-results") %> + <%= link_to t("admin.results.results_by_booth.see_results"), + admin_poll_booth_assignment_path(@poll, booth_assignment, + anchor: "tab-results") %>
    <%= booth_assignment.booth.name %> From 5d3654f92f9fe872e29ab017e523def0978125e0 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 18 Oct 2017 22:40:41 +0200 Subject: [PATCH 137/211] refactors recounts into partial --- app/views/admin/poll/results/_recount.html.erb | 14 ++++++++++++++ app/views/admin/poll/results/_result.html.erb | 16 ---------------- app/views/admin/poll/results/index.html.erb | 1 + 3 files changed, 15 insertions(+), 16 deletions(-) create mode 100644 app/views/admin/poll/results/_recount.html.erb diff --git a/app/views/admin/poll/results/_recount.html.erb b/app/views/admin/poll/results/_recount.html.erb new file mode 100644 index 000000000..f4ab43954 --- /dev/null +++ b/app/views/admin/poll/results/_recount.html.erb @@ -0,0 +1,14 @@ + + + + + + + + + + + + + +
    <%= t("admin.results.result.table_whites") %><%= t("admin.results.result.table_nulls") %><%= t("admin.results.result.table_total") %>
    <%= resource.recounts.sum(:white_amount) %><%= resource.recounts.sum(:null_amount) %><%= resource.recounts.sum(:total_amount) %>
    \ No newline at end of file diff --git a/app/views/admin/poll/results/_result.html.erb b/app/views/admin/poll/results/_result.html.erb index 64da2c9b2..e2fe5f037 100644 --- a/app/views/admin/poll/results/_result.html.erb +++ b/app/views/admin/poll/results/_result.html.erb @@ -1,19 +1,3 @@ - - - - - - - - - - - - - -
    <%= t("admin.results.result.table_whites") %><%= t("admin.results.result.table_nulls") %><%= t("admin.results.result.table_total") %>
    <%= @poll.recounts.sum(:white_amount) %><%= @poll.recounts.sum(:null_amount) %><%= @poll.recounts.sum(:total_amount) %>
    - - <% by_question = @partial_results.group_by(&:question_id) %> <% @poll.questions.each do |question| %>

    <%= question.title %>

    diff --git a/app/views/admin/poll/results/index.html.erb b/app/views/admin/poll/results/index.html.erb index f4823ccd4..7f21e5452 100644 --- a/app/views/admin/poll/results/index.html.erb +++ b/app/views/admin/poll/results/index.html.erb @@ -9,6 +9,7 @@ <%= t("admin.results.index.no_results") %> <% else %> + <%= render "recount", resource: @poll %> <%= render "result" %> <%= render "results_by_booth" %> <% end %> From 39ebc5173a3d34f11cc952ace04fd5fe94edcbf1 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 18 Oct 2017 22:40:53 +0200 Subject: [PATCH 138/211] displays recounts for a single booth --- app/controllers/admin/poll/booth_assignments_controller.rb | 1 + app/views/admin/poll/booth_assignments/_results.html.erb | 1 + 2 files changed, 2 insertions(+) diff --git a/app/controllers/admin/poll/booth_assignments_controller.rb b/app/controllers/admin/poll/booth_assignments_controller.rb index c9f95de30..7998f29a2 100644 --- a/app/controllers/admin/poll/booth_assignments_controller.rb +++ b/app/controllers/admin/poll/booth_assignments_controller.rb @@ -19,6 +19,7 @@ class Admin::Poll::BoothAssignmentsController < Admin::Poll::BaseController officer_assignments: [officer: [:user]]).find(params[:id]) @voters_by_date = @booth_assignment.voters.group_by {|v| v.created_at.to_date} @partial_results = @booth_assignment.partial_results + @recounts = @booth_assignment.recounts end def create diff --git a/app/views/admin/poll/booth_assignments/_results.html.erb b/app/views/admin/poll/booth_assignments/_results.html.erb index 224da76ab..1b3f1ec08 100644 --- a/app/views/admin/poll/booth_assignments/_results.html.erb +++ b/app/views/admin/poll/booth_assignments/_results.html.erb @@ -6,6 +6,7 @@ <%= t("admin.results.index.no_results") %> <% else %> + <%= render "admin/poll/results/recount", resource: @booth_assignment %> <%= render "admin/poll/results/result" %> <% end %> \ No newline at end of file From 98f5d70e6d7e84bc534044dc7e11dd96a2c7e0a2 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 18 Oct 2017 22:41:31 +0200 Subject: [PATCH 139/211] makes specs more robust --- spec/features/admin/poll/booth_assigments_spec.rb | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/spec/features/admin/poll/booth_assigments_spec.rb b/spec/features/admin/poll/booth_assigments_spec.rb index b527170d2..5813e2dac 100644 --- a/spec/features/admin/poll/booth_assigments_spec.rb +++ b/spec/features/admin/poll/booth_assigments_spec.rb @@ -126,9 +126,10 @@ feature 'Admin booths assignments' do end end - scenario 'Results' do + scenario 'Results for a booth assignment' do poll = create(:poll) booth_assignment = create(:poll_booth_assignment, poll: poll) + other_booth_assignment = create(:poll_booth_assignment, poll: poll) question_1 = create(:poll_question, poll: poll) create(:poll_question_answer, title: 'Yes', question: question_1) @@ -162,12 +163,24 @@ feature 'Admin booths assignments' do answer: 'Tomorrow', amount: 6) + create(:poll_partial_result, + booth_assignment: other_booth_assignment, + question: question_1, + answer: 'Yes', + amount: 9999) + create(:poll_recount, booth_assignment: booth_assignment, white_amount: 21, null_amount: 44, total_amount: 66) + create(:poll_recount, + booth_assignment: other_booth_assignment, + white_amount: 999, + null_amount: 999, + total_amount: 999) + visit admin_poll_booth_assignment_path(poll, booth_assignment) click_link 'Results' From b6e080abca6525d4e1d0fa583917607812f92962 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Thu, 19 Oct 2017 10:25:14 +0200 Subject: [PATCH 140/211] fixes alignment --- app/views/admin/poll/booth_assignments/_results.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/poll/booth_assignments/_results.html.erb b/app/views/admin/poll/booth_assignments/_results.html.erb index 1b3f1ec08..fdbc4da3f 100644 --- a/app/views/admin/poll/booth_assignments/_results.html.erb +++ b/app/views/admin/poll/booth_assignments/_results.html.erb @@ -6,7 +6,7 @@ <%= t("admin.results.index.no_results") %> <% else %> - <%= render "admin/poll/results/recount", resource: @booth_assignment %> + <%= render "admin/poll/results/recount", resource: @booth_assignment %> <%= render "admin/poll/results/result" %> <% end %> \ No newline at end of file From 1ae91017b445bc78e53ef2e8acac2b934f39cf2c Mon Sep 17 00:00:00 2001 From: rgarcia Date: Thu, 19 Oct 2017 10:28:35 +0200 Subject: [PATCH 141/211] adds heading to results by booth table --- app/views/admin/poll/results/_results_by_booth.html.erb | 3 ++- config/locales/en/admin.yml | 1 + config/locales/es/admin.yml | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/admin/poll/results/_results_by_booth.html.erb b/app/views/admin/poll/results/_results_by_booth.html.erb index 4e2a8bcae..58d7ea83c 100644 --- a/app/views/admin/poll/results/_results_by_booth.html.erb +++ b/app/views/admin/poll/results/_results_by_booth.html.erb @@ -1,4 +1,5 @@ - +

    <%= t("admin.results.results_by_booth.title") %>

    +
    diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 2b6f2988e..38abe6f56 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -658,6 +658,7 @@ en: booth: Booth results: Results see_results: See results + title: "Results by booth" booths: index: title: "List of booths" diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 26e2d18dc..3336cdc5b 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -660,6 +660,7 @@ es: booth: Urna results: Resultados see_results: Ver resultados + title: "Resultados por urna" booths: index: title: "Lista de urnas" From 7ddc225d8b60b50d8c7b4d584b2ee6e8eec52c7a Mon Sep 17 00:00:00 2001 From: rgarcia Date: Thu, 19 Oct 2017 10:31:24 +0200 Subject: [PATCH 142/211] fixes alignment for link params --- app/views/admin/poll/results/_results_by_booth.html.erb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/views/admin/poll/results/_results_by_booth.html.erb b/app/views/admin/poll/results/_results_by_booth.html.erb index 58d7ea83c..9266a58fb 100644 --- a/app/views/admin/poll/results/_results_by_booth.html.erb +++ b/app/views/admin/poll/results/_results_by_booth.html.erb @@ -11,9 +11,8 @@ <% end %> From 6e680c187fb50bf560c93cdd4cd7b01bf8b2a1c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Thu, 19 Oct 2017 12:17:20 +0200 Subject: [PATCH 143/211] Added new column `most_voted` to Poll::Question::Answers --- app/models/poll/question/answer.rb | 9 ++-- ..._add_most_voted_to_poll_question_answer.rb | 5 ++ db/schema.rb | 54 ++++++++++++++++--- 3 files changed, 58 insertions(+), 10 deletions(-) create mode 100644 db/migrate/20171019095042_add_most_voted_to_poll_question_answer.rb diff --git a/app/models/poll/question/answer.rb b/app/models/poll/question/answer.rb index de6e35d1d..eff45a57a 100644 --- a/app/models/poll/question/answer.rb +++ b/app/models/poll/question/answer.rb @@ -13,6 +13,7 @@ class Poll::Question::Answer < ActiveRecord::Base validates :given_order, presence: true, uniqueness: { scope: :question_id } before_validation :set_order, on: :create + before_save :most_voted def description super.try :html_safe @@ -36,13 +37,15 @@ class Poll::Question::Answer < ActiveRecord::Base Poll::Answer.where(question_id: question, answer: title).count end - def is_winner? + def most_voted answers = question.question_answers .map { |a| Poll::Answer.where(question_id: a.question, answer: a.title).count } - !answers.any?{ |a| a > total_votes } + most_voted = !answers.any?{ |a| a > total_votes } + + self.update_attributes(most_voted: most_voted) end def total_votes_percentage - ((total_votes*100) / question.answers_total_votes).round(2) + ((total_votes*100) / question.answers_total_votes).round(2) rescue 0 end end diff --git a/db/migrate/20171019095042_add_most_voted_to_poll_question_answer.rb b/db/migrate/20171019095042_add_most_voted_to_poll_question_answer.rb new file mode 100644 index 000000000..e32b7e325 --- /dev/null +++ b/db/migrate/20171019095042_add_most_voted_to_poll_question_answer.rb @@ -0,0 +1,5 @@ +class AddMostVotedToPollQuestionAnswer < ActiveRecord::Migration + def change + add_column :poll_question_answers, :most_voted, :boolean + end +end diff --git a/db/schema.rb b/db/schema.rb index 8a03412be..f83358423 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20171010143623) do +ActiveRecord::Schema.define(version: 20171019095042) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -486,6 +486,10 @@ ActiveRecord::Schema.define(version: 20171010143623) do t.boolean "draft_publication_enabled", default: false t.boolean "result_publication_enabled", default: false t.boolean "published", default: true + t.date "proposals_phase_start_date" + t.date "proposals_phase_end_date" + t.boolean "proposals_phase_enabled" + t.text "proposals_description" end add_index "legislation_processes", ["allegations_end_date"], name: "index_legislation_processes_on_allegations_end_date", using: :btree @@ -498,6 +502,36 @@ ActiveRecord::Schema.define(version: 20171010143623) do add_index "legislation_processes", ["result_publication_date"], name: "index_legislation_processes_on_result_publication_date", using: :btree add_index "legislation_processes", ["start_date"], name: "index_legislation_processes_on_start_date", using: :btree + create_table "legislation_proposals", force: :cascade do |t| + t.integer "legislation_process_id" + t.string "title", limit: 80 + t.text "description" + t.string "question" + t.string "external_url" + t.integer "author_id" + t.datetime "hidden_at" + t.integer "flags_count", default: 0 + t.datetime "ignored_flag_at" + t.integer "cached_votes_up", default: 0 + t.integer "comments_count", default: 0 + t.datetime "confirmed_hide_at" + t.integer "hot_score", limit: 8, default: 0 + t.integer "confidence_score", default: 0 + t.string "responsible_name", limit: 60 + t.text "summary" + t.string "video_url" + t.tsvector "tsv" + t.integer "geozone_id" + t.datetime "retired_at" + t.string "retired_reason" + t.text "retired_explanation" + t.integer "community_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "legislation_proposals", ["legislation_process_id"], name: "index_legislation_proposals_on_legislation_process_id", using: :btree + create_table "legislation_question_options", force: :cascade do |t| t.integer "legislation_question_id" t.string "value" @@ -666,6 +700,7 @@ ActiveRecord::Schema.define(version: 20171010143623) do t.text "description" t.integer "question_id" t.integer "given_order", default: 1 + t.boolean "most_voted" end add_index "poll_question_answers", ["question_id"], name: "index_poll_question_answers_on_question_id", using: :btree @@ -919,16 +954,20 @@ ActiveRecord::Schema.define(version: 20171010143623) do add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree create_table "tags", force: :cascade do |t| - t.string "name", limit: 40 - t.integer "taggings_count", default: 0 - t.integer "debates_count", default: 0 - t.integer "proposals_count", default: 0 - t.integer "spending_proposals_count", default: 0 + t.string "name", limit: 40 + t.integer "taggings_count", default: 0 + t.integer "debates_count", default: 0 + t.integer "proposals_count", default: 0 + t.integer "spending_proposals_count", default: 0 t.string "kind" - t.integer "budget/investments_count", default: 0 + t.integer "budget/investments_count", default: 0 + t.integer "legislation/proposals_count", default: 0 + t.integer "legislation/processes_count", default: 0 end add_index "tags", ["debates_count"], name: "index_tags_on_debates_count", using: :btree + add_index "tags", ["legislation/processes_count"], name: "index_tags_on_legislation/processes_count", using: :btree + add_index "tags", ["legislation/proposals_count"], name: "index_tags_on_legislation/proposals_count", using: :btree add_index "tags", ["name"], name: "index_tags_on_name", unique: true, using: :btree add_index "tags", ["proposals_count"], name: "index_tags_on_proposals_count", using: :btree add_index "tags", ["spending_proposals_count"], name: "index_tags_on_spending_proposals_count", using: :btree @@ -1106,6 +1145,7 @@ ActiveRecord::Schema.define(version: 20171010143623) do add_foreign_key "identities", "users" add_foreign_key "images", "users" add_foreign_key "legislation_draft_versions", "legislation_processes" + add_foreign_key "legislation_proposals", "legislation_processes" add_foreign_key "locks", "users" add_foreign_key "managers", "users" add_foreign_key "moderators", "users" From f029cc20165840121d54ab0231fca7e33bd7a6e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Thu, 19 Oct 2017 12:17:33 +0200 Subject: [PATCH 144/211] Cached Poll stats methods --- app/models/poll/stats.rb | 118 ++++++++++++++++++++++----------------- 1 file changed, 68 insertions(+), 50 deletions(-) diff --git a/app/models/poll/stats.rb b/app/models/poll/stats.rb index 1df281434..ac45a2aae 100644 --- a/app/models/poll/stats.rb +++ b/app/models/poll/stats.rb @@ -16,110 +16,128 @@ class Poll end private - + def total_participants - total_participants_web + total_participants_booth + stats_cache('total_participants') { total_participants_web + total_participants_booth } end def total_participants_web - total_web_valid + total_web_white + total_web_null + stats_cache('total_participants_web') { total_web_valid + total_web_white + total_web_null } end - + def total_participants_web_percentage - (total_participants) == 0 ? 0 : total_participants_web * 100 / total_participants + stats_cache('total_participants_web_percentage') { + (total_participants) == 0 ? 0 : total_participants_web * 100 / total_participants + } end def total_participants_booth - voters.where(origin: 'booth').count + stats_cache('total_participants_booth') { voters.where(origin: 'booth').count } end - + def total_participants_booth_percentage - (total_participants) == 0 ? 0 : total_participants_booth * 100 / total_participants.to_f + stats_cache('total_participants_booth_percentage') { + (total_participants) == 0 ? 0 : total_participants_booth * 100 / total_participants.to_f + } end - + def total_web_valid - voters.where(origin: 'web').count + stats_cache('total_web_valid') { voters.where(origin: 'web').count } end - + def valid_percentage_web - (total_valid_votes) == 0 ? 0 : total_web_valid * 100 / total_valid_votes.to_f + stats_cache('valid_percentage_web') { + (total_valid_votes) == 0 ? 0 : total_web_valid * 100 / total_valid_votes.to_f + } end - + def total_web_white - 0 + stats_cache('total_web_white') { 0 } end - + def white_percentage_web - 0 + stats_cache('white_percentage_web') { 0 } end - + def total_web_null - 0 + stats_cache('total_web_null') { 0 } end - + def null_percentage_web - 0 + stats_cache('null_percentage_web') { 0 } end - + def total_booth_valid - recounts.sum(:total_amount) + stats_cache('total_booth_valid') { recounts.sum(:total_amount) } end - + def valid_percentage_booth - (total_valid_votes) == 0 ? 0 : total_booth_valid * 100 / total_valid_votes.to_f + stats_cache('valid_percentage_booth') { + (total_valid_votes) == 0 ? 0 : total_booth_valid * 100 / total_valid_votes.to_f + } end - - def total_booth_white - recounts.sum(:white_amount) + + def total_booth_white + stats_cache('total_booth_white') { recounts.sum(:white_amount) } end - + def white_percentage_booth - (total_white_votes) == 0 ? 0 : total_booth_white * 100 / total_white_votes.to_f + stats_cache('white_percentage_booth') { + (total_white_votes) == 0 ? 0 : total_booth_white * 100 / total_white_votes.to_f + } end - + def total_booth_null - recounts.sum(:null_amount) + stats_cache('total_booth_null') { recounts.sum(:null_amount) } end - + def null_percentage_booth - (total_null_votes == 0) ? 0 : total_booth_null * 100 / total_null_votes.to_f + stats_cache('null_percentage_booth') { + (total_null_votes == 0) ? 0 : total_booth_null * 100 / total_null_votes.to_f + } end - + def total_valid_votes - total_web_valid + total_booth_valid + stats_cache('total_valid_votes') { total_web_valid + total_booth_valid } end - + def total_valid_percentage - (total_participants) == 0 ? 0 : total_valid_votes * 100 / total_participants.to_f + stats_cache('total_valid_percentage'){ + (total_participants) == 0 ? 0 : total_valid_votes * 100 / total_participants.to_f + } end - + def total_white_votes - total_web_white + total_booth_white + stats_cache('total_white_votes') { total_web_white + total_booth_white } end - + def total_white_percentage - (total_participants) == 0 ? 0 : total_white_votes * 100 / total_participants.to_f + stats_cache('total_white_percentage') { + (total_participants) == 0 ? 0 : total_white_votes * 100 / total_participants.to_f + } end - + def total_null_votes - total_web_null + total_booth_null + stats_cache('total_null_votes') { total_web_null + total_booth_null } end - + def total_null_percentage - (total_participants) == 0 ? 0 : total_null_votes * 100 / total_participants.to_f + stats_cache('total_null_percentage') { + (total_participants) == 0 ? 0 : total_null_votes * 100 / total_participants.to_f + } end def voters - @poll.voters + stats_cache('voters') { @poll.voters } end - + def recounts - @poll.recounts + stats_cache('recounts') { @poll.recounts } end def stats_cache(key, &block) - Rails.cache.fetch("polls_stats/#{@poll.id}/#{key}/v7", &block) + Rails.cache.fetch("polls_stats/#{@poll.id}/#{key}", &block) end end -end \ No newline at end of file +end From 8be8bb07f9b681047154a90d0c808ef22ff56f14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Thu, 19 Oct 2017 12:17:49 +0200 Subject: [PATCH 145/211] Added first poll results tests --- spec/features/polls/results_spec.rb | 26 ++++++++++++++++++++++++++ spec/features/polls/voter_spec.rb | 4 ++-- spec/support/common_actions.rb | 6 +++--- 3 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 spec/features/polls/results_spec.rb diff --git a/spec/features/polls/results_spec.rb b/spec/features/polls/results_spec.rb new file mode 100644 index 000000000..c67ad3869 --- /dev/null +++ b/spec/features/polls/results_spec.rb @@ -0,0 +1,26 @@ +require 'rails_helper' + +feature 'Poll Results' do + scenario 'List each Poll question' do + user = create(:user, :level_two) + + poll = create(:poll) + question1 = create(:poll_question, poll: poll) + answer1 = create(:poll_question_answer, question: question1, title: 'Yes') + answer2 = create(:poll_question_answer, question: question1, title: 'No') + + question2 = create(:poll_question, poll: poll) + answer3 = create(:poll_question_answer, question: question2, title: 'Blue') + answer4 = create(:poll_question_answer, question: question2, title: 'Green') + answer5 = create(:poll_question_answer, question: question2, title: 'Yellow') + + login_as user + vote_for_poll_via_web(poll, question1, 'Yes') + vote_for_poll_via_web(poll, question1, 'Blue') + + visit poll_results_path(poll) + + expect(page).to have_content(question1.title) + expect(page).to have_content(question2.title) + end +end diff --git a/spec/features/polls/voter_spec.rb b/spec/features/polls/voter_spec.rb index ff9b71755..7e451be17 100644 --- a/spec/features/polls/voter_spec.rb +++ b/spec/features/polls/voter_spec.rb @@ -95,7 +95,7 @@ feature "Voter" do scenario "Trying to vote in web and then in booth", :js do login_as user - vote_for_poll_via_web(poll, question) + vote_for_poll_via_web(poll, question, 'Yes') click_link "Sign out" @@ -127,7 +127,7 @@ feature "Voter" do scenario "Trying to vote in web again", :js do login_as user - vote_for_poll_via_web(poll, question) + vote_for_poll_via_web(poll, question, 'Yes') visit poll_path(poll) diff --git a/spec/support/common_actions.rb b/spec/support/common_actions.rb index b87a54d8e..90deab1b5 100644 --- a/spec/support/common_actions.rb +++ b/spec/support/common_actions.rb @@ -299,12 +299,12 @@ module CommonActions end end - def vote_for_poll_via_web(poll, question) + def vote_for_poll_via_web(poll, question, answer) visit poll_path(poll) within("#poll_question_#{question.id}_answers") do - click_link 'Yes' - expect(page).to_not have_link('Yes') + click_link "#{answer}" + expect(page).to_not have_link("#{answer}") end expect(Poll::Voter.count).to eq(1) From 78fa77b28d8d6f7d334a54c4f4aec576e58084e0 Mon Sep 17 00:00:00 2001 From: decabeza Date: Thu, 19 Oct 2017 12:23:14 +0200 Subject: [PATCH 146/211] fixes styles for poll subnav --- app/assets/stylesheets/layout.scss | 2 ++ app/views/polls/_poll_subnav.html.erb | 42 ++++++++++++++++----------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index 06fdfd396..d79a2b37f 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -214,6 +214,8 @@ a { margin-bottom: $line-height / 2; li { + font-size: $base-font-size; + margin-bottom: 0; margin-right: $line-height / 2; @include breakpoint(medium) { diff --git a/app/views/polls/_poll_subnav.html.erb b/app/views/polls/_poll_subnav.html.erb index 9b37e1867..8155e2ef4 100644 --- a/app/views/polls/_poll_subnav.html.erb +++ b/app/views/polls/_poll_subnav.html.erb @@ -1,21 +1,29 @@ -
    +
    -
      -
    • - <%= link_to t("polls.show.results_menu"), - poll_results_path(@poll), - class: (controller_name == "polls" && action_name == "results" ? "is-active" : "") %> -
    • -
    • - <%= link_to t("polls.show.stats_menu"), - poll_stats_path(@poll), - class: (controller_name == "polls" && action_name == "stats" ? "is-active" : "") %> -
    • -
    • - <%= link_to t("polls.show.info_menu"), - poll_path(@poll), - class: (controller_name == "polls" && action_name == "show" ? "is-active" : "") %> -
    • +
    From a0eb6e56a10da349ed3f8c22d84c7a7385c34db2 Mon Sep 17 00:00:00 2001 From: decabeza Date: Thu, 19 Oct 2017 12:23:57 +0200 Subject: [PATCH 147/211] fixes styles for polls tabs, uses underscore for ids --- app/assets/stylesheets/layout.scss | 13 ++++++++----- app/views/polls/_filter_subnav.html.erb | 6 +++--- app/views/polls/show.html.erb | 4 ++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index d79a2b37f..9e6d3bc08 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -318,13 +318,16 @@ a { } .tabs { - border: { - left: 0; - right: 0; - top: 0; - }; + border-left: 0; + border-right: 0; + border-top: 0; margin-bottom: $line-height; + .tabs-title { + font-size: $base-font-size; + margin-bottom: 0; + } + .tabs-title > a { color: $text-medium; margin-bottom: rem-calc(-1); diff --git a/app/views/polls/_filter_subnav.html.erb b/app/views/polls/_filter_subnav.html.erb index b096edaf2..fe43ddf5d 100644 --- a/app/views/polls/_filter_subnav.html.erb +++ b/app/views/polls/_filter_subnav.html.erb @@ -1,8 +1,8 @@ -
    +
    -
      +
      • - <%= link_to "#tab-comments" do %> + <%= link_to "#tab_comments" do %>

        <%= t("polls.show.comments_tab") %> (<%= @poll.comments_count %>) diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index 4eabd240b..01bdddc54 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -124,10 +124,10 @@

    -
    +
    <%= render "filter_subnav" %> -
    +
    <%= render "comments" %>
    From e13a48b57219eb2226a6ba65adf642b983965573 Mon Sep 17 00:00:00 2001 From: decabeza Date: Thu, 19 Oct 2017 12:27:22 +0200 Subject: [PATCH 148/211] adds styles to polls stats --- app/assets/stylesheets/layout.scss | 4 + app/assets/stylesheets/participation.scss | 50 ++++++++ app/views/polls/stats.html.erb | 136 +++++++++++++--------- 3 files changed, 134 insertions(+), 56 deletions(-) diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index 9e6d3bc08..9428c1982 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -381,6 +381,10 @@ a { box-shadow: none; } +.uppercase { + text-transform: uppercase; +} + // 02. Header // ---------- diff --git a/app/assets/stylesheets/participation.scss b/app/assets/stylesheets/participation.scss index a887d83de..382615739 100644 --- a/app/assets/stylesheets/participation.scss +++ b/app/assets/stylesheets/participation.scss @@ -8,6 +8,7 @@ // 06. Budget // 07. Proposals successful // 08. Polls +// 09. Polls results and stats // // 01. Votes and supports @@ -1803,3 +1804,52 @@ } } } + +// 09. Polls results and stats +// --------------------------- + +.polls-results-stats { + + .sidebar { + border-right: 1px solid $border; + + .menu { + padding: 0; + + li a { + color: $link; + } + } + } + + table { + table-layout: fixed; + + caption { + padding: $line-height / 2 0; + text-align: left; + } + + th { + text-align: left; + + &.win { + background: #009fde; + } + } + + td { + + &.win { + background: #ccedf8; + font-weight: bold; + } + } + } + + .number { + font-size: rem-calc(60); + font-weight: bold; + line-height: rem-calc(60); + } +} diff --git a/app/views/polls/stats.html.erb b/app/views/polls/stats.html.erb index 20e5411ab..5daaf433a 100644 --- a/app/views/polls/stats.html.erb +++ b/app/views/polls/stats.html.erb @@ -1,25 +1,28 @@ <% provide :title do %><%= @poll.name %><% end %> -
    +
    <%= render "poll_header" %> <%= render "poll_subnav" %> -
    -
    <%= t("admin.results.results_by_booth.booth") %>
    <%= booth_assignment.booth.name %> - <%= link_to t("admin.results.results_by_booth.see_results"), - admin_poll_booth_assignment_path(@poll, booth_assignment, - anchor: "tab-results") %> + <%= link_to t("admin.results.results_by_booth.see_results"), + admin_poll_booth_assignment_path(@poll, booth_assignment, anchor: "tab-results") %>
    + +
    @@ -30,60 +33,81 @@ - - - - + + + + - - - - + + + + - - - - + + + + - - - + + + From f20db4e3e4710b63a7a2647471f4203d0cc5c7db Mon Sep 17 00:00:00 2001 From: Bertocq Date: Thu, 19 Oct 2017 13:32:48 +0200 Subject: [PATCH 149/211] Fix user helper expectation --- spec/helpers/users_helper_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/helpers/users_helper_spec.rb b/spec/helpers/users_helper_spec.rb index 55ea8445b..fe2cdd786 100644 --- a/spec/helpers/users_helper_spec.rb +++ b/spec/helpers/users_helper_spec.rb @@ -35,7 +35,7 @@ describe UsersHelper do investment.hide - expect(comment_commentable_title(comment)).to eq '' + comment.commentable.title + ' (This investment has been deleted)' + expect(comment_commentable_title(comment)).to eq '' + comment.commentable.title + ' (This investment project has been deleted)' end end From 3daf9578134d1f512ffcc990b9cb48afee002f65 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Thu, 19 Oct 2017 13:35:04 +0200 Subject: [PATCH 150/211] Fix table tag indentation --- app/views/admin/poll/results/_results_by_booth.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/admin/poll/results/_results_by_booth.html.erb b/app/views/admin/poll/results/_results_by_booth.html.erb index 9266a58fb..f270adaab 100644 --- a/app/views/admin/poll/results/_results_by_booth.html.erb +++ b/app/views/admin/poll/results/_results_by_booth.html.erb @@ -1,5 +1,5 @@

    <%= t("admin.results.results_by_booth.title") %>

    -
    <%= t("polls.show.stats.votes") %>
    <%= t("polls.show.stats.valid") %><%= @stats[:total_web_valid] %> - (<%= number_to_percentage(@stats[:valid_percentage_web], - strip_insignificant_zeros: true, - precision: 2) %>)<%= @stats[:total_booth_valid] %> - (<%= number_to_percentage(@stats[:valid_percentage_booth], - strip_insignificant_zeros: true, - precision: 2) %>)<%= @stats[:total_valid_votes] %> - (<%= number_to_percentage(@stats[:total_valid_percentage], - strip_insignificant_zeros: true, - precision: 2) %>)<%= t("polls.show.stats.valid") %> + <%= @stats[:total_web_valid] %> + (<%= number_to_percentage(@stats[:valid_percentage_web], + strip_insignificant_zeros: true, + precision: 2) %>) + + <%= @stats[:total_booth_valid] %> + (<%= number_to_percentage(@stats[:valid_percentage_booth], + strip_insignificant_zeros: true, + precision: 2) %>) + + <%= @stats[:total_valid_votes] %> + (<%= number_to_percentage(@stats[:total_valid_percentage], + strip_insignificant_zeros: true, + precision: 2) %>) +
    <%= t("polls.show.stats.white") %><%= @stats[:total_web_white] %> - (<%= number_to_percentage(@stats[:white_percentage_web], - strip_insignificant_zeros: true, - precision: 2) %>)<%= @stats[:total_booth_white] %> - (<%= number_to_percentage(@stats[:white_percentage_booth], - strip_insignificant_zeros: true, - precision: 2) %>)<%= @stats[:total_white_votes] %> - (<%= number_to_percentage(@stats[:total_white_percentage], - strip_insignificant_zeros: true, - precision: 2) %>)<%= t("polls.show.stats.white") %> + <%= @stats[:total_web_white] %> + (<%= number_to_percentage(@stats[:white_percentage_web], + strip_insignificant_zeros: true, + precision: 2) %>) + + <%= @stats[:total_booth_white] %> + (<%= number_to_percentage(@stats[:white_percentage_booth], + strip_insignificant_zeros: true, + precision: 2) %>) + <%= @stats[:total_white_votes] %> + (<%= number_to_percentage(@stats[:total_white_percentage], + strip_insignificant_zeros: true, + precision: 2) %>) +
    <%= t("polls.show.stats.null_votes") %><%= @stats[:total_web_null] %> - (<%= number_to_percentage(@stats[:null_percentage_web], - strip_insignificant_zeros: true, - precision: 2) %>)<%= @stats[:total_booth_null] %> - (<%= number_to_percentage(@stats[:null_percentage_booth], - strip_insignificant_zeros: true, - precision: 2) %>)<%= @stats[:total_null_votes] %> - (<%= number_to_percentage(@stats[:total_null_percentage], - strip_insignificant_zeros: true, - precision: 2) %>)<%= t("polls.show.stats.null_votes") %> + <%= @stats[:total_web_null] %> + (<%= number_to_percentage(@stats[:null_percentage_web], + strip_insignificant_zeros: true, + precision: 2) %>) + + <%= @stats[:total_booth_null] %> + (<%= number_to_percentage(@stats[:null_percentage_booth], + strip_insignificant_zeros: true, + precision: 2) %>) + + <%= @stats[:total_null_votes] %> + (<%= number_to_percentage(@stats[:total_null_percentage], + strip_insignificant_zeros: true, + precision: 2) %>) +
    <%= t("polls.show.stats.total") %><%= @stats[:total_participants_web] %> - (<%= number_to_percentage(@stats[:total_participants_web_percentage], - strip_insignificant_zeros: true, - precision: 2) %>)<%= @stats[:total_participants_booth] %> - (<%= number_to_percentage(@stats[:total_participants_booth_percentage], - strip_insignificant_zeros: true, - precision: 2) %>)<%= t("polls.show.stats.total") %> + <%= @stats[:total_participants_web] %> + (<%= number_to_percentage(@stats[:total_participants_web_percentage], + strip_insignificant_zeros: true, + precision: 2) %>) + + <%= @stats[:total_participants_booth] %> + (<%= number_to_percentage(@stats[:total_participants_booth_percentage], + strip_insignificant_zeros: true, + precision: 2) %>) + <%= @stats[:total_participants_web] + @stats[:total_participants_booth] %>
    +
    @@ -17,4 +17,4 @@ <% end %> -
    <%= t("admin.results.results_by_booth.booth") %>
    \ No newline at end of file +
    From 45d91a7e502eaeb99062b088dba5213b2a24babb Mon Sep 17 00:00:00 2001 From: Bertocq Date: Thu, 19 Oct 2017 19:27:26 +0200 Subject: [PATCH 151/211] Add Poll booth_assignments and :Poll::BoothAssignment manage routes, actions and views --- .../poll/booth_assignments_controller.rb | 4 +++ .../admin/poll/polls_controller.rb | 4 +++ app/models/abilities/administrator.rb | 4 +-- app/views/admin/_menu.html.erb | 7 +++++- .../poll/booth_assignments/manage.html.erb | 25 +++++++++++++++++++ .../poll/polls/booth_assignments.html.erb | 18 +++++++++++++ config/locales/en/admin.yml | 1 + config/locales/es/admin.yml | 1 + config/routes.rb | 4 ++- 9 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 app/views/admin/poll/booth_assignments/manage.html.erb create mode 100644 app/views/admin/poll/polls/booth_assignments.html.erb diff --git a/app/controllers/admin/poll/booth_assignments_controller.rb b/app/controllers/admin/poll/booth_assignments_controller.rb index 7998f29a2..221a623ef 100644 --- a/app/controllers/admin/poll/booth_assignments_controller.rb +++ b/app/controllers/admin/poll/booth_assignments_controller.rb @@ -45,6 +45,10 @@ class Admin::Poll::BoothAssignmentsController < Admin::Poll::BaseController redirect_to admin_poll_booth_assignments_path(@booth_assignment.poll_id), notice: notice end + def manage + @booths = ::Poll::Booth.all + end + private def load_booth_assignment diff --git a/app/controllers/admin/poll/polls_controller.rb b/app/controllers/admin/poll/polls_controller.rb index 5103275fb..8ba6e934e 100644 --- a/app/controllers/admin/poll/polls_controller.rb +++ b/app/controllers/admin/poll/polls_controller.rb @@ -47,6 +47,10 @@ class Admin::Poll::PollsController < Admin::Poll::BaseController redirect_to admin_poll_path(@poll), notice: notice end + def booth_assignments + @polls = Poll.current_or_incoming + end + private def load_geozones diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index 1bc8d5e0c..704f9be24 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -56,10 +56,10 @@ module Abilities can [:index, :create, :edit, :update, :destroy], Geozone - can [:read, :create, :update, :destroy, :add_question, :search_booths, :search_officers], Poll + can [:read, :create, :update, :destroy, :add_question, :search_booths, :search_officers, :booth_assignments], Poll can [:read, :create, :update, :destroy, :available], Poll::Booth can [:search, :create, :index, :destroy], ::Poll::Officer - can [:create, :destroy], ::Poll::BoothAssignment + can [:create, :destroy, :manage], ::Poll::BoothAssignment can [:create, :destroy], ::Poll::OfficerAssignment can [:read, :create, :update], Poll::Question can :destroy, Poll::Question # , comments_count: 0, votes_up: 0 diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index f2af2c116..0518aa0e3 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -60,7 +60,8 @@ <%= t("admin.menu.title_polls") %>
      > -
    • > +
    • > <%= link_to t('admin.menu.polls'), admin_polls_path %>
    • @@ -84,6 +85,10 @@ action_name == "available" %>> <%= link_to t('admin.menu.poll_shifts'), available_admin_booths_path %> + +
    • > + <%= link_to t('admin.menu.poll_booth_assignments'), booth_assignments_admin_polls_path %> +
    <% end %> diff --git a/app/views/admin/poll/booth_assignments/manage.html.erb b/app/views/admin/poll/booth_assignments/manage.html.erb new file mode 100644 index 000000000..65cec228a --- /dev/null +++ b/app/views/admin/poll/booth_assignments/manage.html.erb @@ -0,0 +1,25 @@ +

    <%= t("admin.booths.index.title") %>

    + +<% if controller_name == "booths" && action_name != "available" %> + <%= link_to t("admin.booths.index.add_booth"), new_admin_booth_path, class: "button success float-right" %> +<% end %> + +<% if @booths.empty? %> +
    + <%= t("admin.booths.index.no_booths") %> +
    +<% end %> + +<% if @booths.any? %> + + + + + + + <% @booths.each do |booth| %> + <% end %> + +
    <%= t("admin.booths.index.name") %><%= t("admin.actions.actions") %>
    + +<% end %> diff --git a/app/views/admin/poll/polls/booth_assignments.html.erb b/app/views/admin/poll/polls/booth_assignments.html.erb new file mode 100644 index 000000000..0d9bf98ce --- /dev/null +++ b/app/views/admin/poll/polls/booth_assignments.html.erb @@ -0,0 +1,18 @@ +

    <%= t("admin.polls.index.title") %>

    + +<% if @polls.any? %> + + + + + + + + <%= render @polls %> + +
    <%= t("admin.polls.index.name") %><%= t("admin.polls.index.dates") %><%= t("admin.actions.actions") %>
    +<% else %> +
    + <%= t("admin.polls.index.no_polls") %> +
    +<% end %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 38abe6f56..a2657a2b3 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -409,6 +409,7 @@ en: poll_officers: Poll officers polls: Polls poll_booths: Booths location + poll_booth_assignments: Booths Assignments poll_shifts: Manage shifts officials: Officials organizations: Organisations diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 3336cdc5b..4c56e131c 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -420,6 +420,7 @@ es: poll_officers: Presidentes de mesa polls: Votaciones poll_booths: Ubicación de urnas + poll_booth_assignments: Asignación de urnas poll_shifts: Asignar turnos officials: Cargos públicos organizations: Organizaciones diff --git a/config/routes.rb b/config/routes.rb index ae4f7280c..6f94594a3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -111,7 +111,7 @@ Rails.application.routes.draw do resources :annotations do get :search, on: :collection end - + resources :polls, only: [:show, :index] do resources :questions, controller: 'polls/questions', shallow: true do post :answer, on: :member @@ -273,10 +273,12 @@ Rails.application.routes.draw do scope module: :poll do resources :polls do + get :booth_assignments, on: :collection patch :add_question, on: :member resources :booth_assignments, only: [:index, :show, :create, :destroy] do get :search_booths, on: :collection + get :manage, on: :collection end resources :officer_assignments, only: [:index, :create, :destroy] do From c52c0a5452f8e1170401dc871834b7c531870dd7 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Thu, 19 Oct 2017 19:42:00 +0200 Subject: [PATCH 152/211] Complete Poll list with booth assigment management links --- .../admin/poll/polls/booth_assignments.html.erb | 16 +++++++++++++++- config/locales/en/admin.yml | 2 ++ config/locales/es/admin.yml | 2 ++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/app/views/admin/poll/polls/booth_assignments.html.erb b/app/views/admin/poll/polls/booth_assignments.html.erb index 0d9bf98ce..819474852 100644 --- a/app/views/admin/poll/polls/booth_assignments.html.erb +++ b/app/views/admin/poll/polls/booth_assignments.html.erb @@ -8,7 +8,21 @@ <%= t("admin.actions.actions") %> - <%= render @polls %> + <% @polls.each do |poll| %> + + + <%= poll.name %> + + + <%= l poll.starts_at.to_date %> - <%= l poll.ends_at.to_date %> + + + <%= link_to t("admin.booth_assignments.manage_assignments"), + manage_admin_poll_booth_assignments_path(poll), + class: "button hollow" %> + + + <% end %> <% else %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index a2657a2b3..863ae8688 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -525,6 +525,8 @@ en: date_missing: "A date must be selected" vote_collection: Collect Votes recount_scrutiny: Recount & Scrutiny + booth_assignments: + manage_assignments: Manage assignments poll_booth_assignments: flash: destroy: "Booth not assigned anymore" diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 4c56e131c..a7d4d2c81 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -525,6 +525,8 @@ es: date_missing: "Debe seleccionarse una fecha" vote_collection: Recoger Votos recount_scrutiny: Recuento & Escrutinio + booth_assignments: + manage_assignments: Gestionar asignaciones poll_booth_assignments: flash: destroy: "Urna desasignada" From f8839434f77d37a2243f3af77ba1f8239248148d Mon Sep 17 00:00:00 2001 From: Bertocq Date: Thu, 19 Oct 2017 20:10:51 +0200 Subject: [PATCH 153/211] Complete booth assignment view list without actions yet --- .../admin/poll/booth_assignments_controller.rb | 1 + .../_booth_assignment.html.erb | 17 +++++++++++++++++ .../poll/booth_assignments/manage.html.erb | 16 ++++++++-------- config/locales/en/admin.yml | 9 +++++++++ config/locales/es/admin.yml | 9 +++++++++ 5 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 app/views/admin/poll/booth_assignments/_booth_assignment.html.erb diff --git a/app/controllers/admin/poll/booth_assignments_controller.rb b/app/controllers/admin/poll/booth_assignments_controller.rb index 221a623ef..ab3f52d11 100644 --- a/app/controllers/admin/poll/booth_assignments_controller.rb +++ b/app/controllers/admin/poll/booth_assignments_controller.rb @@ -47,6 +47,7 @@ class Admin::Poll::BoothAssignmentsController < Admin::Poll::BaseController def manage @booths = ::Poll::Booth.all + @poll = Poll.find(params[:poll_id]) end private diff --git a/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb b/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb new file mode 100644 index 000000000..06188df9c --- /dev/null +++ b/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb @@ -0,0 +1,17 @@ + + + <%= link_to booth.name, admin_booth_path(booth) %> + + + <%= t("admin.booth_assignments.status.assigned") %> + <%= t("admin.booth_assignments.status.unassigned") %> + + + <%= link_to t("admin.booth_assignments.manage.assign"), + new_admin_booth_shift_path(booth), + class: "button" %> + <%= link_to t("admin.booth_assignments.manage.unassign"), + new_admin_booth_shift_path(booth), + class: "button hollow" %> + + diff --git a/app/views/admin/poll/booth_assignments/manage.html.erb b/app/views/admin/poll/booth_assignments/manage.html.erb index 65cec228a..c76485cc9 100644 --- a/app/views/admin/poll/booth_assignments/manage.html.erb +++ b/app/views/admin/poll/booth_assignments/manage.html.erb @@ -1,25 +1,25 @@ -

    <%= t("admin.booths.index.title") %>

    - -<% if controller_name == "booths" && action_name != "available" %> - <%= link_to t("admin.booths.index.add_booth"), new_admin_booth_path, class: "button success float-right" %> +<%= link_to booth_assignments_admin_polls_path do %> + <%= t("shared.back") %> <% end %> +
    + +

    <%= t("admin.booth_assignments.manage.assignments_list", poll: @poll.name) %>

    <% if @booths.empty? %>
    <%= t("admin.booths.index.no_booths") %>
    -<% end %> - -<% if @booths.any? %> +<% else %> + <% @booths.each do |booth| %> + <%= render partial: "booth_assignment", locals: { booth: booth } %> <% end %>
    <%= t("admin.booths.index.name") %><%= t("admin.booth_assignments.status.assign_status") %> <%= t("admin.actions.actions") %>
    - <% end %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 863ae8688..398744720 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -527,6 +527,15 @@ en: recount_scrutiny: Recount & Scrutiny booth_assignments: manage_assignments: Manage assignments + manage: + assignments_list: "Assignments for poll '%{poll}'" + status: + assign_status: Assignment + assigned: Assigned + unassigned: Unassigned + actions: + assign: Assign booth + unassign: Unassign booth poll_booth_assignments: flash: destroy: "Booth not assigned anymore" diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index a7d4d2c81..7169d6017 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -527,6 +527,15 @@ es: recount_scrutiny: Recuento & Escrutinio booth_assignments: manage_assignments: Gestionar asignaciones + manage: + assignments_list: "Asignaciones para la votación '%{poll}'" + status: + assign_status: Asignación + assigned: Asignada + unassigned: No asignada + actions: + assign: Assign booth + unassign: Unassign booth poll_booth_assignments: flash: destroy: "Urna desasignada" From e6efd8ad7d7c385ea5f97a7252dd8a283ac5d0f7 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Thu, 19 Oct 2017 20:54:42 +0200 Subject: [PATCH 154/211] Remove assign/unassign booth to poll from poll booth assigments list --- .../booth_assignments/_search_booths_results.html.erb | 9 --------- app/views/admin/poll/booth_assignments/index.html.erb | 7 ------- config/locales/en/admin.yml | 2 -- config/locales/es/admin.yml | 2 -- 4 files changed, 20 deletions(-) diff --git a/app/views/admin/poll/booth_assignments/_search_booths_results.html.erb b/app/views/admin/poll/booth_assignments/_search_booths_results.html.erb index 3fa7fc080..cebde154c 100644 --- a/app/views/admin/poll/booth_assignments/_search_booths_results.html.erb +++ b/app/views/admin/poll/booth_assignments/_search_booths_results.html.erb @@ -12,7 +12,6 @@ <%= t("admin.poll_booth_assignments.index.table_name") %> <%= t("admin.poll_booth_assignments.index.table_location") %> - <%= t("admin.poll_booth_assignments.index.table_assignment") %> @@ -24,14 +23,6 @@ <%= booth.location %> - - <% unless @poll.booth_ids.include?(booth.id) %> - <%= link_to t("admin.poll_booth_assignments.index.add_booth"), - admin_poll_booth_assignments_path(@poll, booth_id: booth.id), - method: :post, - class: "button hollow" %> - <% end %> - <% end %> diff --git a/app/views/admin/poll/booth_assignments/index.html.erb b/app/views/admin/poll/booth_assignments/index.html.erb index f14e59ef1..fcedaec79 100644 --- a/app/views/admin/poll/booth_assignments/index.html.erb +++ b/app/views/admin/poll/booth_assignments/index.html.erb @@ -14,7 +14,6 @@ <%= t("admin.poll_booth_assignments.index.table_name") %> <%= t("admin.poll_booth_assignments.index.table_location") %> - <%= t("admin.poll_booth_assignments.index.table_assignment") %> <% @booth_assignments.each do |booth_assignment| %> @@ -27,12 +26,6 @@ <%= booth_assignment.booth.location %> - - <%= link_to t("admin.poll_booth_assignments.index.remove_booth"), - admin_poll_booth_assignment_path(@poll, booth_assignment), - method: :delete, - class: "button hollow alert" %> - <% end %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 398744720..d991ad85f 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -559,8 +559,6 @@ en: no_booths: "There are no booths assigned to this poll." table_name: "Name" table_location: "Location" - table_assignment: "Assignment" - remove_booth: "Remove booth from poll" add_booth: "Assign booth" polls: index: diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 7169d6017..1ac21c633 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -559,8 +559,6 @@ es: no_booths: "No hay urnas asignadas a esta votación." table_name: "Nombre" table_location: "Ubicación" - table_assignment: "Asignación" - remove_booth: "Desasignar urna" add_booth: "Asignar urna" polls: index: From 7507f43ea813a63ac56cd71936ff4097fbeb1d2c Mon Sep 17 00:00:00 2001 From: Bertocq Date: Thu, 19 Oct 2017 21:30:31 +0200 Subject: [PATCH 155/211] Add helper method on Booth model to get booth assigment for a given poll --- app/models/poll/booth.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/models/poll/booth.rb b/app/models/poll/booth.rb index 04f9d3dea..07e7d2456 100644 --- a/app/models/poll/booth.rb +++ b/app/models/poll/booth.rb @@ -15,5 +15,8 @@ class Poll where(polls: { id: Poll.current_or_incoming }).includes(:polls) end + def assignment_on_poll(poll) + booth_assignments.where(poll: poll).first + end end -end \ No newline at end of file +end From ca9e807cd4134aa4677848fa16c8d08b2d5d4288 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Thu, 19 Oct 2017 21:30:57 +0200 Subject: [PATCH 156/211] Add link to booth assignment management at poll booth assigments list --- app/views/admin/poll/booth_assignments/index.html.erb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/views/admin/poll/booth_assignments/index.html.erb b/app/views/admin/poll/booth_assignments/index.html.erb index fcedaec79..39435254b 100644 --- a/app/views/admin/poll/booth_assignments/index.html.erb +++ b/app/views/admin/poll/booth_assignments/index.html.erb @@ -1,10 +1,16 @@ <%= render "/admin/poll/polls/poll_header" %> + +
    <%= render "/admin/poll/polls/subnav" %> <%= render "search_booths" %>

    <%= t("admin.poll_booth_assignments.index.booths_title") %>

    + <%= link_to t("admin.booth_assignments.manage_assignments"), + manage_admin_poll_booth_assignments_path(@poll), + class: "button hollow float-right" %> + <% if @booth_assignments.empty? %>
    <%= t("admin.poll_booth_assignments.index.no_booths") %> From 68b7528bab4f7a44967c01a1bae988d684050482 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Thu, 19 Oct 2017 21:31:36 +0200 Subject: [PATCH 157/211] Complete booth assigment partial with assign/unassign buttons and status --- .../_booth_assignment.html.erb | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb b/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb index 06188df9c..5956b5342 100644 --- a/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb +++ b/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb @@ -1,17 +1,28 @@ - + + <%= link_to booth.name, admin_booth_path(booth) %> + +<% if booth_assignment.present? %> - <%= link_to booth.name, admin_booth_path(booth) %> - - - <%= t("admin.booth_assignments.status.assigned") %> - <%= t("admin.booth_assignments.status.unassigned") %> + <%= t("admin.booth_assignments.status.assigned") %> - <%= link_to t("admin.booth_assignments.manage.assign"), - new_admin_booth_shift_path(booth), - class: "button" %> - <%= link_to t("admin.booth_assignments.manage.unassign"), - new_admin_booth_shift_path(booth), - class: "button hollow" %> + <%= link_to t("admin.booth_assignments.manage.actions.unassign"), + admin_poll_booth_assignment_path(@poll, booth_assignment, booth_id: booth.id), + method: :delete, + remote: true, + title: t("admin.booth_assignments.manage.actions.unassign"), + class: "button hollow alert" %> - +<% else %> + + <%= t("admin.booth_assignments.status.unassigned") %> + + + <%= link_to t("admin.booth_assignments.manage.actions.assign"), + admin_poll_booth_assignments_path(@poll, booth_id: booth.id), + method: :post, + remote: true, + title: t("admin.booth_assignments.manage.actions.assign"), + class: "button" %> + +<% end %> From ce25780f70f122bd52796b6ce12c5c4decea5b36 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Thu, 19 Oct 2017 21:32:09 +0200 Subject: [PATCH 158/211] Use booth assigment partial correctly --- app/views/admin/poll/booth_assignments/manage.html.erb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/admin/poll/booth_assignments/manage.html.erb b/app/views/admin/poll/booth_assignments/manage.html.erb index c76485cc9..fab5b8487 100644 --- a/app/views/admin/poll/booth_assignments/manage.html.erb +++ b/app/views/admin/poll/booth_assignments/manage.html.erb @@ -18,7 +18,9 @@ <% @booths.each do |booth| %> - <%= render partial: "booth_assignment", locals: { booth: booth } %> + + <%= render partial: "booth_assignment", locals: { booth: booth, booth_assignment: booth.assignment_on_poll(@poll) } %> + <% end %> From 085e6ecba4c6d19856c2168067cb746cd6dc9718 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Thu, 19 Oct 2017 21:32:37 +0200 Subject: [PATCH 159/211] Complete booth assigment create/destroy methods to work with ajax --- .../admin/poll/booth_assignments_controller.rb | 16 ++++++++++++---- .../admin/poll/booth_assignments/create.js.erb | 1 + .../admin/poll/booth_assignments/destroy.js.erb | 1 + 3 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 app/views/admin/poll/booth_assignments/create.js.erb create mode 100644 app/views/admin/poll/booth_assignments/destroy.js.erb diff --git a/app/controllers/admin/poll/booth_assignments_controller.rb b/app/controllers/admin/poll/booth_assignments_controller.rb index ab3f52d11..5b9ea9d7b 100644 --- a/app/controllers/admin/poll/booth_assignments_controller.rb +++ b/app/controllers/admin/poll/booth_assignments_controller.rb @@ -23,18 +23,24 @@ class Admin::Poll::BoothAssignmentsController < Admin::Poll::BaseController end def create - @booth_assignment = ::Poll::BoothAssignment.new(poll_id: booth_assignment_params[:poll_id], - booth_id: booth_assignment_params[:booth_id]) + @poll = Poll.find(booth_assignment_params[:poll_id]) + @booth = Poll::Booth.find(booth_assignment_params[:booth_id]) + @booth_assignment = ::Poll::BoothAssignment.new(poll: @poll, + booth: @booth) if @booth_assignment.save notice = t("admin.poll_booth_assignments.flash.create") else notice = t("admin.poll_booth_assignments.flash.error_create") end - redirect_to admin_poll_booth_assignments_path(@booth_assignment.poll_id), notice: notice + respond_to do |format| + format.js { render layout: false } + end end def destroy + @poll = Poll.find(booth_assignment_params[:poll_id]) + @booth = Poll::Booth.find(booth_assignment_params[:booth_id]) @booth_assignment = ::Poll::BoothAssignment.find(params[:id]) if @booth_assignment.destroy @@ -42,7 +48,9 @@ class Admin::Poll::BoothAssignmentsController < Admin::Poll::BaseController else notice = t("admin.poll_booth_assignments.flash.error_destroy") end - redirect_to admin_poll_booth_assignments_path(@booth_assignment.poll_id), notice: notice + respond_to do |format| + format.js { render layout: false } + end end def manage diff --git a/app/views/admin/poll/booth_assignments/create.js.erb b/app/views/admin/poll/booth_assignments/create.js.erb new file mode 100644 index 000000000..8b278f7b3 --- /dev/null +++ b/app/views/admin/poll/booth_assignments/create.js.erb @@ -0,0 +1 @@ +$("#<%= dom_id(@booth) %>").html('<%= j render("booth_assignment", booth: @booth, booth_assignment: @booth.assignment_on_poll(@poll)) %>'); diff --git a/app/views/admin/poll/booth_assignments/destroy.js.erb b/app/views/admin/poll/booth_assignments/destroy.js.erb new file mode 100644 index 000000000..8b278f7b3 --- /dev/null +++ b/app/views/admin/poll/booth_assignments/destroy.js.erb @@ -0,0 +1 @@ +$("#<%= dom_id(@booth) %>").html('<%= j render("booth_assignment", booth: @booth, booth_assignment: @booth.assignment_on_poll(@poll)) %>'); From 9b70b90e6a0d5dd295429c480ae6aa12b1367a26 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Thu, 19 Oct 2017 22:05:02 +0200 Subject: [PATCH 160/211] Fix texts for booth assignment management --- .../admin/poll/booth_assignments/_booth_assignment.html.erb | 4 ++-- app/views/admin/poll/booth_assignments/manage.html.erb | 2 +- config/locales/en/admin.yml | 1 - config/locales/es/admin.yml | 1 - 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb b/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb index 5956b5342..7865b201e 100644 --- a/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb +++ b/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb @@ -3,7 +3,7 @@ <% if booth_assignment.present? %> - <%= t("admin.booth_assignments.status.assigned") %> + <%= t("admin.booth_assignments.manage.status.assigned") %> <%= link_to t("admin.booth_assignments.manage.actions.unassign"), @@ -15,7 +15,7 @@ <% else %> - <%= t("admin.booth_assignments.status.unassigned") %> + <%= t("admin.booth_assignments.manage.status.unassigned") %> <%= link_to t("admin.booth_assignments.manage.actions.assign"), diff --git a/app/views/admin/poll/booth_assignments/manage.html.erb b/app/views/admin/poll/booth_assignments/manage.html.erb index fab5b8487..f55e85c74 100644 --- a/app/views/admin/poll/booth_assignments/manage.html.erb +++ b/app/views/admin/poll/booth_assignments/manage.html.erb @@ -13,7 +13,7 @@ - + diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index d991ad85f..3826e9764 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -559,7 +559,6 @@ en: no_booths: "There are no booths assigned to this poll." table_name: "Name" table_location: "Location" - add_booth: "Assign booth" polls: index: title: "List of polls" diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 1ac21c633..9bc97c35f 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -559,7 +559,6 @@ es: no_booths: "No hay urnas asignadas a esta votación." table_name: "Nombre" table_location: "Ubicación" - add_booth: "Asignar urna" polls: index: title: "Listado de votaciones" From 17e6a66b80a9e8573c5e82dc031d0d3b8ab7bffe Mon Sep 17 00:00:00 2001 From: Bertocq Date: Thu, 19 Oct 2017 22:33:00 +0200 Subject: [PATCH 161/211] Refactor booth assigment management feature specs to test new assign/unassign feature --- .../admin/poll/booth_assigments_spec.rb | 139 ++++++++++++------ 1 file changed, 91 insertions(+), 48 deletions(-) diff --git a/spec/features/admin/poll/booth_assigments_spec.rb b/spec/features/admin/poll/booth_assigments_spec.rb index 5813e2dac..cceec1a3e 100644 --- a/spec/features/admin/poll/booth_assigments_spec.rb +++ b/spec/features/admin/poll/booth_assigments_spec.rb @@ -7,66 +7,109 @@ feature 'Admin booths assignments' do login_as(admin.user) end - scenario 'Assign booth to poll', :js do - poll = create(:poll) - booth = create(:poll_booth) + feature 'Admin Booth Assignment management' do - visit admin_poll_path(poll) - within('#poll-resources') do - click_link 'Booths (0)' + let!(:poll) { create(:poll) } + let!(:booth) { create(:poll_booth) } + + scenario 'List Polls and Booths to manage', :js do + second_poll = create(:poll) + second_booth = create(:poll_booth) + + visit booth_assignments_admin_polls_path + + expect(page).to have_content(poll.name) + expect(page).to have_content(second_poll.name) + + within("#poll_#{second_poll.id}") do + click_link 'Manage assignments' + end + + expect(page).to have_content "Assignments for poll '#{second_poll.name}'" + + expect(page).to have_content(booth.name) + expect(page).to have_content(second_booth.name) end - expect(page).to have_content 'There are no booths assigned to this poll.' + scenario 'Assign booth to poll', :js do + visit admin_poll_path(poll) + within('#poll-resources') do + click_link 'Booths (0)' + end - fill_in 'search-booths', with: booth.name - click_button 'Search' - expect(page).to have_content(booth.name) + expect(page).to have_content 'There are no booths assigned to this poll.' + expect(page).to_not have_content booth.name - within('#search-booths-results') do - click_link 'Assign booth' + fill_in 'search-booths', with: booth.name + click_button 'Search' + expect(page).to have_content(booth.name) + + visit manage_admin_poll_booth_assignments_path(poll) + + expect(page).to have_content "Assignments for poll '#{poll.name}'" + + within("#poll_booth_#{booth.id}") do + expect(page).to have_content(booth.name) + expect(page).to have_content "Unassigned" + + click_link 'Assign booth' + + expect(page).not_to have_content "Unassigned" + expect(page).to have_content "Assigned" + expect(page).to have_link "Unassign booth" + end + + visit admin_poll_path(poll) + within('#poll-resources') do + click_link 'Booths (1)' + end + + expect(page).to_not have_content 'There are no booths assigned to this poll.' + expect(page).to have_content booth.name end - expect(page).to have_content 'Booth assigned' + scenario 'Unassign booth from poll', :js do + assignment = create(:poll_booth_assignment, poll: poll, booth: booth) - visit admin_poll_path(poll) - within('#poll-resources') do - click_link 'Booths (1)' + visit admin_poll_path(poll) + within('#poll-resources') do + click_link 'Booths (1)' + end + + expect(page).not_to have_content 'There are no booths assigned to this poll.' + expect(page).to have_content booth.name + + fill_in 'search-booths', with: booth.name + click_button 'Search' + expect(page).to have_content(booth.name) + + visit manage_admin_poll_booth_assignments_path(poll) + + expect(page).to have_content "Assignments for poll '#{poll.name}'" + + within("#poll_booth_#{booth.id}") do + expect(page).to have_content(booth.name) + expect(page).to have_content "Assigned" + + click_link 'Unassign booth' + + expect(page).to have_content "Unassigned" + expect(page).not_to have_content "Assigned" + expect(page).to have_link "Assign booth" + end + + visit admin_poll_path(poll) + within('#poll-resources') do + click_link 'Booths (0)' + end + + expect(page).to have_content 'There are no booths assigned to this poll.' + expect(page).not_to have_content booth.name end - - expect(page).to_not have_content 'There are no booths assigned to this poll.' - expect(page).to have_content booth.name - end - - scenario 'Remove booth from poll', :js do - poll = create(:poll) - booth = create(:poll_booth) - assignment = create(:poll_booth_assignment, poll: poll, booth: booth) - - visit admin_poll_path(poll) - within('#poll-resources') do - click_link 'Booths (1)' - end - - expect(page).to_not have_content 'There are no booths assigned to this poll.' - expect(page).to have_content booth.name - - within("#poll_booth_assignment_#{assignment.id}") do - click_link 'Remove booth from poll' - end - - expect(page).to have_content 'Booth not assigned anymore' - - visit admin_poll_path(poll) - within('#poll-resources') do - click_link 'Booths (0)' - end - - expect(page).to have_content 'There are no booths assigned to this poll.' - expect(page).to_not have_content booth.name end feature 'Show' do - scenario 'Lists all assigned poll oficers' do + scenario 'Lists all assigned poll officers' do poll = create(:poll) booth = create(:poll_booth) booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth) From 9de9a81b8cd641880fdaa03c0fc2940e7f57ebf5 Mon Sep 17 00:00:00 2001 From: Manuel Ortega Date: Fri, 20 Oct 2017 14:12:31 +0200 Subject: [PATCH 162/211] Added reference to event on the .on method('ajax:success',... --- app/assets/javascripts/prevent_double_submission.js.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/prevent_double_submission.js.coffee b/app/assets/javascripts/prevent_double_submission.js.coffee index abb8f8314..56a099730 100644 --- a/app/assets/javascripts/prevent_double_submission.js.coffee +++ b/app/assets/javascripts/prevent_double_submission.js.coffee @@ -25,7 +25,7 @@ App.PreventDoubleSubmission = unless event.target.id == "new_officing_voter" buttons = $(this).find(':button, :submit') App.PreventDoubleSubmission.disable_buttons(buttons) - ).on('ajax:success', -> + ).on('ajax:success', (event) -> unless event.target.id == "new_officing_voter" buttons = $(this).find(':button, :submit') App.PreventDoubleSubmission.reset_buttons(buttons) From 9bbf0b1ef9a1edba7ca111d06709e4649a39f629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Fri, 20 Oct 2017 16:48:54 +0200 Subject: [PATCH 163/211] Improved `most_voted` method --- app/controllers/polls/questions_controller.rb | 4 ++++ app/models/poll/question/answer.rb | 17 ++++++++++------- app/views/polls/results.html.erb | 6 +++--- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/app/controllers/polls/questions_controller.rb b/app/controllers/polls/questions_controller.rb index 407e6d984..6345773f2 100644 --- a/app/controllers/polls/questions_controller.rb +++ b/app/controllers/polls/questions_controller.rb @@ -13,6 +13,10 @@ class Polls::QuestionsController < ApplicationController answer.touch if answer.persisted? answer.save! answer.record_voter_participation(token) + @question.question_answers + .where(question_id: @question, title: answer.answer) + .first + .set_most_voted @answers_by_question_id = { @question.id => params[:answer] } end diff --git a/app/models/poll/question/answer.rb b/app/models/poll/question/answer.rb index eff45a57a..8241aa78e 100644 --- a/app/models/poll/question/answer.rb +++ b/app/models/poll/question/answer.rb @@ -13,7 +13,6 @@ class Poll::Question::Answer < ActiveRecord::Base validates :given_order, presence: true, uniqueness: { scope: :question_id } before_validation :set_order, on: :create - before_save :most_voted def description super.try :html_safe @@ -37,15 +36,19 @@ class Poll::Question::Answer < ActiveRecord::Base Poll::Answer.where(question_id: question, answer: title).count end - def most_voted - answers = question.question_answers - .map { |a| Poll::Answer.where(question_id: a.question, answer: a.title).count } - most_voted = !answers.any?{ |a| a > total_votes } - - self.update_attributes(most_voted: most_voted) + def most_voted? + self.most_voted end def total_votes_percentage ((total_votes*100) / question.answers_total_votes).round(2) rescue 0 end + + def set_most_voted + answers = question.question_answers + .map { |a| Poll::Answer.where(question_id: a.question, answer: a.title).count } + is_most_voted = !answers.any?{ |a| a > self.total_votes } + + self.update(most_voted: is_most_voted) + end end diff --git a/app/views/polls/results.html.erb b/app/views/polls/results.html.erb index f0c9e4a38..c8e9cbfab 100644 --- a/app/views/polls/results.html.erb +++ b/app/views/polls/results.html.erb @@ -17,19 +17,19 @@
    <%- @poll.questions.each do |question| %> -
    <%= t("admin.booths.index.name") %><%= t("admin.booth_assignments.status.assign_status") %><%= t("admin.booth_assignments.manage.status.assign_status") %> <%= t("admin.actions.actions") %>
    +

    <%= question.title %>

    <%- question.question_answers.each do |answer| %> - + <% end %> <%- question.question_answers.each do |answer| %> - From bb06af3877240597acea5132b5918f8b23baca7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Fri, 20 Oct 2017 16:49:25 +0200 Subject: [PATCH 164/211] Improved results tests --- spec/features/polls/results_spec.rb | 35 +++++++++++++++++++++++++---- spec/features/polls/voter_spec.rb | 2 ++ spec/support/common_actions.rb | 2 -- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/spec/features/polls/results_spec.rb b/spec/features/polls/results_spec.rb index c67ad3869..b17fb463a 100644 --- a/spec/features/polls/results_spec.rb +++ b/spec/features/polls/results_spec.rb @@ -1,8 +1,10 @@ require 'rails_helper' feature 'Poll Results' do - scenario 'List each Poll question' do - user = create(:user, :level_two) + scenario 'List each Poll question', :js do + user1 = create(:user, :level_two) + user2 = create(:user, :level_two) + user3 = create(:user, :level_two) poll = create(:poll) question1 = create(:poll_question, poll: poll) @@ -14,13 +16,38 @@ feature 'Poll Results' do answer4 = create(:poll_question_answer, question: question2, title: 'Green') answer5 = create(:poll_question_answer, question: question2, title: 'Yellow') - login_as user + login_as user1 vote_for_poll_via_web(poll, question1, 'Yes') - vote_for_poll_via_web(poll, question1, 'Blue') + vote_for_poll_via_web(poll, question2, 'Blue') + expect(Poll::Voter.count).to eq(1) + logout + + login_as user2 + vote_for_poll_via_web(poll, question1, 'Yes') + vote_for_poll_via_web(poll, question2, 'Green') + expect(Poll::Voter.count).to eq(2) + logout + + login_as user3 + vote_for_poll_via_web(poll, question1, 'No') + vote_for_poll_via_web(poll, question2, 'Yellow') + expect(Poll::Voter.count).to eq(3) + logout visit poll_results_path(poll) expect(page).to have_content(question1.title) expect(page).to have_content(question2.title) + + within("#question_#{question1.id}_results_table") do + expect(find("#answer_#{answer1.id}_result")).to have_content("2 (66.0%)") + expect(find("#answer_#{answer2.id}_result")).to have_content("1 (33.0%)") + end + + within("#question_#{question2.id}_results_table") do + expect(find("#answer_#{answer3.id}_result")).to have_content("1 (33.0%)") + expect(find("#answer_#{answer4.id}_result")).to have_content("1 (33.0%)") + expect(find("#answer_#{answer5.id}_result")).to have_content("1 (33.0%)") + end end end diff --git a/spec/features/polls/voter_spec.rb b/spec/features/polls/voter_spec.rb index 7e451be17..aee0ff522 100644 --- a/spec/features/polls/voter_spec.rb +++ b/spec/features/polls/voter_spec.rb @@ -96,6 +96,7 @@ feature "Voter" do scenario "Trying to vote in web and then in booth", :js do login_as user vote_for_poll_via_web(poll, question, 'Yes') + expect(Poll::Voter.count).to eq(1) click_link "Sign out" @@ -128,6 +129,7 @@ feature "Voter" do scenario "Trying to vote in web again", :js do login_as user vote_for_poll_via_web(poll, question, 'Yes') + expect(Poll::Voter.count).to eq(1) visit poll_path(poll) diff --git a/spec/support/common_actions.rb b/spec/support/common_actions.rb index 90deab1b5..5023c1952 100644 --- a/spec/support/common_actions.rb +++ b/spec/support/common_actions.rb @@ -306,8 +306,6 @@ module CommonActions click_link "#{answer}" expect(page).to_not have_link("#{answer}") end - - expect(Poll::Voter.count).to eq(1) end def vote_for_poll_via_booth From dfa8f4590aebd51978d5da4879cb307b0f1f0551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Fri, 20 Oct 2017 16:57:41 +0200 Subject: [PATCH 165/211] Most voted fix --- app/controllers/polls/questions_controller.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/controllers/polls/questions_controller.rb b/app/controllers/polls/questions_controller.rb index 6345773f2..e1fc73805 100644 --- a/app/controllers/polls/questions_controller.rb +++ b/app/controllers/polls/questions_controller.rb @@ -13,10 +13,9 @@ class Polls::QuestionsController < ApplicationController answer.touch if answer.persisted? answer.save! answer.record_voter_participation(token) - @question.question_answers - .where(question_id: @question, title: answer.answer) - .first - .set_most_voted + @question.question_answers.where(question_id: @question).each do |answer| + answer.set_most_voted + end @answers_by_question_id = { @question.id => params[:answer] } end From 796fe333e30eb7523ef92584bf39b2fb347d5c90 Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 20 Oct 2017 17:05:23 +0200 Subject: [PATCH 166/211] adds case when topic on notifications controller --- app/controllers/notifications_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index 16a82de6a..7d833f6a1 100644 --- a/app/controllers/notifications_controller.rb +++ b/app/controllers/notifications_controller.rb @@ -29,6 +29,8 @@ class NotificationsController < ApplicationController case notification.linkable_resource.class.name when "Budget::Investment" budget_investment_path @notification.linkable_resource.budget, @notification.linkable_resource + when "Topic" + community_topic_path @notification.linkable_resource.community, @notification.linkable_resource else url_for @notification.linkable_resource end From 45133a917fb742a9d2eb43a5a10d60806c57648a Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 20 Oct 2017 17:07:44 +0200 Subject: [PATCH 167/211] adds topic notifications specs --- spec/features/notifications_spec.rb | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/spec/features/notifications_spec.rb b/spec/features/notifications_spec.rb index 9925b0d56..75ed91857 100644 --- a/spec/features/notifications_spec.rb +++ b/spec/features/notifications_spec.rb @@ -14,6 +14,12 @@ feature "Notifications" do let(:legislation_question) { create(:legislation_question, process: process, author: administrator) } let(:legislation_annotation) { create(:legislation_annotation, author: author) } + let(:topic) { + proposal = create(:proposal) + community = proposal.community + create(:topic, community: community, author: author) + } + scenario "User commented on my debate", :js do create(:notification, notifiable: debate, user: author) login_as author @@ -40,6 +46,19 @@ feature "Notifications" do expect(page).to have_xpath "//a[@href='#{notification_path(Notification.last)}']" end + scenario "User commented on my topic", :js do + create(:notification, notifiable: topic, user: author) + login_as author + visit root_path + + find(".icon-notification").click + + expect(page).to have_css ".notification", count: 1 + + expect(page).to have_content "Someone commented on" + expect(page).to have_xpath "//a[@href='#{notification_path(Notification.last)}']" + end + scenario "Multiple comments on my proposal", :js do login_as user visit proposal_path proposal From e85c98f4b447c2f30ebe490cb3dec3b64e247a6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Fri, 20 Oct 2017 17:18:54 +0200 Subject: [PATCH 168/211] Improved results and stats percentages --- app/models/poll/question/answer.rb | 2 +- app/views/polls/results.html.erb | 6 ++-- app/views/polls/stats.html.erb | 44 ++++++++---------------------- 3 files changed, 15 insertions(+), 37 deletions(-) diff --git a/app/models/poll/question/answer.rb b/app/models/poll/question/answer.rb index 8241aa78e..dbf2f2139 100644 --- a/app/models/poll/question/answer.rb +++ b/app/models/poll/question/answer.rb @@ -41,7 +41,7 @@ class Poll::Question::Answer < ActiveRecord::Base end def total_votes_percentage - ((total_votes*100) / question.answers_total_votes).round(2) rescue 0 + question.answers_total_votes == 0 ? 0 : (total_votes * 100) / question.answers_total_votes end def set_most_voted diff --git a/app/views/polls/results.html.erb b/app/views/polls/results.html.erb index c8e9cbfab..697382ed2 100644 --- a/app/views/polls/results.html.erb +++ b/app/views/polls/results.html.erb @@ -1,6 +1,6 @@ <% provide :title do %><%= @poll.name %><% end %> -
    +
    <%= render "poll_header" %> <%= render "poll_subnav" %> @@ -18,7 +18,7 @@
    <%- @poll.questions.each do |question| %>
    ><%= answer.title %>><%= answer.title %>
    > + > <%= answer.total_votes %> (<%= answer.total_votes_percentage %>%)
    -

    <%= question.title %>

    +

    <%= question.title %>

    <%- question.question_answers.each do |answer| %> @@ -31,7 +31,7 @@ <%- question.question_answers.each do |answer| %> <% end %> diff --git a/app/views/polls/stats.html.erb b/app/views/polls/stats.html.erb index 5daaf433a..3a4d99dba 100644 --- a/app/views/polls/stats.html.erb +++ b/app/views/polls/stats.html.erb @@ -36,77 +36,55 @@ From b42bacd588e1ee9491f5156a586130d618cd9701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Fri, 20 Oct 2017 17:26:32 +0200 Subject: [PATCH 169/211] `most_voted` to false by default --- .../20171019095042_add_most_voted_to_poll_question_answer.rb | 2 +- db/schema.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/db/migrate/20171019095042_add_most_voted_to_poll_question_answer.rb b/db/migrate/20171019095042_add_most_voted_to_poll_question_answer.rb index e32b7e325..e4650643b 100644 --- a/db/migrate/20171019095042_add_most_voted_to_poll_question_answer.rb +++ b/db/migrate/20171019095042_add_most_voted_to_poll_question_answer.rb @@ -1,5 +1,5 @@ class AddMostVotedToPollQuestionAnswer < ActiveRecord::Migration def change - add_column :poll_question_answers, :most_voted, :boolean + add_column :poll_question_answers, :most_voted, :boolean, default: false end end diff --git a/db/schema.rb b/db/schema.rb index 29dbe0500..b2c99b9be 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -700,7 +700,7 @@ ActiveRecord::Schema.define(version: 20171019095042) do t.text "description" t.integer "question_id" t.integer "given_order", default: 1 - t.boolean "most_voted" + t.boolean "most_voted", default: false end add_index "poll_question_answers", ["question_id"], name: "index_poll_question_answers_on_question_id", using: :btree From c13268718ad292fc7401e48474aff73217e2adaa Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 20 Oct 2017 18:34:39 +0200 Subject: [PATCH 170/211] fixes line height on menu sidebar --- app/assets/stylesheets/participation.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/stylesheets/participation.scss b/app/assets/stylesheets/participation.scss index 20b586f23..ff2af5f2b 100644 --- a/app/assets/stylesheets/participation.scss +++ b/app/assets/stylesheets/participation.scss @@ -1814,6 +1814,7 @@ li a { color: $link; + line-height: $line-height; } } } From 5ebd630b27b505faf63a7aba298c88ab0ec2f56e Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 20 Oct 2017 18:35:03 +0200 Subject: [PATCH 171/211] adds answer most voted text for screen readers --- app/views/polls/results.html.erb | 7 ++++++- config/locales/en/general.yml | 2 ++ config/locales/es/general.yml | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/views/polls/results.html.erb b/app/views/polls/results.html.erb index 697382ed2..884f341f7 100644 --- a/app/views/polls/results.html.erb +++ b/app/views/polls/results.html.erb @@ -22,7 +22,12 @@ <%- question.question_answers.each do |answer| %> - + <% end %> diff --git a/config/locales/en/general.yml b/config/locales/en/general.yml index 6e4b9b662..586a90a45 100644 --- a/config/locales/en/general.yml +++ b/config/locales/en/general.yml @@ -513,6 +513,8 @@ en: valid: "Valid" white: "White votes" null_votes: "Invalid" + results: + most_voted_answer: "Most voted answer: " poll_questions: create_question: "Create question" show: diff --git a/config/locales/es/general.yml b/config/locales/es/general.yml index 2acbb540e..08fe25e1e 100644 --- a/config/locales/es/general.yml +++ b/config/locales/es/general.yml @@ -513,6 +513,8 @@ es: valid: "Válidos" white: "En blanco" null_votes: "Nulos" + results: + most_voted_answer: "Respuesta más votada: " poll_questions: create_question: "Crear pregunta para votación" show: From 9fc35e9087d957fd205d958854bc9f97fac2dfc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Fri, 20 Oct 2017 18:44:56 +0200 Subject: [PATCH 172/211] Added `results_enabled` and `stats_enabled` to Poll --- ...20163240_add_results_and_stats_to_polls.rb | 6 ++ db/schema.rb | 56 ++++++++++++++++--- 2 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 db/migrate/20171020163240_add_results_and_stats_to_polls.rb diff --git a/db/migrate/20171020163240_add_results_and_stats_to_polls.rb b/db/migrate/20171020163240_add_results_and_stats_to_polls.rb new file mode 100644 index 000000000..af6f82aaa --- /dev/null +++ b/db/migrate/20171020163240_add_results_and_stats_to_polls.rb @@ -0,0 +1,6 @@ +class AddResultsAndStatsToPolls < ActiveRecord::Migration + def change + add_column :polls, :results_enabled, :boolean, default: false + add_column :polls, :stats_enabled, :boolean, default: false + end +end diff --git a/db/schema.rb b/db/schema.rb index c3ccbeac7..f8dd19c13 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20171017221546) do +ActiveRecord::Schema.define(version: 20171020163240) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -486,6 +486,10 @@ ActiveRecord::Schema.define(version: 20171017221546) do t.boolean "draft_publication_enabled", default: false t.boolean "result_publication_enabled", default: false t.boolean "published", default: true + t.date "proposals_phase_start_date" + t.date "proposals_phase_end_date" + t.boolean "proposals_phase_enabled" + t.text "proposals_description" end add_index "legislation_processes", ["allegations_end_date"], name: "index_legislation_processes_on_allegations_end_date", using: :btree @@ -498,6 +502,36 @@ ActiveRecord::Schema.define(version: 20171017221546) do add_index "legislation_processes", ["result_publication_date"], name: "index_legislation_processes_on_result_publication_date", using: :btree add_index "legislation_processes", ["start_date"], name: "index_legislation_processes_on_start_date", using: :btree + create_table "legislation_proposals", force: :cascade do |t| + t.integer "legislation_process_id" + t.string "title", limit: 80 + t.text "description" + t.string "question" + t.string "external_url" + t.integer "author_id" + t.datetime "hidden_at" + t.integer "flags_count", default: 0 + t.datetime "ignored_flag_at" + t.integer "cached_votes_up", default: 0 + t.integer "comments_count", default: 0 + t.datetime "confirmed_hide_at" + t.integer "hot_score", limit: 8, default: 0 + t.integer "confidence_score", default: 0 + t.string "responsible_name", limit: 60 + t.text "summary" + t.string "video_url" + t.tsvector "tsv" + t.integer "geozone_id" + t.datetime "retired_at" + t.string "retired_reason" + t.text "retired_explanation" + t.integer "community_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "legislation_proposals", ["legislation_process_id"], name: "index_legislation_proposals_on_legislation_process_id", using: :btree + create_table "legislation_question_options", force: :cascade do |t| t.integer "legislation_question_id" t.string "value" @@ -666,6 +700,7 @@ ActiveRecord::Schema.define(version: 20171017221546) do t.text "description" t.integer "question_id" t.integer "given_order", default: 1 + t.boolean "most_voted", default: false end add_index "poll_question_answers", ["question_id"], name: "index_poll_question_answers_on_question_id", using: :btree @@ -759,6 +794,8 @@ ActiveRecord::Schema.define(version: 20171017221546) do t.integer "comments_count", default: 0 t.integer "author_id" t.datetime "hidden_at" + t.boolean "results_enabled", default: false + t.boolean "stats_enabled", default: false end add_index "polls", ["starts_at", "ends_at"], name: "index_polls_on_starts_at_and_ends_at", using: :btree @@ -918,16 +955,20 @@ ActiveRecord::Schema.define(version: 20171017221546) do add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree create_table "tags", force: :cascade do |t| - t.string "name", limit: 40 - t.integer "taggings_count", default: 0 - t.integer "debates_count", default: 0 - t.integer "proposals_count", default: 0 - t.integer "spending_proposals_count", default: 0 + t.string "name", limit: 40 + t.integer "taggings_count", default: 0 + t.integer "debates_count", default: 0 + t.integer "proposals_count", default: 0 + t.integer "spending_proposals_count", default: 0 t.string "kind" - t.integer "budget/investments_count", default: 0 + t.integer "budget/investments_count", default: 0 + t.integer "legislation/proposals_count", default: 0 + t.integer "legislation/processes_count", default: 0 end add_index "tags", ["debates_count"], name: "index_tags_on_debates_count", using: :btree + add_index "tags", ["legislation/processes_count"], name: "index_tags_on_legislation/processes_count", using: :btree + add_index "tags", ["legislation/proposals_count"], name: "index_tags_on_legislation/proposals_count", using: :btree add_index "tags", ["name"], name: "index_tags_on_name", unique: true, using: :btree add_index "tags", ["proposals_count"], name: "index_tags_on_proposals_count", using: :btree add_index "tags", ["spending_proposals_count"], name: "index_tags_on_spending_proposals_count", using: :btree @@ -1105,6 +1146,7 @@ ActiveRecord::Schema.define(version: 20171017221546) do add_foreign_key "identities", "users" add_foreign_key "images", "users" add_foreign_key "legislation_draft_versions", "legislation_processes" + add_foreign_key "legislation_proposals", "legislation_processes" add_foreign_key "locks", "users" add_foreign_key "managers", "users" add_foreign_key "moderators", "users" From 62b1998ec6ccbb4e9e5571ae044d1bc4deb4883d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Fri, 20 Oct 2017 18:45:34 +0200 Subject: [PATCH 173/211] Added `results_enabled` and `stats_enabled` to Poll admin form --- app/controllers/admin/poll/polls_controller.rb | 7 ++++--- app/models/poll.rb | 8 ++++++++ app/views/admin/poll/polls/_form.html.erb | 9 +++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/app/controllers/admin/poll/polls_controller.rb b/app/controllers/admin/poll/polls_controller.rb index 5103275fb..b146f66cc 100644 --- a/app/controllers/admin/poll/polls_controller.rb +++ b/app/controllers/admin/poll/polls_controller.rb @@ -54,9 +54,10 @@ class Admin::Poll::PollsController < Admin::Poll::BaseController end def poll_params - params.require(:poll).permit(:name, :starts_at, :ends_at, :geozone_restricted, :summary, :description, - geozone_ids: [], - image_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy]) + params.require(:poll).permit(:name, :starts_at, :ends_at, :geozone_restricted, + :summary, :description, :results_enabled,:stats_enabled, + geozone_ids: [], + image_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy]) end def search_params diff --git a/app/models/poll.rb b/app/models/poll.rb index 27125d8a1..e1a1c2754 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -90,4 +90,12 @@ class Poll < ActiveRecord::Base end end + def results_enabled? + results_enabled + end + + def stats_enabled? + stats_enabled + end + end diff --git a/app/views/admin/poll/polls/_form.html.erb b/app/views/admin/poll/polls/_form.html.erb index aff19d9d7..21f1a97f3 100644 --- a/app/views/admin/poll/polls/_form.html.erb +++ b/app/views/admin/poll/polls/_form.html.erb @@ -53,6 +53,15 @@ +
    +
    + <%= t('admin.polls.new.show_results_and_stats') %> + <%= f.check_box :results_enabled, checked: @poll.results_enabled?, label: t('admin.polls.new.show_results') %> + <%= f.check_box :stats_enabled, checked: @poll.stats_enabled?, label: t('admin.polls.new.show_stats') %> +

    <%= t('admin.polls.new.results_and_stats_reminder') %> +

    +
    +
    <%= f.submit t("admin.polls.#{admin_submit_action(@poll)}.submit_button"), From b64ef9f68972fef5518b08a321fd25813f6f2203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Fri, 20 Oct 2017 18:45:43 +0200 Subject: [PATCH 174/211] New translations --- config/locales/en/admin.yml | 4 ++++ config/locales/es/admin.yml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 38abe6f56..084a0443c 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -560,6 +560,10 @@ en: geozone_restricted: "Restricted to districts" new: title: "New poll" + show_results_and_stats: "Show results and stats" + show_results: "Show results" + show_stats: "Show stats" + results_and_stats_reminder: "Marking these checkboxes the results and/or stats of this poll will be publicly available and every user will see them." submit_button: "Create poll" edit: title: "Edit poll" diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 3336cdc5b..c13292f89 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -560,6 +560,10 @@ es: geozone_restricted: "Restringida a los distritos" new: title: "Nueva votación" + show_results_and_stats: "Mostrar resultados y estadísticas" + show_results: "Mostrar resultados" + show_stats: "Mostrar estadísticas" + results_and_stats_reminder: "Si marcas estas casillas los resultados y/o estadísticas de esta votación serán públicos y podrán verlos todos los usuarios." submit_button: "Crear votación" edit: title: "Editar votación" From 8ee35df35f5743b958f7d45ea3658b3dd88df672 Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 20 Oct 2017 20:56:01 +0200 Subject: [PATCH 175/211] changes poll title link if results or stats are enabled --- app/views/polls/_poll_group.html.erb | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/app/views/polls/_poll_group.html.erb b/app/views/polls/_poll_group.html.erb index 529e9a99e..9d83d5233 100644 --- a/app/views/polls/_poll_group.html.erb +++ b/app/views/polls/_poll_group.html.erb @@ -19,11 +19,27 @@
    <% if poll.questions.count == 1 %> <% poll.questions.each do |question| %> -

    <%= link_to question.title, poll %>

    +

    + <% if poll.results_enabled? %> + <%= link_to question.title, poll_results_path(poll) %> + <% elsif poll.stats_enabled? %> + <%= link_to question.title, poll_stats_path(poll) %> + <% else %> + <%= link_to question.title, poll %> + <% end %> +

    <%= poll_dates(poll) %> <% end %> <% else %> -

    <%= link_to poll.name, poll %>

    +

    + <% if poll.results_enabled? %> + <%= link_to poll.name, poll_results_path(poll) %> + <% elsif poll.stats_enabled? %> + <%= link_to poll.name, poll_stats_path(poll) %> + <% else %> + <%= link_to poll.name, poll %> + <% end %> +

    <%= poll_dates(poll) %>
      <% poll.questions.each do |question| %> From d21f0aa8a1427e25a7299f8984e89c27bdff8509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Fri, 20 Oct 2017 21:11:54 +0200 Subject: [PATCH 176/211] Hide results and stats from poll create form --- app/views/admin/poll/polls/_form.html.erb | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/app/views/admin/poll/polls/_form.html.erb b/app/views/admin/poll/polls/_form.html.erb index 21f1a97f3..4926e28ac 100644 --- a/app/views/admin/poll/polls/_form.html.erb +++ b/app/views/admin/poll/polls/_form.html.erb @@ -53,14 +53,16 @@
    -
    -
    - <%= t('admin.polls.new.show_results_and_stats') %> - <%= f.check_box :results_enabled, checked: @poll.results_enabled?, label: t('admin.polls.new.show_results') %> - <%= f.check_box :stats_enabled, checked: @poll.stats_enabled?, label: t('admin.polls.new.show_stats') %> -

    <%= t('admin.polls.new.results_and_stats_reminder') %> -

    -
    + <% if controller_name == "polls" && action_name == "edit" %> +
    +
    + <%= t('admin.polls.new.show_results_and_stats') %> + <%= f.check_box :results_enabled, checked: @poll.results_enabled?, label: t('admin.polls.new.show_results') %> + <%= f.check_box :stats_enabled, checked: @poll.stats_enabled?, label: t('admin.polls.new.show_stats') %> +

    <%= t('admin.polls.new.results_and_stats_reminder') %> +

    +
    + <% end %>
    From 995289304e24530533dbc8b4f2eaa4402b9559f8 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Thu, 19 Oct 2017 22:41:54 +0200 Subject: [PATCH 177/211] Add booth location on booth assigment management list, plus poll links on list --- .../admin/poll/booth_assignments/_booth_assignment.html.erb | 3 +++ app/views/admin/poll/booth_assignments/index.html.erb | 3 +-- app/views/admin/poll/booth_assignments/manage.html.erb | 1 + app/views/admin/poll/polls/booth_assignments.html.erb | 2 +- config/locales/en/admin.yml | 1 + config/locales/es/admin.yml | 1 + 6 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb b/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb index 7865b201e..d78f7be8b 100644 --- a/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb +++ b/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb @@ -1,6 +1,9 @@
    + <% if booth_assignment.present? %> <% end %> diff --git a/app/views/admin/poll/booth_assignments/manage.html.erb b/app/views/admin/poll/booth_assignments/manage.html.erb index f55e85c74..a24fac478 100644 --- a/app/views/admin/poll/booth_assignments/manage.html.erb +++ b/app/views/admin/poll/booth_assignments/manage.html.erb @@ -13,6 +13,7 @@
    > <%= answer.total_votes %> - (<%= answer.total_votes_percentage %>%) + (<%= answer.total_votes_percentage.round(2) %>%)
    <%= t("polls.show.stats.valid") %> <%= @stats[:total_web_valid] %> - (<%= number_to_percentage(@stats[:valid_percentage_web], - strip_insignificant_zeros: true, - precision: 2) %>) + (<%= @stats[:valid_percentage_web].round(2) %>%) <%= @stats[:total_booth_valid] %> - (<%= number_to_percentage(@stats[:valid_percentage_booth], - strip_insignificant_zeros: true, - precision: 2) %>) + (<%= @stats[:valid_percentage_booth].round(2) %>%) <%= @stats[:total_valid_votes] %> - (<%= number_to_percentage(@stats[:total_valid_percentage], - strip_insignificant_zeros: true, - precision: 2) %>) + (<%= @stats[:total_valid_percentage].round(2) %>%)
    <%= t("polls.show.stats.white") %> <%= @stats[:total_web_white] %> - (<%= number_to_percentage(@stats[:white_percentage_web], - strip_insignificant_zeros: true, - precision: 2) %>) + (<%= @stats[:white_percentage_web].round(2) %>%) <%= @stats[:total_booth_white] %> - (<%= number_to_percentage(@stats[:white_percentage_booth], - strip_insignificant_zeros: true, - precision: 2) %>) + (<%= @stats[:white_percentage_booth].round(2) %>%) <%= @stats[:total_white_votes] %> - (<%= number_to_percentage(@stats[:total_white_percentage], - strip_insignificant_zeros: true, - precision: 2) %>) + (<%= @stats[:total_white_percentage].round(2) %>%)
    <%= t("polls.show.stats.null_votes") %> <%= @stats[:total_web_null] %> - (<%= number_to_percentage(@stats[:null_percentage_web], - strip_insignificant_zeros: true, - precision: 2) %>) + (<%= @stats[:null_percentage_web].round(2) %>%) <%= @stats[:total_booth_null] %> - (<%= number_to_percentage(@stats[:null_percentage_booth], - strip_insignificant_zeros: true, - precision: 2) %>) + (<%= @stats[:null_percentage_booth].round(2) %>%) <%= @stats[:total_null_votes] %> - (<%= number_to_percentage(@stats[:total_null_percentage], - strip_insignificant_zeros: true, - precision: 2) %>) + (<%= @stats[:total_null_percentage].round(2) %>%)
    <%= t("polls.show.stats.total") %> <%= @stats[:total_participants_web] %> - (<%= number_to_percentage(@stats[:total_participants_web_percentage], - strip_insignificant_zeros: true, - precision: 2) %>) + (<%= @stats[:total_participants_web_percentage].round(2) %>%) <%= @stats[:total_participants_booth] %> - (<%= number_to_percentage(@stats[:total_participants_booth_percentage], - strip_insignificant_zeros: true, - precision: 2) %>) + (<%= @stats[:total_participants_booth_percentage].round(2) %>%) <%= @stats[:total_participants_web] + @stats[:total_participants_booth] %>
    ><%= answer.title %>> + <% if answer.most_voted %> + <%= t ("polls.show.results.most_voted_answer") %> + <% end %> + <%= answer.title %> +
    <%= link_to booth.name, admin_booth_path(booth) %> + <%= booth.location || t("admin.booths.index.no_location") %> + <%= t("admin.booth_assignments.manage.status.assigned") %> diff --git a/app/views/admin/poll/booth_assignments/index.html.erb b/app/views/admin/poll/booth_assignments/index.html.erb index 39435254b..75cbe889f 100644 --- a/app/views/admin/poll/booth_assignments/index.html.erb +++ b/app/views/admin/poll/booth_assignments/index.html.erb @@ -1,6 +1,5 @@ <%= render "/admin/poll/polls/poll_header" %> -
    <%= render "/admin/poll/polls/subnav" %> <%= render "search_booths" %> @@ -30,7 +29,7 @@
    - <%= booth_assignment.booth.location %> + <%= booth_assignment.booth.location || t("admin.booths.index.no_location") %>
    + diff --git a/app/views/admin/poll/polls/booth_assignments.html.erb b/app/views/admin/poll/polls/booth_assignments.html.erb index 819474852..ad5dc6211 100644 --- a/app/views/admin/poll/polls/booth_assignments.html.erb +++ b/app/views/admin/poll/polls/booth_assignments.html.erb @@ -11,7 +11,7 @@ <% @polls.each do |poll| %> From 96f588566a970e05e591703c851dcc6db199299c Mon Sep 17 00:00:00 2001 From: decabeza Date: Sun, 22 Oct 2017 01:06:03 +0200 Subject: [PATCH 187/211] changes id name to specs --- app/views/polls/_filter_subnav.html.erb | 2 +- app/views/polls/show.html.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/polls/_filter_subnav.html.erb b/app/views/polls/_filter_subnav.html.erb index fe43ddf5d..88ee5beb9 100644 --- a/app/views/polls/_filter_subnav.html.erb +++ b/app/views/polls/_filter_subnav.html.erb @@ -2,7 +2,7 @@
    • - <%= link_to "#tab_comments" do %> + <%= link_to "#tab-comments" do %>

      <%= t("polls.show.comments_tab") %> (<%= @poll.comments_count %>) diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index 01bdddc54..839b8725a 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -127,7 +127,7 @@
      <%= render "filter_subnav" %> -
      +
      <%= render "comments" %>
      From 6b5c29f23ec2429119fe7dc63e5d4922460bd896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Mon, 23 Oct 2017 12:25:51 +0200 Subject: [PATCH 188/211] Added tests --- spec/features/admin/poll/polls_spec.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb index 2a2d26ea5..8180a89f2 100644 --- a/spec/features/admin/poll/polls_spec.rb +++ b/spec/features/admin/poll/polls_spec.rb @@ -60,6 +60,10 @@ feature 'Admin polls' do fill_in 'poll_ends_at', with: end_date.strftime("%d/%m/%Y") fill_in 'poll_summary', with: "Upcoming poll's summary. This poll..." fill_in 'poll_description', with: "Upcomming poll's description. This poll..." + + expect(page).to_not have_css("#poll_results_enabled") + expect(page).to_not have_css("#poll_stats_enabled") + click_button "Create poll" expect(page).to have_content "Poll created successfully" @@ -79,6 +83,9 @@ feature 'Admin polls' do expect(page).to have_css("img[alt='#{poll.image.title}']") + expect(page).to have_css("#poll_results_enabled") + expect(page).to have_css("#poll_stats_enabled") + fill_in "poll_name", with: "Next Poll" fill_in 'poll_ends_at', with: end_date.strftime("%d/%m/%Y") From fad5841d8ff501279d4193c81ae3e5876339ae96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Mon, 23 Oct 2017 12:57:41 +0200 Subject: [PATCH 189/211] Improvements --- app/models/poll.rb | 8 ------- db/schema.rb | 52 ++++++---------------------------------------- 2 files changed, 6 insertions(+), 54 deletions(-) diff --git a/app/models/poll.rb b/app/models/poll.rb index e1a1c2754..27125d8a1 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -90,12 +90,4 @@ class Poll < ActiveRecord::Base end end - def results_enabled? - results_enabled - end - - def stats_enabled? - stats_enabled - end - end diff --git a/db/schema.rb b/db/schema.rb index f8dd19c13..506153b6a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -486,10 +486,6 @@ ActiveRecord::Schema.define(version: 20171020163240) do t.boolean "draft_publication_enabled", default: false t.boolean "result_publication_enabled", default: false t.boolean "published", default: true - t.date "proposals_phase_start_date" - t.date "proposals_phase_end_date" - t.boolean "proposals_phase_enabled" - t.text "proposals_description" end add_index "legislation_processes", ["allegations_end_date"], name: "index_legislation_processes_on_allegations_end_date", using: :btree @@ -502,36 +498,6 @@ ActiveRecord::Schema.define(version: 20171020163240) do add_index "legislation_processes", ["result_publication_date"], name: "index_legislation_processes_on_result_publication_date", using: :btree add_index "legislation_processes", ["start_date"], name: "index_legislation_processes_on_start_date", using: :btree - create_table "legislation_proposals", force: :cascade do |t| - t.integer "legislation_process_id" - t.string "title", limit: 80 - t.text "description" - t.string "question" - t.string "external_url" - t.integer "author_id" - t.datetime "hidden_at" - t.integer "flags_count", default: 0 - t.datetime "ignored_flag_at" - t.integer "cached_votes_up", default: 0 - t.integer "comments_count", default: 0 - t.datetime "confirmed_hide_at" - t.integer "hot_score", limit: 8, default: 0 - t.integer "confidence_score", default: 0 - t.string "responsible_name", limit: 60 - t.text "summary" - t.string "video_url" - t.tsvector "tsv" - t.integer "geozone_id" - t.datetime "retired_at" - t.string "retired_reason" - t.text "retired_explanation" - t.integer "community_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - add_index "legislation_proposals", ["legislation_process_id"], name: "index_legislation_proposals_on_legislation_process_id", using: :btree - create_table "legislation_question_options", force: :cascade do |t| t.integer "legislation_question_id" t.string "value" @@ -700,7 +666,6 @@ ActiveRecord::Schema.define(version: 20171020163240) do t.text "description" t.integer "question_id" t.integer "given_order", default: 1 - t.boolean "most_voted", default: false end add_index "poll_question_answers", ["question_id"], name: "index_poll_question_answers_on_question_id", using: :btree @@ -955,20 +920,16 @@ ActiveRecord::Schema.define(version: 20171020163240) do add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree create_table "tags", force: :cascade do |t| - t.string "name", limit: 40 - t.integer "taggings_count", default: 0 - t.integer "debates_count", default: 0 - t.integer "proposals_count", default: 0 - t.integer "spending_proposals_count", default: 0 + t.string "name", limit: 40 + t.integer "taggings_count", default: 0 + t.integer "debates_count", default: 0 + t.integer "proposals_count", default: 0 + t.integer "spending_proposals_count", default: 0 t.string "kind" - t.integer "budget/investments_count", default: 0 - t.integer "legislation/proposals_count", default: 0 - t.integer "legislation/processes_count", default: 0 + t.integer "budget/investments_count", default: 0 end add_index "tags", ["debates_count"], name: "index_tags_on_debates_count", using: :btree - add_index "tags", ["legislation/processes_count"], name: "index_tags_on_legislation/processes_count", using: :btree - add_index "tags", ["legislation/proposals_count"], name: "index_tags_on_legislation/proposals_count", using: :btree add_index "tags", ["name"], name: "index_tags_on_name", unique: true, using: :btree add_index "tags", ["proposals_count"], name: "index_tags_on_proposals_count", using: :btree add_index "tags", ["spending_proposals_count"], name: "index_tags_on_spending_proposals_count", using: :btree @@ -1146,7 +1107,6 @@ ActiveRecord::Schema.define(version: 20171020163240) do add_foreign_key "identities", "users" add_foreign_key "images", "users" add_foreign_key "legislation_draft_versions", "legislation_processes" - add_foreign_key "legislation_proposals", "legislation_processes" add_foreign_key "locks", "users" add_foreign_key "managers", "users" add_foreign_key "moderators", "users" From b1e91cdc03acf3072d6d5b27c8d14965d2d0cb53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Mon, 23 Oct 2017 12:57:52 +0200 Subject: [PATCH 190/211] Tests improvements --- spec/features/admin/poll/polls_spec.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb index 8180a89f2..210b2ff6a 100644 --- a/spec/features/admin/poll/polls_spec.rb +++ b/spec/features/admin/poll/polls_spec.rb @@ -88,12 +88,20 @@ feature 'Admin polls' do fill_in "poll_name", with: "Next Poll" fill_in 'poll_ends_at', with: end_date.strftime("%d/%m/%Y") + check 'poll_results_enabled' + check 'poll_stats_enabled' click_button "Update poll" expect(page).to have_content "Poll updated successfully" expect(page).to have_content "Next Poll" expect(page).to have_content I18n.l(end_date.to_date) + + click_link "Edit poll" + + expect(page).to have_field('poll_results_enabled', checked: true) + expect(page).to have_field('poll_stats_enabled', checked: true) + end scenario 'Edit from index' do From f38f333fe55288919254f0c6412de2a90b632757 Mon Sep 17 00:00:00 2001 From: decabeza Date: Mon, 23 Oct 2017 13:02:37 +0200 Subject: [PATCH 191/211] undo changes on poll title links --- app/views/polls/_poll_group.html.erb | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/app/views/polls/_poll_group.html.erb b/app/views/polls/_poll_group.html.erb index 9d83d5233..529e9a99e 100644 --- a/app/views/polls/_poll_group.html.erb +++ b/app/views/polls/_poll_group.html.erb @@ -19,27 +19,11 @@
      <% if poll.questions.count == 1 %> <% poll.questions.each do |question| %> -

      - <% if poll.results_enabled? %> - <%= link_to question.title, poll_results_path(poll) %> - <% elsif poll.stats_enabled? %> - <%= link_to question.title, poll_stats_path(poll) %> - <% else %> - <%= link_to question.title, poll %> - <% end %> -

      +

      <%= link_to question.title, poll %>

      <%= poll_dates(poll) %> <% end %> <% else %> -

      - <% if poll.results_enabled? %> - <%= link_to poll.name, poll_results_path(poll) %> - <% elsif poll.stats_enabled? %> - <%= link_to poll.name, poll_stats_path(poll) %> - <% else %> - <%= link_to poll.name, poll %> - <% end %> -

      +

      <%= link_to poll.name, poll %>

      <%= poll_dates(poll) %>
        <% poll.questions.each do |question| %> From 84f67db26d777397381c4b4f21aa5263b717522c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Mon, 23 Oct 2017 14:17:25 +0200 Subject: [PATCH 192/211] Added restrictions to access Poll results and stats --- app/models/abilities/administrator.rb | 2 +- app/models/abilities/everyone.rb | 4 +- app/views/polls/_poll_subnav.html.erb | 58 +++++++++++++++------------ app/views/polls/show.html.erb | 2 +- 4 files changed, 37 insertions(+), 29 deletions(-) diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index 704f9be24..1274229b5 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -56,7 +56,7 @@ module Abilities can [:index, :create, :edit, :update, :destroy], Geozone - can [:read, :create, :update, :destroy, :add_question, :search_booths, :search_officers, :booth_assignments], Poll + can [:read, :create, :update, :destroy, :add_question, :search_booths, :search_officers, :booth_assignments, :results, :stats], Poll can [:read, :create, :update, :destroy, :available], Poll::Booth can [:search, :create, :index, :destroy], ::Poll::Officer can [:create, :destroy, :manage], ::Poll::BoothAssignment diff --git a/app/models/abilities/everyone.rb b/app/models/abilities/everyone.rb index 4d2fe4434..32f948a5a 100644 --- a/app/models/abilities/everyone.rb +++ b/app/models/abilities/everyone.rb @@ -6,7 +6,9 @@ module Abilities can [:read, :map], Debate can [:read, :map, :summary, :share], Proposal can :read, Comment - can [:read, :results, :stats], Poll + can :read, Poll + cannot :results, Poll, results_enabled: false + cannot :stats, Poll, stats_enabled: false can :read, Poll::Question can [:read, :welcome], Budget can :read, SpendingProposal diff --git a/app/views/polls/_poll_subnav.html.erb b/app/views/polls/_poll_subnav.html.erb index 8155e2ef4..371571896 100644 --- a/app/views/polls/_poll_subnav.html.erb +++ b/app/views/polls/_poll_subnav.html.erb @@ -1,29 +1,35 @@ -
        -
        - +
        -
      +<% end %> diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index 839b8725a..709fcc2a2 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -15,7 +15,7 @@

    <% else %> - <% if current_user && @poll.voted_in_web?(current_user) %> + <% if current_user && @poll.voted_in_web?(current_user) && !@poll.expired? %>
    <%= t("polls.show.already_voted_in_web") %>
    From 9ce704571765006cae2d392cc7162d8d08a28d6a Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 23 Oct 2017 15:17:35 +0200 Subject: [PATCH 193/211] fixes specs --- app/views/polls/_poll_subnav.html.erb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/polls/_poll_subnav.html.erb b/app/views/polls/_poll_subnav.html.erb index 371571896..67325fa3a 100644 --- a/app/views/polls/_poll_subnav.html.erb +++ b/app/views/polls/_poll_subnav.html.erb @@ -1,4 +1,5 @@ -<% if current_user.administrator? || (@poll.expired? && (@poll.results_enabled? || @poll.stats_enabled?)) %> +<% if current_user && current_user.administrator? || + (@poll.expired? && (@poll.results_enabled? || @poll.stats_enabled?)) %>
    <%= t("admin.booths.index.name") %><%= t("admin.booths.index.location") %> <%= t("admin.booth_assignments.manage.status.assign_status") %> <%= t("admin.actions.actions") %>
    - <%= poll.name %> + <%= link_to poll.name, admin_poll_path(poll) %> <%= l poll.starts_at.to_date %> - <%= l poll.ends_at.to_date %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 3826e9764..aa0fc0f8a 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -675,6 +675,7 @@ en: add_booth: "Add booth" name: "Name" location: "Location" + no_location: "No Location" new: title: "New booth" name: "Name" diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 9bc97c35f..2ff4449ec 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -677,6 +677,7 @@ es: add_booth: "Añadir urna" name: "Nombre" location: "Ubicación" + no_location: "Sin Ubicación" new: title: "Nueva urna" name: "Nombre" From 5b40696f4f71f3fdebde55fc6be36ea249cf1628 Mon Sep 17 00:00:00 2001 From: decabeza Date: Sat, 21 Oct 2017 17:34:45 +0200 Subject: [PATCH 178/211] shows admin shortcuts menu only to admin users --- .../admin/shared/_admin_shortcuts.html.erb | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/app/views/admin/shared/_admin_shortcuts.html.erb b/app/views/admin/shared/_admin_shortcuts.html.erb index 7ead6d419..8a292d6bb 100644 --- a/app/views/admin/shared/_admin_shortcuts.html.erb +++ b/app/views/admin/shared/_admin_shortcuts.html.erb @@ -1,10 +1,12 @@ -
  • - <%= link_to admin_stats_path, title: t("admin.menu.stats") do %> - - <% end %> -
  • -
  • - <%= link_to admin_settings_path, title: t("admin.menu.settings") do %> - - <% end %> -
  • +<% if current_user.administrator? %> +
  • + <%= link_to admin_stats_path, title: t("admin.menu.stats") do %> + + <% end %> +
  • +
  • + <%= link_to admin_settings_path, title: t("admin.menu.settings") do %> + + <% end %> +
  • +<% end %> \ No newline at end of file From 668745f3e1d56559152abd264affe9fde0ba2e87 Mon Sep 17 00:00:00 2001 From: decabeza Date: Sat, 21 Oct 2017 17:36:44 +0200 Subject: [PATCH 179/211] moves officing menu outside of admin dropdown --- app/helpers/users_helper.rb | 6 +----- app/views/shared/_admin_login_items.html.erb | 11 +++++------ 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index 111a80267..da340bb46 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -52,12 +52,8 @@ module UsersHelper current_user && current_user.manager? end - def current_poll_officer? - current_user && current_user.poll_officer? - end - def show_admin_menu? - current_administrator? || current_moderator? || current_valuator? || current_manager? || current_poll_officer? + current_administrator? || current_moderator? || current_valuator? || current_manager? end def interests_title_text(user) diff --git a/app/views/shared/_admin_login_items.html.erb b/app/views/shared/_admin_login_items.html.erb index 9634874f9..a9e6fa4b9 100644 --- a/app/views/shared/_admin_login_items.html.erb +++ b/app/views/shared/_admin_login_items.html.erb @@ -26,12 +26,11 @@ <%= link_to t("layouts.header.management"), management_sign_in_path %> <% end %> - - <% if current_user.administrator? || current_user.poll_officer? %> -
  • - <%= link_to t("layouts.header.officing"), officing_root_path %> -
  • - <% end %> <% end %> +<% if current_user && current_user.poll_officer? %> +
  • + <%= link_to t("layouts.header.officing"), officing_root_path %> +
  • +<% end %> From 573961a3218a6c81c78b7f4370af9213f7b69bf0 Mon Sep 17 00:00:00 2001 From: decabeza Date: Sat, 21 Oct 2017 17:37:14 +0200 Subject: [PATCH 180/211] avoids admin access to officing panel --- app/controllers/officing/base_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/officing/base_controller.rb b/app/controllers/officing/base_controller.rb index 97ef23d30..07cf4cfa5 100644 --- a/app/controllers/officing/base_controller.rb +++ b/app/controllers/officing/base_controller.rb @@ -7,6 +7,6 @@ class Officing::BaseController < ApplicationController skip_authorization_check def verify_officer - raise CanCan::AccessDenied unless current_user.try(:poll_officer?) || current_user.try(:administrator?) + raise CanCan::AccessDenied unless current_user.try(:poll_officer?) end end \ No newline at end of file From 47d626619fcab1a6372b1ac516bbf39962364dd6 Mon Sep 17 00:00:00 2001 From: decabeza Date: Sat, 21 Oct 2017 17:37:37 +0200 Subject: [PATCH 181/211] adds specs for admin access to officing --- spec/features/officing_spec.rb | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/spec/features/officing_spec.rb b/spec/features/officing_spec.rb index 338b416ea..b208b735c 100644 --- a/spec/features/officing_spec.rb +++ b/spec/features/officing_spec.rb @@ -55,7 +55,22 @@ feature 'Poll Officing' do expect(page).to have_content "You do not have permission to access this page" end - scenario 'Access as an poll officer is authorized' do + scenario 'Access as an administrator is not authorized' do + create(:administrator, user: user) + create(:poll) + login_as(user) + visit root_path + + expect(page).to_not have_link("Polling officers") + visit officing_root_path + + expect(current_path).not_to eq(officing_root_path) + expect(current_path).to eq(root_path) + expect(page).to have_content "You do not have permission to access this page" + end + + scenario 'Access as an administrator with poll officer role is authorized' do + create(:administrator, user: user) create(:poll_officer, user: user) create(:poll) login_as(user) @@ -68,8 +83,8 @@ feature 'Poll Officing' do expect(page).to_not have_content "You do not have permission to access this page" end - scenario 'Access as an administrator is authorized' do - create(:administrator, user: user) + scenario 'Access as an poll officer is authorized' do + create(:poll_officer, user: user) create(:poll) login_as(user) visit root_path From 3b2f3ae40bf57e6f7ea35bc3f0186855bd3c3945 Mon Sep 17 00:00:00 2001 From: decabeza Date: Sat, 21 Oct 2017 18:20:09 +0200 Subject: [PATCH 182/211] changes admin menu order --- app/views/admin/_menu.html.erb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 0518aa0e3..2cc44711f 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -80,15 +80,15 @@ <%= link_to t('admin.menu.poll_booths'), admin_booths_path %> +
  • > + <%= link_to t('admin.menu.poll_booth_assignments'), booth_assignments_admin_polls_path %> +
  • +
  • > <%= link_to t('admin.menu.poll_shifts'), available_admin_booths_path %>
  • - -
  • > - <%= link_to t('admin.menu.poll_booth_assignments'), booth_assignments_admin_polls_path %> -
  • <% end %> From e0a1a73e0b2b8c95ab2d0089866a56c1d8645831 Mon Sep 17 00:00:00 2001 From: decabeza Date: Sat, 21 Oct 2017 18:20:26 +0200 Subject: [PATCH 183/211] fixes active class on polls admin menu --- app/views/admin/_menu.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 2cc44711f..f3abf04aa 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -60,8 +60,8 @@ <%= t("admin.menu.title_polls") %>
      > -
    • > +
    • > <%= link_to t('admin.menu.polls'), admin_polls_path %>
    • From 70713e08c3469965bb2930404743486b88a78d5b Mon Sep 17 00:00:00 2001 From: decabeza Date: Sat, 21 Oct 2017 18:25:30 +0200 Subject: [PATCH 184/211] adds missing space --- app/controllers/admin/poll/polls_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/poll/polls_controller.rb b/app/controllers/admin/poll/polls_controller.rb index b146f66cc..0860e8518 100644 --- a/app/controllers/admin/poll/polls_controller.rb +++ b/app/controllers/admin/poll/polls_controller.rb @@ -55,7 +55,7 @@ class Admin::Poll::PollsController < Admin::Poll::BaseController def poll_params params.require(:poll).permit(:name, :starts_at, :ends_at, :geozone_restricted, - :summary, :description, :results_enabled,:stats_enabled, + :summary, :description, :results_enabled, :stats_enabled, geozone_ids: [], image_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy]) end From f8e5f791b34154767c3d93cccd1d5d6e18e65e4b Mon Sep 17 00:00:00 2001 From: decabeza Date: Sat, 21 Oct 2017 18:25:58 +0200 Subject: [PATCH 185/211] adds missing p close tag --- app/views/admin/poll/polls/_form.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/poll/polls/_form.html.erb b/app/views/admin/poll/polls/_form.html.erb index 4926e28ac..c0439af7b 100644 --- a/app/views/admin/poll/polls/_form.html.erb +++ b/app/views/admin/poll/polls/_form.html.erb @@ -59,7 +59,7 @@ <%= t('admin.polls.new.show_results_and_stats') %> <%= f.check_box :results_enabled, checked: @poll.results_enabled?, label: t('admin.polls.new.show_results') %> <%= f.check_box :stats_enabled, checked: @poll.stats_enabled?, label: t('admin.polls.new.show_stats') %> -

      <%= t('admin.polls.new.results_and_stats_reminder') %> +

      <%= t('admin.polls.new.results_and_stats_reminder') %>

      <% end %> From 3f2189b12406de3bf80eba1962c57d53fe6f4a12 Mon Sep 17 00:00:00 2001 From: decabeza Date: Sat, 21 Oct 2017 20:07:13 +0200 Subject: [PATCH 186/211] removes unnecessary blank space :sweat_smile: --- app/views/polls/results.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/polls/results.html.erb b/app/views/polls/results.html.erb index 884f341f7..07ca75bc3 100644 --- a/app/views/polls/results.html.erb +++ b/app/views/polls/results.html.erb @@ -24,7 +24,7 @@ <%- question.question_answers.each do |answer| %>
    > <% if answer.most_voted %> - <%= t ("polls.show.results.most_voted_answer") %> + <%= t("polls.show.results.most_voted_answer") %> <% end %> <%= answer.title %>

    <%= question.title %>

    diff --git a/app/views/polls/stats.html.erb b/app/views/polls/stats.html.erb index 3a4d99dba..a89277ac4 100644 --- a/app/views/polls/stats.html.erb +++ b/app/views/polls/stats.html.erb @@ -5,7 +5,7 @@ <%= render "poll_subnav" %> -
    +