diff --git a/CHANGELOG.md b/CHANGELOG.md index fb09a5769..adfaaac31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,75 @@ 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.16.0](https://github.com/consul/consul/compare/v0.15...v0.16) - 2018-07-16 + +### Added +- **Budgets:** Budgets investment show messages https://github.com/consul/consul/pull/2766 +- **Budgets:** Add Valuator Group name validation & related specs https://github.com/consul/consul/pull/2576 +- **Budgets:** Investment milestone's project status https://github.com/consul/consul/pull/2706 +- **Budgets:** Budget statuses https://github.com/consul/consul/pull/2705 +- **Budgets:** Display only selected budget investmests in "Publishing prices" phase https://github.com/consul/consul/pull/2657 +- **Budgets:** Budgets see results https://github.com/consul/consul/pull/2620 +- **Budgets:** Show 'See Results' button in budget admin panel https://github.com/consul/consul/pull/2632 +- **Budgets:** Adds message to selected budget investments https://github.com/consul/consul/pull/2622 +- **Budgets:** Fixes Issue \#2604 https://github.com/consul/consul/pull/2614 +- **Officing:** Officing not to vote https://github.com/consul/consul/pull/2726 +- **Officing:** Officing sidebar menu https://github.com/consul/consul/pull/2725 +- **Homepage:** Homepage cards https://github.com/consul/consul/pull/2693 +- **Homepage:** Adding homepage header and cards seeds https://github.com/consul/consul/pull/2679 +- **Homepage:** Add customization of homepage from admin section https://github.com/consul/consul/pull/2641 +- **Globalization:** Allow admin generated content to be translatable https://github.com/consul/consul/pull/2619 +- **Recommendations:** Debates and proposals recommendations for users https://github.com/consul/consul/pull/2760 +- **Notifications:** Allow author notifications to be moderated https://github.com/consul/consul/pull/2717 +- **Configuration:** Document upload setting https://github.com/consul/consul/pull/2585 +- **Maintenance:** add proposal image on dev\_seeds task https://github.com/consul/consul/pull/2768 +- **Docker:** Add imagemagick package to Docker configuration https://github.com/consul/consul/pull/2655 +- **Design/UX:** Legislation help gif https://github.com/consul/consul/pull/2732 + +### Changed +- **Budgets:** Add valuator groups assigned to investments to admin tables & csv export https://github.com/consul/consul/pull/2592 +- **Design/UX:** Adds ballot booths menu on admin https://github.com/consul/consul/pull/2716 +- **Design/UX:** Polls UI https://github.com/consul/consul/pull/2765 +- **Design/UX:** Manager UI https://github.com/consul/consul/pull/2715 +- **Design/UX:** Homepage design https://github.com/consul/consul/pull/2694 +- **Design/UX:** Admin UI https://github.com/consul/consul/pull/2666 +- **Design/UX:** Minor fixes https://github.com/consul/consul/pull/2665 +- **Design/UX:** Homepage layout https://github.com/consul/consul/pull/2663 +- **Design/UX:** Admin form improvements https://github.com/consul/consul/pull/2645 +- **Maintenance:** Regenerate Gemfile.lock https://github.com/consul/consul/pull/2701 +- **Maintenance:** Update Sprockets to fix vulnerability https://github.com/consul/consul/pull/2758 +- **Maintenance:** Split spec common actions support helper https://github.com/consul/consul/pull/2653 +- **Maintenance:** Split admin settings https://github.com/consul/consul/pull/2650 +- **Maintenance:** Update README with production configuration https://github.com/consul/consul/pull/2648 +- **Maintenance:** Remove sitemap generator output when running specs https://github.com/consul/consul/pull/2599 +- **Maintenance:** Avoid db:dev\_seed log print when run from its test https://github.com/consul/consul/pull/2598 +- **Maintenance:** Foundation update https://github.com/consul/consul/pull/2590 +- **Docker:** Docker/docker-compose enhancements https://github.com/consul/consul/pull/2661 + +### Fixed +- **Budgets:** Fix valuation heading filters https://github.com/consul/consul/pull/2578 +- **Budgets:** Budgets homepage map fixes https://github.com/consul/consul/pull/2654 +- **Budgets:** Display message in budget's index when there are no budgets https://github.com/consul/consul/pull/2575 +- **Proposals:** Fix validation error when creating proposals without user verification https://github.com/consul/consul/pull/2775 +- **Design/UX:** UI design https://github.com/consul/consul/pull/2733 +- **Design/UX:** A11y https://github.com/consul/consul/pull/2724 +- **Design/UX:** UI design https://github.com/consul/consul/pull/2608 +- **Design/UX:** Fixes admin menu toggle https://github.com/consul/consul/pull/2692 +- **Maintenance:** Fix flaky spec: Budget Investments Show milestones https://github.com/consul/consul/pull/2719 +- **Maintenance:** Fix flaky specs: Votes Debates and Voting comments Update https://github.com/consul/consul/pull/2734 +- **Maintenance:** Fix flaky specs using CKEditor https://github.com/consul/consul/pull/2711 +- **Maintenance:** Fix suggestions being requested with every keystroke https://github.com/consul/consul/pull/2708 +- **Maintenance:** Fix valuation heading filters https://github.com/consul/consul/pull/2702 +- **Maintenance:** Flaky spec: Polls Concerns behaves like notifiable in-app Multiple users commented on my notifiable https://github.com/consul/consul/pull/2699 +- **Maintenance:** Fix flaky spec: Proposals Voting Voting proposals on behalf of someone in show view https://github.com/consul/consul/pull/2697 +- **Maintenance:** Fix flaky spec: Admin budgets Manage groups and headings Create group https://github.com/consul/consul/pull/2696 +- **Maintenance:** Fix flaky specs: Emails Budgets Selected/Unselected investment https://github.com/consul/consul/pull/2695 +- **Maintenance:** Fix flaky specs: Officing Results Add/Edit results https://github.com/consul/consul/pull/2712 +- **Maintenance:** Add issue template https://github.com/consul/consul/pull/2722 +- **Users activity:** Deal gracefully with hidden followable in my activity https://github.com/consul/consul/pull/2752 +- **Recommendations:** Deal gracefully with recommendations of hidden proposals https://github.com/consul/consul/pull/2751 +- **Maps:** Fix MapLocation json\_data to return mappable ids https://github.com/consul/consul/pull/2613 + ## [0.15.0](https://github.com/consul/consul/compare/v0.14...v0.15) - 2018-05-23 ### Added @@ -56,7 +125,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - **Social share:** Fixes social share buttons https://github.com/consul/consul/pull/2525 - **Newsletters:** Fixed how newsletters controller and mailer handle recipients https://github.com/consul/consul/pull/2492 - **Newsletters:** Fix UserSegment feasible and undecided investment authors https://github.com/consul/consul/pull/2491 -- **Newsletters:** Remove empty emails from user segment usages +- **Newsletters:** Remove empty emails from user segment usages - **Design:** Mode view https://github.com/consul/consul/pull/2567 - **Design:** Minor fixes https://github.com/consul/consul/pull/2566 - **Design:** Improve Documents list https://github.com/consul/consul/pull/2490 @@ -347,7 +416,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Rails 4.2.6 - Ruby 2.2.3 -[Unreleased]: https://github.com/consul/consul/compare/v0.15...consul:master +[Unreleased]: https://github.com/consul/consul/compare/v0.16...consul:master +[0.16.0]: https://github.com/consul/consul/compare/v0.15...v.016 [0.15.0]: https://github.com/consul/consul/compare/v0.14...v0.15 [0.14.0]: https://github.com/consul/consul/compare/v0.13...v0.14 [0.13.0]: https://github.com/consul/consul/compare/v0.12...v0.13 diff --git a/app/assets/images/banners/banner1.png b/app/assets/images/banners/banner1.png deleted file mode 100644 index eff1cb9d7..000000000 Binary files a/app/assets/images/banners/banner1.png and /dev/null differ diff --git a/app/assets/images/banners/banner2.png b/app/assets/images/banners/banner2.png deleted file mode 100644 index 8ae0715e2..000000000 Binary files a/app/assets/images/banners/banner2.png and /dev/null differ diff --git a/app/assets/images/banners/banner3.png b/app/assets/images/banners/banner3.png deleted file mode 100644 index e4ff49093..000000000 Binary files a/app/assets/images/banners/banner3.png and /dev/null differ diff --git a/app/assets/images/logo_header.png b/app/assets/images/logo_header.png index c178ec781..84478da83 100644 Binary files a/app/assets/images/logo_header.png and b/app/assets/images/logo_header.png differ diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index f9c38b1c6..e1fda6bb3 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -83,6 +83,7 @@ //= require clipboard //= require clipboard_button //= require best_in_place_initialize +//= require send_admin_notification_alert var initialize_modules = function() { App.Comments.initialize(); @@ -130,6 +131,7 @@ var initialize_modules = function() { App.Globalize.initialize(); App.ClipboardButton.initialize(); App.BestInPlace.initialize(); + App.SendAdminNotificationAlert.initialize(); }; $(function(){ diff --git a/app/assets/javascripts/send_admin_notification_alert.js.coffee b/app/assets/javascripts/send_admin_notification_alert.js.coffee new file mode 100644 index 000000000..8c1c928e5 --- /dev/null +++ b/app/assets/javascripts/send_admin_notification_alert.js.coffee @@ -0,0 +1,4 @@ +App.SendAdminNotificationAlert = + initialize: -> + $('#js-send-admin_notification-alert').on 'click', -> + confirm(this.dataset.alert); diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index a5f541b47..7e1ff6370 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -1165,6 +1165,17 @@ table { } } +.max-headings-label { + color: $text-medium; + font-size: $small-font-size; + margin-left: $line-height / 2; +} + +.current-of-max-headings { + color: #000; + font-weight: bold; +} + // 11. Newsletters // ----------------- diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index 1ad457b87..a140fca4c 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -34,6 +34,12 @@ background-color: $brand; } +html, +body { + height: 100%; + margin: 0; +} + body { font-size: $base-font-size; } @@ -542,6 +548,20 @@ header { } } } + + .top-bar-title { + line-height: $line-height; + + a img { + height: rem-calc(48); + margin: 0; + width: auto; + + @include breakpoint(medium up) { + height: auto; + } + } + } } .menu-icon { @@ -780,8 +800,7 @@ footer { } .footer { - background: $border; - border-top: 6px solid $brand; + background: #f1f1f1; margin-top: $line-height * 2; padding-top: $line-height; } @@ -2483,10 +2502,6 @@ table { padding: 0 $line-height / 2; position: relative; - a { - word-wrap: break-word; - } - .icon-document { color: #007bb7; display: inline-block; @@ -2501,6 +2516,10 @@ table { } } +.document-link a { + word-wrap: break-word; +} + .additional-document-link { background: $highlight-soft; border: 1px solid $highlight; diff --git a/app/controllers/admin/admin_notifications_controller.rb b/app/controllers/admin/admin_notifications_controller.rb new file mode 100644 index 000000000..1dd03038a --- /dev/null +++ b/app/controllers/admin/admin_notifications_controller.rb @@ -0,0 +1,67 @@ +class Admin::AdminNotificationsController < Admin::BaseController + + def index + @admin_notifications = AdminNotification.all + end + + def show + @admin_notification = AdminNotification.find(params[:id]) + end + + def new + @admin_notification = AdminNotification.new + end + + def create + @admin_notification = AdminNotification.new(admin_notification_params) + + if @admin_notification.save + notice = t("admin.admin_notifications.create_success") + redirect_to [:admin, @admin_notification], notice: notice + else + render :new + end + end + + def edit + @admin_notification = AdminNotification.find(params[:id]) + end + + def update + @admin_notification = AdminNotification.find(params[:id]) + + if @admin_notification.update(admin_notification_params) + notice = t("admin.admin_notifications.update_success") + redirect_to [:admin, @admin_notification], notice: notice + else + render :edit + end + end + + def destroy + @admin_notification = AdminNotification.find(params[:id]) + @admin_notification.destroy + + notice = t("admin.admin_notifications.delete_success") + redirect_to admin_admin_notifications_path, notice: notice + end + + def deliver + @admin_notification = AdminNotification.find(params[:id]) + + if @admin_notification.valid? + @admin_notification.deliver + flash[:notice] = t("admin.admin_notifications.send_success") + else + flash[:error] = t("admin.segment_recipient.invalid_recipients_segment") + end + + redirect_to [:admin, @admin_notification] + end + + private + + def admin_notification_params + params.require(:admin_notification).permit(:title, :body, :link, :segment_recipient) + end +end diff --git a/app/controllers/admin/budget_investments_controller.rb b/app/controllers/admin/budget_investments_controller.rb index 2c27259ee..0258c23a6 100644 --- a/app/controllers/admin/budget_investments_controller.rb +++ b/app/controllers/admin/budget_investments_controller.rb @@ -84,12 +84,8 @@ class Admin::BudgetInvestmentsController < Admin::BaseController end def load_investments - @investments = if params[:title_or_id].present? - Budget::Investment.search_by_title_or_id(params) - else - Budget::Investment.scoped_filter(params, @current_filter) - .order(sort_by(params[:sort_by])) - end + @investments = Budget::Investment.scoped_filter(params, @current_filter) + .order(sort_by(params[:sort_by])) @investments = @investments.page(params[:page]) unless request.format.csv? end diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb index 1e1df4f1f..ca2bf7dc4 100644 --- a/app/controllers/budgets/investments_controller.rb +++ b/app/controllers/budgets/investments_controller.rb @@ -32,7 +32,11 @@ module Budgets respond_to :html, :js def index - @investments = investments.page(params[:page]).per(10).for_render + if @budget.finished? + @investments = investments.winners.page(params[:page]).per(10).for_render + else + @investments = investments.page(params[:page]).per(10).for_render + end @investment_ids = @investments.pluck(:id) load_investment_votes(@investments) @@ -112,8 +116,9 @@ module Budgets def set_random_seed if params[:order] == 'random' || params[:order].blank? - seed = params[:random_seed] || session[:random_seed] || rand(-100000..100000) - params[:random_seed] ||= Float(seed) rescue 0 + seed = params[:random_seed] || session[:random_seed] || rand + params[:random_seed] = seed + session[:random_seed] = params[:random_seed] else params[:random_seed] = nil end diff --git a/app/controllers/installation_controller.rb b/app/controllers/installation_controller.rb index e13f29d89..0651e9386 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.15' + release: 'v0.16' }.merge(features: settings_feature_flags) end @@ -21,4 +21,3 @@ class InstallationController < ApplicationController end end - diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index 588f2ed6b..ee6878502 100644 --- a/app/controllers/notifications_controller.rb +++ b/app/controllers/notifications_controller.rb @@ -44,7 +44,11 @@ class NotificationsController < ApplicationController when "Topic" community_topic_path @notification.linkable_resource.community, @notification.linkable_resource else - url_for @notification.linkable_resource + if @notification.linkable_resource.is_a?(AdminNotification) + @notification.linkable_resource.link || notifications_path + else + url_for @notification.linkable_resource + end end end diff --git a/app/helpers/admin_budget_investments_helper.rb b/app/helpers/admin_budget_investments_helper.rb new file mode 100644 index 000000000..742ff5bac --- /dev/null +++ b/app/helpers/admin_budget_investments_helper.rb @@ -0,0 +1,11 @@ +module AdminBudgetInvestmentsHelper + + def advanced_menu_visibility + (params[:advanced_filters].empty? && params["max_per_heading"].blank?) ? 'hide' : '' + end + + def init_advanced_menu + params[:advanced_filters] = [] unless params[:advanced_filters] + end + +end diff --git a/app/models/admin_notification.rb b/app/models/admin_notification.rb new file mode 100644 index 000000000..eccd90910 --- /dev/null +++ b/app/models/admin_notification.rb @@ -0,0 +1,44 @@ +class AdminNotification < ActiveRecord::Base + include Notifiable + + validates :title, presence: true + validates :body, presence: true + validates :segment_recipient, presence: true + validate :validate_segment_recipient + + before_validation :complete_link_url + + def list_of_recipients + UserSegments.send(segment_recipient) if valid_segment_recipient? + end + + def valid_segment_recipient? + segment_recipient && UserSegments.respond_to?(segment_recipient) + end + + def draft? + sent_at.nil? + end + + def list_of_recipients_count + list_of_recipients.try(:count) || 0 + end + + def deliver + list_of_recipients.each { |user| Notification.add(user, self) } + self.update(sent_at: Time.current, recipients_count: list_of_recipients.count) + end + + private + + def validate_segment_recipient + errors.add(:segment_recipient, :invalid) unless valid_segment_recipient? + end + + def complete_link_url + return unless link.present? + unless self.link[/\Ahttp:\/\//] || self.link[/\Ahttps:\/\//] + self.link = "http://#{self.link}" + end + end +end diff --git a/app/models/budget.rb b/app/models/budget.rb index a79746615..3f4bed9a1 100644 --- a/app/models/budget.rb +++ b/app/models/budget.rb @@ -146,6 +146,8 @@ class Budget < ActiveRecord::Base %w{random} when 'publishing_prices', 'balloting', 'reviewing_ballots' %w{random price} + when 'finished' + %w{random} else %w{random confidence_score} end @@ -193,5 +195,3 @@ class Budget < ActiveRecord::Base slug.nil? || drafting? end end - - diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 6a9b95cd4..ee3292fcd 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -109,14 +109,15 @@ class Budget budget = Budget.find_by(slug: params[:budget_id]) || Budget.find_by(id: params[:budget_id]) results = Investment.by_budget(budget) - results = limit_results(budget, params, results) if params[:max_per_heading].present? - results = results.where(group_id: params[:group_id]) if params[:group_id].present? - results = results.by_tag(params[:tag_name]) if params[:tag_name].present? - results = results.by_heading(params[:heading_id]) if params[:heading_id].present? - results = results.by_valuator(params[:valuator_id]) if params[:valuator_id].present? - results = results.by_valuator_group(params[:valuator_group_id]) if params[:valuator_group_id].present? - results = results.by_admin(params[:administrator_id]) if params[:administrator_id].present? - results = advanced_filters(params, results) if params[:advanced_filters].present? + results = limit_results(budget, params, results) if params[:max_per_heading].present? + results = results.where(group_id: params[:group_id]) if params[:group_id].present? + results = results.by_tag(params[:tag_name]) if params[:tag_name].present? + results = results.by_heading(params[:heading_id]) if params[:heading_id].present? + results = results.by_valuator(params[:valuator_id]) if params[:valuator_id].present? + results = results.by_valuator_group(params[:valuator_group_id]) if params[:valuator_group_id].present? + results = results.by_admin(params[:administrator_id]) if params[:administrator_id].present? + results = advanced_filters(params, results) if params[:advanced_filters].present? + results = search_by_title_or_id(params[:title_or_id].strip, results) if params[:title_or_id] results = results.send(current_filter) if current_filter.present? results.includes(:heading, :group, :budget, administrator: :user, valuators: :user) @@ -143,11 +144,12 @@ class Budget results.where("budget_investments.id IN (?)", ids) end - def self.search_by_title_or_id(params) - results = Investment.where(budget_id: params[:budget_id]) - - return results.where(id: params[:title_or_id]) if params[:title_or_id] =~ /\A[0-9]+\z/ - results.where("title ILIKE ?", "%#{params[:title_or_id].strip}%") + def self.search_by_title_or_id(title_or_id, results) + if title_or_id =~ /^[0-9]+$/ + results.where(id: title_or_id) + else + results.where("title ILIKE ?", "%#{title_or_id}%") + end end def searchable_values diff --git a/app/models/budget/investment/exporter.rb b/app/models/budget/investment/exporter.rb index 03900fd7e..c7e4ce461 100644 --- a/app/models/budget/investment/exporter.rb +++ b/app/models/budget/investment/exporter.rb @@ -16,16 +16,18 @@ class Budget::Investment::Exporter def headers [ - I18n.t("admin.budget_investments.index.table_id"), - I18n.t("admin.budget_investments.index.table_title"), - I18n.t("admin.budget_investments.index.table_supports"), - I18n.t("admin.budget_investments.index.table_admin"), - I18n.t("admin.budget_investments.index.table_valuator"), - I18n.t("admin.budget_investments.index.table_valuation_group"), - I18n.t("admin.budget_investments.index.table_geozone"), - I18n.t("admin.budget_investments.index.table_feasibility"), - I18n.t("admin.budget_investments.index.table_valuation_finished"), - I18n.t("admin.budget_investments.index.table_selection") + I18n.t("admin.budget_investments.index.list.id"), + I18n.t("admin.budget_investments.index.list.title"), + I18n.t("admin.budget_investments.index.list.supports"), + I18n.t("admin.budget_investments.index.list.admin"), + I18n.t("admin.budget_investments.index.list.valuator"), + I18n.t("admin.budget_investments.index.list.valuation_group"), + I18n.t("admin.budget_investments.index.list.geozone"), + I18n.t("admin.budget_investments.index.list.feasibility"), + I18n.t("admin.budget_investments.index.list.valuation_finished"), + I18n.t("admin.budget_investments.index.list.selected"), + I18n.t("admin.budget_investments.index.list.visible_to_valuators"), + I18n.t("admin.budget_investments.index.list.author_username") ] end @@ -40,7 +42,9 @@ class Budget::Investment::Exporter investment.heading.name, price(investment), investment.valuation_finished? ? I18n.t('shared.yes') : I18n.t('shared.no'), - investment.selected? ? I18n.t('shared.yes') : I18n.t('shared.no') + investment.selected? ? I18n.t('shared.yes') : I18n.t('shared.no'), + investment.visible_to_valuators? ? I18n.t('shared.yes') : I18n.t('shared.no'), + investment.author.username ] end diff --git a/app/models/notification.rb b/app/models/notification.rb index 33bf7701c..dacedb762 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -53,9 +53,19 @@ class Notification < ActiveRecord::Base "proposal_notification" when "Comment" "replies_to" + when "AdminNotification" + nil else "comments_on" end end -end \ No newline at end of file + def link + if notifiable.is_a?(AdminNotification) && notifiable.link.blank? + nil + else + self + end + end + +end diff --git a/app/models/proposal.rb b/app/models/proposal.rb index 32dec90df..571942099 100644 --- a/app/models/proposal.rb +++ b/app/models/proposal.rb @@ -39,12 +39,12 @@ class Proposal < ActiveRecord::Base validates :question, presence: true validates :summary, presence: true validates :author, presence: true - validates :responsible_name, presence: true + validates :responsible_name, presence: true, unless: :skip_user_verification? validates :title, length: { in: 4..Proposal.title_max_length } validates :description, length: { maximum: Proposal.description_max_length } validates :question, length: { in: 10..Proposal.question_max_length } - validates :responsible_name, length: { in: 6..Proposal.responsible_name_max_length } + validates :responsible_name, length: { in: 6..Proposal.responsible_name_max_length }, unless: :skip_user_verification? validates :retired_reason, inclusion: { in: RETIRE_OPTIONS, allow_nil: true } validates :terms_of_service, acceptance: { allow_nil: false }, on: :create @@ -232,6 +232,10 @@ class Proposal < ActiveRecord::Base return orders end + def skip_user_verification? + Setting["feature.user.skip_verification"].present? + end + protected def set_responsible_name diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 229b7c866..f05c5abf9 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -79,18 +79,21 @@ <% end %> - <% messages_sections = %w(newsletters emails_download) %> - <% messages_menu_active = messages_sections.include?(controller_name) %> -
  • > + <% newsletters_notifications_sections = %w(newsletters emails_download admin_notifications) %> + <% newsletters_menu_active = newsletters_notifications_sections.include?(controller_name) %> +
  • > - <%= t("admin.menu.emails") %> + <%= t("admin.menu.newsletters_and_notifications") %> -
  • diff --git a/app/views/admin/admin_notifications/_form.html.erb b/app/views/admin/admin_notifications/_form.html.erb new file mode 100644 index 000000000..4053bb66d --- /dev/null +++ b/app/views/admin/admin_notifications/_form.html.erb @@ -0,0 +1,13 @@ +<%= form_for [:admin, @admin_notification] do |f| %> + <%= render 'shared/errors', resource: @admin_notification %> + + <%= f.select :segment_recipient, options_for_select(user_segments_options, + @admin_notification[:segment_recipient]) %> + <%= f.text_field :title %> + <%= f.text_field :link %> + <%= f.text_area :body %> + +
    + <%= f.submit class: "button success" %> +
    +<% end %> diff --git a/app/views/admin/admin_notifications/edit.html.erb b/app/views/admin/admin_notifications/edit.html.erb new file mode 100644 index 000000000..cb14f0a0b --- /dev/null +++ b/app/views/admin/admin_notifications/edit.html.erb @@ -0,0 +1,4 @@ +<%= back_link_to %> +

    <%= t("admin.admin_notifications.edit.section_title") %>

    + +<%= render "form" %> diff --git a/app/views/admin/admin_notifications/index.html.erb b/app/views/admin/admin_notifications/index.html.erb new file mode 100644 index 000000000..d16ee476e --- /dev/null +++ b/app/views/admin/admin_notifications/index.html.erb @@ -0,0 +1,56 @@ +

    <%= t("admin.admin_notifications.index.section_title") %>

    +<%= link_to t("admin.admin_notifications.index.new_notification"), new_admin_admin_notification_path, + class: "button float-right" %> + +<% if @admin_notifications.any? %> + + + + + + + + + + + <% @admin_notifications.order(created_at: :desc).each do |admin_notification| %> + + + + + + + <% end %> + +
    <%= t("admin.admin_notifications.index.title") %><%= t("admin.admin_notifications.index.segment_recipient") %><%= t("admin.admin_notifications.index.sent") %><%= t("admin.admin_notifications.index.actions") %>
    + <%= admin_notification.title %> + + <%= segment_name(admin_notification.segment_recipient) %> + + <% if admin_notification.draft? %> + <%= t("admin.admin_notifications.index.draft") %> + <% else %> + <%= l admin_notification.sent_at.to_date %> + <% end %> + + <% if admin_notification.draft? %> + <%= link_to t("admin.admin_notifications.index.edit"), + edit_admin_admin_notification_path(admin_notification), + method: :get, class: "button hollow" %> + <%= link_to t("admin.admin_notifications.index.delete"), + admin_admin_notification_path(admin_notification), + method: :delete, class: "button hollow alert" %> + <%= link_to t("admin.admin_notifications.index.preview"), + admin_admin_notification_path(admin_notification), + class: "button" %> + <% else %> + <%= link_to t("admin.admin_notifications.index.view"), + admin_admin_notification_path(admin_notification), + class: "button" %> + <% end %> +
    +<% else %> +
    + <%= t("admin.admin_notifications.index.empty_notifications") %> +
    +<% end %> diff --git a/app/views/admin/admin_notifications/new.html.erb b/app/views/admin/admin_notifications/new.html.erb new file mode 100644 index 000000000..69bf2a80b --- /dev/null +++ b/app/views/admin/admin_notifications/new.html.erb @@ -0,0 +1,4 @@ +<%= back_link_to %> +

    <%= t("admin.admin_notifications.new.section_title") %>

    + +<%= render "form" %> diff --git a/app/views/admin/admin_notifications/show.html.erb b/app/views/admin/admin_notifications/show.html.erb new file mode 100644 index 000000000..92c0e37fc --- /dev/null +++ b/app/views/admin/admin_notifications/show.html.erb @@ -0,0 +1,77 @@ +<%= back_link_to admin_admin_notifications_path %> + +

    <%= t("admin.admin_notifications.show.section_title") %>

    + +
    +
    +
    +
    + <%= t("admin.admin_notifications.show.sent_at") %>
    + <% if @admin_notification.draft? %> + <%= t("admin.admin_notifications.index.draft") %> + <% else %> + <%= l(@admin_notification.sent_at.to_date) %> + <% end %> +
    +
    + <%= t("admin.admin_notifications.show.title") %>
    + <%= @admin_notification.title %> +
    +
    +
    + +
    + <%= t("admin.admin_notifications.show.body") %>
    + <%= @admin_notification.body %> +
    +
    + <%= t("admin.admin_notifications.show.link") %>
    + <%= @admin_notification.link %> +
    +
    +
    +
    + <%= t("admin.admin_notifications.show.segment_recipient") %>
    + <%= segment_name(@admin_notification.segment_recipient) %> + <% if @admin_notification.draft? %> + <%= t("admin.admin_notifications.show.will_get_notified", + n: @admin_notification.list_of_recipients_count) %> + <% else %> + <%= t("admin.admin_notifications.show.got_notified", + n: @admin_notification.recipients_count) %> + <% end %> +
    +
    +
    + +

    + <% if @admin_notification.draft? %> + <%= t("admin.admin_notifications.show.preview_guide") %> + <% else %> + <%= t("admin.admin_notifications.show.sent_guide") %> + <% end %> +

    +
    +
    +
      +
    • + <% locals = { notification: nil, + title: @admin_notification.title, + body: @admin_notification.body, + timestamp: Time.current } %> + <% link_text = render partial: '/notifications/notification_body', locals: locals %> + <%= link_to_if @admin_notification.link.present?, link_text, @admin_notification.link %> +
    • +
    +
    +
    +
    +<% if @admin_notification.draft? && @admin_notification.valid_segment_recipient? %> + <%= link_to t("admin.admin_notifications.show.send"), + deliver_admin_admin_notification_path(@admin_notification), + "data-alert": t("admin.admin_notifications.show.send_alert", + n: @admin_notification.list_of_recipients_count), + method: :post, + id: "js-send-admin_notification-alert", + class: "button success" %> +<% end %> diff --git a/app/views/admin/budget_groups/update.js.erb b/app/views/admin/budget_groups/update.js.erb index 5a5a244df..c4f9774ba 100644 --- a/app/views/admin/budget_groups/update.js.erb +++ b/app/views/admin/budget_groups/update.js.erb @@ -2,5 +2,6 @@ $("#group-form-<%= @group.id %>").html('<%= j render("admin/budgets/group_form", group: @group, budget: @group.budget, button_title: t("admin.budgets.form.submit"), id: "group-form-#{@group.id}", css_class: "group-toggle-#{@group.id}" ) %>'); <% else %> $("#group-name-<%= @group.id %>").html('<%= @group.name %>') + $("#max-heading-label-<%=@group.id%>").html('<%= j render("admin/budgets/max_headings_label", current: @group.max_votable_headings, max: @group.headings.count, group: @group) %>') $(".group-toggle-<%= @group.id %>").toggle() <% end %> diff --git a/app/views/admin/budget_investments/_advanced_filters.html.erb b/app/views/admin/budget_investments/_advanced_filters.html.erb deleted file mode 100644 index 017d8e63f..000000000 --- a/app/views/admin/budget_investments/_advanced_filters.html.erb +++ /dev/null @@ -1,45 +0,0 @@ -<%= link_to "#advanced_filters_content", - data: {toggle: "advanced_filters"}, - class: "advanced-filters float-right clear" do %> - <%= t("admin.budget_investments.index.advanced_filters") %> -<% end %> - -
    - <%= form_tag(admin_budget_budget_investments_path(budget: @budget, - filter: params[:filter], - sort_by: params[:sort_by], - max_per_heading: params[:max_per_heading], - advanced_filters: params[:advanced_filters], - page: 1), method: :get, remote: true, enforce_utf8: false) do %> -
    - - <%= check_box_tag "advanced_filters[]", "feasible" %> - <%= t("#{i18n_namespace}.filters.feasible") %> - - - - <%= check_box_tag "advanced_filters[]", "selected" %> - <%= t("#{i18n_namespace}.filters.selected") %> - - - - <%= check_box_tag "advanced_filters[]", "undecided" %> - <%= t("#{i18n_namespace}.filters.undecided") %> - - - - <%= check_box_tag "advanced_filters[]", "unfeasible" %> - <%= t("#{i18n_namespace}.filters.unfeasible") %> - - - - <%= t("#{i18n_namespace}.filters.max_per_heading") %> - <%= text_field_tag :max_per_heading %> - -
    - -
    - <%= submit_tag t("admin.budget_investments.index.buttons.filter"), class: "button expanded" %> -
    - <% end %> -
    diff --git a/app/views/admin/budget_investments/_investments.html.erb b/app/views/admin/budget_investments/_investments.html.erb index 17b0315b1..c5b7493c6 100644 --- a/app/views/admin/budget_investments/_investments.html.erb +++ b/app/views/admin/budget_investments/_investments.html.erb @@ -35,21 +35,21 @@ - - - - + + + + - - - - - + + + + + <% if params[:filter] == "selected" %> - + <% end %> diff --git a/app/views/admin/budget_investments/_search_form.html.erb b/app/views/admin/budget_investments/_search_form.html.erb index 11f99e221..0f3090c60 100644 --- a/app/views/admin/budget_investments/_search_form.html.erb +++ b/app/views/admin/budget_investments/_search_form.html.erb @@ -1,12 +1,61 @@ -
    - <%= form_for(Budget::Investment.new, url: admin_budget_budget_investments_path(budget: @budget), - method: :get, - remote: true) do |f| %> -
    - <%= text_field_tag :title_or_id, "", placeholder: t("admin.budget_investments.index.placeholder") %> -
    - <%= f.submit t("admin.budget_investments.index.buttons.search"), class: "button" %> +<% init_advanced_menu %> +<%= form_tag(admin_budget_budget_investments_path(budget: @budget), method: :get, enforce_utf8: false) do %> +
    +
    + <%= link_to "#advanced_filters_content", + data: {toggle: "advanced_filters"}, + class: "advanced-filters float-right clear" do %> + <%= t("admin.budget_investments.index.advanced_filters") %> + <% end %> +
    +
    +
    +
    + <% ["feasible", "selected", "undecided", "unfeasible"].each do |option| %> +
    + <%= check_box_tag "advanced_filters[]", option, params[:advanced_filters].index(option), id: "advanced_filters_#{option}" %> + <%= t("admin.budget_investments.index.filters.#{option}") %> +
    + <% end %> +
    + <%= text_field_tag :max_per_heading, params["max_per_heading"], placeholder: t("admin.budget_investments.index.filters.max_per_heading") %>
    - <% end %> -
    +
    +
    +
    + <%= select_tag :administrator_id, + options_for_select(admin_select_options, params[:administrator_id]), + { prompt: t("admin.budget_investments.index.administrator_filter_all"), + label: false} %> +
    +
    + <%= select_tag :valuator_or_group_id, + options_for_select(valuator_or_group_select_options, params[:valuator_or_group_id]), + { prompt: t("admin.budget_investments.index.valuator_filter_all"), + label: false} %> +
    +
    + <%= select_tag :heading_id, + options_for_select(budget_heading_select_options(@budget), params[:heading_id]), + { prompt: t("admin.budget_investments.index.heading_filter_all"), + label: false} %> +
    +
    + <%= select_tag :tag_name, + options_for_select(investment_tags_select_options(@budget), params[:tag_name]), + { prompt: t("admin.budget_investments.index.tags_filter_all"), + label: false} %> +
    +
    +
    +
    +
    + <%= text_field_tag :title_or_id, params["title_or_id"], placeholder: t("admin.budget_investments.index.placeholder") %> +
    +
    +
    + <%= submit_tag t("admin.budget_investments.index.buttons.filter"), class: "button expanded" %> +
    +
    +<% end %> diff --git a/app/views/admin/budget_investments/index.html.erb b/app/views/admin/budget_investments/index.html.erb index f2672f564..09b6e875b 100644 --- a/app/views/admin/budget_investments/index.html.erb +++ b/app/views/admin/budget_investments/index.html.erb @@ -8,42 +8,6 @@ <%= render "search_form" %> -<%= form_tag(admin_budget_budget_investments_path(budget: @budget), method: :get, enforce_utf8: false) do %> -
    - <%= select_tag :administrator_id, - options_for_select(admin_select_options, params[:administrator_id]), - { prompt: t("admin.budget_investments.index.administrator_filter_all"), - label: false, - class: "js-submit-on-change" } %> -
    - -
    - <%= select_tag :valuator_or_group_id, - options_for_select(valuator_or_group_select_options, params[:valuator_or_group_id]), - { prompt: t("admin.budget_investments.index.valuator_filter_all"), - label: false, - class: "js-submit-on-change" } %> -
    - -
    - <%= select_tag :heading_id, - options_for_select(budget_heading_select_options(@budget), params[:heading_id]), - { prompt: t("admin.budget_investments.index.heading_filter_all"), - label: false, - class: "js-submit-on-change" } %> -
    - -
    - <%= select_tag :tag_name, - options_for_select(investment_tags_select_options(@budget), params[:tag_name]), - { prompt: t("admin.budget_investments.index.tags_filter_all"), - label: false, - class: "js-submit-on-change" } %> -
    -<% end %> - -<%= render "advanced_filters", i18n_namespace: "admin.budget_investments.index" %> - <%= render "/shared/filter_subnav", i18n_namespace: "admin.budget_investments.index" %>
    diff --git a/app/views/admin/budgets/_group.html.erb b/app/views/admin/budgets/_group.html.erb index 360fd75a7..f38d34a9d 100644 --- a/app/views/admin/budgets/_group.html.erb +++ b/app/views/admin/budgets/_group.html.erb @@ -3,6 +3,9 @@
    <%= t("admin.budget_investments.index.table_id") %><%= t("admin.budget_investments.index.table_title") %><%= t("admin.budget_investments.index.table_supports") %><%= t("admin.budget_investments.index.table_admin") %><%= t("admin.budget_investments.index.list.id") %><%= t("admin.budget_investments.index.list.title") %><%= t("admin.budget_investments.index.list.supports") %><%= t("admin.budget_investments.index.list.admin") %> - <%= t("admin.budget_investments.index.table_valuation_group") %> - <%= t("admin.budget_investments.index.table_valuator") %> + <%= t("admin.budget_investments.index.list.valuation_group") %> + <%= t("admin.budget_investments.index.list.valuator") %> <%= t("admin.budget_investments.index.table_geozone") %><%= t("admin.budget_investments.index.table_feasibility") %><%= t("admin.budget_investments.index.table_valuation_finished") %><%= t("admin.budget_investments.index.table_evaluation") %><%= t("admin.budget_investments.index.table_selection") %><%= t("admin.budget_investments.index.list.geozone") %><%= t("admin.budget_investments.index.list.feasibility") %><%= t("admin.budget_investments.index.list.valuation_finished") %><%= t("admin.budget_investments.index.list.visible_to_valuators") %><%= t("admin.budget_investments.index.list.selected") %><%= t("admin.budget_investments.index.table_incompatible") %><%= t("admin.budget_investments.index.list.incompatible") %>
    <%= content_tag(:span, group.name, class:"group-toggle-#{group.id}", id:"group-name-#{group.id}") %> + + <%= content_tag(:span, (render 'admin/budgets/max_headings_label', current: group.max_votable_headings, max: group.headings.count, group: group if group.max_votable_headings), class:"max-headings-label group-toggle-#{group.id}", id:"max-heading-label-#{group.id}") %> + <%= render 'admin/budgets/group_form', budget: @budget, group: group, id: "group-form-#{group.id}", button_title: t("admin.budgets.form.submit"), css_class: "group-toggle-#{group.id}" %> <%= link_to t("admin.budgets.form.edit_group"), "#", class: "button float-right js-toggle-link hollow", data: { "toggle-selector" => ".group-toggle-#{group.id}" } %> <%= link_to t("admin.budgets.form.add_heading"), "#", class: "button float-right js-toggle-link", data: { "toggle-selector" => "#group-#{group.id}-new-heading-form" } %> diff --git a/app/views/admin/budgets/_max_headings_label.html.erb b/app/views/admin/budgets/_max_headings_label.html.erb new file mode 100644 index 000000000..61bf98dc7 --- /dev/null +++ b/app/views/admin/budgets/_max_headings_label.html.erb @@ -0,0 +1,5 @@ +<%= t("admin.budgets.form.max_votable_headings")%> +<%= content_tag(:strong, + t('admin.budgets.form.current_of_max_headings', current: current, max: max ), + class:"current-of-max-headings") %> + diff --git a/app/views/layouts/_header.html.erb b/app/views/layouts/_header.html.erb index c2c3aeb0b..c127f62c2 100644 --- a/app/views/layouts/_header.html.erb +++ b/app/views/layouts/_header.html.erb @@ -10,68 +10,47 @@
    -
    - -
    <%= t("application.menu")%>
    -
    -
    - -
    -
    -
    - + + + <%= t("application.menu")%> + + +
    + <%= link_to root_path, accesskey: "0" do %> + <%= image_tag(image_path_for('logo_header.png'), class: 'float-left', alt: t("layouts.header.logo")) %> + <% end %>
    -
    - -
    +
    +
    + -
    -
    - <% if with_subnavigation %> -