From 0f59b9c1d0133393f68194a366aafc27ca23392b Mon Sep 17 00:00:00 2001 From: cedricnjanga Date: Tue, 23 Jan 2018 22:46:16 -0800 Subject: First draft for including calendars into workgroup for having appropriate scoping --- app/controllers/calendars_controller.rb | 4 +++- app/decorators/calendar_decorator.rb | 2 +- app/helpers/table_builder_helper.rb | 8 +++++++- app/helpers/table_builder_helper/custom_links.rb | 7 ++++--- app/helpers/table_builder_helper/url.rb | 5 +++-- app/models/calendar.rb | 1 + app/models/workgroup.rb | 1 + app/views/calendars/_filters.html.slim | 4 ++-- app/views/calendars/index.html.slim | 4 ++-- app/views/dashboards/_dashboard.html.slim | 6 +++--- .../layouts/navigation/_main_nav_left_content_stif.html.slim | 2 +- app/views/stif/dashboards/_dashboard.html.slim | 4 ++-- config/routes.rb | 7 ++++--- db/migrate/20180123174450_add_workgroup_id_to_calendars.rb | 6 ++++++ db/schema.rb | 6 ++++-- lib/stif/dashboard.rb | 2 +- 16 files changed, 45 insertions(+), 24 deletions(-) create mode 100644 db/migrate/20180123174450_add_workgroup_id_to_calendars.rb diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb index 4a752f2b9..72d213953 100644 --- a/app/controllers/calendars_controller.rb +++ b/app/controllers/calendars_controller.rb @@ -7,7 +7,9 @@ class CalendarsController < ChouetteController def index index! do - @calendars = ModelDecorator.decorate(@calendars, with: CalendarDecorator) + @calendars = ModelDecorator.decorate(@calendars, with: CalendarDecorator, context: { + workgroup: current_workgroup + }) end end diff --git a/app/decorators/calendar_decorator.rb b/app/decorators/calendar_decorator.rb index 37e2cfe80..ce2c1a2dd 100644 --- a/app/decorators/calendar_decorator.rb +++ b/app/decorators/calendar_decorator.rb @@ -7,7 +7,7 @@ class CalendarDecorator < Draper::Decorator if h.policy(object).destroy? links << Link.new( content: h.destroy_link_content, - href: h.calendar_path(object), + href: h.workgroup_calendar_path(context[:workgroup], object), method: :delete, data: { confirm: h.t('calendars.actions.destroy_confirm') } ) diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb index dede51920..9ead7180a 100644 --- a/app/helpers/table_builder_helper.rb +++ b/app/helpers/table_builder_helper.rb @@ -308,7 +308,7 @@ module TableBuilderHelper menu = content_tag :ul, class: 'dropdown-menu' do ( - CustomLinks.new(item, pundit_user, links, referential).links + + CustomLinks.new(item, pundit_user, links, referential, workgroup).links + item.action_links.select { |link| link.is_a?(Link) } ).map do |link| gear_menu_link(link) @@ -391,4 +391,10 @@ module TableBuilderHelper # cases, avoid a `NoMethodError`. @__referential__ ||= try(:current_referential) end + + def workgroup + # Certain controllers don't define a `#current_referential`. In these + # cases, avoid a `NoMethodError`. + @__workgroup__ ||= try(:current_workgroup) + end end diff --git a/app/helpers/table_builder_helper/custom_links.rb b/app/helpers/table_builder_helper/custom_links.rb index b1bb11f10..e09078be0 100644 --- a/app/helpers/table_builder_helper/custom_links.rb +++ b/app/helpers/table_builder_helper/custom_links.rb @@ -8,13 +8,14 @@ module TableBuilderHelper unarchive: :put } - attr_reader :actions, :object, :user_context, :referential + attr_reader :actions, :object, :user_context, :referential, :workgroup - def initialize(object, user_context, actions, referential = nil) + def initialize(object, user_context, actions, referential = nil, workgroup = nil) @object = object @user_context = user_context @actions = actions @referential = referential + @workgroup = workgroup end def links @@ -34,7 +35,7 @@ module TableBuilderHelper polymorph_url << action end - polymorph_url += URL.polymorphic_url_parts(object, referential) + polymorph_url += URL.polymorphic_url_parts(object, referential, workgroup) end def method_for_action(action) diff --git a/app/helpers/table_builder_helper/url.rb b/app/helpers/table_builder_helper/url.rb index 28f1ade76..40e1f839f 100644 --- a/app/helpers/table_builder_helper/url.rb +++ b/app/helpers/table_builder_helper/url.rb @@ -1,9 +1,9 @@ module TableBuilderHelper class URL - def self.polymorphic_url_parts(item, referential) + def self.polymorphic_url_parts(item, referential, workgroup) polymorph_url = [] - unless item.is_a?(Calendar) || item.is_a?(Referential) || item.is_a?(ComplianceControlSet) + unless item.is_a?(Referential) || item.is_a?(ComplianceControlSet) if referential polymorph_url << referential polymorph_url << item.line if item.respond_to? :line @@ -20,6 +20,7 @@ module TableBuilderHelper end end else + polymorph_url << item.workgroup if item.is_a?(Calendar) polymorph_url << item end diff --git a/app/models/calendar.rb b/app/models/calendar.rb index a7fd9220c..236223892 100644 --- a/app/models/calendar.rb +++ b/app/models/calendar.rb @@ -8,6 +8,7 @@ class Calendar < ActiveRecord::Base has_paper_trail class_name: 'PublicVersion' belongs_to :organisation + belongs_to :workgroup validates_presence_of :name, :short_name, :organisation validates_uniqueness_of :short_name diff --git a/app/models/workgroup.rb b/app/models/workgroup.rb index 3d761e81f..3af20ae23 100644 --- a/app/models/workgroup.rb +++ b/app/models/workgroup.rb @@ -3,6 +3,7 @@ class Workgroup < ActiveRecord::Base belongs_to :stop_area_referential has_many :workbenches + has_many :calendars has_many :organisations, through: :workbenches has_many :referentials, through: :workbenches diff --git a/app/views/calendars/_filters.html.slim b/app/views/calendars/_filters.html.slim index b5283c1e8..c1d8c47f7 100644 --- a/app/views/calendars/_filters.html.slim +++ b/app/views/calendars/_filters.html.slim @@ -1,4 +1,4 @@ -= search_form_for @q, url: calendars_path, builder: SimpleForm::FormBuilder, html: { method: :get, class: 'form form-filter' } do |f| += search_form_for @q, url: workgroup_calendars_path(current_workgroup), builder: SimpleForm::FormBuilder, html: { method: :get, class: 'form form-filter' } do |f| .ffg-row .input-group.search_bar = f.search_field :name_or_short_name_cont, class: 'form-control', placeholder: 'Indiquez un nom/nom court de calendrier...' @@ -18,5 +18,5 @@ = f.input :contains_date, as: :date, label: false, wrapper_html: { class: 'date smart_date' }, class: 'form-control', include_blank: true .actions - = link_to 'Effacer', calendars_path, class: 'btn btn-link' + = link_to 'Effacer', workgroup_calendars_path(current_workgroup), class: 'btn btn-link' = f.submit 'Filtrer', id: 'calendar_filter_btn', class: 'btn btn-default' diff --git a/app/views/calendars/index.html.slim b/app/views/calendars/index.html.slim index 77478a624..d0544856d 100644 --- a/app/views/calendars/index.html.slim +++ b/app/views/calendars/index.html.slim @@ -1,7 +1,7 @@ - breadcrumb :calendars - content_for :page_header_actions do - if policy(Calendar).create? - = link_to(t('actions.add'), new_calendar_path, class: 'btn btn-default') + = link_to(t('actions.add'), new_workgroup_calendar_path(current_workgroup), class: 'btn btn-default') .page_content .container-fluid @@ -19,7 +19,7 @@ key: :name, \ attribute: 'name', \ link_to: lambda do |calendar| \ - calendar_path(calendar) \ + workgroup_calendar_path(current_workgroup, calendar) \ end \ ), \ TableBuilderHelper::Column.new( \ diff --git a/app/views/dashboards/_dashboard.html.slim b/app/views/dashboards/_dashboard.html.slim index 075b94ddc..58cfcc542 100644 --- a/app/views/dashboards/_dashboard.html.slim +++ b/app/views/dashboards/_dashboard.html.slim @@ -22,13 +22,13 @@ .panel.panel-default .panel-heading h3.panel-title.with_actions - = link_to I18n.t("activerecord.models.calendar", count: @dashboard.current_organisation.calendars.size), calendars_path + = link_to I18n.t("activerecord.models.calendar", count: @dashboard.current_organisation.calendars.size), workgroup_calendars_path(current_workgroup) div - = link_to '', calendars_path, class: ' fa fa-chevron-right pull-right' + = link_to '', workgroup_calendars_path(current_workgroup), class: ' fa fa-chevron-right pull-right' - if @dashboard.current_organisation.calendars.present? .list-group - @dashboard.current_organisation.calendars.order("updated_at desc").limit(5).each do |calendar| - = link_to calendar.name, calendar_path(calendar), class: 'list-group-item' + = link_to calendar.name, workgroup_calendars_path(current_workgroup, calendar), class: 'list-group-item' - else .panel-body em.small.text-muted diff --git a/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim b/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim index 3963d4cd4..1b7293d21 100644 --- a/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim +++ b/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim @@ -29,7 +29,7 @@ span Jeux de données = link_to workbench_imports_path(current_offer_workbench), class: "list-group-item #{(params[:controller] == 'imports') ? 'active' : ''}" do span Import - = link_to calendars_path, class: 'list-group-item' do + = link_to workgroup_calendars_path(current_workgroup), class: 'list-group-item' do span Modèles de calendrier = link_to workbench_compliance_check_sets_path(current_offer_workbench), class: 'list-group-item' do span Rapport de contrôle diff --git a/app/views/stif/dashboards/_dashboard.html.slim b/app/views/stif/dashboards/_dashboard.html.slim index 64e7d4f96..c28696a94 100644 --- a/app/views/stif/dashboards/_dashboard.html.slim +++ b/app/views/stif/dashboards/_dashboard.html.slim @@ -60,12 +60,12 @@ span.badge.ml-xs = @dashboard.calendars.count if @dashboard.calendars.present? div - = link_to '', calendars_path, class: ' fa fa-chevron-right pull-right', title: t('.see') + = link_to '', workgroup_calendars_path(current_workgroup), class: ' fa fa-chevron-right pull-right', title: t('.see') - if @dashboard.calendars.present? .list-group - @dashboard.calendars.first(5).each_with_index do |calendar, i| - = link_to calendar.name, calendar_path(calendar), class: 'list-group-item' if i < 6 + = link_to calendar.name, workgroup_calendar_path(current_workgroup, calendar), class: 'list-group-item' if i < 6 - else .panel-body diff --git a/config/routes.rb b/config/routes.rb index 0f60733af..6a6a7cb07 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -111,9 +111,10 @@ ChouetteIhm::Application.routes.draw do resources :companies resources :networks end - - resources :calendars do - get :autocomplete, on: :collection, controller: 'autocomplete_calendars' + resources :workgroups do + resources :calendars do + get :autocomplete, on: :collection, controller: 'autocomplete_calendars' + end end resources :referentials, except: :index do diff --git a/db/migrate/20180123174450_add_workgroup_id_to_calendars.rb b/db/migrate/20180123174450_add_workgroup_id_to_calendars.rb new file mode 100644 index 000000000..64ad1a752 --- /dev/null +++ b/db/migrate/20180123174450_add_workgroup_id_to_calendars.rb @@ -0,0 +1,6 @@ +class AddWorkgroupIdToCalendars < ActiveRecord::Migration + def change + add_column :calendars, :workgroup_id, :integer, limit: 8 + add_index :calendars, :workgroup_id + end +end diff --git a/db/schema.rb b/db/schema.rb index 2c5520110..11fb96ee3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180111200406) do +ActiveRecord::Schema.define(version: 20180123174450) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -90,10 +90,12 @@ ActiveRecord::Schema.define(version: 20180111200406) do t.integer "organisation_id", limit: 8 t.datetime "created_at" t.datetime "updated_at" + t.integer "workgroup_id", limit: 8 end add_index "calendars", ["organisation_id"], name: "index_calendars_on_organisation_id", using: :btree add_index "calendars", ["short_name"], name: "index_calendars_on_short_name", unique: true, using: :btree + add_index "calendars", ["workgroup_id"], name: "index_calendars_on_workgroup_id", using: :btree create_table "clean_up_results", id: :bigserial, force: :cascade do |t| t.string "message_key" @@ -416,9 +418,9 @@ ActiveRecord::Schema.define(version: 20180111200406) do t.string "type" t.integer "parent_id", limit: 8 t.string "parent_type" - t.datetime "notified_parent_at" t.integer "current_step", default: 0 t.integer "total_steps", default: 0 + t.datetime "notified_parent_at" t.string "creator" end diff --git a/lib/stif/dashboard.rb b/lib/stif/dashboard.rb index b6b6b8284..7dd83efbc 100644 --- a/lib/stif/dashboard.rb +++ b/lib/stif/dashboard.rb @@ -9,7 +9,7 @@ module Stif end def calendars - @calendars ||= Calendar.where('organisation_id = ? OR shared = ?', current_organisation.id, true) + @calendars ||= Calendar.where('workgroup_id = ? OR shared = ?', @workbench.workgroup_id, true) end end end -- cgit v1.2.3 From f32d869cc3f34a939764cc3fa4d612a5d6544d08 Mon Sep 17 00:00:00 2001 From: cedricnjanga Date: Wed, 24 Jan 2018 19:55:56 -0800 Subject: update calendar build_links for table builder --- app/controllers/calendars_controller.rb | 25 +++++++++++++++++++------ app/controllers/concerns/workgroup_support.rb | 12 ++++++++++++ app/helpers/table_builder_helper/url.rb | 4 ++-- app/models/calendar.rb | 2 +- app/views/calendars/_form.html.slim | 2 +- app/views/calendars/edit.html.slim | 2 +- app/views/calendars/index.html.slim | 2 +- app/views/calendars/new.html.slim | 2 +- app/views/calendars/show.html.slim | 4 ++-- config/breadcrumbs.rb | 10 +++++----- lib/stif/dashboard.rb | 6 +++++- 11 files changed, 50 insertions(+), 21 deletions(-) create mode 100644 app/controllers/concerns/workgroup_support.rb diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb index 72d213953..27c944f5f 100644 --- a/app/controllers/calendars_controller.rb +++ b/app/controllers/calendars_controller.rb @@ -1,4 +1,5 @@ class CalendarsController < ChouetteController + include WorkgroupSupport include PolicyChecker defaults resource_class: Calendar before_action :ransack_contains_date, only: [:index] @@ -7,19 +8,30 @@ class CalendarsController < ChouetteController def index index! do - @calendars = ModelDecorator.decorate(@calendars, with: CalendarDecorator, context: { - workgroup: current_workgroup - }) + @calendars = decorate_calendars(@calendars) end end def show show! do - @calendar = @calendar.decorate + @calendar = @calendar.decorate(context: { + workgroup: current_workgroup + }) end end private + + def decorate_calendars(calendars) + ModelDecorator.decorate( + calendars, + with: CalendarDecorator, + context: { + workgroup: current_workgroup + } + ) + end + def calendar_params permitted_params = [:id, :name, :short_name, :shared, periods_attributes: [:id, :begin, :end, :_destroy], date_values_attributes: [:id, :value, :_destroy]] permitted_params << :shared if policy(Calendar).share? @@ -36,18 +48,19 @@ class CalendarsController < ChouetteController protected def resource - @calendar = Calendar.where('organisation_id = ? OR shared = true', current_organisation.id).find_by_id(params[:id]) + @calendar = Calendar.where('(organisation_id = ? OR shared = ?) AND workgroup_id = ?', current_organisation.id).find_by_id(params[:id], true, @workgroup.id) end def build_resource super.tap do |calendar| + calendar.workgroup = current_workgroup calendar.organisation = current_organisation end end def collection return @calendars if @calendars - scope = Calendar.where('organisation_id = ? OR shared = ?', current_organisation.id, true) + scope = Calendar.where('(organisation_id = ? OR shared = ?) AND workgroup_id = ?', current_organisation.id, true, @workgroup.id) scope = shared_scope(scope) @q = scope.ransack(params[:q]) diff --git a/app/controllers/concerns/workgroup_support.rb b/app/controllers/concerns/workgroup_support.rb new file mode 100644 index 000000000..a3b49bb12 --- /dev/null +++ b/app/controllers/concerns/workgroup_support.rb @@ -0,0 +1,12 @@ +module WorkgroupSupport + extend ActiveSupport::Concern + + included do + before_action :find_workgroup + end + + def find_workgroup + @workgroup ||= Workgroup.find params[:workgroup_id] + end + +end diff --git a/app/helpers/table_builder_helper/url.rb b/app/helpers/table_builder_helper/url.rb index 40e1f839f..0e3dce0aa 100644 --- a/app/helpers/table_builder_helper/url.rb +++ b/app/helpers/table_builder_helper/url.rb @@ -3,7 +3,7 @@ module TableBuilderHelper def self.polymorphic_url_parts(item, referential, workgroup) polymorph_url = [] - unless item.is_a?(Referential) || item.is_a?(ComplianceControlSet) + unless item.is_a?(Calendar) || item.is_a?(Referential) || item.is_a?(ComplianceControlSet) if referential polymorph_url << referential polymorph_url << item.line if item.respond_to? :line @@ -20,7 +20,7 @@ module TableBuilderHelper end end else - polymorph_url << item.workgroup if item.is_a?(Calendar) + polymorph_url << item.workgroup if item.respond_to? :workgroup polymorph_url << item end diff --git a/app/models/calendar.rb b/app/models/calendar.rb index 236223892..d93532908 100644 --- a/app/models/calendar.rb +++ b/app/models/calendar.rb @@ -10,7 +10,7 @@ class Calendar < ActiveRecord::Base belongs_to :organisation belongs_to :workgroup - validates_presence_of :name, :short_name, :organisation + validates_presence_of :name, :short_name, :organisation, :workgroup validates_uniqueness_of :short_name has_many :time_tables diff --git a/app/views/calendars/_form.html.slim b/app/views/calendars/_form.html.slim index 3c152c61d..bf9f4f3a7 100644 --- a/app/views/calendars/_form.html.slim +++ b/app/views/calendars/_form.html.slim @@ -1,4 +1,4 @@ -= simple_form_for @calendar, html: { class: 'form-horizontal', id: 'calendar_form' }, wrapper: :horizontal_form do |f| += simple_form_for [@workgroup, @calendar], html: { class: 'form-horizontal', id: 'calendar_form' }, wrapper: :horizontal_form do |f| .row .col-lg-12 = f.input :name diff --git a/app/views/calendars/edit.html.slim b/app/views/calendars/edit.html.slim index e806fc94b..a1af5e257 100644 --- a/app/views/calendars/edit.html.slim +++ b/app/views/calendars/edit.html.slim @@ -1,4 +1,4 @@ -- breadcrumb :calendar, @calendar +- breadcrumb :calendar, @workgroup, @calendar - page_header_content_for @calendar .page_content .container-fluid diff --git a/app/views/calendars/index.html.slim b/app/views/calendars/index.html.slim index d0544856d..60bc9793d 100644 --- a/app/views/calendars/index.html.slim +++ b/app/views/calendars/index.html.slim @@ -1,4 +1,4 @@ -- breadcrumb :calendars +- breadcrumb :calendars, current_workgroup - content_for :page_header_actions do - if policy(Calendar).create? = link_to(t('actions.add'), new_workgroup_calendar_path(current_workgroup), class: 'btn btn-default') diff --git a/app/views/calendars/new.html.slim b/app/views/calendars/new.html.slim index ce8b6a036..c1e084913 100644 --- a/app/views/calendars/new.html.slim +++ b/app/views/calendars/new.html.slim @@ -1,4 +1,4 @@ -- breadcrumb :calendars +- breadcrumb :calendars, @workgroup .page_content .container-fluid .row diff --git a/app/views/calendars/show.html.slim b/app/views/calendars/show.html.slim index da4afa3e6..9f7512173 100644 --- a/app/views/calendars/show.html.slim +++ b/app/views/calendars/show.html.slim @@ -1,4 +1,4 @@ -- breadcrumb :calendar, @calendar +- breadcrumb :calendar, @workgroup, @calendar - page_header_content_for @calendar - content_for :page_header_content do .row.mb-sm @@ -11,7 +11,7 @@ = link.content - if policy(@calendar).edit? - content_for :page_header_actions do - = link_to(t('actions.edit'), edit_calendar_path(@calendar), class: 'btn btn-default') + = link_to(t('actions.edit'), edit_workgroup_calendar_path(@workgroup, @calendar), class: 'btn btn-default') .page_content .container-fluid diff --git a/config/breadcrumbs.rb b/config/breadcrumbs.rb index 6da96d73a..2772895fe 100644 --- a/config/breadcrumbs.rb +++ b/config/breadcrumbs.rb @@ -202,13 +202,13 @@ crumb :purchase_window do |referential, purchase_window| parent :purchase_windows, referential end -crumb :calendars do - link I18n.t('calendars.index.title'), calendars_path +crumb :calendars do |workgroup| + link I18n.t('calendars.index.title'), workgroup_calendars_path(workgroup) end -crumb :calendar do |calendar| - link breadcrumb_name(calendar), calendar_path(calendar) - parent :calendars +crumb :calendar do |workgroup, calendar| + link breadcrumb_name(calendar), workgroup_calendar_path(workgroup, calendar) + parent :calendars, workgroup end crumb :referential_line do |referential, line| diff --git a/lib/stif/dashboard.rb b/lib/stif/dashboard.rb index 7dd83efbc..46c635091 100644 --- a/lib/stif/dashboard.rb +++ b/lib/stif/dashboard.rb @@ -4,12 +4,16 @@ module Stif @workbench ||= current_organisation.workbenches.find_by(name: "Gestion de l'offre") end + def workgroup + workbench.workgroup + end + def referentials @referentials ||= self.workbench.all_referentials end def calendars - @calendars ||= Calendar.where('workgroup_id = ? OR shared = ?', @workbench.workgroup_id, true) + @calendars ||= Calendar.where('(organisation_id = ? OR shared = ?) AND workgroup_id = ?', current_organisation.id, true, workgroup.id) end end end -- cgit v1.2.3 From 4023ea52097a47458ac2fcad36d343aba0c8e68b Mon Sep 17 00:00:00 2001 From: cedricnjanga Date: Tue, 30 Jan 2018 23:07:07 -0800 Subject: Make some changes to avoid unnacessaty lines of code --- app/controllers/calendars_controller.rb | 33 +++++++++++++++++------------ app/views/calendars/index.html.slim | 4 ++-- spec/factories/calendars.rb | 1 + spec/features/calendars_permissions_spec.rb | 7 +++--- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb index 27c944f5f..193680342 100644 --- a/app/controllers/calendars_controller.rb +++ b/app/controllers/calendars_controller.rb @@ -1,10 +1,11 @@ class CalendarsController < ChouetteController - include WorkgroupSupport include PolicyChecker defaults resource_class: Calendar before_action :ransack_contains_date, only: [:index] respond_to :html respond_to :js, only: :index + + belongs_to :workgroup def index index! do @@ -15,7 +16,7 @@ class CalendarsController < ChouetteController def show show! do @calendar = @calendar.decorate(context: { - workgroup: current_workgroup + workgroup: workgroup }) end end @@ -27,7 +28,7 @@ class CalendarsController < ChouetteController calendars, with: CalendarDecorator, context: { - workgroup: current_workgroup + workgroup: workgroup } ) end @@ -47,26 +48,30 @@ class CalendarsController < ChouetteController end protected + + alias_method :workgroup, :parent + helper_method :workgroup + def resource - @calendar = Calendar.where('(organisation_id = ? OR shared = ?) AND workgroup_id = ?', current_organisation.id).find_by_id(params[:id], true, @workgroup.id) + @calendar ||= workgroup.calendars.where('(organisation_id = ? OR shared = ?)', current_organisation.id, true).find_by_id(params[:id]) end def build_resource super.tap do |calendar| - calendar.workgroup = current_workgroup + calendar.workgroup = workgroup calendar.organisation = current_organisation end end def collection - return @calendars if @calendars - scope = Calendar.where('(organisation_id = ? OR shared = ?) AND workgroup_id = ?', current_organisation.id, true, @workgroup.id) - scope = shared_scope(scope) - @q = scope.ransack(params[:q]) - - calendars = @q.result - calendars = calendars.order(sort_column + ' ' + sort_direction) if sort_column && sort_direction - @calendars = calendars.paginate(page: params[:page]) + @calendars ||= begin + scope = workgroup.calendars.where('(organisation_id = ? OR shared = ?)', current_organisation.id, true) + scope = shared_scope(scope) + @q = scope.ransack(params[:q]) + calendars = @q.result + calendars = calendars.order(sort_column + ' ' + sort_direction) if sort_column && sort_direction + calendars = calendars.paginate(page: params[:page]) + end end def ransack_contains_date @@ -91,4 +96,4 @@ class CalendarsController < ChouetteController scope end -end +end \ No newline at end of file diff --git a/app/views/calendars/index.html.slim b/app/views/calendars/index.html.slim index 309f0e6f9..0b58c0c72 100644 --- a/app/views/calendars/index.html.slim +++ b/app/views/calendars/index.html.slim @@ -1,4 +1,4 @@ -- breadcrumb :calendars, current_workgroup +- breadcrumb :calendars, workgroup .page_content .container-fluid @@ -16,7 +16,7 @@ key: :name, \ attribute: 'name', \ link_to: lambda do |calendar| \ - workgroup_calendar_path(current_workgroup, calendar) \ + workgroup_calendar_path(workgroup, calendar) \ end \ ), \ TableBuilderHelper::Column.new( \ diff --git a/spec/factories/calendars.rb b/spec/factories/calendars.rb index 5f3188bee..d9fd242d1 100644 --- a/spec/factories/calendars.rb +++ b/spec/factories/calendars.rb @@ -6,6 +6,7 @@ FactoryGirl.define do sequence(:dates) { |n| [ Date.yesterday - n, Date.yesterday - 2*n ] } shared false organisation + workgroup end sequence :date_range do |n| diff --git a/spec/features/calendars_permissions_spec.rb b/spec/features/calendars_permissions_spec.rb index 9b47ab2bb..4857592d5 100644 --- a/spec/features/calendars_permissions_spec.rb +++ b/spec/features/calendars_permissions_spec.rb @@ -2,6 +2,7 @@ RSpec.describe 'Calendars', type: :feature do login_user let(:calendar) { create :calendar, organisation_id: 1 } + let(:workgroup) { calendar.workgroup } describe 'permissions' do before do @@ -13,7 +14,7 @@ RSpec.describe 'Calendars', type: :feature do end context 'on show view' do - let( :path ){ calendar_path(calendar) } + let( :path ){ workgroup_calendar_path(workgroup, calendar) } context 'if present → ' do let( :permission ){ true } @@ -33,7 +34,7 @@ RSpec.describe 'Calendars', type: :feature do end context 'on edit view' do - let( :path ){ edit_calendar_path(calendar) } + let( :path ){ edit_workgroup_calendar_path(workgroup, calendar) } context 'if present → ' do let( :permission ){ true } @@ -51,7 +52,7 @@ RSpec.describe 'Calendars', type: :feature do end context 'on index view' do - let( :path ){ calendars_path } + let( :path ){ workgroup_calendars_path(workgroup) } context 'if present → ' do let( :permission ){ true } -- cgit v1.2.3 From fe7915ffac359db41c7737a3847f31a728f502e6 Mon Sep 17 00:00:00 2001 From: Zog Date: Wed, 31 Jan 2018 11:39:39 +0100 Subject: Refs #5683 @2H; Fix specs and refactor action_links Note: Did not fix the missing workgroup in the calendar mailer --- app/controllers/calendars_controller.rb | 21 ++++---- app/decorators/calendar_decorator.rb | 2 + app/decorators/company_decorator.rb | 19 ++----- app/decorators/compliance_control_decorator.rb | 18 ++----- app/decorators/import_decorator.rb | 7 ++- app/decorators/line_decorator.rb | 10 ++-- app/decorators/network_decorator.rb | 14 +---- app/decorators/purchase_window_decorator.rb | 18 ++----- app/decorators/referential_line_decorator.rb | 10 ++-- app/decorators/referential_network_decorator.rb | 21 ++------ app/decorators/route_decorator.rb | 29 ++-------- .../routing_constraint_zone_decorator.rb | 39 ++------------ app/decorators/stop_area_decorator.rb | 22 +------- app/helpers/table_builder_helper.rb | 1 - lib/af83/decorator.rb | 63 ++++++++++++---------- lib/af83/decorator/enhanced_decorator.rb | 22 ++++++-- lib/af83/decorator/link.rb | 3 +- spec/support/pundit/pundit_view_policy.rb | 5 +- spec/support/referential.rb | 4 +- spec/views/referentials/show.html.erb_spec.rb | 6 ++- 20 files changed, 114 insertions(+), 220 deletions(-) diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb index 193680342..6f1522428 100644 --- a/app/controllers/calendars_controller.rb +++ b/app/controllers/calendars_controller.rb @@ -4,7 +4,7 @@ class CalendarsController < ChouetteController before_action :ransack_contains_date, only: [:index] respond_to :html respond_to :js, only: :index - + belongs_to :workgroup def index @@ -24,9 +24,8 @@ class CalendarsController < ChouetteController private def decorate_calendars(calendars) - ModelDecorator.decorate( + CalendarDecorator.decorate( calendars, - with: CalendarDecorator, context: { workgroup: workgroup } @@ -65,13 +64,13 @@ class CalendarsController < ChouetteController def collection @calendars ||= begin - scope = workgroup.calendars.where('(organisation_id = ? OR shared = ?)', current_organisation.id, true) - scope = shared_scope(scope) - @q = scope.ransack(params[:q]) - calendars = @q.result - calendars = calendars.order(sort_column + ' ' + sort_direction) if sort_column && sort_direction - calendars = calendars.paginate(page: params[:page]) - end + scope = workgroup.calendars.where('(organisation_id = ? OR shared = ?)', current_organisation.id, true) + scope = shared_scope(scope) + @q = scope.ransack(params[:q]) + calendars = @q.result + calendars = calendars.order(sort_column + ' ' + sort_direction) if sort_column && sort_direction + calendars = calendars.paginate(page: params[:page]) + end end def ransack_contains_date @@ -96,4 +95,4 @@ class CalendarsController < ChouetteController scope end -end \ No newline at end of file +end diff --git a/app/decorators/calendar_decorator.rb b/app/decorators/calendar_decorator.rb index be1f9e3bf..0a7cbc312 100644 --- a/app/decorators/calendar_decorator.rb +++ b/app/decorators/calendar_decorator.rb @@ -1,6 +1,8 @@ class CalendarDecorator < AF83::Decorator decorates Calendar + set_scope { context[:workgroup] } + create_action_link with_instance_decorator do |instance_decorator| diff --git a/app/decorators/company_decorator.rb b/app/decorators/company_decorator.rb index aadce68bb..5580e0d4a 100644 --- a/app/decorators/company_decorator.rb +++ b/app/decorators/company_decorator.rb @@ -1,34 +1,21 @@ class CompanyDecorator < AF83::Decorator decorates Chouette::Company + set_scope { context[:referential] } + create_action_link do |l| l.content { h.t('companies.actions.new') } - l.href { [:new, context[:referential], :company] } end with_instance_decorator do |instance_decorator| - instance_decorator.show_action_link do |l| - l.href { [context[:referential], object] } - end + instance_decorator.show_action_link instance_decorator.edit_action_link do |l| l.content {|l| l.action == "show" ? h.t('actions.edit') : h.t('companies.actions.edit') } - l.href { - h.edit_line_referential_company_path( - context[:referential], - object - ) - } end instance_decorator.destroy_action_link do |l| l.content { h.destroy_link_content('companies.actions.destroy') } - l.href { - h.edit_line_referential_company_path( - context[:referential], - object - ) - } l.data {{ confirm: h.t('companies.actions.destroy_confirm') }} end end diff --git a/app/decorators/compliance_control_decorator.rb b/app/decorators/compliance_control_decorator.rb index c57a7ccc7..fd2dbd9ce 100644 --- a/app/decorators/compliance_control_decorator.rb +++ b/app/decorators/compliance_control_decorator.rb @@ -1,6 +1,8 @@ class ComplianceControlDecorator < AF83::Decorator decorates ComplianceControl + set_scope { object.compliance_control_set } + with_instance_decorator do |instance_decorator| instance_decorator.show_action_link do |l| l.content h.t('compliance_control_sets.actions.show') @@ -12,23 +14,9 @@ class ComplianceControlDecorator < AF83::Decorator end end - instance_decorator.edit_action_link do |l| - l.href do - h.edit_compliance_control_set_compliance_control_path( - object.compliance_control_set_id, - object.id - ) - end - end + instance_decorator.edit_action_link instance_decorator.destroy_action_link do |l| - l.content h.destroy_link_content - l.href do - h.compliance_control_set_compliance_control_path( - object.compliance_control_set.id, - object.id - ) - end l.data confirm: h.t('compliance_controls.actions.destroy_confirm') end end diff --git a/app/decorators/import_decorator.rb b/app/decorators/import_decorator.rb index c6b1f2349..1964365ae 100644 --- a/app/decorators/import_decorator.rb +++ b/app/decorators/import_decorator.rb @@ -1,6 +1,8 @@ class ImportDecorator < AF83::Decorator decorates Import + set_scope { context[:workbench] } + define_instance_method :import_status_css_class do cls ='' cls = 'overheaded-success' if object.status == 'successful' @@ -11,13 +13,10 @@ class ImportDecorator < AF83::Decorator create_action_link do |l| l.content t('imports.actions.new') - l.href { h.new_workbench_import_path(workbench_id: context[:workbench]) } end with_instance_decorator do |instance_decorator| - instance_decorator.show_action_link do |l| - l.href { h.workbench_import_path(context[:workbench], object) } - end + instance_decorator.show_action_link instance_decorator.action_link secondary: :show do |l| l.content t('imports.actions.download') diff --git a/app/decorators/line_decorator.rb b/app/decorators/line_decorator.rb index 9171a6310..039ad90a3 100644 --- a/app/decorators/line_decorator.rb +++ b/app/decorators/line_decorator.rb @@ -1,9 +1,10 @@ class LineDecorator < AF83::Decorator decorates Chouette::Line + set_scope { context[:line_referential] } + create_action_link do |l| l.content t('lines.actions.new') - l.href { h.new_line_referential_line_path(context[:line_referential]) } end with_instance_decorator do |instance_decorator| @@ -14,17 +15,16 @@ class LineDecorator < AF83::Decorator instance_decorator.show_action_link do |l| l.content t('lines.actions.show') - l.href { [context[:line_referential], object] } end instance_decorator.action_link secondary: :show do |l| l.content t('lines.actions.show_network') - l.href { [context[:line_referential], object.network] } + l.href { [scope, object.network] } end instance_decorator.action_link secondary: :show do |l| l.content t('lines.actions.show_company') - l.href { [context[:line_referential], object.company] } + l.href { [scope, object.company] } l.disabled { object.company.nil? } end @@ -33,7 +33,6 @@ class LineDecorator < AF83::Decorator instance_decorator.with_condition can_edit_line do edit_action_link do |l| l.content {|l| l.primary? ? h.t('actions.edit') : h.t('lines.actions.edit') } - l.href { h.edit_line_referential_line_path(context[:line_referential], object.id) } end action_link on: :index, secondary: :index do |l| @@ -63,7 +62,6 @@ class LineDecorator < AF83::Decorator instance_decorator.destroy_action_link do |l| l.content { h.destroy_link_content('lines.actions.destroy') } - l.href { h.line_referential_line_path(context[:line_referential], object) } l.data confirm: h.t('lines.actions.destroy_confirm') l.add_class "delete-action" end diff --git a/app/decorators/network_decorator.rb b/app/decorators/network_decorator.rb index 90f0d0e82..ea0f73dc2 100644 --- a/app/decorators/network_decorator.rb +++ b/app/decorators/network_decorator.rb @@ -1,6 +1,7 @@ class NetworkDecorator < AF83::Decorator decorates Chouette::Network + set_scope { context[:line_referential] } # Action links require: # context: { # line_referential: , @@ -8,15 +9,10 @@ class NetworkDecorator < AF83::Decorator create_action_link do |l| l.content t('networks.actions.new') - l.href { h.new_line_referential_network_path(context[:line_referential]) } end with_instance_decorator do |instance_decorator| - instance_decorator.show_action_link do |l| - l.href do - h.line_referential_network_path(context[:line_referential], object) - end - end + instance_decorator.show_action_link instance_decorator.action_link secondary: true, policy: :edit do |l| l.content t('networks.actions.edit') @@ -30,12 +26,6 @@ class NetworkDecorator < AF83::Decorator instance_decorator.destroy_action_link do |l| l.content h.destroy_link_content('networks.actions.destroy') - l.href do - h.line_referential_network_path( - context[:line_referential], - object - ) - end l.data confirm: h.t('networks.actions.destroy_confirm') end end diff --git a/app/decorators/purchase_window_decorator.rb b/app/decorators/purchase_window_decorator.rb index 54b241173..9b58577b2 100644 --- a/app/decorators/purchase_window_decorator.rb +++ b/app/decorators/purchase_window_decorator.rb @@ -1,32 +1,20 @@ class PurchaseWindowDecorator < AF83::Decorator decorates Chouette::PurchaseWindow + set_scope { context[:referential] } + create_action_link do |l| l.content t('purchase_windows.actions.new') - l.href { h.new_referential_purchase_window_path(context[:referential]) } end with_instance_decorator do |instance_decorator| instance_decorator.show_action_link do |l| l.content t('purchase_windows.actions.show') - l.href do - h.referential_purchase_window_path( - context[:referential], - object - ) - end end - instance_decorator.edit_action_link do |l| - l.href do - h.edit_referential_purchase_window_path(context[:referential].id, object) - end - end + instance_decorator.edit_action_link instance_decorator.destroy_action_link do |l| - l.href do - h.referential_purchase_window_path(context[:referential].id, object) - end l.data confirm: h.t('purchase_windows.actions.destroy_confirm') end end diff --git a/app/decorators/referential_line_decorator.rb b/app/decorators/referential_line_decorator.rb index 8f884a8e0..3ac846d76 100644 --- a/app/decorators/referential_line_decorator.rb +++ b/app/decorators/referential_line_decorator.rb @@ -1,6 +1,8 @@ class ReferentialLineDecorator < AF83::Decorator decorates Chouette::Line + set_scope { context[:referential] } + # Action links require: # context: { # referential: , @@ -8,9 +10,7 @@ class ReferentialLineDecorator < AF83::Decorator # } with_instance_decorator do |instance_decorator| - instance_decorator.show_action_link do |l| - l.href { h.referential_line_path(context[:referential], object) } - end + instance_decorator.show_action_link instance_decorator.action_link secondary: true do |l| l.content Chouette::Line.human_attribute_name(:footnotes) @@ -21,7 +21,7 @@ class ReferentialLineDecorator < AF83::Decorator l.content h.t('routing_constraint_zones.index.title') l.href do h.referential_line_routing_constraint_zones_path( - context[:referential], + scope, object ) end @@ -37,7 +37,7 @@ class ReferentialLineDecorator < AF83::Decorator secondary: true ) do |l| l.content h.t('routes.actions.new') - l.href { h.new_referential_line_route_path(context[:referential], object) } + l.href { h.new_referential_line_route_path(scope, object) } end end end diff --git a/app/decorators/referential_network_decorator.rb b/app/decorators/referential_network_decorator.rb index ff3467188..c508452c0 100644 --- a/app/decorators/referential_network_decorator.rb +++ b/app/decorators/referential_network_decorator.rb @@ -1,6 +1,8 @@ class ReferentialNetworkDecorator < AF83::Decorator decorates Chouette::Network + set_scope { context[:referential] } + # Action links require: # context: { # referential: , @@ -8,33 +10,18 @@ class ReferentialNetworkDecorator < AF83::Decorator create_action_link do |l| l.content t('networks.actions.new') - l.href { h.new_referential_network_path(context[:referential]) } end with_instance_decorator do |instance_decorator| - instance_decorator.show_action_link do |l| - l.href { h.referential_network_path(context[:referential], object) } - end + instance_decorator.show_action_link instance_decorator.edit_action_link do |l| l.content t('networks.actions.edit') - l.href do - h.edit_referential_network_path( - context[:referential], - object - ) - end end instance_decorator.destroy_action_link do |l| l.content h.destroy_link_content('networks.actions.destroy') - l.href do - h.referential_network_path( - context[:referential], - object - ) - end l.data confirm: h.t('networks.actions.destroy_confirm') end end -end \ No newline at end of file +end diff --git a/app/decorators/route_decorator.rb b/app/decorators/route_decorator.rb index 7e3ea889f..75ef20d63 100644 --- a/app/decorators/route_decorator.rb +++ b/app/decorators/route_decorator.rb @@ -7,26 +7,12 @@ class RouteDecorator < AF83::Decorator # line: # } + set_scope { [context[:referential], context[:line]] } + with_instance_decorator do |instance_decorator| - instance_decorator.show_action_link do |l| - l.href do - h.referential_line_route_path( - context[:referential], - context[:line], - object - ) - end - end + instance_decorator.show_action_link - instance_decorator.edit_action_link do |l| - l.href do - h.edit_referential_line_route_path( - context[:referential], - context[:line], - object - ) - end - end + instance_decorator.edit_action_link instance_decorator.action_link( if: ->() { object.stop_points.any? }, @@ -85,13 +71,6 @@ class RouteDecorator < AF83::Decorator end instance_decorator.destroy_action_link do |l| - l.href do - h.referential_line_route_path( - context[:referential], - context[:line], - object - ) - end l.data confirm: h.t('routes.actions.destroy_confirm') end end diff --git a/app/decorators/routing_constraint_zone_decorator.rb b/app/decorators/routing_constraint_zone_decorator.rb index 962625fa7..de73068be 100644 --- a/app/decorators/routing_constraint_zone_decorator.rb +++ b/app/decorators/routing_constraint_zone_decorator.rb @@ -1,6 +1,8 @@ class RoutingConstraintZoneDecorator < AF83::Decorator decorates Chouette::RoutingConstraintZone + set_scope { [context[:referential], context[:line]] } + # Action links require: # context: { # referential: , @@ -12,44 +14,13 @@ class RoutingConstraintZoneDecorator < AF83::Decorator h.policy(Chouette::RoutingConstraintZone).create? && context[:referential].organisation == h.current_organisation } - ) do |l| - l.href do - h.new_referential_line_routing_constraint_zone_path( - context[:referential], - context[:line] - ) - end - end + ) with_instance_decorator do |instance_decorator| - instance_decorator.show_action_link do |l| - l.href do - h.referential_line_routing_constraint_zone_path( - context[:referential], - context[:line], - object - ) - end - end - - instance_decorator.edit_action_link do |l| - l.href do - h.edit_referential_line_routing_constraint_zone_path( - context[:referential], - context[:line], - object - ) - end - end + instance_decorator.show_action_link + instance_decorator.edit_action_link instance_decorator.destroy_action_link do |l| - l.href do - h.referential_line_routing_constraint_zone_path( - context[:referential], - context[:line], - object - ) - end l.data confirm: h.t('routing_constraint_zones.actions.destroy_confirm') end end diff --git a/app/decorators/stop_area_decorator.rb b/app/decorators/stop_area_decorator.rb index 2e57da0e4..525681971 100644 --- a/app/decorators/stop_area_decorator.rb +++ b/app/decorators/stop_area_decorator.rb @@ -7,23 +7,11 @@ class StopAreaDecorator < AF83::Decorator end with_instance_decorator do |instance_decorator| - instance_decorator.show_action_link do |l| - l.href do - h.stop_area_referential_stop_area_path( - object.stop_area_referential, - object - ) - end - end + set_scope { object.stop_area_referential } + instance_decorator.show_action_link instance_decorator.edit_action_link do |l| l.content h.t('stop_areas.actions.edit') - l.href do - h.edit_stop_area_referential_stop_area_path( - object.stop_area_referential, - object - ) - end end instance_decorator.action_link policy: :deactivate, secondary: true do |l| @@ -54,12 +42,6 @@ class StopAreaDecorator < AF83::Decorator instance_decorator.destroy_action_link do |l| l.content h.destroy_link_content('stop_areas.actions.destroy') - l.href do - h.stop_area_referential_stop_area_path( - object.stop_area_referential, - object - ) - end l.data confirm: h.t('stop_areas.actions.destroy_confirm') end end diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb index f48075ed9..2068dd23c 100644 --- a/app/helpers/table_builder_helper.rb +++ b/app/helpers/table_builder_helper.rb @@ -395,7 +395,6 @@ module TableBuilderHelper klass << link.extra_class if link.extra_class klass << 'delete-action' if link.method == :delete klass << 'disabled' if link.disabled - content_tag( :li, link_to( diff --git a/lib/af83/decorator.rb b/lib/af83/decorator.rb index f990555fe..71cf1170d 100644 --- a/lib/af83/decorator.rb +++ b/lib/af83/decorator.rb @@ -2,40 +2,49 @@ class AF83::Decorator < ModelDecorator include AF83::Decorator::EnhancedDecorator extend AF83::Decorator::EnhancedDecorator::ClassMethods - def self.decorates klass - instance_decorator.decorates klass - end + class << self + def decorates klass + instance_decorator.decorates klass + end - def self.instance_decorator - @instance_decorator ||= begin - klass = Class.new(AF83::Decorator::InstanceDecorator) - klass.delegate_all - klass + def instance_decorator + @instance_decorator ||= begin + klass = Class.new(AF83::Decorator::InstanceDecorator) + klass.delegate_all + klass + end end - end - def self.with_instance_decorator - @_with_instance_decorator = true - yield instance_decorator - @_with_instance_decorator = false - end + def with_instance_decorator + @_with_instance_decorator = true + yield instance_decorator + @_with_instance_decorator = false + end + + def decorate object, options = {} + if object.is_a?(ActiveRecord::Base) + return instance_decorator.decorate object, options + else + self.new object, options.update(with: instance_decorator) + end + end - def self.decorate object, options = {} - if object.is_a?(ActiveRecord::Base) - return instance_decorator.decorate object, options - else - self.new object, options.update(with: instance_decorator) + def define_instance_method method_name, &block + instance_decorator.send(:define_method, method_name, &block) end - end - def self.define_instance_method method_name, &block - instance_decorator.send(:define_method, method_name, &block) - end + # Defines a class method on the decorated object's class. These + # can be called like `object.class.my_method`. + def define_instance_class_method method_name, &block + instance_decorator.send(:define_singleton_method, method_name, &block) + end + + def set_scope_with_instance_decorator value=nil, &block + set_scope_without_instance_decorator value, &block + instance_decorator.set_scope value, &block + end - # Defines a class method on the decorated object's class. These - # can be called like `object.class.my_method`. - def self.define_instance_class_method method_name, &block - instance_decorator.send(:define_singleton_method, method_name, &block) + alias_method_chain :set_scope, :instance_decorator end class ActionLinks diff --git a/lib/af83/decorator/enhanced_decorator.rb b/lib/af83/decorator/enhanced_decorator.rb index 904d1b2da..fff8bb8b3 100644 --- a/lib/af83/decorator/enhanced_decorator.rb +++ b/lib/af83/decorator/enhanced_decorator.rb @@ -25,7 +25,7 @@ module AF83::Decorator::EnhancedDecorator policy: :create, before_block: -> (l){ l.content { h.t('actions.add') } - l.href { [:new, object.klass.name.underscore.singularize] } + l.href { [:new, scope, object.klass.model_name.singular] } } } action_link opts.update(args), &block @@ -37,7 +37,7 @@ module AF83::Decorator::EnhancedDecorator primary: :index, before_block: -> (l){ l.content { h.t('actions.show') } - l.href { [object] } + l.href { [scope, object] } } } action_link opts.update(args), &block @@ -49,7 +49,7 @@ module AF83::Decorator::EnhancedDecorator policy: :edit, before_block: -> (l){ l.content { h.t('actions.edit') } - l.href { [:edit, object] } + l.href { [:edit, scope, object] } } } action_link opts.update(args), &block @@ -62,7 +62,7 @@ module AF83::Decorator::EnhancedDecorator secondary: :show, before_block: -> (l){ l.content { h.destroy_link_content } - l.href { [object] } + l.href { [scope, object] } l.method :delete l.data {{ confirm: h.t('actions.destroy_confirm') }} } @@ -70,6 +70,14 @@ module AF83::Decorator::EnhancedDecorator action_link opts.update(args), &block end + def set_scope value=nil, &block + @scope = value || block + end + + def scope + @scope + end + def t key eval "-> (l){ h.t('#{key}') }" end @@ -142,4 +150,10 @@ module AF83::Decorator::EnhancedDecorator def check_feature feature h.has_feature? feature end + + def scope + scope = self.class.scope + scope = instance_exec &scope if scope.is_a? Proc + scope + end end diff --git a/lib/af83/decorator/link.rb b/lib/af83/decorator/link.rb index 7d2896e6a..de7106740 100644 --- a/lib/af83/decorator/link.rb +++ b/lib/af83/decorator/link.rb @@ -30,7 +30,8 @@ class AF83::Decorator::Link @options[name] = block elsif args.size == 0 out = @options[name] - out = context.instance_exec(self, &out) if out.is_a?(Proc) + out = context.instance_exec(self, &out) if out.is_a?(Proc) + out = out.flatten.compact if name.to_s == "href" && out.is_a?(Array) out else # we can use l.foo("bar") or l.foo = "bar" diff --git a/spec/support/pundit/pundit_view_policy.rb b/spec/support/pundit/pundit_view_policy.rb index 91be0624c..330209049 100644 --- a/spec/support/pundit/pundit_view_policy.rb +++ b/spec/support/pundit/pundit_view_policy.rb @@ -2,9 +2,8 @@ module Pundit module PunditViewPolicy def self.included into into.let(:permissions){ nil } - into.let(:organisation){ referential.try(:organisation) } - into.let(:current_referential){ referential || build_stubbed(:referential) } - into.let(:current_user){ build_stubbed :user, permissions: permissions, organisation: organisation } + into.let(:current_referential){ referential || build_stubbed(:referential, organisation: organisation) } + into.let(:current_user){ create :user, permissions: permissions, organisation: organisation } into.let(:pundit_user){ UserContext.new(current_user, referential: current_referential) } into.before do allow(view).to receive(:pundit_user) { pundit_user } diff --git a/spec/support/referential.rb b/spec/support/referential.rb index 497ff47a8..9acdce73a 100644 --- a/spec/support/referential.rb +++ b/spec/support/referential.rb @@ -11,8 +11,8 @@ module ReferentialHelper def self.included(base) base.class_eval do extend ClassMethods - alias_method :referential, :first_referential - alias_method :organisation, :first_organisation + base.let(:referential){ first_referential } + base.let(:organisation){ first_organisation } end end diff --git a/spec/views/referentials/show.html.erb_spec.rb b/spec/views/referentials/show.html.erb_spec.rb index 4a2afe2ca..6fd51949a 100644 --- a/spec/views/referentials/show.html.erb_spec.rb +++ b/spec/views/referentials/show.html.erb_spec.rb @@ -3,20 +3,22 @@ require 'spec_helper' describe "referentials/show", type: :view do let!(:referential) do - referential = create(:referential) + referential = create(:referential, organisation: organisation) assign :referential, referential.decorate(context: { current_organisation: referential.organisation }) end let(:permissions){ [] } let(:current_organisation) { organisation } - let(:current_offer_workbench) { create :workbench, organisation: current_organisation} + let(:current_offer_workbench) { create :workbench, organisation: organisation} + let(:current_workgroup) { current_offer_workbench.workgroup } let(:readonly){ false } before :each do assign :reflines, [] allow(view).to receive(:current_offer_workbench).and_return(current_offer_workbench) allow(view).to receive(:current_organisation).and_return(current_organisation) + allow(view).to receive(:current_workgroup).and_return(current_workgroup) allow(view).to receive(:current_user).and_return(current_user) allow(view).to receive(:resource).and_return(referential) -- cgit v1.2.3 From d56aed95bcd9970bdc49477c2d5c59befbaeeefd Mon Sep 17 00:00:00 2001 From: Zog Date: Mon, 22 Jan 2018 11:05:09 +0100 Subject: Refs #5647; Scope CustomField validations on workgroup --- app/models/custom_field.rb | 5 +++-- spec/models/custom_field_spec.rb | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/models/custom_field.rb b/app/models/custom_field.rb index 3f79ec62c..774c8b0f6 100644 --- a/app/models/custom_field.rb +++ b/app/models/custom_field.rb @@ -1,8 +1,9 @@ class CustomField < ActiveRecord::Base extend Enumerize + belongs_to :workgroup enumerize :field_type, in: %i{list} - validates :name, uniqueness: {scope: :resource_type} - validates :code, uniqueness: {scope: :resource_type, case_sensitive: false} + validates :name, uniqueness: {scope: [:resource_type, :workgroup_id]} + validates :code, uniqueness: {scope: [:resource_type, :workgroup_id], case_sensitive: false} end diff --git a/spec/models/custom_field_spec.rb b/spec/models/custom_field_spec.rb index 8a6d0cb41..51128b0a2 100644 --- a/spec/models/custom_field_spec.rb +++ b/spec/models/custom_field_spec.rb @@ -4,8 +4,8 @@ RSpec.describe CustomField, type: :model do let( :vj ){ create :vehicle_journey, custom_field_values: {energy: 99} } context "validates" do - it { should validate_uniqueness_of(:name).scoped_to(:resource_type) } - it { should validate_uniqueness_of(:code).scoped_to(:resource_type).case_insensitive } + it { should validate_uniqueness_of(:name).scoped_to(:resource_type, :workgroup_id) } + it { should validate_uniqueness_of(:code).scoped_to(:resource_type, :workgroup_id).case_insensitive } end context "field access" do -- cgit v1.2.3 From 87e0ea06cbc6bdfb281da8805b0221868341fee2 Mon Sep 17 00:00:00 2001 From: Zog Date: Wed, 24 Jan 2018 08:58:28 +0100 Subject: Add a toolbar for devs to easily manage permissions and features --- .gitignore | 1 + app/assets/stylesheets/components/_toolbar.sass | 47 +++++++++++++++++++++ app/controllers/development_toolbar_controller.rb | 11 +++++ app/views/layouts/application.html.slim | 3 ++ .../layouts/navigation/_main_nav_top.html.slim | 4 ++ app/views/shared/_development_toolbar.html.slim | 48 ++++++++++++++++++++++ config/environments/development.rb | 7 ++++ config/routes.rb | 4 ++ 8 files changed, 125 insertions(+) create mode 100644 app/assets/stylesheets/components/_toolbar.sass create mode 100644 app/controllers/development_toolbar_controller.rb create mode 100644 app/views/shared/_development_toolbar.html.slim diff --git a/.gitignore b/.gitignore index ddd5fdda3..acdb5e230 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,4 @@ coverage /bin/spring spec/fixtures/target_* +config/development_toolbar.rb diff --git a/app/assets/stylesheets/components/_toolbar.sass b/app/assets/stylesheets/components/_toolbar.sass new file mode 100644 index 000000000..47ae2ac0c --- /dev/null +++ b/app/assets/stylesheets/components/_toolbar.sass @@ -0,0 +1,47 @@ +#development-toolbar + .inner + overflow: scroll + padding: 10px + max-height: 70vh + display: flex + flex-direction: row + .toggles + font-size: 0.7em + float: right + a:first-child + padding-right: 3px + margin-right: 3px + border-right: 1px solid $lightgrey + + .col + flex: 1 1 + padding-right: 10px + padding-left: 10px + border-right: 1px solid $lightgrey + &:last-child + padding-right: 0 + border-right: none + + ul + padding: 0 + li + list-style-type: none + label + padding-left: 5px + font-weight: normal + h5 + font-weight: bold + &.permissions + ul + overflow: hidden + li + float: left + width: 33% + label + font-size: 0.8em + max-width: calc(100% - 15px) + text-overflow: ellipsis + overflow: hidden + padding-top: 3px + input + vertical-align: top diff --git a/app/controllers/development_toolbar_controller.rb b/app/controllers/development_toolbar_controller.rb new file mode 100644 index 000000000..20349f7b8 --- /dev/null +++ b/app/controllers/development_toolbar_controller.rb @@ -0,0 +1,11 @@ +class DevelopmentToolbarController < ApplicationController + def update_settings + return unless Rails.application.config.development_toolbar.present? + organisation = current_user.organisation + organisation.features = params[:features].keys.select{|k| params[:features][k] == "true"} + organisation.save + current_user.permissions = params[:permissions].keys.select{|k| params[:permissions][k] == "true"} + current_user.save + redirect_to request.referrer || "/" + end +end diff --git a/app/views/layouts/application.html.slim b/app/views/layouts/application.html.slim index 567e14ef0..34b373295 100644 --- a/app/views/layouts/application.html.slim +++ b/app/views/layouts/application.html.slim @@ -21,3 +21,6 @@ html lang=I18n.locale = yield #sidebar = yield :sidebar + + = render 'shared/development_toolbar' + = yield :javascript diff --git a/app/views/layouts/navigation/_main_nav_top.html.slim b/app/views/layouts/navigation/_main_nav_top.html.slim index 278249e09..f664d5416 100644 --- a/app/views/layouts/navigation/_main_nav_top.html.slim +++ b/app/views/layouts/navigation/_main_nav_top.html.slim @@ -14,9 +14,13 @@ span = current_user.name span.fa.fa-lg.fa-user + - if Rails.application.config.development_toolbar + = link_to '#', data: { toggle: 'modal', target: '#development-toolbar' }, class: "toolbar-button menu-item" do + .fa.fa-cog = link_to destroy_user_session_path, method: :delete, class: 'menu-item', title: 'Se déconnecter' do span.fa.fa-lg.fa-sign-out + = render 'layouts/navigation/nav_panel_operations' = render 'layouts/navigation/nav_panel_profile' if user_signed_in? diff --git a/app/views/shared/_development_toolbar.html.slim b/app/views/shared/_development_toolbar.html.slim new file mode 100644 index 000000000..b51bb3de6 --- /dev/null +++ b/app/views/shared/_development_toolbar.html.slim @@ -0,0 +1,48 @@ +- if Rails.application.config.development_toolbar + = modalbox 'development-toolbar' do + = form_tag development_toolbar_update_settings_path, authenticity_token: true do + .modal-header + h3= "Toolbar" + + .inner + .col.features + h4 + = "Features" + .toggles + = link_to 'all', '#', data: {mask: 'features', val: true} + = link_to 'none', '#', data: {mask: 'features', val: false} + ul + - Rails.application.config.development_toolbar.available_features.sort.each do |feature| + li + = hidden_field_tag "features[#{feature}]", false, id: "" + = check_box_tag "features[#{feature}]", true, has_feature?(feature) + = label :features, feature + .col.permissions + h4 + = "Permissions" + .toggles + = link_to 'all', '#', data: {mask: 'permissions', val: true} + = link_to 'none', '#', data: {mask: 'permissions', val: false} + - model = "" + - Rails.application.config.development_toolbar.available_permissions.sort.each do |permission| + - if permission.split('.').first != model + - model = permission.split('.').first + + h5 + = model + .toggles + = link_to 'all', '#', data: {mask: "permissions[#{model}", val: true} + = link_to 'none', '#', data: {mask: "permissions[#{model}", val: false} +