Create tracker rol

This commit is contained in:
German Galia
2019-06-03 09:29:52 +02:00
committed by lalo
parent 800a701a40
commit 9ce524e1f3
75 changed files with 1586 additions and 271 deletions

View File

@@ -1,8 +0,0 @@
class Admin::BudgetInvestmentMilestonesController < Admin::MilestonesController
private
def milestoneable
Budget::Investment.find(params[:budget_investment_id])
end
end

View File

@@ -1,8 +0,0 @@
class Admin::BudgetInvestmentProgressBarsController < Admin::ProgressBarsController
private
def progressable
Budget::Investment.find(params[:budget_investment_id])
end
end

View File

@@ -37,6 +37,7 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
load_admins load_admins
load_valuators load_valuators
load_valuator_groups load_valuator_groups
load_trackers
load_tags load_tags
end end
@@ -50,6 +51,7 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
load_admins load_admins
load_valuators load_valuators
load_valuator_groups load_valuator_groups
load_trackers
load_tags load_tags
render :edit render :edit
end end
@@ -88,7 +90,7 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
params.require(:budget_investment) params.require(:budget_investment)
.permit(:title, :description, :external_url, :heading_id, :administrator_id, :tag_list, .permit(:title, :description, :external_url, :heading_id, :administrator_id, :tag_list,
:valuation_tag_list, :incompatible, :visible_to_valuators, :selected, :valuation_tag_list, :incompatible, :visible_to_valuators, :selected,
:milestone_tag_list, valuator_ids: [], valuator_group_ids: []) :milestone_tag_list, tracker_ids: [], valuator_ids: [], valuator_group_ids: [])
end end
def load_budget def load_budget
@@ -103,6 +105,10 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
@admins = Administrator.includes(:user).all @admins = Administrator.includes(:user).all
end end
def load_trackers
@trackers = Tracker.includes(:user).all.order(description: :asc).order("users.email ASC")
end
def load_valuators def load_valuators
@valuators = Valuator.includes(:user).all.order(description: :asc).order("users.email ASC") @valuators = Valuator.includes(:user).all.order(description: :asc).order("users.email ASC")
end end

View File

@@ -1,4 +1,4 @@
class Admin::Legislation::MilestonesController < Admin::MilestonesController class Admin::Legislation::MilestonesController < Tracking::MilestonesController
include FeatureFlags include FeatureFlags
feature_flag :legislation feature_flag :legislation
@@ -11,8 +11,4 @@ class Admin::Legislation::MilestonesController < Admin::MilestonesController
def milestoneable def milestoneable
::Legislation::Process.find(params[:process_id]) ::Legislation::Process.find(params[:process_id])
end end
def milestoneable_path
admin_legislation_process_milestones_path(milestoneable)
end
end end

View File

@@ -1,72 +0,0 @@
class Admin::MilestonesController < Admin::BaseController
include Translatable
include ImageAttributes
before_action :load_milestoneable, only: [:index, :new, :create, :edit, :update, :destroy]
before_action :load_milestone, only: [:edit, :update, :destroy]
before_action :load_statuses, only: [:index, :new, :create, :edit, :update]
helper_method :milestoneable_path
def index
end
def new
@milestone = @milestoneable.milestones.new
end
def create
@milestone = @milestoneable.milestones.new(milestone_params)
if @milestone.save
redirect_to milestoneable_path, notice: t("admin.milestones.create.notice")
else
render :new
end
end
def edit
end
def update
if @milestone.update(milestone_params)
redirect_to milestoneable_path, notice: t("admin.milestones.update.notice")
else
render :edit
end
end
def destroy
@milestone.destroy
redirect_to milestoneable_path, notice: t("admin.milestones.delete.notice")
end
private
def milestone_params
documents_attributes = [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy]
attributes = [:publication_date, :status_id,
translation_params(Milestone),
image_attributes: image_attributes, documents_attributes: documents_attributes]
params.require(:milestone).permit(*attributes)
end
def load_milestoneable
@milestoneable = milestoneable
end
def milestoneable
raise "Implement in subclass"
end
def load_milestone
@milestone = @milestoneable.milestones.find(params[:id])
end
def load_statuses
@statuses = Milestone::Status.all
end
def milestoneable_path
polymorphic_path([:admin, *resource_hierarchy_for(@milestone.milestoneable)])
end
end

View File

@@ -1,8 +0,0 @@
class Admin::ProposalMilestonesController < Admin::MilestonesController
private
def milestoneable
Proposal.find(params[:proposal_id])
end
end

View File

@@ -0,0 +1,56 @@
class Admin::TrackersController < Admin::BaseController
load_and_authorize_resource
before_action :set_tracker, only: [:show, :edit, :update, :destroy]
def show
@tracker = Tracker.find(params[:id])
end
def index
@trackers = @trackers.page(params[:page])
end
def search
@users = User.search(params[:name_or_email])
.includes(:tracker)
.page(params[:page])
.for_render
end
def create
@tracker = Tracker.new(tracker_params)
@tracker.save
redirect_to admin_trackers_path
end
def edit
@tracker = Tracker.find(params[:id])
end
def update
@tracker = Tracker.find(params[:id])
if @tracker.update(tracker_params)
notice = t("admin.trackers.form.updated")
redirect_to [:admin, @tracker], notice: notice
else
render :edit
end
end
def destroy
@tracker.destroy
redirect_to admin_trackers_path
end
private
def set_tracker
@tracker = Tracker.find(params[:id])
end
def tracker_params
params[:tracker][:description] = nil if params[:tracker][:description].blank?
params.require(:tracker).permit(:user_id, :description, :budget_investment_count)
end
end

View File

@@ -0,0 +1,15 @@
class Tracking::BaseController < ApplicationController
layout "admin"
before_action :authenticate_user!
before_action :verify_tracker
skip_authorization_check
private
def verify_tracker
raise CanCan::AccessDenied unless current_user.try(:tracker?) || current_user.try(:administrator?)
end
end

View File

@@ -0,0 +1,8 @@
class Tracking::BudgetInvestmentMilestonesController < Tracking::MilestonesController
private
def milestoneable
Budget::Investment.find(params[:budget_investment_id])
end
end

View File

@@ -0,0 +1,17 @@
class Tracking::BudgetInvestmentProgressBarsController < Tracking::ProgressBarsController
before_action :restrict_access_to_assigned_items
private
def progressable
Budget::Investment.find(params[:budget_investment_id])
end
def restrict_access_to_assigned_items
return if current_user.administrator? ||
Budget::TrackerAssignment.exists?(investment_id: params[:budget_investment_id],
tracker_id: current_user.tracker.id)
raise ActionController::RoutingError.new("Not Found")
end
end

View File

@@ -0,0 +1,83 @@
class Tracking::BudgetInvestmentsController < Tracking::BaseController
include FeatureFlags
include CommentableActions
feature_flag :budgets
before_action :restrict_access_to_assigned_items, only: [:show, :edit]
before_action :load_budget
before_action :load_investment, only: [:show, :edit]
has_orders %w{oldest}, only: [:show, :edit]
load_and_authorize_resource :investment, class: "Budget::Investment"
def index
@heading_filters = heading_filters
@investments = if current_user.tracker? && @budget.present?
current_user.tracker.investments_by_heading(heading_params, @budget)
.page(params[:page])
else
Budget::Investment.none.page(params[:page])
end
end
def show
end
def edit
end
private
def resource_model
Budget::Investment
end
def resource_name
resource_model.parameterize(separator: "_")
end
def load_budget
@budget = Budget.find(params[:budget_id])
end
def load_investment
@investment = @budget.investments.find params[:id]
end
def heading_filters
investments = @budget.investments.by_tracker(current_user.tracker.try(:id))
.distinct
investment_headings = Budget::Heading.where(id: investments.pluck(:heading_id).uniq)
.order(name: :asc)
all_headings_filter = [
{
name: t("valuation.budget_investments.index.headings_filter_all"),
id: nil,
count: investments.size
}
]
filters = investment_headings.inject(all_headings_filter) do |filters, heading|
filters << {
name: heading.name,
id: heading.id,
count: investments.select{|i| i.heading_id == heading.id}.size
}
end
filters.uniq
end
def restrict_access_to_assigned_items
return if current_user.administrator? ||
Budget::TrackerAssignment.exists?(investment_id: params[:id],
tracker_id: current_user.tracker.id)
raise ActionController::RoutingError.new("Not Found")
end
def heading_params
params.permit(:heading_id)
end
end

View File

@@ -0,0 +1,14 @@
class Tracking::BudgetsController < Tracking::BaseController
include FeatureFlags
feature_flag :budgets
load_and_authorize_resource
def index
@budget = current_budget
if @budget.present?
@investments = @budget.investments
.by_tracker(current_user.tracker)
end
end
end

View File

@@ -0,0 +1,18 @@
class Tracking::Legislation::MilestonesController < Tracking::MilestonesController
include FeatureFlags
feature_flag :legislation
def index
@process = milestoneable
end
private
def milestoneable
::Legislation::Process.find(params[:process_id])
end
def milestoneable_path
admin_legislation_process_milestones_path(milestoneable)
end
end

View File

@@ -1,4 +1,4 @@
class Admin::Legislation::ProgressBarsController < Admin::ProgressBarsController class Tracking::Legislation::ProgressBarsController < Tracking::ProgressBarsController
include FeatureFlags include FeatureFlags
feature_flag :legislation feature_flag :legislation

View File

