diff --git a/CHANGELOG.md b/CHANGELOG.md index 955ffc300..3121f2670 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,30 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html) +## [0.18.1](https://github.com/consul/consul/tree/v0.18.1) (2019-01-17) + +### Added + +- **Legislation:** Legislation process homepage phase [\#3188](https://github.com/consul/consul/pull/3188) +- **Legislation:** Show documents on processes proposals phase [\#3136](https://github.com/consul/consul/pull/3136) +- **Maintenance-Refactorings:** Remove semicolons from controllers [\#3160](https://github.com/consul/consul/pull/3160) +- **Maintenance-Refactorings:** Remove before action not used [\#3167](https://github.com/consul/consul/pull/3167) +- **Maintenance-Rubocop:** Enable double quotes rubocop rule [\#3175](https://github.com/consul/consul/pull/3175) +- **Maintenance-Rubocop:** Enable line length rubocop rule [\#3165](https://github.com/consul/consul/pull/3165) +- **Maintenance-Rubocop:** Add rubocop rule to indent private methods [\#3134](https://github.com/consul/consul/pull/3134) + +### Changed + +- **Admin:** Improve CRUD budgets and content blocks [\#3173](https://github.com/consul/consul/pull/3173) +- **Design/UX:** new CRUD budgets, content blocks and heading map [\#3150](https://github.com/consul/consul/pull/3150) +- **Design/UX:** Processes key dates [\#3137](https://github.com/consul/consul/pull/3137) + +### Fixed + +- **Admin:** checks for deleted proposals [\#3154](https://github.com/consul/consul/pull/3154) +- **Admin:** Add default order for admin budget investments list [\#3151](https://github.com/consul/consul/pull/3151) +- **Budgets:** Bug Management Cannot create Budget Investment without a map location [\#3133](https://github.com/consul/consul/pull/3133) + ## [0.18.0](https://github.com/consul/consul/compare/v0.17...v0.18) (2018-12-27) ### Added @@ -47,6 +71,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - **Admin:** Improve visualization for small resolution [\#3025](https://github.com/consul/consul/pull/3025) - **Admin:** Budgets admin [\#3012](https://github.com/consul/consul/pull/3012) - **Budgets:** Budget investments social share [\#3053](https://github.com/consul/consul/pull/3053) +- **Design/UX:** Documents title [\#3131](https://github.com/consul/consul/pull/3131) - **Design/UX:** Proposal create question [\#3122](https://github.com/consul/consul/pull/3122) - **Design/UX:** Budget investments price explanation [\#3121](https://github.com/consul/consul/pull/3121) - **Design/UX:** Change CRUD for budget groups and headings [\#3106](https://github.com/consul/consul/pull/3106) diff --git a/app/assets/images/map.jpg b/app/assets/images/map.jpg index 0b3ad3516..b35490b52 100644 Binary files a/app/assets/images/map.jpg and b/app/assets/images/map.jpg differ diff --git a/app/assets/javascripts/forms.js.coffee b/app/assets/javascripts/forms.js.coffee index edf4c525f..3562335a4 100644 --- a/app/assets/javascripts/forms.js.coffee +++ b/app/assets/javascripts/forms.js.coffee @@ -23,8 +23,29 @@ App.Forms = false ) + synchronizeInputs: -> + $("[name='progress_bar[percentage]']").on + input: -> + $("[name='#{this.name}']").val($(this).val()) + + $("[name='progress_bar[percentage]'][type='range']").trigger("input") + + hideOrShowFieldsAfterSelection: -> + $("[name='progress_bar[kind]']").on + change: -> + title_field = $("[name^='progress_bar'][name$='[title]']").parent() + + if this.value == "primary" + title_field.hide() + else + title_field.show() + + $("[name='progress_bar[kind]']").change() + initialize: -> App.Forms.disableEnter() App.Forms.submitOnChange() App.Forms.toggleLink() + App.Forms.synchronizeInputs() + App.Forms.hideOrShowFieldsAfterSelection() false diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index f08d14fda..95f29e862 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -251,6 +251,13 @@ $sidebar-active: #f4fcd0; max-width: none; } + form { + + .input-group-label { + height: $line-height * 2; + } + } + .menu.simple { margin-bottom: $line-height / 2; diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 3f93ffa6b..5e993d5d6 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -6,6 +6,7 @@ @import 'admin'; @import 'layout'; @import 'participation'; +@import 'milestones'; @import 'pages'; @import 'legislation'; @import 'legislation_process'; diff --git a/app/assets/stylesheets/milestones.scss b/app/assets/stylesheets/milestones.scss new file mode 100644 index 000000000..bc4515665 --- /dev/null +++ b/app/assets/stylesheets/milestones.scss @@ -0,0 +1,95 @@ +.tab-milestones ul { + margin-top: rem-calc(40); + position: relative; +} + +.tab-milestones .timeline li { + margin: 0 auto; + position: relative; + width: 0; + + @include breakpoint(small only) { + width: 100%; + } + + &::before { + background: $budget; + border-radius: rem-calc(20); + content: ''; + height: rem-calc(20); + position: absolute; + top: 5px; + transform: translateX(-50%); + width: rem-calc(20); + z-index: 2; + } + + &::after { + background: $light-gray; + bottom: 100%; + content: ''; + height: 100%; + position: absolute; + top: 25px; + width: 1px; + z-index: 1; + } + + .milestone-content { + padding: $line-height / 6 $line-height / 2; + position: relative; + + @include breakpoint(medium) { + width: rem-calc(300); + } + + @include breakpoint(large) { + width: rem-calc(450); + } + + h3 { + margin-bottom: 0; + } + + .milestone-date { + color: $text-medium; + font-size: $small-font-size; + } + } + + &:nth-child(odd) { + + .milestone-content { + text-align: right; + + @include breakpoint(medium) { + margin-left: rem-calc(-315); + } + + @include breakpoint(large) { + margin-left: rem-calc(-465); + } + + @include breakpoint(small only) { + left: 15px; + text-align: left; + } + } + } + + &:nth-child(even) { + + .milestone-content { + left: 15px; + } + } +} + +.milestone-status { + background: $budget; + border-radius: rem-calc(4); + color: #fff; + display: inline-block; + margin-top: $line-height / 6; + padding: $line-height / 4 $line-height / 2; +} diff --git a/app/assets/stylesheets/participation.scss b/app/assets/stylesheets/participation.scss index 023686b6e..ba02e18ad 100644 --- a/app/assets/stylesheets/participation.scss +++ b/app/assets/stylesheets/participation.scss @@ -523,118 +523,6 @@ } } -.tab-milestones ul { - margin-top: rem-calc(40); - position: relative; - - li { - margin: 0 auto; - position: relative; - width: 0; - } - - li::before { - background: $budget; - border-radius: rem-calc(20); - content: ''; - height: rem-calc(20); - position: absolute; - top: 5px; - transform: translateX(-50%); - width: rem-calc(20); - z-index: 2; - } - - li::after { - background: $light-gray; - bottom: 100%; - content: ''; - height: 100%; - position: absolute; - top: 25px; - width: 1px; - z-index: 1; - } -} - -.tab-milestones ul .milestone-content { - padding: $line-height / 6 $line-height / 2; - position: relative; - - h3 { - margin-bottom: 0; - } - - .milestone-date { - color: $text-medium; - font-size: $small-font-size; - } -} - -.tab-milestones .timeline ul li:nth-child(odd), -.tab-milestones .timeline ul li:nth-child(even) { - - .milestone-content { - - @include breakpoint(medium) { - width: rem-calc(300); - } - - @include breakpoint(large) { - width: rem-calc(450); - } - } -} - -.tab-milestones .timeline ul li:nth-child(odd) { - - .milestone-content { - text-align: right; - - @include breakpoint(medium) { - margin-left: rem-calc(-315); - } - - @include breakpoint(large) { - margin-left: rem-calc(-465); - } - } -} - -.tab-milestones .timeline ul li:nth-child(even) { - - .milestone-content { - left: 15px; - } -} - -.tab-milestones { - @include breakpoint(small only) { - - .timeline ul li { - width: 100%; - - &:nth-child(odd), - &:nth-child(even) { - - .milestone-content { - left: 15px; - text-align: left; - } - } - } - } -} - -.milestone-status { - background: $budget; - border-radius: rem-calc(4); - color: #fff; - display: inline-block; - margin-top: $line-height / 6; - padding: $line-height / 4 $line-height / 2; -} - .show-actions-menu { [class^="icon-"] { diff --git a/app/controllers/admin/budget_investment_progress_bars_controller.rb b/app/controllers/admin/budget_investment_progress_bars_controller.rb new file mode 100644 index 000000000..bb4db0d79 --- /dev/null +++ b/app/controllers/admin/budget_investment_progress_bars_controller.rb @@ -0,0 +1,8 @@ +class Admin::BudgetInvestmentProgressBarsController < Admin::ProgressBarsController + + private + + def progressable + Budget::Investment.find(params[:budget_investment_id]) + end +end diff --git a/app/controllers/admin/legislation/progress_bars_controller.rb b/app/controllers/admin/legislation/progress_bars_controller.rb new file mode 100644 index 000000000..ba00d5e91 --- /dev/null +++ b/app/controllers/admin/legislation/progress_bars_controller.rb @@ -0,0 +1,14 @@ +class Admin::Legislation::ProgressBarsController < Admin::ProgressBarsController + include FeatureFlags + feature_flag :legislation + + def index + @process = progressable + end + + private + + def progressable + ::Legislation::Process.find(params[:process_id]) + end +end diff --git a/app/controllers/admin/progress_bars_controller.rb b/app/controllers/admin/progress_bars_controller.rb new file mode 100644 index 000000000..a9611b364 --- /dev/null +++ b/app/controllers/admin/progress_bars_controller.rb @@ -0,0 +1,69 @@ +class Admin::ProgressBarsController < Admin::BaseController + include Translatable + + before_action :load_progressable + before_action :load_progress_bar, only: [:edit, :update, :destroy] + helper_method :progress_bars_index + + def index + end + + def new + @progress_bar = @progressable.progress_bars.new + end + + def create + @progress_bar = @progressable.progress_bars.new(progress_bar_params) + if @progress_bar.save + redirect_to progress_bars_index, notice: t("admin.progress_bars.create.notice") + else + render :new + end + end + + def edit + end + + def update + if @progress_bar.update(progress_bar_params) + redirect_to progress_bars_index, notice: t('admin.progress_bars.update.notice') + else + render :edit + end + end + + def destroy + @progress_bar.destroy + redirect_to progress_bars_index, notice: t('admin.progress_bars.delete.notice') + end + + private + + def progress_bar_params + params.require(:progress_bar).permit(allowed_params) + end + + def allowed_params + [ + :kind, + :percentage, + translation_params(ProgressBar) + ] + end + + def load_progressable + @progressable = progressable + end + + def progressable + raise "This method must be implemented in subclass #{self.class.name}" + end + + def load_progress_bar + @progress_bar = progressable.progress_bars.find(params[:id]) + end + + def progress_bars_index + polymorphic_path([:admin, *resource_hierarchy_for(@progressable), ProgressBar.new]) + end +end diff --git a/app/controllers/admin/proposal_progress_bars_controller.rb b/app/controllers/admin/proposal_progress_bars_controller.rb new file mode 100644 index 000000000..9259acc4b --- /dev/null +++ b/app/controllers/admin/proposal_progress_bars_controller.rb @@ -0,0 +1,7 @@ +class Admin::ProposalProgressBarsController < Admin::ProgressBarsController + + private + def progressable + Proposal.find(params[:proposal_id]) + end +end diff --git a/app/controllers/documents_controller.rb b/app/controllers/documents_controller.rb index 001d23446..1d6df8d14 100644 --- a/app/controllers/documents_controller.rb +++ b/app/controllers/documents_controller.rb @@ -11,7 +11,7 @@ class DocumentsController < ApplicationController else flash[:alert] = t "documents.actions.destroy.alert" end - redirect_to params[:from] + redirect_to request.referer end format.js do if @document.destroy diff --git a/app/controllers/installation_controller.rb b/app/controllers/installation_controller.rb index bc0e32943..8aef8b659 100644 --- a/app/controllers/installation_controller.rb +++ b/app/controllers/installation_controller.rb @@ -12,7 +12,7 @@ class InstallationController < ApplicationController def consul_installation_details { - release: 'v0.18' + release: "v0.18.1" }.merge(features: settings_feature_flags) end diff --git a/app/helpers/polls_helper.rb b/app/helpers/polls_helper.rb index 0cb875dff..83200c621 100644 --- a/app/helpers/polls_helper.rb +++ b/app/helpers/polls_helper.rb @@ -49,4 +49,19 @@ module PollsHelper question.answers.where(author: current_user).any? { |vote| current_user.current_sign_in_at > vote.updated_at } end + def show_stats_or_results? + @poll.expired? && (@poll.results_enabled? || @poll.stats_enabled?) + end + + def results_menu? + controller_name == "polls" && action_name == "results" + end + + def stats_menu? + controller_name == "polls" && action_name == "stats" + end + + def info_menu? + controller_name == "polls" && action_name == "show" + end end diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index bdc457bc0..847f1effc 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -93,6 +93,7 @@ module Abilities cannot :comment_as_moderator, [::Legislation::Question, Legislation::Annotation, ::Legislation::Proposal] can [:create], Document + can [:destroy], Document, documentable_type: "Poll::Question::Answer" can [:create, :destroy], DirectUpload can [:deliver], Newsletter, hidden_at: nil diff --git a/app/models/concerns/milestoneable.rb b/app/models/concerns/milestoneable.rb index 2e961c613..7f58a77bb 100644 --- a/app/models/concerns/milestoneable.rb +++ b/app/models/concerns/milestoneable.rb @@ -5,5 +5,7 @@ module Milestoneable has_many :milestones, as: :milestoneable, dependent: :destroy scope :with_milestones, -> { joins(:milestones).distinct } + + has_many :progress_bars, as: :progressable end end diff --git a/app/models/progress_bar.rb b/app/models/progress_bar.rb new file mode 100644 index 000000000..7a7973723 --- /dev/null +++ b/app/models/progress_bar.rb @@ -0,0 +1,28 @@ +class ProgressBar < ActiveRecord::Base + self.inheritance_column = nil + RANGE = 0..100 + + enum kind: %i[primary secondary] + + belongs_to :progressable, polymorphic: true + + translates :title, touch: true + include Globalizable + + validates :progressable, presence: true + validates :kind, presence: true, + uniqueness: { + scope: [:progressable_type, :progressable_id], + conditions: -> { primary } + } + validates :percentage, presence: true, inclusion: RANGE, numericality: { only_integer: true } + + before_validation :assign_progress_bar_to_translations + validates_translation :title, presence: true, unless: :primary? + + private + + def assign_progress_bar_to_translations + translations.each { |translation| translation.globalized_model = self } + end +end diff --git a/app/models/progress_bar/translation.rb b/app/models/progress_bar/translation.rb new file mode 100644 index 000000000..d61f1d47b --- /dev/null +++ b/app/models/progress_bar/translation.rb @@ -0,0 +1,3 @@ +class ProgressBar::Translation < Globalize::ActiveRecord::Translation + delegate :primary?, to: :globalized_model +end diff --git a/app/models/site_customization/image.rb b/app/models/site_customization/image.rb index c3219e427..e933c40a0 100644 --- a/app/models/site_customization/image.rb +++ b/app/models/site_customization/image.rb @@ -4,13 +4,14 @@ class SiteCustomization::Image < ActiveRecord::Base "social_media_icon" => [470, 246], "social_media_icon_twitter" => [246, 246], "apple-touch-icon-200" => [200, 200], - "budget_execution_no_image" => [800, 600] + "budget_execution_no_image" => [800, 600], + "map" => [420, 500] } has_attached_file :image validates :name, presence: true, uniqueness: true, inclusion: { in: VALID_IMAGES.keys } - validates_attachment_content_type :image, content_type: ["image/png"] + validates_attachment_content_type :image, content_type: ["image/png", "image/jpeg"] validate :check_image def self.all_images diff --git a/app/views/admin/budgets/_form.html.erb b/app/views/admin/budgets/_form.html.erb index 9a31c6cd2..7c8175613 100644 --- a/app/views/admin/budgets/_form.html.erb +++ b/app/views/admin/budgets/_form.html.erb @@ -6,7 +6,7 @@
| - <%= link_to t('documents.buttons.download_document'), + <%= link_to t("documents.buttons.download_document"), document.attachment.url, target: "_blank", rel: "nofollow", - class: 'button hollow' %> + class: "button hollow" %> + + <%= link_to t("admin.shared.delete"), + document_path(document), + method: :delete, + class: "button hollow alert", + data: { confirm: t("admin.actions.confirm") } %> | <% end %> diff --git a/app/views/admin/progress_bars/_form.html.erb b/app/views/admin/progress_bars/_form.html.erb new file mode 100644 index 000000000..cdc6af59e --- /dev/null +++ b/app/views/admin/progress_bars/_form.html.erb @@ -0,0 +1,31 @@ +<%= render "admin/shared/globalize_locales", resource: @progress_bar %> + +<%= translatable_form_for [:admin, *resource_hierarchy_for(@progress_bar)] do |f| %> + +
| <%= t("admin.progress_bars.index.table_id") %> | +<%= t("admin.progress_bars.index.table_kind") %> | +<%= t("admin.progress_bars.index.table_title") %> | +<%= t("admin.progress_bars.index.table_percentage") %> | +<%= t("admin.actions.actions") %> | +
|---|---|---|---|---|
| + <%= progress_bar.id %> + | +<%= ProgressBar.human_attribute_name("kind.#{progress_bar.kind}") %> | ++ <% if progress_bar.title.present? %> + <%= progress_bar.title %> + <% else %> + <%= t("admin.progress_bars.index.primary") %> + <% end %> + | ++ <%= number_to_percentage(progress_bar.percentage, strip_insignificant_zeros: true) %> + | ++ <%= link_to t("admin.actions.edit"), + polymorphic_path([:admin, *resource_hierarchy_for(progress_bar)], + action: :edit), + class: "button hollow" %> + + <%= link_to t("admin.actions.delete"), + polymorphic_path([:admin, *resource_hierarchy_for(progress_bar)]), + method: :delete, + class: "button hollow alert" %> + | +