Merge branch 'master' into community-design
@@ -11,3 +11,6 @@ insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.yml]
|
||||
insert_final_newline = false
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
inherit_from: .rubocop_todo.yml
|
||||
|
||||
AllCops:
|
||||
DisplayCopNames: true
|
||||
DisplayStyleGuide: true
|
||||
Include:
|
||||
- '**/Rakefile'
|
||||
- '**/config.ru'
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config`
|
||||
# on 2017-07-07 21:23:30 +0200 using RuboCop version 0.49.1.
|
||||
# on 2017-10-17 22:05:23 +0200 using RuboCop version 0.49.1.
|
||||
# The point is for the user to remove these configuration records
|
||||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
# versions of RuboCop, may require this file to be generated again.
|
||||
|
||||
# Offense count: 45
|
||||
# Offense count: 40
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedHashRocketStyle, SupportedHashRocketStyles, EnforcedColonStyle, SupportedColonStyles, EnforcedLastArgumentHashStyle, SupportedLastArgumentHashStyles.
|
||||
# SupportedHashRocketStyles: key, separator, table
|
||||
@@ -14,11 +14,10 @@
|
||||
# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
|
||||
Layout/AlignHash:
|
||||
Exclude:
|
||||
- 'app/controllers/officing/results_controller.rb'
|
||||
- 'spec/controllers/legislation/annotations_controller_spec.rb'
|
||||
- 'spec/features/admin/banners_spec.rb'
|
||||
|
||||
# Offense count: 50
|
||||
# Offense count: 52
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
|
||||
# SupportedStyles: with_first_parameter, with_fixed_indentation
|
||||
@@ -33,7 +32,7 @@ Layout/ClosingParenthesisIndentation:
|
||||
- 'spec/models/legislation/annotation_spec.rb'
|
||||
- 'spec/rails_helper.rb'
|
||||
|
||||
# Offense count: 51
|
||||
# Offense count: 37
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: leading, trailing
|
||||
@@ -68,11 +67,10 @@ Layout/EmptyLines:
|
||||
Exclude:
|
||||
- 'app/controllers/admin/budget_investment_milestones_controller.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Layout/EmptyLinesAroundMethodBody:
|
||||
Exclude:
|
||||
- 'app/models/abilities/administrator.rb'
|
||||
- 'lib/graph_ql/api_types_creator.rb'
|
||||
|
||||
# Offense count: 2
|
||||
@@ -126,13 +124,13 @@ Layout/IndentationConsistency:
|
||||
- 'spec/models/legislation/draft_version_spec.rb'
|
||||
- 'spec/models/proposal_spec.rb'
|
||||
|
||||
# Offense count: 23
|
||||
# Offense count: 48
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: Width, IgnoredPatterns.
|
||||
Layout/IndentationWidth:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 7
|
||||
# Offense count: 6
|
||||
# Cop supports --auto-correct.
|
||||
Layout/LeadingCommentSpace:
|
||||
Exclude:
|
||||
@@ -140,7 +138,6 @@ Layout/LeadingCommentSpace:
|
||||
- 'app/controllers/budgets/ballot/lines_controller.rb'
|
||||
- 'spec/features/budgets/ballots_spec.rb'
|
||||
- 'spec/features/comments/poll_questions_spec.rb'
|
||||
- 'spec/features/officing/voters_spec.rb'
|
||||
- 'spec/support/common_actions.rb'
|
||||
|
||||
# Offense count: 3
|
||||
@@ -181,7 +178,7 @@ Layout/MultilineMethodCallBraceLayout:
|
||||
- 'spec/models/legislation/annotation_spec.rb'
|
||||
- 'spec/rails_helper.rb'
|
||||
|
||||
# Offense count: 71
|
||||
# Offense count: 59
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
|
||||
# SupportedStyles: aligned, indented, indented_relative_to_receiver
|
||||
@@ -201,7 +198,7 @@ Layout/MultilineMethodCallIndentation:
|
||||
- 'spec/models/proposal_spec.rb'
|
||||
- 'spec/models/user_spec.rb'
|
||||
|
||||
# Offense count: 8
|
||||
# Offense count: 7
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
|
||||
# SupportedStyles: aligned, indented
|
||||
@@ -264,29 +261,11 @@ Lint/LiteralInCondition:
|
||||
Exclude:
|
||||
- 'app/models/budget/investment.rb'
|
||||
|
||||
# Offense count: 51
|
||||
Lint/ParenthesesAsGroupedExpression:
|
||||
Exclude:
|
||||
- 'spec/factories.rb'
|
||||
- 'spec/features/admin/organizations_spec.rb'
|
||||
- 'spec/features/budgets/investments_spec.rb'
|
||||
- 'spec/features/campaigns_spec.rb'
|
||||
- 'spec/features/debates_spec.rb'
|
||||
- 'spec/features/management/managed_users_spec.rb'
|
||||
- 'spec/features/management/proposals_spec.rb'
|
||||
- 'spec/features/management/spending_proposals_spec.rb'
|
||||
- 'spec/features/management/users_spec.rb'
|
||||
- 'spec/features/proposals_spec.rb'
|
||||
- 'spec/models/debate_spec.rb'
|
||||
|
||||
# Offense count: 13
|
||||
# Offense count: 3
|
||||
# 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.
|
||||
@@ -311,7 +290,7 @@ Lint/UnusedMethodArgument:
|
||||
- 'app/mailers/mailer.rb'
|
||||
- 'app/models/abilities/everyone.rb'
|
||||
|
||||
# Offense count: 278
|
||||
# Offense count: 325
|
||||
Lint/UselessAssignment:
|
||||
Enabled: false
|
||||
|
||||
@@ -320,35 +299,46 @@ Lint/Void:
|
||||
Exclude:
|
||||
- 'app/controllers/polls_controller.rb'
|
||||
|
||||
# Offense count: 74
|
||||
# Offense count: 86
|
||||
Metrics/AbcSize:
|
||||
Max: 54
|
||||
Max: 64
|
||||
|
||||
# Offense count: 454
|
||||
# Offense count: 487
|
||||
# Configuration parameters: CountComments, ExcludedMethods.
|
||||
Metrics/BlockLength:
|
||||
Max: 1071
|
||||
|
||||
# Offense count: 8
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/ClassLength:
|
||||
Max: 256
|
||||
Max: 1227
|
||||
|
||||
# Offense count: 10
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/ClassLength:
|
||||
Max: 262
|
||||
|
||||
# Offense count: 13
|
||||
Metrics/CyclomaticComplexity:
|
||||
Max: 10
|
||||
|
||||
# Offense count: 53
|
||||
# Offense count: 25
|
||||
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
||||
# URISchemes: http, https
|
||||
Metrics/LineLength:
|
||||
Max: 248
|
||||
|
||||
# Offense count: 67
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/MethodLength:
|
||||
Max: 49
|
||||
Max: 56
|
||||
|
||||
# Offense count: 1
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/ModuleLength:
|
||||
Max: 214
|
||||
Max: 242
|
||||
|
||||
# Offense count: 7
|
||||
# Offense count: 3
|
||||
# Configuration parameters: CountKeywordArgs.
|
||||
Metrics/ParameterLists:
|
||||
Max: 7
|
||||
|
||||
# Offense count: 8
|
||||
Metrics/PerceivedComplexity:
|
||||
Max: 11
|
||||
|
||||
@@ -402,20 +392,20 @@ Rails/HttpPositionalArguments:
|
||||
- 'spec/controllers/pages_controller_spec.rb'
|
||||
- 'spec/controllers/users/registrations_controller_spec.rb'
|
||||
|
||||
# Offense count: 20
|
||||
# Offense count: 18
|
||||
Rails/OutputSafety:
|
||||
Exclude:
|
||||
- 'app/controllers/admin/legislation/draft_versions_controller.rb'
|
||||
- 'app/controllers/admin/legislation/processes_controller.rb'
|
||||
- 'app/controllers/admin/legislation/questions_controller.rb'
|
||||
- 'app/controllers/budgets/investments_controller.rb'
|
||||
- 'app/controllers/direct_uploads_controller.rb'
|
||||
- 'app/controllers/spending_proposals_controller.rb'
|
||||
- 'app/helpers/application_helper.rb'
|
||||
- 'app/helpers/text_with_links_helper.rb'
|
||||
- 'app/helpers/users_helper.rb'
|
||||
- 'app/helpers/valuation_helper.rb'
|
||||
|
||||
# Offense count: 70
|
||||
# Offense count: 71
|
||||
# Configuration parameters: Blacklist.
|
||||
# Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters
|
||||
Rails/SkipsModelValidations:
|
||||
@@ -431,7 +421,7 @@ Style/AccessorMethodName:
|
||||
- 'app/controllers/proposals_controller.rb'
|
||||
- 'lib/merged_comment_tree.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Offense count: 8
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: braces, no_braces, context_dependent
|
||||
@@ -441,7 +431,7 @@ Style/BracesAroundHashParameters:
|
||||
- 'spec/features/budgets/investments_spec.rb'
|
||||
- 'spec/features/proposals_spec.rb'
|
||||
|
||||
# Offense count: 119
|
||||
# Offense count: 123
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: nested, compact
|
||||
Style/ClassAndModuleChildren:
|
||||
@@ -454,20 +444,13 @@ Style/ClassVars:
|
||||
- 'app/models/organization.rb'
|
||||
- 'app/models/user.rb'
|
||||
|
||||
# Offense count: 6
|
||||
# Cop supports --auto-correct.
|
||||
Style/ColonMethodCall:
|
||||
Exclude:
|
||||
- 'spec/models/budget/investment_spec.rb'
|
||||
|
||||
# Offense count: 12
|
||||
# Offense count: 8
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, SingleLineConditionsOnly, IncludeTernaryExpressions.
|
||||
# SupportedStyles: assign_to_condition, assign_inside_condition
|
||||
Style/ConditionalAssignment:
|
||||
Exclude:
|
||||
- 'app/controllers/admin/poll/booth_assignments_controller.rb'
|
||||
- 'app/controllers/admin/poll/officer_assignments_controller.rb'
|
||||
- 'app/controllers/admin/poll/questions_controller.rb'
|
||||
- 'app/controllers/comments_controller.rb'
|
||||
- 'app/controllers/management/spending_proposals_controller.rb'
|
||||
@@ -480,12 +463,6 @@ Style/DoubleNegation:
|
||||
Exclude:
|
||||
- 'app/models/flag.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Style/EmptyCaseCondition:
|
||||
Exclude:
|
||||
- 'app/models/concerns/verification.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms.
|
||||
# AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS
|
||||
@@ -499,7 +476,7 @@ Style/FileName:
|
||||
Style/GuardClause:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 12
|
||||
# Offense count: 11
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: MaxLineLength.
|
||||
Style/IfUnlessModifier:
|
||||
@@ -510,37 +487,23 @@ Style/IfUnlessModifier:
|
||||
- 'app/controllers/legislation/annotations_controller.rb'
|
||||
- 'app/controllers/valuation/budget_investments_controller.rb'
|
||||
- 'app/controllers/verification/letter_controller.rb'
|
||||
- 'app/controllers/welcome_controller.rb'
|
||||
- 'app/helpers/embed_videos_helper.rb'
|
||||
- 'app/mailers/mailer.rb'
|
||||
- 'app/models/proposal.rb'
|
||||
- 'app/models/spending_proposal.rb'
|
||||
|
||||
# Offense count: 4
|
||||
# Offense count: 5
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: line_count_dependent, lambda, literal
|
||||
Style/Lambda:
|
||||
Exclude:
|
||||
- 'app/models/comment.rb'
|
||||
- 'app/models/concerns/followable.rb'
|
||||
- 'app/models/direct_message.rb'
|
||||
- 'app/models/vote.rb'
|
||||
- 'lib/graph_ql/api_types_creator.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Style/MethodCallWithoutArgsParentheses:
|
||||
Exclude:
|
||||
- 'app/controllers/management/document_verifications_controller.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: require_parentheses, require_no_parentheses, require_no_parentheses_except_multiline
|
||||
Style/MethodDefParentheses:
|
||||
Exclude:
|
||||
- 'spec/helpers/comments_helper_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
Style/MultilineBlockChain:
|
||||
Exclude:
|
||||
@@ -552,17 +515,14 @@ Style/MultilineIfThen:
|
||||
Exclude:
|
||||
- 'app/controllers/management/users_controller.rb'
|
||||
|
||||
# Offense count: 15
|
||||
# Offense count: 13
|
||||
# Cop supports --auto-correct.
|
||||
Style/MutableConstant:
|
||||
Exclude:
|
||||
- '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'
|
||||
@@ -572,32 +532,13 @@ Style/MutableConstant:
|
||||
- 'lib/tag_sanitizer.rb'
|
||||
- 'lib/wysiwyg_sanitizer.rb'
|
||||
|
||||
# Offense count: 29
|
||||
# Cop supports --auto-correct.
|
||||
Style/NestedParenthesizedCalls:
|
||||
Exclude:
|
||||
- 'spec/features/debates_spec.rb'
|
||||
- 'spec/features/emails_spec.rb'
|
||||
- 'spec/features/valuation/budget_investments_spec.rb'
|
||||
- 'spec/features/valuation/spending_proposals_spec.rb'
|
||||
- 'spec/helpers/settings_helper_spec.rb'
|
||||
- 'spec/helpers/verification_helper_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles.
|
||||
# SupportedStyles: skip_modifier_ifs, always
|
||||
Style/Next:
|
||||
Exclude:
|
||||
- 'app/controllers/officing/results_controller.rb'
|
||||
|
||||
# Offense count: 54
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: Strict.
|
||||
Style/NumericLiterals:
|
||||
MinDigits: 9
|
||||
|
||||
# Offense count: 19
|
||||
# Offense count: 20
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AutoCorrect, EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: predicate, comparison
|
||||
@@ -625,16 +566,7 @@ Style/ParallelAssignment:
|
||||
- 'lib/active_model/dates.rb'
|
||||
- 'spec/support/common_actions.rb'
|
||||
|
||||
# Offense count: 3
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AllowSafeAssignment.
|
||||
Style/ParenthesesAroundCondition:
|
||||
Exclude:
|
||||
- 'app/controllers/proposals_controller.rb'
|
||||
- 'app/models/debate.rb'
|
||||
- 'app/models/proposal.rb'
|
||||
|
||||
# Offense count: 11
|
||||
# Offense count: 10
|
||||
# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist.
|
||||
# NamePrefix: is_, has_, have_
|
||||
# NamePrefixBlacklist: is_, has_, have_
|
||||
@@ -648,7 +580,6 @@ Style/PredicateName:
|
||||
- 'app/helpers/debates_helper.rb'
|
||||
- 'app/models/budget/ballot.rb'
|
||||
- 'app/models/user.rb'
|
||||
- 'lib/census_api.rb'
|
||||
|
||||
# Offense count: 4
|
||||
# Cop supports --auto-correct.
|
||||
@@ -668,18 +599,14 @@ Style/RedundantBegin:
|
||||
- 'app/controllers/graphql_controller.rb'
|
||||
- 'app/models/legislation/annotation.rb'
|
||||
|
||||
# Offense count: 55
|
||||
# Cop supports --auto-correct.
|
||||
Style/RedundantParentheses:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 3
|
||||
# Offense count: 5
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes.
|
||||
# SupportedStyles: slashes, percent_r, mixed
|
||||
Style/RegexpLiteral:
|
||||
Exclude:
|
||||
- 'app/helpers/embed_videos_helper.rb'
|
||||
- 'app/models/poll/question/answer/video.rb'
|
||||
- 'spec/customization_engine_spec.rb'
|
||||
|
||||
# Offense count: 6
|
||||
@@ -698,38 +625,16 @@ Style/SafeNavigation:
|
||||
Exclude:
|
||||
- 'app/models/signature.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: single_quotes, double_quotes
|
||||
Style/StringLiteralsInInterpolation:
|
||||
Exclude:
|
||||
- 'spec/features/budgets/investments_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyleForMultiline, SupportedStylesForMultiline.
|
||||
# SupportedStylesForMultiline: comma, consistent_comma, no_comma
|
||||
Style/TrailingCommaInArguments:
|
||||
Exclude:
|
||||
- 'app/controllers/legislation/answers_controller.rb'
|
||||
|
||||
# Offense count: 9
|
||||
# Configuration parameters: SupportedStyles.
|
||||
# SupportedStyles: snake_case, camelCase
|
||||
Style/VariableName:
|
||||
EnforcedStyle: snake_case
|
||||
|
||||
# Offense count: 107
|
||||
# Offense count: 93
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: snake_case, normalcase, non_integer
|
||||
Style/VariableNumber:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 31
|
||||
# Offense count: 34
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: SupportedStyles, WordRegex.
|
||||
# SupportedStyles: percent, brackets
|
||||
Style/WordArray:
|
||||
EnforcedStyle: percent
|
||||
MinSize: 9
|
||||
MinSize: 8
|
||||
|
||||
@@ -4,6 +4,7 @@ addons:
|
||||
rvm:
|
||||
- "2.3.2"
|
||||
cache: bundler
|
||||
bundler_args: --without development
|
||||
before_script:
|
||||
- "for i in config/*.example; do cp \"$i\" \"${i/.example}\"; done"
|
||||
- bundle exec rake db:setup
|
||||
@@ -15,4 +16,4 @@ env:
|
||||
- CI_NODE_TOTAL=2
|
||||
matrix:
|
||||
- CI_NODE_INDEX=0
|
||||
- CI_NODE_INDEX=1
|
||||
- CI_NODE_INDEX=1
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
* Raimond García [github](https://github.com/voodoorai2000) | [twitter](https://twitter.com/voodoorai2000)
|
||||
* Juanjo Bazán [github](https://github.com/xuanxu) | [twitter](https://twitter.com/xuanxu)
|
||||
* Enrique García Cota [github](https://github.com/kikito) | [twitter](https://twitter.com/otikik)
|
||||
* Alberto García Cabeza [github](https://github.com/decabeza) | [twitter](https://twitter.com/decabeza)
|
||||
* Alberto García Cabeza [github](https://github.com/decabeza)
|
||||
* Alberto Calderón [github](https://github.com/bertocq) | [twitter](https://twitter.com/bertocq)
|
||||
* Maria Checa [github](https://github.com/MariaCheca)
|
||||
|
||||
## Code of conduct
|
||||
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
* Raimond García [github](https://github.com/voodoorai2000) | [twitter](https://twitter.com/voodoorai2000)
|
||||
* Juanjo Bazán [github](https://github.com/xuanxu) | [twitter](https://twitter.com/xuanxu)
|
||||
* Enrique García Cota [github](https://github.com/kikito) | [twitter](https://twitter.com/otikik)
|
||||
* Alberto García Cabeza [github](https://github.com/decabeza) | [twitter](https://twitter.com/decabeza)
|
||||
* Alberto García Cabeza [github](https://github.com/decabeza)
|
||||
* Alberto Calderón [github](https://github.com/bertocq) | [twitter](https://twitter.com/bertocq)
|
||||
* Maria Checa [github](https://github.com/MariaCheca)
|
||||
|
||||
## Código de conducta
|
||||
|
||||
|
||||
37
Dockerfile
Normal file
@@ -0,0 +1,37 @@
|
||||
# # Select ubuntu as the base image
|
||||
FROM coreapps/ruby2.3
|
||||
|
||||
# Install essential Linux packages
|
||||
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev postgresql-client nodejs
|
||||
|
||||
# Define where our application will live inside the image
|
||||
ENV RAILS_ROOT /var/www/consul
|
||||
|
||||
# Create application home. App server will need the pids dir so just create everything in one shot
|
||||
RUN mkdir -p $RAILS_ROOT/tmp/pids
|
||||
|
||||
# Set our working directory inside the image
|
||||
WORKDIR $RAILS_ROOT
|
||||
|
||||
# Use the Gemfiles as Docker cache markers. Always bundle before copying app src.
|
||||
# (the src likely changed and we don't want to invalidate Docker's cache too early)
|
||||
# http://ilikestuffblog.com/2014/01/06/how-to-skip-bundle-install-when-deploying-a-rails-app-to-docker/
|
||||
COPY Gemfile Gemfile
|
||||
|
||||
COPY Gemfile.lock Gemfile.lock
|
||||
|
||||
COPY Gemfile_custom Gemfile_custom
|
||||
|
||||
# Prevent bundler warnings; ensure that the bundler version executed is >= that which created Gemfile.lock
|
||||
RUN gem install bundler
|
||||
|
||||
# Finish establishing our Ruby enviornment
|
||||
RUN bundle install --full-index
|
||||
|
||||
# Copy the Rails application into place
|
||||
COPY . .
|
||||
|
||||
# Define the script we want run once the container boots
|
||||
# Use the "exec" form of CMD so our script shuts down gracefully on SIGTERM (i.e. `docker stop`)
|
||||
#CMD [ "config/containers/app_cmd.sh" ]
|
||||
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]
|
||||
18
Gemfile
@@ -1,6 +1,6 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
gem 'rails', '4.2.9'
|
||||
gem 'rails', '4.2.10'
|
||||
|
||||
gem 'acts-as-taggable-on', '~> 4.0.0'
|
||||
gem 'acts_as_votable', '~> 0.10.0'
|
||||
@@ -37,7 +37,6 @@ gem 'paperclip', '~> 5.1.0'
|
||||
gem 'paranoia', '~> 2.3.1'
|
||||
gem 'pg', '~> 0.21.0'
|
||||
gem 'pg_search', '~> 2.0.1'
|
||||
gem 'rails-assets-markdown-it', '~> 8.2.1', source: 'https://rails-assets.org'
|
||||
gem 'redcarpet', '~> 3.4.0'
|
||||
gem 'responders', '~> 2.4.0'
|
||||
gem 'rinku', '~> 2.0.2', require: 'rails_rinku'
|
||||
@@ -54,17 +53,21 @@ gem 'uglifier', '~> 3.2.0'
|
||||
gem 'unicorn', '~> 5.3.0'
|
||||
gem 'whenever', '~> 0.9.7', require: false
|
||||
|
||||
source 'https://rails-assets.org' do
|
||||
gem 'rails-assets-leaflet'
|
||||
gem 'rails-assets-markdown-it', '~> 8.2.1'
|
||||
end
|
||||
|
||||
group :development, :test do
|
||||
gem "bullet", '~> 5.5.1'
|
||||
gem 'byebug', '~> 9.0.6'
|
||||
gem 'bullet', '~> 5.5.1'
|
||||
gem 'byebug', '~> 9.1.0'
|
||||
gem 'factory_girl_rails', '~> 4.8.0'
|
||||
gem "faker", '~> 1.7.3'
|
||||
gem 'faker', '~> 1.7.3'
|
||||
gem 'i18n-tasks', '~> 0.9.15'
|
||||
gem 'knapsack', '~> 1.13.3'
|
||||
gem 'launchy', '~> 2.4.3'
|
||||
gem 'letter_opener_web', '~> 1.3.1'
|
||||
gem 'quiet_assets', '~> 1.1.0'
|
||||
gem 'rubocop', '~> 0.49.1', require: false
|
||||
gem 'spring', '~> 2.0.1'
|
||||
gem 'spring-commands-rspec', '~> 1.0.4'
|
||||
end
|
||||
@@ -81,9 +84,10 @@ end
|
||||
group :development do
|
||||
gem 'capistrano', '~> 3.8.1', require: false
|
||||
gem 'capistrano-bundler', '~> 1.2', require: false
|
||||
gem "capistrano-rails", '~> 1.2.3', require: false
|
||||
gem 'capistrano-rails', '~> 1.2.3', require: false
|
||||
gem 'capistrano3-delayed-job', '~> 1.7.3'
|
||||
gem 'mdl', '~> 0.4.0', require: false
|
||||
gem 'rubocop', '~> 0.49.1', require: false
|
||||
gem 'rvm1-capistrano3', '~> 1.4.0', require: false
|
||||
gem 'scss_lint', '~> 0.54.0', require: false
|
||||
gem 'web-console', '~> 3.3.0'
|
||||
|
||||
92
Gemfile.lock
@@ -2,36 +2,36 @@ GEM
|
||||
remote: https://rubygems.org/
|
||||
remote: https://rails-assets.org/
|
||||
specs:
|
||||
actionmailer (4.2.9)
|
||||
actionpack (= 4.2.9)
|
||||
actionview (= 4.2.9)
|
||||
activejob (= 4.2.9)
|
||||
actionmailer (4.2.10)
|
||||
actionpack (= 4.2.10)
|
||||
actionview (= 4.2.10)
|
||||
activejob (= 4.2.10)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
actionpack (4.2.9)
|
||||
actionview (= 4.2.9)
|
||||
activesupport (= 4.2.9)
|
||||
actionpack (4.2.10)
|
||||
actionview (= 4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
rack (~> 1.6)
|
||||
rack-test (~> 0.6.2)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
actionview (4.2.9)
|
||||
activesupport (= 4.2.9)
|
||||
actionview (4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
builder (~> 3.1)
|
||||
erubis (~> 2.7.0)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||
activejob (4.2.9)
|
||||
activesupport (= 4.2.9)
|
||||
activejob (4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
globalid (>= 0.3.0)
|
||||
activemodel (4.2.9)
|
||||
activesupport (= 4.2.9)
|
||||
activemodel (4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
builder (~> 3.1)
|
||||
activerecord (4.2.9)
|
||||
activemodel (= 4.2.9)
|
||||
activesupport (= 4.2.9)
|
||||
activerecord (4.2.10)
|
||||
activemodel (= 4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
arel (~> 6.0)
|
||||
activesupport (4.2.9)
|
||||
activesupport (4.2.10)
|
||||
i18n (~> 0.7)
|
||||
minitest (~> 5.1)
|
||||
thread_safe (~> 0.3, >= 0.3.4)
|
||||
@@ -71,7 +71,7 @@ GEM
|
||||
bullet (5.5.1)
|
||||
activesupport (>= 3.0.0)
|
||||
uniform_notifier (~> 1.10.0)
|
||||
byebug (9.0.6)
|
||||
byebug (9.1.0)
|
||||
cancancan (1.16.0)
|
||||
capistrano (3.8.2)
|
||||
airbrussh (>= 1.0.0)
|
||||
@@ -117,6 +117,7 @@ GEM
|
||||
term-ansicolor (~> 1.3)
|
||||
thor (~> 0.19.4)
|
||||
tins (~> 1.6)
|
||||
crass (1.0.3)
|
||||
daemons (1.2.4)
|
||||
dalli (2.7.6)
|
||||
database_cleaner (1.6.1)
|
||||
@@ -172,7 +173,7 @@ GEM
|
||||
railties (>= 4.1)
|
||||
tzinfo (~> 1.2, >= 1.2.2)
|
||||
geocoder (1.4.4)
|
||||
globalid (0.4.0)
|
||||
globalid (0.4.1)
|
||||
activesupport (>= 4.2.0)
|
||||
graphiql-rails (1.4.2)
|
||||
rails
|
||||
@@ -187,7 +188,8 @@ GEM
|
||||
httpi (2.4.2)
|
||||
rack
|
||||
socksify
|
||||
i18n (0.8.6)
|
||||
i18n (0.9.1)
|
||||
concurrent-ruby (~> 1.0)
|
||||
i18n-tasks (0.9.18)
|
||||
activesupport (>= 4.0.2)
|
||||
ast (>= 2.1.0)
|
||||
@@ -239,10 +241,11 @@ GEM
|
||||
actionmailer (>= 3.2)
|
||||
letter_opener (~> 1.0)
|
||||
railties (>= 3.2)
|
||||
loofah (2.0.3)
|
||||
loofah (2.1.1)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
mail (2.6.6)
|
||||
mime-types (>= 1.16, < 4)
|
||||
mail (2.7.0)
|
||||
mini_mime (>= 0.1.1)
|
||||
mdl (0.4.0)
|
||||
kramdown (~> 1.12, >= 1.12.0)
|
||||
mixlib-cli (~> 1.7, >= 1.7.0)
|
||||
@@ -251,7 +254,8 @@ GEM
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2016.0521)
|
||||
mimemagic (0.3.2)
|
||||
mini_portile2 (2.2.0)
|
||||
mini_mime (1.0.0)
|
||||
mini_portile2 (2.3.0)
|
||||
minitest (5.10.3)
|
||||
mixlib-cli (1.7.0)
|
||||
mixlib-config (2.2.4)
|
||||
@@ -262,8 +266,8 @@ GEM
|
||||
net-ssh (>= 2.6.5)
|
||||
net-ssh (4.1.0)
|
||||
newrelic_rpm (4.1.0.333)
|
||||
nokogiri (1.8.0)
|
||||
mini_portile2 (~> 2.2.0)
|
||||
nokogiri (1.8.1)
|
||||
mini_portile2 (~> 2.3.0)
|
||||
nori (2.6.0)
|
||||
oauth (0.5.3)
|
||||
oauth2 (1.4.0)
|
||||
@@ -323,17 +327,18 @@ GEM
|
||||
rack
|
||||
rack-test (0.6.3)
|
||||
rack (>= 1.0)
|
||||
rails (4.2.9)
|
||||
actionmailer (= 4.2.9)
|
||||
actionpack (= 4.2.9)
|
||||
actionview (= 4.2.9)
|
||||
activejob (= 4.2.9)
|
||||
activemodel (= 4.2.9)
|
||||
activerecord (= 4.2.9)
|
||||
activesupport (= 4.2.9)
|
||||
rails (4.2.10)
|
||||
actionmailer (= 4.2.10)
|
||||
actionpack (= 4.2.10)
|
||||
actionview (= 4.2.10)
|
||||
activejob (= 4.2.10)
|
||||
activemodel (= 4.2.10)
|
||||
activerecord (= 4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
bundler (>= 1.3.0, < 2.0)
|
||||
railties (= 4.2.9)
|
||||
railties (= 4.2.10)
|
||||
sprockets-rails
|
||||
rails-assets-leaflet (1.1.0)
|
||||
rails-assets-markdown-it (8.2.2)
|
||||
rails-deprecated_sanitizer (1.0.3)
|
||||
activesupport (>= 4.2.0.alpha)
|
||||
@@ -343,15 +348,15 @@ GEM
|
||||
rails-deprecated_sanitizer (>= 1.0.1)
|
||||
rails-html-sanitizer (1.0.3)
|
||||
loofah (~> 2.0)
|
||||
railties (4.2.9)
|
||||
actionpack (= 4.2.9)
|
||||
activesupport (= 4.2.9)
|
||||
railties (4.2.10)
|
||||
actionpack (= 4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rainbow (2.2.2)
|
||||
rake
|
||||
raindrops (0.18.0)
|
||||
rake (12.0.0)
|
||||
rake (12.2.1)
|
||||
redcarpet (3.4.0)
|
||||
referer-parser (0.3.0)
|
||||
request_store (1.3.2)
|
||||
@@ -455,7 +460,7 @@ GEM
|
||||
rack (>= 1.3, < 3)
|
||||
rack-accept (~> 0.4)
|
||||
tilt (>= 1.4, < 3)
|
||||
tzinfo (1.2.3)
|
||||
tzinfo (1.2.4)
|
||||
thread_safe (~> 0.1)
|
||||
uglifier (3.2.0)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
@@ -493,7 +498,7 @@ DEPENDENCIES
|
||||
ancestry (~> 2.2.2)
|
||||
browser (~> 2.3.0)
|
||||
bullet (~> 5.5.1)
|
||||
byebug (~> 9.0.6)
|
||||
byebug (~> 9.1.0)
|
||||
cancancan (~> 1.16.0)
|
||||
capistrano (~> 3.8.1)
|
||||
capistrano-bundler (~> 1.2)
|
||||
@@ -541,7 +546,8 @@ DEPENDENCIES
|
||||
pg_search (~> 2.0.1)
|
||||
poltergeist (~> 1.15.0)
|
||||
quiet_assets (~> 1.1.0)
|
||||
rails (= 4.2.9)
|
||||
rails (= 4.2.10)
|
||||
rails-assets-leaflet!
|
||||
rails-assets-markdown-it (~> 8.2.1)!
|
||||
redcarpet (~> 3.4.0)
|
||||
responders (~> 2.4.0)
|
||||
@@ -567,4 +573,4 @@ DEPENDENCIES
|
||||
whenever (~> 0.9.7)
|
||||
|
||||
BUNDLED WITH
|
||||
1.15.3
|
||||
1.15.4
|
||||
|
||||
@@ -76,3 +76,8 @@ Code published under AFFERO GPL v3 (see [LICENSE-AGPLv3.txt](LICENSE-AGPLv3.txt)
|
||||
## Contributions
|
||||
|
||||
See [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||
|
||||
|
||||
## Local development with Docker
|
||||
|
||||
Please check the documentation at https://consul_docs.gitbooks.io/docs/content
|
||||
|
||||
@@ -62,4 +62,12 @@
|
||||
<glyph glyph-name="expand" unicode="0" d="M26 168l-26-158c0-2 1-5 3-7 0 0 0 0 0 0 2-2 5-3 7-3l158 27c3 0 6 3 7 6 1 3 0 7-3 9l-30 31 82 82c4 4 4 9 0 13l-57 57c-3 3-9 3-12 0l-83-83-31 31c-2 2-5 3-9 2-3-1-5-4-6-7z m460 176l26 158c0 2-1 5-3 7 0 0 0 0 0 0-2 2-5 3-7 3l-158-27c-3 0-6-3-7-6-1-3 0-7 3-9l30-31-82-82c-4-4-4-9 0-13l57-57c3-3 9-3 12 0l83 83 31-31c2-2 5-3 9-2 3 1 5 4 6 7z"/>
|
||||
<glyph glyph-name="telegram" unicode="1" d="M504 509c6-5 9-11 8-18l-73-439c-1-6-4-10-10-13-2-2-5-2-8-2-3 0-5 0-7 1l-130 53-69-84c-3-5-8-7-14-7-2 0-4 0-6 1-4 1-7 4-9 7-2 3-3 6-3 10l0 100 247 303-306-265-113 47c-7 2-10 7-11 15 0 8 3 14 9 17l476 274c2 2 5 3 9 3 4 0 7-1 10-3z"/>
|
||||
<glyph glyph-name="instagram" unicode="2" d="M426 105l0 185-39 0c4-12 6-25 6-38 0-24-6-46-18-66-13-20-29-36-50-48-21-12-44-18-69-18-37 0-69 13-96 39-27 26-40 57-40 93 0 13 2 26 6 38l-41 0 0-185c0-5 2-10 5-13 4-3 8-5 13-5l305 0c5 0 9 2 13 5 3 3 5 8 5 13z m-81 152c0 23-9 44-26 60-18 17-38 25-63 25-24 0-45-8-62-25-17-16-26-37-26-60 0-24 9-44 26-61 17-16 38-25 62-25 25 0 45 9 63 25 17 17 26 37 26 61z m81 103l0 47c0 5-2 10-6 14-4 4-8 6-14 6l-50 0c-5 0-10-2-14-6-4-4-5-9-5-14l0-47c0-6 1-10 5-14 4-4 9-6 14-6l50 0c6 0 10 2 14 6 4 4 6 8 6 14z m49 59l0-326c0-16-5-29-16-40-11-11-24-16-40-16l-326 0c-16 0-29 5-40 16-11 11-16 24-16 40l0 326c0 16 5 29 16 40 11 11 24 16 40 16l326 0c16 0 29-5 40-16 11-11 16-24 16-40z"/>
|
||||
<glyph glyph-name="image" unicode="3" d="M165 347c0-15-6-28-16-38-11-11-24-16-39-16-16 0-28 5-39 16-11 10-16 23-16 38 0 16 5 29 16 39 11 11 23 16 39 16 15 0 28-5 39-16 10-10 16-23 16-39z m292-109l0-128-402 0 0 55 91 91 46-46 146 147z m28 201l-458 0c-2 0-4-1-6-3-2-2-3-4-3-6l0-348c0-2 1-4 3-6 2-2 4-3 6-3l458 0c2 0 4 1 6 3 2 2 3 4 3 6l0 348c0 2-1 4-3 6-2 2-4 3-6 3z m45-9l0-348c0-12-4-23-13-32-9-9-20-13-32-13l-458 0c-12 0-23 4-32 13-9 9-13 20-13 32l0 348c0 12 4 23 13 32 9 9 20 13 32 13l458 0c12 0 23-4 32-13 9-9 13-20 13-32z"/>
|
||||
<glyph glyph-name="search-plus" unicode="4" d="M311 283l0-18c0-2-1-4-3-6-2-2-4-3-6-3l-64 0 0-64c0-2-1-5-3-6-2-2-4-3-6-3l-19 0c-2 0-4 1-6 3-2 1-3 4-3 6l0 64-64 0c-2 0-4 1-6 3-2 2-3 4-3 6l0 18c0 3 1 5 3 7 2 2 4 3 6 3l64 0 0 64c0 2 1 4 3 6 2 2 4 3 6 3l19 0c2 0 4-1 6-3 2-2 3-4 3-6l0-64 64 0c2 0 4-1 6-3 2-2 3-4 3-7z m36-9c0 36-12 66-37 91-25 25-55 37-91 37-35 0-65-12-90-37-25-25-38-55-38-91 0-35 13-65 38-90 25-25 55-38 90-38 36 0 66 13 91 38 25 25 37 55 37 90z m147-237c0-11-4-19-11-26-7-7-16-11-26-11-10 0-19 4-26 11l-98 98c-34-24-72-36-114-36-27 0-53 5-78 16-25 11-46 25-64 43-18 18-32 39-43 64-10 25-16 51-16 78 0 28 6 54 16 78 11 25 25 47 43 65 18 18 39 32 64 43 25 10 51 15 78 15 28 0 54-5 79-15 24-11 46-25 64-43 18-18 32-40 43-65 10-24 16-50 16-78 0-42-12-80-36-114l98-98c7-7 11-15 11-25z"/>
|
||||
<glyph glyph-name="search-minus" unicode="5" d="M311 283l0-18c0-2-1-4-3-6-2-2-4-3-6-3l-165 0c-2 0-4 1-6 3-2 2-3 4-3 6l0 18c0 3 1 5 3 7 2 2 4 3 6 3l165 0c2 0 4-1 6-3 2-2 3-4 3-7z m36-9c0 36-12 66-37 91-25 25-55 37-91 37-35 0-65-12-90-37-25-25-38-55-38-91 0-35 13-65 38-90 25-25 55-38 90-38 36 0 66 13 91 38 25 25 37 55 37 90z m147-237c0-11-4-19-11-26-7-7-16-11-26-11-10 0-19 4-26 11l-98 98c-34-24-72-36-114-36-27 0-53 5-78 16-25 11-46 25-64 43-18 18-32 39-43 64-10 25-16 51-16 78 0 28 6 54 16 78 11 25 25 47 43 65 18 18 39 32 64 43 25 10 51 15 78 15 28 0 54-5 79-15 24-11 46-25 64-43 18-18 32-40 43-65 10-24 16-50 16-78 0-42-12-80-36-114l98-98c7-7 11-15 11-25z"/>
|
||||
<glyph glyph-name="calculator" unicode="6" d="M110 73c0 10-4 19-11 26-7 7-16 11-26 11-10 0-19-4-26-11-7-7-10-16-10-26 0-10 3-19 10-26 7-7 16-10 26-10 10 0 19 3 26 10 7 7 11 16 11 26z m109 0c0 10-3 19-10 26-7 7-16 11-26 11-10 0-19-4-26-11-7-7-11-16-11-26 0-10 4-19 11-26 7-7 16-10 26-10 10 0 19 3 26 10 7 7 10 16 10 26z m-109 110c0 10-4 19-11 26-7 7-16 10-26 10-10 0-19-3-26-10-7-7-10-16-10-26 0-10 3-19 10-26 7-7 16-11 26-11 10 0 19 4 26 11 7 7 11 16 11 26z m219-110c0 10-3 19-11 26-7 7-15 11-25 11-11 0-19-4-26-11-7-7-11-16-11-26 0-10 4-19 11-26 7-7 15-10 26-10 10 0 18 3 25 10 8 7 11 16 11 26z m-110 110c0 10-3 19-10 26-7 7-16 10-26 10-10 0-19-3-26-10-7-7-11-16-11-26 0-10 4-19 11-26 7-7 16-11 26-11 10 0 19 4 26 11 7 7 10 16 10 26z m-109 110c0 10-4 18-11 25-7 8-16 11-26 11-10 0-19-3-26-11-7-7-10-15-10-25 0-11 3-19 10-26 7-7 16-11 26-11 10 0 19 4 26 11 7 7 11 15 11 26z m219-110c0 10-3 19-11 26-7 7-15 10-25 10-11 0-19-3-26-10-7-7-11-16-11-26 0-10 4-19 11-26 7-7 15-11 26-11 10 0 18 4 25 11 8 7 11 16 11 26z m-110 110c0 10-3 18-10 25-7 8-16 11-26 11-10 0-19-3-26-11-7-7-11-15-11-25 0-11 4-19 11-26 7-7 16-11 26-11 10 0 19 4 26 11 7 7 10 15 10 26z m220-220l0 110c0 10-4 18-11 26-7 7-16 10-26 10-10 0-18-3-25-10-8-8-11-16-11-26l0-110c0-10 3-18 11-26 7-7 15-10 25-10 10 0 19 3 26 10 7 8 11 16 11 26z m-110 220c0 10-3 18-11 25-7 8-15 11-25 11-11 0-19-3-26-11-7-7-11-15-11-25 0-11 4-19 11-26 7-7 15-11 26-11 10 0 18 4 25 11 8 7 11 15 11 26z m110 91l0 73c0 5-2 9-6 13-3 4-7 5-12 5l-366 0c-5 0-9-1-13-5-4-4-5-8-5-13l0-73c0-5 1-9 5-13 4-3 8-5 13-5l366 0c5 0 9 2 12 5 4 4 6 8 6 13z m0-91c0 10-4 18-11 25-7 8-16 11-26 11-10 0-18-3-26-11-7-7-10-15-10-25 0-11 3-19 10-26 8-7 16-11 26-11 10 0 19 4 26 11 7 7 11 15 11 26z m36 182l0-438c0-10-3-19-10-26-8-7-16-11-26-11l-402 0c-10 0-19 4-26 11-7 7-11 16-11 26l0 438c0 10 4 19 11 26 7 7 16 11 26 11l402 0c10 0 18-4 26-11 7-7 10-16 10-26z"/>
|
||||
<glyph glyph-name="map-marker" unicode="7" d="M329 329c0 20-7 38-21 52-15 14-32 21-52 21-20 0-37-7-52-21-14-14-21-32-21-52 0-20 7-37 21-52 15-14 32-21 52-21 20 0 37 7 52 21 14 15 21 32 21 52z m73 0c0-21-3-38-9-51l-104-221c-3-6-8-11-14-15-6-4-12-5-19-5-7 0-13 1-19 5-6 4-11 9-14 15l-104 221c-6 13-9 30-9 51 0 41 14 75 43 104 28 28 63 42 103 42 40 0 75-14 103-42 29-29 43-63 43-104z"/>
|
||||
<glyph glyph-name="user-plus" unicode="8" d="M165 256c-31 0-57 11-78 32-21 22-32 47-32 78 0 30 11 56 32 77 21 22 47 32 78 32 30 0 56-10 77-32 22-21 32-47 32-77 0-31-10-56-32-78-21-21-47-32-77-32z m274-37l100 0c3 0 5 0 7-2 2-2 3-4 3-7l0-55c0-2-1-4-3-6-2-2-4-3-7-3l-100 0 0-100c0-3-1-5-3-7-2-2-4-2-6-2l-55 0c-3 0-5 0-7 2-1 2-2 4-2 7l0 100-101 0c-2 0-4 1-6 3-2 2-3 4-3 6l0 55c0 3 1 5 3 7 2 2 4 2 6 2l101 0 0 101c0 2 1 5 2 6 2 2 4 3 7 3l55 0c2 0 4-1 6-3 2-1 3-4 3-6z m-210-64c0-9 3-18 10-25 8-8 16-11 26-11l73 0 0-68c-13-10-29-14-49-14l-249 0c-23 0-42 6-56 19-14 13-21 32-21 55 0 10 1 20 1 29 1 10 2 20 4 31 2 11 5 22 8 31 3 10 7 19 12 28 5 9 11 17 18 23 7 7 15 12 24 16 10 3 21 5 32 5 4 0 8-1 11-5 15-11 30-20 45-26 14-6 30-8 47-8 17 0 32 2 47 8 14 6 29 15 44 26 4 4 7 5 11 5 25 0 46-9 62-27l-64 0c-10 0-18-4-26-11-7-7-10-16-10-26z"/>
|
||||
<glyph glyph-name="file-text-o" unicode="9" d="M456 403c5-5 10-12 14-21 4-9 5-18 5-25l0-330c0-7-2-14-8-19-5-5-11-8-19-8l-384 0c-8 0-14 3-19 8-6 5-8 12-8 19l0 458c0 7 2 14 8 19 5 5 11 8 19 8l256 0c8 0 16-2 25-6 9-4 17-8 22-13z m-127 70l0-107 108 0c-2 5-4 9-7 11l-89 90c-2 2-6 4-12 6z m110-436l0 292-119 0c-8 0-14 3-19 8-6 5-8 12-8 20l0 118-220 0 0-438z m-293 246c0 3 1 5 3 7 2 2 4 3 6 3l202 0c2 0 4-1 6-3 2-2 3-4 3-7l0-18c0-3-1-5-3-6-2-2-4-3-6-3l-202 0c-2 0-4 1-6 3-2 1-3 3-3 6z m211-64c2 0 4 0 6-2 2-2 3-4 3-7l0-18c0-3-1-5-3-7-2-1-4-2-6-2l-202 0c-2 0-4 1-6 2-2 2-3 4-3 7l0 18c0 3 1 5 3 7 2 2 4 2 6 2z m0-73c2 0 4-1 6-2 2-2 3-4 3-7l0-18c0-3-1-5-3-7-2-1-4-2-6-2l-202 0c-2 0-4 1-6 2-2 2-3 4-3 7l0 18c0 3 1 5 3 7 2 1 4 2 6 2z"/>
|
||||
<glyph glyph-name="file-text" unicode="!" d="M456 376c3-3 5-6 8-10l-135 0 0 135c4-3 8-6 10-8z m-136-47l155 0 0-302c0-7-2-14-8-19-5-5-11-8-19-8l-384 0c-8 0-14 3-19 8-6 5-8 12-8 19l0 458c0 7 2 14 8 19 5 5 11 8 19 8l229 0 0-155c0-8 2-15 8-20 5-5 11-8 19-8z m46-210l0 18c0 3-1 5-3 7-2 1-4 2-6 2l-202 0c-2 0-4-1-6-2-2-2-3-4-3-7l0-18c0-3 1-5 3-7 2-1 4-2 6-2l202 0c2 0 4 1 6 2 2 2 3 4 3 7z m0 73l0 18c0 3-1 5-3 7-2 2-4 2-6 2l-202 0c-2 0-4 0-6-2-2-2-3-4-3-7l0-18c0-3 1-5 3-7 2-1 4-2 6-2l202 0c2 0 4 1 6 2 2 2 3 4 3 7z m0 73l0 18c0 3-1 5-3 7-2 2-4 3-6 3l-202 0c-2 0-4-1-6-3-2-2-3-4-3-7l0-18c0-3 1-5 3-6 2-2 4-3 6-3l202 0c2 0 4 1 6 3 2 1 3 3 3 6z"/>
|
||||
</font></defs></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.6 KiB |
@@ -14,6 +14,8 @@
|
||||
//= require jquery_ujs
|
||||
//= require jquery-ui/widgets/datepicker
|
||||
//= require jquery-ui/i18n/datepicker-es
|
||||
//= require jquery-ui/widgets/autocomplete
|
||||
//= require jquery-ui/widgets/sortable
|
||||
//= require jquery-fileupload/basic
|
||||
//= require foundation
|
||||
//= require turbolinks
|
||||
@@ -62,8 +64,15 @@
|
||||
//= require followable
|
||||
//= require flaggable
|
||||
//= require documentable
|
||||
//= require imageable
|
||||
//= require tree_navigator
|
||||
//= require custom
|
||||
//= require tag_autocomplete
|
||||
//= require polls_admin
|
||||
//= require leaflet
|
||||
//= require map
|
||||
//= require polls
|
||||
//= require sortable
|
||||
|
||||
var initialize_modules = function() {
|
||||
App.Comments.initialize();
|
||||
@@ -98,10 +107,16 @@ var initialize_modules = function() {
|
||||
App.WatchFormChanges.initialize();
|
||||
App.TreeNavigator.initialize();
|
||||
App.Documentable.initialize();
|
||||
App.Imageable.initialize();
|
||||
App.TagAutocomplete.initialize();
|
||||
App.PollsAdmin.initialize();
|
||||
App.Map.initialize();
|
||||
App.Polls.initialize();
|
||||
App.Sortable.initialize();
|
||||
};
|
||||
|
||||
$(function(){
|
||||
Turbolinks.enableProgressBar()
|
||||
Turbolinks.enableProgressBar();
|
||||
|
||||
$(document).ready(initialize_modules);
|
||||
$(document).on('page:load', initialize_modules);
|
||||
|
||||
@@ -1,101 +1,156 @@
|
||||
App.Documentable =
|
||||
|
||||
initialize: ->
|
||||
@initializeDirectUploads()
|
||||
@initializeInterface()
|
||||
|
||||
initializeDirectUploads: ->
|
||||
inputFiles = $('.js-document-attachment')
|
||||
$.each inputFiles, (index, input) ->
|
||||
App.Documentable.initializeDirectUploadInput(input)
|
||||
|
||||
$('input.js-document-attachment[type=file]').fileupload
|
||||
$('#nested-documents').on 'cocoon:after-remove', (e, insertedItem) ->
|
||||
App.Documentable.unlockUploads()
|
||||
|
||||
paramName: "document[attachment]"
|
||||
$('#nested-documents').on 'cocoon:after-insert', (e, nested_document) ->
|
||||
input = $(nested_document).find('.js-document-attachment')
|
||||
App.Documentable.initializeDirectUploadInput(input)
|
||||
|
||||
if $(nested_document).closest('#nested-documents').find('.document:visible').length >= $('#nested-documents').data('max-documents-allowed')
|
||||
App.Documentable.lockUploads()
|
||||
|
||||
initializeDirectUploadInput: (input) ->
|
||||
|
||||
inputData = @buildData([], input)
|
||||
|
||||
@initializeRemoveCachedDocumentLink(input, inputData)
|
||||
|
||||
$(input).fileupload
|
||||
|
||||
paramName: "attachment"
|
||||
|
||||
formData: null
|
||||
|
||||
add: (e, data) ->
|
||||
wrapper = $(e.target).closest('.document')
|
||||
index = $(e.target).data('index')
|
||||
is_nested_document = $(e.target).data('nested-document')
|
||||
$(wrapper).find('.progress-bar-placeholder').empty()
|
||||
data.progressBar = $(wrapper).find('.progress-bar-placeholder').html('<div class="progress-bar"><div class="loading-bar uploading"></div></div>')
|
||||
$(wrapper).find('.progress-bar-placeholder').css('display','block')
|
||||
data.formData = {
|
||||
"document[title]": $(wrapper).find('input.document-title').val() || data.files[0].name
|
||||
"index": index,
|
||||
"nested_document": is_nested_document
|
||||
}
|
||||
data = App.Documentable.buildFileUploadData(e, data)
|
||||
App.Documentable.clearProgressBar(data)
|
||||
App.Documentable.setProgressBar(data, 'uploading')
|
||||
data.submit()
|
||||
|
||||
change: (e, data) ->
|
||||
wrapper = $(e.target).parent()
|
||||
$.each(data.files, (index, file)->
|
||||
$(wrapper).find('.file-name').text(file.name)
|
||||
)
|
||||
$.each data.files, (index, file) ->
|
||||
App.Documentable.setFilename(inputData, file.name)
|
||||
|
||||
fail: (e, data) ->
|
||||
$(data.cachedAttachmentField).val("")
|
||||
App.Documentable.clearFilename(data)
|
||||
App.Documentable.setProgressBar(data, 'errors')
|
||||
App.Documentable.clearInputErrors(data)
|
||||
App.Documentable.setInputErrors(data)
|
||||
$(data.destroyAttachmentLinkContainer).find("a.delete:not(.remove-nested)").remove()
|
||||
$(data.addAttachmentLabel).addClass('error')
|
||||
$(data.addAttachmentLabel).show()
|
||||
|
||||
done: (e, data) ->
|
||||
$(data.cachedAttachmentField).val(data.result.cached_attachment)
|
||||
App.Documentable.setTitleFromFile(data, data.result.filename)
|
||||
App.Documentable.setProgressBar(data, 'complete')
|
||||
App.Documentable.setFilename(data, data.result.filename)
|
||||
App.Documentable.clearInputErrors(data)
|
||||
$(data.addAttachmentLabel).hide()
|
||||
$(data.wrapper).find(".attachment-actions").removeClass('small-12').addClass('small-6 float-right')
|
||||
$(data.wrapper).find(".attachment-actions .action-remove").removeClass('small-3').addClass('small-12')
|
||||
|
||||
destroyAttachmentLink = $(data.result.destroy_link)
|
||||
$(data.destroyAttachmentLinkContainer).html(destroyAttachmentLink)
|
||||
$(destroyAttachmentLink).on 'click', (e) ->
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
App.Documentable.doDeleteCachedAttachmentRequest(this.href, data)
|
||||
|
||||
progress: (e, data) ->
|
||||
progress = parseInt(data.loaded / data.total * 100, 10)
|
||||
$(data.progressBar).find('.loading-bar').css 'width', progress + '%'
|
||||
return
|
||||
|
||||
initializeInterface: ->
|
||||
input_files = $('input.js-document-attachment[type=file]')
|
||||
buildFileUploadData: (e, data) ->
|
||||
data = @buildData(data, e.target)
|
||||
return data
|
||||
|
||||
$.each input_files, (index, file) ->
|
||||
wrapper = $(file).parent()
|
||||
App.Documentable.watchRemoveDocumentbutton(wrapper)
|
||||
buildData: (data, input) ->
|
||||
wrapper = $(input).closest('.direct-upload')
|
||||
data.input = input
|
||||
data.wrapper = wrapper
|
||||
data.progressBar = $(wrapper).find('.progress-bar-placeholder')
|
||||
data.errorContainer = $(wrapper).find('.attachment-errors')
|
||||
data.fileNameContainer = $(wrapper).find('p.file-name')
|
||||
data.destroyAttachmentLinkContainer = $(wrapper).find('.action-remove')
|
||||
data.addAttachmentLabel = $(wrapper).find('.action-add label')
|
||||
data.cachedAttachmentField = $(wrapper).find("input[name$='[cached_attachment]']")
|
||||
data.titleField = $(wrapper).find("input[name$='[title]']")
|
||||
$(wrapper).find('.progress-bar-placeholder').css('display', 'block')
|
||||
return data
|
||||
|
||||
watchRemoveDocumentbutton: (wrapper) ->
|
||||
remove_document_button = $(wrapper).find('.remove-document')
|
||||
$(remove_document_button).on 'click', (e) ->
|
||||
clearFilename: (data) ->
|
||||
$(data.fileNameContainer).text('')
|
||||
$(data.fileNameContainer).hide()
|
||||
|
||||
clearInputErrors: (data) ->
|
||||
$(data.errorContainer).find('small.error').remove()
|
||||
|
||||
clearProgressBar: (data) ->
|
||||
$(data.progressBar).find('.loading-bar').removeClass('complete errors uploading').css('width', "0px")
|
||||
|
||||
setFilename: (data, file_name) ->
|
||||
$(data.fileNameContainer).text(file_name)
|
||||
$(data.fileNameContainer).show()
|
||||
|
||||
setProgressBar: (data, klass) ->
|
||||
$(data.progressBar).find('.loading-bar').addClass(klass)
|
||||
|
||||
setTitleFromFile: (data, title) ->
|
||||
if $(data.titleField).val() == ""
|
||||
$(data.titleField).val(title)
|
||||
|
||||
setInputErrors: (data) ->
|
||||
errors = '<small class="error">' + data.jqXHR.responseJSON.errors + '</small>'
|
||||
$(data.errorContainer).append(errors)
|
||||
|
||||
lockUploads: ->
|
||||
$('#max-documents-notice').removeClass('hide')
|
||||
$('#new_document_link').addClass('hide')
|
||||
|
||||
unlockUploads: ->
|
||||
$('#max-documents-notice').addClass('hide')
|
||||
$('#new_document_link').removeClass('hide')
|
||||
|
||||
doDeleteCachedAttachmentRequest: (url, data) ->
|
||||
$.ajax
|
||||
type: "POST"
|
||||
url: url
|
||||
dataType: "json"
|
||||
data: { "_method": "delete" }
|
||||
complete: ->
|
||||
$(data.cachedAttachmentField).val("")
|
||||
$(data.addAttachmentLabel).show()
|
||||
|
||||
App.Documentable.clearFilename(data)
|
||||
App.Documentable.clearInputErrors(data)
|
||||
App.Documentable.clearProgressBar(data)
|
||||
|
||||
App.Documentable.unlockUploads()
|
||||
$(data.wrapper).find(".attachment-actions").addClass('small-12').removeClass('small-6 float-right')
|
||||
$(data.wrapper).find(".attachment-actions .action-remove").addClass('small-3').removeClass('small-12')
|
||||
|
||||
if $(data.input).data('nested-document') == true
|
||||
$(data.wrapper).remove()
|
||||
else
|
||||
$(data.wrapper).find('a.remove-cached-attachment').remove()
|
||||
|
||||
initializeRemoveCachedDocumentLink: (input, data) ->
|
||||
wrapper = $(input).closest(".direct-upload")
|
||||
remove_document_link = $(wrapper).find('a.remove-cached-attachment')
|
||||
$(remove_document_link).on 'click', (e) ->
|
||||
e.preventDefault()
|
||||
$(wrapper).remove()
|
||||
$('#new_document_link').show()
|
||||
$('.max-documents-notice').hide()
|
||||
e.stopPropagation()
|
||||
App.Documentable.doDeleteCachedAttachmentRequest(this.href, data)
|
||||
|
||||
uploadNestedDocument: (id, nested_document, result) ->
|
||||
$('#' + id).replaceWith(nested_document)
|
||||
@updateLoadingBar(id, result)
|
||||
@initialize()
|
||||
|
||||
uploadPlainDocument: (id, nested_document, result) ->
|
||||
$('#' + id).replaceWith(nested_document)
|
||||
@updateLoadingBar(id, result)
|
||||
@initialize()
|
||||
|
||||
updateLoadingBar: (id, result) ->
|
||||
if result
|
||||
$('#' + id).find('.loading-bar').addClass 'complete'
|
||||
else
|
||||
$('#' + id).find('.loading-bar').addClass 'errors'
|
||||
$('#' + id).find('.progress-bar-placeholder').css('display','block')
|
||||
|
||||
new: (nested_fields) ->
|
||||
$(".documents-list").append(nested_fields)
|
||||
@initialize()
|
||||
|
||||
destroyNestedDocument: (id, notice) ->
|
||||
removeDocument: (id) ->
|
||||
$('#' + id).remove()
|
||||
@updateNotice(notice)
|
||||
|
||||
replacePlainDocument: (id, notice, plain_document) ->
|
||||
$('#' + id).replaceWith(plain_document)
|
||||
@updateNotice(notice)
|
||||
@initialize()
|
||||
|
||||
updateNotice: (notice) ->
|
||||
if $('[data-alert]').length > 0
|
||||
$('[data-alert]').replaceWith(notice)
|
||||
else
|
||||
$("body").append(notice)
|
||||
|
||||
updateNewDocumentButton: (link) ->
|
||||
if $('.document').length >= $('.documents').data('max-documents')
|
||||
$('#new_document_link').hide()
|
||||
$('.max-documents-notice').removeClass('hide')
|
||||
$('.max-documents-notice').show()
|
||||
else if $('#new_document_link').length > 0
|
||||
$('#new_document_link').replaceWith(link)
|
||||
$('.max-documents-notice').hide()
|
||||
else
|
||||
$('.max-documents-notice').hide()
|
||||
$(link).insertBefore('.documents hr:last')
|
||||
|
||||
166
app/assets/javascripts/imageable.js.coffee
Normal file
@@ -0,0 +1,166 @@
|
||||
App.Imageable =
|
||||
|
||||
initialize: ->
|
||||
inputFiles = $('.js-image-attachment')
|
||||
$.each inputFiles, (index, input) ->
|
||||
App.Imageable.initializeDirectUploadInput(input)
|
||||
|
||||
$('#nested-image').on 'cocoon:after-remove', (e, item) ->
|
||||
$("#new_image_link").removeClass('hide')
|
||||
|
||||
$('#nested-image').on 'cocoon:before-insert', (e, nested_image) ->
|
||||
if $(".js-image-attachment").length > 0
|
||||
$(".js-image-attachment").closest('.image').remove()
|
||||
|
||||
$('#nested-image').on 'cocoon:after-insert', (e, nested_image) ->
|
||||
$("#new_image_link").addClass('hide')
|
||||
input = $(nested_image).find('.js-image-attachment')
|
||||
App.Imageable.initializeDirectUploadInput(input)
|
||||
|
||||
initializeDirectUploadInput: (input) ->
|
||||
|
||||
inputData = @buildData([], input)
|
||||
|
||||
@initializeRemoveCachedImageLink(input, inputData)
|
||||
|
||||
$(input).fileupload
|
||||
|
||||
paramName: "attachment"
|
||||
|
||||
formData: null
|
||||
|
||||
add: (e, data) ->
|
||||
data = App.Imageable.buildFileUploadData(e, data)
|
||||
App.Imageable.clearProgressBar(data)
|
||||
App.Imageable.setProgressBar(data, 'uploading')
|
||||
data.submit()
|
||||
|
||||
change: (e, data) ->
|
||||
$.each data.files, (index, file) ->
|
||||
App.Imageable.setFilename(inputData, file.name)
|
||||
|
||||
fail: (e, data) ->
|
||||
$(data.cachedAttachmentField).val("")
|
||||
App.Imageable.clearFilename(data)
|
||||
App.Imageable.setProgressBar(data, 'errors')
|
||||
App.Imageable.clearInputErrors(data)
|
||||
App.Imageable.setInputErrors(data)
|
||||
App.Imageable.clearPreview(data)
|
||||
$(data.destroyAttachmentLinkContainer).find("a.delete:not(.remove-nested)").remove()
|
||||
$(data.addAttachmentLabel).addClass('error')
|
||||
$(data.addAttachmentLabel).show()
|
||||
|
||||
done: (e, data) ->
|
||||
$(data.cachedAttachmentField).val(data.result.cached_attachment)
|
||||
App.Imageable.setTitleFromFile(data, data.result.filename)
|
||||
App.Imageable.setProgressBar(data, 'complete')
|
||||
App.Imageable.setFilename(data, data.result.filename)
|
||||
App.Imageable.clearInputErrors(data)
|
||||
$(data.addAttachmentLabel).hide()
|
||||
$(data.wrapper).find(".attachment-actions").removeClass('small-12').addClass('small-6 float-right')
|
||||
$(data.wrapper).find(".attachment-actions .action-remove").removeClass('small-3').addClass('small-12')
|
||||
App.Imageable.setPreview(data)
|
||||
|
||||
destroyAttachmentLink = $(data.result.destroy_link)
|
||||
$(data.destroyAttachmentLinkContainer).html(destroyAttachmentLink)
|
||||
$(destroyAttachmentLink).on 'click', (e) ->
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
App.Imageable.doDeleteCachedAttachmentRequest(this.href, data)
|
||||
|
||||
progress: (e, data) ->
|
||||
progress = parseInt(data.loaded / data.total * 100, 10)
|
||||
$(data.progressBar).find('.loading-bar').css 'width', progress + '%'
|
||||
return
|
||||
|
||||
buildFileUploadData: (e, data) ->
|
||||
data = @buildData(data, e.target)
|
||||
return data
|
||||
|
||||
buildData: (data, input) ->
|
||||
wrapper = $(input).closest('.direct-upload')
|
||||
data.input = input
|
||||
data.wrapper = wrapper
|
||||
data.progressBar = $(wrapper).find('.progress-bar-placeholder')
|
||||
data.preview = $(wrapper).find('.image-preview')
|
||||
data.errorContainer = $(wrapper).find('.attachment-errors')
|
||||
data.fileNameContainer = $(wrapper).find('p.file-name')
|
||||
data.destroyAttachmentLinkContainer = $(wrapper).find('.action-remove')
|
||||
data.addAttachmentLabel = $(wrapper).find('.action-add label')
|
||||
data.cachedAttachmentField = $(wrapper).find("input[name$='[cached_attachment]']")
|
||||
data.titleField = $(wrapper).find("input[name$='[title]']")
|
||||
$(wrapper).find('.progress-bar-placeholder').css('display', 'block')
|
||||
return data
|
||||
|
||||
clearFilename: (data) ->
|
||||
$(data.fileNameContainer).text('')
|
||||
$(data.fileNameContainer).hide()
|
||||
|
||||
clearInputErrors: (data) ->
|
||||
$(data.errorContainer).find('small.error').remove()
|
||||
|
||||
clearProgressBar: (data) ->
|
||||
$(data.progressBar).find('.loading-bar').removeClass('complete errors uploading').css('width', "0px")
|
||||
|
||||
clearPreview: (data) ->
|
||||
$(data.wrapper).find('.image-preview').remove()
|
||||
|
||||
setFilename: (data, file_name) ->
|
||||
$(data.fileNameContainer).text(file_name)
|
||||
$(data.fileNameContainer).show()
|
||||
|
||||
setProgressBar: (data, klass) ->
|
||||
$(data.progressBar).find('.loading-bar').addClass(klass)
|
||||
|
||||
setTitleFromFile: (data, title) ->
|
||||
if $(data.titleField).val() == ""
|
||||
$(data.titleField).val(title)
|
||||
|
||||
setInputErrors: (data) ->
|
||||
errors = '<small class="error">' + data.jqXHR.responseJSON.errors + '</small>'
|
||||
$(data.errorContainer).append(errors)
|
||||
|
||||
setPreview: (data) ->
|
||||
image_preview = '<div class="small-12 column text-center image-preview"><figure><img src="' + data.result.attachment_url + '" class="cached-image"/></figure></div>'
|
||||
if $(data.preview).length > 0
|
||||
$(data.preview).replaceWith(image_preview)
|
||||
else
|
||||
$(image_preview).insertBefore($(data.wrapper).find(".attachment-actions"))
|
||||
data.preview = $(data.wrapper).find('.image-preview')
|
||||
|
||||
doDeleteCachedAttachmentRequest: (url, data) ->
|
||||
$.ajax
|
||||
type: "POST"
|
||||
url: url
|
||||
dataType: "json"
|
||||
data: { "_method": "delete" }
|
||||
complete: ->
|
||||
$(data.cachedAttachmentField).val("")
|
||||
$(data.addAttachmentLabel).show()
|
||||
|
||||
App.Imageable.clearFilename(data)
|
||||
App.Imageable.clearInputErrors(data)
|
||||
App.Imageable.clearProgressBar(data)
|
||||
App.Imageable.clearPreview(data)
|
||||
|
||||
$('#new_image_link').removeClass('hide')
|
||||
|
||||
$(data.wrapper).find(".attachment-actions").addClass('small-12').removeClass('small-6 float-right')
|
||||
$(data.wrapper).find(".attachment-actions .action-remove").addClass('small-3').removeClass('small-12')
|
||||
|
||||
if $(data.input).data('nested-image') == true
|
||||
$(data.wrapper).remove()
|
||||
else
|
||||
$(data.wrapper).find('a.remove-cached-attachment').remove()
|
||||
|
||||
initializeRemoveCachedImageLink: (input, data) ->
|
||||
wrapper = $(input).closest(".direct-upload")
|
||||
remove_image_link = $(wrapper).find('a.remove-cached-attachment')
|
||||
$(remove_image_link).on 'click', (e) ->
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
App.Imageable.doDeleteCachedAttachmentRequest(this.href, data)
|
||||
|
||||
removeImage: (id) ->
|
||||
$('#' + id).remove()
|
||||
$("#new_image_link").removeClass('hide')
|
||||
78
app/assets/javascripts/map.js.coffee
Normal file
@@ -0,0 +1,78 @@
|
||||
App.Map =
|
||||
|
||||
initialize: ->
|
||||
maps = $('*[data-map]')
|
||||
|
||||
if maps.length > 0
|
||||
$.each maps, (index, map) ->
|
||||
App.Map.initializeMap map
|
||||
|
||||
initializeMap: (element) ->
|
||||
|
||||
mapCenterLatitude = $(element).data('map-center-latitude')
|
||||
mapCenterLongitude = $(element).data('map-center-longitude')
|
||||
markerLatitude = $(element).data('marker-latitude')
|
||||
markerLongitude = $(element).data('marker-longitude')
|
||||
zoom = $(element).data('map-zoom')
|
||||
mapTilesProvider = $(element).data('map-tiles-provider')
|
||||
mapAttribution = $(element).data('map-tiles-provider-attribution')
|
||||
latitudeInputSelector = $(element).data('latitude-input-selector')
|
||||
longitudeInputSelector = $(element).data('longitude-input-selector')
|
||||
zoomInputSelector = $(element).data('zoom-input-selector')
|
||||
removeMarkerSelector = $(element).data('marker-remove-selector')
|
||||
editable = $(element).data('marker-editable')
|
||||
marker = null;
|
||||
markerIcon = L.divIcon(
|
||||
className: 'map-marker'
|
||||
iconSize: [30, 30]
|
||||
iconAnchor: [15, 40]
|
||||
html: '<div class="map-icon"></div>')
|
||||
|
||||
createMarker = (latitude, longitude) ->
|
||||
markerLatLng = new (L.LatLng)(latitude, longitude)
|
||||
marker = L.marker(markerLatLng, { icon: markerIcon, draggable: editable })
|
||||
if editable
|
||||
marker.on 'dragend', updateFormfields
|
||||
marker.addTo(map)
|
||||
return marker
|
||||
|
||||
removeMarker = (e) ->
|
||||
e.preventDefault()
|
||||
if marker
|
||||
map.removeLayer(marker)
|
||||
marker = null;
|
||||
clearFormfields()
|
||||
return
|
||||
|
||||
moveOrPlaceMarker = (e) ->
|
||||
if marker
|
||||
marker.setLatLng(e.latlng)
|
||||
else
|
||||
marker = createMarker(e.latlng.lat, e.latlng.lng)
|
||||
|
||||
updateFormfields()
|
||||
return
|
||||
|
||||
updateFormfields = ->
|
||||
$(latitudeInputSelector).val marker.getLatLng().lat
|
||||
$(longitudeInputSelector).val marker.getLatLng().lng
|
||||
$(zoomInputSelector).val map.getZoom()
|
||||
return
|
||||
|
||||
clearFormfields = ->
|
||||
$(latitudeInputSelector).val ''
|
||||
$(longitudeInputSelector).val ''
|
||||
$(zoomInputSelector).val ''
|
||||
return
|
||||
|
||||
mapCenterLatLng = new (L.LatLng)(mapCenterLatitude, mapCenterLongitude)
|
||||
map = L.map(element.id).setView(mapCenterLatLng, zoom)
|
||||
L.tileLayer(mapTilesProvider, attribution: mapAttribution).addTo map
|
||||
|
||||
if markerLatitude && markerLongitude
|
||||
marker = createMarker(markerLatitude, markerLongitude)
|
||||
|
||||
if editable
|
||||
$(removeMarkerSelector).on 'click', removeMarker
|
||||
map.on 'zoomend', updateFormfields
|
||||
map.on 'click', moveOrPlaceMarker
|
||||
44
app/assets/javascripts/polls.js.coffee
Normal file
@@ -0,0 +1,44 @@
|
||||
App.Polls =
|
||||
generateToken: ->
|
||||
token = ''
|
||||
rand = ''
|
||||
for n in [0..5]
|
||||
rand = Math.random().toString(36).substr(2) # remove `0.`
|
||||
token = token + rand;
|
||||
|
||||
token = token.substring(0, 64)
|
||||
return token
|
||||
|
||||
replaceToken: ->
|
||||
for link in $('.js-question-answer')
|
||||
token_param = link.search.slice(-6)
|
||||
if token_param == "token="
|
||||
link.href = link.href + @token
|
||||
|
||||
initialize: ->
|
||||
@token = App.Polls.generateToken()
|
||||
App.Polls.replaceToken()
|
||||
|
||||
$(".js-question-answer").on
|
||||
click: =>
|
||||
token_message = $(".js-token-message")
|
||||
if !token_message.is(':visible')
|
||||
token_message.html(token_message.html() + "<br><strong>" + @token + "</strong>");
|
||||
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'));
|
||||
|
||||
12
app/assets/javascripts/polls_admin.js.coffee
Normal file
@@ -0,0 +1,12 @@
|
||||
App.PollsAdmin =
|
||||
|
||||
initialize: ->
|
||||
$("select[class='js-poll-shifts']").on
|
||||
change: ->
|
||||
switch ($(this).val())
|
||||
when 'vote_collection'
|
||||
$("select[class='js-shift-vote-collection-dates']").show();
|
||||
$("select[class='js-shift-recount-scrutiny-dates']").hide();
|
||||
when 'recount_scrutiny'
|
||||
$("select[class='js-shift-recount-scrutiny-dates']").show();
|
||||
$("select[class='js-shift-vote-collection-dates']").hide();
|
||||
@@ -22,11 +22,13 @@ App.PreventDoubleSubmission =
|
||||
|
||||
initialize: ->
|
||||
$('form').on('submit', (event) ->
|
||||
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.disable_buttons(buttons)
|
||||
).on('ajax:success', (event) ->
|
||||
unless event.target.id == "new_officing_voter"
|
||||
buttons = $(this).find(':button, :submit')
|
||||
App.PreventDoubleSubmission.reset_buttons(buttons)
|
||||
)
|
||||
|
||||
false
|
||||
|
||||
9
app/assets/javascripts/sortable.js.coffee
Normal file
@@ -0,0 +1,9 @@
|
||||
App.Sortable =
|
||||
initialize: ->
|
||||
$(".sortable").sortable
|
||||
update: (event, ui) ->
|
||||
new_order = $(this).sortable('toArray', {attribute: 'data-answer-id'});
|
||||
$.ajax
|
||||
url: $('.sortable').data('js-url'),
|
||||
data: {ordered_list: new_order},
|
||||
type: 'POST'
|
||||
34
app/assets/javascripts/tag_autocomplete.js.coffee
Normal file
@@ -0,0 +1,34 @@
|
||||
App.TagAutocomplete =
|
||||
|
||||
split: ( val ) ->
|
||||
return (val.split( /,\s*/ ))
|
||||
|
||||
extractLast: ( term ) ->
|
||||
return (App.TagAutocomplete.split( term ).pop())
|
||||
|
||||
init_autocomplete: ->
|
||||
$('.tag-autocomplete').autocomplete
|
||||
source: (request, response) ->
|
||||
$.ajax
|
||||
url: $('.tag-autocomplete').data('js-url'),
|
||||
data: {search: App.TagAutocomplete.extractLast( request.term )},
|
||||
type: 'GET',
|
||||
dataType: 'json'
|
||||
success: ( data ) ->
|
||||
response( data );
|
||||
|
||||
minLength: 0,
|
||||
search: ->
|
||||
App.TagAutocomplete.extractLast( this.value );
|
||||
focus: ->
|
||||
return false;
|
||||
select: ( event, ui ) -> (
|
||||
terms = App.TagAutocomplete.split( this.value );
|
||||
terms.pop();
|
||||
terms.push( ui.item.value );
|
||||
terms.push( "" );
|
||||
this.value = terms.join( ", " );
|
||||
return false;);
|
||||
|
||||
initialize: ->
|
||||
App.TagAutocomplete.init_autocomplete();
|
||||
@@ -75,3 +75,5 @@ $accordion-content-color: foreground($accordion-background, $text);
|
||||
$tab-item-font-size: $base-font-size;
|
||||
$tab-item-padding: $line-height / 2 0;
|
||||
$tab-content-border: $border;
|
||||
|
||||
$orbit-bullet-diameter: 0.8rem;
|
||||
|
||||
@@ -8,38 +8,105 @@
|
||||
// 06. Polls
|
||||
// 07. Legislation
|
||||
// 08. CMS
|
||||
// 09. Map
|
||||
//
|
||||
|
||||
// 01. Global styles
|
||||
// -----------------
|
||||
|
||||
$admin-color: #cf3638;
|
||||
$admin-color: #245b80;
|
||||
$sidebar: #245b80;
|
||||
$sidebar-hover: #25597c;
|
||||
$sidebar-active: #f4fcd0;
|
||||
|
||||
.admin {
|
||||
|
||||
h2 {
|
||||
font-weight: 100;
|
||||
margin-bottom: $line-height;
|
||||
|
||||
&.title {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
.back {
|
||||
float: none;
|
||||
}
|
||||
|
||||
.header {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.top-links {
|
||||
background: darken($admin-color, 15%);
|
||||
}
|
||||
|
||||
.back-web {
|
||||
padding-top: $line-height / 4;
|
||||
text-decoration: underline;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
.top-bar {
|
||||
background: $admin-color !important;
|
||||
background: #fff !important;
|
||||
border-bottom: 1px solid #eee;
|
||||
box-shadow: 0 2px 2px #eee;
|
||||
color: #000;
|
||||
height: auto;
|
||||
|
||||
[class^="icon-"]:not(.icon-circle) {
|
||||
font-size: $base-font-size;
|
||||
}
|
||||
}
|
||||
|
||||
.top-bar-title {
|
||||
|
||||
h1 {
|
||||
margin-bottom: 0;
|
||||
margin-top: $line-height / 2;
|
||||
|
||||
@include breakpoint(medium) {
|
||||
margin-left: $line-height / 2;
|
||||
}
|
||||
|
||||
small {
|
||||
color: #000;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: #000 !important;
|
||||
line-height: $line-height !important;
|
||||
|
||||
@include breakpoint(medium) {
|
||||
line-height: $line-height !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.top-bar .menu > li {
|
||||
|
||||
@include breakpoint(medium) {
|
||||
height: auto !important;
|
||||
padding-top: $line-height / 2;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #000 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-icon.dark {
|
||||
|
||||
&::after,
|
||||
&:hover::after {
|
||||
background: #000 !important;
|
||||
box-shadow: 0 7px 0 #000, 0 14px 0 #000 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.notifications .icon-circle {
|
||||
color: $admin-color;
|
||||
}
|
||||
|
||||
.dropdown.menu > .is-dropdown-submenu-parent > a::after {
|
||||
border-color: #000 transparent transparent;
|
||||
}
|
||||
|
||||
.fieldset {
|
||||
@@ -54,7 +121,8 @@ $admin-color: #cf3638;
|
||||
}
|
||||
}
|
||||
|
||||
th, td {
|
||||
th,
|
||||
td {
|
||||
text-align: left;
|
||||
|
||||
&.text-center {
|
||||
@@ -81,6 +149,7 @@ $admin-color: #cf3638;
|
||||
}
|
||||
|
||||
table {
|
||||
|
||||
.break {
|
||||
word-break: break-word;
|
||||
}
|
||||
@@ -107,9 +176,19 @@ $admin-color: #cf3638;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.menu.simple .active {
|
||||
border-bottom: 2px solid $admin-color;
|
||||
color: $admin-color;
|
||||
.menu.simple {
|
||||
margin-bottom: $line-height / 2;
|
||||
|
||||
h2 {
|
||||
font-weight: bold;
|
||||
margin-bottom: $line-height / 3;
|
||||
}
|
||||
|
||||
.active {
|
||||
border-bottom: 2px solid $admin-color;
|
||||
color: $admin-color;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.tabs-panel {
|
||||
@@ -195,6 +274,8 @@ $admin-color: #cf3638;
|
||||
// -----------
|
||||
|
||||
.admin-sidebar {
|
||||
background: $sidebar;
|
||||
background: linear-gradient(to bottom, #245b80 0%, #488fb5 100%);
|
||||
border-right: 1px solid $border;
|
||||
|
||||
@include breakpoint(medium) {
|
||||
@@ -208,7 +289,7 @@ $admin-color: #cf3638;
|
||||
padding: 0;
|
||||
|
||||
[class^="icon-"] {
|
||||
color: $admin-color;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
font-size: rem-calc(24);
|
||||
line-height: $line-height;
|
||||
@@ -219,39 +300,32 @@ $admin-color: #cf3638;
|
||||
}
|
||||
|
||||
li {
|
||||
background: #fff;
|
||||
margin: 0;
|
||||
outline: 0;
|
||||
|
||||
ul {
|
||||
margin-left: $line-height / 1.5;
|
||||
border-left: 1px solid $border;
|
||||
border-left: 1px solid $sidebar-hover;
|
||||
padding-left: $line-height / 2;
|
||||
}
|
||||
|
||||
&.section-title {
|
||||
border-bottom: 1px solid $border;
|
||||
}
|
||||
|
||||
&.active a {
|
||||
background: #f3f6f7;
|
||||
border-radius: rem-calc(6);
|
||||
color: $admin-color;
|
||||
background: $sidebar-hover;
|
||||
border-left: 2px solid $sidebar-active;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
li a {
|
||||
color: $text;
|
||||
color: #fff;
|
||||
display: block;
|
||||
line-height: rem-calc(48);
|
||||
padding-left: rem-calc(12);
|
||||
vertical-align: top;
|
||||
|
||||
&:hover {
|
||||
background: #f3f6f7;
|
||||
border-radius: rem-calc(6);
|
||||
color: $admin-color;
|
||||
background: $sidebar-hover;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
@@ -259,7 +333,13 @@ $admin-color: #cf3638;
|
||||
.is-accordion-submenu-parent {
|
||||
|
||||
> a::after {
|
||||
border-color: $admin-color transparent transparent;
|
||||
border: 0;
|
||||
content: '\61' !important;
|
||||
font-family: "icons" !important;
|
||||
height: auto;
|
||||
position: absolute !important;
|
||||
right: 30px;
|
||||
top: 6px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,6 +605,7 @@ table {
|
||||
.callout {
|
||||
height: $line-height * 2;
|
||||
line-height: $line-height * 2;
|
||||
margin: 0;
|
||||
padding: 0 $line-height / 2;
|
||||
}
|
||||
}
|
||||
@@ -898,3 +979,51 @@ table {
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 09. Map
|
||||
// --------------
|
||||
|
||||
.map {
|
||||
width: 100%;
|
||||
height: 350px;
|
||||
|
||||
.map-marker {
|
||||
visibility: visible;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin-top: -5px;
|
||||
|
||||
.map-icon {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 50% 50% 50% 0;
|
||||
background: #00cae9;
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
.map-icon::after {
|
||||
content: '';
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin: 8px 0 0 8px;
|
||||
background: #fff;
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.map-attributtion {
|
||||
visibility: visible;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.map-marker {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.map-attributtion {
|
||||
visibility: hidden;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
@@ -16,4 +16,7 @@
|
||||
@import 'annotator_overrides';
|
||||
@import 'jquery-ui/datepicker';
|
||||
@import 'datepicker_overrides';
|
||||
@import 'documentable';
|
||||
@import 'jquery-ui/autocomplete';
|
||||
@import 'autocomplete_overrides';
|
||||
@import 'jquery-ui/sortable';
|
||||
@import 'leaflet';
|
||||
|
||||
40
app/assets/stylesheets/autocomplete_overrides.scss
Normal file
@@ -0,0 +1,40 @@
|
||||
// Overrides styles of jquery-ui/autocomplete
|
||||
//
|
||||
|
||||
/* Autocomplete
|
||||
----------------------------------*/
|
||||
.ui-autocomplete {
|
||||
position: absolute;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* workarounds */
|
||||
* html .ui-autocomplete {
|
||||
width: 1px;
|
||||
} /* without this, the menu expands to 100% in IE6 */
|
||||
|
||||
/* Menu
|
||||
----------------------------------*/
|
||||
.ui-menu {
|
||||
list-style: none;
|
||||
padding: $line-height / 4 $line-height / 3;
|
||||
display: block;
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
font-size: $small-font-size;
|
||||
|
||||
.ui-menu-item {
|
||||
|
||||
.ui-menu-item-wrapper {
|
||||
padding: $line-height / 4 $line-height / 3;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ui-state-hover,
|
||||
.ui-state-active {
|
||||
background: #ececec;
|
||||
border-radius: rem-calc(6);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
.progress-bar-placeholder {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.document-form {
|
||||
|
||||
.document .file-name {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.progress-bar-placeholder {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.document .loading-bar.errors {
|
||||
margin-top: $line-height * 2;
|
||||
}
|
||||
}
|
||||
|
||||
.document {
|
||||
|
||||
.button {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
width: 100%;
|
||||
background-color: $light-gray;
|
||||
}
|
||||
|
||||
.js-document-attachment {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.file-name {
|
||||
margin-top: $line-height / 2;
|
||||
}
|
||||
|
||||
.loading-bar {
|
||||
height: 5px;
|
||||
width: 0;
|
||||
transition: width 500ms ease-out;
|
||||
|
||||
&.uploading {
|
||||
background-color: $dark-gray;
|
||||
}
|
||||
|
||||
&.complete {
|
||||
background-color: $success-color;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&.errors {
|
||||
background-color: $alert-color;
|
||||
width: 100%;
|
||||
margin-top: $line-height / 2;
|
||||
}
|
||||
}
|
||||
|
||||
.loading-bar.no-transition {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
@import 'consul_settings';
|
||||
@import 'custom_settings';
|
||||
@import 'foundation';
|
||||
@import 'motion-ui/motion-ui';
|
||||
|
||||
@include foundation-global-styles;
|
||||
@include foundation-grid;
|
||||
@@ -37,3 +38,7 @@
|
||||
@include foundation-title-bar;
|
||||
@include foundation-top-bar;
|
||||
@include foundation-menu-icon;
|
||||
@include foundation-orbit;
|
||||
|
||||
@include motion-ui-transitions;
|
||||
@include motion-ui-animations;
|
||||
|
||||
@@ -97,10 +97,6 @@
|
||||
content: '\72';
|
||||
}
|
||||
|
||||
.icon-documents::before {
|
||||
content: '\68';
|
||||
}
|
||||
|
||||
.icon-proposals::before {
|
||||
content: '\68';
|
||||
}
|
||||
@@ -260,3 +256,35 @@
|
||||
.icon-instagram::before {
|
||||
content: '\32';
|
||||
}
|
||||
|
||||
.icon-image::before {
|
||||
content: '\33';
|
||||
}
|
||||
|
||||
.icon-search-plus::before {
|
||||
content: '\34';
|
||||
}
|
||||
|
||||
.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';
|
||||
}
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
// 16. Flags
|
||||
// 17. Activity
|
||||
// 18. Banners
|
||||
// 19. Documents
|
||||
// 19. Recommended Section Home
|
||||
// 20. Documents
|
||||
//
|
||||
|
||||
// 01. Global styles
|
||||
@@ -154,6 +155,10 @@ a {
|
||||
margin-bottom: $line-height;
|
||||
}
|
||||
|
||||
.margin-left {
|
||||
margin-left: $line-height;
|
||||
}
|
||||
|
||||
.margin-right {
|
||||
margin-right: $line-height;
|
||||
}
|
||||
@@ -205,19 +210,42 @@ a {
|
||||
|
||||
.menu.simple {
|
||||
border-bottom: 1px solid $border;
|
||||
margin-bottom: $line-height;
|
||||
clear: both;
|
||||
margin-bottom: $line-height / 2;
|
||||
|
||||
li {
|
||||
padding-bottom: rem-calc(7);
|
||||
font-size: $base-font-size;
|
||||
margin-bottom: 0;
|
||||
margin-right: $line-height / 2;
|
||||
|
||||
@include breakpoint(medium) {
|
||||
margin-right: $line-height * 1.5;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $text-medium;
|
||||
color: $text;
|
||||
display: inline-block;
|
||||
font-weight: bold;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
|
||||
&:hover {
|
||||
color: $link;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
border-bottom: 2px solid $brand;
|
||||
color: $brand;
|
||||
}
|
||||
|
||||
&:not(.active) {
|
||||
margin-bottom: $line-height / 3;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: $base-font-size;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,18 +309,25 @@ a {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.back:not([class^="icon-"]) {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.tabs-content {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.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);
|
||||
@@ -320,10 +355,32 @@ a {
|
||||
background: $brand;
|
||||
}
|
||||
|
||||
.truncate-horizontal-text {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.align-top {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.aling-middle {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.table {
|
||||
display: table;
|
||||
}
|
||||
|
||||
.table-cell {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.off-canvas-content {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.uppercase {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
@@ -371,7 +428,11 @@ header {
|
||||
|
||||
.top-bar-title a {
|
||||
@include logo;
|
||||
line-height: rem-calc(80) !important;
|
||||
line-height: rem-calc(80);
|
||||
|
||||
@include breakpoint(medium) {
|
||||
line-height: rem-calc(80);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
@@ -591,7 +652,7 @@ header {
|
||||
text-align: left;
|
||||
|
||||
@include breakpoint(medium) {
|
||||
margin-right: $line-height * 1.5;
|
||||
margin-right: $line-height;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@@ -1087,8 +1148,13 @@ form {
|
||||
color: #ecf00b;
|
||||
font-size: rem-calc(10);
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
left: 12px;
|
||||
top: 6px;
|
||||
|
||||
@include breakpoint(medium) {
|
||||
left: auto;
|
||||
right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1976,7 +2042,6 @@ table {
|
||||
// ------------
|
||||
|
||||
.activity {
|
||||
margin-bottom: $line-height * 2;
|
||||
|
||||
.accordion li {
|
||||
margin-bottom: $line-height / 2;
|
||||
@@ -2008,62 +2073,15 @@ table {
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
border: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
td {
|
||||
position: relative;
|
||||
|
||||
&:first-child {
|
||||
padding-left: $line-height * 1.5;
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
&::before {
|
||||
color: $brand;
|
||||
font-family: "icons" !important;
|
||||
font-size: rem-calc(24);
|
||||
left: 4px;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
.activity-comments td:first-child::before {
|
||||
content: 'e';
|
||||
top: 18px;
|
||||
}
|
||||
|
||||
.activity-debates td:first-child::before {
|
||||
content: 'i';
|
||||
top: 14px;
|
||||
}
|
||||
|
||||
.activity-proposals {
|
||||
|
||||
td:first-child::before {
|
||||
content: 'h';
|
||||
top: 18px;
|
||||
}
|
||||
|
||||
.retired {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
|
||||
.activity-investment-projects td:first-child::before,
|
||||
.activity-ballot td:first-child::before {
|
||||
content: '\53';
|
||||
top: 10px;
|
||||
.retired {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
|
||||
.public-interests {
|
||||
margin-top: $line-height;
|
||||
|
||||
.column {
|
||||
padding-left: 0;
|
||||
li {
|
||||
margin-right: $line-height / 4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2140,68 +2158,146 @@ table {
|
||||
}
|
||||
}
|
||||
|
||||
// 19. Documents
|
||||
.document-form form {
|
||||
// 19. Recommended Section Home
|
||||
// ----------------------------
|
||||
|
||||
.radio-buttons {
|
||||
label {
|
||||
margin-right: $line-height;
|
||||
}
|
||||
.home-page {
|
||||
|
||||
.push {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.section-recommended {
|
||||
padding: $line-height * 2 0;
|
||||
|
||||
h2 {
|
||||
margin-bottom: $line-height * 2;
|
||||
}
|
||||
|
||||
.source-option-link {
|
||||
input {
|
||||
padding-bottom: 0;
|
||||
.debates,
|
||||
.proposals,
|
||||
.budget-investments {
|
||||
|
||||
@include breakpoint(medium) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.error {
|
||||
@include breakpoint(small) {
|
||||
margin-bottom: $line-height;
|
||||
}
|
||||
|
||||
label {
|
||||
&.error {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.button.hollow {
|
||||
margin-top: rem-calc(15);
|
||||
}
|
||||
}
|
||||
|
||||
.source-option-file {
|
||||
.file-name {
|
||||
label {
|
||||
.card {
|
||||
|
||||
@include breakpoint(small medium) {
|
||||
float: none;
|
||||
}
|
||||
|
||||
@include breakpoint(large) {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
.card-section {
|
||||
padding: $line-height 0;
|
||||
max-width: rem-calc(300);
|
||||
margin: 0 auto;
|
||||
|
||||
p {
|
||||
font-size: rem-calc(15);
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
@include breakpoint(small medium) {
|
||||
float: none;
|
||||
margin-top: 0;
|
||||
margin-left: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.orbit {
|
||||
height: rem-calc(300);
|
||||
|
||||
@include breakpoint(large) {
|
||||
float: left;
|
||||
margin-bottom: 0;
|
||||
margin-top: $line-height / 2;
|
||||
margin-left: $line-height;
|
||||
}
|
||||
.orbit-wrapper {
|
||||
max-height: rem-calc(250);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.orbit-bullets {
|
||||
@include orbit-bullets;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.attachment-errors {
|
||||
margin-bottom: $line-height;
|
||||
.card .orbit .orbit-wrapper .truncate {
|
||||
background: image-url('truncate.png');
|
||||
background-repeat: repeat-x;
|
||||
bottom: 0;
|
||||
height: rem-calc(20);
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.debates-inner {
|
||||
border-top: 4px solid $debates;
|
||||
}
|
||||
|
||||
.proposals-inner {
|
||||
border-top: 4px solid $proposals;
|
||||
}
|
||||
|
||||
.budget-investments-inner {
|
||||
border-top: 4px solid $budget;
|
||||
}
|
||||
|
||||
.debates-inner,
|
||||
.proposals-inner,
|
||||
.budget-investments-inner {
|
||||
background: #fff;
|
||||
max-height: rem-calc(350);
|
||||
|
||||
@include breakpoint(small) {
|
||||
max-height: rem-calc(400);
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin-top: $line-height;
|
||||
margin-bottom: 0;
|
||||
font-size: rem-calc(18);
|
||||
min-height: rem-calc(50);
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: $small-font-size;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.carousel-image {
|
||||
|
||||
.card .orbit {
|
||||
height: rem-calc(480);
|
||||
|
||||
.orbit-wrapper {
|
||||
max-height: rem-calc(450);
|
||||
}
|
||||
}
|
||||
|
||||
.debates-inner,
|
||||
.proposals-inner,
|
||||
.budget-investments-inner {
|
||||
max-height: rem-calc(500);
|
||||
|
||||
@include breakpoint(small) {
|
||||
max-height: rem-calc(600);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.carousel-image .orbit-wrapper img {
|
||||
display: block;
|
||||
|
||||
@include breakpoint(small) {
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 20. Documents
|
||||
// -------------
|
||||
|
||||
.documents-list {
|
||||
|
||||
table {
|
||||
@@ -2258,6 +2354,31 @@ table {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.additional-document-link {
|
||||
background: $highlight-soft;
|
||||
border: 1px solid $highlight;
|
||||
display: block;
|
||||
margin: $line-height / 2 0;
|
||||
padding: $line-height / 2;
|
||||
position: relative;
|
||||
|
||||
a {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.icon-document {
|
||||
color: #007bb7;
|
||||
display: inline-block;
|
||||
font-size: rem-calc(24);
|
||||
line-height: $line-height;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.document-divider {
|
||||
background: #fafafa;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
@@ -109,16 +109,13 @@ $border-dark: darken($border, 10%);
|
||||
li {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
margin: 0 1rem 1rem 0;
|
||||
margin-bottom: $line-height;
|
||||
margin-right: $line-height;
|
||||
transition: all 0.4s;
|
||||
border-bottom: 2px solid transparent;
|
||||
|
||||
@include breakpoint(medium) {
|
||||
margin-left: $line-height * 2;
|
||||
}
|
||||
|
||||
&:first-of-type {
|
||||
margin-left: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
@@ -459,11 +456,11 @@ $border-dark: darken($border, 10%);
|
||||
span {
|
||||
vertical-align: inherit;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline;
|
||||
color: $text-medium;
|
||||
}
|
||||
.see-changes {
|
||||
color: $text-medium;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -477,6 +474,7 @@ $border-dark: darken($border, 10%);
|
||||
}
|
||||
|
||||
.draft-allegation {
|
||||
|
||||
@include breakpoint(medium) {
|
||||
display: flex;
|
||||
padding-left: 0.9375rem;
|
||||
@@ -493,7 +491,6 @@ $border-dark: darken($border, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
// Panel calcs for desktop
|
||||
@media screen and (min-width: 40em) {
|
||||
.calc-index {
|
||||
width: calc(35% - 25px);
|
||||
@@ -509,6 +506,7 @@ $border-dark: darken($border, 10%);
|
||||
width: rem-calc(50);
|
||||
|
||||
.draft-panel {
|
||||
|
||||
.panel-title {
|
||||
display: none;
|
||||
}
|
||||
@@ -912,19 +910,15 @@ $border-dark: darken($border, 10%);
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.show-for-medium {
|
||||
.panel-title {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 08. Legislation changes
|
||||
// -----------------
|
||||
|
||||
.legislation-changes {
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
margin-left: 0;
|
||||
@@ -936,35 +930,36 @@ $border-dark: darken($border, 10%);
|
||||
margin-right: 0.25rem;
|
||||
content: '—';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.changes-link {
|
||||
display: block;
|
||||
margin-left: 1rem;
|
||||
font-size: $small-font-size;
|
||||
.changes-link {
|
||||
display: block;
|
||||
margin-left: 1rem;
|
||||
font-size: $small-font-size;
|
||||
|
||||
@include breakpoint(medium) {
|
||||
display: inline-block;
|
||||
}
|
||||
@include breakpoint(medium) {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
a {
|
||||
span {
|
||||
text-decoration: underline;
|
||||
}
|
||||
a {
|
||||
|
||||
.icon-external {
|
||||
text-decoration: none;
|
||||
color: #999;
|
||||
line-height: 0;
|
||||
vertical-align: sub;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
span {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
&:active,
|
||||
&:focus,
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
.icon-external {
|
||||
text-decoration: none;
|
||||
color: #999;
|
||||
line-height: 0;
|
||||
vertical-align: sub;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
&:active,
|
||||
&:focus,
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -972,6 +967,7 @@ $border-dark: darken($border, 10%);
|
||||
|
||||
// 09. Legislation comments
|
||||
// -----------------
|
||||
|
||||
.legislation-comments {
|
||||
|
||||
.pull-right {
|
||||
@@ -1020,6 +1016,7 @@ $border-dark: darken($border, 10%);
|
||||
|
||||
// 10. Legislation draft comment
|
||||
// -----------------
|
||||
|
||||
.legislation-comment {
|
||||
|
||||
.annotation-share-comment {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
// Table of Contents
|
||||
//
|
||||
// 01. Logo
|
||||
//
|
||||
// 02. Orbit bullets
|
||||
// 03. Direct uploads
|
||||
// ------------------
|
||||
|
||||
// 01. Logo
|
||||
// --------
|
||||
@@ -30,3 +32,108 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 02. Orbit bullet
|
||||
// ----------------
|
||||
|
||||
@mixin orbit-bullets {
|
||||
@include disable-mouse-outline;
|
||||
position: relative;
|
||||
margin-top: $orbit-bullet-margin-top;
|
||||
margin-bottom: $orbit-bullet-margin-bottom;
|
||||
text-align: center;
|
||||
|
||||
button {
|
||||
width: $orbit-bullet-diameter;
|
||||
height: $orbit-bullet-diameter;
|
||||
margin: $orbit-bullet-margin;
|
||||
|
||||
border-radius: 50%;
|
||||
background-color: $orbit-bullet-background;
|
||||
|
||||
&:hover {
|
||||
background-color: $orbit-bullet-background-active;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
background-color: $orbit-bullet-background-active;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 03. Direct uploads
|
||||
// ------------------
|
||||
|
||||
@mixin direct-uploads {
|
||||
|
||||
.cached-image {
|
||||
max-width: rem-calc(150);
|
||||
max-height: rem-calc(150);
|
||||
}
|
||||
|
||||
.progress-bar-placeholder {
|
||||
display: none;
|
||||
margin-bottom: $line-height;
|
||||
}
|
||||
|
||||
.document,
|
||||
.image {
|
||||
|
||||
.document-attachment,
|
||||
.image-attachment {
|
||||
padding-left: 0;
|
||||
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.attachment-errors {
|
||||
|
||||
> .js-image-attachment,
|
||||
> .js-document-attachment {
|
||||
display: none;
|
||||
|
||||
~ .error {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
width: 100%;
|
||||
background-color: $light-gray;
|
||||
}
|
||||
|
||||
.file-name {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.loading-bar {
|
||||
height: 5px;
|
||||
width: 0;
|
||||
transition: width 500ms ease-out;
|
||||
|
||||
&.uploading {
|
||||
background-color: $dark-gray;
|
||||
}
|
||||
|
||||
&.complete {
|
||||
background-color: $success-color;
|
||||
}
|
||||
|
||||
&.errors {
|
||||
background-color: $alert-color;
|
||||
margin-top: $line-height / 2;
|
||||
}
|
||||
}
|
||||
|
||||
.loading-bar.no-transition {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
// 06. Budget
|
||||
// 07. Proposals successful
|
||||
// 08. Polls
|
||||
// 09. Polls results and stats
|
||||
//
|
||||
|
||||
// 01. Votes and supports
|
||||
@@ -249,12 +250,14 @@
|
||||
.proposal-form,
|
||||
.budget-investment-form,
|
||||
.spending-proposal-form,
|
||||
.document-form {
|
||||
.document-form,
|
||||
.topic-new,
|
||||
.topic-form {
|
||||
|
||||
.icon-debates,
|
||||
.icon-proposals,
|
||||
.icon-budget,
|
||||
.icon-documents {
|
||||
.icon-image {
|
||||
font-size: rem-calc(50);
|
||||
line-height: $line-height;
|
||||
opacity: 0.5;
|
||||
@@ -265,7 +268,7 @@
|
||||
}
|
||||
|
||||
.icon-proposals,
|
||||
.icon-documents {
|
||||
.icon-image {
|
||||
color: $proposals;
|
||||
}
|
||||
|
||||
@@ -298,13 +301,25 @@
|
||||
}
|
||||
|
||||
.proposal-form,
|
||||
.document-form {
|
||||
.document-form,
|
||||
.topic-form,
|
||||
.topic-new {
|
||||
|
||||
.recommendations li::before {
|
||||
color: $proposals;
|
||||
}
|
||||
}
|
||||
|
||||
.budget-investment-new,
|
||||
.proposal-form,
|
||||
.proposal-edit,
|
||||
.polls-form,
|
||||
.poll-question-form,
|
||||
.legislation-process-new,
|
||||
.legislation-process-edit {
|
||||
@include direct-uploads;
|
||||
}
|
||||
|
||||
// 03. Show participation
|
||||
// ----------------------
|
||||
|
||||
@@ -325,8 +340,16 @@
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.callout.proposal-retired {
|
||||
font-size: $base-font-size;
|
||||
.callout {
|
||||
&.token-message {
|
||||
background-color: #fff;
|
||||
border-color: $info-border;
|
||||
color: $color-info;
|
||||
}
|
||||
|
||||
&.proposal-retired {
|
||||
font-size: $base-font-size;
|
||||
}
|
||||
}
|
||||
|
||||
.social-share-full .social-share-button {
|
||||
@@ -345,11 +368,6 @@
|
||||
width: rem-calc(48);
|
||||
}
|
||||
|
||||
.edit-debate,
|
||||
.edit-proposal {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.debate-info,
|
||||
.proposal-info,
|
||||
.investment-project-info,
|
||||
@@ -636,6 +654,71 @@
|
||||
}
|
||||
}
|
||||
|
||||
.budget-investments-list .budget-investment,
|
||||
.proposals-list .proposal {
|
||||
|
||||
.no-image {
|
||||
background: $brand;
|
||||
}
|
||||
}
|
||||
|
||||
.budget-investments-list .budget-investment,
|
||||
.proposals-list .proposal {
|
||||
|
||||
@include breakpoint(small) {
|
||||
|
||||
.no-image {
|
||||
width: 100%;
|
||||
max-width: rem-calc(300);
|
||||
margin: 0 auto;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
display: block;
|
||||
padding-top: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include breakpoint(medium) {
|
||||
|
||||
.panel {
|
||||
|
||||
&.with-image {
|
||||
padding: 0 $line-height / 2 0 0;
|
||||
}
|
||||
|
||||
.no-image {
|
||||
height: 100%;
|
||||
min-height: rem-calc(245);
|
||||
width: rem-calc(140);
|
||||
}
|
||||
}
|
||||
|
||||
.column:first-child {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.column:nth-child(2) {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.column:last-child:not(:first-child) {
|
||||
padding-top: $line-height / 2;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 12rem;
|
||||
}
|
||||
|
||||
.budget-investment-content {
|
||||
ul {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.debate,
|
||||
.proposal,
|
||||
.investment-project,
|
||||
@@ -751,7 +834,7 @@
|
||||
background: image-url('truncate.png');
|
||||
background-repeat: repeat-x;
|
||||
bottom: 0;
|
||||
height: 24px;
|
||||
height: rem-calc(24);
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
@@ -765,12 +848,6 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
.document-form {
|
||||
max-width: 75rem;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.more-info {
|
||||
clear: both;
|
||||
color: $text-medium;
|
||||
@@ -782,7 +859,9 @@
|
||||
}
|
||||
|
||||
.debate,
|
||||
.debate-show {
|
||||
.debate-show,
|
||||
.proposal-show,
|
||||
.legislation-proposals {
|
||||
|
||||
.votes {
|
||||
@include votes;
|
||||
@@ -797,6 +876,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.proposal-show .votes,
|
||||
.debate-show .votes {
|
||||
border: 0;
|
||||
padding: $line-height / 2 0;
|
||||
@@ -855,6 +935,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
.budget-investment-show {
|
||||
|
||||
figure {
|
||||
margin: rem-calc(10) 0 0;
|
||||
display: inline-block;
|
||||
|
||||
figcaption {
|
||||
font-size: $small-font-size;
|
||||
margin-top: rem-calc(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.investment-project-show .supports,
|
||||
.budget-investment-show .supports {
|
||||
border: 0;
|
||||
@@ -1389,33 +1482,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 {
|
||||
@@ -1464,18 +1530,8 @@
|
||||
// 08. Polls
|
||||
// ----------------------
|
||||
|
||||
.dark-heading {
|
||||
background: #2d3e50;
|
||||
color: #fff;
|
||||
|
||||
.title {
|
||||
color: #92ba48;
|
||||
}
|
||||
|
||||
.button {
|
||||
background: #fff;
|
||||
color: $brand;
|
||||
}
|
||||
.polls-show-header {
|
||||
background: #fafafa;
|
||||
|
||||
.callout {
|
||||
|
||||
@@ -1491,28 +1547,117 @@
|
||||
color: $color-alert;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
background: #314253;
|
||||
padding: $line-height;
|
||||
.poll-more-info,
|
||||
.poll-more-info-answers {
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
|
||||
@include breakpoint(medium) {
|
||||
border-top: rem-calc(6) solid #92ba48;
|
||||
.poll-more-info-answers {
|
||||
background: #fafafa;
|
||||
border-bottom: 1px solid #eee;
|
||||
|
||||
.column:nth-child(odd) {
|
||||
border-right: 2px solid $text;
|
||||
}
|
||||
|
||||
.answer-divider {
|
||||
border-bottom: 2px solid $text;
|
||||
border-right: 0 !important;
|
||||
margin-bottom: $line-height;
|
||||
padding-bottom: $line-height;
|
||||
}
|
||||
|
||||
.answer-description {
|
||||
height: 100%;
|
||||
|
||||
&.short {
|
||||
height: rem-calc(300);
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a:not(.button) {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
.orbit-bullets button {
|
||||
background-color: #ccc;
|
||||
height: $line-height / 2;
|
||||
width: $line-height / 2;
|
||||
|
||||
&.is-active {
|
||||
background-color: $brand;
|
||||
}
|
||||
}
|
||||
|
||||
.back,
|
||||
.icon-angle-left {
|
||||
color: #fff;
|
||||
.orbit-container {
|
||||
height: 100% !important;
|
||||
max-height: none !important;
|
||||
|
||||
li {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.polls-show-header {
|
||||
min-height: $line-height * 8;
|
||||
.orbit-slide {
|
||||
max-height: none !important;
|
||||
|
||||
img {
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
}
|
||||
|
||||
.orbit-caption {
|
||||
background: #eee;
|
||||
color: $text;
|
||||
}
|
||||
|
||||
.orbit-next,
|
||||
.orbit-previous {
|
||||
background: rgba(34, 34, 34, 0.25);
|
||||
}
|
||||
|
||||
.zoom-link {
|
||||
background: #fff;
|
||||
border-radius: rem-calc(48);
|
||||
color: #000;
|
||||
font-size: rem-calc(24);
|
||||
font-weight: bold;
|
||||
height: rem-calc(48);
|
||||
line-height: rem-calc(48);
|
||||
right: 12px;
|
||||
padding-top: rem-calc(4);
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: 24px;
|
||||
width: rem-calc(48);
|
||||
z-index: 9;
|
||||
|
||||
&:hover {
|
||||
background: $dark;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.image-container {
|
||||
background: #fafafa;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.poll {
|
||||
|
||||
&.with-image {
|
||||
|
||||
@include breakpoint(medium) {
|
||||
padding: 0 $line-height / 2 0 0;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 100%;
|
||||
max-width: none;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1610,9 +1755,13 @@
|
||||
}
|
||||
|
||||
.section-title-divider {
|
||||
border-bottom: 2px solid $brand;
|
||||
color: $brand;
|
||||
margin-bottom: $line-height;
|
||||
border-bottom: 1px solid #eee;
|
||||
color: #000;
|
||||
margin: $line-height 0;
|
||||
|
||||
span {
|
||||
border-bottom: 1px solid #000;
|
||||
}
|
||||
}
|
||||
|
||||
.poll-question {
|
||||
@@ -1633,6 +1782,10 @@
|
||||
margin-right: $line-height / 4;
|
||||
min-width: rem-calc(168);
|
||||
|
||||
@include breakpoint(medium down) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&.answered {
|
||||
background: #f4f8ec;
|
||||
border: 2px solid #92ba48;
|
||||
@@ -1654,3 +1807,59 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 09. Polls results and stats
|
||||
// ---------------------------
|
||||
|
||||
.polls-results-stats {
|
||||
|
||||
.sidebar {
|
||||
border-bottom: 1px solid $border;
|
||||
margin-bottom: $line-height;
|
||||
|
||||
@include breakpoint(medium) {
|
||||
border-bottom: 0;
|
||||
border-right: 1px solid $border;
|
||||
}
|
||||
|
||||
.menu {
|
||||
padding: 0;
|
||||
|
||||
li a {
|
||||
color: $link;
|
||||
line-height: $line-height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#print_link { display: none !important; }
|
||||
|
||||
#responsive-menu { display: none !important; }
|
||||
#responsive_menu { display: none !important; }
|
||||
|
||||
.admin-sidebar { display: none !important; }
|
||||
|
||||
|
||||
@@ -6,16 +6,10 @@ class Admin::AdministratorsController < Admin::BaseController
|
||||
end
|
||||
|
||||
def search
|
||||
@user = User.find_by(email: params[:email])
|
||||
|
||||
respond_to do |format|
|
||||
if @user
|
||||
@administrator = Administrator.find_or_initialize_by(user: @user)
|
||||
format.js
|
||||
else
|
||||
format.js { render "user_not_found" }
|
||||
end
|
||||
end
|
||||
@users = User.search(params[:name_or_email])
|
||||
.includes(:administrator)
|
||||
.page(params[:page])
|
||||
.for_render
|
||||
end
|
||||
|
||||
def create
|
||||
|
||||
@@ -51,7 +51,7 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
|
||||
|
||||
def budget_investment_params
|
||||
params.require(:budget_investment)
|
||||
.permit(:title, :description, :external_url, :heading_id, :administrator_id, :valuation_tag_list, :incompatible,
|
||||
.permit(:title, :description, :external_url, :heading_id, :administrator_id, :tag_list, :valuation_tag_list, :incompatible,
|
||||
:selected, valuator_ids: [])
|
||||
end
|
||||
|
||||
|
||||
@@ -19,8 +19,10 @@ class Admin::Legislation::ProcessesController < Admin::Legislation::BaseControll
|
||||
|
||||
def update
|
||||
if @process.update(process_params)
|
||||
set_tag_list
|
||||
|
||||
link = legislation_process_path(@process).html_safe
|
||||
redirect_to edit_admin_legislation_process_path(@process), notice: t('admin.legislation.processes.update.notice', link: link)
|
||||
redirect_to :back, notice: t('admin.legislation.processes.update.notice', link: link)
|
||||
else
|
||||
flash.now[:error] = t('admin.legislation.processes.update.error')
|
||||
render :edit
|
||||
@@ -47,12 +49,23 @@ class Admin::Legislation::ProcessesController < Admin::Legislation::BaseControll
|
||||
:draft_publication_date,
|
||||
:allegations_start_date,
|
||||
:allegations_end_date,
|
||||
:proposals_phase_start_date,
|
||||
:proposals_phase_end_date,
|
||||
:result_publication_date,
|
||||
:debate_phase_enabled,
|
||||
:allegations_phase_enabled,
|
||||
:proposals_phase_enabled,
|
||||
:draft_publication_enabled,
|
||||
:result_publication_enabled,
|
||||
:published
|
||||
:published,
|
||||
:proposals_description,
|
||||
:custom_list,
|
||||
documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy]
|
||||
)
|
||||
end
|
||||
|
||||
def set_tag_list
|
||||
@process.set_tag_list_on(:customs, process_params[:custom_list])
|
||||
@process.save
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
class Admin::Legislation::ProposalsController < Admin::Legislation::BaseController
|
||||
load_and_authorize_resource :process, class: "Legislation::Process"
|
||||
load_and_authorize_resource :proposal, class: "Legislation::Proposal", through: :process
|
||||
|
||||
def index
|
||||
end
|
||||
end
|
||||
@@ -6,16 +6,10 @@ class Admin::ManagersController < Admin::BaseController
|
||||
end
|
||||
|
||||
def search
|
||||
@user = User.find_by(email: params[:email])
|
||||
|
||||
respond_to do |format|
|
||||
if @user
|
||||
@manager = Manager.find_or_initialize_by(user: @user)
|
||||
format.js
|
||||
else
|
||||
format.js { render "user_not_found" }
|
||||
end
|
||||
end
|
||||
@users = User.search(params[:name_or_email])
|
||||
.includes(:manager)
|
||||
.page(params[:page])
|
||||
.for_render
|
||||
end
|
||||
|
||||
def create
|
||||
|
||||
@@ -6,16 +6,10 @@ class Admin::ModeratorsController < Admin::BaseController
|
||||
end
|
||||
|
||||
def search
|
||||
@user = User.find_by(email: params[:email])
|
||||
|
||||
respond_to do |format|
|
||||
if @user
|
||||
@moderator = Moderator.find_or_initialize_by(user: @user)
|
||||
format.js
|
||||
else
|
||||
format.js { render "user_not_found" }
|
||||
end
|
||||
end
|
||||
@users = User.search(params[:name_or_email])
|
||||
.includes(:moderator)
|
||||
.page(params[:page])
|
||||
.for_render
|
||||
end
|
||||
|
||||
def create
|
||||
|
||||
@@ -15,24 +15,32 @@ class Admin::Poll::BoothAssignmentsController < Admin::Poll::BaseController
|
||||
end
|
||||
|
||||
def show
|
||||
@booth_assignment = @poll.booth_assignments.includes(:total_results, :voters,
|
||||
@booth_assignment = @poll.booth_assignments.includes(:recounts, :voters,
|
||||
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
|
||||
@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
|
||||
@@ -40,7 +48,14 @@ 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
|
||||
@booths = ::Poll::Booth.all
|
||||
@poll = Poll.find(params[:poll_id])
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -18,14 +18,16 @@ class Admin::Poll::OfficerAssignmentsController < Admin::Poll::BaseController
|
||||
@officer = ::Poll::Officer.includes(:user).find(officer_assignment_params[:officer_id])
|
||||
@officer_assignments = ::Poll::OfficerAssignment.
|
||||
joins(:booth_assignment).
|
||||
includes(:total_results, booth_assignment: :booth).
|
||||
includes(:recounts, booth_assignment: :booth).
|
||||
where("officer_id = ? AND poll_booth_assignments.poll_id = ?", @officer.id, @poll.id).
|
||||
order(:date)
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class Admin::Poll::PollsController < Admin::Poll::BaseController
|
||||
load_and_authorize_resource
|
||||
|
||||
before_action :load_search, only: [:search_booths, :search_questions, :search_officers]
|
||||
before_action :load_search, only: [:search_booths, :search_officers]
|
||||
before_action :load_geozones, only: [:new, :create, :edit, :update]
|
||||
|
||||
def index
|
||||
@@ -47,23 +47,8 @@ class Admin::Poll::PollsController < Admin::Poll::BaseController
|
||||
redirect_to admin_poll_path(@poll), notice: notice
|
||||
end
|
||||
|
||||
def remove_question
|
||||
question = ::Poll::Question.find(params[:question_id])
|
||||
|
||||
if @poll.questions.include? question
|
||||
@poll.questions.delete(question)
|
||||
notice = t("admin.polls.flash.question_removed")
|
||||
else
|
||||
notice = t("admin.polls.flash.error_on_question_removed")
|
||||
end
|
||||
redirect_to admin_poll_path(@poll), notice: notice
|
||||
end
|
||||
|
||||
def search_questions
|
||||
@questions = ::Poll::Question.where("poll_id IS ? OR poll_id != ?", nil, @poll.id).search(search: @search).order(title: :asc)
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
def booth_assignments
|
||||
@polls = Poll.current_or_incoming
|
||||
end
|
||||
|
||||
private
|
||||
@@ -73,7 +58,10 @@ class Admin::Poll::PollsController < Admin::Poll::BaseController
|
||||
end
|
||||
|
||||
def poll_params
|
||||
params.require(:poll).permit(:name, :starts_at, :ends_at, :geozone_restricted, geozone_ids: [])
|
||||
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
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
class Admin::Poll::Questions::Answers::ImagesController < Admin::Poll::BaseController
|
||||
before_action :load_answer
|
||||
|
||||
def index
|
||||
end
|
||||
|
||||
def new
|
||||
@answer = ::Poll::Question::Answer.find(params[:answer_id])
|
||||
end
|
||||
|
||||
def create
|
||||
@answer = ::Poll::Question::Answer.find(params[:answer_id])
|
||||
@answer.attributes = images_params
|
||||
|
||||
if @answer.save
|
||||
redirect_to admin_answer_images_path(@answer),
|
||||
notice: "Image uploaded successfully"
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def images_params
|
||||
params.require(:poll_question_answer).permit(:answer_id,
|
||||
images_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy])
|
||||
end
|
||||
|
||||
def load_answer
|
||||
@answer = ::Poll::Question::Answer.find(params[:answer_id])
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,57 @@
|
||||
class Admin::Poll::Questions::Answers::VideosController < Admin::Poll::BaseController
|
||||
before_action :load_answer, only: [:index, :new, :create]
|
||||
before_action :load_video, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
end
|
||||
|
||||
def new
|
||||
@video = ::Poll::Question::Answer::Video.new
|
||||
end
|
||||
|
||||
def create
|
||||
@video = ::Poll::Question::Answer::Video.new(video_params)
|
||||
|
||||
if @video.save
|
||||
redirect_to admin_answer_videos_path(@answer),
|
||||
notice: t("flash.actions.create.poll_question_answer_video")
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
if @video.update(video_params)
|
||||
redirect_to admin_answer_videos_path(@video.answer_id),
|
||||
notice: t("flash.actions.save_changes.notice")
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
notice = if @video.destroy
|
||||
t("flash.actions.destroy.poll_question_answer_video")
|
||||
else
|
||||
t("flash.actions.destroy.error")
|
||||
end
|
||||
redirect_to :back, notice: notice
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def video_params
|
||||
params.require(:poll_question_answer_video).permit(:title, :url, :answer_id)
|
||||
end
|
||||
|
||||
def load_answer
|
||||
@answer = ::Poll::Question::Answer.find(params[:answer_id])
|
||||
end
|
||||
|
||||
def load_video
|
||||
@video = ::Poll::Question::Answer::Video.find(params[:id])
|
||||
end
|
||||
end
|
||||
57
app/controllers/admin/poll/questions/answers_controller.rb
Normal file
@@ -0,0 +1,57 @@
|
||||
class Admin::Poll::Questions::AnswersController < Admin::Poll::BaseController
|
||||
before_action :load_answer, only: [:show, :edit, :update, :documents]
|
||||
|
||||
load_and_authorize_resource :question, class: "::Poll::Question"
|
||||
|
||||
def new
|
||||
@answer = ::Poll::Question::Answer.new
|
||||
end
|
||||
|
||||
def create
|
||||
@answer = ::Poll::Question::Answer.new(answer_params)
|
||||
|
||||
if @answer.save
|
||||
redirect_to admin_question_path(@answer.question),
|
||||
notice: t("flash.actions.create.poll_question_answer")
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
if @answer.update(answer_params)
|
||||
redirect_to admin_question_path(@answer.question),
|
||||
notice: t("flash.actions.save_changes.notice")
|
||||
else
|
||||
redirect_to :back
|
||||
end
|
||||
end
|
||||
|
||||
def documents
|
||||
@documents = @answer.documents
|
||||
|
||||
render 'admin/poll/questions/answers/documents'
|
||||
end
|
||||
|
||||
def order_answers
|
||||
::Poll::Question::Answer.order_answers(params[:ordered_list])
|
||||
render nothing: true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def answer_params
|
||||
params.require(:poll_question_answer).permit(:title, :description, :question_id, documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy])
|
||||
end
|
||||
|
||||
def load_answer
|
||||
@answer = ::Poll::Question::Answer.find(params[:id] || params[:answer_id])
|
||||
end
|
||||
|
||||
end
|
||||
@@ -15,14 +15,12 @@ class Admin::Poll::QuestionsController < Admin::Poll::BaseController
|
||||
|
||||
def new
|
||||
@polls = Poll.all
|
||||
@question.valid_answers = I18n.t('poll_questions.default_valid_answers')
|
||||
proposal = Proposal.find(params[:proposal_id]) if params[:proposal_id].present?
|
||||
@question.copy_attributes_from_proposal(proposal)
|
||||
end
|
||||
|
||||
def create
|
||||
@question.author = @question.proposal.try(:author) || current_user
|
||||
recover_documents_from_cache(@question)
|
||||
|
||||
if @question.save
|
||||
redirect_to admin_question_path(@question)
|
||||
@@ -32,7 +30,6 @@ class Admin::Poll::QuestionsController < Admin::Poll::BaseController
|
||||
end
|
||||
|
||||
def show
|
||||
@document = Document.new(documentable: @question)
|
||||
end
|
||||
|
||||
def edit
|
||||
@@ -58,8 +55,7 @@ class Admin::Poll::QuestionsController < Admin::Poll::BaseController
|
||||
private
|
||||
|
||||
def question_params
|
||||
params.require(:poll_question).permit(:poll_id, :title, :question, :description, :proposal_id, :valid_answers, :video_url,
|
||||
documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id])
|
||||
params.require(:poll_question).permit(:poll_id, :title, :question, :proposal_id, :video_url)
|
||||
end
|
||||
|
||||
def search_params
|
||||
|
||||
@@ -3,7 +3,7 @@ class Admin::Poll::RecountsController < Admin::Poll::BaseController
|
||||
|
||||
def index
|
||||
@booth_assignments = @poll.booth_assignments.
|
||||
includes(:booth, :total_results, :voters).
|
||||
includes(:booth, :recounts, :voters).
|
||||
order("poll_booths.name").
|
||||
page(params[:page]).per(50)
|
||||
end
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
class Admin::Poll::ShiftsController < Admin::Poll::BaseController
|
||||
|
||||
before_action :load_booth
|
||||
before_action :load_polls
|
||||
before_action :load_officer
|
||||
|
||||
def new
|
||||
load_shifts
|
||||
@shift = ::Poll::Shift.new
|
||||
@voting_polls = @booth.polls.current_or_incoming
|
||||
@recount_polls = @booth.polls.current_or_recounting_or_incoming
|
||||
end
|
||||
|
||||
def create
|
||||
@@ -14,10 +15,10 @@ class Admin::Poll::ShiftsController < Admin::Poll::BaseController
|
||||
@officer = @shift.officer
|
||||
|
||||
if @shift.save
|
||||
notice = t("admin.poll_shifts.flash.create")
|
||||
redirect_to new_admin_booth_shift_path(@shift.booth), notice: notice
|
||||
redirect_to new_admin_booth_shift_path(@shift.booth), notice: t("admin.poll_shifts.flash.create")
|
||||
else
|
||||
load_shifts
|
||||
flash[:error] = t("admin.poll_shifts.flash.date_missing")
|
||||
render :new
|
||||
end
|
||||
end
|
||||
@@ -30,7 +31,7 @@ class Admin::Poll::ShiftsController < Admin::Poll::BaseController
|
||||
end
|
||||
|
||||
def search_officers
|
||||
@officers = User.search(params[:search]).order(username: :asc)
|
||||
@officers = User.search(params[:search]).order(username: :asc).select { |o| o.poll_officer? == true }
|
||||
end
|
||||
|
||||
private
|
||||
@@ -39,10 +40,6 @@ class Admin::Poll::ShiftsController < Admin::Poll::BaseController
|
||||
@booth = ::Poll::Booth.find(params[:booth_id])
|
||||
end
|
||||
|
||||
def load_polls
|
||||
@polls = ::Poll.current_or_incoming
|
||||
end
|
||||
|
||||
def load_shifts
|
||||
@shifts = @booth.shifts
|
||||
end
|
||||
@@ -54,7 +51,7 @@ class Admin::Poll::ShiftsController < Admin::Poll::BaseController
|
||||
end
|
||||
|
||||
def shift_params
|
||||
params.require(:shift).permit(:booth_id, :officer_id, :date)
|
||||
shift_params = params.require(:shift).permit(:booth_id, :officer_id, :task, date: [:vote_collection_date, :recount_scrutiny_date])
|
||||
shift_params.merge(date: shift_params[:date]["#{shift_params[:task]}_date".to_sym])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class Admin::SettingsController < Admin::BaseController
|
||||
|
||||
def index
|
||||
all_settings = (Setting.all).group_by { |s| s.type }
|
||||
all_settings = Setting.all.group_by { |s| s.type }
|
||||
@settings = all_settings['common']
|
||||
@feature_flags = all_settings['feature']
|
||||
@banner_styles = all_settings['banner-style']
|
||||
@@ -14,6 +14,13 @@ class Admin::SettingsController < Admin::BaseController
|
||||
redirect_to admin_settings_path, notice: t("admin.settings.flash.updated")
|
||||
end
|
||||
|
||||
def update_map
|
||||
Setting["map_latitude"] = params[:latitude].to_f
|
||||
Setting["map_longitude"] = params[:longitude].to_f
|
||||
Setting["map_zoom"] = params[:zoom].to_i
|
||||
redirect_to admin_settings_path, notice: t("admin.settings.index.map.flash.update")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def settings_params
|
||||
|
||||
@@ -6,16 +6,10 @@ class Admin::ValuatorsController < Admin::BaseController
|
||||
end
|
||||
|
||||
def search
|
||||
@user = User.find_by(email: params[:email])
|
||||
|
||||
respond_to do |format|
|
||||
if @user
|
||||
@valuator = Valuator.find_or_initialize_by(user: @user)
|
||||
format.js
|
||||
else
|
||||
format.js { render "user_not_found" }
|
||||
end
|
||||
end
|
||||
@users = User.search(params[:name_or_email])
|
||||
.includes(:valuator)
|
||||
.page(params[:page])
|
||||
.for_render
|
||||
end
|
||||
|
||||
def create
|
||||
@@ -25,6 +19,11 @@ class Admin::ValuatorsController < Admin::BaseController
|
||||
redirect_to admin_valuators_path
|
||||
end
|
||||
|
||||
def destroy
|
||||
@valuator.destroy
|
||||
redirect_to admin_valuators_path
|
||||
end
|
||||
|
||||
def summary
|
||||
@valuators = Valuator.order(spending_proposals_count: :desc)
|
||||
end
|
||||
@@ -36,4 +35,4 @@ class Admin::ValuatorsController < Admin::BaseController
|
||||
params.require(:valuator).permit(:user_id, :description)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -44,12 +44,10 @@ module Budgets
|
||||
set_comment_flags(@comment_tree.comments)
|
||||
load_investment_votes(@investment)
|
||||
@investment_ids = [@investment.id]
|
||||
@document = Document.new(documentable: @investment)
|
||||
end
|
||||
|
||||
def create
|
||||
@investment.author = current_user
|
||||
recover_documents_from_cache(@investment)
|
||||
|
||||
if @investment.save
|
||||
Mailer.budget_investment_created(@investment).deliver_later
|
||||
@@ -105,9 +103,12 @@ module Budgets
|
||||
end
|
||||
|
||||
def investment_params
|
||||
params.require(:budget_investment).permit(:title, :description, :external_url, :heading_id, :tag_list,
|
||||
:organization_name, :location, :terms_of_service,
|
||||
documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id])
|
||||
params.require(:budget_investment)
|
||||
.permit(:title, :description, :external_url, :heading_id, :tag_list,
|
||||
:organization_name, :location, :terms_of_service,
|
||||
image_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy],
|
||||
documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy],
|
||||
map_location_attributes: [:latitude, :longitude, :zoom])
|
||||
end
|
||||
|
||||
def load_ballot
|
||||
|
||||
@@ -4,17 +4,22 @@ module CommentableActions
|
||||
include Search
|
||||
|
||||
def index
|
||||
@resources = @search_terms.present? ? resource_model.search(@search_terms) : resource_model.all
|
||||
@resources = @advanced_search_terms.present? ? @resources.filter(@advanced_search_terms) : @resources
|
||||
@resources = resource_model.all
|
||||
|
||||
@resources = @current_order == "recommendations" && current_user.present? ? @resources.recommendations(current_user) : @resources.for_render
|
||||
@resources = @resources.search(@search_terms) if @search_terms.present?
|
||||
@resources = @advanced_search_terms.present? ? @resources.filter(@advanced_search_terms) : @resources
|
||||
@resources = @resources.tagged_with(@tag_filter) if @tag_filter
|
||||
@resources = @resources.page(params[:page]).for_render.send("sort_by_#{@current_order}")
|
||||
|
||||
@resources = @resources.page(params[:page]).send("sort_by_#{@current_order}")
|
||||
|
||||
index_customization if index_customization.present?
|
||||
|
||||
@tag_cloud = tag_cloud
|
||||
@banners = Banner.with_active
|
||||
|
||||
set_resource_votes(@resources)
|
||||
|
||||
set_resources_instance
|
||||
end
|
||||
|
||||
@@ -57,10 +62,7 @@ module CommentableActions
|
||||
end
|
||||
|
||||
def update
|
||||
resource.assign_attributes(strong_params)
|
||||
recover_documents_from_cache(resource)
|
||||
|
||||
if resource.save
|
||||
if resource.update(strong_params)
|
||||
redirect_to resource, notice: t("flash.actions.update.#{resource_name.underscore}")
|
||||
else
|
||||
load_categories
|
||||
@@ -112,11 +114,4 @@ module CommentableActions
|
||||
nil
|
||||
end
|
||||
|
||||
def recover_documents_from_cache(resource)
|
||||
return false unless resource.try(:documents)
|
||||
resource.documents = resource.documents.each do |document|
|
||||
document.set_attachment_from_cached_attachment if document.cached_attachment.present?
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -10,7 +10,7 @@ class DebatesController < ApplicationController
|
||||
|
||||
invisible_captcha only: [:create, :update], honeypot: :subtitle
|
||||
|
||||
has_orders %w{hot_score confidence_score created_at relevance}, only: :index
|
||||
has_orders ->(c) { Debate.debates_orders(c.current_user) }, only: :index
|
||||
has_orders %w{most_voted newest oldest}, only: :show
|
||||
|
||||
load_and_authorize_resource
|
||||
|
||||
48
app/controllers/direct_uploads_controller.rb
Normal file
@@ -0,0 +1,48 @@
|
||||
class DirectUploadsController < ApplicationController
|
||||
include DirectUploadsHelper
|
||||
include ActionView::Helpers::UrlHelper
|
||||
before_action :authenticate_user!
|
||||
|
||||
load_and_authorize_resource except: :create
|
||||
skip_authorization_check only: :create
|
||||
|
||||
helper_method :render_destroy_upload_link
|
||||
|
||||
def create
|
||||
@direct_upload = DirectUpload.new(direct_upload_params.merge(user: current_user, attachment: params[:attachment]))
|
||||
|
||||
if @direct_upload.valid?
|
||||
@direct_upload.save_attachment
|
||||
@direct_upload.relation.set_cached_attachment_from_attachment
|
||||
|
||||
render json: { cached_attachment: @direct_upload.relation.cached_attachment,
|
||||
filename: @direct_upload.relation.attachment.original_filename,
|
||||
destroy_link: render_destroy_upload_link(@direct_upload).html_safe,
|
||||
attachment_url: @direct_upload.relation.attachment.url}
|
||||
else
|
||||
@direct_upload.destroy_attachment
|
||||
render json: { errors: @direct_upload.errors[:attachment].join(", ") },
|
||||
status: 422
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@direct_upload = DirectUpload.new(direct_upload_params.merge(user: current_user))
|
||||
@direct_upload.relation.set_attachment_from_cached_attachment
|
||||
|
||||
if @direct_upload.destroy_attachment
|
||||
render json: :ok
|
||||
else
|
||||
render json: :error
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def direct_upload_params
|
||||
params.require(:direct_upload)
|
||||
.permit(:resource, :resource_type, :resource_id, :resource_relation,
|
||||
:attachment, :cached_attachment, attachment_attributes: [])
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,29 +1,7 @@
|
||||
class DocumentsController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
before_action :find_documentable, except: :destroy
|
||||
before_action :prepare_new_document, only: [:new, :new_nested]
|
||||
before_action :prepare_document_for_creation, only: :create
|
||||
|
||||
load_and_authorize_resource except: :upload
|
||||
skip_authorization_check only: :upload
|
||||
|
||||
def new
|
||||
end
|
||||
|
||||
def new_nested
|
||||
end
|
||||
|
||||
def create
|
||||
recover_attachments_from_cache
|
||||
|
||||
if @document.save
|
||||
flash[:notice] = t "documents.actions.create.notice"
|
||||
redirect_to params[:from]
|
||||
else
|
||||
flash[:alert] = t "documents.actions.create.alert"
|
||||
render :new
|
||||
end
|
||||
end
|
||||
load_and_authorize_resource
|
||||
|
||||
def destroy
|
||||
respond_to do |format|
|
||||
@@ -45,57 +23,4 @@ class DocumentsController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
def destroy_upload
|
||||
@document = Document.new(cached_attachment: params[:path])
|
||||
@document.set_attachment_from_cached_attachment
|
||||
@document.cached_attachment = nil
|
||||
@document.documentable = @documentable
|
||||
|
||||
if @document.attachment.destroy
|
||||
flash.now[:notice] = t "documents.actions.destroy.notice"
|
||||
else
|
||||
flash.now[:alert] = t "documents.actions.destroy.alert"
|
||||
end
|
||||
render :destroy
|
||||
end
|
||||
|
||||
def upload
|
||||
@document = Document.new(document_params.merge(user: current_user))
|
||||
@document.documentable = @documentable
|
||||
|
||||
if @document.valid?
|
||||
@document.attachment.save
|
||||
@document.set_cached_attachment_from_attachment(URI(request.url))
|
||||
else
|
||||
@document.attachment.destroy
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def document_params
|
||||
params.require(:document).permit(:title, :documentable_type, :documentable_id,
|
||||
:attachment, :cached_attachment, :user_id)
|
||||
end
|
||||
|
||||
def find_documentable
|
||||
@documentable = params[:documentable_type].constantize.find_or_initialize_by(id: params[:documentable_id])
|
||||
end
|
||||
|
||||
def prepare_new_document
|
||||
@document = Document.new(documentable: @documentable, user_id: current_user.id)
|
||||
end
|
||||
|
||||
def prepare_document_for_creation
|
||||
@document = Document.new(document_params)
|
||||
@document.documentable = @documentable
|
||||
@document.user = current_user
|
||||
end
|
||||
|
||||
def recover_attachments_from_cache
|
||||
if @document.attachment.blank? && @document.cached_attachment.present?
|
||||
@document.set_attachment_from_cached_attachment
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
26
app/controllers/images_controller.rb
Normal file
@@ -0,0 +1,26 @@
|
||||
class ImagesController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
|
||||
load_and_authorize_resource
|
||||
|
||||
def destroy
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
if @image.destroy
|
||||
flash[:notice] = t "images.actions.destroy.notice"
|
||||
else
|
||||
flash[:alert] = t "images.actions.destroy.alert"
|
||||
end
|
||||
redirect_to params[:from]
|
||||
end
|
||||
format.js do
|
||||
if @image.destroy
|
||||
flash.now[:notice] = t "images.actions.destroy.notice"
|
||||
else
|
||||
flash.now[:alert] = t "images.actions.destroy.alert"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -30,7 +30,7 @@ class Legislation::AnnotationsController < ApplicationController
|
||||
|
||||
def create
|
||||
if !@process.allegations_phase.open? || @draft_version.final_version?
|
||||
render(json: {}, status: :not_found) && (return)
|
||||
render(json: {}, status: :not_found) && return
|
||||
end
|
||||
|
||||
existing_annotation = @draft_version.annotations.where(
|
||||
|
||||
@@ -30,7 +30,7 @@ class Legislation::AnswersController < Legislation::BaseController
|
||||
|
||||
def answer_params
|
||||
params.require(:legislation_answer).permit(
|
||||
:legislation_question_option_id,
|
||||
:legislation_question_option_id
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -2,4 +2,8 @@ class Legislation::BaseController < ApplicationController
|
||||
include FeatureFlags
|
||||
|
||||
feature_flag :legislation
|
||||
|
||||
def legislation_proposal_votes(proposals)
|
||||
@legislation_proposal_votes = current_user ? current_user.legislation_proposal_votes(proposals) : {}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,6 +14,8 @@ class Legislation::ProcessesController < Legislation::BaseController
|
||||
redirect_to legislation_process_draft_version_path(@process, draft_version)
|
||||
elsif @process.debate_phase.enabled?
|
||||
redirect_to debate_legislation_process_path(@process)
|
||||
elsif @process.proposals_phase.enabled?
|
||||
redirect_to proposals_legislation_process_path(@process)
|
||||
else
|
||||
redirect_to allegations_legislation_process_path(@process)
|
||||
end
|
||||
@@ -81,6 +83,18 @@ class Legislation::ProcessesController < Legislation::BaseController
|
||||
end
|
||||
end
|
||||
|
||||
def proposals
|
||||
set_process
|
||||
@phase = :proposals_phase
|
||||
|
||||
if @process.proposals_phase.started?
|
||||
legislation_proposal_votes(@process.proposals)
|
||||
render :proposals
|
||||
else
|
||||
render :phase_not_open
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def member_method?
|
||||
|
||||
72
app/controllers/legislation/proposals_controller.rb
Normal file
@@ -0,0 +1,72 @@
|
||||
class Legislation::ProposalsController < Legislation::BaseController
|
||||
include CommentableActions
|
||||
include FlagActions
|
||||
|
||||
load_and_authorize_resource :process, class: "Legislation::Process"
|
||||
load_and_authorize_resource :proposal, class: "Legislation::Proposal", through: :process
|
||||
|
||||
before_action :parse_tag_filter, only: :index
|
||||
before_action :load_categories, only: [:index, :new, :create, :edit, :map, :summary]
|
||||
before_action :load_geozones, only: [:edit, :map, :summary]
|
||||
before_action :authenticate_user!, except: [:index, :show, :map, :summary]
|
||||
|
||||
invisible_captcha only: [:create, :update], honeypot: :subtitle
|
||||
|
||||
has_orders %w{confidence_score created_at}, only: :index
|
||||
has_orders %w{most_voted newest oldest}, only: :show
|
||||
|
||||
helper_method :resource_model, :resource_name
|
||||
respond_to :html, :js
|
||||
|
||||
def show
|
||||
super
|
||||
legislation_proposal_votes(@process.proposals)
|
||||
@document = Document.new(documentable: @proposal)
|
||||
if request.path != legislation_process_proposal_path(params[:process_id], @proposal)
|
||||
redirect_to legislation_process_proposal_path(params[:process_id], @proposal),
|
||||
status: :moved_permanently
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@proposal = Legislation::Proposal.new(proposal_params.merge(author: current_user))
|
||||
|
||||
if @proposal.save
|
||||
redirect_to legislation_process_proposal_path(params[:process_id], @proposal), notice: I18n.t('flash.actions.create.proposal')
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def index_customization
|
||||
load_successful_proposals
|
||||
load_featured unless @proposal_successful_exists
|
||||
end
|
||||
|
||||
def vote
|
||||
@proposal.register_vote(current_user, params[:value])
|
||||
legislation_proposal_votes(@proposal)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def proposal_params
|
||||
params.require(:legislation_proposal).permit(:legislation_process_id, :title,
|
||||
:question, :summary, :description, :video_url, :tag_list,
|
||||
:terms_of_service, :geozone_id,
|
||||
documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id])
|
||||
end
|
||||
|
||||
def resource_model
|
||||
Legislation::Proposal
|
||||
end
|
||||
|
||||
def resource_name
|
||||
'proposal'
|
||||
end
|
||||
|
||||
def load_successful_proposals
|
||||
@proposal_successful_exists = Legislation::Proposal.successful.exists?
|
||||
end
|
||||
|
||||
end
|
||||
@@ -4,7 +4,7 @@ class Management::DocumentVerificationsController < Management::BaseController
|
||||
before_action :set_document, only: :check
|
||||
|
||||
def index
|
||||
@document_verification = Verification::Management::Document.new()
|
||||
@document_verification = Verification::Management::Document.new
|
||||
end
|
||||
|
||||
def check
|
||||
|
||||
@@ -11,7 +11,7 @@ class NotificationsController < ApplicationController
|
||||
|
||||
def show
|
||||
@notification = current_user.notifications.find(params[:id])
|
||||
redirect_to url_for(@notification.linkable_resource)
|
||||
redirect_to linkable_resource_path(@notification)
|
||||
end
|
||||
|
||||
def mark_all_as_read
|
||||
@@ -25,4 +25,15 @@ class NotificationsController < ApplicationController
|
||||
@notification.mark_as_read
|
||||
end
|
||||
|
||||
def linkable_resource_path(notification)
|
||||
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
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -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
|
||||
@@ -7,7 +7,9 @@ class Officing::PollsController < Officing::BaseController
|
||||
|
||||
def final
|
||||
@polls = if current_user.poll_officer?
|
||||
current_user.poll_officer.final_days_assigned_polls.select {|poll| poll.ends_at > 2.week.ago && poll.expired?}
|
||||
current_user.poll_officer.final_days_assigned_polls.select do |poll|
|
||||
poll.ends_at > 2.weeks.ago && poll.expired? || poll.ends_at.today?
|
||||
end
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@ class Officing::ResultsController < Officing::BaseController
|
||||
before_action :load_partial_results, only: :new
|
||||
|
||||
before_action :load_officer_assignment, only: :create
|
||||
before_action :check_booth_and_date, only: :create
|
||||
before_action :check_officer_assignment, only: :create
|
||||
before_action :build_results, only: :create
|
||||
|
||||
def new
|
||||
@@ -26,21 +26,15 @@ class Officing::ResultsController < Officing::BaseController
|
||||
@partial_results = ::Poll::PartialResult.includes(:question).
|
||||
where(booth_assignment_id: index_params[:booth_assignment_id]).
|
||||
where(date: index_params[:date])
|
||||
@whites = ::Poll::WhiteResult.where(booth_assignment_id: @booth_assignment.id, date: index_params[:date]).sum(:amount)
|
||||
@nulls = ::Poll::NullResult.where(booth_assignment_id: @booth_assignment.id, date: index_params[:date]).sum(:amount)
|
||||
@total = ::Poll::TotalResult.where(booth_assignment_id: @booth_assignment.id, date: index_params[:date]).sum(:amount)
|
||||
@recounts = ::Poll::Recount.where(booth_assignment_id: @booth_assignment.id, date: index_params[:date])
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def check_booth_and_date
|
||||
def check_officer_assignment
|
||||
if @officer_assignment.blank?
|
||||
go_back_to_new(t("officing.results.flash.error_wrong_booth"))
|
||||
elsif results_params[:date].blank? ||
|
||||
Date.parse(results_params[:date]) < @poll.starts_at.to_date ||
|
||||
Date.parse(results_params[:date]) > @poll.ends_at.to_date
|
||||
go_back_to_new(t("officing.results.flash.error_wrong_date"))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -52,66 +46,41 @@ class Officing::ResultsController < Officing::BaseController
|
||||
go_back_to_new if question.blank?
|
||||
|
||||
results.each_pair do |answer_index, count|
|
||||
if count.present?
|
||||
answer = question.valid_answers[answer_index.to_i]
|
||||
go_back_to_new if question.blank?
|
||||
next if count.blank?
|
||||
answer = question.question_answers.where(given_order: answer_index.to_i + 1).first.title
|
||||
go_back_to_new if question.blank?
|
||||
|
||||
partial_result = ::Poll::PartialResult.find_or_initialize_by(booth_assignment_id: @officer_assignment.booth_assignment_id,
|
||||
date: results_params[:date],
|
||||
question_id: question_id,
|
||||
answer: answer)
|
||||
partial_result.officer_assignment_id = @officer_assignment.id
|
||||
partial_result.amount = count.to_i
|
||||
partial_result.author = current_user
|
||||
partial_result.origin = 'booth'
|
||||
@results << partial_result
|
||||
end
|
||||
partial_result = ::Poll::PartialResult.find_or_initialize_by(booth_assignment_id: @officer_assignment.booth_assignment_id,
|
||||
date: Date.current,
|
||||
question_id: question_id,
|
||||
answer: answer)
|
||||
partial_result.officer_assignment_id = @officer_assignment.id
|
||||
partial_result.amount = count.to_i
|
||||
partial_result.author = current_user
|
||||
partial_result.origin = 'booth'
|
||||
@results << partial_result
|
||||
end
|
||||
end
|
||||
|
||||
build_white_results
|
||||
build_null_results
|
||||
build_total_results
|
||||
build_recounts
|
||||
end
|
||||
|
||||
def build_white_results
|
||||
if results_params[:whites].present?
|
||||
white_result = ::Poll::WhiteResult.find_or_initialize_by(booth_assignment_id: @officer_assignment.booth_assignment_id,
|
||||
date: results_params[:date])
|
||||
white_result.officer_assignment_id = @officer_assignment.id
|
||||
white_result.amount = results_params[:whites].to_i
|
||||
white_result.author = current_user
|
||||
white_result.origin = 'booth'
|
||||
@results << white_result
|
||||
end
|
||||
end
|
||||
|
||||
def build_null_results
|
||||
if results_params[:nulls].present?
|
||||
null_result = ::Poll::NullResult.find_or_initialize_by(booth_assignment_id: @officer_assignment.booth_assignment_id,
|
||||
date: results_params[:date])
|
||||
null_result.officer_assignment_id = @officer_assignment.id
|
||||
null_result.amount = results_params[:nulls].to_i
|
||||
null_result.author = current_user
|
||||
null_result.origin = 'booth'
|
||||
@results << null_result
|
||||
end
|
||||
end
|
||||
|
||||
def build_total_results
|
||||
if results_params[:total].present?
|
||||
total_result = ::Poll::TotalResult.find_or_initialize_by(booth_assignment_id: @officer_assignment.booth_assignment_id,
|
||||
date: results_params[:date])
|
||||
total_result.officer_assignment_id = @officer_assignment.id
|
||||
total_result.amount = results_params[:total].to_i
|
||||
total_result.author = current_user
|
||||
total_result.origin = 'booth'
|
||||
@results << total_result
|
||||
def build_recounts
|
||||
recount = ::Poll::Recount.find_or_initialize_by(booth_assignment_id: @officer_assignment.booth_assignment_id,
|
||||
date: Date.current)
|
||||
recount.officer_assignment_id = @officer_assignment.id
|
||||
recount.author = current_user
|
||||
recount.origin = 'booth'
|
||||
[:whites, :nulls, :total].each do |recount_type|
|
||||
if results_params[recount_type].present?
|
||||
recount["#{recount_type.to_s.singularize}_amount"] = results_params[recount_type].to_i
|
||||
end
|
||||
end
|
||||
@results << recount
|
||||
end
|
||||
|
||||
def go_back_to_new(alert = nil)
|
||||
params[:d] = results_params[:date]
|
||||
params[:d] = Date.current
|
||||
params[:oa] = results_params[:officer_assignment_id]
|
||||
flash.now[:alert] = (alert || t("officing.results.flash.error_create"))
|
||||
load_officer_assignments
|
||||
@@ -120,7 +89,7 @@ class Officing::ResultsController < Officing::BaseController
|
||||
end
|
||||
|
||||
def load_poll
|
||||
@poll = ::Poll.expired.includes(:questions).find(params[:poll_id])
|
||||
@poll = ::Poll.includes(:questions).find(params[:poll_id])
|
||||
end
|
||||
|
||||
def load_officer_assignment
|
||||
@@ -135,7 +104,7 @@ class Officing::ResultsController < Officing::BaseController
|
||||
final.
|
||||
where(id: current_user.poll_officer.officer_assignment_ids).
|
||||
where("poll_booth_assignments.poll_id = ?", @poll.id).
|
||||
order(date: :asc)
|
||||
where(date: Date.current)
|
||||
end
|
||||
|
||||
def load_partial_results
|
||||
@@ -146,7 +115,7 @@ class Officing::ResultsController < Officing::BaseController
|
||||
end
|
||||
|
||||
def results_params
|
||||
params.permit(:officer_assignment_id, :date, :questions, :whites, :nulls, :total)
|
||||
params.permit(:officer_assignment_id, :questions, :whites, :nulls, :total)
|
||||
end
|
||||
|
||||
def index_params
|
||||
|
||||
@@ -3,7 +3,8 @@ class Officing::VotersController < Officing::BaseController
|
||||
|
||||
def new
|
||||
@user = User.find(params[:id])
|
||||
@polls = Poll.answerable_by(@user)
|
||||
booths = current_user.poll_officer.shifts.current.vote_collection.pluck(:booth_id).uniq
|
||||
@polls = Poll.answerable_by(@user).where(id: Poll::BoothAssignment.where(booth: booths).pluck(:poll_id).uniq)
|
||||
end
|
||||
|
||||
def create
|
||||
@@ -12,7 +13,9 @@ class Officing::VotersController < Officing::BaseController
|
||||
@voter = Poll::Voter.new(document_type: @user.document_type,
|
||||
document_number: @user.document_number,
|
||||
user: @user,
|
||||
poll: @poll)
|
||||
poll: @poll,
|
||||
origin: "booth",
|
||||
officer: current_user.poll_officer)
|
||||
@voter.save!
|
||||
end
|
||||
|
||||
|
||||
@@ -5,25 +5,19 @@ class Polls::QuestionsController < ApplicationController
|
||||
|
||||
has_orders %w{most_voted newest oldest}, only: :show
|
||||
|
||||
def show
|
||||
@commentable = @question.proposal.present? ? @question.proposal : @question
|
||||
@comment_tree = CommentTree.new(@commentable, params[:page], @current_order)
|
||||
set_comment_flags(@comment_tree.comments)
|
||||
|
||||
@document = Document.new(documentable: @question)
|
||||
|
||||
question_answer = @question.answers.where(author_id: current_user.try(:id)).first
|
||||
@answers_by_question_id = {@question.id => question_answer.try(:answer)}
|
||||
end
|
||||
|
||||
def answer
|
||||
answer = @question.answers.find_or_initialize_by(author: current_user)
|
||||
token = params[:token]
|
||||
|
||||
answer.answer = params[:answer]
|
||||
answer.touch if answer.persisted?
|
||||
answer.save!
|
||||
answer.record_voter_participation
|
||||
answer.record_voter_participation(token)
|
||||
@question.question_answers.where(question_id: @question).each do |question_answer|
|
||||
question_answer.set_most_voted
|
||||
end
|
||||
|
||||
@answers_by_question_id = {@question.id => params[:answer]}
|
||||
@answers_by_question_id = { @question.id => params[:answer] }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
class PollsController < ApplicationController
|
||||
include PollsHelper
|
||||
|
||||
load_and_authorize_resource
|
||||
|
||||
has_filters %w{current expired incoming}
|
||||
has_orders %w{most_voted newest oldest}, only: :show
|
||||
|
||||
::Poll::Answer # trigger autoload
|
||||
|
||||
@@ -12,12 +14,24 @@ 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).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))
|
||||
poll_answers.each do |answer|
|
||||
@answers_by_question_id[answer.question_id] = answer.answer
|
||||
end
|
||||
|
||||
@commentable = @poll
|
||||
@comment_tree = CommentTree.new(@commentable, params[:page], @current_order)
|
||||
end
|
||||
|
||||
def stats
|
||||
@stats = Poll::Stats.new(@poll).generate
|
||||
end
|
||||
|
||||
def results
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -9,7 +9,7 @@ class ProposalsController < ApplicationController
|
||||
|
||||
invisible_captcha only: [:create, :update], honeypot: :subtitle
|
||||
|
||||
has_orders %w{hot_score confidence_score created_at relevance archival_date}, only: :index
|
||||
has_orders ->(c) { Proposal.proposals_orders(c.current_user) }, only: :index
|
||||
has_orders %w{most_voted newest oldest}, only: :show
|
||||
|
||||
load_and_authorize_resource
|
||||
@@ -19,13 +19,11 @@ class ProposalsController < ApplicationController
|
||||
def show
|
||||
super
|
||||
@notifications = @proposal.notifications
|
||||
@document = Document.new(documentable: @proposal)
|
||||
redirect_to proposal_path(@proposal), status: :moved_permanently if request.path != proposal_path(@proposal)
|
||||
end
|
||||
|
||||
def create
|
||||
@proposal = Proposal.new(proposal_params.merge(author: current_user))
|
||||
recover_documents_from_cache(@proposal)
|
||||
|
||||
if @proposal.save
|
||||
redirect_to share_proposal_path(@proposal), notice: I18n.t('flash.actions.create.proposal')
|
||||
@@ -78,7 +76,9 @@ class ProposalsController < ApplicationController
|
||||
def proposal_params
|
||||
params.require(:proposal).permit(:title, :question, :summary, :description, :external_url, :video_url,
|
||||
:responsible_name, :tag_list, :terms_of_service, :geozone_id,
|
||||
documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id])
|
||||
image_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy],
|
||||
documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy],
|
||||
map_location_attributes: [:latitude, :longitude, :zoom])
|
||||
end
|
||||
|
||||
def retired_params
|
||||
@@ -113,7 +113,7 @@ class ProposalsController < ApplicationController
|
||||
end
|
||||
|
||||
def load_featured
|
||||
return unless !@advanced_search_terms && @search_terms.blank? && @tag_filter.blank? && params[:retired].blank?
|
||||
return unless !@advanced_search_terms && @search_terms.blank? && @tag_filter.blank? && params[:retired].blank? && @current_order != "recommendations"
|
||||
@featured_proposals = Proposal.not_archived.sort_by_confidence_score.limit(3)
|
||||
if @featured_proposals.present?
|
||||
set_featured_proposal_votes(@featured_proposals)
|
||||
|
||||
11
app/controllers/tags_controller.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class TagsController < ApplicationController
|
||||
|
||||
load_and_authorize_resource class: ActsAsTaggableOn::Tag
|
||||
respond_to :json
|
||||
|
||||
def suggest
|
||||
@tags = ActsAsTaggableOn::Tag.search(params[:search]).map(&:name)
|
||||
respond_with @tags
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,12 +1,10 @@
|
||||
class WelcomeController < ApplicationController
|
||||
skip_authorization_check
|
||||
before_action :set_user_recommendations, only: :index, if: :current_user
|
||||
|
||||
layout "devise", only: [:welcome, :verification]
|
||||
|
||||
def index
|
||||
if current_user
|
||||
redirect_to :proposals
|
||||
end
|
||||
end
|
||||
|
||||
def welcome
|
||||
@@ -16,4 +14,11 @@ class WelcomeController < ApplicationController
|
||||
redirect_to verification_path if signed_in?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_user_recommendations
|
||||
@recommended_debates = Debate.recommendations(current_user).sort_by_recommendations.limit(3)
|
||||
@recommended_proposals = Proposal.recommendations(current_user).sort_by_recommendations.limit(3)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -13,33 +13,33 @@ module AdminHelper
|
||||
end
|
||||
|
||||
def menu_tags?
|
||||
["tags"].include? controller_name
|
||||
["tags"].include?(controller_name)
|
||||
end
|
||||
|
||||
def menu_moderated_content?
|
||||
["proposals", "debates", "comments", "hidden_users"].include? controller_name
|
||||
["proposals", "debates", "comments", "hidden_users"].include?(controller_name) && controller.class.parent != Admin::Legislation
|
||||
end
|
||||
|
||||
def menu_budget?
|
||||
["spending_proposals"].include? controller_name
|
||||
["spending_proposals"].include?(controller_name)
|
||||
end
|
||||
|
||||
def menu_polls?
|
||||
["polls", "questions", "officers", "booths", "officer_assignments", "booth_assignments", "recounts", "results", "shifts"].include? controller_name
|
||||
%w[polls questions officers booths officer_assignments booth_assignments recounts results shifts questions answers].include?(controller_name)
|
||||
end
|
||||
|
||||
def menu_profiles?
|
||||
["administrators", "organizations", "officials", "moderators", "valuators", "managers", "users"].include? controller_name
|
||||
%w[administrators organizations officials moderators valuators managers users activity].include?(controller_name)
|
||||
end
|
||||
|
||||
def menu_banners?
|
||||
["banners"].include? controller_name
|
||||
["banners"].include?(controller_name)
|
||||
end
|
||||
|
||||
def menu_customization?
|
||||
["pages", "images", "content_blocks"].include? controller_name
|
||||
["pages", "images", "content_blocks"].include?(controller_name)
|
||||
end
|
||||
|
||||
|
||||
def official_level_options
|
||||
options = [["", 0]]
|
||||
(1..5).each do |i|
|
||||
|
||||
@@ -60,4 +60,8 @@ module ApplicationHelper
|
||||
def format_price(number)
|
||||
number_to_currency(number, precision: 0, locale: I18n.default_locale)
|
||||
end
|
||||
|
||||
def kaminari_path(url)
|
||||
"#{root_url.chomp("\/")}#{url}"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,4 +4,12 @@ module DebatesHelper
|
||||
Debate.all.featured.count > 0
|
||||
end
|
||||
|
||||
end
|
||||
def empty_recommended_debates_message_text(user)
|
||||
if user.interests.any?
|
||||
t('debates.index.recommendations.without_results')
|
||||
else
|
||||
t('debates.index.recommendations.without_interests')
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
16
app/helpers/direct_uploads_helper.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
module DirectUploadsHelper
|
||||
|
||||
def render_destroy_upload_link(direct_upload)
|
||||
label = direct_upload.resource_relation == "image" ? "images" : "documents"
|
||||
link_to t("#{label}.form.delete_button"),
|
||||
direct_upload_destroy_url("direct_upload[resource_type]": direct_upload.resource_type,
|
||||
"direct_upload[resource_id]": direct_upload.resource_id,
|
||||
"direct_upload[resource_relation]": direct_upload.resource_relation,
|
||||
"direct_upload[cached_attachment]": direct_upload.relation.cached_attachment,
|
||||
format: :json),
|
||||
method: :delete,
|
||||
remote: true,
|
||||
class: "delete remove-cached-attachment"
|
||||
end
|
||||
|
||||
end
|
||||
@@ -8,12 +8,12 @@ module DocumentablesHelper
|
||||
documentable.class.max_documents_allowed
|
||||
end
|
||||
|
||||
def max_file_size(documentable)
|
||||
bytes_to_mega(documentable.class.max_file_size)
|
||||
def max_file_size(documentable_class)
|
||||
bytes_to_mega(documentable_class.max_file_size)
|
||||
end
|
||||
|
||||
def accepted_content_types(documentable)
|
||||
documentable.class.accepted_content_types
|
||||
def accepted_content_types(documentable_class)
|
||||
documentable_class.accepted_content_types
|
||||
end
|
||||
|
||||
def accepted_content_types_extensions(documentable_class)
|
||||
@@ -22,20 +22,19 @@ module DocumentablesHelper
|
||||
.join(",")
|
||||
end
|
||||
|
||||
def humanized_accepted_content_types(documentable)
|
||||
documentable.class.accepted_content_types
|
||||
.collect{ |content_type| content_type.split("/").last }
|
||||
.join(", ")
|
||||
def documentable_humanized_accepted_content_types(documentable_class)
|
||||
documentable_class.accepted_content_types
|
||||
.collect{ |content_type| content_type.split("/").last }
|
||||
.join(", ")
|
||||
end
|
||||
|
||||
def documentables_note(documentable)
|
||||
t "documents.form.note", max_documents_allowed: max_documents_allowed(documentable),
|
||||
accepted_content_types: humanized_accepted_content_types(documentable),
|
||||
max_file_size: max_file_size(documentable)
|
||||
accepted_content_types: documentable_humanized_accepted_content_types(documentable.class),
|
||||
max_file_size: max_file_size(documentable.class)
|
||||
end
|
||||
|
||||
def max_documents_allowed?(documentable)
|
||||
documentable.documents.count >= documentable.class.max_documents_allowed
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -4,7 +4,7 @@ module DocumentsHelper
|
||||
document.attachment_file_name
|
||||
end
|
||||
|
||||
def errors_on_attachment(document)
|
||||
def document_errors_on_attachment(document)
|
||||
document.errors[:attachment].join(', ') if document.errors.key?(:attachment)
|
||||
end
|
||||
|
||||
@@ -12,78 +12,53 @@ module DocumentsHelper
|
||||
bytes / Numeric::MEGABYTE
|
||||
end
|
||||
|
||||
def document_nested_field_name(document, index, field)
|
||||
parent = document.documentable_type.parameterize.underscore
|
||||
"#{parent.parameterize}[documents_attributes][#{index}][#{field}]"
|
||||
end
|
||||
|
||||
def document_nested_field_id(document, index, field)
|
||||
parent = document.documentable_type.parameterize.underscore
|
||||
"#{parent.parameterize}_documents_attributes_#{index}_#{field}"
|
||||
end
|
||||
|
||||
def document_nested_field_wrapper_id(index)
|
||||
"document_#{index}"
|
||||
end
|
||||
|
||||
def render_destroy_document_link(document, index)
|
||||
if document.persisted?
|
||||
def render_destroy_document_link(builder, document)
|
||||
if !document.persisted? && document.cached_attachment.present?
|
||||
link_to t('documents.form.delete_button'),
|
||||
document_path(document, index: index, nested_document: true),
|
||||
method: :delete,
|
||||
remote: true,
|
||||
data: { confirm: t('documents.actions.destroy.confirm') },
|
||||
class: "delete float-right"
|
||||
elsif !document.persisted? && document.cached_attachment.present?
|
||||
link_to t('documents.form.delete_button'),
|
||||
destroy_upload_documents_path(path: document.cached_attachment,
|
||||
nested_document: true,
|
||||
index: index,
|
||||
documentable_type: document.documentable_type,
|
||||
documentable_id: document.documentable_id),
|
||||
method: :delete,
|
||||
remote: true,
|
||||
class: "delete float-right"
|
||||
direct_upload_destroy_url("direct_upload[resource_type]": document.documentable_type,
|
||||
"direct_upload[resource_id]": document.documentable_id,
|
||||
"direct_upload[resource_relation]": "documents",
|
||||
"direct_upload[cached_attachment]": document.cached_attachment),
|
||||
method: :delete,
|
||||
remote: true,
|
||||
class: "delete remove-cached-attachment"
|
||||
else
|
||||
link_to t('documents.form.delete_button'),
|
||||
"#",
|
||||
class: "delete float-right remove-document"
|
||||
link_to_remove_association t('documents.form.delete_button'), builder, class: "delete remove-document"
|
||||
end
|
||||
end
|
||||
|
||||
def render_attachment(document, index)
|
||||
html = file_field_tag :attachment,
|
||||
accept: accepted_content_types_extensions(document.documentable_type.constantize),
|
||||
class: 'js-document-attachment',
|
||||
data: {
|
||||
url: document_direct_upload_url(document),
|
||||
cached_attachment_input_field: document_nested_field_id(document, index, :cached_attachment),
|
||||
multiple: false,
|
||||
index: index,
|
||||
nested_document: true
|
||||
},
|
||||
name: document_nested_field_name(document, index, :attachment),
|
||||
id: document_nested_field_id(document, index, :attachment)
|
||||
if document.attachment.blank? && document.cached_attachment.blank?
|
||||
klass = document.errors[:attachment].any? ? "error" : ""
|
||||
html += label_tag document_nested_field_id(document, index, :attachment),
|
||||
t("documents.form.attachment_label"),
|
||||
class: "button hollow #{klass}"
|
||||
if document.errors[:attachment].any?
|
||||
html += content_tag :small, class: "error" do
|
||||
errors_on_attachment(document)
|
||||
end
|
||||
end
|
||||
end
|
||||
def render_attachment(builder, document)
|
||||
klass = document.errors[:attachment].any? ? "error" : ""
|
||||
klass = document.persisted? || document.cached_attachment.present? ? " hide" : ""
|
||||
html = builder.label :attachment,
|
||||
t("documents.form.attachment_label"),
|
||||
class: "button hollow #{klass}"
|
||||
html += builder.file_field :attachment,
|
||||
label: false,
|
||||
accept: accepted_content_types_extensions(document.documentable_type.constantize),
|
||||
class: 'js-document-attachment',
|
||||
data: {
|
||||
url: document_direct_upload_url(document),
|
||||
nested_document: true
|
||||
}
|
||||
html
|
||||
end
|
||||
|
||||
def document_direct_upload_url(document)
|
||||
upload_documents_url(
|
||||
documentable_type: document.documentable_type,
|
||||
documentable_id: document.documentable_id,
|
||||
format: :js
|
||||
)
|
||||
direct_uploads_url("direct_upload[resource_type]": document.documentable_type,
|
||||
"direct_upload[resource_id]": document.documentable_id,
|
||||
"direct_upload[resource_relation]": "documents")
|
||||
end
|
||||
|
||||
def document_item_link(document)
|
||||
link_to "#{document.title} <small>(#{document.humanized_content_type} | \
|
||||
#{number_to_human_size(document.attachment_file_size)}</small>)".html_safe,
|
||||
document.attachment.url,
|
||||
target: "_blank",
|
||||
title: t("shared.target_blank_html")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -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
|
||||
|
||||
40
app/helpers/imageables_helper.rb
Normal file
@@ -0,0 +1,40 @@
|
||||
module ImageablesHelper
|
||||
|
||||
def can_destroy_image?(imageable)
|
||||
imageable.image.present? && can?(:destroy, imageable.image)
|
||||
end
|
||||
|
||||
def imageable_class(imageable)
|
||||
imageable.class.name.parameterize('_')
|
||||
end
|
||||
|
||||
def imageable_max_file_size
|
||||
bytes_to_megabytes(Image::MAX_IMAGE_SIZE)
|
||||
end
|
||||
|
||||
def bytes_to_megabytes(bytes)
|
||||
bytes / Numeric::MEGABYTE
|
||||
end
|
||||
|
||||
def imageable_accepted_content_types
|
||||
Image::ACCEPTED_CONTENT_TYPE
|
||||
end
|
||||
|
||||
def imageable_accepted_content_types_extensions
|
||||
Image::ACCEPTED_CONTENT_TYPE
|
||||
.collect{ |content_type| ".#{content_type.split('/').last}" }
|
||||
.join(",")
|
||||
end
|
||||
|
||||
def imageable_humanized_accepted_content_types
|
||||
Image::ACCEPTED_CONTENT_TYPE
|
||||
.collect{ |content_type| content_type.split("/").last }
|
||||
.join(", ")
|
||||
end
|
||||
|
||||
def imageables_note(_imageable)
|
||||
t "images.form.note", accepted_content_types: imageable_humanized_accepted_content_types,
|
||||
max_file_size: imageable_max_file_size
|
||||
end
|
||||
|
||||
end
|
||||
79
app/helpers/images_helper.rb
Normal file
@@ -0,0 +1,79 @@
|
||||
module ImagesHelper
|
||||
|
||||
def image_absolute_url(image, version)
|
||||
return "" unless image
|
||||
if Paperclip::Attachment.default_options[:storage] == :filesystem
|
||||
URI(request.url) + image.attachment.url(version)
|
||||
else
|
||||
investment.image_url(version)
|
||||
end
|
||||
end
|
||||
|
||||
def image_first_recommendation(image)
|
||||
t "images.#{image.imageable.class.name.parameterize.underscore}.recommendation_one_html",
|
||||
title: image.imageable.title
|
||||
end
|
||||
|
||||
def image_attachment_file_name(image)
|
||||
image.attachment_file_name
|
||||
end
|
||||
|
||||
def image_errors_on_attachment(image)
|
||||
image.errors[:attachment].join(', ') if image.errors.key?(:attachment)
|
||||
end
|
||||
|
||||
def image_bytes_to_megabytes(bytes)
|
||||
bytes / Numeric::MEGABYTE
|
||||
end
|
||||
|
||||
def image_class(image)
|
||||
image.persisted? ? "persisted-image" : "cached-image"
|
||||
end
|
||||
|
||||
def render_destroy_image_link(builder, image)
|
||||
if !image.persisted? && image.cached_attachment.present?
|
||||
link_to t('images.form.delete_button'),
|
||||
direct_upload_destroy_url("direct_upload[resource_type]": image.imageable_type,
|
||||
"direct_upload[resource_id]": image.imageable_id,
|
||||
"direct_upload[resource_relation]": "image",
|
||||
"direct_upload[cached_attachment]": image.cached_attachment),
|
||||
method: :delete,
|
||||
remote: true,
|
||||
class: "delete remove-cached-attachment"
|
||||
else
|
||||
link_to_remove_association t('images.form.delete_button'), builder, class: "delete remove-image"
|
||||
end
|
||||
end
|
||||
|
||||
def render_image_attachment(builder, imageable, image)
|
||||
klass = image.errors[:attachment].any? ? "error" : ""
|
||||
klass = image.persisted? || image.cached_attachment.present? ? " hide" : ""
|
||||
html = builder.label :attachment,
|
||||
t("images.form.attachment_label"),
|
||||
class: "button hollow #{klass}"
|
||||
html += builder.file_field :attachment,
|
||||
label: false,
|
||||
accept: imageable_accepted_content_types_extensions,
|
||||
class: 'js-image-attachment',
|
||||
data: {
|
||||
url: image_direct_upload_url(imageable),
|
||||
nested_image: true
|
||||
}
|
||||
|
||||
html
|
||||
end
|
||||
|
||||
def render_image(image, version, show_caption = true)
|
||||
version = image.persisted? ? version : :original
|
||||
render partial: "images/image", locals: { image: image,
|
||||
version: version,
|
||||
show_caption: show_caption }
|
||||
end
|
||||
|
||||
def image_direct_upload_url(imageable)
|
||||
direct_uploads_url("direct_upload[resource_type]": imageable.class.name,
|
||||
"direct_upload[resource_id]": imageable.id,
|
||||
"direct_upload[resource_relation]": "image")
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
module LegislationHelper
|
||||
def format_date(date)
|
||||
l(date, format: "%d %b %Y") if date
|
||||
l(date, format: "%d %h %Y") if date
|
||||
end
|
||||
|
||||
def format_date_for_calendar_form(date)
|
||||
|
||||
67
app/helpers/map_locations_helper.rb
Normal file
@@ -0,0 +1,67 @@
|
||||
module MapLocationsHelper
|
||||
|
||||
def map_location_available?(map_location)
|
||||
map_location.present? && map_location.available?
|
||||
end
|
||||
|
||||
def map_location_latitude(map_location)
|
||||
map_location.present? && map_location.latitude.present? ? map_location.latitude : Setting["map_latitude"]
|
||||
end
|
||||
|
||||
def map_location_longitude(map_location)
|
||||
map_location.present? && map_location.longitude.present? ? map_location.longitude : Setting["map_longitude"]
|
||||
end
|
||||
|
||||
def map_location_zoom(map_location)
|
||||
map_location.present? && map_location.zoom.present? ? map_location.zoom : Setting["map_zoom"]
|
||||
end
|
||||
|
||||
def map_location_input_id(prefix, attribute)
|
||||
"#{prefix}_map_location_attributes_#{attribute}"
|
||||
end
|
||||
|
||||
def map_location_remove_marker_link_id(map_location)
|
||||
"remove-marker-link-#{dom_id(map_location)}"
|
||||
end
|
||||
|
||||
def render_map(map_location, parent_class, editable, remove_marker_label)
|
||||
map = content_tag_for :div,
|
||||
map_location,
|
||||
class: "map",
|
||||
data: prepare_map_settings(map_location, editable, parent_class)
|
||||
map += map_location_remove_marker(map_location, remove_marker_label) if editable
|
||||
map
|
||||
end
|
||||
|
||||
def map_location_remove_marker(map_location, text)
|
||||
content_tag :div, class: "text-right" do
|
||||
content_tag :a,
|
||||
id: map_location_remove_marker_link_id(map_location),
|
||||
href: "#",
|
||||
class: "location-map-remove-marker-button delete" do
|
||||
text
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def prepare_map_settings(map_location, editable, parent_class)
|
||||
options = {
|
||||
map: "",
|
||||
map_center_latitude: map_location_latitude(map_location),
|
||||
map_center_longitude: map_location_longitude(map_location),
|
||||
map_zoom: map_location_zoom(map_location),
|
||||
map_tiles_provider: Rails.application.secrets.map_tiles_provider,
|
||||
map_tiles_provider_attribution: Rails.application.secrets.map_tiles_provider_attribution,
|
||||
marker_editable: editable,
|
||||
marker_latitude: map_location.latitude,
|
||||
marker_longitude: map_location.longitude,
|
||||
marker_remove_selector: "##{map_location_remove_marker_link_id(map_location)}",
|
||||
latitude_input_selector: "##{map_location_input_id(parent_class, 'latitude')}",
|
||||
longitude_input_selector: "##{map_location_input_id(parent_class, 'longitude')}",
|
||||
zoom_input_selector: "##{map_location_input_id(parent_class, 'zoom')}"
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,7 +1,7 @@
|
||||
module PollRecountsHelper
|
||||
|
||||
def total_recounts_by_booth(booth_assignment)
|
||||
booth_assignment.total_results.any? ? booth_assignment.total_results.to_a.sum(&:amount) : nil
|
||||
booth_assignment.recounts.any? ? booth_assignment.recounts.to_a.sum(&:total_amount) : nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -41,4 +41,12 @@ module PollsHelper
|
||||
booth.name + location
|
||||
end
|
||||
|
||||
def poll_voter_token(poll, user)
|
||||
Poll::Voter.where(poll: poll, user: user, origin: "web").first&.token || ''
|
||||
end
|
||||
|
||||
def voted_before_sign_in(question)
|
||||
question.answers.where(author: current_user).any? { |vote| current_user.current_sign_in_at >= vote.updated_at }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -12,8 +12,8 @@ module ProposalsHelper
|
||||
percentage = (proposal.total_votes.to_f * 100 / Proposal.votes_needed_for_success)
|
||||
case percentage
|
||||
when 0 then "0%"
|
||||
when 0..(0.1) then "0.1%"
|
||||
when (0.1)..100 then number_to_percentage(percentage, strip_insignificant_zeros: true, precision: 1)
|
||||
when 0..0.1 then "0.1%"
|
||||
when 0.1..100 then number_to_percentage(percentage, strip_insignificant_zeros: true, precision: 1)
|
||||
else "100%"
|
||||
end
|
||||
end
|
||||
@@ -32,8 +32,12 @@ module ProposalsHelper
|
||||
Proposal::RETIRE_OPTIONS.collect { |option| [ t("proposals.retire_options.#{option}"), option ] }
|
||||
end
|
||||
|
||||
def can_create_document?(document, proposal)
|
||||
can?(:create, document) && proposal.documents.size < Proposal.max_documents_allowed
|
||||
def empty_recommended_proposals_message_text(user)
|
||||
if user.interests.any?
|
||||
t('proposals.index.recommendations.without_results')
|
||||
else
|
||||
t('proposals.index.recommendations.without_interests')
|
||||
end
|
||||
end
|
||||
|
||||
def author_of_proposal?(proposal)
|
||||
@@ -44,4 +48,4 @@ module ProposalsHelper
|
||||
current_user && proposal.editable_by?(current_user)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,15 +1,30 @@
|
||||
module ShiftsHelper
|
||||
|
||||
def shift_dates_select_options(polls)
|
||||
options = []
|
||||
(start_date(polls)..end_date(polls)).each do |date|
|
||||
options << [l(date, format: :long), l(date)]
|
||||
def shift_vote_collection_dates(booth, polls)
|
||||
return [] if polls.blank?
|
||||
date_options((start_date(polls)..end_date(polls)), Poll::Shift.tasks[:vote_collection], booth)
|
||||
end
|
||||
|
||||
def shift_recount_scrutiny_dates(booth, polls)
|
||||
return [] if polls.blank?
|
||||
dates = polls.map(&:ends_at).map(&:to_date).sort.inject([]) do |total, date|
|
||||
initial_date = date < Date.current ? Date.current : date
|
||||
total << (initial_date..date + Poll::RECOUNT_DURATION).to_a
|
||||
end
|
||||
options_for_select(options, params[:date])
|
||||
date_options(dates.flatten.uniq, Poll::Shift.tasks[:recount_scrutiny], booth)
|
||||
end
|
||||
|
||||
def date_options(dates, task_id, booth)
|
||||
valid_dates(dates, task_id, booth).map { |date| [l(date, format: :long), l(date)] }
|
||||
end
|
||||
|
||||
def valid_dates(dates, task_id, booth)
|
||||
dates.reject { |date| officer_shifts(task_id, booth).include?(date) }
|
||||
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)
|
||||
@@ -20,4 +35,9 @@ module ShiftsHelper
|
||||
officers.collect { |officer| [officer.name, officer.id] }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def officer_shifts(task_id, booth)
|
||||
@officer.shifts.where(task: task_id, booth: booth).map(&:date)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,6 +8,8 @@ module TagsHelper
|
||||
proposals_path(search: tag_name)
|
||||
when 'budget/investment'
|
||||
budget_investments_path(@budget, search: tag_name)
|
||||
when 'legislation/proposal'
|
||||
legislation_process_proposals_path(@process, search: tag_name)
|
||||
else
|
||||
'#'
|
||||
end
|
||||
@@ -22,6 +24,8 @@ module TagsHelper
|
||||
proposal_path(taggable)
|
||||
when 'budget/investment'
|
||||
budget_investment_path(taggable.budget_id, taggable)
|
||||
when 'legislation/proposal'
|
||||
legislation_process_proposal_path(@process, taggable)
|
||||
else
|
||||
'#'
|
||||
end
|
||||
|
||||
@@ -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)
|
||||
|
||||
58
app/helpers/welcome_helper.rb
Normal file
@@ -0,0 +1,58 @@
|
||||
module WelcomeHelper
|
||||
|
||||
def active_class(index)
|
||||
"is-active is-in" if index.zero?
|
||||
end
|
||||
|
||||
def slide_display(index)
|
||||
"display: none;" if index.positive?
|
||||
end
|
||||
|
||||
def recommended_path(recommended)
|
||||
case recommended.class.name
|
||||
when "Debate"
|
||||
debate_path(recommended)
|
||||
when "Proposal"
|
||||
proposal_path(recommended)
|
||||
else
|
||||
'#'
|
||||
end
|
||||
end
|
||||
|
||||
def render_recommendation_image(recommended, image_default)
|
||||
image_path = calculate_image_path(recommended, image_default)
|
||||
image_tag(image_path) if image_path.present?
|
||||
end
|
||||
|
||||
def calculate_image_path(recommended, image_default)
|
||||
if recommended.try(:image) && recommended.image.present? && recommended.image.attachment.exists?
|
||||
recommended.image.attachment.send("url", :medium)
|
||||
elsif image_default.present?
|
||||
image_default
|
||||
end
|
||||
end
|
||||
|
||||
def calculate_carousel_size(debates, proposals, apply_offset)
|
||||
offset = calculate_offset(debates, proposals, apply_offset)
|
||||
centered = calculate_centered(debates, proposals)
|
||||
"#{offset if offset} #{centered if centered}"
|
||||
end
|
||||
|
||||
def calculate_centered(debates, proposals)
|
||||
if (debates.blank? && proposals.any?) ||
|
||||
(debates.any? && proposals.blank?)
|
||||
centered = "medium-centered large-centered"
|
||||
end
|
||||
end
|
||||
|
||||
def calculate_offset(debates, proposals, apply_offset)
|
||||
if debates.any? && proposals.any?
|
||||
offset = if apply_offset
|
||||
"medium-offset-2 large-offset-2"
|
||||
else
|
||||
"end"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -14,6 +14,9 @@ module Abilities
|
||||
can :restore, Proposal
|
||||
cannot :restore, Proposal, hidden_at: nil
|
||||
|
||||
can :restore, Legislation::Proposal
|
||||
cannot :restore, Legislation::Proposal, hidden_at: nil
|
||||
|
||||
can :restore, User
|
||||
cannot :restore, User, hidden_at: nil
|
||||
|
||||
@@ -26,6 +29,9 @@ module Abilities
|
||||
can :confirm_hide, Proposal
|
||||
cannot :confirm_hide, Proposal, hidden_at: nil
|
||||
|
||||
can :confirm_hide, Legislation::Proposal
|
||||
cannot :confirm_hide, Legislation::Proposal, hidden_at: nil
|
||||
|
||||
can :confirm_hide, User
|
||||
cannot :confirm_hide, User, hidden_at: nil
|
||||
|
||||
@@ -33,11 +39,11 @@ module Abilities
|
||||
can :unmark_featured, Debate
|
||||
|
||||
can :comment_as_administrator, [Debate, Comment, Proposal, Poll::Question, Budget::Investment,
|
||||
Legislation::Question, Legislation::Annotation, Topic]
|
||||
Legislation::Question, Legislation::Proposal, Legislation::Annotation, Topic]
|
||||
|
||||
can [:search, :create, :index, :destroy], ::Administrator
|
||||
can [:search, :create, :index, :destroy], ::Moderator
|
||||
can [:search, :create, :index, :summary], ::Valuator
|
||||
can [:search, :create, :index, :destroy, :summary], ::Valuator
|
||||
can [:search, :create, :index, :destroy], ::Manager
|
||||
can [:search, :index], ::User
|
||||
|
||||
@@ -45,7 +51,7 @@ module Abilities
|
||||
|
||||
can [:read, :update, :valuate, :destroy, :summary], SpendingProposal
|
||||
|
||||
can [:index, :read, :new, :create, :update, :destroy, :calculate_winners], Budget
|
||||
can [:index, :read, :new, :create, :update, :destroy, :calculate_winners, :read_results], Budget
|
||||
can [:read, :create, :update, :destroy], Budget::Group
|
||||
can [:read, :create, :update, :destroy], Budget::Heading
|
||||
can [:hide, :update, :toggle_selection], Budget::Investment
|
||||
@@ -56,10 +62,10 @@ module Abilities
|
||||
|
||||
can [:index, :create, :edit, :update, :destroy], Geozone
|
||||
|
||||
can [:read, :create, :update, :destroy, :add_question, :remove_question, :search_booths, :search_questions, :search_officers], 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], ::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
|
||||
@@ -71,9 +77,12 @@ module Abilities
|
||||
can [:manage], ::Legislation::Process
|
||||
can [:manage], ::Legislation::DraftVersion
|
||||
can [:manage], ::Legislation::Question
|
||||
cannot :comment_as_moderator, [::Legislation::Question, Legislation::Annotation]
|
||||
can [:manage], ::Legislation::Proposal
|
||||
cannot :comment_as_moderator, [::Legislation::Question, Legislation::Annotation, ::Legislation::Proposal]
|
||||
|
||||
can [:create, :destroy], Document
|
||||
can [:destroy], Image
|
||||
can [:create, :destroy], DirectUpload
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -18,12 +18,21 @@ module Abilities
|
||||
end
|
||||
can [:retire_form, :retire], Proposal, author_id: user.id
|
||||
|
||||
can :read, Legislation::Proposal
|
||||
cannot [:edit, :update], Legislation::Proposal do |proposal|
|
||||
proposal.editable_by?(user)
|
||||
end
|
||||
can [:retire_form, :retire], Legislation::Proposal, author_id: user.id
|
||||
|
||||
can :create, Comment
|
||||
can :create, Debate
|
||||
can :create, Proposal
|
||||
can :create, Legislation::Proposal
|
||||
|
||||
can :suggest, Debate
|
||||
can :suggest, Proposal
|
||||
can :suggest, Legislation::Proposal
|
||||
can :suggest, ActsAsTaggableOn::Tag
|
||||
|
||||
can [:flag, :unflag], Comment
|
||||
cannot [:flag, :unflag], Comment, user_id: user.id
|
||||
@@ -34,10 +43,16 @@ module Abilities
|
||||
can [:flag, :unflag], Proposal
|
||||
cannot [:flag, :unflag], Proposal, author_id: user.id
|
||||
|
||||
can [:flag, :unflag], Legislation::Proposal
|
||||
cannot [:flag, :unflag], Legislation::Proposal, author_id: user.id
|
||||
|
||||
can [:create, :destroy], Follow
|
||||
|
||||
can [:create, :destroy, :new], Document, documentable: { author_id: user.id }
|
||||
can [:new_nested, :upload, :destroy_upload], Document
|
||||
can [:destroy], Document, documentable: { author_id: user.id }
|
||||
|
||||
can [:destroy], Image, imageable: { author_id: user.id }
|
||||
|
||||
can [:create, :destroy], DirectUpload
|
||||
|
||||
unless user.organization?
|
||||
can :vote, Debate
|
||||
@@ -50,10 +65,15 @@ module Abilities
|
||||
can :vote, SpendingProposal
|
||||
can :create, SpendingProposal
|
||||
|
||||
can :vote, Legislation::Proposal
|
||||
can :vote_featured, Legislation::Proposal
|
||||
can :create, Legislation::Answer
|
||||
|
||||
can :create, Budget::Investment, budget: { phase: "accepting" }
|
||||
can :suggest, Budget::Investment, budget: { phase: "accepting" }
|
||||
can :destroy, Budget::Investment, budget: { phase: ["accepting", "reviewing"] }, author_id: user.id
|
||||
can :vote, Budget::Investment, budget: { phase: "selecting" }
|
||||
|
||||
can [:show, :create], Budget::Ballot, budget: { phase: "balloting" }
|
||||
can [:create, :destroy], Budget::Ballot::Line, budget: { phase: "balloting" }
|
||||
|
||||
|
||||
@@ -7,6 +7,12 @@ module Abilities
|
||||
can [:read, :map, :summary, :share], Proposal
|
||||
can :read, Comment
|
||||
can :read, Poll
|
||||
can :results, Poll do |poll|
|
||||
poll.expired? && poll.results_enabled?
|
||||
end
|
||||
can :stats, Poll do |poll|
|
||||
poll.expired? && poll.stats_enabled?
|
||||
end
|
||||
can :read, Poll::Question
|
||||
can [:read, :welcome], Budget
|
||||
can :read, SpendingProposal
|
||||
@@ -18,10 +24,10 @@ module Abilities
|
||||
can [:read, :print], Budget::Investment
|
||||
can :read_results, Budget, phase: "finished"
|
||||
can :new, DirectMessage
|
||||
can [:read, :debate, :draft_publication, :allegations, :result_publication], Legislation::Process, published: true
|
||||
can [:read, :debate, :draft_publication, :allegations, :result_publication, :proposals], Legislation::Process, published: true
|
||||
can [:read, :changes, :go_to_version], Legislation::DraftVersion
|
||||
can [:read], Legislation::Question
|
||||
can [:create], Legislation::Answer
|
||||
can [:read, :map, :share], Legislation::Proposal
|
||||
can [:search, :comments, :read, :create, :new_comment], Legislation::Annotation
|
||||
end
|
||||
end
|
||||
|
||||
@@ -38,6 +38,15 @@ module Abilities
|
||||
can :moderate, Proposal
|
||||
cannot :moderate, Proposal, author_id: user.id
|
||||
|
||||
can :hide, Legislation::Proposal, hidden_at: nil
|
||||
cannot :hide, Legislation::Proposal, author_id: user.id
|
||||
|
||||
can :ignore_flag, Legislation::Proposal, ignored_flag_at: nil, hidden_at: nil
|
||||
cannot :ignore_flag, Legislation::Proposal, author_id: user.id
|
||||
|
||||
can :moderate, Legislation::Proposal
|
||||
cannot :moderate, Legislation::Proposal, author_id: user.id
|
||||
|
||||
can :hide, User
|
||||
cannot :hide, User, id: user.id
|
||||
|
||||
|
||||