@@ -0,0 +1,73 @@
class Tracking::MilestonesController < Tracking::BaseController
include Translatable
include ImageAttributes
before_action :load_milestoneable, only: [:index, :new, :create, :edit, :update, :destroy]
before_action :load_milestone, only: [:edit, :update, :destroy]
before_action :load_statuses, only: [:index, :new, :create, :edit, :update]
helper_method :milestoneable_path
def index
end
def new
@milestone = @milestoneable.milestones.new
end
def create
@milestone = @milestoneable.milestones.new(milestone_params)
if @milestone.save
redirect_to milestoneable_path, notice: t("tracking.milestones.create.notice")
else
render :new
end
end
def edit
end
def update
if @milestone.update(milestone_params)
redirect_to milestoneable_path, notice: t("tracking.milestones.update.notice")
else
render :edit
end
end
def destroy
@milestone.destroy
redirect_to milestoneable_path, notice: t("tracking.milestones.delete.notice")
end
private
def milestone_params
documents_attributes = [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy]
attributes = [:publication_date, :status_id,
translation_params(Milestone),
image_attributes: image_attributes, documents_attributes: documents_attributes]
params.require(:milestone).permit(*attributes)
end
def load_milestoneable
@milestoneable = milestoneable
end
def milestoneable
raise "Implement in subclass"
end
def load_milestone
@milestone = @milestoneable.milestones.find(params[:id])
end
def load_statuses
@statuses = Milestone::Status.all
end
def milestoneable_path
polymorphic_path([current_user.administrator? ? :admin : :tracking,
*resource_hierarchy_for(@milestone.milestoneable)])
end
end

View File

@@ -1,4 +1,4 @@
class Admin::ProgressBarsController < Admin::BaseController class Tracking::ProgressBarsController < Tracking::BaseController
include Translatable include Translatable
before_action :load_progressable before_action :load_progressable
@@ -15,7 +15,7 @@ class Admin::ProgressBarsController < Admin::BaseController
def create def create
@progress_bar = @progressable.progress_bars.new(progress_bar_params) @progress_bar = @progressable.progress_bars.new(progress_bar_params)
if @progress_bar.save if @progress_bar.save
redirect_to progress_bars_index, notice: t("admin.progress_bars.create.notice") redirect_to progress_bars_index, notice: t("tracking.progress_bars.create.notice")
else else
render :new render :new
end end
@@ -26,7 +26,7 @@ class Admin::ProgressBarsController < Admin::BaseController
def update def update
if @progress_bar.update(progress_bar_params) if @progress_bar.update(progress_bar_params)
redirect_to progress_bars_index, notice: t("admin.progress_bars.update.notice") redirect_to progress_bars_index, notice: t("tracking.progress_bars.update.notice")
else else
render :edit render :edit
end end
@@ -34,7 +34,7 @@ class Admin::ProgressBarsController < Admin::BaseController
def destroy def destroy
@progress_bar.destroy @progress_bar.destroy
redirect_to progress_bars_index, notice: t("admin.progress_bars.delete.notice") redirect_to progress_bars_index, notice: t("tracking.progress_bars.delete.notice")
end end
private private
@@ -64,6 +64,6 @@ class Admin::ProgressBarsController < Admin::BaseController
end end
def progress_bars_index def progress_bars_index
polymorphic_path([:admin, *resource_hierarchy_for(@progressable), ProgressBar.new]) polymorphic_path([:tracking, *resource_hierarchy_for(@progressable), ProgressBar.new])
end end
end end

View File

@@ -0,0 +1,8 @@
class Tracking::ProposalMilestonesController < Tracking::MilestonesController
private
def milestoneable
Proposal.find(params[:proposal_id])
end
end

View File

@@ -1,4 +1,4 @@
class Admin::ProposalProgressBarsController < Admin::ProgressBarsController class Tracking::ProposalProgressBarsController < Tracking::ProgressBarsController
private private
def progressable def progressable

View File

@@ -0,0 +1,21 @@
module TrackersHelper
def tracker_label(tracker)
truncate([tracker.name, tracker.email, tracker.description].compact.join(" - "), length: 100)
end
def tracker_back_path(progressable)
if progressable.class.to_s == "Legislation::Process"
admin_legislation_process_milestones_path(progressable)
else
polymorphic_path([tracker_namespace, *resource_hierarchy_for(progressable)])
end
end
private
def tracker_namespace
current_user.administrator? ? :admin : :tracking
end
end

View File

@@ -56,11 +56,13 @@ module UsersHelper
current_user && current_user.poll_officer? current_user && current_user.poll_officer?
end end
def show_admin_menu?(user = nil) def current_tracker?
unless namespace == "officing" current_user && current_user.tracker?
current_administrator? || current_moderator? || current_valuator? || current_manager? ||
(user && user.administrator?) || current_poll_officer?
end end
def show_admin_menu?(user = nil)
current_administrator? || current_moderator? || current_valuator? || current_manager? ||
current_tracker? || (user && user.administrator?) || current_poll_officer?
end end
def interests_title_text(user) def interests_title_text(user)

View File

@@ -99,6 +99,7 @@ module Abilities
can [:create, :destroy], DirectUpload can [:create, :destroy], DirectUpload
can [:deliver], Newsletter, hidden_at: nil can [:deliver], Newsletter, hidden_at: nil
can [:manage], ::Tracker
can [:manage], Dashboard::AdministratorTask can [:manage], Dashboard::AdministratorTask
can [:edit, :update], DownloadSetting can [:edit, :update], DownloadSetting

View File

@@ -0,0 +1,14 @@
module Abilities
class Tracker
include CanCan::Ability
def initialize(user)
tracker = user.tracker
can :index, Budget
can [:index, :show, :edit], Budget::Investment
can :manage, Milestone
can :manage, ProgressBar
end
end
end

View File

@@ -8,6 +8,7 @@ class Ability
if user # logged-in users if user # logged-in users
merge Abilities::Valuator.new(user) if user.valuator? merge Abilities::Valuator.new(user) if user.valuator?
merge Abilities::Tracker.new(user) if user.tracker?
if user.administrator? if user.administrator?
merge Abilities::Administrator.new(user) merge Abilities::Administrator.new(user)

View File

@@ -26,6 +26,8 @@ class Budget
include Milestoneable include Milestoneable
include Randomizable include Randomizable
extend DownloadSettings::BudgetInvestmentCsv
belongs_to :author, -> { with_hidden }, class_name: "User", foreign_key: "author_id" belongs_to :author, -> { with_hidden }, class_name: "User", foreign_key: "author_id"
belongs_to :heading belongs_to :heading
belongs_to :group belongs_to :group
@@ -41,7 +43,9 @@ class Budget
has_many :comments, -> {where(valuation: false)}, as: :commentable, class_name: "Comment" has_many :comments, -> {where(valuation: false)}, as: :commentable, class_name: "Comment"
has_many :valuations, -> {where(valuation: true)}, as: :commentable, class_name: "Comment" has_many :valuations, -> {where(valuation: true)}, as: :commentable, class_name: "Comment"
extend DownloadSettings::BudgetInvestmentCsv has_many :tracker_assignments, dependent: :destroy
has_many :trackers, through: :tracker_assignments
delegate :name, :email, to: :author, prefix: true delegate :name, :email, to: :author, prefix: true
validates :title, presence: true validates :title, presence: true
@@ -93,6 +97,7 @@ class Budget
scope :by_admin, ->(admin_id) { where(administrator_id: admin_id) } scope :by_admin, ->(admin_id) { where(administrator_id: admin_id) }
scope :by_tag, ->(tag_name) { tagged_with(tag_name) } scope :by_tag, ->(tag_name) { tagged_with(tag_name) }
scope :by_valuator, ->(valuator_id) { where("budget_valuator_assignments.valuator_id = ?", valuator_id).joins(:valuator_assignments) } scope :by_valuator, ->(valuator_id) { where("budget_valuator_assignments.valuator_id = ?", valuator_id).joins(:valuator_assignments) }
scope :by_tracker, ->(tracker_id) { where("budget_tracker_assignments.tracker_id = ?", tracker_id).joins(:tracker_assignments) }
scope :by_valuator_group, ->(valuator_group_id) { where("budget_valuator_group_assignments.valuator_group_id = ?", valuator_group_id).joins(:valuator_group_assignments) } scope :by_valuator_group, ->(valuator_group_id) { where("budget_valuator_group_assignments.valuator_group_id = ?", valuator_group_id).joins(:valuator_group_assignments) }
scope :for_render, -> { includes(:heading) } scope :for_render, -> { includes(:heading) }

View File

@@ -0,0 +1,6 @@
class Budget
class TrackerAssignment < ApplicationRecord
belongs_to :tracker, counter_cache: :budget_investment_count
belongs_to :investment, counter_cache: true
end
end

30
app/models/tracker.rb Normal file
View File

@@ -0,0 +1,30 @@
class Tracker < ApplicationRecord
belongs_to :user, touch: true
delegate :name, :email, :name_and_email, to: :user
has_many :tracker_assignments, dependent: :destroy, class_name: "Budget::TrackerAssignment"
has_many :investments, through: :tracker_assignments, class_name: "Budget::Investment"
validates :user_id, presence: true, uniqueness: true
def description_or_email
description.present? ? description : email
end
def description_or_name
description.present? ? description : name
end
def assigned_investment_ids
investment_ids
end
def investments_by_heading(params, budget)
results = investments.by_budget(budget)
if params[:heading_id].present?
results = results.by_heading(params[:heading_id])
end
results
end
end

View File

@@ -15,6 +15,7 @@ class User < ApplicationRecord
has_one :administrator has_one :administrator
has_one :moderator has_one :moderator
has_one :valuator has_one :valuator
has_one :tracker
has_one :manager has_one :manager
has_one :poll_officer, class_name: "Poll::Officer" has_one :poll_officer, class_name: "Poll::Officer"
has_one :organization has_one :organization
@@ -151,6 +152,10 @@ class User < ApplicationRecord
valuator.present? valuator.present?
end end
def tracker?
tracker.present?
end
def manager? def manager?
manager.present? manager.present?
end end

View File

@@ -212,6 +212,10 @@
<%= link_to t("admin.menu.valuators"), admin_valuators_path %> <%= link_to t("admin.menu.valuators"), admin_valuators_path %>
</li> </li>
<li <%= "class=is-active" if controller_name == "trackers" %>>
<%= link_to t("admin.menu.trackers"), admin_trackers_path %>
</li>
<li <%= "class=is-active" if controller_name == "managers" %>> <li <%= "class=is-active" if controller_name == "managers" %>>
<%= link_to t("admin.menu.managers"), admin_managers_path %> <%= link_to t("admin.menu.managers"), admin_managers_path %>
</li> </li>

View File

@@ -84,6 +84,16 @@
<% end %> <% end %>
</ul> </ul>
</div> </div>
<div class="small-12 column">
<hr>
<%= f.label :tracker_ids, t("admin.budget_investments.edit.assigned_trackers") %>
<ul>
<%= f.collection_check_boxes :tracker_ids, @trackers, :id, :email do |b| %>
<li><%= b.label(title: tracker_label(b.object)) { b.check_box + truncate(b.object.description_or_email, length: 60) } %></li>
<% end %>
</ul>
</div>
</div> </div>
<div class="row expanded margin-top"> <div class="row expanded margin-top">

View File

@@ -50,6 +50,15 @@
<% end %> <% end %>
</p> </p>
<p id="assigned_trackers">
<strong><%= t("admin.budget_investments.show.assigned_trackers") %>:</strong>
<% if @investment.trackers.any? %>
<%= @investment.trackers.collect(&:name_and_email).join(", ") %>
<% else %>
<%= t("admin.budget_investments.show.undefined") %>
<% end %>
</p>
<p> <p>
<%= link_to t("admin.budget_investments.show.edit_classification"), <%= link_to t("admin.budget_investments.show.edit_classification"),
edit_admin_budget_budget_investment_path(@budget, @investment, edit_admin_budget_budget_investment_path(@budget, @investment,
@@ -66,6 +75,6 @@
<%= render "valuation/budget_investments/valuation_comments" %> <%= render "valuation/budget_investments/valuation_comments" %>
<%= render "admin/milestones/milestones", milestoneable: @investment %>
<%= render "admin/change_logs/change_log", logs: @logs %> <%= render "admin/change_logs/change_log", logs: @logs %>
<%= render "tracking/milestones/milestones", milestoneable: @investment %>

View File

@@ -9,4 +9,4 @@
<%= render "admin/legislation/processes/subnav", process: @process, active: "milestones" %> <%= render "admin/legislation/processes/subnav", process: @process, active: "milestones" %>
<%= render "summary_form", process: @process %> <%= render "summary_form", process: @process %>
<%= render "admin/milestones/milestones", milestoneable: @process %> <%= render "tracking/milestones/milestones", milestoneable: @process %>

View File

@@ -1,15 +0,0 @@
<% if @progress_bar.primary? %>
<% bar_title = t("admin.progress_bars.edit.title.primary") %>
<% else %>
<% bar_title = t("admin.progress_bars.edit.title.secondary", title: @progress_bar.title) %>
<% end %>
<% provide :title do %>
<%= "#{t("admin.header.title")} - #{bar_title}" %>
<% end %>
<%= back_link_to progress_bars_index %>
<h2><%= bar_title %></h2>
<%= render "form" %>

View File

@@ -1,9 +0,0 @@
<% provide :title do %>
<%= "#{t("admin.header.title")} - #{t("admin.progress_bars.index.title")}" %>
<% end %>
<%= back_link_to polymorphic_path([:admin, *resource_hierarchy_for(@progressable)]) %>
<div class="clear"></div>
<%= render "admin/progress_bars/progress_bars", progressable: @progressable %>

View File

@@ -1,9 +0,0 @@
<% provide :title do %>
<%= "#{t("admin.header.title")} - #{t("admin.progress_bars.new.creating")}" %>
<% end %>
<%= back_link_to progress_bars_index %>
<h2><%= t("admin.progress_bars.new.creating") %></h2>
<%= render "form" %>

View File

@@ -32,4 +32,4 @@
<hr> <hr>
</div> </div>
<%= render "admin/milestones/milestones", milestoneable: @proposal %> <%= render "tracking/milestones/milestones", milestoneable: @proposal %>

View File

@@ -0,0 +1,32 @@
<%= form_for(tracker) do |f| %>
<% if tracker.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(tracker.errors.count, "error") %> prohibited this tracker from being saved:</h2>
<ul>
<% tracker.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :user_id %>
<%= f.text_field :user_id %>
</div>
<div class="field">
<%= f.label :description %>
<%= f.text_field :description %>
</div>
<div class="field">
<%= f.label :budget_investment_count %>
<%= f.number_field :budget_investment_count %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>

View File

@@ -0,0 +1,16 @@
<%= back_link_to admin_trackers_path %>
<h2><%= t("admin.trackers.form.edit_title") %></h2>
<div class="callout highlight">
<strong><%= @tracker.name %></strong><br>
<%= @tracker.email %>
</div>
<div class="margin-top">
<%= form_for [:admin, @tracker] do |f| %>
<%= f.text_field :description %>
<%= f.submit t("admin.trackers.form.update"), class: "button success" %>
<% end %>
</div>

View File

@@ -0,0 +1,48 @@
<h2 class="inline-block"><%= t("admin.trackers.index.title") %></h2>
<%= render "admin/shared/user_search", url: search_admin_trackers_path %>
<div id="trackers">
<% if @trackers.any? %>
<h3 class="margin"><%= page_entries_info @trackers %></h3>
<table>
<thead>
<th scope="col"><%= t("admin.trackers.index.name") %></th>
<th scope="col"><%= t("admin.trackers.index.email") %></th>
<th scope="col"><%= t("admin.valuators.index.description") %></th>
<th scope="col" class="small-3"><%= t("admin.actions.actions") %></th>
</thead>
<tbody>
<% @trackers.each do |tracker| %>
<tr>
<td><%= link_to tracker.name, admin_tracker_path(tracker) %></td>
<td><%= tracker.email %></td>
<td>
<% if tracker.description.present? %>
<%= tracker.description %>
<% else %>
<%= t("admin.trackers.index.no_description") %>
<% end %>
</td>
<td>
<%= link_to t("admin.actions.edit"),
edit_admin_tracker_path(tracker),
class: "button hollow" %>
<%= link_to t("admin.valuators.valuator.delete"),
admin_tracker_path(tracker),
method: :delete,
class: "button hollow alert" %>
</td>
</tr>
<% end %>
</tbody>
</table>
<%= paginate @trackers %>
<% else %>
<div class="callout primary">
<%= t("admin.trackers.index.no_trackers") %>
</div>
<% end %>
</div>

View File

@@ -0,0 +1,58 @@
<h2><%= t("admin.trackers.search.title") %></h2>
<%= render "admin/shared/user_search", url: search_admin_trackers_path %>
<div id="trackers">
<% if @users.any? %>
<h3 class="margin"><%= page_entries_info @users %></h3>
<table>
<thead>
<th scope="col"><%= t("admin.trackers.index.name") %></th>
<th scope="col"><%= t("admin.trackers.index.email") %></th>
<th scope="col"><%= t("admin.trackers.index.description") %></th>
<th scope="col"><%= t("admin.shared.actions") %></th>
</thead>
<tbody>
<% @users.each do |user| %>
<tr>
<td><%= user.name %></td>
<td><%= user.email %></td>
<td>
<% if user.tracker %>
<% if user.tracker.description.present? %>
<%= user.tracker.description %>
<% else %>
<%= t("admin.trackers.index.no_description") %>
<% end %>
<% else %>
<%= t("admin.trackers.index.no_description") %>
<% end %>
<td>
<% if user.tracker? %>
<%= link_to t("admin.actions.edit"),
edit_admin_tracker_path(user.tracker),
class: "button hollow" %>
<%= link_to t("admin.valuators.valuator.delete"),
admin_tracker_path(user.tracker),
method: :delete,
class: "button hollow alert" %>
<% else %>
<%= form_for Tracker.new(user: user), url: admin_trackers_path do |f| %>
<%= f.hidden_field :user_id %>
<%= f.submit t("admin.trackers.tracker.add"),
class: "button success expanded" %>
<% end %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% else %>
<div class="callout alert margin">
<%= t("admin.shared.no_search_results") %>
</div>
<% end %>
</div>

View File

@@ -0,0 +1,22 @@
<%= back_link_to admin_trackers_path %>
<%= link_to t("admin.actions.edit"), edit_admin_tracker_path(@tracker), class: "button hollow float-right" %>
<div class="clear"></div>
<h2><%= @tracker.name %></h2>
<div class="callout highlight">
<p>
<strong><%= t("admin.trackers.show.email") %></strong><br>
<%= @tracker.email %>
</p>
<p>
<strong><%= t("admin.trackers.show.description") %></strong><br>
<% if @tracker.description.present? %>
<%= @tracker.description %>
<% else %>
<%= t("admin.trackers.show.no_description") %>
<% end %>
</p>
</div>

View File

@@ -21,6 +21,13 @@
</li> </li>
<% end %> <% end %>
<% if (feature?(:budgets)) &&
(current_user.administrator? || current_user.tracker?) %>
<li>
<%= link_to t("layouts.header.tracking"), tracking_root_path %>
</li>
<% end %>
<% if current_user.administrator? || current_user.manager? %> <% if current_user.administrator? || current_user.manager? %>
<li> <li>
<%= link_to t("layouts.header.management"), management_sign_in_path %> <%= link_to t("layouts.header.management"), management_sign_in_path %>

View File

@@ -0,0 +1,17 @@
<nav class="admin-sidebar">
<ul id="valuation_menu">
<li>
<%= link_to t("tracking.menu.title"), tracking_root_path %>
</li>
<% if feature?(:budgets) %>
<li <%= "class=is-active" if controller_name == "budget_investments" %>>
<%= link_to tracking_budgets_path do %>
<span class="icon-budget"></span>
<%= t("tracking.menu.budgets") %>
<% end %>
</li>
<% end %>
</ul>
</nav>

View File

@@ -0,0 +1,12 @@
<%= link_to tracking_budget_budget_investment_path(@budget, @investment), class: "back" do %>
<span class="icon-angle-left"></span>
<%= "#{t("tracking.budget_investments.show.title")} #{@investment.id}"%>
<% end %>
<br>
<h1><%= @investment.title %></h1>
<%= safe_html_with_links @investment.description %>
<%= render "tracking/milestones/milestones", milestoneable: @investment %>

View File

@@ -0,0 +1,58 @@
<h2>
<%= @budget.name %> - <%= t("tracking.budget_investments.index.title") %>
<small><%= t("tracking.budget_investments.index.assigned_to", tracker: current_user.name) %></small>
</h2>
<div class="row expanded collapse margin-bottom">
<% @heading_filters.each_slice(8) do |slice| %>
<div class="small-12 medium-4 column select-heading">
<% slice.each do |filter| %>
<%= link_to tracking_budget_budget_investments_path(budget_id: @budget.id, heading_id: filter[:id]),
class: "#{"is-active" if params[:heading_id].to_s == filter[:id].to_s}" do %>
<%= filter[:name] %> (<%= filter[:count] %>)
<% end %>
<% end %>
</div>
<% end %>
</div>
<% if @investments.any? %>
<h3><%= page_entries_info @investments %></h3>
<table>
<thead>
<tr>
<th><%= t("tracking.budget_investments.index.table_id") %></th>
<th><%= t("tracking.budget_investments.index.table_title") %></th>
<th><%= t("tracking.budget_investments.index.table_heading_name") %></th>
<th><%= t("tracking.budget_investments.index.table_actions") %></th>
</tr>
</thead>
<tbody>
<% @investments.each do |investment| %>
<tr id="<%= dom_id(investment) %>" class="budget_investment">
<td>
<strong><%= investment.id %></strong>
</td>
<td>
<%= link_to investment.title, tracking_budget_budget_investment_path(@budget, investment) %>
</td>
<td class="small">
<%= investment.heading.name %>
</td>
<td class="small">
<%= link_to t("tracking.budget_investments.index.edit"),
edit_tracking_budget_budget_investment_path(@budget, investment),
class: "button hollow expanded" %>
</td>
</tr>
<% end %>
</tbody>
</table>
<%= paginate @investments %>
<% else %>
<div class="callout primary">
<%= t("tracking.budget_investments.index.no_investments") %>
</div>
<% end %>

View File

@@ -0,0 +1,47 @@
<%= back_link_to tracking_budget_budget_investments_path %>
<h2><%= t("tracking.budget_investments.show.title") %> <%= @investment.id %> </h2>
<h1><%= @investment.title %></h1>
<%= safe_html_with_links @investment.description %>
<% if @investment.external_url.present? %>
<p><%= text_with_links @investment.external_url %></p>
<% end %>
<h2><%= t("tracking.budget_investments.show.info") %></h2>
<p><strong><%= t("tracking.budget_investments.show.by") %>:</strong>
<%= @investment.author.name %>
</p>
<p><strong><%= t("tracking.budget_investments.show.heading") %>:</strong>
<%= @investment.heading.name %>
</p>
<p><strong><%= t("tracking.budget_investments.show.sent") %>:</strong>
<%= l @investment.created_at, format: :datetime %>
</p>
<h2><%= t("tracking.budget_investments.show.responsibles") %></h2>
<p><strong><%= t("tracking.budget_investments.show.assigned_admin") %>:</strong>
<% if @investment.administrator.present? %>
<%= @investment.administrator.name_and_email %>
<% else %>
<%= t("tracking.budget_investments.show.undefined") %>
<% end %>
</p>
<p><strong><%= t("trackers.budget_investments.show.assigned_trackers") %>:</strong></p>
<div id="assigned_trackers">
<ul>
<% @investment.trackers.each do |tracker| %>
<li><%= tracker.name_and_email %></li>
<% end %>
<% if @investment.trackers.empty? %>
<li><%= t("tracking.budget_investments.show.undefined") %></li>
<% end %>
</ul>
</div>

View File

@@ -0,0 +1,36 @@
<h2 class="inline-block"><%= t("tracking.budgets.index.title") %></h2>
<% if @budget.present? %>
<table>
<thead>
<tr>
<th><%= t("tracking.budgets.index.table_name") %></th>
<th><%= t("tracking.budgets.index.table_phase") %></th>
<th><%= t("tracking.budgets.index.table_assigned_investments_tracking_open") %></th>
<th><%= t("tracking.budgets.index.table_actions") %></th>
</tr>
</thead>
<tbody>
<tr id="<%= dom_id(@budget) %>" class="budget">
<td>
<%= @budget.name %>
</td>
<td>
<%= t("budgets.phase.#{@budget.phase}") %>
</td>
<td>
<%= @investments.count %>
</td>
<td>
<%= link_to t("tracking.budgets.index.tracking"),
tracking_budget_budget_investments_path(budget_id: @budget.id),
class: "button hollow expanded" %>
</td>
</tr>
</tbody>
</table>
<% else %>
<div class="callout primary clear">
<%= t("tracking.budgets.index.no_budgets") %>
</div>
<% end %>

View File

@@ -1,13 +1,13 @@
<%= render "admin/shared/globalize_locales", resource: @milestone %> <%= render "admin/shared/globalize_locales", resource: @milestone %>
<%= translatable_form_for [:admin, *resource_hierarchy_for(@milestone)] do |f| %> <%= translatable_form_for [:tracking, *resource_hierarchy_for(@milestone)] do |f| %>
<div class="small-12 medium-6 margin-bottom"> <div class="small-12 medium-6 margin-bottom">
<%= f.select :status_id, <%= f.select :status_id,
@statuses.collect { |s| [s.name, s.id] }, @statuses.collect { |s| [s.name, s.id] },
{ include_blank: @statuses.any? ? "" : t("admin.milestones.form.no_statuses_defined") }, { include_blank: @statuses.any? ? "" : t("tracking.milestones.form.no_statuses_defined") },
{ disabled: @statuses.blank? } %> { disabled: @statuses.blank? } %>
<%= link_to t("admin.milestones.form.admin_statuses"), <%= link_to t("tracking.milestones.form.admin_statuses"),
admin_milestone_statuses_path %> admin_milestone_statuses_path %>
</div> </div>
@@ -17,10 +17,10 @@
<%= translations_form.text_area :description, <%= translations_form.text_area :description,
rows: 5, rows: 5,
label: t("admin.milestones.new.description") %> label: t("tracking.milestones.new.description") %>
<% end %> <% end %>
<%= f.label :publication_date, t("admin.milestones.new.date") %> <%= f.label :publication_date, t("tracking.milestones.new.date") %>
<%= f.text_field :publication_date, <%= f.text_field :publication_date,
value: @milestone.publication_date.present? ? l(@milestone.publication_date.to_date) : nil, value: @milestone.publication_date.present? ? l(@milestone.publication_date.to_date) : nil,
label: false, label: false,

View File

@@ -1,7 +1,7 @@
<h2 class="inline-block"><%= t("admin.milestones.index.milestone") %></h2> <h2 class="inline-block"><%= t("tracking.milestones.index.milestone") %></h2>
<%= link_to t("admin.progress_bars.manage"), <%= link_to t("tracking.progress_bars.manage"),
polymorphic_path([:admin, *resource_hierarchy_for(milestoneable.progress_bars.new)]), polymorphic_path([:tracking, *resource_hierarchy_for(milestoneable.progress_bars.new)]),
class: "button hollow float-right" %> class: "button hollow float-right" %>
<% if milestoneable.milestone_tag_list.any? %> <% if milestoneable.milestone_tag_list.any? %>
@@ -16,14 +16,14 @@
<table> <table>
<thead> <thead>
<tr> <tr>
<th><%= t("admin.milestones.index.table_id") %></th> <th><%= t("tracking.milestones.index.table_id") %></th>
<th><%= t("admin.milestones.index.table_title") %></th> <th><%= t("tracking.milestones.index.table_title") %></th>
<th><%= t("admin.milestones.index.table_description") %></th> <th><%= t("tracking.milestones.index.table_description") %></th>
<th><%= t("admin.milestones.index.table_publication_date") %></th> <th><%= t("tracking.milestones.index.table_publication_date") %></th>
<th><%= t("admin.milestones.index.table_status") %></th> <th><%= t("tracking.milestones.index.table_status") %></th>
<th><%= t("admin.milestones.index.image") %></th> <th><%= t("tracking.milestones.index.image") %></th>
<th><%= t("admin.milestones.index.documents") %></th> <th><%= t("tracking.milestones.index.documents") %></th>
<th><%= t("admin.milestones.index.table_actions") %></th> <th><%= t("tracking.milestones.index.table_actions") %></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -32,7 +32,7 @@
<td class="text-center"><%= milestone.id %></td> <td class="text-center"><%= milestone.id %></td>
<td> <td>
<%= link_to milestone.title, <%= link_to milestone.title,
polymorphic_path([:admin, *resource_hierarchy_for(milestone)], polymorphic_path([:tracking, *resource_hierarchy_for(milestone)],
action: :edit) %> action: :edit) %>
</td> </td>
<td class="small small-5"><%= milestone.description %></td> <td class="small small-5"><%= milestone.description %></td>
@@ -43,7 +43,7 @@
<%= milestone.status.present? ? milestone.status.name : "" %> <%= milestone.status.present? ? milestone.status.name : "" %>
</td> </td>
<td class="small"> <td class="small">
<%= link_to t("admin.milestones.index.show_image"), <%= link_to t("tracking.milestones.index.show_image"),
milestone.image_url(:large), milestone.image_url(:large),
target: :_blank if milestone.image.present? %> target: :_blank if milestone.image.present? %>
</td> </td>
@@ -58,8 +58,8 @@
<% end %> <% end %>
</td> </td>
<td class="small-2"> <td class="small-2">
<%= link_to t("admin.milestones.index.delete"), <%= link_to t("tracking.milestones.index.delete"),
polymorphic_path([:admin, *resource_hierarchy_for(milestone)]), polymorphic_path([:tracking, *resource_hierarchy_for(milestone)]),
method: :delete, method: :delete,
class: "button hollow alert expanded" %> class: "button hollow alert expanded" %>
</td> </td>
@@ -68,12 +68,12 @@
</tbody> </tbody>
</table> </table>
<% else %> <% else %>
<p><%= t("admin.milestones.index.no_milestones") %></p> <p><%= t("tracking.milestones.index.no_milestones") %></p>
<% end %> <% end %>
<p> <p>
<%= link_to t("admin.milestones.index.new_milestone"), <%= link_to t("tracking.milestones.index.new_milestone"),
polymorphic_path([:admin, *resource_hierarchy_for(milestoneable.milestones.new)], polymorphic_path([:tracking, *resource_hierarchy_for(milestoneable.milestones.new)],
action: :new), action: :new),
class: "button hollow" %> class: "button hollow" %>
</p> </p>

View File

@@ -1,6 +1,6 @@
<%= back_link_to milestoneable_path %> <%= back_link_to milestoneable_path %>
<h2><%= t("admin.milestones.edit.title") %></h2> <h2><%= t("tracking.milestones.edit.title") %></h2>
<div class="milestone-edit"> <div class="milestone-edit">
<%= render "form" %> <%= render "form" %>

View File

@@ -3,7 +3,7 @@
<div class="small-12 column"> <div class="small-12 column">
<%= back_link_to milestoneable_path %> <%= back_link_to milestoneable_path %>
<h1><%= t("admin.milestones.new.creating") %></h1> <h1><%= t("tracking.milestones.new.creating") %></h1>
<%= render "form" %> <%= render "form" %>
</div> </div>

View File

@@ -1,6 +1,6 @@
<%= render "admin/shared/globalize_locales", resource: @progress_bar %> <%= render "admin/shared/globalize_locales", resource: @progress_bar %>
<%= translatable_form_for [:admin, *resource_hierarchy_for(@progress_bar)] do |f| %> <%= translatable_form_for [:tracking, *resource_hierarchy_for(@progress_bar)] do |f| %>
<div class="small-12 medium-6"> <div class="small-12 medium-6">
<%= f.enum_select :kind %> <%= f.enum_select :kind %>

View File

@@ -1,8 +1,8 @@
<h2 class="inline-block"><%= t("admin.progress_bars.index.title") %></h2> <h2 class="inline-block"><%= t("tracking.progress_bars.index.title") %></h2>
<%= link_to t("admin.progress_bars.index.new_progress_bar"), <%= link_to t("tracking.progress_bars.index.new_progress_bar"),
polymorphic_path( polymorphic_path(
[:admin, *resource_hierarchy_for(ProgressBar.new(progressable: progressable))], [:tracking, *resource_hierarchy_for(ProgressBar.new(progressable: progressable))],
action: :new action: :new
), ),
class: "button float-right" %> class: "button float-right" %>
@@ -11,10 +11,10 @@
<table> <table>
<thead> <thead>
<tr> <tr>
<th><%= t("admin.progress_bars.index.table_id") %></th> <th><%= t("tracking.progress_bars.index.table_id") %></th>
<th><%= t("admin.progress_bars.index.table_kind") %></th> <th><%= t("tracking.progress_bars.index.table_kind") %></th>
<th><%= t("admin.progress_bars.index.table_title") %></th> <th><%= t("tracking.progress_bars.index.table_title") %></th>
<th class="text-center"><%= t("admin.progress_bars.index.table_percentage") %></th> <th class="text-center"><%= t("tracking.progress_bars.index.table_percentage") %></th>
<th><%= t("admin.actions.actions") %></th> <th><%= t("admin.actions.actions") %></th>
</tr> </tr>
</thead> </thead>
@@ -29,7 +29,7 @@
<% if progress_bar.title.present? %> <% if progress_bar.title.present? %>
<%= progress_bar.title %> <%= progress_bar.title %>
<% else %> <% else %>
<strong><%= t("admin.progress_bars.index.primary") %></strong> <strong><%= t("tracking.progress_bars.index.primary") %></strong>
<% end %> <% end %>
</td> </td>
<td class="text-center"> <td class="text-center">
@@ -37,12 +37,12 @@
</td> </td>
<td> <td>
<%= link_to t("admin.actions.edit"), <%= link_to t("admin.actions.edit"),
polymorphic_path([:admin, *resource_hierarchy_for(progress_bar)], polymorphic_path([:tracking, *resource_hierarchy_for(progress_bar)],
action: :edit), action: :edit),
class: "button hollow" %> class: "button hollow" %>
<%= link_to t("admin.actions.delete"), <%= link_to t("admin.actions.delete"),
polymorphic_path([:admin, *resource_hierarchy_for(progress_bar)]), polymorphic_path([:tracking, *resource_hierarchy_for(progress_bar)]),
method: :delete, method: :delete,
class: "button hollow alert" %> class: "button hollow alert" %>
</td> </td>
@@ -52,6 +52,6 @@
</table> </table>
<% else %> <% else %>
<div class="callout primary"> <div class="callout primary">
<%= t("admin.progress_bars.index.no_progress_bars") %> <%= t("tracking.progress_bars.index.no_progress_bars") %>
</div> </div>
<% end %> <% end %>

View File

@@ -0,0 +1,15 @@
<% if @progress_bar.primary? %>
<% bar_title = t("tracking.progress_bars.edit.title.primary") %>
<% else %>
<% bar_title = t("tracking.progress_bars.edit.title.secondary", title: @progress_bar.title) %>
<% end %>
<% provide :title do %>
<%= "#{t("tracking.header.title")} - #{bar_title}" %>
<% end %>
<%= back_link_to progress_bars_index %>
<h2><%= bar_title %></h2>
<%= render "form" %>

View File

@@ -0,0 +1,9 @@
<% provide :title do %>
<%= "#{t("admin.header.title")} - #{t("tracking.progress_bars.index.title")}" %>
<% end %>
<%= back_link_to tracker_back_path(@progressable) %>
<div class="clear"></div>
<%= render "tracking/progress_bars/progress_bars", progressable: @progressable %>

View File

@@ -0,0 +1,9 @@
<% provide :title do %>
<%= "#{t("admin.header.title")} - #{t("tracking.progress_bars.new.creating")}" %>
<% end %>
<%= back_link_to progress_bars_index %>
<h2><%= t("tracking.progress_bars.new.creating") %></h2>
<%= render "form" %>

View File

@@ -47,6 +47,7 @@ data:
- config/locales/%{locale}/milestones.yml - config/locales/%{locale}/milestones.yml
- config/locales/%{locale}/stats.yml - config/locales/%{locale}/stats.yml
- config/locales/%{locale}/download.yml - config/locales/%{locale}/download.yml
- config/locales/%{locale}/tracking.yml
# Locale files to write new keys to, based on a list of key pattern => file rules. Matched from top to bottom: # Locale files to write new keys to, based on a list of key pattern => file rules. Matched from top to bottom:
# `i18n-tasks normalize -p` will force move the keys according to these rules # `i18n-tasks normalize -p` will force move the keys according to these rules

View File

@@ -261,6 +261,7 @@ en:
"false": "No" "false": "No"
valuator_groups: "Valuator Groups" valuator_groups: "Valuator Groups"
preview: Investment preview preview: Investment preview
assigned_trackers: "Assigned trackers"
edit: edit:
classification: Classification classification: Classification
compatibility: Compatibility compatibility: Compatibility
@@ -275,39 +276,12 @@ en:
tags_placeholder: "Write the tags you want separated by commas (,)" tags_placeholder: "Write the tags you want separated by commas (,)"
undefined: Undefined undefined: Undefined
user_groups: "Groups" user_groups: "Groups"
assigned_trackers: "Trackers"
milestone_tags: Milestone tags milestone_tags: Milestone tags
search_unfeasible: Search unfeasible search_unfeasible: Search unfeasible
milestones: milestones:
index: index:
table_id: "ID"
table_title: "Title"
table_description: "Description"
table_publication_date: "Publication date"
table_status: Status
table_actions: "Actions"
delete: "Delete milestone"
no_milestones: "Don't have defined milestones"
image: "Image"
show_image: "Show image"
documents: "Documents"
milestone: Milestone
new_milestone: Create new milestone
milestone_tags: Milestone Tags milestone_tags: Milestone Tags
form:
admin_statuses: Manage statuses
no_statuses_defined: There are no defined statuses yet
new:
creating: Create milestone
date: Date
description: Description
edit:
title: Edit milestone
create:
notice: New milestone created successfully!
update:
notice: Milestone updated successfully
delete:
notice: Milestone successfully deleted
statuses: statuses:
index: index:
title: Milestone statuses title: Milestone statuses
@@ -734,6 +708,7 @@ en:
title_booths: Voting booths title_booths: Voting booths
legislation: Collaborative Legislation legislation: Collaborative Legislation
users: Users users: Users
trackers: "Trackers"
dashboard: Proposals dashboard dashboard: Proposals dashboard
administrator_tasks: Resources requested administrator_tasks: Resources requested
dashboard_actions: Resources and actions dashboard_actions: Resources and actions
@@ -1648,3 +1623,26 @@ en:
edited_by: "Edited by" edited_by: "Edited by"
actions: "Actions" actions: "Actions"
empty: "There are not changes logged" empty: "There are not changes logged"
trackers:
index:
title: Trackers
name: Name
email: Email
description: Description
no_description: No description
no_trackers: There are no trackers.
tracker:
add: "Add to trackers"
form:
update: Update Tracker
updated: "Tracker updated succesfully."
edit_title: "Trackers: Edit tracker"
show:
email: Email
description: Description
no_description: No description.
search:
title: Trackers
progress_bars:
index:
title: "Progress bars"

View File

@@ -260,6 +260,7 @@ en:
other: You have %{count} new notifications other: You have %{count} new notifications
notifications: Notifications notifications: Notifications
no_notifications: "You don't have new notifications" no_notifications: "You don't have new notifications"
tracking: "Tracking"
admin: admin:
watch_form_message: "You have unsaved changes. Do you confirm to leave the page?" watch_form_message: "You have unsaved changes. Do you confirm to leave the page?"
notifications: notifications:

View File

@@ -0,0 +1,92 @@
en:
tracking:
header:
title: Tracking
menu:
title: Tracking
budgets: Participatory budgets
budgets:
index:
title: Participatory budgets
table_name: Name
table_phase: Phase
table_assigned_investments_tracking_open: Investment projects assigned with tracking open
table_actions: Actions
tracking: Tracking
no_budgets: "There are no budgets"
budget_investments:
index:
assigned_to: "Assigned to %{tracker}"
title: Investment projects
edit: Edit milestones
table_id: ID
table_title: Title
table_heading_name: Heading name
table_actions: Actions
no_investments: "There are no investment projects."
show:
title: Investment project
info: Author info
by: Sent by
sent: Sent at
heading: Heading
undefined: "Undefined"
responsibles: Responsibles
assigned_admin: Assigned admin
milestones:
index:
table_id: "ID"
table_title: "Title"
table_description: "Description"
table_publication_date: "Publication date"
table_status: Status
table_actions: "Actions"
delete: "Delete milestone"
no_milestones: "Don't have defined milestones"
image: "Image"
show_image: "Show image"
documents: "Documents"
milestone: Milestone
new_milestone: Create new milestone
form:
admin_statuses: Manage statuses
no_statuses_defined: There are no defined statuses yet
new:
creating: Create milestone
date: Date
description: Description
edit:
title: Edit milestone
create:
notice: New milestone created successfully!
update:
notice: Milestone updated successfully
delete:
notice: Milestone successfully deleted
progress_bars:
manage: "Manage progress bars"
index:
title: "Progress bars"
no_progress_bars: "There are no progress bars"
new_progress_bar: "Create new progress bar"
primary: "Primary progress bar"
table_id: "ID"
table_kind: "Type"
table_title: "Title"
table_percentage: "Current progress"
new:
creating: "Create progress bar"
edit:
title:
primary: "Edit primary progress bar"
secondary: "Edit progress bar %{title}"
create:
notice: "Progress bar created successfully!"
update:
notice: "Progress bar updated successfully"
delete:
notice: "Progress bar deleted successfully"
trackers:
budget_investments:
show:
assigned_trackers: "Assigned trackers"

View File

@@ -261,6 +261,7 @@ es:
"false": "No" "false": "No"
valuator_groups: "Grupos de evaluadores" valuator_groups: "Grupos de evaluadores"
preview: Vista previa preview: Vista previa
assigned_trackers: "Gestores de seguimiento asignados"
edit: edit:
classification: Clasificación classification: Clasificación
compatibility: Compatibilidad compatibility: Compatibilidad
@@ -275,39 +276,12 @@ es:
tags_placeholder: "Escribe las etiquetas que desees separadas por comas (,)" tags_placeholder: "Escribe las etiquetas que desees separadas por comas (,)"
undefined: Sin definir undefined: Sin definir
user_groups: "Grupos" user_groups: "Grupos"
assigned_trackers: "Gestores de seguimiento"
milestone_tags: Etiquetas de Seguimiento milestone_tags: Etiquetas de Seguimiento
search_unfeasible: Buscar inviables search_unfeasible: Buscar inviables
milestones: milestones:
index: index:
table_id: "ID"
table_title: "Título"
table_description: "Descripción"
table_publication_date: "Fecha de publicación"
table_status: Estado
table_actions: "Acciones"
delete: "Eliminar hito"
no_milestones: "No hay hitos definidos"
image: "Imagen"
show_image: "Mostrar imagen"
documents: "Documentos"
milestone: Seguimiento
new_milestone: Crear nuevo hito
milestone_tags: Etiquetas de Seguimiento milestone_tags: Etiquetas de Seguimiento
form:
admin_statuses: Gestionar estados
no_statuses_defined: No hay estados definidos
new:
creating: Crear hito
date: Fecha
description: Descripción
edit:
title: Editar hito
create:
notice: '¡Nuevo hito creado con éxito!'
update:
notice: Hito actualizado
delete:
notice: Hito borrado correctamente
statuses: statuses:
index: index:
title: Estados de seguimiento title: Estados de seguimiento
@@ -735,6 +709,7 @@ es:
title_booths: Urnas de votación title_booths: Urnas de votación
legislation: Legislación colaborativa legislation: Legislación colaborativa
users: Usuarios users: Usuarios
trackers: "Gestores de seguimiento"
dashboard: Panel de progreso de propuestas dashboard: Panel de progreso de propuestas
administrator_tasks: Recursos solicitados administrator_tasks: Recursos solicitados
dashboard_actions: Recursos y acciones dashboard_actions: Recursos y acciones
@@ -1646,3 +1621,26 @@ es:
edited_by: "Editado por" edited_by: "Editado por"
actions: "Acciones" actions: "Acciones"
empty: "No hay cambios registrados" empty: "No hay cambios registrados"
trackers:
index:
title: Gestores de seguimiento
name: Nombre
email: Email
description: Descripción
no_description: Sin descripción
no_trackers: No hay gestores de seguimiento.
tracker:
add: "Añadir a gestores de seguimiento"
form:
update: "Actualizar gestor"
updated: "Gestor de seguimiento actualizado correctamente."
edit_title: "Gestores de seguimiento: Editar gestor"
show:
email: Email
description: Descripción
no_description: Sin descripción.
search:
title: Trackers
progress_bars:
index:
title: "Barras de progreso"

View File

@@ -260,6 +260,7 @@ es:
other: Tienes %{count} notificaciones nuevas other: Tienes %{count} notificaciones nuevas
notifications: Notificaciones notifications: Notificaciones
no_notifications: "No tienes notificaciones nuevas" no_notifications: "No tienes notificaciones nuevas"
tracking: "Seguimiento"
admin: admin:
watch_form_message: "Has realizado cambios que no han sido guardados. ¿Seguro que quieres abandonar la página?" watch_form_message: "Has realizado cambios que no han sido guardados. ¿Seguro que quieres abandonar la página?"
notifications: notifications:

View File

@@ -0,0 +1,92 @@
es:
tracking:
header:
title: Seguimiento
menu:
title: Seguimiento
budgets: Presupuestos participativos
budgets:
index:
title: Presupuestos participativos
table_name: Nombre
table_phase: Fase
table_assigned_investments_tracking_open: Prop. Inv. asignadas en segumiento
table_actions: Acciones
tracking: Seguimiento
no_budgets: "No hay presupuestos"
budget_investments:
index:
assigned_to: "Asignadas a %{tracker}"
title: Proyectos de gasto
edit: Editar seguimiento
table_id: ID
table_title: Título
table_heading_name: Nombre de la partida
table_actions: Acciones
no_investments: "No hay proyectos de gasto."
show:
title: Proyecto de gasto
info: Datos de envío
by: Enviada por
sent: Fecha de creación
heading: Partida
undefined: Sin definir
responsibles: Responsables
assigned_admin: Administrador asignado
milestones:
index:
table_id: "ID"
table_title: "Título"
table_description: "Descripción"
table_publication_date: "Fecha de publicación"
table_status: Estado
table_actions: "Acciones"
delete: "Eliminar hito"
no_milestones: "No hay hitos definidos"
image: "Imagen"
show_image: "Mostrar imagen"
documents: "Documentos"
milestone: Seguimiento
new_milestone: Crear nuevo hito
form:
admin_statuses: Gestionar estados
no_statuses_defined: No hay estados definidos
new:
creating: Crear hito
date: Fecha
description: Descripción
edit:
title: Editar hito
create:
notice: "¡Nuevo hito creado con éxito!"
update:
notice: Hito actualizado
delete:
notice: Hito borrado correctamente
progress_bars:
manage: "Gestionar barras de progreso"
index:
title: "Barras de progreso"
no_progress_bars: "No hay barras de progreso"
new_progress_bar: "Crear nueva barra de progreso"
primary: "Barra de progreso principal"
table_id: "ID"
table_kind: "Tipo"
table_title: "Título"
table_percentage: "Progreso"
new:
creating: "Crear barra de progreso"
edit:
title:
primary: "Editar barra de progreso principal"
secondary: "Editar barra de progreso %{title}"
create:
notice: "¡Barra de progreso creada con éxito!"
update:
notice: "Barra de progreso actualizada"
delete:
notice: "Barra de progreso eliminada correctamente"
trackers:
budget_investments:
show:
assigned_trackers: "Gestores de seguimiento asignados"

View File

@@ -31,6 +31,7 @@ Rails.application.routes.draw do
draw :tag draw :tag
draw :user draw :user
draw :valuation draw :valuation
draw :tracking
draw :verification draw :verification
root "welcome#index" root "welcome#index"

View File

@@ -61,8 +61,6 @@ namespace :admin do
end end
resources :budget_investments, only: [:index, :show, :edit, :update] do resources :budget_investments, only: [:index, :show, :edit, :update] do
resources :milestones, controller: "budget_investment_milestones"
resources :progress_bars, except: :show, controller: "budget_investment_progress_bars"
member { patch :toggle_selection } member { patch :toggle_selection }
end end
@@ -105,6 +103,11 @@ namespace :admin do
get :summary, on: :collection get :summary, on: :collection
end end
resources :trackers, only: [:show, :index, :edit, :update, :create, :destroy] do
get :search, on: :collection
get :summary, on: :collection
end
resources :valuator_groups resources :valuator_groups
resources :managers, only: [:index, :create, :destroy] do resources :managers, only: [:index, :create, :destroy] do
@@ -207,8 +210,7 @@ namespace :admin do
member { patch :toggle_selection } member { patch :toggle_selection }
end end
resources :draft_versions resources :draft_versions
resources :milestones resources :milestones, only: :index
resources :progress_bars, except: :show
resource :homepage, only: [:edit, :update] resource :homepage, only: [:edit, :update]
end end
end end

23
config/routes/tracking.rb Normal file
View File

@@ -0,0 +1,23 @@
namespace :tracking do
root to: "budgets#index"
resources :budgets, only: :index do
resources :budget_investments, only: [:index, :show, :edit] do
resources :milestones, controller: "budget_investment_milestones"
resources :progress_bars, except: :show, controller: "budget_investment_progress_bars"
patch :track, on: :member
end
end
resources :proposals, only: [:index, :show] do
resources :milestones, controller: "proposal_milestones"
resources :progress_bars, except: :show, controller: "proposal_progress_bars"
end
namespace :legislation do
resources :processes, only: [:index, :show] do
resources :milestones
resources :progress_bars, except: :show
end
end
end

View File

@@ -0,0 +1,11 @@
class CreateTrackers < ActiveRecord::Migration[5.0]
def change
create_table :trackers do |t|
t.references :user, foreign_key: true
t.string :description
t.integer :budget_investment_count, default: 0
t.timestamps
end
end
end

View File

@@ -0,0 +1,10 @@
class CreateBudgetTrackerAssignments < ActiveRecord::Migration[5.0]
def change
create_table :budget_tracker_assignments, index: false do |t|
t.references :tracker, foreign_key: true
t.integer :investment_id, index: true
t.timestamps null:false
end
end
end

View File

@@ -0,0 +1,5 @@
class AddTrackerAssignmentsCountToBudgetInvestments < ActiveRecord::Migration[5.0]
def change
add_column :budget_investments, :tracker_assignments_count, :integer
end
end

View File

@@ -269,6 +269,7 @@ ActiveRecord::Schema.define(version: 20190607160900) do
t.datetime "confirmed_hide_at" t.datetime "confirmed_hide_at"
t.datetime "ignored_flag_at" t.datetime "ignored_flag_at"
t.integer "flags_count", default: 0 t.integer "flags_count", default: 0
t.integer "tracker_assignments_count"
t.index ["administrator_id"], name: "index_budget_investments_on_administrator_id", using: :btree t.index ["administrator_id"], name: "index_budget_investments_on_administrator_id", using: :btree
t.index ["author_id"], name: "index_budget_investments_on_author_id", using: :btree t.index ["author_id"], name: "index_budget_investments_on_author_id", using: :btree
t.index ["community_id"], name: "index_budget_investments_on_community_id", using: :btree t.index ["community_id"], name: "index_budget_investments_on_community_id", using: :btree
@@ -310,6 +311,15 @@ ActiveRecord::Schema.define(version: 20190607160900) do
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
end end
create_table "budget_tracker_assignments", force: :cascade do |t|
t.integer "tracker_id"
t.integer "investment_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["investment_id"], name: "index_budget_tracker_assignments_on_investment_id", using: :btree
t.index ["tracker_id"], name: "index_budget_tracker_assignments_on_tracker_id", using: :btree
end
create_table "budget_translations", force: :cascade do |t| create_table "budget_translations", force: :cascade do |t|
t.integer "budget_id", null: false t.integer "budget_id", null: false
t.string "locale", null: false t.string "locale", null: false
@@ -1427,6 +1437,15 @@ ActiveRecord::Schema.define(version: 20190607160900) do
t.index ["hidden_at"], name: "index_topics_on_hidden_at", using: :btree t.index ["hidden_at"], name: "index_topics_on_hidden_at", using: :btree
end end
create_table "trackers", force: :cascade do |t|
t.integer "user_id"
t.string "description"
t.integer "budget_investment_count", default: 0
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_trackers_on_user_id", using: :btree
end
create_table "users", force: :cascade do |t| create_table "users", force: :cascade do |t|
t.string "email", default: "" t.string "email", default: ""
t.string "encrypted_password", default: "", null: false t.string "encrypted_password", default: "", null: false
@@ -1612,6 +1631,7 @@ ActiveRecord::Schema.define(version: 20190607160900) do
add_foreign_key "administrators", "users" add_foreign_key "administrators", "users"
add_foreign_key "budget_investments", "communities" add_foreign_key "budget_investments", "communities"
add_foreign_key "budget_tracker_assignments", "trackers"
add_foreign_key "dashboard_administrator_tasks", "users" add_foreign_key "dashboard_administrator_tasks", "users"
add_foreign_key "dashboard_executed_actions", "dashboard_actions", column: "action_id" add_foreign_key "dashboard_executed_actions", "dashboard_actions", column: "action_id"
add_foreign_key "dashboard_executed_actions", "proposals" add_foreign_key "dashboard_executed_actions", "proposals"
@@ -1650,6 +1670,7 @@ ActiveRecord::Schema.define(version: 20190607160900) do
add_foreign_key "proposals", "communities" add_foreign_key "proposals", "communities"
add_foreign_key "related_content_scores", "related_contents" add_foreign_key "related_content_scores", "related_contents"
add_foreign_key "related_content_scores", "users" add_foreign_key "related_content_scores", "users"
add_foreign_key "trackers", "users"
add_foreign_key "users", "geozones" add_foreign_key "users", "geozones"
add_foreign_key "valuators", "users" add_foreign_key "valuators", "users"
end end

View File

@@ -67,6 +67,10 @@ FactoryBot.define do
user user
end end
factory :tracker do
user
end
factory :valuator do factory :valuator do
user user
end end

View File

@@ -4,6 +4,6 @@ describe "Admin budget investment milestones" do
it_behaves_like "translatable", it_behaves_like "translatable",
"milestone", "milestone",
"edit_admin_budget_budget_investment_milestone_path", "edit_tracking_budget_budget_investment_milestone_path",
%w[description] %w[description]
end end

View File

@@ -108,7 +108,7 @@ describe "Poll Officing" do
expect(page).not_to have_link("Moderation") expect(page).not_to have_link("Moderation")
end end
scenario "Officing dashboard" do xscenario "Officing dashboard" do
create(:poll_officer, user: user) create(:poll_officer, user: user)
create(:poll) create(:poll)
login_as(user) login_as(user)

View File

@@ -0,0 +1,365 @@
require "rails_helper"
feature "Valuation budget investments" do
let(:budget) { create(:budget) }
let(:tracker) do
create(:tracker, user: create(:user, username: "Rachel", email: "rachel@trackers.org"))
end
background do
login_as(tracker.user)
end
scenario "Disabled with a feature flag" do
Setting["process.budgets"] = nil
expect{
visit tracking_budget_budget_investments_path(create(:budget))
}.to raise_exception(FeatureFlags::FeatureDisabled)
end
scenario "Display link to tracking section" do
visit root_path
expect(page).to have_link "Tracking", href: tracking_root_path
end
feature "Index" do
scenario "Index shows budget investments assigned to current tracker" do
investment1 = create(:budget_investment, budget: budget)
investment2 = create(:budget_investment, budget: budget)
investment1.trackers << tracker
visit tracking_budget_budget_investments_path(budget)
expect(page).to have_content(investment1.title)
expect(page).not_to have_content(investment2.title)
end
scenario "Index shows no budget investment to admins no trackers" do
investment1 = create(:budget_investment, budget: budget)
investment2 = create(:budget_investment, budget: budget)
investment1.trackers << tracker
logout
login_as create(:administrator).user
visit tracking_budget_budget_investments_path(budget)
expect(page).not_to have_content(investment1.title)
expect(page).not_to have_content(investment2.title)
end
scenario "Index displays investments paginated" do
per_page = Kaminari.config.default_per_page
(per_page + 2).times do
investment = create(:budget_investment, budget: budget)
investment.trackers << tracker
end
visit tracking_budget_budget_investments_path(budget)
expect(page).to have_css(".budget_investment", count: per_page)
within("ul.pagination") do
expect(page).to have_content("1")
expect(page).to have_content("2")
expect(page).not_to have_content("3")
click_link "Next", exact: false
end
expect(page).to have_css(".budget_investment", count: 2)
end
scenario "headings" do
investment1 = create(:budget_investment,
budget: budget,
title: "investment 1",
heading: create(:budget_heading, name: "first_heading"))
investment2 = create(:budget_investment,
budget: budget, title: "investment 2",
heading: create(:budget_heading, name: "last_heading"))
investment3 = create(:budget_investment,
budget: budget,
title: "investment 3",
heading: create(:budget_heading, name: "no_heading"))
investment1.trackers << tracker
investment2.trackers << tracker
visit tracking_budget_budget_investments_path(budget)
expect(page).to have_link("All headings (2)")
expect(page).to have_link("last_heading (1)")
expect(page).to have_link("first_heading (1)")
expect(page).not_to have_link("no_heading (1)")
expect(page).to have_content("investment 1")
expect(page).to have_content("investment 2")
expect(page).not_to have_content("investment 3")
expect(page.find(".select-heading .is-active")).to have_content("All headings")
click_on "last_heading (1)"
expect(page.find(".select-heading .is-active")).to have_content("last_heading (1)")
expect(page).not_to have_content("investment 1")
expect(page).to have_content("investment 2")
expect(page).not_to have_content("investment 3")
end
end
feature "Show" do
let(:administrator) do
create(:administrator, user: create(:user, username: "Ana", email: "ana@admins.org"))
end
let(:second_tracker) do
create(:tracker, user: create(:user, username: "Rick", email: "rick@trackers.org"))
end
let(:investment) do
create(:budget_investment, budget: budget, administrator: administrator)
end
background do
investment.trackers << [tracker, second_tracker]
end
scenario "visible for assigned trackers" do
visit tracking_budget_budget_investments_path(budget)
click_link investment.title
expect(page).to have_content(investment.title)
expect(page).to have_content(investment.description)
expect(page).to have_content(investment.author.name)
expect(page).to have_content(investment.heading.name)
within("#assigned_trackers") do
expect(page).to have_content("Rachel (rachel@trackers.org)")
expect(page).to have_content("Rick (rick@trackers.org)")
end
end
scenario "visible for admins" do
logout
login_as create(:administrator).user
visit tracking_budget_budget_investment_path(budget, investment)
expect(page).to have_content(investment.title)
expect(page).to have_content(investment.description)
expect(page).to have_content(investment.author.name)
expect(page).to have_content(investment.heading.name)
expect(page).to have_content("Ana (ana@admins.org)")
within("#assigned_trackers") do
expect(page).to have_content("Rachel (rachel@trackers.org)")
expect(page).to have_content("Rick (rick@trackers.org)")
end
end
scenario "not visible for not assigned trackers" do
logout
login_as create(:tracker).user
expect{
visit tracking_budget_budget_investment_path(budget, investment)
}.to raise_error "Not Found"
end
end
feature "Milestones" do
let(:admin) { create(:administrator) }
let(:investment) do
heading = create(:budget_heading)
create(:budget_investment, heading: heading, budget: budget,
administrator: admin)
end
background do
investment.trackers << tracker
end
scenario "visit investment manage milestones" do
visit tracking_budget_budget_investments_path(budget)
click_link "Edit milestones"
expect(page).to have_content("Milestone")
expect(page).to have_content(investment.title)
end
scenario "create investment milestones" do
visit edit_tracking_budget_budget_investment_path(budget, investment)
expect(page).to have_content("Milestone")
expect(page).to have_content(investment.title)
click_link "Create new milestone"
expect(page).to have_content("Create milestone")
fill_in("Description", with: "Test Description")
page.find("#milestone_publication_date").set(Date.today)
click_button "Create milestone"
visit edit_tracking_budget_budget_investment_path(budget, investment)
expect(page).to have_content("Test Description")
end
scenario "delete investment milestones" do
milestone = create(:milestone,
milestoneable: investment,
description: "Test delete milestone")
visit edit_tracking_budget_budget_investment_path(budget, investment)
expect(page).to have_content("Test delete milestone")
page.find("#milestone_#{milestone.id}").click_link("Delete milestone")
visit edit_tracking_budget_budget_investment_path(budget, investment)
expect(page).not_to have_content("Test delete milestone")
end
scenario "edit investment milestones" do
milestone = create(:milestone, milestoneable: investment, description: "Test edit milestone")
visit edit_tracking_budget_budget_investment_path(budget, investment)
expect(page).to have_content("Test edit milestone")
page.find("#milestone_#{milestone.id}").first("a").click
expect(page).to have_content("Edit milestone")
expect(page).to have_content("Test edit milestone")
fill_in("Description", with: "Test edited milestone")
click_button "Update milestone"
visit edit_tracking_budget_budget_investment_path(budget, investment)
expect(page).not_to have_content("Test edit milestone")
expect(page).to have_content("Test edited milestone")
end
end
feature "Progress Bars" do
let(:admin) { create(:administrator) }
let(:investment) do
heading = create(:budget_heading)
create(:budget_investment, heading: heading, budget: budget,
administrator: admin)
end
background do
investment.trackers << tracker
end
scenario "view index" do
visit edit_tracking_budget_budget_investment_path(budget, investment)
click_link "Manage progress bars"
expect(page).to have_content("Progress bars")
logout
login_as create(:tracker, user: create(:user)).user
expect{
visit tracking_budget_budget_investment_progress_bars_path(budget, investment)
}.to raise_error "Not Found"
end
scenario "create primary progress bar" do
visit tracking_budget_budget_investment_progress_bars_path(budget, investment)
expect(page).to have_content("Progress bars")
click_link "Create new progress bar"
expect(page).to have_content("Create progress bar")
select("Primary", :from => "Type")
fill_in("Current progress", :with => 50)
click_button "Create Progress bar"
expect(page).to have_content("Progress bars")
expect(page).to have_content("Primary")
end
scenario "create secondary progress bar" do
visit tracking_budget_budget_investment_progress_bars_path(budget, investment)
expect(page).to have_content("Progress bars")
click_link "Create new progress bar"
expect(page).to have_content("Create progress bar")
select("Secondary", :from => "Type")
fill_in("Title", :with => "secondary_progress_bar")
fill_in("Current progress", :with => 50)
click_button "Create Progress bar"
expect(page).to have_content("Progress bars")
expect(page).to have_content("secondary_progress_bar")
end
scenario "delete" do
primary_progress_bar = create(:progress_bar, progressable: investment)
secondary_progress_bar = create(:progress_bar,
:secondary,
title: "to delete",
progressable: investment)
visit tracking_budget_budget_investment_progress_bars_path(budget, investment)
expect(page).to have_content("Primary")
expect(page).to have_content(secondary_progress_bar.title)
page.find("#progress_bar_#{secondary_progress_bar.id}").click_link("Delete")
visit tracking_budget_budget_investment_progress_bars_path(budget, investment)
expect(page).to have_content("Primary")
expect(page).not_to have_content(secondary_progress_bar.title)
end
scenario "edit" do
primary_progress_bar = create(:progress_bar, progressable: investment)
secondary_progress_bar = create(:progress_bar,
:secondary,
title: "to edit",
progressable: investment)
visit tracking_budget_budget_investment_progress_bars_path(budget, investment)
expect(page).to have_content("Primary")
expect(page).to have_content(secondary_progress_bar.title)
page.find("#progress_bar_#{secondary_progress_bar.id}").click_link("Edit")
fill_in("Title", :with => "edited")
click_button "Update Progress bar"
expect(page).to have_content("Progress bars")
expect(page).to have_content("edited")
end
end
end

View File

@@ -0,0 +1,31 @@
require "rails_helper"
feature "Tracking budgets" do
background do
@tracker = create(:tracker, user: create(:user, username: "Rachel", email: "rachel@trackers.org"))
login_as(@tracker.user)
end
scenario "Disabled with a feature flag" do
Setting["process.budgets"] = nil
expect{ visit tracking_budgets_path }.to raise_exception(FeatureFlags::FeatureDisabled)
end
context "Index" do
scenario "Displaying budgets" do
budget = create(:budget)
visit tracking_budgets_path
expect(page).to have_content(budget.name)
end
scenario "With no budgets" do
visit tracking_budgets_path
expect(page).to have_content "There are no budgets"
end
end
end

View File

@@ -5,7 +5,7 @@ shared_examples "admin_progressable" do |factory_name, path_name|
let(:progressable_path) { send(path_name, *resource_hierarchy_for(progressable)) } let(:progressable_path) { send(path_name, *resource_hierarchy_for(progressable)) }
let(:path) do let(:path) do
polymorphic_path([:admin, *resource_hierarchy_for(progressable.progress_bars.new)]) polymorphic_path([:tracking, *resource_hierarchy_for(progressable.progress_bars.new)])
end end
context "Index" do context "Index" do