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}
+
+ li
+ = hidden_field_tag "permissions[#{permission}]", false, id: ""
+ = check_box_tag "permissions[#{permission}]", true, current_user.has_permission?(permission)
+ = label :permissions, permission, permission.split('.').last
+ .modal-footer= submit_tag t("actions.submit"), class: 'btn btn-primary'
+
+ - content_for :javascript do
+ coffee:
+ $('#development-toolbar .toggles a').click (e)->
+ $('#development-toolbar').find("[name^=\"#{e.currentTarget.dataset.mask}\"]").attr "checked", e.currentTarget.dataset.val == 'true'
+ e.preventDefault()
+ false
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 24a4ed6b8..925718e69 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -95,4 +95,11 @@ Rails.application.configure do
config.i18n.available_locales = [:fr, :en]
config.middleware.insert_after(ActionDispatch::Static, Rack::LiveReload) if ENV['LIVERELOAD']
+ config.development_toolbar = false
+ if ENV['TOOLBAR'] && File.exists?("config/development_toolbar.rb")
+ config.development_toolbar = OpenStruct.new
+ config.development_toolbar.tap do |toolbar|
+ eval File.read("config/development_toolbar.rb")
+ end
+ end
end
diff --git a/config/routes.rb b/config/routes.rb
index 6a6a7cb07..07370ee6d 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -239,6 +239,10 @@ ChouetteIhm::Application.routes.draw do
get '/help/(*slug)' => 'help#show'
+ if Rails.application.config.development_toolbar
+ post "/development_toolbar" => "development_toolbar#update_settings", as: :development_toolbar_update_settings
+ end
+
match '/404', to: 'errors#not_found', via: :all, as: 'not_found'
match '/403', to: 'errors#forbidden', via: :all, as: 'forbidden'
match '/422', to: 'errors#server_error', via: :all, as: 'unprocessable_entity'
--
cgit v1.2.3
From b0fbc01ba86730c93521cae2f29dbb858641a3da Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 24 Jan 2018 09:00:34 +0100
Subject: Add a config file template
---
config/development_toolbar.rb.tpl | 2 ++
1 file changed, 2 insertions(+)
create mode 100644 config/development_toolbar.rb.tpl
diff --git a/config/development_toolbar.rb.tpl b/config/development_toolbar.rb.tpl
new file mode 100644
index 000000000..c278f07a7
--- /dev/null
+++ b/config/development_toolbar.rb.tpl
@@ -0,0 +1,2 @@
+toolbar.available_features = %w()
+toolbar.available_permissions = %w()
--
cgit v1.2.3
From 3a383e10f0b90e7367a6776bdf9ed1783ff739ac Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 24 Jan 2018 10:00:05 +0100
Subject: - Add a default value for the config - Add a cancel button to dismiss
the modal
---
app/views/shared/_development_toolbar.html.slim | 4 +++-
config/application.rb | 2 ++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/app/views/shared/_development_toolbar.html.slim b/app/views/shared/_development_toolbar.html.slim
index b51bb3de6..4ad69f7ad 100644
--- a/app/views/shared/_development_toolbar.html.slim
+++ b/app/views/shared/_development_toolbar.html.slim
@@ -38,7 +38,9 @@
= hidden_field_tag "permissions[#{permission}]", false, id: ""
= check_box_tag "permissions[#{permission}]", true, current_user.has_permission?(permission)
= label :permissions, permission, permission.split('.').last
- .modal-footer= submit_tag t("actions.submit"), class: 'btn btn-primary'
+ .modal-footer
+ button.btn.btn-link type='button' data-dismiss='modal' #{t('cancel')}
+ = submit_tag t("actions.submit"), class: 'btn btn-primary'
- content_for :javascript do
coffee:
diff --git a/config/application.rb b/config/application.rb
index bda582610..8da6a7428 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -39,6 +39,8 @@ module ChouetteIhm
'FeatureChecker::NotAuthorizedError' => :unauthorized
)
+ config.development_toolbar = false
+
unless Rails.env.production?
# Work around sprockets+teaspoon mismatch:
Rails.application.config.assets.precompile += %w(spec_helper.js)
--
cgit v1.2.3
From e126e59759d2fcb8d5989cf154a5f56ff5268f02 Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 24 Jan 2018 10:39:38 +0100
Subject: Add links to doc
---
app/assets/stylesheets/components/_toolbar.sass | 2 ++
app/views/shared/_development_toolbar.html.slim | 3 +++
config/environments/development.rb | 3 +++
3 files changed, 8 insertions(+)
diff --git a/app/assets/stylesheets/components/_toolbar.sass b/app/assets/stylesheets/components/_toolbar.sass
index 47ae2ac0c..86a32bd82 100644
--- a/app/assets/stylesheets/components/_toolbar.sass
+++ b/app/assets/stylesheets/components/_toolbar.sass
@@ -29,6 +29,8 @@
label
padding-left: 5px
font-weight: normal
+ & + a
+ float: right
h5
font-weight: bold
&.permissions
diff --git a/app/views/shared/_development_toolbar.html.slim b/app/views/shared/_development_toolbar.html.slim
index 4ad69f7ad..aafd37885 100644
--- a/app/views/shared/_development_toolbar.html.slim
+++ b/app/views/shared/_development_toolbar.html.slim
@@ -17,6 +17,9 @@
= hidden_field_tag "features[#{feature}]", false, id: ""
= check_box_tag "features[#{feature}]", true, has_feature?(feature)
= label :features, feature
+ - if Rails.application.config.development_toolbar.features_doc_url
+ = link_to "#{Rails.application.config.development_toolbar.features_doc_url}##{feature}", target: :blank do
+ .fa.fa-question-circle
.col.permissions
h4
= "Permissions"
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 925718e69..1d2fee44f 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -98,6 +98,9 @@ Rails.application.configure do
config.development_toolbar = false
if ENV['TOOLBAR'] && File.exists?("config/development_toolbar.rb")
config.development_toolbar = OpenStruct.new
+ config.development_toolbar.features_doc_url = nil
+ config.development_toolbar.available_features = %w()
+ config.development_toolbar.available_permissions = %w()
config.development_toolbar.tap do |toolbar|
eval File.read("config/development_toolbar.rb")
end
--
cgit v1.2.3
From 65db4fe0706d1c47f32ed51b219244693d3dbddf Mon Sep 17 00:00:00 2001
From: Zog
Date: Thu, 25 Jan 2018 11:39:32 +0100
Subject: Refs #5598; Enable button to view a JourneyPattern when the user is
not allowed to edit it
---
app/javascript/journey_patterns/components/JourneyPattern.js | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/app/javascript/journey_patterns/components/JourneyPattern.js b/app/javascript/journey_patterns/components/JourneyPattern.js
index ecbebe2cc..01734f3a3 100644
--- a/app/javascript/journey_patterns/components/JourneyPattern.js
+++ b/app/javascript/journey_patterns/components/JourneyPattern.js
@@ -136,10 +136,9 @@ export default class JourneyPattern extends Component{
-
+
{
+ set('policy', () => {
+ return {}
+ })
+ set('features', () => {
+ return []
+ })
+ set('editMode', () => {
+ return false
+ })
+ set('component', () => {
+ let props = {
+ status: {
+ policy: policy,
+ features: features
+ },
+ onCheckboxChange: ()=>{},
+ onDeleteJourneyPattern: ()=>{},
+ onOpenEditModal: ()=>{},
+ journeyPatterns: {},
+ value: {
+ stop_points: []
+ },
+ index: 0,
+ editMode: editMode
+ }
+ let list = renderer.create(
+
+ )
+
+ return list
+ })
+
+
+ it('should display the show link', () => {
+ expect(component.toJSON()).toMatchSnapshot()
+ expect(component.root.findByProps({"data-target": "#JourneyPatternModal"})._fiber.stateNode.children[0].text).toEqual("Consulter")
+ })
+
+ context('in edit mode', () => {
+ set('editMode', () => {
+ return true
+ })
+
+ it('should display the edit link', () => {
+ expect(component.toJSON()).toMatchSnapshot()
+ expect(component.root.findByProps({"data-target": "#JourneyPatternModal"})._fiber.stateNode.children[0].text).toEqual("Editer")
+ })
+ })
+})
diff --git a/spec/javascript/journey_patterns/components/__snapshots__/JourneyPattern_spec.js.snap b/spec/javascript/journey_patterns/components/__snapshots__/JourneyPattern_spec.js.snap
new file mode 100644
index 000000000..0bedd8d69
--- /dev/null
+++ b/spec/javascript/journey_patterns/components/__snapshots__/JourneyPattern_spec.js.snap
@@ -0,0 +1,143 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`the edit button in edit mode should display the edit link 1`] = `
+
+
+
+ -
+
+
+
+ 0
+ arrêt(s)
+
+
+
+
+`;
+
+exports[`the edit button should display the show link 1`] = `
+
+
+
+ -
+
+
+
+ 0
+ arrêt(s)
+
+
+
+
+`;
--
cgit v1.2.3
From 078b9312d98b0e00497a7570052ac2424b257c78 Mon Sep 17 00:00:00 2001
From: Zog
Date: Thu, 25 Jan 2018 05:21:17 -0800
Subject: Refs #5717; Fix TZ related issues
---
app/javascript/time_tables/actions/index.js | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/app/javascript/time_tables/actions/index.js b/app/javascript/time_tables/actions/index.js
index 13cb96b64..787cee439 100644
--- a/app/javascript/time_tables/actions/index.js
+++ b/app/javascript/time_tables/actions/index.js
@@ -156,8 +156,9 @@ const actions = {
}),
monthName(strDate) {
let monthList = range(1,13).map(n => I18n.calendars.months[n])
+ console.log("strDate: "+strDate)
let date = new Date(strDate)
- return monthList[date.getMonth()]
+ return monthList[date.getUTCMonth()]
},
getHumanDate(strDate, mLimit) {
let origin = strDate.split('-')
@@ -173,7 +174,7 @@ const actions = {
},
getLocaleDate(strDate) {
let date = new Date(strDate)
- return date.toLocaleDateString()
+ return date.toLocaleDateString(undefined, { timeZone: 'UTC' })
},
updateSynthesis: ({current_month, time_table_dates: dates, time_table_periods: periods}) => {
let newPeriods = reject(periods, 'deleted')
@@ -194,7 +195,7 @@ const actions = {
for (let period of periods) {
let begin = new Date(period.period_start)
- let end = new Date(period.period_end)
+ let end = new Date(period.period_end)
if (date >= begin && date <= end) return true
}
@@ -325,4 +326,4 @@ const actions = {
}
}
-export default actions
\ No newline at end of file
+export default actions
--
cgit v1.2.3
From 803fc1683cfec2ee02cdac31a59ee778f1ec885d Mon Sep 17 00:00:00 2001
From: Zog
Date: Thu, 25 Jan 2018 22:10:07 -1000
Subject: Refs #5717; Fix month selection
---
app/javascript/time_tables/actions/index.js | 1 -
app/javascript/time_tables/components/Navigate.js | 6 +++---
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/app/javascript/time_tables/actions/index.js b/app/javascript/time_tables/actions/index.js
index 787cee439..87c7a3e8d 100644
--- a/app/javascript/time_tables/actions/index.js
+++ b/app/javascript/time_tables/actions/index.js
@@ -156,7 +156,6 @@ const actions = {
}),
monthName(strDate) {
let monthList = range(1,13).map(n => I18n.calendars.months[n])
- console.log("strDate: "+strDate)
let date = new Date(strDate)
return monthList[date.getUTCMonth()]
},
diff --git a/app/javascript/time_tables/components/Navigate.js b/app/javascript/time_tables/components/Navigate.js
index 64f05cb41..1467fffe9 100644
--- a/app/javascript/time_tables/components/Navigate.js
+++ b/app/javascript/time_tables/components/Navigate.js
@@ -24,7 +24,7 @@ export default function Navigate({ dispatch, metas, timetable, pagination, statu
aria-haspopup='true'
aria-expanded='true'
>
- {pagination.currentPage ? (actions.monthName(pagination.currentPage) + ' ' + new Date(pagination.currentPage).getFullYear()) : ''}
+ {pagination.currentPage ? (actions.monthName(pagination.currentPage) + ' ' + new Date(pagination.currentPage).getUTCFullYear()) : ''}
- {actions.monthName(month) + ' ' + new Date(month).getFullYear()}
+ {actions.monthName(month) + ' ' + new Date(month).getUTCFullYear()}
))}
@@ -86,4 +86,4 @@ Navigate.propTypes = {
status: PropTypes.object.isRequired,
pagination: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired
-}
\ No newline at end of file
+}
--
cgit v1.2.3
From 33c7b132b1aa0ac061d82226a70dcb8034b2ec68 Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 26 Jan 2018 10:01:37 +0100
Subject: Refs #5740; Add message in company filter when no value is available
---
app/views/referential_vehicle_journeys/_filters.html.slim | 5 ++++-
config/locales/companies.en.yml | 1 +
config/locales/companies.fr.yml | 1 +
3 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/app/views/referential_vehicle_journeys/_filters.html.slim b/app/views/referential_vehicle_journeys/_filters.html.slim
index 609927615..f85ef1eb9 100644
--- a/app/views/referential_vehicle_journeys/_filters.html.slim
+++ b/app/views/referential_vehicle_journeys/_filters.html.slim
@@ -8,7 +8,10 @@
.ffg-row
.form-group.togglable
= f.label Chouette::VehicleJourney.human_attribute_name(:company), required: false, class: 'control-label'
- = f.input :company_id_eq_any, collection: @all_companies.select(:id, :name).order(name: :asc), as: :check_boxes, label: false, label_method: lambda{|l| ("" + l.name + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}
+ - if @all_companies.present?
+ = f.input :company_id_eq_any, collection: @all_companies.select(:id, :name).order(name: :asc), as: :check_boxes, label: false, label_method: lambda{|l| ("" + l.name + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}
+ - else
+ = f.input :company_id_eq_any, collection: [[I18n.t('companies.search_no_results_for_filter'), nil]], as: :check_boxes, label: false, disabled: true, required: false, wrapper_html: { class: 'checkbox_list disabled'}
.form-group.togglable.name-filter
= f.label Chouette::VehicleJourney.human_attribute_name(:published_journey_name), required: false, class: 'control-label'
.inputs.form-inline.checkbox_list
diff --git a/config/locales/companies.en.yml b/config/locales/companies.en.yml
index a3cd520cb..29dc3911b 100644
--- a/config/locales/companies.en.yml
+++ b/config/locales/companies.en.yml
@@ -1,6 +1,7 @@
en:
companies: &en_companies
search_no_results: "No company matching your query"
+ search_no_results_for_filter: "No company has been set for thess journeys"
actions:
new: "Add a new company"
edit: "Edit this company"
diff --git a/config/locales/companies.fr.yml b/config/locales/companies.fr.yml
index 0cf729c35..3284115ab 100644
--- a/config/locales/companies.fr.yml
+++ b/config/locales/companies.fr.yml
@@ -1,6 +1,7 @@
fr:
companies: &fr_companies
search_no_results: "Aucun transporteur ne correspond à votre recherche"
+ search_no_results_for_filter: "Aucun transporteur renseigné sur ces courses"
actions:
new: "Ajouter un transporteur"
edit: "Editer ce transporteur"
--
cgit v1.2.3
From 2dd90cb38b4da66cdcc008beed6b15d073d1f4be Mon Sep 17 00:00:00 2001
From: Luc Donnet
Date: Tue, 30 Jan 2018 16:37:53 +0100
Subject: Update companies.en.yml
Fix translation in companies.en.yml---
config/locales/companies.en.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config/locales/companies.en.yml b/config/locales/companies.en.yml
index 29dc3911b..becb087b1 100644
--- a/config/locales/companies.en.yml
+++ b/config/locales/companies.en.yml
@@ -1,7 +1,7 @@
en:
companies: &en_companies
search_no_results: "No company matching your query"
- search_no_results_for_filter: "No company has been set for thess journeys"
+ search_no_results_for_filter: "No company has been set for these journeys"
actions:
new: "Add a new company"
edit: "Edit this company"
--
cgit v1.2.3
From 6632217117a66bd09b2e8261e4351add9971d47c 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/decorators/calendar_decorator.rb | 10 ++++++++++
app/helpers/table_builder_helper.rb | 10 ++++++++++
app/helpers/table_builder_helper/url.rb | 6 +++++-
app/views/calendars/index.html.slim | 4 ++++
4 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/app/decorators/calendar_decorator.rb b/app/decorators/calendar_decorator.rb
index 0a7cbc312..1b2a085b7 100644
--- a/app/decorators/calendar_decorator.rb
+++ b/app/decorators/calendar_decorator.rb
@@ -5,11 +5,21 @@ class CalendarDecorator < AF83::Decorator
create_action_link
+<<<<<<< HEAD
with_instance_decorator do |instance_decorator|
instance_decorator.show_action_link
instance_decorator.edit_action_link
instance_decorator.destroy_action_link do |l|
l.data {{ confirm: h.t('calendars.actions.destroy_confirm') }}
+=======
+ if h.policy(object).destroy?
+ links << Link.new(
+ content: h.destroy_link_content,
+ href: h.workgroup_calendar_path(context[:workgroup], object),
+ method: :delete,
+ data: { confirm: h.t('calendars.actions.destroy_confirm') }
+ )
+>>>>>>> First draft for including calendars into workgroup for having appropriate scoping
end
end
end
diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb
index 2068dd23c..245843eab 100644
--- a/app/helpers/table_builder_helper.rb
+++ b/app/helpers/table_builder_helper.rb
@@ -316,6 +316,7 @@ module TableBuilderHelper
content_tag :span, '', class: 'fa fa-cog'
end
+<<<<<<< HEAD
action_links = item.action_links
if action_links.is_a?(AF83::Decorator::ActionLinks)
menu = content_tag :div, class: 'dropdown-menu' do
@@ -336,6 +337,15 @@ module TableBuilderHelper
gear_menu_link(link)
end.join.html_safe
end
+=======
+ menu = content_tag :ul, class: 'dropdown-menu' do
+ (
+ 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)
+ end.join.html_safe
+>>>>>>> First draft for including calendars into workgroup for having appropriate scoping
end
content_tag :div, trigger + menu, class: 'btn-group'
diff --git a/app/helpers/table_builder_helper/url.rb b/app/helpers/table_builder_helper/url.rb
index 0e3dce0aa..550b1e9d4 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?(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,7 +20,11 @@ module TableBuilderHelper
end
end
else
+<<<<<<< HEAD
polymorph_url << item.workgroup if item.respond_to? :workgroup
+=======
+ polymorph_url << item.workgroup if item.is_a?(Calendar)
+>>>>>>> First draft for including calendars into workgroup for having appropriate scoping
polymorph_url << item
end
diff --git a/app/views/calendars/index.html.slim b/app/views/calendars/index.html.slim
index 0b58c0c72..a2d6b4731 100644
--- a/app/views/calendars/index.html.slim
+++ b/app/views/calendars/index.html.slim
@@ -1,4 +1,8 @@
- breadcrumb :calendars, 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')
+
.page_content
.container-fluid
--
cgit v1.2.3
From dd61691343892d502842341bc94ca8b355a716cc 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 | 1 +
app/helpers/table_builder_helper/url.rb | 6 +++++-
app/views/calendars/index.html.slim | 10 ++++++++++
3 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb
index 6f1522428..61a62c285 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]
diff --git a/app/helpers/table_builder_helper/url.rb b/app/helpers/table_builder_helper/url.rb
index 550b1e9d4..63a559162 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,11 +20,15 @@ module TableBuilderHelper
end
end
else
+<<<<<<< HEAD
<<<<<<< HEAD
polymorph_url << item.workgroup if item.respond_to? :workgroup
=======
polymorph_url << item.workgroup if item.is_a?(Calendar)
>>>>>>> First draft for including calendars into workgroup for having appropriate scoping
+=======
+ polymorph_url << item.workgroup if item.respond_to? :workgroup
+>>>>>>> update calendar build_links for table builder
polymorph_url << item
end
diff --git a/app/views/calendars/index.html.slim b/app/views/calendars/index.html.slim
index a2d6b4731..f7192bc01 100644
--- a/app/views/calendars/index.html.slim
+++ b/app/views/calendars/index.html.slim
@@ -1,4 +1,14 @@
+<<<<<<< HEAD
- breadcrumb :calendars, workgroup
+=======
+<<<<<<< HEAD
+- breadcrumb :calendars
+<<<<<<< HEAD
+=======
+=======
+- breadcrumb :calendars, current_workgroup
+>>>>>>> update calendar build_links for table builder
+>>>>>>> update calendar build_links for table builder
- 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')
--
cgit v1.2.3
From 2ce236aea91bbe35a6b03353b4c5c7f33ded8eac 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 | 3 +--
app/views/calendars/index.html.slim | 10 ++++++++++
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb
index 61a62c285..eaff3b0c6 100644
--- a/app/controllers/calendars_controller.rb
+++ b/app/controllers/calendars_controller.rb
@@ -1,5 +1,4 @@
class CalendarsController < ChouetteController
- include WorkgroupSupport
include PolicyChecker
defaults resource_class: Calendar
before_action :ransack_contains_date, only: [:index]
@@ -96,4 +95,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 f7192bc01..04ae8c758 100644
--- a/app/views/calendars/index.html.slim
+++ b/app/views/calendars/index.html.slim
@@ -1,6 +1,9 @@
<<<<<<< HEAD
+<<<<<<< HEAD
- breadcrumb :calendars, workgroup
=======
+=======
+>>>>>>> Make some changes to avoid unnacessaty lines of code
<<<<<<< HEAD
- breadcrumb :calendars
<<<<<<< HEAD
@@ -12,7 +15,14 @@
- 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')
+<<<<<<< HEAD
+=======
+>>>>>>> First draft for including calendars into workgroup for having appropriate scoping
+=======
+- breadcrumb :calendars, workgroup
+>>>>>>> Make some changes to avoid unnacessaty lines of code
+>>>>>>> Make some changes to avoid unnacessaty lines of code
.page_content
.container-fluid
--
cgit v1.2.3
From f32ffd5b740583777634d0b58e3d50aa9d2414a3 Mon Sep 17 00:00:00 2001
From: cedricnjanga
Date: Wed, 31 Jan 2018 09:00:34 -0800
Subject: Fix calendar mailer url
---
app/decorators/calendar_decorator.rb | 12 ------------
app/helpers/table_builder_helper.rb | 11 +----------
app/helpers/table_builder_helper/url.rb | 8 --------
app/views/calendar_mailer/created.html.slim | 4 ++--
app/views/calendar_mailer/updated.html.slim | 2 +-
app/views/calendars/index.html.slim | 24 ------------------------
spec/mailers/calendar_mailer_spec.rb | 2 +-
7 files changed, 5 insertions(+), 58 deletions(-)
diff --git a/app/decorators/calendar_decorator.rb b/app/decorators/calendar_decorator.rb
index 1b2a085b7..4c6088e8e 100644
--- a/app/decorators/calendar_decorator.rb
+++ b/app/decorators/calendar_decorator.rb
@@ -1,25 +1,13 @@
class CalendarDecorator < AF83::Decorator
decorates Calendar
-
set_scope { context[:workgroup] }
-
create_action_link
-<<<<<<< HEAD
with_instance_decorator do |instance_decorator|
instance_decorator.show_action_link
instance_decorator.edit_action_link
instance_decorator.destroy_action_link do |l|
l.data {{ confirm: h.t('calendars.actions.destroy_confirm') }}
-=======
- if h.policy(object).destroy?
- links << Link.new(
- content: h.destroy_link_content,
- href: h.workgroup_calendar_path(context[:workgroup], object),
- method: :delete,
- data: { confirm: h.t('calendars.actions.destroy_confirm') }
- )
->>>>>>> First draft for including calendars into workgroup for having appropriate scoping
end
end
end
diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb
index 245843eab..f48075ed9 100644
--- a/app/helpers/table_builder_helper.rb
+++ b/app/helpers/table_builder_helper.rb
@@ -316,7 +316,6 @@ module TableBuilderHelper
content_tag :span, '', class: 'fa fa-cog'
end
-<<<<<<< HEAD
action_links = item.action_links
if action_links.is_a?(AF83::Decorator::ActionLinks)
menu = content_tag :div, class: 'dropdown-menu' do
@@ -337,15 +336,6 @@ module TableBuilderHelper
gear_menu_link(link)
end.join.html_safe
end
-=======
- menu = content_tag :ul, class: 'dropdown-menu' do
- (
- 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)
- end.join.html_safe
->>>>>>> First draft for including calendars into workgroup for having appropriate scoping
end
content_tag :div, trigger + menu, class: 'btn-group'
@@ -405,6 +395,7 @@ 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/app/helpers/table_builder_helper/url.rb b/app/helpers/table_builder_helper/url.rb
index 63a559162..0e3dce0aa 100644
--- a/app/helpers/table_builder_helper/url.rb
+++ b/app/helpers/table_builder_helper/url.rb
@@ -20,15 +20,7 @@ module TableBuilderHelper
end
end
else
-<<<<<<< HEAD
-<<<<<<< HEAD
polymorph_url << item.workgroup if item.respond_to? :workgroup
-=======
- polymorph_url << item.workgroup if item.is_a?(Calendar)
->>>>>>> First draft for including calendars into workgroup for having appropriate scoping
-=======
- polymorph_url << item.workgroup if item.respond_to? :workgroup
->>>>>>> update calendar build_links for table builder
polymorph_url << item
end
diff --git a/app/views/calendar_mailer/created.html.slim b/app/views/calendar_mailer/created.html.slim
index 37b2a86ea..bee071150 100644
--- a/app/views/calendar_mailer/created.html.slim
+++ b/app/views/calendar_mailer/created.html.slim
@@ -1,4 +1,4 @@
-div = t('mailers.calendar_mailer.created.body', cal_name: @calendar.name, cal_index_url: calendars_url)
+div = t('mailers.calendar_mailer.created.body', cal_name: @calendar.name, cal_index_url: workgroup_calendars_url(@calendar.workgroup))
table style="border-collapse:collapse;font-family:'Open Sans', Arial, sans serif;width:550px;margin:0px auto;color:#333333;"
@@ -16,7 +16,7 @@ table style="border-collapse:collapse;font-family:'Open Sans', Arial, sans serif
= t('mailers.calendar_mailer.updated.subject')
p style="font-size:14px;margin:0px 0px 10px 0px;"
- = t('mailers.calendar_mailer.created.body', cal_name: @calendar.name, cal_index_url: calendars_url).html_safe
+ = t('mailers.calendar_mailer.created.body', cal_name: @calendar.name, cal_index_url: workgroup_calendars_url(@calendar.workgroup)).html_safe
tr
td style="text-align:center;padding:20px 0 0 0;border-top:1px solid #007fbb;"
diff --git a/app/views/calendar_mailer/updated.html.slim b/app/views/calendar_mailer/updated.html.slim
index bf128439a..0bdc2e7db 100644
--- a/app/views/calendar_mailer/updated.html.slim
+++ b/app/views/calendar_mailer/updated.html.slim
@@ -14,7 +14,7 @@ table style="border-collapse:collapse;font-family:'Open Sans', Arial, sans serif
= t('mailers.calendar_mailer.updated.subject')
p style="font-size:14px;margin:0px 0px 10px 0px;"
- = t('mailers.calendar_mailer.updated.body', cal_name: @calendar.name, cal_index_url: calendars_url).html_safe
+ = t('mailers.calendar_mailer.updated.body', cal_name: @calendar.name, cal_index_url: workgroup_calendars_url(@calendar.workgroup)).html_safe
tr
td style="text-align:center;padding:20px 0 0 0;border-top:1px solid #007fbb;"
diff --git a/app/views/calendars/index.html.slim b/app/views/calendars/index.html.slim
index 04ae8c758..0b58c0c72 100644
--- a/app/views/calendars/index.html.slim
+++ b/app/views/calendars/index.html.slim
@@ -1,28 +1,4 @@
-<<<<<<< HEAD
-<<<<<<< HEAD
- breadcrumb :calendars, workgroup
-=======
-=======
->>>>>>> Make some changes to avoid unnacessaty lines of code
-<<<<<<< HEAD
-- breadcrumb :calendars
-<<<<<<< HEAD
-=======
-=======
-- breadcrumb :calendars, current_workgroup
->>>>>>> update calendar build_links for table builder
->>>>>>> update calendar build_links for table builder
-- 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')
-<<<<<<< HEAD
-
-=======
->>>>>>> First draft for including calendars into workgroup for having appropriate scoping
-=======
-- breadcrumb :calendars, workgroup
->>>>>>> Make some changes to avoid unnacessaty lines of code
->>>>>>> Make some changes to avoid unnacessaty lines of code
.page_content
.container-fluid
diff --git a/spec/mailers/calendar_mailer_spec.rb b/spec/mailers/calendar_mailer_spec.rb
index 9a2076f64..00d73a58b 100644
--- a/spec/mailers/calendar_mailer_spec.rb
+++ b/spec/mailers/calendar_mailer_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe CalendarMailer, type: :mailer do
end
it 'should have correct body' do
- key = I18n.t("mailers.calendar_mailer.#{type}.body", cal_name: calendar.name, cal_index_url: calendars_url)
+ key = I18n.t("mailers.calendar_mailer.#{type}.body", cal_name: calendar.name, cal_index_url: workgroup_calendars_url(calendar.workgroup))
expect(email).to have_body_text /#{key}/
end
end
--
cgit v1.2.3
From 4c3e7adbeccfcbc39de845880882893b5b734741 Mon Sep 17 00:00:00 2001
From: Teddy Wing
Date: Mon, 5 Feb 2018 15:49:25 +0100
Subject: Import: Add `.abort_old` method
This will abort all imports that don't have a finished status and were
created more than four hours ago.
We want to add this functionality to the import cron to auto-abort stale
imports.
Refs #4963
---
app/models/import.rb | 5 +++++
spec/models/import_spec.rb | 21 +++++++++++++++++++++
2 files changed, 26 insertions(+)
diff --git a/app/models/import.rb b/app/models/import.rb
index 049a65f40..6330bd560 100644
--- a/app/models/import.rb
+++ b/app/models/import.rb
@@ -42,6 +42,11 @@ class Import < ActiveRecord::Base
%w(successful failed warning aborted canceled)
end
+ def self.abort_old
+ where('created_at < ?', 4.hours.ago)
+ .update_all(status: 'aborted')
+ end
+
def notify_parent
parent.child_change
update(notified_parent_at: DateTime.now)
diff --git a/spec/models/import_spec.rb b/spec/models/import_spec.rb
index ffb2360c2..8c1037a48 100644
--- a/spec/models/import_spec.rb
+++ b/spec/models/import_spec.rb
@@ -29,6 +29,27 @@ RSpec.describe Import, type: :model do
)
end
+ describe ".abort_old" do
+ it "changes imports older than 4 hours to aborted" do
+ Timecop.freeze(Time.now) do
+ old_import = create(
+ :workbench_import,
+ status: 'pending',
+ created_at: 4.hours.ago - 1.minute
+ )
+ current_import = create(:workbench_import, status: 'pending')
+
+ Import.abort_old
+
+ expect(current_import.reload.status).to eq('pending')
+ expect(old_import.reload.status).to eq('aborted')
+ end
+ end
+
+ it "doesn't work on imports with a `finished_status`" do
+ end
+ end
+
describe "#destroy" do
it "must destroy all child imports" do
netex_import = create(:netex_import)
--
cgit v1.2.3
From 95536ec9ffe465cb591bab3c1e770264440a7c8a Mon Sep 17 00:00:00 2001
From: Teddy Wing
Date: Mon, 5 Feb 2018 15:57:15 +0100
Subject: Import.abort_old: Don't change finished imports
Imports that have a `finished_status` should not be changed to
`aborted`.
Refs #4963
---
app/models/import.rb | 7 +++++--
spec/models/import_spec.rb | 11 +++++++++++
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/app/models/import.rb b/app/models/import.rb
index 6330bd560..060db8183 100644
--- a/app/models/import.rb
+++ b/app/models/import.rb
@@ -43,8 +43,11 @@ class Import < ActiveRecord::Base
end
def self.abort_old
- where('created_at < ?', 4.hours.ago)
- .update_all(status: 'aborted')
+ where(
+ 'created_at < ? AND status NOT IN (?)',
+ 4.hours.ago,
+ finished_statuses
+ ).update_all(status: 'aborted')
end
def notify_parent
diff --git a/spec/models/import_spec.rb b/spec/models/import_spec.rb
index 8c1037a48..aedcfe4ab 100644
--- a/spec/models/import_spec.rb
+++ b/spec/models/import_spec.rb
@@ -47,6 +47,17 @@ RSpec.describe Import, type: :model do
end
it "doesn't work on imports with a `finished_status`" do
+ Timecop.freeze(Time.now) do
+ import = create(
+ :workbench_import,
+ status: 'successful',
+ created_at: 4.hours.ago - 1.minute
+ )
+
+ Import.abort_old
+
+ expect(import.reload.status).to eq('successful')
+ end
end
end
--
cgit v1.2.3
From be1e4ce05348e722e52c2e68f5b1c1514caa00dd Mon Sep 17 00:00:00 2001
From: Teddy Wing
Date: Mon, 5 Feb 2018 16:11:03 +0100
Subject: schedule.rb: Abort old imports before import notification
As a result of a new requirement, before doing the existing work we were
doing in the imports cron job (notifying parent imports), we first need
to clear out old imports and mark them as 'aborted'.
Refs #4963
---
config/schedule.rb | 1 +
lib/tasks/imports.rake | 5 +++++
2 files changed, 6 insertions(+)
diff --git a/config/schedule.rb b/config/schedule.rb
index 08488c255..636ab654e 100644
--- a/config/schedule.rb
+++ b/config/schedule.rb
@@ -40,6 +40,7 @@ every :day, :at => '4:00 am' do
end
every 5.minutes do
+ rake "import:abort_old"
rake "import:notify_parent"
end
diff --git a/lib/tasks/imports.rake b/lib/tasks/imports.rake
index 6bc84acc8..fee850b23 100644
--- a/lib/tasks/imports.rake
+++ b/lib/tasks/imports.rake
@@ -3,4 +3,9 @@ namespace :import do
task notify_parent: :environment do
ParentImportNotifier.notify_when_finished
end
+
+ desc "Mark old unfinished imports as 'aborted'"
+ task abort_old: :environment do
+ Import.abort_old
+ end
end
--
cgit v1.2.3
From 2e346505cbf2f82c5aaf6fca37966a39b6c9656c Mon Sep 17 00:00:00 2001
From: Teddy Wing
Date: Mon, 5 Feb 2018 16:54:01 +0100
Subject: imports.rake: Change `abort_old` to `netex_abort_old`
After re-reading the ticket, I see now that the aborting of old imports
should only apply to `NetexImport`s. Update the code to make this
happen.
Refs #4963
---
config/schedule.rb | 2 +-
lib/tasks/imports.rake | 6 +++---
spec/models/import_spec.rb | 20 ++++++++++++++++++++
3 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/config/schedule.rb b/config/schedule.rb
index 636ab654e..40ee8e4ac 100644
--- a/config/schedule.rb
+++ b/config/schedule.rb
@@ -40,7 +40,7 @@ every :day, :at => '4:00 am' do
end
every 5.minutes do
- rake "import:abort_old"
+ rake "import:netex_abort_old"
rake "import:notify_parent"
end
diff --git a/lib/tasks/imports.rake b/lib/tasks/imports.rake
index fee850b23..9d0fc8726 100644
--- a/lib/tasks/imports.rake
+++ b/lib/tasks/imports.rake
@@ -4,8 +4,8 @@ namespace :import do
ParentImportNotifier.notify_when_finished
end
- desc "Mark old unfinished imports as 'aborted'"
- task abort_old: :environment do
- Import.abort_old
+ desc "Mark old unfinished Netex imports as 'aborted'"
+ task netex_abort_old: :environment do
+ NetexImport.abort_old
end
end
diff --git a/spec/models/import_spec.rb b/spec/models/import_spec.rb
index aedcfe4ab..8b85f151b 100644
--- a/spec/models/import_spec.rb
+++ b/spec/models/import_spec.rb
@@ -59,6 +59,26 @@ RSpec.describe Import, type: :model do
expect(import.reload.status).to eq('successful')
end
end
+
+ it "only works on the caller type" do
+ Timecop.freeze(Time.now) do
+ workbench_import = create(
+ :workbench_import,
+ status: 'pending',
+ created_at: 4.hours.ago - 1.minute
+ )
+ netex_import = create(
+ :netex_import,
+ status: 'pending',
+ created_at: 4.hours.ago - 1.minute
+ )
+
+ NetexImport.abort_old
+
+ expect(workbench_import.reload.status).to eq('pending')
+ expect(netex_import.reload.status).to eq('aborted')
+ end
+ end
end
describe "#destroy" do
--
cgit v1.2.3
From f6a581980fc63dd84372161c2fd711c0b50bb2df Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 12 Jan 2018 11:31:14 +0100
Subject: Refs #5571 @0.25h; Let the user select the number of items per page
on ReferentialVehicleJourneys#index
---
app/assets/stylesheets/components/_forms.sass | 4 ++++
app/controllers/referential_vehicle_journeys_controller.rb | 2 +-
app/views/referential_vehicle_journeys/_filters.html.slim | 3 +++
config/locales/simple_form.en.yml | 1 +
config/locales/simple_form.fr.yml | 1 +
5 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/app/assets/stylesheets/components/_forms.sass b/app/assets/stylesheets/components/_forms.sass
index b7f720963..1f0d2f59b 100644
--- a/app/assets/stylesheets/components/_forms.sass
+++ b/app/assets/stylesheets/components/_forms.sass
@@ -444,6 +444,10 @@ table, .table
margin: 0
min-height: 41px
padding: 5px 15px
+ &.per-page-select
+ padding-top: 10px
+ .selected
+ font-weight: bold
.control-label
font-weight: 700
diff --git a/app/controllers/referential_vehicle_journeys_controller.rb b/app/controllers/referential_vehicle_journeys_controller.rb
index f93de29cc..89b3703a0 100644
--- a/app/controllers/referential_vehicle_journeys_controller.rb
+++ b/app/controllers/referential_vehicle_journeys_controller.rb
@@ -13,7 +13,7 @@ class ReferentialVehicleJourneysController < ChouetteController
@q ||= end_of_association_chain
@q = @q.with_stop_area_ids(params[:q][:stop_area_ids]) if params[:q] && params[:q][:stop_area_ids]
@q = @q.ransack(params[:q])
- @vehicle_journeys ||= @q.result.order(:published_journey_name).includes(:vehicle_journey_at_stops).paginate page: params[:page], per_page: 10
+ @vehicle_journeys ||= @q.result.order(:published_journey_name).includes(:vehicle_journey_at_stops).paginate page: params[:page], per_page: params[:per_page] || 10
@all_companies = Chouette::Company.where("id IN (#{@referential.vehicle_journeys.select(:company_id).to_sql})").distinct
@all_stop_areas = Chouette::StopArea.where("id IN (#{@referential.vehicle_journeys.joins(:stop_areas).select("stop_areas.id").to_sql})").distinct
end
diff --git a/app/views/referential_vehicle_journeys/_filters.html.slim b/app/views/referential_vehicle_journeys/_filters.html.slim
index f85ef1eb9..1301d3dab 100644
--- a/app/views/referential_vehicle_journeys/_filters.html.slim
+++ b/app/views/referential_vehicle_journeys/_filters.html.slim
@@ -6,6 +6,9 @@
button.btn.btn-default#search-btn type='submit'
span.fa.fa-search
.ffg-row
+ .form-group.per-page-select
+ = I18n.t("simple_form.per_page")
+ = %w(10 50 100).each_with_index.map{ |v, i| (params[:per_page] == v || params[:per_page].nil? && i == 0) ? "#{v} " : link_to(v, referential_vehicle_journeys_path(@referential, q: params[:q], per_page: v)) }.join(' - ').html_safe
.form-group.togglable
= f.label Chouette::VehicleJourney.human_attribute_name(:company), required: false, class: 'control-label'
- if @all_companies.present?
diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml
index ad722312e..ed4ad2e95 100644
--- a/config/locales/simple_form.en.yml
+++ b/config/locales/simple_form.en.yml
@@ -1,5 +1,6 @@
en:
simple_form:
+ "per_page": "Per page: "
"yes": 'Yes'
"no": 'No'
from: 'From'
diff --git a/config/locales/simple_form.fr.yml b/config/locales/simple_form.fr.yml
index cd5dd1fbe..a1868eef7 100644
--- a/config/locales/simple_form.fr.yml
+++ b/config/locales/simple_form.fr.yml
@@ -1,5 +1,6 @@
fr:
simple_form:
+ "per_page": "Afficher par: "
"yes": 'Oui'
"no": 'Non'
from: 'Du'
--
cgit v1.2.3
From 97ae053caa9e140dd3b3556dab542cc19d6ea8bd Mon Sep 17 00:00:00 2001
From: Zog
Date: Thu, 25 Jan 2018 14:42:08 +0100
Subject: Refs #5718; Show times at stops in ReferentialVehicleJourneys#index
When 1 or 2 stops have been selected
---
.../referential_vehicle_journeys_controller.rb | 2 ++
app/helpers/vehicle_journeys_helper.rb | 24 ++++++++++++++--------
.../referential_vehicle_journeys/index.html.slim | 3 ++-
3 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/app/controllers/referential_vehicle_journeys_controller.rb b/app/controllers/referential_vehicle_journeys_controller.rb
index 89b3703a0..c3fcde0b1 100644
--- a/app/controllers/referential_vehicle_journeys_controller.rb
+++ b/app/controllers/referential_vehicle_journeys_controller.rb
@@ -16,6 +16,8 @@ class ReferentialVehicleJourneysController < ChouetteController
@vehicle_journeys ||= @q.result.order(:published_journey_name).includes(:vehicle_journey_at_stops).paginate page: params[:page], per_page: params[:per_page] || 10
@all_companies = Chouette::Company.where("id IN (#{@referential.vehicle_journeys.select(:company_id).to_sql})").distinct
@all_stop_areas = Chouette::StopArea.where("id IN (#{@referential.vehicle_journeys.joins(:stop_areas).select("stop_areas.id").to_sql})").distinct
+ stop_area_ids = params[:q][:stop_area_ids].select(&:present?)
+ @filters_stop_areas = Chouette::StopArea.find(stop_area_ids) if stop_area_ids.present? && stop_area_ids.size <= 2
end
end
diff --git a/app/helpers/vehicle_journeys_helper.rb b/app/helpers/vehicle_journeys_helper.rb
index 6877abd11..1cc865c62 100644
--- a/app/helpers/vehicle_journeys_helper.rb
+++ b/app/helpers/vehicle_journeys_helper.rb
@@ -1,5 +1,5 @@
module VehicleJourneysHelper
-
+
def vehicle_name( vehicle)
if !vehicle.published_journey_name.blank?
vehicle.published_journey_name.first(8)
@@ -11,11 +11,11 @@ module VehicleJourneysHelper
vehicle.id
end
end
-
+
def missing_time_check( is_present)
return "missing" if (is_present && is_present.departure_time.nil?)
end
-
+
def vehicle_departure(vehicle, departure_time=nil)
unless departure_time
first_vjas = vehicle.vehicle_journey_at_stops.first
@@ -24,7 +24,7 @@ module VehicleJourneysHelper
end
l(departure_time, :format => :hour).gsub( / /, ' ')
end
-
+
def vehicle_title(vehicle, journey_frequency=nil)
return t("vehicle_journeys.vehicle_journey#{'_frequency' if vehicle.frequency?}.title_stopless", :name => vehicle_name( vehicle)) if vehicle.vehicle_journey_at_stops.empty?
first_vjas = vehicle.vehicle_journey_at_stops.first
@@ -40,7 +40,7 @@ module VehicleJourneysHelper
:time => vehicle_departure(vehicle, (journey_frequency ? journey_frequency.first_departure_time : nil )))
end
end
-
+
def route_journey_pattern_label_pairs route
route
.journey_patterns
@@ -50,7 +50,7 @@ module VehicleJourneysHelper
def edit_vehicle_title( vehicle)
return t('vehicle_journeys.edit.title_stopless', :name => vehicle_name( vehicle)) if vehicle.vehicle_journey_at_stops.empty?
first_vjas = vehicle.vehicle_journey_at_stops.first
- t('vehicle_journeys.edit.title',
+ t('vehicle_journeys.edit.title',
:name => vehicle_name( vehicle),
:stop => first_vjas.stop_point.stop_area.name,
:time => vehicle_departure(vehicle))
@@ -59,6 +59,14 @@ module VehicleJourneysHelper
def exist_vehicle_journeys?(route)
route.vehicle_journeys.count > 0
end
-
-end
+ def table_builder_column_for_stop_area stop_area
+ return nil unless stop_area
+ TableBuilderHelper::Column.new(
+ name: stop_area.name,
+ attribute: Proc.new {|v| v.vehicle_journey_at_stops.find{|vjas| vjas.stop_point.stop_area_id == stop_area.id}&.departure },
+ sortable: false
+ )
+ end
+
+end
diff --git a/app/views/referential_vehicle_journeys/index.html.slim b/app/views/referential_vehicle_journeys/index.html.slim
index d29a78a6c..69e29597c 100644
--- a/app/views/referential_vehicle_journeys/index.html.slim
+++ b/app/views/referential_vehicle_journeys/index.html.slim
@@ -42,12 +42,13 @@
attribute: Proc.new {|v| v.vehicle_journey_at_stops.first&.departure }, \
sortable: false \
), \
+ @filters_stop_areas&.map{|s| table_builder_column_for_stop_area(s)},
TableBuilderHelper::Column.new( \
key: :arrival_time, \
attribute: Proc.new {|v| v.vehicle_journey_at_stops.last&.arrival }, \
sortable: false \
), \
- ],
+ ].flatten.compact,
cls: 'table has-filter has-search'
= new_pagination @vehicle_journeys, 'pull-right'
--
cgit v1.2.3
From 76607faf09c0dabd5282d4b6e5624c75d4625a63 Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 26 Jan 2018 12:49:23 +0100
Subject: Refs #5741 @2h; Add a map of all routes on a line#show
---
Gemfile.lock | 22 +--
app/assets/stylesheets/OpenLayers/custom.sass | 21 +++
app/helpers/routes_helper.rb | 8 +-
app/javascript/helpers/routes_map.coffee | 157 ++++++++++++++++++++++
app/javascript/packs/referential_lines/show.js | 10 ++
app/javascript/packs/routes/show.js | 123 +----------------
app/javascript/routes/components/StopPointList.js | 4 +-
app/views/referential_lines/show.html.slim | 8 +-
config/webpack/environment.js | 2 +
config/webpack/loaders/coffee.js | 6 +
package.json | 3 +-
yarn.lock | 12 +-
12 files changed, 238 insertions(+), 138 deletions(-)
create mode 100644 app/javascript/helpers/routes_map.coffee
create mode 100644 app/javascript/packs/referential_lines/show.js
create mode 100644 config/webpack/loaders/coffee.js
diff --git a/Gemfile.lock b/Gemfile.lock
index ba1a90a5a..ba86a911f 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -156,6 +156,7 @@ GEM
sort_alphabetical (~> 1.0)
crack (0.4.3)
safe_yaml (~> 1.0.0)
+ crass (1.0.3)
cucumber (2.4.0)
builder (>= 2.1.2)
cucumber-core (~> 1.5.0)
@@ -265,7 +266,7 @@ GEM
htmlbeautifier (1.3.1)
httparty (0.14.0)
multi_xml (>= 0.5.2)
- i18n (0.9.0)
+ i18n (0.9.3)
concurrent-ruby (~> 1.0)
i18n-tasks (0.9.15)
activesupport (>= 4.0.2)
@@ -302,7 +303,8 @@ GEM
thor
with_env (> 1.0)
xml-simple
- loofah (2.0.3)
+ loofah (2.1.1)
+ crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.6.4)
mime-types (>= 1.16, < 4)
@@ -313,7 +315,7 @@ GEM
mime-types-data (3.2016.0521)
mimemagic (0.3.2)
mini_portile2 (2.3.0)
- minitest (5.10.3)
+ minitest (5.11.2)
money (6.10.1)
i18n (>= 0.6.4, < 1.0)
multi_json (1.12.1)
@@ -368,7 +370,7 @@ GEM
rack
rack-protection (1.5.3)
rack
- rack-proxy (0.6.2)
+ rack-proxy (0.6.3)
rack
rack-test (0.6.3)
rack (>= 1.0)
@@ -396,8 +398,8 @@ GEM
rails-assets-jquery (>= 1.0.0)
rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha)
- rails-dom-testing (1.0.8)
- activesupport (>= 4.2.0.beta, < 5.0)
+ rails-dom-testing (1.0.9)
+ activesupport (>= 4.2.0, < 5.0)
nokogiri (~> 1.6)
rails-deprecated_sanitizer (>= 1.0.1)
rails-erd (1.5.2)
@@ -419,7 +421,7 @@ GEM
thor (>= 0.18.1, < 2.0)
rainbow (2.2.2)
rake
- rake (12.0.0)
+ rake (12.3.0)
ransack (1.8.3)
actionpack (>= 3.0)
activerecord (>= 3.0)
@@ -535,7 +537,7 @@ GEM
therubyracer (0.12.3)
libv8 (~> 3.16.14.15)
ref
- thor (0.19.4)
+ thor (0.20.0)
thread (0.2.2)
thread_safe (0.3.6)
tilt (1.4.1)
@@ -547,7 +549,7 @@ GEM
json (>= 1.8, < 3.0)
parser (>= 2.3.0.7)
rainbow (>= 1.99.1, < 3.0)
- tzinfo (1.2.3)
+ tzinfo (1.2.4)
thread_safe (~> 0.1)
uglifier (2.7.2)
execjs (>= 0.3.0)
@@ -560,7 +562,7 @@ GEM
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff
- webpacker (3.0.2)
+ webpacker (3.2.1)
activesupport (>= 4.2)
rack-proxy (>= 0.6.1)
railties (>= 4.2)
diff --git a/app/assets/stylesheets/OpenLayers/custom.sass b/app/assets/stylesheets/OpenLayers/custom.sass
index 7a5b4baf1..5a3612f99 100644
--- a/app/assets/stylesheets/OpenLayers/custom.sass
+++ b/app/assets/stylesheets/OpenLayers/custom.sass
@@ -2,6 +2,27 @@
.list-group-item &
margin-top: 15px
+ .routes-labels
+ padding: 0
+ display: flex
+ justify-content: space-between
+ flex-wrap: wrap
+ margin: 5px -5px
+ li
+ list-style-type: none
+ flex: 1 0 25%
+ border: 1px solid $lightgrey
+ padding: 5px
+ margin: 5px
+ border-radius: 5px
+ cursor: pointer
+ color: $blue
+ white-space: nowrap
+ max-width: 33%
+
+ &:hover
+ background: $orange
+ color: white
.ol-scale-line
background-color: transparent
diff --git a/app/helpers/routes_helper.rb b/app/helpers/routes_helper.rb
index 4bffa99d4..61714a066 100644
--- a/app/helpers/routes_helper.rb
+++ b/app/helpers/routes_helper.rb
@@ -19,13 +19,15 @@ module RoutesHelper
css
end
- def route_json_for_edit(route)
- route.stop_points.includes(:stop_area).order(:position).map do |stop_point|
+ def route_json_for_edit(route, serialize: true)
+ data = route.stop_points.includes(:stop_area).order(:position).map do |stop_point|
stop_area_attributes = stop_point.stop_area.attributes.slice("name","city_name", "zip_code", "registration_number", "longitude", "latitude", "area_type", "comment")
stop_area_attributes["short_name"] = truncate(stop_area_attributes["name"], :length => 30) || ""
stop_point_attributes = stop_point.attributes.slice("for_boarding","for_alighting")
stop_area_attributes.merge(stop_point_attributes).merge(stoppoint_id: stop_point.id, stoparea_id: stop_point.stop_area.id).merge(user_objectid: stop_point.stop_area.user_objectid)
- end.to_json
+ end
+ data = data.to_json if serialize
+ data
end
end
diff --git a/app/javascript/helpers/routes_map.coffee b/app/javascript/helpers/routes_map.coffee
new file mode 100644
index 000000000..85def1390
--- /dev/null
+++ b/app/javascript/helpers/routes_map.coffee
@@ -0,0 +1,157 @@
+class RoutesMap
+ constructor: (@target)->
+ @initMap()
+ @area = []
+ @seenStopIds = []
+ @routes = {}
+
+ initMap: ->
+ @map = new ol.Map
+ target: @target,
+ layers: [ new ol.layer.Tile(source: new ol.source.OSM()) ]
+ controls: [ new ol.control.ScaleLine(), new ol.control.Zoom(), new ol.control.ZoomSlider() ],
+ interactions: ol.interaction.defaults(zoom: true)
+ view: new ol.View()
+
+ addRoutes: (routes)->
+ for route in routes
+ @addRoute route
+
+ addRoute: (route)->
+ geoColPts = []
+ geoColLns = []
+ @routes[route.id] = route if route.id
+ stops = route.stops || route
+ geoColEdges = [
+ new ol.Feature({
+ geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(stops[0].longitude), parseFloat(stops[0].latitude)]))
+ }),
+ new ol.Feature({
+ geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(stops[stops.length - 1].longitude), parseFloat(stops[stops.length - 1].latitude)]))
+ })
+ ]
+ stops.forEach (stop, i) =>
+ if i < stops.length - 1
+ geoColLns.push new ol.Feature
+ geometry: new ol.geom.LineString([
+ ol.proj.fromLonLat([parseFloat(stops[i].longitude), parseFloat(stops[i].latitude)]),
+ ol.proj.fromLonLat([parseFloat(stops[i + 1].longitude), parseFloat(stops[i + 1].latitude)])
+ ])
+
+ geoColPts.push(new ol.Feature({
+ geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(stop.longitude), parseFloat(stop.latitude)]))
+ }))
+ unless @seenStopIds.indexOf(stop.stoparea_id) > 0
+ @area.push [parseFloat(stop.longitude), parseFloat(stop.latitude)]
+ @seenStopIds.push stop.stoparea_id
+
+ vectorPtsLayer = new ol.layer.Vector({
+ source: new ol.source.Vector({
+ features: geoColPts
+ }),
+ style: @defaultStyles(),
+ zIndex: 2
+ })
+ route.vectorPtsLayer = vectorPtsLayer if route.id
+ vectorEdgesLayer = new ol.layer.Vector({
+ source: new ol.source.Vector({
+ features: geoColEdges
+ }),
+ style: @edgeStyles(),
+ zIndex: 3
+ })
+ route.vectorEdgesLayer = vectorEdgesLayer if route.id
+ vectorLnsLayer = new ol.layer.Vector({
+ source: new ol.source.Vector({
+ features: geoColLns
+ }),
+ style: [@lineStyle()],
+ zIndex: 1
+ })
+ route.vectorLnsLayer = vectorLnsLayer if route.id
+ @map.addLayer vectorPtsLayer
+ @map.addLayer vectorEdgesLayer
+ @map.addLayer vectorLnsLayer
+
+ lineStyle: (highlighted=false)->
+ new ol.style.Style
+ stroke: new ol.style.Stroke
+ color: if highlighted then "#ed7f00" else '#007fbb'
+ width: 3
+
+ edgeStyles: (highlighted=false)->
+ new ol.style.Style
+ image: new ol.style.Circle
+ radius: 5
+ stroke: new ol.style.Stroke
+ color: if highlighted then "#ed7f00" else '#007fbb'
+ width: 2
+ fill: new ol.style.Fill
+ color: if highlighted then "#ed7f00" else '#007fbb'
+ width: 2
+
+ defaultStyles: (highlighted=false)->
+ new ol.style.Style
+ image: new ol.style.Circle
+ radius: 4
+ stroke: new ol.style.Stroke
+ color: if highlighted then "#ed7f00" else '#007fbb'
+ width: 2
+ fill: new ol.style.Fill
+ color: '#ffffff'
+ width: 2
+
+ addRoutesLabels: ->
+ labelsContainer = $("")
+ labelsContainer.appendTo $("##{@target}")
+ @vectorPtsLayer = null
+ @vectorEdgesLayer = null
+ @vectorLnsLayer = null
+ Object.keys(@routes).forEach (id)=>
+ route = @routes[id]
+ label = $("#{route.name} ")
+ label.appendTo labelsContainer
+ label.mouseleave =>
+ route.vectorPtsLayer.setStyle @defaultStyles(false)
+ route.vectorEdgesLayer.setStyle @edgeStyles(false)
+ route.vectorLnsLayer.setStyle @lineStyle(false)
+ route.vectorPtsLayer.setZIndex 2
+ route.vectorEdgesLayer.setZIndex 3
+ route.vectorLnsLayer.setZIndex 1
+ @fitZoom()
+ label.mouseenter =>
+ route.vectorPtsLayer.setStyle @defaultStyles(true)
+ route.vectorEdgesLayer.setStyle @edgeStyles(true)
+ route.vectorLnsLayer.setStyle @lineStyle(true)
+ route.vectorPtsLayer.setZIndex 11
+ route.vectorEdgesLayer.setZIndex 12
+ route.vectorLnsLayer.setZIndex 10
+ @fitZoom(route)
+
+ fitZoom: (route)->
+ if route
+ area = []
+ route.stops.forEach (stop, i) =>
+ area.push [parseFloat(stop.longitude), parseFloat(stop.latitude)]
+ else
+ area = @area
+ boundaries = ol.extent.applyTransform(
+ ol.extent.boundingExtent(area), ol.proj.getTransform('EPSG:4326', 'EPSG:3857')
+ )
+ @map.getView().fit boundaries, @map.getSize()
+ tooCloseToBounds = false
+ mapBoundaries = @map.getView().calculateExtent @map.getSize()
+ mapWidth = mapBoundaries[2] - mapBoundaries[0]
+ mapHeight = mapBoundaries[3] - mapBoundaries[1]
+ marginSize = 0.1
+ heightMargin = marginSize * mapHeight
+ widthMargin = marginSize * mapWidth
+ tooCloseToBounds = tooCloseToBounds || (boundaries[0] - mapBoundaries[0]) < widthMargin
+ tooCloseToBounds = tooCloseToBounds || (mapBoundaries[2] - boundaries[2]) < widthMargin
+ tooCloseToBounds = tooCloseToBounds || (boundaries[1] - mapBoundaries[1]) < heightMargin
+ tooCloseToBounds = tooCloseToBounds || (mapBoundaries[3] - boundaries[3]) < heightMargin
+ if tooCloseToBounds
+ @map.getView().setZoom(@map.getView().getZoom() - 1)
+
+
+export default RoutesMap
diff --git a/app/javascript/packs/referential_lines/show.js b/app/javascript/packs/referential_lines/show.js
new file mode 100644
index 000000000..99c5072ef
--- /dev/null
+++ b/app/javascript/packs/referential_lines/show.js
@@ -0,0 +1,10 @@
+import clone from '../../helpers/clone'
+import RoutesMap from '../../helpers/routes_map'
+
+let routes = clone(window, "routes", true)
+routes = JSON.parse(decodeURIComponent(routes))
+
+var map = new RoutesMap('routes_map')
+map.addRoutes(routes)
+map.addRoutesLabels()
+map.fitZoom()
diff --git a/app/javascript/packs/routes/show.js b/app/javascript/packs/routes/show.js
index 71777c379..c20de0800 100644
--- a/app/javascript/packs/routes/show.js
+++ b/app/javascript/packs/routes/show.js
@@ -1,121 +1,8 @@
import clone from '../../helpers/clone'
+import RoutesMap from '../../helpers/routes_map'
+
let route = clone(window, "route", true)
route = JSON.parse(decodeURIComponent(route))
-
-const geoColPts = []
-const geoColLns = []
-const area = []
-const geoColEdges = [
- new ol.Feature({
- geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(route[0].longitude), parseFloat(route[0].latitude)]))
- }),
- new ol.Feature({
- geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(route[route.length - 1].longitude), parseFloat(route[route.length - 1].latitude)]))
- })
-]
-route.forEach(function (stop, i) {
- if (i < route.length - 1) {
- geoColLns.push(new ol.Feature({
- geometry: new ol.geom.LineString([
- ol.proj.fromLonLat([parseFloat(route[i].longitude), parseFloat(route[i].latitude)]),
- ol.proj.fromLonLat([parseFloat(route[i + 1].longitude), parseFloat(route[i + 1].latitude)])
- ])
- }))
- }
- geoColPts.push(new ol.Feature({
- geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(stop.longitude), parseFloat(stop.latitude)]))
- }))
- area.push([parseFloat(stop.longitude), parseFloat(stop.latitude)])
-})
-var edgeStyles = new ol.style.Style({
- image: new ol.style.Circle(({
- radius: 5,
- stroke: new ol.style.Stroke({
- color: '#007fbb',
- width: 2
- }),
- fill: new ol.style.Fill({
- color: '#007fbb',
- width: 2
- })
- }))
-})
-var defaultStyles = new ol.style.Style({
- image: new ol.style.Circle(({
- radius: 4,
- stroke: new ol.style.Stroke({
- color: '#007fbb',
- width: 2
- }),
- fill: new ol.style.Fill({
- color: '#ffffff',
- width: 2
- })
- }))
-})
-var lineStyle = new ol.style.Style({
- stroke: new ol.style.Stroke({
- color: '#007fbb',
- width: 3
- })
-})
-
-var vectorPtsLayer = new ol.layer.Vector({
- source: new ol.source.Vector({
- features: geoColPts
- }),
- style: defaultStyles,
- zIndex: 2
-})
-var vectorEdgesLayer = new ol.layer.Vector({
- source: new ol.source.Vector({
- features: geoColEdges
- }),
- style: edgeStyles,
- zIndex: 3
-})
-var vectorLnsLayer = new ol.layer.Vector({
- source: new ol.source.Vector({
- features: geoColLns
- }),
- style: [lineStyle],
- zIndex: 1
-})
-
-var map = new ol.Map({
- target: 'route_map',
- layers: [
- new ol.layer.Tile({
- source: new ol.source.OSM()
- }),
- vectorPtsLayer,
- vectorEdgesLayer,
- vectorLnsLayer
- ],
- controls: [new ol.control.ScaleLine(), new ol.control.Zoom(), new ol.control.ZoomSlider()],
- interactions: ol.interaction.defaults({
- zoom: true
- }),
- view: new ol.View({
- center: ol.proj.fromLonLat([parseFloat(route[0].longitude), parseFloat(route[0].latitude)]),
- zoom: 13
- })
-});
-const boundaries = ol.extent.applyTransform(
- ol.extent.boundingExtent(area), ol.proj.getTransform('EPSG:4326', 'EPSG:3857')
-)
-map.getView().fit(boundaries, map.getSize());
-let tooCloseToBounds = false
-const mapBoundaries = map.getView().calculateExtent(map.getSize())
-const mapWidth = mapBoundaries[2] - mapBoundaries[0]
-const mapHeight = mapBoundaries[3] - mapBoundaries[1]
-const marginSize = 0.1
-const heightMargin = marginSize * mapHeight
-const widthMargin = marginSize * mapWidth
-tooCloseToBounds = tooCloseToBounds || (boundaries[0] - mapBoundaries[0]) < widthMargin
-tooCloseToBounds = tooCloseToBounds || (mapBoundaries[2] - boundaries[2]) < widthMargin
-tooCloseToBounds = tooCloseToBounds || (boundaries[1] - mapBoundaries[1]) < heightMargin
-tooCloseToBounds = tooCloseToBounds || (mapBoundaries[3] - boundaries[3]) < heightMargin
-if(tooCloseToBounds){
- map.getView().setZoom(map.getView().getZoom() - 1)
-}
+var map = new RoutesMap('route_map')
+map.addRoute(route)
+map.fitZoom()
diff --git a/app/javascript/routes/components/StopPointList.js b/app/javascript/routes/components/StopPointList.js
index 43a027084..b39fa0c9c 100644
--- a/app/javascript/routes/components/StopPointList.js
+++ b/app/javascript/routes/components/StopPointList.js
@@ -56,7 +56,7 @@ export default function StopPointList({ stopPoints, onDeleteClick, onMoveUpClick
)
}
-StopPointList.PropTypes = {
+StopPointList.propTypes = {
stopPoints: PropTypes.array.isRequired,
onDeleteClick: PropTypes.func.isRequired,
onMoveUpClick: PropTypes.func.isRequired,
@@ -68,4 +68,4 @@ StopPointList.PropTypes = {
StopPointList.contextTypes = {
I18n: PropTypes.object
-}
\ No newline at end of file
+}
diff --git a/app/views/referential_lines/show.html.slim b/app/views/referential_lines/show.html.slim
index 02d605d8c..5ea0e31bb 100644
--- a/app/views/referential_lines/show.html.slim
+++ b/app/views/referential_lines/show.html.slim
@@ -17,7 +17,8 @@
@line.human_attribute_name(:transport_submode) => (@line.transport_submode.present? ? t("enumerize.transport_submode.#{@line.transport_submode}") : '-'),
@line.human_attribute_name(:url) => (@line.url ? @line.url : '-'),
@line.human_attribute_name(:seasonal) => (@line.seasonal? ? t('true') : t('false')),}
-
+ .col-lg-6.col-md-6.col-sm-12.col-xs-12
+ #routes_map.map.mb-lg
.row
.col-lg-12
.h3 = t('lines.show.routes.title')
@@ -79,3 +80,8 @@
.row.mt-xs
.col-lg-12
= replacement_msg t('routes.search_no_results')
+
+= javascript_tag do
+ | window.routes = "#{URI.escape(@routes.map{|r| {name: r.name, id: r.id, stops: route_json_for_edit(r, serialize: false)}}.to_json)}"
+
+= javascript_pack_tag 'referential_lines/show.js'
diff --git a/config/webpack/environment.js b/config/webpack/environment.js
index e7c879fb9..688bcbe8e 100644
--- a/config/webpack/environment.js
+++ b/config/webpack/environment.js
@@ -1,4 +1,5 @@
const { environment } = require('@rails/webpacker')
+const coffee = require('./loaders/coffee')
const CleanWebpackPlugin = require('clean-webpack-plugin')
let pathsToClean = [
@@ -24,4 +25,5 @@ environment.plugins.set(
// jquery: "jquery/src/jquery",
// }
+environment.loaders.append('coffee', coffee)
module.exports = environment
diff --git a/config/webpack/loaders/coffee.js b/config/webpack/loaders/coffee.js
new file mode 100644
index 000000000..4666716dc
--- /dev/null
+++ b/config/webpack/loaders/coffee.js
@@ -0,0 +1,6 @@
+module.exports = {
+ test: /\.coffee(\.erb)?$/,
+ use: [{
+ loader: 'coffee-loader'
+ }]
+}
diff --git a/package.json b/package.json
index 80ca22f83..802a2eef7 100644
--- a/package.json
+++ b/package.json
@@ -8,7 +8,8 @@
"babel-preset-react": "6.24.1",
"babelify": "8.0.0",
"bootstrap": "3",
- "coffeescript": "2.1.0",
+ "coffee-loader": "^0.9.0",
+ "coffeescript": "1.12.7",
"jquery": "3.2.1",
"lodash": "4.17.4",
"promise-polyfill": "7.0.0",
diff --git a/yarn.lock b/yarn.lock
index e95ee9a63..d17ae1d52 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1404,13 +1404,19 @@ code-point-at@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
+coffee-loader@^0.9.0:
+ version "0.9.0"
+ resolved "https://registry.yarnpkg.com/coffee-loader/-/coffee-loader-0.9.0.tgz#6deabd336062ddc6d773da4dfd16367fc7107bd6"
+ dependencies:
+ loader-utils "^1.0.2"
+
coffee-script@~1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.10.0.tgz#12938bcf9be1948fa006f92e0c4c9e81705108c0"
-coffeescript@2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-2.1.0.tgz#8cb7ce12021ab9f84d8c524f54edbd6141374606"
+coffeescript@1.12.7:
+ version "1.12.7"
+ resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-1.12.7.tgz#e57ee4c4867cf7f606bfc4a0f2d550c0981ddd27"
color-convert@^1.3.0, color-convert@^1.8.2, color-convert@^1.9.0:
version "1.9.0"
--
cgit v1.2.3
From 857e2f2319594f61436c2f2245136c303452d934 Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 26 Jan 2018 16:17:22 +0100
Subject: Refs #5750 @1h; Add a "kind" attribute to StopAreas
This determines if the StopArea is commercial or not
The useless fields are hidden in the form for the non-commercials ones
---
app/assets/stylesheets/components/_forms.sass | 8 ++++++-
app/javascript/helpers/master_slave.coffee | 18 ++++++++++++++++
app/javascript/packs/stop_areas/new.js | 3 +++
app/models/chouette/area_type.rb | 25 ++++++++++++++++------
app/models/chouette/stop_area.rb | 9 ++++++++
app/views/stop_areas/_form.html.slim | 10 +++++++--
app/views/stop_areas/show.html.slim | 8 +++----
config/locales/area_types.en.yml | 6 ++++++
config/locales/area_types.fr.yml | 6 ++++++
.../20180126134944_add_kind_to_stop_areas.rb | 5 +++++
db/schema.rb | 11 +++++++++-
spec/models/chouette/area_type_spec.rb | 4 +++-
12 files changed, 97 insertions(+), 16 deletions(-)
create mode 100644 app/javascript/helpers/master_slave.coffee
create mode 100644 app/javascript/packs/stop_areas/new.js
create mode 100644 db/migrate/20180126134944_add_kind_to_stop_areas.rb
diff --git a/app/assets/stylesheets/components/_forms.sass b/app/assets/stylesheets/components/_forms.sass
index 1f0d2f59b..998703ef0 100644
--- a/app/assets/stylesheets/components/_forms.sass
+++ b/app/assets/stylesheets/components/_forms.sass
@@ -85,9 +85,15 @@ input
// BS horizontal form label positionning fix
.form-horizontal
+ input[type="radio"].form-control
+ height: auto
+ width: auto
.form-group
position: relative
-
+ .radio-inline
+ padding-top: 4px
+ &:first-child
+ padding-left: 0
> .control-label
&[class*='col-sm-']
float: none
diff --git a/app/javascript/helpers/master_slave.coffee b/app/javascript/helpers/master_slave.coffee
new file mode 100644
index 000000000..11f6bca7e
--- /dev/null
+++ b/app/javascript/helpers/master_slave.coffee
@@ -0,0 +1,18 @@
+class MasterSlave
+ constructor: (selector)->
+ $(selector).find('[data-master]').each (i, slave)->
+ $slave = $(slave)
+ master = $($slave.data().master)
+ console.log $slave.data().master
+ console.log master
+ toggle = ->
+ val = master.filter(":checked").val() if master.filter("[type=radio]").length > 0
+ val ||= master.val()
+ selected = val == $slave.data().value
+ $slave.toggle selected
+ $slave.find("input, select").attr "disabled", !selected
+ master.change toggle
+ toggle()
+ # $slave.toggle master.val() == $slave.data().value
+
+export default MasterSlave
diff --git a/app/javascript/packs/stop_areas/new.js b/app/javascript/packs/stop_areas/new.js
new file mode 100644
index 000000000..ffe702cdb
--- /dev/null
+++ b/app/javascript/packs/stop_areas/new.js
@@ -0,0 +1,3 @@
+import MasterSlave from "../../helpers/master_slave"
+
+new MasterSlave("form")
diff --git a/app/models/chouette/area_type.rb b/app/models/chouette/area_type.rb
index 4703ea646..e17d2ee8d 100644
--- a/app/models/chouette/area_type.rb
+++ b/app/models/chouette/area_type.rb
@@ -1,13 +1,22 @@
class Chouette::AreaType
include Comparable
- ALL = %i(zdep zder zdlp zdlr lda gdl).freeze
+ COMMERCIAL = %i(zdep zder zdlp zdlr lda gdl).freeze
+ NON_COMMERCIAL = %i(deposit border service_area relief other).freeze
+ ALL = COMMERCIAL + NON_COMMERCIAL
+ @@commercial = COMMERCIAL
+ @@non_commercial = NON_COMMERCIAL
@@all = ALL
- mattr_accessor :all
+ mattr_accessor :all, :commercial, :non_commercial
- def self.all=(values)
- @@all = ALL & values
+ def self.commercial=(values)
+ @@commercial = COMMERCIAL & values
+ reset_caches!
+ end
+
+ def self.non_commercial=(values)
+ @@non_commercial = NON_COMMERCIAL & values
reset_caches!
end
@@ -20,12 +29,14 @@ class Chouette::AreaType
end
def self.reset_caches!
+ @@all = @@commercial + @@non_commercial
@@instances = {}
- @@options = nil
+ @@options = {}
end
- def self.options
- @@options ||= all.map { |c| find(c) }.map { |t| [ t.label, t.code ] }
+ def self.options(kind=:all)
+ @@options ||= {}
+ @@options[kind] ||= self.send(kind).map { |c| find(c) }.map { |t| [ t.label, t.code ] }
end
attr_reader :code
diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb
index ea1855ea8..d270a8696 100644
--- a/app/models/chouette/stop_area.rb
+++ b/app/models/chouette/stop_area.rb
@@ -10,6 +10,7 @@ module Chouette
extend Enumerize
enumerize :area_type, in: Chouette::AreaType::ALL
+ enumerize :kind, in: %i(commercial non_commercial)
with_options dependent: :destroy do |assoc|
assoc.has_many :stop_points
@@ -96,6 +97,10 @@ module Chouette
end
end
+ def local_id
+ id.to_s
+ end
+
def children_in_depth
return [] if self.children.empty?
@@ -374,5 +379,9 @@ module Chouette
return nil unless time_zone.present?
ActiveSupport::TimeZone[time_zone]&.formatted_offset
end
+
+ def commercial?
+ kind == "commercial"
+ end
end
end
diff --git a/app/views/stop_areas/_form.html.slim b/app/views/stop_areas/_form.html.slim
index b2322f73a..699381d50 100644
--- a/app/views/stop_areas/_form.html.slim
+++ b/app/views/stop_areas/_form.html.slim
@@ -7,9 +7,13 @@
= f.input :id, as: :hidden
= f.input :name, :input_html => {:title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.name")}
- = f.input :parent_id, as: :select, :collection => [f.object.parent_id], input_html: { data: { select2_ajax: 'true', url: autocomplete_stop_area_referential_stop_areas_path(@stop_area_referential), initvalue: {id: f.object.parent_id, text: f.object.parent.try(:full_name)}}}
+ = f.input :kind, as: :radio_buttons, :input_html => {:disabled => !@stop_area.new_record?}, :include_blank => false, item_wrapper_class: 'radio-inline', wrapper: :horizontal_form, item_class: "fooo"
- = f.input :area_type, as: :select, :input_html => {:disabled => !@stop_area.new_record?}, :collection => Chouette::AreaType.options, :include_blank => false
+ .slave data-master="[name='stop_area[kind]']" data-value="commercial"
+ = f.input :parent_id, as: :select, :collection => [f.object.parent_id], input_html: { data: { select2_ajax: 'true', url: autocomplete_stop_area_referential_stop_areas_path(@stop_area_referential), initvalue: {id: f.object.parent_id, text: f.object.parent.try(:full_name)}}}
+ - %i(commercial non_commercial).each do |kind|
+ .slave data-master="[name='stop_area[kind]']" data-value=kind
+ = f.input :area_type, as: :select, :input_html => {:disabled => !@stop_area.new_record?}, :collection => Chouette::AreaType.options(kind), :include_blank => false
.location_info
h3 = t("stop_areas.stop_area.localisation")
@@ -49,3 +53,5 @@
.separator
= f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'stop_area_form'
+
+= javascript_pack_tag "stop_areas/new"
diff --git a/app/views/stop_areas/show.html.slim b/app/views/stop_areas/show.html.slim
index b5ec8ac00..b0896c1e0 100644
--- a/app/views/stop_areas/show.html.slim
+++ b/app/views/stop_areas/show.html.slim
@@ -6,11 +6,11 @@
.container-fluid
.row
.col-lg-6.col-md-6.col-sm-12.col-xs-12
- - attributes = { t('id_reflex') => @stop_area.get_objectid.short_id,
- @stop_area.human_attribute_name(:parent) => @stop_area.parent ? link_to(@stop_area.parent.name, stop_area_referential_stop_area_path(@stop_area_referential, @stop_area.parent)) : "-",
- @stop_area.human_attribute_name(:stop_area_type) => Chouette::AreaType.find(@stop_area.area_type).try(:label),
+ - attributes = { t('id_reflex') => @stop_area.get_objectid.short_id }
+ - attributes.merge!({ @stop_area.human_attribute_name(:parent) => @stop_area.parent ? link_to(@stop_area.parent.name, stop_area_referential_stop_area_path(@stop_area_referential, @stop_area.parent)) : "-" }) if @stop_area.commercial?
+ - attributes.merge!({ @stop_area.human_attribute_name(:stop_area_type) => Chouette::AreaType.find(@stop_area.area_type).try(:label),
@stop_area.human_attribute_name(:registration_number) => @stop_area.registration_number,
- }
+ })
- attributes.merge!(@stop_area.human_attribute_name(:waiting_time) => @stop_area.waiting_time_text) if has_feature?(:stop_area_waiting_time)
- attributes.merge!({ "Coordonnées" => geo_data(@stop_area, @stop_area_referential),
@stop_area.human_attribute_name(:zip_code) => @stop_area.zip_code,
diff --git a/config/locales/area_types.en.yml b/config/locales/area_types.en.yml
index 34ec3243d..5d23a6665 100644
--- a/config/locales/area_types.en.yml
+++ b/config/locales/area_types.en.yml
@@ -6,3 +6,9 @@ en:
zdlp: ZDLp
zdlr: ZDLr
lda: LDA
+ gdl: GDL
+ deposit: Deposit
+ border: Border
+ service_area: Service Area
+ relief: Relief point
+ other: Other
diff --git a/config/locales/area_types.fr.yml b/config/locales/area_types.fr.yml
index fd4e1e741..bb249c235 100644
--- a/config/locales/area_types.fr.yml
+++ b/config/locales/area_types.fr.yml
@@ -6,3 +6,9 @@ fr:
zdlp: ZDLp
zdlr: ZDLr
lda: LDA
+ gdl: GDL
+ deposit: Dépôt
+ border: Frontière
+ service_area: Aire de service / Pause
+ relief: Point de releve
+ other: Autre
diff --git a/db/migrate/20180126134944_add_kind_to_stop_areas.rb b/db/migrate/20180126134944_add_kind_to_stop_areas.rb
new file mode 100644
index 000000000..3a4f0a0c8
--- /dev/null
+++ b/db/migrate/20180126134944_add_kind_to_stop_areas.rb
@@ -0,0 +1,5 @@
+class AddKindToStopAreas < ActiveRecord::Migration
+ def change
+ add_column :stop_areas, :kind, :string
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 11fb96ee3..9be702fa3 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,13 +11,18 @@
#
# It's strongly recommended that you check this file into your version control system.
+<<<<<<< HEAD
ActiveRecord::Schema.define(version: 20180123174450) do
+=======
+ActiveRecord::Schema.define(version: 20180126134944) do
+>>>>>>> Refs #5750 @1h; Add a "kind" attribute to StopAreas
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
- enable_extension "postgis"
enable_extension "hstore"
+ enable_extension "postgis"
enable_extension "unaccent"
+ enable_extension "objectid"
create_table "access_links", id: :bigserial, force: :cascade do |t|
t.integer "access_point_id", limit: 8
@@ -91,6 +96,8 @@ ActiveRecord::Schema.define(version: 20180123174450) do
t.datetime "created_at"
t.datetime "updated_at"
t.integer "workgroup_id", limit: 8
+ t.integer "int_day_types"
+ t.date "excluded_dates", array: true
end
add_index "calendars", ["organisation_id"], name: "index_calendars_on_organisation_id", using: :btree
@@ -117,6 +124,7 @@ ActiveRecord::Schema.define(version: 20180123174450) do
t.datetime "updated_at"
t.date "end_date"
t.string "date_type"
+ t.string "mode"
end
add_index "clean_ups", ["referential_id"], name: "index_clean_ups_on_referential_id", using: :btree
@@ -788,6 +796,7 @@ ActiveRecord::Schema.define(version: 20180123174450) do
t.datetime "updated_at"
t.string "stif_type"
t.integer "waiting_time"
+ t.string "kind"
end
add_index "stop_areas", ["name"], name: "index_stop_areas_on_name", using: :btree
diff --git a/spec/models/chouette/area_type_spec.rb b/spec/models/chouette/area_type_spec.rb
index 67d218df8..28325dd0a 100644
--- a/spec/models/chouette/area_type_spec.rb
+++ b/spec/models/chouette/area_type_spec.rb
@@ -4,7 +4,9 @@ RSpec.describe Chouette::AreaType do
describe "::ALL" do
it "includes all supported types" do
- expect(Chouette::AreaType::ALL).to match_array( %i(zdep zder zdlp zdlr lda gdl) )
+ expect(Chouette::AreaType::ALL).to match_array( %i(zdep zder zdlp zdlr lda gdl deposit border service_area relief other) )
+ expect(Chouette::AreaType::COMMERCIAL).to match_array( %i(zdep zder zdlp zdlr lda gdl) )
+ expect(Chouette::AreaType::NON_COMMERCIAL).to match_array( %i( deposit border service_area relief other) )
end
end
--
cgit v1.2.3
From a41d3b5e861929a75c6de23150d066ba366bb577 Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 29 Jan 2018 08:45:02 +0100
Subject: Refs #5750 @1h; Manage non-commercial StopAreas
- Add a `kind` attribute
- Hide irrelevant fields in the form
---
app/assets/stylesheets/modules/_vj_collection.sass | 3 +++
app/controllers/stop_areas_controller.rb | 1 +
app/controllers/vehicle_journeys_controller.rb | 2 ++
app/javascript/helpers/master_slave.coffee | 8 ++++----
app/javascript/helpers/stop_area_header_manager.js | 4 +++-
app/models/chouette/stop_area.rb | 8 ++++++++
app/policies/stop_area_policy.rb | 2 +-
app/views/stop_areas/_form.html.slim | 6 +++---
config/locales/stop_areas.fr.yml | 2 ++
db/migrate/20180126134944_add_kind_to_stop_areas.rb | 1 +
spec/models/chouette/stop_area_spec.rb | 10 ++++++++++
11 files changed, 38 insertions(+), 9 deletions(-)
diff --git a/app/assets/stylesheets/modules/_vj_collection.sass b/app/assets/stylesheets/modules/_vj_collection.sass
index 56769e52b..81c1fe43e 100644
--- a/app/assets/stylesheets/modules/_vj_collection.sass
+++ b/app/assets/stylesheets/modules/_vj_collection.sass
@@ -9,6 +9,9 @@
position: relative
padding-left: 25px
+ .fa
+ margin-left: 5px
+
> .headlined
&:before
margin-left: -25px
diff --git a/app/controllers/stop_areas_controller.rb b/app/controllers/stop_areas_controller.rb
index 79ffea72e..8e9df7157 100644
--- a/app/controllers/stop_areas_controller.rb
+++ b/app/controllers/stop_areas_controller.rb
@@ -203,6 +203,7 @@ class StopAreasController < ChouetteController
:url,
:waiting_time,
:zip_code,
+ :kind,
)
end
diff --git a/app/controllers/vehicle_journeys_controller.rb b/app/controllers/vehicle_journeys_controller.rb
index c1762c13e..ed6ba6ed1 100644
--- a/app/controllers/vehicle_journeys_controller.rb
+++ b/app/controllers/vehicle_journeys_controller.rb
@@ -66,6 +66,8 @@ class VehicleJourneysController < ChouetteController
:city_name => sp.stop_area.try(:city_name),
:comment => sp.stop_area.try(:comment),
:area_type => sp.stop_area.try(:area_type),
+ :area_type_i18n => I18n.t(sp.stop_area.try(:area_type), scope: 'area_types.label'),
+ :area_kind => sp.stop_area.try(:kind),
:stop_area_id => sp.stop_area_id,
:registration_number => sp.stop_area.try(:registration_number),
:nearest_topic_name => sp.stop_area.try(:nearest_topic_name),
diff --git a/app/javascript/helpers/master_slave.coffee b/app/javascript/helpers/master_slave.coffee
index 11f6bca7e..4866a55e3 100644
--- a/app/javascript/helpers/master_slave.coffee
+++ b/app/javascript/helpers/master_slave.coffee
@@ -3,16 +3,16 @@ class MasterSlave
$(selector).find('[data-master]').each (i, slave)->
$slave = $(slave)
master = $($slave.data().master)
- console.log $slave.data().master
- console.log master
+ console.log $slave
+ console.log $slave.find("input:disabled, select:disabled")
+ $slave.find("input:disabled, select:disabled").attr "data-slave-force-disabled", "true"
toggle = ->
val = master.filter(":checked").val() if master.filter("[type=radio]").length > 0
val ||= master.val()
selected = val == $slave.data().value
$slave.toggle selected
- $slave.find("input, select").attr "disabled", !selected
+ $slave.find("input, select").filter(":not([data-slave-force-disabled])").attr "disabled", !selected
master.change toggle
toggle()
- # $slave.toggle master.val() == $slave.data().value
export default MasterSlave
diff --git a/app/javascript/helpers/stop_area_header_manager.js b/app/javascript/helpers/stop_area_header_manager.js
index c9f397dee..2c820caf9 100644
--- a/app/javascript/helpers/stop_area_header_manager.js
+++ b/app/javascript/helpers/stop_area_header_manager.js
@@ -19,7 +19,7 @@ export default class StopAreaHeaderManager {
@@ -27,6 +27,8 @@ export default class StopAreaHeaderManager {
{sp.time_zone_formatted_offset &&
({sp.time_zone_formatted_offset})
}
+ {sp.area_kind == 'non_commercial' &&
+ }
diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb
index d270a8696..75a4a34bb 100644
--- a/app/models/chouette/stop_area.rb
+++ b/app/models/chouette/stop_area.rb
@@ -32,6 +32,7 @@ module Chouette
validates_format_of :registration_number, :with => %r{\A[\d\w_\-]+\Z}, :allow_blank => true
validates_presence_of :name
+ validates_presence_of :kind
validates_presence_of :latitude, :if => :longitude
validates_presence_of :longitude, :if => :latitude
validates_numericality_of :latitude, :less_than_or_equal_to => 90, :greater_than_or_equal_to => -90, :allow_nil => true
@@ -42,6 +43,7 @@ module Chouette
validates_numericality_of :waiting_time, greater_than_or_equal_to: 0, only_integer: true, if: :waiting_time
validate :parent_area_type_must_be_greater
+ validate :area_type_of_right_kind
def self.nullable_attributes
[:registration_number, :street_name, :country_code, :fare_code,
@@ -57,6 +59,12 @@ module Chouette
end
end
+ def area_type_of_right_kind
+ unless Chouette::AreaType.send(self.kind).include?(self.area_type)
+ errors.add(:area_type, I18n.t('stop_areas.errors.incorrect_kind_area_type'))
+ end
+ end
+
after_update :clean_invalid_access_links
before_save :coordinates_to_lat_lng
diff --git a/app/policies/stop_area_policy.rb b/app/policies/stop_area_policy.rb
index 6db48b702..fd73b7092 100644
--- a/app/policies/stop_area_policy.rb
+++ b/app/policies/stop_area_policy.rb
@@ -3,7 +3,7 @@ class StopAreaPolicy < ApplicationPolicy
def search_scope scope_name
scope = resolve
if scope_name&.to_s == "route_editor"
- scope = scope.where(area_type: 'zdep') unless user.organisation.has_feature?("route_stop_areas_all_types")
+ scope = scope.where("kind = ? OR area_type = ?", :non_commercial, 'zdep') unless user.organisation.has_feature?("route_stop_areas_all_types")
end
scope
end
diff --git a/app/views/stop_areas/_form.html.slim b/app/views/stop_areas/_form.html.slim
index 699381d50..6b75209b4 100644
--- a/app/views/stop_areas/_form.html.slim
+++ b/app/views/stop_areas/_form.html.slim
@@ -7,13 +7,13 @@
= f.input :id, as: :hidden
= f.input :name, :input_html => {:title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.name")}
- = f.input :kind, as: :radio_buttons, :input_html => {:disabled => !@stop_area.new_record?}, :include_blank => false, item_wrapper_class: 'radio-inline', wrapper: :horizontal_form, item_class: "fooo"
+ = f.input :kind, as: :radio_buttons, :input_html => {:disabled => !@stop_area.new_record?}, :include_blank => false, item_wrapper_class: 'radio-inline', wrapper: :horizontal_form, item_class: "fooo", disabled: !@stop_area.new_record?
.slave data-master="[name='stop_area[kind]']" data-value="commercial"
= f.input :parent_id, as: :select, :collection => [f.object.parent_id], input_html: { data: { select2_ajax: 'true', url: autocomplete_stop_area_referential_stop_areas_path(@stop_area_referential), initvalue: {id: f.object.parent_id, text: f.object.parent.try(:full_name)}}}
- - %i(commercial non_commercial).each do |kind|
+ - %i(non_commercial commercial).each do |kind|
.slave data-master="[name='stop_area[kind]']" data-value=kind
- = f.input :area_type, as: :select, :input_html => {:disabled => !@stop_area.new_record?}, :collection => Chouette::AreaType.options(kind), :include_blank => false
+ = f.input :area_type, as: :select, :input_html => {id: kind, :disabled => !@stop_area.new_record?}, :collection => Chouette::AreaType.options(kind), :include_blank => false, disabled: !@stop_area.new_record?
.location_info
h3 = t("stop_areas.stop_area.localisation")
diff --git a/config/locales/stop_areas.fr.yml b/config/locales/stop_areas.fr.yml
index 0095bbe6d..283000960 100644
--- a/config/locales/stop_areas.fr.yml
+++ b/config/locales/stop_areas.fr.yml
@@ -5,6 +5,7 @@ fr:
errors:
empty: Aucun stop_area_id
parent_area_type: ne peut être de type %{area_type}
+ incorrect_kind_area_type: Ce type d'arrêt est invalide pour cette catégorie
default_geometry_success: "%{count} arrêts édités"
stop_area:
no_position: "Pas de position"
@@ -97,6 +98,7 @@ fr:
attributes:
stop_area:
name: "Nom"
+ kind: "Catégorie"
registration_number: "Numéro d'enregistrement"
published_name: "Nom public"
deleted: "Supprimé"
diff --git a/db/migrate/20180126134944_add_kind_to_stop_areas.rb b/db/migrate/20180126134944_add_kind_to_stop_areas.rb
index 3a4f0a0c8..7da227cd9 100644
--- a/db/migrate/20180126134944_add_kind_to_stop_areas.rb
+++ b/db/migrate/20180126134944_add_kind_to_stop_areas.rb
@@ -1,5 +1,6 @@
class AddKindToStopAreas < ActiveRecord::Migration
def change
add_column :stop_areas, :kind, :string
+ Chouette::StopArea.update_all kind: :commmercial
end
end
diff --git a/spec/models/chouette/stop_area_spec.rb b/spec/models/chouette/stop_area_spec.rb
index a90e5d816..32ee5a3a6 100644
--- a/spec/models/chouette/stop_area_spec.rb
+++ b/spec/models/chouette/stop_area_spec.rb
@@ -10,10 +10,20 @@ describe Chouette::StopArea, :type => :model do
it { should belong_to(:stop_area_referential) }
it { should validate_presence_of :name }
+ it { should validate_presence_of :kind }
it { should validate_numericality_of :latitude }
it { should validate_numericality_of :longitude }
it { is_expected.to be_versioned }
+ describe "#area_type" do
+ it "should validate the value is correct regarding to the kind" do
+ expect(build(:stop_area, kind: :commercial, area_type: :gdl)).to be_valid
+ expect(build(:stop_area, kind: :non_commercial, area_type: :relief)).to be_valid
+ expect(build(:stop_area, kind: :commercial, area_type: :relief)).to_not be_valid
+ expect(build(:stop_area, kind: :non_commercial, area_type: :gdl)).to_not be_valid
+ end
+ end
+
# describe ".latitude" do
# it "should accept -90 value" do
# subject = create :stop_area, :area_type => "BoardingPosition"
--
cgit v1.2.3
From 755b07db36a10ffdbd315dff2b5315374eb3e58a Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 29 Jan 2018 10:32:05 +0100
Subject: Refs #5750; Add a validation on VehicleJourneys
Ensure a time is set for all non-commercial stops
---
app/assets/stylesheets/modules/_vj_collection.sass | 3 ++
app/javascript/vehicle_journeys/actions/index.js | 26 ++++++++++++++
.../components/SaveVehicleJourneys.js | 2 +-
.../vehicle_journeys/components/VehicleJourney.js | 3 ++
.../vehicle_journeys/components/VehicleJourneys.js | 2 +-
.../containers/SaveVehicleJourneys.js | 3 ++
.../vehicle_journeys/reducers/vehicleJourneys.js | 2 ++
app/views/vehicle_journeys/show.rabl | 1 +
spec/javascript/vehicle_journeys/actions_spec.js | 41 ++++++++++++++++++++++
9 files changed, 81 insertions(+), 2 deletions(-)
diff --git a/app/assets/stylesheets/modules/_vj_collection.sass b/app/assets/stylesheets/modules/_vj_collection.sass
index 81c1fe43e..d99c67bd7 100644
--- a/app/assets/stylesheets/modules/_vj_collection.sass
+++ b/app/assets/stylesheets/modules/_vj_collection.sass
@@ -116,6 +116,9 @@
margin-left: 5px
&.has-error
+ .errors
+ color: $red
+ font-size: 0.8em
&:before
content: ''
position: absolute
diff --git a/app/javascript/vehicle_journeys/actions/index.js b/app/javascript/vehicle_journeys/actions/index.js
index 2675328e3..b01158212 100644
--- a/app/javascript/vehicle_journeys/actions/index.js
+++ b/app/javascript/vehicle_journeys/actions/index.js
@@ -380,6 +380,32 @@ const actions = {
}
})
},
+
+ validate : (dispatch, vehicleJourneys, next) => {
+ let valid = true
+ let vj, vjas
+ for (vj of vehicleJourneys){
+ vj.errors = false
+ for(vjas of vj.vehicle_journey_at_stops){
+ vjas.errors = null
+ if (vjas.area_kind == "non_commercial" && parseInt(vjas.departure_time.hour) == 0 && parseInt(vjas.departure_time.minute) == 0){
+ vjas.errors = "Champ requis"
+ vj.errors = true
+ valid = false
+ }
+ }
+ }
+ dispatch(actions.didValidateVehicleJourneys(vehicleJourneys))
+ if(valid){
+ actions.submitVehicleJourneys(dispatch, vehicleJourneys, next)
+ }
+ },
+
+ didValidateVehicleJourneys : (vehicleJourneys) => ({
+ type: 'DID_VALIDATE_VEHICLE_JOURNEYS',
+ vehicleJourneys
+ }),
+
submitVehicleJourneys : (dispatch, state, next) => {
dispatch(actions.fetchingApi())
let urlJSON = window.location.pathname + "_collection.json"
diff --git a/app/javascript/vehicle_journeys/components/SaveVehicleJourneys.js b/app/javascript/vehicle_journeys/components/SaveVehicleJourneys.js
index 6e94b04a3..fb921df9c 100644
--- a/app/javascript/vehicle_journeys/components/SaveVehicleJourneys.js
+++ b/app/javascript/vehicle_journeys/components/SaveVehicleJourneys.js
@@ -13,7 +13,7 @@ export default class SaveVehicleJourneys extends SaveButton{
}
submitForm(){
- this.props.onSubmitVehicleJourneys(this.props.dispatch, this.props.vehicleJourneys)
+ this.props.validate(this.props.vehicleJourneys, this.props.dispatch)
}
}
diff --git a/app/javascript/vehicle_journeys/components/VehicleJourney.js b/app/javascript/vehicle_journeys/components/VehicleJourney.js
index d240757a3..2b5783dda 100644
--- a/app/javascript/vehicle_journeys/components/VehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/VehicleJourney.js
@@ -153,6 +153,9 @@ export default class VehicleJourney extends Component {
/>
+ {vj.errors &&
+ {vj.errors}
+
}
)}
diff --git a/app/javascript/vehicle_journeys/components/VehicleJourneys.js b/app/javascript/vehicle_journeys/components/VehicleJourneys.js
index b188962c2..256ca81f9 100644
--- a/app/javascript/vehicle_journeys/components/VehicleJourneys.js
+++ b/app/javascript/vehicle_journeys/components/VehicleJourneys.js
@@ -89,7 +89,7 @@ export default class VehicleJourneys extends Component {
)}
- { _.some(this.props.vehicleJourneys, 'errors') && (
+ { this.props.vehicleJourneys.errors && this.props.vehicleJourneys.errors.length && _.some(this.props.vehicleJourneys, 'errors') && (
Erreur :
{this.props.vehicleJourneys.map((vj, index) =>
diff --git a/app/javascript/vehicle_journeys/containers/SaveVehicleJourneys.js b/app/javascript/vehicle_journeys/containers/SaveVehicleJourneys.js
index f5f879ed8..3daf831f8 100644
--- a/app/javascript/vehicle_journeys/containers/SaveVehicleJourneys.js
+++ b/app/javascript/vehicle_journeys/containers/SaveVehicleJourneys.js
@@ -23,6 +23,9 @@ const mapDispatchToProps = (dispatch) => {
},
onSubmitVehicleJourneys: (next, state) => {
actions.submitVehicleJourneys(dispatch, state, next)
+ },
+ validate: (state) =>{
+ actions.validate(dispatch, state)
}
}
}
diff --git a/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js b/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
index ae45993a8..1a15ec46d 100644
--- a/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
+++ b/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
@@ -273,6 +273,8 @@ export default function vehicleJourneys(state = [], action) {
return vj
}
})
+ case 'DID_VALIDATE_VEHICLE_JOURNEYS':
+ return [...action.vehicleJourneys]
default:
return state
}
diff --git a/app/views/vehicle_journeys/show.rabl b/app/views/vehicle_journeys/show.rabl
index fc65e6cb6..dca0866b3 100644
--- a/app/views/vehicle_journeys/show.rabl
+++ b/app/views/vehicle_journeys/show.rabl
@@ -45,6 +45,7 @@ child(:vehicle_journey_at_stops_matrix, :object_root => false) do |vehicle_stops
end
node(:dummy) { vehicle_stop.dummy }
+ node(:area_kind) { vehicle_stop.stop_point.stop_area.kind }
node(:stop_area_object_id) do
vehicle_stop.stop_point.stop_area.objectid
diff --git a/spec/javascript/vehicle_journeys/actions_spec.js b/spec/javascript/vehicle_journeys/actions_spec.js
index 9515b57f2..d486c9af8 100644
--- a/spec/javascript/vehicle_journeys/actions_spec.js
+++ b/spec/javascript/vehicle_journeys/actions_spec.js
@@ -37,6 +37,47 @@ describe('when clicking on add button', () => {
expect(actions.openCreateModal()).toEqual(expectedAction)
})
})
+describe('when validating the form', () => {
+ it('should check that non-commercial stops have passing time', () => {
+ let state = [{
+ vehicle_journey_at_stops: [{
+ area_kind: "non_commercial",
+ departure_time: {
+ hour: "00",
+ minute: "00"
+ }
+ }]
+ }]
+
+ expect(actions.validate(dispatch, state)).toEqual(false)
+
+ state = [{
+ vehicle_journey_at_stops: [{
+ area_kind: "non_commercial",
+ departure_time: {
+ hour: "00",
+ minute: "01"
+ }
+ }]
+ }]
+
+ expect(actions.validate(dispatch, state)).toEqual(true)
+ })
+
+ it('should not check that commercial stops', () => {
+ let state = [{
+ vehicle_journey_at_stops: [{
+ area_kind: "commercial",
+ departure_time: {
+ hour: "00",
+ minute: "00"
+ }
+ }]
+ }]
+
+ expect(actions.validate(dispatch, state)).toEqual(true)
+ })
+})
describe('when using select2 to pick a journey pattern', () => {
it('should create an action to select a journey pattern inside modal', () => {
let selectedJP = {
--
cgit v1.2.3
From fe3e3d7d8e623d8b172aa12496e24c5d91278166 Mon Sep 17 00:00:00 2001
From: Teddy Wing
Date: Tue, 30 Jan 2018 14:48:01 +0100
Subject: VehicleJourney: Allow deletion of associated company
If the state doesn't contain a company, that means it was deleted on the
frontend. In that case, the backend code should correctly delete the
associated company from the vehicle journey.
Refs #5574
---
app/models/chouette/vehicle_journey.rb | 8 ++++++--
spec/models/chouette/vehicle_journey_spec.rb | 8 ++++++++
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb
index 8a704d8c0..5cd87a66a 100644
--- a/app/models/chouette/vehicle_journey.rb
+++ b/app/models/chouette/vehicle_journey.rb
@@ -221,9 +221,13 @@ module Chouette
def self.state_permited_attributes item
attrs = item.slice('published_journey_identifier', 'published_journey_name', 'journey_pattern_id', 'company_id').to_hash
- ['company', 'journey_pattern'].map do |association|
- attrs["#{association}_id"] = item[association]['id'] if item[association]
+
+ if item['journey_pattern']
+ attrs['journey_pattern_id'] = item['journey_pattern']['id']
end
+
+ attrs['company_id'] = item['company'] ? item['company']['id'] : nil
+
attrs["custom_field_values"] = Hash[*(item["custom_fields"] || {}).map{|k, v| [k, v["value"]]}.flatten]
attrs
end
diff --git a/spec/models/chouette/vehicle_journey_spec.rb b/spec/models/chouette/vehicle_journey_spec.rb
index 2a88ac3ce..21bbc1ba8 100644
--- a/spec/models/chouette/vehicle_journey_spec.rb
+++ b/spec/models/chouette/vehicle_journey_spec.rb
@@ -231,6 +231,14 @@ describe Chouette::VehicleJourney, :type => :model do
expect(vehicle_journey.reload.company_id).to eq state['company']['id']
end
+ it "handles vehicle journey company deletion" do
+ vehicle_journey.update(company: create(:company))
+ state.delete('company')
+ Chouette::VehicleJourney.state_update(route, collection)
+
+ expect(vehicle_journey.reload.company_id).to be_nil
+ end
+
it 'should update vj attributes from state' do
state['published_journey_name'] = 'edited_name'
state['published_journey_identifier'] = 'edited_identifier'
--
cgit v1.2.3
From f6a00ca090d5048772ad1869eb6d39068aba16f2 Mon Sep 17 00:00:00 2001
From: Teddy Wing
Date: Tue, 30 Jan 2018 14:53:34 +0100
Subject: VehicleJourney.state_permited_attributes: Fix whitespace
Add line breaks to make this method more readable.
Refs #5574
---
app/models/chouette/vehicle_journey.rb | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb
index 5cd87a66a..d94b69271 100644
--- a/app/models/chouette/vehicle_journey.rb
+++ b/app/models/chouette/vehicle_journey.rb
@@ -220,7 +220,12 @@ module Chouette
end
def self.state_permited_attributes item
- attrs = item.slice('published_journey_identifier', 'published_journey_name', 'journey_pattern_id', 'company_id').to_hash
+ attrs = item.slice(
+ 'published_journey_identifier',
+ 'published_journey_name',
+ 'journey_pattern_id',
+ 'company_id'
+ ).to_hash
if item['journey_pattern']
attrs['journey_pattern_id'] = item['journey_pattern']['id']
@@ -228,7 +233,12 @@ module Chouette
attrs['company_id'] = item['company'] ? item['company']['id'] : nil
- attrs["custom_field_values"] = Hash[*(item["custom_fields"] || {}).map{|k, v| [k, v["value"]]}.flatten]
+ attrs["custom_field_values"] = Hash[
+ *(item["custom_fields"] || {})
+ .map { |k, v| [k, v["value"]] }
+ .flatten
+ ]
+
attrs
end
--
cgit v1.2.3
From c539b09d834476a36804072a92f8c2c373aa487b Mon Sep 17 00:00:00 2001
From: cedricnjanga
Date: Tue, 30 Jan 2018 23:26:45 -0800
Subject: Refs ##5370 Set network action_link to disabled if line doesn't have
one
---
app/decorators/line_decorator.rb | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/decorators/line_decorator.rb b/app/decorators/line_decorator.rb
index 039ad90a3..0e7b6b9ae 100644
--- a/app/decorators/line_decorator.rb
+++ b/app/decorators/line_decorator.rb
@@ -20,6 +20,7 @@ class LineDecorator < AF83::Decorator
instance_decorator.action_link secondary: :show do |l|
l.content t('lines.actions.show_network')
l.href { [scope, object.network] }
+ l.disabled { object.network.nil? }
end
instance_decorator.action_link secondary: :show do |l|
--
cgit v1.2.3
From aa4fa0970e35920e7e1553112fc2d1f792abe05d Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 31 Jan 2018 10:46:02 +0100
Subject: Refs #5750; Fix validation
---
app/controllers/stop_areas_controller.rb | 2 +-
app/models/chouette/stop_area.rb | 3 ++-
app/views/stop_areas/_form.html.slim | 3 +--
db/migrate/20180126134944_add_kind_to_stop_areas.rb | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/app/controllers/stop_areas_controller.rb b/app/controllers/stop_areas_controller.rb
index 8e9df7157..8d424b8d1 100644
--- a/app/controllers/stop_areas_controller.rb
+++ b/app/controllers/stop_areas_controller.rb
@@ -97,7 +97,7 @@ class StopAreasController < ChouetteController
edit! do
stop_area.position ||= stop_area.default_position
map.editable = true
- end
+ end
end
def destroy
diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb
index 75a4a34bb..ad42d54ae 100644
--- a/app/models/chouette/stop_area.rb
+++ b/app/models/chouette/stop_area.rb
@@ -60,7 +60,8 @@ module Chouette
end
def area_type_of_right_kind
- unless Chouette::AreaType.send(self.kind).include?(self.area_type)
+
+ unless Chouette::AreaType.send(self.kind).map(&:to_s).include?(self.area_type)
errors.add(:area_type, I18n.t('stop_areas.errors.incorrect_kind_area_type'))
end
end
diff --git a/app/views/stop_areas/_form.html.slim b/app/views/stop_areas/_form.html.slim
index 6b75209b4..aa156f7bd 100644
--- a/app/views/stop_areas/_form.html.slim
+++ b/app/views/stop_areas/_form.html.slim
@@ -6,8 +6,7 @@
/= @map.to_html
= f.input :id, as: :hidden
= f.input :name, :input_html => {:title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.name")}
-
- = f.input :kind, as: :radio_buttons, :input_html => {:disabled => !@stop_area.new_record?}, :include_blank => false, item_wrapper_class: 'radio-inline', wrapper: :horizontal_form, item_class: "fooo", disabled: !@stop_area.new_record?
+ = f.input :kind, as: :radio_buttons, checked: @stop_area.kind, :input_html => {:disabled => !@stop_area.new_record?}, :include_blank => false, item_wrapper_class: 'radio-inline', wrapper: :horizontal_form, disabled: !@stop_area.new_record?
.slave data-master="[name='stop_area[kind]']" data-value="commercial"
= f.input :parent_id, as: :select, :collection => [f.object.parent_id], input_html: { data: { select2_ajax: 'true', url: autocomplete_stop_area_referential_stop_areas_path(@stop_area_referential), initvalue: {id: f.object.parent_id, text: f.object.parent.try(:full_name)}}}
diff --git a/db/migrate/20180126134944_add_kind_to_stop_areas.rb b/db/migrate/20180126134944_add_kind_to_stop_areas.rb
index 7da227cd9..08f54a6c5 100644
--- a/db/migrate/20180126134944_add_kind_to_stop_areas.rb
+++ b/db/migrate/20180126134944_add_kind_to_stop_areas.rb
@@ -1,6 +1,6 @@
class AddKindToStopAreas < ActiveRecord::Migration
def change
add_column :stop_areas, :kind, :string
- Chouette::StopArea.update_all kind: :commmercial
+ Chouette::StopArea.where.not(kind: :non_commercial).update_all kind: :commercial
end
end
--
cgit v1.2.3
From 19a25d3ebb1ce40483104c6cc19c8e1654413e65 Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 31 Jan 2018 11:14:23 +0100
Subject: Disable immature feature
---
app/javascript/packs/referential_lines/show.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/javascript/packs/referential_lines/show.js b/app/javascript/packs/referential_lines/show.js
index 99c5072ef..542188018 100644
--- a/app/javascript/packs/referential_lines/show.js
+++ b/app/javascript/packs/referential_lines/show.js
@@ -6,5 +6,5 @@ routes = JSON.parse(decodeURIComponent(routes))
var map = new RoutesMap('routes_map')
map.addRoutes(routes)
-map.addRoutesLabels()
+// map.addRoutesLabels()
map.fitZoom()
--
cgit v1.2.3
From 607cc587b2b2719feb3fafaf9a1b754cada143a9 Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 31 Jan 2018 11:17:02 +0100
Subject: Refs #5750; Remove useless validation
---
app/javascript/vehicle_journeys/actions/index.js | 17 +----------------
1 file changed, 1 insertion(+), 16 deletions(-)
diff --git a/app/javascript/vehicle_journeys/actions/index.js b/app/javascript/vehicle_journeys/actions/index.js
index b01158212..4a4ec371d 100644
--- a/app/javascript/vehicle_journeys/actions/index.js
+++ b/app/javascript/vehicle_journeys/actions/index.js
@@ -382,23 +382,8 @@ const actions = {
},
validate : (dispatch, vehicleJourneys, next) => {
- let valid = true
- let vj, vjas
- for (vj of vehicleJourneys){
- vj.errors = false
- for(vjas of vj.vehicle_journey_at_stops){
- vjas.errors = null
- if (vjas.area_kind == "non_commercial" && parseInt(vjas.departure_time.hour) == 0 && parseInt(vjas.departure_time.minute) == 0){
- vjas.errors = "Champ requis"
- vj.errors = true
- valid = false
- }
- }
- }
dispatch(actions.didValidateVehicleJourneys(vehicleJourneys))
- if(valid){
- actions.submitVehicleJourneys(dispatch, vehicleJourneys, next)
- }
+ actions.submitVehicleJourneys(dispatch, vehicleJourneys, next)
},
didValidateVehicleJourneys : (vehicleJourneys) => ({
--
cgit v1.2.3
From 2a6b96b7b820afdf02c58cc277b31a0a6236a6ea Mon Sep 17 00:00:00 2001
From: Teddy Wing
Date: Wed, 31 Jan 2018 13:23:24 +0100
Subject: VehicleJourneys#index: Allow company deletion in 'add' modal
While the 'x' button in the Select2 was available in the 'edit' modal
for a vehicle journey, it was not in the 'add' modal. Thus, once you
added an associated company, you couldn't remove it in the modal. You'd
either have to cancel and create your vehicle journey again, or create
it an delete the company in the 'edit' modal later.
This enables the 'x' button in the 'add' modal (it previously was only
enabled when `editMode` was active) and sets the proper action/reducer
to remove the company.
The `allowClear` attribute was changed to only work in the 'edit' modal
in 0079238842263768b88b0fa0fd977824b49eabd5. That commit appears to be
changing things so that certain functions work when not in 'edit' mode.
The case we're concerned about is that the 'edit' modal can be opened
when in 'view' mode (not 'edit' mode) in order to get more detailed
information about a vehicle journey. This means the company Select2 is
available in 'view' mode, and the 'x' button should not be visible in
that case. But, when I tested this, even with `allowClear: true`, the
'x' button wasn't visible. This, I can only assume, is because the
Select2 is in a 'disabled' state, so it's smart enough to know not to
show the 'x' button. Which works great for us, because this allows us to
not show the 'x' button here and still show it in the 'add' and 'edit'
modals.
Refs #5574
---
app/javascript/vehicle_journeys/components/tools/CreateModal.js | 1 +
.../vehicle_journeys/components/tools/select2s/CompanySelect2.js | 2 +-
app/javascript/vehicle_journeys/containers/tools/AddVehicleJourney.js | 3 +++
3 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/app/javascript/vehicle_journeys/components/tools/CreateModal.js b/app/javascript/vehicle_journeys/components/tools/CreateModal.js
index 90328458b..8536f66e6 100644
--- a/app/javascript/vehicle_journeys/components/tools/CreateModal.js
+++ b/app/javascript/vehicle_journeys/components/tools/CreateModal.js
@@ -66,6 +66,7 @@ export default class CreateModal extends Component {
this.props.onSelect2Company(e)}
+ onUnselect2Company = {() => this.props.onUnselect2Company()}
/>
diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js b/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js
index 28a092945..5c7f75d99 100644
--- a/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js
+++ b/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js
@@ -26,7 +26,7 @@ export default class BSelect4 extends Component {
multiple={false}
ref='company_id'
options={{
- allowClear: this.props.editMode,
+ allowClear: true,
theme: 'bootstrap',
width: '100%',
placeholder: 'Filtrer par transporteur...',
diff --git a/app/javascript/vehicle_journeys/containers/tools/AddVehicleJourney.js b/app/javascript/vehicle_journeys/containers/tools/AddVehicleJourney.js
index 0db7628be..d982f5a5f 100644
--- a/app/javascript/vehicle_journeys/containers/tools/AddVehicleJourney.js
+++ b/app/javascript/vehicle_journeys/containers/tools/AddVehicleJourney.js
@@ -30,6 +30,9 @@ const mapDispatchToProps = (dispatch) => {
},
onSelect2Company: (e) => {
dispatch(actions.select2Company(e.params.data))
+ },
+ onUnselect2Company: () => {
+ dispatch(actions.unselect2Company())
}
}
}
--
cgit v1.2.3
From 0a2cf4363a0bd5c5ca3b971d8f609356016bc7a1 Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 31 Jan 2018 13:37:47 +0100
Subject: Try and fix jenkins builds
---
package.json | 2 +-
yarn.lock | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/package.json b/package.json
index 802a2eef7..e80f5231e 100644
--- a/package.json
+++ b/package.json
@@ -8,6 +8,7 @@
"babel-preset-react": "6.24.1",
"babelify": "8.0.0",
"bootstrap": "3",
+ "clean-webpack-plugin": "^0.1.18",
"coffee-loader": "^0.9.0",
"coffeescript": "1.12.7",
"jquery": "3.2.1",
@@ -29,7 +30,6 @@
"node": "~6.12.0"
},
"devDependencies": {
- "clean-webpack-plugin": "0.1.17",
"es6-object-assign": "1.1.0",
"grunt": "^1.0.1",
"grunt-contrib-watch": "^1.0.0",
diff --git a/yarn.lock b/yarn.lock
index d17ae1d52..b32d906dd 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1347,9 +1347,9 @@ clap@^1.0.9:
dependencies:
chalk "^1.1.3"
-clean-webpack-plugin@0.1.17:
- version "0.1.17"
- resolved "https://registry.yarnpkg.com/clean-webpack-plugin/-/clean-webpack-plugin-0.1.17.tgz#71c57242e6d47204d46f809413176e7bed28ec49"
+clean-webpack-plugin@^0.1.18:
+ version "0.1.18"
+ resolved "https://registry.yarnpkg.com/clean-webpack-plugin/-/clean-webpack-plugin-0.1.18.tgz#2e2173897c76646031bff047c14b9c22c80d8c4a"
dependencies:
rimraf "^2.6.1"
--
cgit v1.2.3
From bde34143629e19273493fba8ba9e50bcd5f0c547 Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 31 Jan 2018 14:02:54 +0100
Subject: Fix StopArea validation breaking the specs
---
app/models/chouette/stop_area.rb | 2 +-
spec/factories/chouette_stop_areas.rb | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb
index ad42d54ae..d7d5c2eb2 100644
--- a/app/models/chouette/stop_area.rb
+++ b/app/models/chouette/stop_area.rb
@@ -60,7 +60,7 @@ module Chouette
end
def area_type_of_right_kind
-
+ return unless self.kind
unless Chouette::AreaType.send(self.kind).map(&:to_s).include?(self.area_type)
errors.add(:area_type, I18n.t('stop_areas.errors.incorrect_kind_area_type'))
end
diff --git a/spec/factories/chouette_stop_areas.rb b/spec/factories/chouette_stop_areas.rb
index 94517f856..9b4764781 100644
--- a/spec/factories/chouette_stop_areas.rb
+++ b/spec/factories/chouette_stop_areas.rb
@@ -3,9 +3,10 @@ FactoryGirl.define do
sequence(:objectid) { |n| "FR:#{n}:ZDE:#{n}:STIF" }
sequence(:name) { |n| "stop_area_#{n}" }
sequence(:registration_number) { |n| "test-#{n}" }
- area_type { Chouette::AreaType.all.sample }
+ area_type { Chouette::AreaType.commercial.sample }
latitude {10.0 * rand}
longitude {10.0 * rand}
+ kind "commercial"
association :stop_area_referential
--
cgit v1.2.3
From 5e1b7a06a9958580fc18a0a4e33ff66ea6adcdf9 Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 29 Jan 2018 11:54:47 +0100
Subject: Refs #5754; Add a filter on purchase_windows on ReferentialVJs#index
---
app/controllers/concerns/ransack_date_filter.rb | 5 +--
.../referential_vehicle_journeys_controller.rb | 5 +++
app/models/chouette/purchase_window.rb | 1 +
app/models/chouette/vehicle_journey.rb | 7 ++++
.../_filters.html.slim | 8 ++++-
config/locales/vehicle_journeys.en.yml | 3 ++
config/locales/vehicle_journeys.fr.yml | 3 ++
spec/models/chouette/vehicle_journey_spec.rb | 41 ++++++++++++++++++++++
8 files changed, 70 insertions(+), 3 deletions(-)
diff --git a/app/controllers/concerns/ransack_date_filter.rb b/app/controllers/concerns/ransack_date_filter.rb
index 0fbde91d3..99889294c 100644
--- a/app/controllers/concerns/ransack_date_filter.rb
+++ b/app/controllers/concerns/ransack_date_filter.rb
@@ -29,13 +29,14 @@ module RansackDateFilter
def ransack_period_range **options
return options[:scope] unless !!@begin_range && !!@end_range
+ scope = options[:scope]
if @begin_range > @end_range
flash.now[:error] = options[:error_message]
else
- scope = options[:scope].send options[:query], @begin_range..@end_range
+ scope = scope.send options[:query], @begin_range..@end_range
end
scope
end
end
-end
\ No newline at end of file
+end
diff --git a/app/controllers/referential_vehicle_journeys_controller.rb b/app/controllers/referential_vehicle_journeys_controller.rb
index c3fcde0b1..385405b84 100644
--- a/app/controllers/referential_vehicle_journeys_controller.rb
+++ b/app/controllers/referential_vehicle_journeys_controller.rb
@@ -3,6 +3,10 @@
#
class ReferentialVehicleJourneysController < ChouetteController
include ReferentialSupport
+ include RansackDateFilter
+
+ before_action only: [:index] { set_date_time_params("purchase_window", Date) }
+
defaults :resource_class => Chouette::VehicleJourney, collection_name: :vehicle_journeys
requires_feature :referential_vehicle_journeys
@@ -12,6 +16,7 @@ class ReferentialVehicleJourneysController < ChouetteController
def collection
@q ||= end_of_association_chain
@q = @q.with_stop_area_ids(params[:q][:stop_area_ids]) if params[:q] && params[:q][:stop_area_ids]
+ @q = ransack_period_range(scope: @q, error_message: t('vehicle_journeys.errors.purchase_window'), query: :in_purchase_window)
@q = @q.ransack(params[:q])
@vehicle_journeys ||= @q.result.order(:published_journey_name).includes(:vehicle_journey_at_stops).paginate page: params[:page], per_page: params[:per_page] || 10
@all_companies = Chouette::Company.where("id IN (#{@referential.vehicle_journeys.select(:company_id).to_sql})").distinct
diff --git a/app/models/chouette/purchase_window.rb b/app/models/chouette/purchase_window.rb
index 22bcc1de1..334493015 100644
--- a/app/models/chouette/purchase_window.rb
+++ b/app/models/chouette/purchase_window.rb
@@ -18,6 +18,7 @@ module Chouette
validates_presence_of :name, :referential
scope :contains_date, ->(date) { where('date ? <@ any (date_ranges)', date) }
+ scope :overlap_dates, ->(date_range) { where('daterange(?, ?) && any (date_ranges)', date_range.first, date_range.last + 1.day) }
def self.ransackable_scopes(auth_object = nil)
[:contains_date]
diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb
index d94b69271..a252d4519 100644
--- a/app/models/chouette/vehicle_journey.rb
+++ b/app/models/chouette/vehicle_journey.rb
@@ -52,8 +52,15 @@ module Chouette
end
}
+ scope :in_purchase_window, ->(range){
+ purchase_windows = Chouette::PurchaseWindow.overlap_dates(range)
+ sql = purchase_windows.joins(:vehicle_journeys).select('vehicle_journeys.id').uniq.to_sql
+ where("id IN (#{sql})")
+ }
+
# We need this for the ransack object in the filters
ransacker :stop_area_ids
+ ransacker :purchase_window_date_gt
# TODO: Remove this validator
# We've eliminated this validation because it prevented vehicle journeys
diff --git a/app/views/referential_vehicle_journeys/_filters.html.slim b/app/views/referential_vehicle_journeys/_filters.html.slim
index 1301d3dab..af8b2de3a 100644
--- a/app/views/referential_vehicle_journeys/_filters.html.slim
+++ b/app/views/referential_vehicle_journeys/_filters.html.slim
@@ -21,10 +21,16 @@
= f.input :published_journey_name_gteq, label: false, wrapper_html: { class: 'w45'}
.form-group.w10.to= I18n.t('vehicle_journeys.form.to')
= f.input :published_journey_name_lteq, label: false, wrapper_html: { class: 'w45'}
-
.form-group.togglable
= f.label Chouette::StopArea.model_name.human.pluralize, required: false, class: 'control-label'
= f.input :stop_area_ids, collection: @all_stop_areas.select(:id, :name).order(name: :asc), checked: params[:q] && params[:q][:stop_area_ids], as: :check_boxes, label: false, label_method: lambda{|l| ("" + l.name + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}, multiple: true
+ .form-group.togglable
+ = f.label Chouette::VehicleJourney.human_attribute_name(:purchase_window), class: 'control-label'
+ .filter_menu
+ = f.simple_fields_for :purchase_window do |p|
+ = p.input :start_date, as: :date, label: t('simple_form.from'), wrapper_html: { class: 'date smart_date filter_menu-item' }, default: @begin_range, include_blank: @begin_range ? false : true
+ = p.input :end_date, as: :date, label: t('simple_form.to'), wrapper_html: { class: 'date smart_date filter_menu-item' }, default: @end_range, include_blank: @end_range ? false : true
+
.actions
= link_to 'Effacer', referential_vehicle_journeys_path(@referential), class: 'btn btn-link'
diff --git a/config/locales/vehicle_journeys.en.yml b/config/locales/vehicle_journeys.en.yml
index 1c1f6c6bd..08a9334cc 100644
--- a/config/locales/vehicle_journeys.en.yml
+++ b/config/locales/vehicle_journeys.en.yml
@@ -67,6 +67,8 @@ en:
time_range_filter: "Filter"
sidebar:
timeless: "Timeless vehicle journeys"
+ errors:
+ purchase_window: Invalid purchase window
activerecord:
models:
vehicle_journey:
@@ -108,6 +110,7 @@ en:
footnote_ids: "Footnotes"
departure_time: "Departure"
arrival_time: "Arrival"
+ purchase_window: "Purchase availability"
errors:
models:
vehicle_journey:
diff --git a/config/locales/vehicle_journeys.fr.yml b/config/locales/vehicle_journeys.fr.yml
index 5749f8f10..8d85d877a 100644
--- a/config/locales/vehicle_journeys.fr.yml
+++ b/config/locales/vehicle_journeys.fr.yml
@@ -67,6 +67,8 @@ fr:
time_range_filter: "Filtrer"
sidebar:
timeless: "Courses sans horaire"
+ errors:
+ purchase_window: Calendrier commercial invalide
activerecord:
models:
vehicle_journey:
@@ -108,6 +110,7 @@ fr:
footnote_ids: "Notes de bas de page"
departure_time: "Départ"
arrival_time: "Arrivée"
+ purchase_window: "Disponibilité commerciale"
errors:
models:
vehicle_journey:
diff --git a/spec/models/chouette/vehicle_journey_spec.rb b/spec/models/chouette/vehicle_journey_spec.rb
index 21bbc1ba8..06f392d65 100644
--- a/spec/models/chouette/vehicle_journey_spec.rb
+++ b/spec/models/chouette/vehicle_journey_spec.rb
@@ -24,6 +24,47 @@ describe Chouette::VehicleJourney, :type => :model do
it_behaves_like 'checksum support', :vehicle_journey
end
+ describe '#in_purchase_window' do
+ let(:start_date){2.month.ago.to_date}
+ let(:end_date){1.month.ago.to_date}
+
+ subject{Chouette::VehicleJourney.in_purchase_window start_date..end_date}
+
+ let!(:without_purchase_window){ create :vehicle_journey }
+ let!(:without_matching_purchase_window){
+ pw = create :purchase_window, referential: Referential.first, date_ranges: [(end_date+1.day..end_date+2.days)]
+ pw2 = create :purchase_window, referential: Referential.first, date_ranges: [(end_date+10.day..end_date+20.days)]
+ create :vehicle_journey, purchase_windows: [pw, pw2]
+ }
+ let!(:included_purchase_window){
+ pw = create :purchase_window, referential: Referential.first, date_ranges: [(start_date..end_date)]
+ pw2 = create :purchase_window, referential: Referential.first
+ create :vehicle_journey, purchase_windows: [pw, pw2]
+ }
+ let!(:overlapping_purchase_window){
+ pw = create :purchase_window, referential: Referential.first, date_ranges: [(end_date..end_date+1.day)]
+ pw2 = create :purchase_window, referential: Referential.first
+ create :vehicle_journey, purchase_windows: [pw, pw2]
+ }
+
+
+ it "should not include VJ with no purchase window" do
+ expect(subject).to_not include without_purchase_window
+ end
+
+ it "should not include VJ with no matching purchase window" do
+ expect(subject).to_not include without_matching_purchase_window
+ end
+
+ it "should include VJ with included purchase window" do
+ expect(subject).to include included_purchase_window
+ end
+
+ it "should include VJ with overlapping_purchase_window purchase window" do
+ expect(subject).to include overlapping_purchase_window
+ end
+ end
+
describe "vjas_departure_time_must_be_before_next_stop_arrival_time",
skip: "Validation currently commented out because it interferes with day offsets" do
--
cgit v1.2.3
From 9f583abe27b77e4a5af5e5428329a91c929f3254 Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 29 Jan 2018 13:17:14 +0100
Subject: Refs #5754; Add a filter on calendars for ReferentialVJs#index
---
app/controllers/concerns/ransack_date_filter.rb | 25 ++++---
.../referential_vehicle_journeys_controller.rb | 6 +-
app/models/chouette/time_table.rb | 1 -
app/models/chouette/vehicle_journey.rb | 14 ++++
.../_filters.html.slim | 10 ++-
config/locales/vehicle_journeys.en.yml | 1 +
config/locales/vehicle_journeys.fr.yml | 1 +
spec/factories/chouette_time_table.rb | 17 +++--
spec/models/chouette/vehicle_journey_spec.rb | 83 +++++++++++++++++++++-
9 files changed, 137 insertions(+), 21 deletions(-)
diff --git a/app/controllers/concerns/ransack_date_filter.rb b/app/controllers/concerns/ransack_date_filter.rb
index 99889294c..055c01130 100644
--- a/app/controllers/concerns/ransack_date_filter.rb
+++ b/app/controllers/concerns/ransack_date_filter.rb
@@ -3,7 +3,15 @@ module RansackDateFilter
included do
- def set_date_time_params(param_name, klass)
+ def begin_range_var prefix
+ "@#{[prefix, "begin_range"].compact.join('_')}"
+ end
+
+ def end_range_var prefix
+ "@#{[prefix, "end_range"].compact.join('_')}"
+ end
+
+ def set_date_time_params(param_name, klass, prefix: nil)
start_date = []
end_date = []
@@ -16,24 +24,25 @@ module RansackDateFilter
params[:q].delete([param_name])
if klass == DateTime
- @begin_range = klass.new(*start_date,0,0,0) rescue nil
- @end_range = klass.new(*end_date,23,59,59) rescue nil
+ instance_variable_set begin_range_var(prefix), klass.new(*start_date,0,0,0) rescue nil
+ instance_variable_set end_range_var(prefix), klass.new(*end_date,23,59,59) rescue nil
else
- @begin_range = klass.new(*start_date) rescue nil
- @end_range = klass.new(*end_date) rescue nil
+ instance_variable_set begin_range_var(prefix), klass.new(*start_date) rescue nil
+ instance_variable_set end_range_var(prefix), klass.new(*end_date) rescue nil
end
end
end
# Fake ransack filter
def ransack_period_range **options
- return options[:scope] unless !!@begin_range && !!@end_range
+ prefix = options[:prefix]
+ return options[:scope] unless !!instance_variable_get(begin_range_var(prefix)) && !!instance_variable_get(end_range_var(prefix))
scope = options[:scope]
- if @begin_range > @end_range
+ if instance_variable_get(begin_range_var(prefix)) > instance_variable_get(end_range_var(prefix))
flash.now[:error] = options[:error_message]
else
- scope = scope.send options[:query], @begin_range..@end_range
+ scope = scope.send options[:query], instance_variable_get(begin_range_var(prefix))..instance_variable_get(end_range_var(prefix))
end
scope
end
diff --git a/app/controllers/referential_vehicle_journeys_controller.rb b/app/controllers/referential_vehicle_journeys_controller.rb
index 385405b84..a199157dd 100644
--- a/app/controllers/referential_vehicle_journeys_controller.rb
+++ b/app/controllers/referential_vehicle_journeys_controller.rb
@@ -5,7 +5,8 @@ class ReferentialVehicleJourneysController < ChouetteController
include ReferentialSupport
include RansackDateFilter
- before_action only: [:index] { set_date_time_params("purchase_window", Date) }
+ before_action only: [:index] { set_date_time_params("purchase_window", Date, prefix: :purchase_window) }
+ before_action only: [:index] { set_date_time_params("time_table", Date, prefix: :time_table) }
defaults :resource_class => Chouette::VehicleJourney, collection_name: :vehicle_journeys
@@ -16,7 +17,8 @@ class ReferentialVehicleJourneysController < ChouetteController
def collection
@q ||= end_of_association_chain
@q = @q.with_stop_area_ids(params[:q][:stop_area_ids]) if params[:q] && params[:q][:stop_area_ids]
- @q = ransack_period_range(scope: @q, error_message: t('vehicle_journeys.errors.purchase_window'), query: :in_purchase_window)
+ @q = ransack_period_range(scope: @q, error_message: t('vehicle_journeys.errors.purchase_window'), query: :in_purchase_window, prefix: :purchase_window)
+ @q = ransack_period_range(scope: @q, error_message: t('vehicle_journeys.errors.time_table'), query: :with_matching_timetable, prefix: :time_table)
@q = @q.ransack(params[:q])
@vehicle_journeys ||= @q.result.order(:published_journey_name).includes(:vehicle_journey_at_stops).paginate page: params[:page], per_page: params[:per_page] || 10
@all_companies = Chouette::Company.where("id IN (#{@referential.vehicle_journeys.select(:company_id).to_sql})").distinct
diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb
index db97dd2fa..07bf35444 100644
--- a/app/models/chouette/time_table.rb
+++ b/app/models/chouette/time_table.rb
@@ -311,7 +311,6 @@ module Chouette
bounding_max = periods_max_date if periods_max_date &&
(bounding_max.nil? || (bounding_max < periods_max_date))
end
-
[bounding_min, bounding_max].compact
end
diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb
index a252d4519..1756a7098 100644
--- a/app/models/chouette/vehicle_journey.rb
+++ b/app/models/chouette/vehicle_journey.rb
@@ -62,6 +62,20 @@ module Chouette
ransacker :stop_area_ids
ransacker :purchase_window_date_gt
+ # returns VehicleJourneys with at least 1 day in their time_tables
+ # included in the given range
+ def self.with_matching_timetable date_range
+ out = []
+ time_tables = Chouette::TimeTable.where(id: self.joins("INNER JOIN time_tables_vehicle_journeys ON vehicle_journeys.id = time_tables_vehicle_journeys.vehicle_journey_id").pluck('time_tables_vehicle_journeys.time_table_id')).overlapping(date_range)
+ time_tables = time_tables.select do |time_table|
+ range = date_range
+ range = date_range & (time_table.start_date-1.day..time_table.end_date+1.day) || [] if time_table.start_date.present? && time_table.end_date.present?
+ range.any?{|d| time_table.include_day?(d) }
+ end
+ out += time_tables.map{|t| t.vehicle_journey_ids}.flatten
+ where(id: out)
+ end
+
# TODO: Remove this validator
# We've eliminated this validation because it prevented vehicle journeys
# from being saved with at-stops having a day offset greater than 0,
diff --git a/app/views/referential_vehicle_journeys/_filters.html.slim b/app/views/referential_vehicle_journeys/_filters.html.slim
index af8b2de3a..bfb5b77dd 100644
--- a/app/views/referential_vehicle_journeys/_filters.html.slim
+++ b/app/views/referential_vehicle_journeys/_filters.html.slim
@@ -28,8 +28,14 @@
= f.label Chouette::VehicleJourney.human_attribute_name(:purchase_window), class: 'control-label'
.filter_menu
= f.simple_fields_for :purchase_window do |p|
- = p.input :start_date, as: :date, label: t('simple_form.from'), wrapper_html: { class: 'date smart_date filter_menu-item' }, default: @begin_range, include_blank: @begin_range ? false : true
- = p.input :end_date, as: :date, label: t('simple_form.to'), wrapper_html: { class: 'date smart_date filter_menu-item' }, default: @end_range, include_blank: @end_range ? false : true
+ = p.input :start_date, as: :date, label: t('simple_form.from'), wrapper_html: { class: 'date smart_date filter_menu-item' }, default: @purchase_window_begin_range, include_blank: @purchase_window_begin_range ? false : true
+ = p.input :end_date, as: :date, label: t('simple_form.to'), wrapper_html: { class: 'date smart_date filter_menu-item' }, default: @purchase_window_end_range, include_blank: @purchase_window_end_range ? false : true
+ .form-group.togglable
+ = f.label Chouette::TimeTable.model_name.human, class: 'control-label'
+ .filter_menu
+ = f.simple_fields_for :time_table do |p|
+ = p.input :start_date, as: :date, label: t('simple_form.from'), wrapper_html: { class: 'date smart_date filter_menu-item' }, default: @time_table_begin_range, include_blank: @time_table_begin_range ? false : true
+ = p.input :end_date, as: :date, label: t('simple_form.to'), wrapper_html: { class: 'date smart_date filter_menu-item' }, default: @time_table_end_range, include_blank: @time_table_end_range ? false : true
.actions
diff --git a/config/locales/vehicle_journeys.en.yml b/config/locales/vehicle_journeys.en.yml
index 08a9334cc..abb1da530 100644
--- a/config/locales/vehicle_journeys.en.yml
+++ b/config/locales/vehicle_journeys.en.yml
@@ -69,6 +69,7 @@ en:
timeless: "Timeless vehicle journeys"
errors:
purchase_window: Invalid purchase window
+ time_table: Invalid dates
activerecord:
models:
vehicle_journey:
diff --git a/config/locales/vehicle_journeys.fr.yml b/config/locales/vehicle_journeys.fr.yml
index 8d85d877a..ca8475812 100644
--- a/config/locales/vehicle_journeys.fr.yml
+++ b/config/locales/vehicle_journeys.fr.yml
@@ -69,6 +69,7 @@ fr:
timeless: "Courses sans horaire"
errors:
purchase_window: Calendrier commercial invalide
+ time_table: Dates d'application invalides
activerecord:
models:
vehicle_journey:
diff --git a/spec/factories/chouette_time_table.rb b/spec/factories/chouette_time_table.rb
index 81a08ca2a..af48e1b42 100644
--- a/spec/factories/chouette_time_table.rb
+++ b/spec/factories/chouette_time_table.rb
@@ -11,18 +11,21 @@ FactoryGirl.define do
end
after(:create) do |time_table, evaluator|
-
- 0.upto(4) do |i|
- time_table.dates << create(:time_table_date, :time_table => time_table, :date => i.days.since.to_date, :in_out => true)
+ unless time_table.dates.any?
+ evaluator.dates_count.times do |i|
+ time_table.dates << create(:time_table_date, :time_table => time_table, :date => i.days.since.to_date, :in_out => true)
+ end
end
start_date = Date.today
end_date = start_date + 10
- 0.upto(4) do |i|
- time_table.periods << create(:time_table_period, :time_table => time_table, :period_start => start_date, :period_end => end_date)
- start_date = start_date + 20
- end_date = start_date + 10
+ unless time_table.periods.any?
+ evaluator.periods_count.times do |i|
+ time_table.periods << create(:time_table_period, :time_table => time_table, :period_start => start_date, :period_end => end_date)
+ start_date = start_date + 20
+ end_date = start_date + 10
+ end
end
time_table.save_shortcuts
time_table.update_checksum!
diff --git a/spec/models/chouette/vehicle_journey_spec.rb b/spec/models/chouette/vehicle_journey_spec.rb
index 06f392d65..70661bcc5 100644
--- a/spec/models/chouette/vehicle_journey_spec.rb
+++ b/spec/models/chouette/vehicle_journey_spec.rb
@@ -60,11 +60,92 @@ describe Chouette::VehicleJourney, :type => :model do
expect(subject).to include included_purchase_window
end
- it "should include VJ with overlapping_purchase_window purchase window" do
+ it "should include VJ with overlapping purchase_window purchase window" do
expect(subject).to include overlapping_purchase_window
end
end
+ describe '#in_time_table' do
+ let(:start_date){2.month.ago.to_date}
+ let(:end_date){1.month.ago.to_date}
+
+ subject{Chouette::VehicleJourney.with_matching_timetable start_date..end_date}
+
+ context "without time table" do
+ let!(:vehicle_journey){ create :vehicle_journey }
+ it "should not include VJ " do
+ expect(subject).to_not include vehicle_journey
+ end
+ end
+
+ context "without a time table matching on a regular day" do
+ let(:timetable){
+ period = create :time_table_period, period_start: start_date-2.day, period_end: start_date
+ create :time_table, periods: [period], dates_count: 0
+ }
+ let!(:vehicle_journey){ create :vehicle_journey, time_tables: [timetable] }
+ it "should include VJ " do
+ expect(subject).to include vehicle_journey
+ end
+ end
+
+ context "without a time table matching on a regular day" do
+ let(:timetable){
+ period = create :time_table_period, period_start: end_date, period_end: end_date+1.day
+ create :time_table, periods: [period], dates_count: 0
+ }
+ let!(:vehicle_journey){ create :vehicle_journey, time_tables: [timetable] }
+ it "should include VJ " do
+ expect(subject).to include vehicle_journey
+ end
+ end
+
+ context "with a time table with a matching period but not the right day" do
+ let(:start_date){end_date - 1.day}
+ let(:end_date){Time.now.end_of_week.to_date}
+
+ let(:timetable){
+ period = create :time_table_period, period_start: start_date-1.month, period_end: end_date+1.month
+ create :time_table, periods: [period], int_day_types: 4 + 8, dates_count: 0
+ }
+ let!(:vehicle_journey){ create :vehicle_journey, time_tables: [timetable] }
+ it "should not include VJ " do
+ expect(subject).to_not include vehicle_journey
+ end
+ end
+
+ context "with a time table with a matching period but day opted-out" do
+ let(:start_date){end_date - 1.day}
+ let(:end_date){Time.now.end_of_week.to_date}
+
+ let(:timetable){
+ period = create :time_table_period, period_start: start_date-1.month, period_end: start_date-1.day
+ date = create(:time_table_date, :date => start_date, in_out: false)
+ create :time_table, periods: [period], dates: [date]
+ }
+ let!(:vehicle_journey){ create :vehicle_journey, time_tables: [timetable] }
+ it "should not include VJ " do
+ expect(subject).to_not include vehicle_journey
+ end
+ end
+
+ context "with a time table with no matching period but not the right extra day" do
+ let(:start_date){end_date - 1.day}
+ let(:end_date){Time.now.end_of_week.to_date}
+
+ let(:timetable){
+ period = create :time_table_period, period_start: start_date-1.month, period_end: start_date-1.day
+ date = create(:time_table_date, :date => start_date, in_out: true)
+ create :time_table, periods: [period], dates: [date]
+ }
+ let!(:vehicle_journey){ create :vehicle_journey, time_tables: [timetable] }
+ it "should include VJ " do
+ expect(subject).to include vehicle_journey
+ end
+ end
+
+ end
+
describe "vjas_departure_time_must_be_before_next_stop_arrival_time",
skip: "Validation currently commented out because it interferes with day offsets" do
--
cgit v1.2.3
From 32bb2b43d463a071164a8e87a3e995f6ddceb17e Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 31 Jan 2018 14:34:48 +0100
Subject: Fix Reflex import
---
lib/stif/reflex_synchronization.rb | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/stif/reflex_synchronization.rb b/lib/stif/reflex_synchronization.rb
index 39a92bd1f..7570e4c49 100644
--- a/lib/stif/reflex_synchronization.rb
+++ b/lib/stif/reflex_synchronization.rb
@@ -151,6 +151,7 @@ module Stif
def create_or_update_stop_area entry
stop = Chouette::StopArea.find_or_create_by(objectid: entry['id'], stop_area_referential: self.defaut_referential )
+ stop.kind = :commercial
stop.deleted_at = nil
{
:comment => 'Description',
--
cgit v1.2.3
From a477a97347792540426aad79b1709dbb12aeb3c2 Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 31 Jan 2018 15:10:40 +0100
Subject: Fix specs
---
app/javascript/vehicle_journeys/actions/index.js | 1 +
spec/javascript/vehicle_journeys/actions_spec.js | 3 ++-
spec/models/chouette/vehicle_journey_spec.rb | 14 ++++++++------
3 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/app/javascript/vehicle_journeys/actions/index.js b/app/javascript/vehicle_journeys/actions/index.js
index 4a4ec371d..8970c6025 100644
--- a/app/javascript/vehicle_journeys/actions/index.js
+++ b/app/javascript/vehicle_journeys/actions/index.js
@@ -384,6 +384,7 @@ const actions = {
validate : (dispatch, vehicleJourneys, next) => {
dispatch(actions.didValidateVehicleJourneys(vehicleJourneys))
actions.submitVehicleJourneys(dispatch, vehicleJourneys, next)
+ return true
},
didValidateVehicleJourneys : (vehicleJourneys) => ({
diff --git a/spec/javascript/vehicle_journeys/actions_spec.js b/spec/javascript/vehicle_journeys/actions_spec.js
index d486c9af8..9710d833c 100644
--- a/spec/javascript/vehicle_journeys/actions_spec.js
+++ b/spec/javascript/vehicle_journeys/actions_spec.js
@@ -1,6 +1,7 @@
import actions from '../../../app/javascript/vehicle_journeys/actions/index'
const dispatch = function(){}
+window.fetch = function(){return Promise.resolve()}
const currentPage = 1
describe('when cannot fetch api', () => {
@@ -49,7 +50,7 @@ describe('when validating the form', () => {
}]
}]
- expect(actions.validate(dispatch, state)).toEqual(false)
+ expect(actions.validate(dispatch, state)).toEqual(true)
state = [{
vehicle_journey_at_stops: [{
diff --git a/spec/models/chouette/vehicle_journey_spec.rb b/spec/models/chouette/vehicle_journey_spec.rb
index 70661bcc5..e9ffddd2a 100644
--- a/spec/models/chouette/vehicle_journey_spec.rb
+++ b/spec/models/chouette/vehicle_journey_spec.rb
@@ -119,9 +119,10 @@ describe Chouette::VehicleJourney, :type => :model do
let(:end_date){Time.now.end_of_week.to_date}
let(:timetable){
- period = create :time_table_period, period_start: start_date-1.month, period_end: start_date-1.day
- date = create(:time_table_date, :date => start_date, in_out: false)
- create :time_table, periods: [period], dates: [date]
+ tt = create :time_table, dates_count: 0, periods_count: 0
+ create :time_table_period, period_start: start_date-1.month, period_end: start_date-1.day, time_table: tt
+ create(:time_table_date, :date => start_date, in_out: false, time_table: tt)
+ tt
}
let!(:vehicle_journey){ create :vehicle_journey, time_tables: [timetable] }
it "should not include VJ " do
@@ -134,9 +135,10 @@ describe Chouette::VehicleJourney, :type => :model do
let(:end_date){Time.now.end_of_week.to_date}
let(:timetable){
- period = create :time_table_period, period_start: start_date-1.month, period_end: start_date-1.day
- date = create(:time_table_date, :date => start_date, in_out: true)
- create :time_table, periods: [period], dates: [date]
+ tt = create :time_table, dates_count: 0, periods_count: 0
+ create :time_table_period, period_start: start_date-1.month, period_end: start_date-1.day, time_table: tt
+ create(:time_table_date, :date => start_date, in_out: true, time_table: tt)
+ tt
}
let!(:vehicle_journey){ create :vehicle_journey, time_tables: [timetable] }
it "should include VJ " do
--
cgit v1.2.3
From 57d1749d53f0ad8fc26f67b42b2b207bf0ab06ad Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 24 Jan 2018 07:28:57 +0100
Subject: Refs #5682; Add application_days field to calendars
---
app/models/calendar.rb | 3 +-
app/models/chouette/time_table.rb | 95 +-----------------
app/models/concerns/application_days_support.rb | 108 +++++++++++++++++++++
...0180124061955_add_int_day_types_to_calendars.rb | 5 +
db/schema.rb | 5 +-
spec/models/calendar_spec.rb | 3 +-
spec/models/chouette/time_table_spec.rb | 5 +-
7 files changed, 121 insertions(+), 103 deletions(-)
create mode 100644 app/models/concerns/application_days_support.rb
create mode 100644 db/migrate/20180124061955_add_int_day_types_to_calendars.rb
diff --git a/app/models/calendar.rb b/app/models/calendar.rb
index d93532908..40dfa1210 100644
--- a/app/models/calendar.rb
+++ b/app/models/calendar.rb
@@ -5,6 +5,7 @@ require_relative 'calendar/period'
class Calendar < ActiveRecord::Base
include DateSupport
include PeriodSupport
+ include ApplicationDaysSupport
has_paper_trail class_name: 'PublicVersion'
belongs_to :organisation
@@ -29,7 +30,7 @@ class Calendar < ActiveRecord::Base
self.periods.each do |p|
tt.periods << Chouette::TimeTablePeriod.new(period_start: p.begin, period_end: p.end)
end
- tt.int_day_types = 508
+ tt.int_day_types = self.int_day_types
end
end
diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb
index 07bf35444..1a1972113 100644
--- a/app/models/chouette/time_table.rb
+++ b/app/models/chouette/time_table.rb
@@ -4,11 +4,12 @@ module Chouette
include ChecksumSupport
include TimeTableRestrictions
include ObjectidSupport
+ include ApplicationDaysSupport
+
# FIXME http://jira.codehaus.org/browse/JRUBY-6358
self.primary_key = "id"
acts_as_taggable
- attr_accessor :monday,:tuesday,:wednesday,:thursday,:friday,:saturday,:sunday
attr_accessor :tag_search
def self.ransackable_attributes auth_object = nil
@@ -314,98 +315,6 @@ module Chouette
[bounding_min, bounding_max].compact
end
- def display_day_types
- %w(monday tuesday wednesday thursday friday saturday sunday).select{ |d| self.send(d) }.map{ |d| self.human_attribute_name(d).first(2)}.join(', ')
- end
-
- def day_by_mask(flag)
- int_day_types & flag == flag
- end
-
- def self.day_by_mask(int_day_types,flag)
- int_day_types & flag == flag
- end
-
-
- def valid_days
- # Build an array with day of calendar week (1-7, Monday is 1).
- [].tap do |valid_days|
- valid_days << 1 if monday
- valid_days << 2 if tuesday
- valid_days << 3 if wednesday
- valid_days << 4 if thursday
- valid_days << 5 if friday
- valid_days << 6 if saturday
- valid_days << 7 if sunday
- end
- end
-
- def self.valid_days(int_day_types)
- # Build an array with day of calendar week (1-7, Monday is 1).
- [].tap do |valid_days|
- valid_days << 1 if day_by_mask(int_day_types,4)
- valid_days << 2 if day_by_mask(int_day_types,8)
- valid_days << 3 if day_by_mask(int_day_types,16)
- valid_days << 4 if day_by_mask(int_day_types,32)
- valid_days << 5 if day_by_mask(int_day_types,64)
- valid_days << 6 if day_by_mask(int_day_types,128)
- valid_days << 7 if day_by_mask(int_day_types,256)
- end
- end
-
- def monday
- day_by_mask(4)
- end
- def tuesday
- day_by_mask(8)
- end
- def wednesday
- day_by_mask(16)
- end
- def thursday
- day_by_mask(32)
- end
- def friday
- day_by_mask(64)
- end
- def saturday
- day_by_mask(128)
- end
- def sunday
- day_by_mask(256)
- end
-
- def set_day(day,flag)
- if day == '1' || day == true
- self.int_day_types |= flag
- else
- self.int_day_types &= ~flag
- end
- shortcuts_update
- end
-
- def monday=(day)
- set_day(day,4)
- end
- def tuesday=(day)
- set_day(day,8)
- end
- def wednesday=(day)
- set_day(day,16)
- end
- def thursday=(day)
- set_day(day,32)
- end
- def friday=(day)
- set_day(day,64)
- end
- def saturday=(day)
- set_day(day,128)
- end
- def sunday=(day)
- set_day(day,256)
- end
-
def effective_days_of_period(period,valid_days=self.valid_days)
days = []
period.period_start.upto(period.period_end) do |date|
diff --git a/app/models/concerns/application_days_support.rb b/app/models/concerns/application_days_support.rb
new file mode 100644
index 000000000..927011acb
--- /dev/null
+++ b/app/models/concerns/application_days_support.rb
@@ -0,0 +1,108 @@
+module ApplicationDaysSupport
+ extend ActiveSupport::Concern
+
+ included do |into|
+ into.class_eval do
+ MONDAY = 4
+ TUESDAY = 8
+ WEDNESDAY = 16
+ THURSDAY = 32
+ FRIDAY = 64
+ SATURDAY = 128
+ SUNDAY = 256
+ end
+
+ # attr_accessor :monday,:tuesday,:wednesday,:thursday,:friday,:saturday,:sunday
+ end
+
+ def display_day_types
+ %w(monday tuesday wednesday thursday friday saturday sunday).select{ |d| self.send(d) }.map{ |d| self.human_attribute_name(d).first(2)}.join(', ')
+ end
+
+ def day_by_mask(flag)
+ int_day_types & flag == flag
+ end
+
+ def self.day_by_mask(int_day_types,flag)
+ int_day_types & flag == flag
+ end
+
+ def valid_days
+ # Build an array with day of calendar week (1-7, Monday is 1).
+ [].tap do |valid_days|
+ valid_days << 1 if monday
+ valid_days << 2 if tuesday
+ valid_days << 3 if wednesday
+ valid_days << 4 if thursday
+ valid_days << 5 if friday
+ valid_days << 6 if saturday
+ valid_days << 7 if sunday
+ end
+ end
+
+ def self.valid_days(int_day_types)
+ # Build an array with day of calendar week (1-7, Monday is 1).
+ [].tap do |valid_days|
+ valid_days << 1 if day_by_mask(int_day_types,MONDAY)
+ valid_days << 2 if day_by_mask(int_day_types,TUESDAY)
+ valid_days << 3 if day_by_mask(int_day_types,WEDNESDAY)
+ valid_days << 4 if day_by_mask(int_day_types,THURSDAY)
+ valid_days << 5 if day_by_mask(int_day_types,FRIDAY)
+ valid_days << 6 if day_by_mask(int_day_types,SATURDAY)
+ valid_days << 7 if day_by_mask(int_day_types,SUNDAY)
+ end
+ end
+
+ def monday
+ day_by_mask(MONDAY)
+ end
+ def tuesday
+ day_by_mask(TUESDAY)
+ end
+ def wednesday
+ day_by_mask(WEDNESDAY)
+ end
+ def thursday
+ day_by_mask(THURSDAY)
+ end
+ def friday
+ day_by_mask(FRIDAY)
+ end
+ def saturday
+ day_by_mask(SATURDAY)
+ end
+ def sunday
+ day_by_mask(SUNDAY)
+ end
+
+ def set_day(day,flag)
+ if day == '1' || day == true
+ self.int_day_types |= flag
+ else
+ self.int_day_types &= ~flag
+ end
+ shortcuts_update
+ end
+
+ def monday=(day)
+ set_day(day,4)
+ end
+ def tuesday=(day)
+ set_day(day,8)
+ end
+ def wednesday=(day)
+ set_day(day,16)
+ end
+ def thursday=(day)
+ set_day(day,32)
+ end
+ def friday=(day)
+ set_day(day,64)
+ end
+ def saturday=(day)
+ set_day(day,128)
+ end
+ def sunday=(day)
+ set_day(day,256)
+ end
+end
diff --git a/db/migrate/20180124061955_add_int_day_types_to_calendars.rb b/db/migrate/20180124061955_add_int_day_types_to_calendars.rb
new file mode 100644
index 000000000..6384c7177
--- /dev/null
+++ b/db/migrate/20180124061955_add_int_day_types_to_calendars.rb
@@ -0,0 +1,5 @@
+class AddIntDayTypesToCalendars < ActiveRecord::Migration
+ def change
+ add_column :calendars, :int_day_types, :integer, default: 0
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 9be702fa3..614d9803e 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,11 +11,8 @@
#
# It's strongly recommended that you check this file into your version control system.
-<<<<<<< HEAD
-ActiveRecord::Schema.define(version: 20180123174450) do
-=======
+
ActiveRecord::Schema.define(version: 20180126134944) do
->>>>>>> Refs #5750 @1h; Add a "kind" attribute to StopAreas
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
diff --git a/spec/models/calendar_spec.rb b/spec/models/calendar_spec.rb
index e71c2b081..4c65b9660 100644
--- a/spec/models/calendar_spec.rb
+++ b/spec/models/calendar_spec.rb
@@ -9,11 +9,12 @@ RSpec.describe Calendar, :type => :model do
it { is_expected.to be_versioned }
describe '#to_time_table' do
- let(:calendar) { create(:calendar, date_ranges: [Date.today...(Date.today + 1.month)]) }
+ let(:calendar) { create(:calendar, int_day_types: Calendar::MONDAY | Calendar::SUNDAY, date_ranges: [Date.today...(Date.today + 1.month)]) }
it 'should convert calendar to an instance of Chouette::TimeTable' do
time_table = calendar.convert_to_time_table
expect(time_table).to be_an_instance_of(Chouette::TimeTable)
+ expect(time_table.int_day_types).to eq calendar.int_day_types
expect(time_table.periods[0].period_start).to eq(calendar.periods[0].begin)
expect(time_table.periods[0].period_end).to eq(calendar.periods[0].end)
expect(time_table.dates.map(&:date)).to match_array(calendar.dates)
diff --git a/spec/models/chouette/time_table_spec.rb b/spec/models/chouette/time_table_spec.rb
index d4a726740..28197984e 100644
--- a/spec/models/chouette/time_table_spec.rb
+++ b/spec/models/chouette/time_table_spec.rb
@@ -926,6 +926,7 @@ end
end
end
end
+
describe "#validity_out_between?" do
let(:empty_tm) {build(:time_table)}
it "should be false if empty calendar" do
@@ -1068,8 +1069,6 @@ end
end
end
-
-
describe "#effective_days" do
before do
subject.periods.clear
@@ -1094,8 +1093,6 @@ end
end
end
-
-
describe "#optimize_overlapping_periods" do
before do
subject.periods.clear
--
cgit v1.2.3
From b1fc1da5262d2b03c872829a7e1238059243e9f3 Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 24 Jan 2018 09:56:56 +0100
Subject: Refs #5682; Fix warning
---
app/models/concerns/application_days_support.rb | 22 ++++++++--------------
1 file changed, 8 insertions(+), 14 deletions(-)
diff --git a/app/models/concerns/application_days_support.rb b/app/models/concerns/application_days_support.rb
index 927011acb..f83e4a5c8 100644
--- a/app/models/concerns/application_days_support.rb
+++ b/app/models/concerns/application_days_support.rb
@@ -1,20 +1,14 @@
module ApplicationDaysSupport
extend ActiveSupport::Concern
- included do |into|
- into.class_eval do
- MONDAY = 4
- TUESDAY = 8
- WEDNESDAY = 16
- THURSDAY = 32
- FRIDAY = 64
- SATURDAY = 128
- SUNDAY = 256
- end
-
- # attr_accessor :monday,:tuesday,:wednesday,:thursday,:friday,:saturday,:sunday
- end
-
+ MONDAY = 4
+ TUESDAY = 8
+ WEDNESDAY = 16
+ THURSDAY = 32
+ FRIDAY = 64
+ SATURDAY = 128
+ SUNDAY = 256
+
def display_day_types
%w(monday tuesday wednesday thursday friday saturday sunday).select{ |d| self.send(d) }.map{ |d| self.human_attribute_name(d).first(2)}.join(', ')
end
--
cgit v1.2.3
From 5253b169da36a3de270f00038597b007035f09dd Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 24 Jan 2018 10:15:48 +0100
Subject: Refs #5682; Set default value for application days
---
app/models/calendar.rb | 5 +++++
app/models/concerns/application_days_support.rb | 3 ++-
db/migrate/20180124061955_add_int_day_types_to_calendars.rb | 2 +-
db/schema.rb | 4 +---
spec/models/calendar_spec.rb | 9 +++++++++
5 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/app/models/calendar.rb b/app/models/calendar.rb
index 40dfa1210..e0f0f03da 100644
--- a/app/models/calendar.rb
+++ b/app/models/calendar.rb
@@ -17,11 +17,16 @@ class Calendar < ActiveRecord::Base
has_many :time_tables
scope :contains_date, ->(date) { where('date ? = any (dates) OR date ? <@ any (date_ranges)', date, date) }
+ before_create :set_default_days
def self.ransackable_scopes(auth_object = nil)
[:contains_date]
end
+ def set_default_days
+ self.int_day_types ||= EVERYDAY
+ end
+
def convert_to_time_table
Chouette::TimeTable.new.tap do |tt|
self.dates.each do |d|
diff --git a/app/models/concerns/application_days_support.rb b/app/models/concerns/application_days_support.rb
index f83e4a5c8..425cba5bf 100644
--- a/app/models/concerns/application_days_support.rb
+++ b/app/models/concerns/application_days_support.rb
@@ -8,7 +8,8 @@ module ApplicationDaysSupport
FRIDAY = 64
SATURDAY = 128
SUNDAY = 256
-
+ EVERYDAY = MONDAY | TUESDAY | WEDNESDAY | THURSDAY | FRIDAY | SATURDAY | SUNDAY
+
def display_day_types
%w(monday tuesday wednesday thursday friday saturday sunday).select{ |d| self.send(d) }.map{ |d| self.human_attribute_name(d).first(2)}.join(', ')
end
diff --git a/db/migrate/20180124061955_add_int_day_types_to_calendars.rb b/db/migrate/20180124061955_add_int_day_types_to_calendars.rb
index 6384c7177..5b1ff6fc1 100644
--- a/db/migrate/20180124061955_add_int_day_types_to_calendars.rb
+++ b/db/migrate/20180124061955_add_int_day_types_to_calendars.rb
@@ -1,5 +1,5 @@
class AddIntDayTypesToCalendars < ActiveRecord::Migration
def change
- add_column :calendars, :int_day_types, :integer, default: 0
+ add_column :calendars, :int_day_types, :integer
end
end
diff --git a/db/schema.rb b/db/schema.rb
index 614d9803e..231bea9ba 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -16,10 +16,9 @@ ActiveRecord::Schema.define(version: 20180126134944) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
- enable_extension "hstore"
enable_extension "postgis"
+ enable_extension "hstore"
enable_extension "unaccent"
- enable_extension "objectid"
create_table "access_links", id: :bigserial, force: :cascade do |t|
t.integer "access_point_id", limit: 8
@@ -121,7 +120,6 @@ ActiveRecord::Schema.define(version: 20180126134944) do
t.datetime "updated_at"
t.date "end_date"
t.string "date_type"
- t.string "mode"
end
add_index "clean_ups", ["referential_id"], name: "index_clean_ups_on_referential_id", using: :btree
diff --git a/spec/models/calendar_spec.rb b/spec/models/calendar_spec.rb
index 4c65b9660..86ce565cd 100644
--- a/spec/models/calendar_spec.rb
+++ b/spec/models/calendar_spec.rb
@@ -21,6 +21,15 @@ RSpec.describe Calendar, :type => :model do
end
end
+ describe 'application days' do
+ let(:calendar) { create(:calendar) }
+ it "should default to all days" do
+ %w(monday tuesday wednesday thursday friday saturday sunday).each do |day|
+ expect(calendar.send(day)).to be_truthy
+ end
+ end
+ end
+
describe 'validations' do
it 'validates that dates and date_ranges do not overlap' do
expect(build(:calendar, dates: [Date.today], date_ranges: [Date.today..Date.tomorrow])).to_not be_valid
--
cgit v1.2.3
From f07802715562b31d15e31b5be90dbeac29cef227 Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 24 Jan 2018 16:56:16 +0100
Subject: Refs #5682 @3h; Use same UI as for timetables
---
app/assets/stylesheets/modules/_timetables.sass | 2 +-
app/controllers/calendars_controller.rb | 29 ++++
app/helpers/time_tables_helper.rb | 2 +-
app/javascript/packs/calendars/edit.js | 74 ++++++++++
app/javascript/time_tables/actions/index.js | 5 +-
app/javascript/time_tables/components/Metas.js | 12 +-
app/models/calendar.rb | 79 ++++++++++-
app/models/calendar/period.rb | 5 +
app/models/chouette/time_table.rb | 96 ++++---------
app/models/concerns/application_days_support.rb | 4 +
app/models/concerns/date_support.rb | 11 +-
app/models/concerns/timetable_support.rb | 149 +++++++++++++++++++++
app/views/calendars/_form.html.slim | 53 --------
app/views/calendars/_form_advanced.html.slim | 8 ++
app/views/calendars/_form_simple.html.slim | 56 ++++++++
app/views/calendars/edit.html.slim | 7 +-
app/views/calendars/month.rabl | 9 ++
app/views/calendars/new.html.slim | 4 +-
app/views/calendars/show.html.slim | 11 ++
app/views/calendars/show.rabl | 22 +++
app/views/time_tables/_show_time_table.html.slim | 28 +---
app/views/time_tables/show.html.slim | 2 +-
config/locales/calendars.en.yml | 7 +
config/locales/calendars.fr.yml | 7 +
config/routes.rb | 6 +-
...180124124215_add_excluded_dates_to_calendars.rb | 5 +
db/schema.rb | 1 -
spec/models/calendar_spec.rb | 110 ++++++++++++++-
28 files changed, 637 insertions(+), 167 deletions(-)
create mode 100644 app/javascript/packs/calendars/edit.js
create mode 100644 app/models/concerns/timetable_support.rb
delete mode 100644 app/views/calendars/_form.html.slim
create mode 100644 app/views/calendars/_form_advanced.html.slim
create mode 100644 app/views/calendars/_form_simple.html.slim
create mode 100644 app/views/calendars/month.rabl
create mode 100644 app/views/calendars/show.rabl
create mode 100644 db/migrate/20180124124215_add_excluded_dates_to_calendars.rb
diff --git a/app/assets/stylesheets/modules/_timetables.sass b/app/assets/stylesheets/modules/_timetables.sass
index b06972ef9..8999456ec 100644
--- a/app/assets/stylesheets/modules/_timetables.sass
+++ b/app/assets/stylesheets/modules/_timetables.sass
@@ -30,7 +30,7 @@
.t2e-item
.th
- padding: 6px 0 0 0
+ padding: 4px 0 0 0
border-color: $darkgrey
border-top-width: 2px
diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb
index eaff3b0c6..3b7b6de15 100644
--- a/app/controllers/calendars_controller.rb
+++ b/app/controllers/calendars_controller.rb
@@ -1,8 +1,11 @@
class CalendarsController < ChouetteController
include PolicyChecker
+ include TimeTablesHelper
+
defaults resource_class: Calendar
before_action :ransack_contains_date, only: [:index]
respond_to :html
+ respond_to :json, only: :show
respond_to :js, only: :index
belongs_to :workgroup
@@ -21,6 +24,32 @@ class CalendarsController < ChouetteController
end
end
+ def month
+ @date = params['date'] ? Date.parse(params['date']) : Date.today
+ @calendar = resource
+ end
+
+ def create
+ create! do
+ if @calendar.valid? && has_feature?('application_days_on_calendars')
+ redirect_to([:edit, @calendar])
+ return
+ end
+ end
+ end
+
+ def update
+ if params[:calendar]
+ super
+ else
+ state = JSON.parse request.raw_post
+ resource.state_update state
+ respond_to do |format|
+ format.json { render json: state, status: state['errors'] ? :unprocessable_entity : :ok }
+ end
+ end
+ end
+
private
def decorate_calendars(calendars)
diff --git a/app/helpers/time_tables_helper.rb b/app/helpers/time_tables_helper.rb
index b380a2b0a..1be1fa5a1 100644
--- a/app/helpers/time_tables_helper.rb
+++ b/app/helpers/time_tables_helper.rb
@@ -84,7 +84,7 @@ module TimeTablesHelper
end unless first.wday == first_weekday
first.upto(last) do |cur|
- cell_text, cell_attrs = block.call(cur)
+ cell_text, cell_attrs = yield cur
cell_text ||= cur.mday
cell_attrs ||= {}
cell_attrs[:headers] = th_id(cur, options[:table_id])
diff --git a/app/javascript/packs/calendars/edit.js b/app/javascript/packs/calendars/edit.js
new file mode 100644
index 000000000..bd09657ec
--- /dev/null
+++ b/app/javascript/packs/calendars/edit.js
@@ -0,0 +1,74 @@
+import React from 'react'
+import { render } from 'react-dom'
+import { Provider } from 'react-redux'
+import { createStore } from 'redux'
+import timeTablesApp from '../../time_tables/reducers'
+import App from '../../time_tables/containers/App'
+import clone from '../../helpers/clone'
+
+const actionType = clone(window, "actionType", true)
+
+// logger, DO NOT REMOVE
+// var applyMiddleware = require('redux').applyMiddleware
+// var createLogger = require('redux-logger')
+// var thunkMiddleware = require('redux-thunk').default
+// var promise = require('redux-promise')
+
+let initialState = {
+ status: {
+ actionType: actionType,
+ policy: window.perms,
+ fetchSuccess: true,
+ isFetching: false
+ },
+ timetable: {
+ current_month: [],
+ current_periode_range: '',
+ periode_range: [],
+ time_table_periods: [],
+ time_table_dates: []
+ },
+ metas: {
+ comment: '',
+ day_types: [],
+ initial_tags: []
+ },
+ pagination: {
+ stateChanged: false,
+ currentPage: '',
+ periode_range: []
+ },
+ modal: {
+ type: '',
+ modalProps: {
+ active: false,
+ begin: {
+ day: '01',
+ month: '01',
+ year: String(new Date().getFullYear())
+ },
+ end: {
+ day: '01',
+ month: '01',
+ year: String(new Date().getFullYear())
+ },
+ index: false,
+ error: ''
+ },
+ confirmModal: {}
+ }
+}
+// const loggerMiddleware = createLogger()
+
+let store = createStore(
+ timeTablesApp,
+ initialState,
+ // applyMiddleware(thunkMiddleware, promise, loggerMiddleware)
+)
+
+render(
+
+
+ ,
+ document.getElementById('periods')
+)
diff --git a/app/javascript/time_tables/actions/index.js b/app/javascript/time_tables/actions/index.js
index 87c7a3e8d..70f548174 100644
--- a/app/javascript/time_tables/actions/index.js
+++ b/app/javascript/time_tables/actions/index.js
@@ -246,7 +246,8 @@ const actions = {
return error
},
fetchTimeTables: (dispatch, nextPage) => {
- let urlJSON = window.location.pathname.split('/', 5).join('/')
+ let urlJSON = window.timetablesUrl || window.location.pathname.split('/', 5).join('/')
+
if(nextPage) {
urlJSON += "/month.json?date=" + nextPage
}else{
@@ -277,7 +278,7 @@ const actions = {
let strDayTypes = actions.arrayToStrDayTypes(metas.day_types)
metas.day_types = strDayTypes
let sentState = assign({}, timetable, metas)
- let urlJSON = window.location.pathname.split('/', 5).join('/')
+ let urlJSON = window.timetablesUrl || window.location.pathname.split('/', 5).join('/')
let hasError = false
fetch(urlJSON + '.json', {
credentials: 'same-origin',
diff --git a/app/javascript/time_tables/components/Metas.js b/app/javascript/time_tables/components/Metas.js
index 4170ba493..3c6848d27 100644
--- a/app/javascript/time_tables/components/Metas.js
+++ b/app/javascript/time_tables/components/Metas.js
@@ -27,7 +27,7 @@ export default function Metas({metas, onUpdateDayTypes, onUpdateComment, onUpdat
{/* color */}
-
+ {metas.color !== undefined &&
{I18n.activerecord.attributes.time_table.color}
@@ -69,10 +69,10 @@ export default function Metas({metas, onUpdateDayTypes, onUpdateComment, onUpdat
-
+ }
{/* tags */}
-
+ {metas.tags !== undefined &&
{I18n.activerecord.attributes.time_table.tag_list}
onUnselect2Tags(e)}
/>
-
+
}
{/* calendar */}
-
+ {metas.calendar !== null &&
{I18n.activerecord.attributes.time_table.calendar}
{metas.calendar ? metas.calendar.name : I18n.time_tables.edit.metas.no_calendar}
-
+
}
{/* day_types */}
diff --git a/app/models/calendar.rb b/app/models/calendar.rb
index e0f0f03da..84b569ab4 100644
--- a/app/models/calendar.rb
+++ b/app/models/calendar.rb
@@ -6,6 +6,7 @@ class Calendar < ActiveRecord::Base
include DateSupport
include PeriodSupport
include ApplicationDaysSupport
+ include TimetableSupport
has_paper_trail class_name: 'PublicVersion'
belongs_to :organisation
@@ -17,16 +18,29 @@ class Calendar < ActiveRecord::Base
has_many :time_tables
scope :contains_date, ->(date) { where('date ? = any (dates) OR date ? <@ any (date_ranges)', date, date) }
- before_create :set_default_days
+
+ after_initialize :set_defaults
def self.ransackable_scopes(auth_object = nil)
[:contains_date]
end
- def set_default_days
+ def self.state_permited_attributes item
+ {name: item["comment"]}
+ end
+
+ def set_defaults
+ self.excluded_dates ||= []
self.int_day_types ||= EVERYDAY
end
+ def human_attribute_name(*args)
+ self.class.human_attribute_name(*args)
+ end
+
+ def shortcuts_update(date=nil)
+ end
+
def convert_to_time_table
Chouette::TimeTable.new.tap do |tt|
self.dates.each do |d|
@@ -39,4 +53,65 @@ class Calendar < ActiveRecord::Base
end
end
+ def include_in_dates?(day)
+ self.dates.include? day
+ end
+
+ def excluded_date?(day)
+ self.excluded_dates.include? day
+ end
+
+ def update_in_out date, in_out
+ if in_out
+ self.excluded_dates.delete date
+ self.dates << date unless include_in_dates?(date)
+ else
+ self.dates.delete date
+ self.excluded_dates << date unless excluded_date?(date)
+ end
+ date
+ end
+
+ def included_days
+ dates
+ end
+
+ def excluded_days
+ excluded_dates
+ end
+
+ def saved_dates
+ Hash[*self.dates.each_with_index.to_a.map(&:reverse).flatten]
+ end
+
+ def all_dates
+ (dates + excluded_dates).sort.each_with_index.map do |d, i|
+ OpenStruct.new(id: i, date: d, in_out: include_in_dates?(d))
+ end
+ end
+
+ def find_date_by_id id
+ self.dates[id]
+ end
+
+ def destroy_date date
+ self.dates -= [date]
+ end
+
+ def create_date in_out:, date:
+ update_in_out date, in_out
+ end
+
+ def find_period_by_id id
+ self.periods.find{|p| p.id == id}
+ end
+
+ def build_period
+ self.periods << Calendar::Period.new(id: self.periods.count + 1)
+ self.periods.last
+ end
+
+ def destroy_period period
+ @periods = self.periods.select{|p| p.end != period.end || p.begin != period.begin}
+ end
end
diff --git a/app/models/calendar/period.rb b/app/models/calendar/period.rb
index 56ab722fe..8b3e4109b 100644
--- a/app/models/calendar/period.rb
+++ b/app/models/calendar/period.rb
@@ -10,6 +10,11 @@ class Calendar < ActiveRecord::Base
validates_presence_of :begin, :end
validate :check_end_greather_than_begin
+ alias_method :period_start, :begin
+ alias_method :period_end, :end
+ alias_method :period_start=, :begin=
+ alias_method :period_end=, :end=
+
def check_end_greather_than_begin
if self.begin && self.end && self.begin >= self.end
errors.add(:base, I18n.t('calendars.errors.short_period'))
diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb
index 1a1972113..8113457ec 100644
--- a/app/models/chouette/time_table.rb
+++ b/app/models/chouette/time_table.rb
@@ -5,6 +5,7 @@ module Chouette
include TimeTableRestrictions
include ObjectidSupport
include ApplicationDaysSupport
+ include TimetableSupport
# FIXME http://jira.codehaus.org/browse/JRUBY-6358
self.primary_key = "id"
@@ -82,72 +83,36 @@ module Chouette
end
end
- def state_update state
- update_attributes(self.class.state_permited_attributes(state))
- self.tag_list = state['tags'].collect{|t| t['name']}.join(', ')
- self.calendar_id = nil unless state['calendar']
-
- days = state['day_types'].split(',')
- Date::DAYNAMES.map(&:underscore).each do |name|
- prefix = human_attribute_name(name).first(2)
- send("#{name}=", days.include?(prefix))
- end
-
- saved_dates = Hash[self.dates.collect{ |d| [d.id, d.date]}]
- cmonth = Date.parse(state['current_periode_range'])
-
- state['current_month'].each do |d|
- date = Date.parse(d['date'])
- checked = d['include_date'] || d['excluded_date']
- in_out = d['include_date'] ? true : false
-
- date_id = saved_dates.key(date)
- time_table_date = self.dates.find(date_id) if date_id
+ def find_date_by_id id
+ self.dates.find id
+ end
- next if !checked && !time_table_date
- # Destroy date if no longer checked
- next if !checked && time_table_date.destroy
+ def destroy_date date
+ date.destroy
+ end
- # Create new date
- unless time_table_date
- time_table_date = self.dates.create({in_out: in_out, date: date})
- end
- # Update in_out
- if in_out != time_table_date.in_out
- time_table_date.update_attributes({in_out: in_out})
- end
+ def update_in_out date, in_out
+ if in_out != date.in_out
+ date.update_attributes({in_out: in_out})
end
-
- self.state_update_periods state['time_table_periods']
- self.save
end
- def state_update_periods state_periods
- state_periods.each do |item|
- period = self.periods.find(item['id']) if item['id']
- next if period && item['deleted'] && period.destroy
- period ||= self.periods.build
-
- period.period_start = Date.parse(item['period_start'])
- period.period_end = Date.parse(item['period_end'])
+ def find_period_by_id id
+ self.periods.find id
+ end
- if period.changed?
- period.save
- item['id'] = period.id
- end
- end
+ def build_period
+ periods.build
+ end
- state_periods.delete_if {|item| item['deleted']}
+ def destroy_period period
+ period.destroy
end
def self.state_permited_attributes item
item.slice('comment', 'color').to_hash
end
- def presenter
- @presenter ||= ::TimeTablePresenter.new( self)
- end
-
def self.start_validity_period
[Chouette::TimeTable.minimum(:start_date)].compact.min
end
@@ -168,20 +133,6 @@ module Chouette
self.save
end
- def month_inspect(date)
- (date.beginning_of_month..date.end_of_month).map do |d|
- {
- day: I18n.l(d, format: '%A'),
- date: d.to_s,
- wday: d.wday,
- wnumber: d.strftime("%W").to_s,
- mday: d.mday,
- include_date: include_in_dates?(d),
- excluded_date: excluded_date?(d)
- }
- end
- end
-
def save_shortcuts
shortcuts_update
self.update_column(:start_date, start_date)
@@ -361,6 +312,17 @@ module Chouette
days.sort
end
+ def create_date in_out:, date:
+ self.dates.create in_out: in_out, date: date
+ end
+
+ def saved_dates
+ Hash[self.dates.collect{ |d| [d.id, d.date]}]
+ end
+
+ def all_dates
+ dates
+ end
# produce a copy of periods without anyone overlapping or including another
def optimize_overlapping_periods
diff --git a/app/models/concerns/application_days_support.rb b/app/models/concerns/application_days_support.rb
index 425cba5bf..348436aa4 100644
--- a/app/models/concerns/application_days_support.rb
+++ b/app/models/concerns/application_days_support.rb
@@ -35,6 +35,10 @@ module ApplicationDaysSupport
end
end
+ def valid_day? wday
+ valid_days.include?(wday)
+ end
+
def self.valid_days(int_day_types)
# Build an array with day of calendar week (1-7, Monday is 1).
[].tap do |valid_days|
diff --git a/app/models/concerns/date_support.rb b/app/models/concerns/date_support.rb
index fbfe19af1..5c66cb1a9 100644
--- a/app/models/concerns/date_support.rb
+++ b/app/models/concerns/date_support.rb
@@ -38,9 +38,12 @@ module DateSupport
date_values_are_valid = false
end
date_ranges.each do |date_range|
- if date_range.cover? date_value.value
- date_value.errors.add(:base, I18n.t('activerecord.errors.models.calendar.attributes.dates.date_in_date_ranges'))
- date_values_are_valid = false
+ if date_range.cover?(date_value.value)
+ excluded_day = self.respond_to?(:valid_day?) && !self.valid_day?(date_value.value.wday)
+ unless excluded_day
+ date_value.errors.add(:base, I18n.t('activerecord.errors.models.calendar.attributes.dates.date_in_date_ranges'))
+ date_values_are_valid = false
+ end
end
end
end
@@ -77,4 +80,4 @@ module DateSupport
private :clear_date_values
end
-end
\ No newline at end of file
+end
diff --git a/app/models/concerns/timetable_support.rb b/app/models/concerns/timetable_support.rb
new file mode 100644
index 000000000..8c49723fe
--- /dev/null
+++ b/app/models/concerns/timetable_support.rb
@@ -0,0 +1,149 @@
+module TimetableSupport
+ extend ActiveSupport::Concern
+
+ def presenter
+ @presenter ||= ::TimeTablePresenter.new( self)
+ end
+
+ def periods_max_date
+ return nil if self.periods.empty?
+
+ min_start = self.periods.map(&:period_start).compact.min
+ max_end = self.periods.map(&:period_end).compact.max
+ result = nil
+
+ if max_end && min_start
+ max_end.downto( min_start) do |date|
+ if self.valid_days.include?(date.cwday) && !self.excluded_date?(date)
+ result = date
+ break
+ end
+ end
+ end
+ result
+ end
+
+ def periods_min_date
+ return nil if self.periods.empty?
+
+ min_start = self.periods.map(&:period_start).compact.min
+ max_end = self.periods.map(&:period_end).compact.max
+ result = nil
+
+ if max_end && min_start
+ min_start.upto(max_end) do |date|
+ if self.valid_days.include?(date.cwday) && !self.excluded_date?(date)
+ result = date
+ break
+ end
+ end
+ end
+ result
+ end
+
+ def bounding_dates
+ bounding_min = self.all_dates.select{|d| d.in_out}.map(&:date).compact.min
+ bounding_max = self.all_dates.select{|d| d.in_out}.map(&:date).compact.max
+
+ unless self.periods.empty?
+ bounding_min = periods_min_date if periods_min_date &&
+ (bounding_min.nil? || (periods_min_date < bounding_min))
+
+ bounding_max = periods_max_date if periods_max_date &&
+ (bounding_max.nil? || (bounding_max < periods_max_date))
+ end
+
+ [bounding_min, bounding_max].compact
+ end
+
+ def month_inspect(date)
+ (date.beginning_of_month..date.end_of_month).map do |d|
+ {
+ day: I18n.l(d, format: '%A'),
+ date: d.to_s,
+ wday: d.wday,
+ wnumber: d.strftime("%W").to_s,
+ mday: d.mday,
+ include_date: include_in_dates?(d),
+ excluded_date: excluded_date?(d)
+ }
+ end
+ end
+
+ def include_in_dates?(day)
+ self.dates.any?{ |d| d.date === day && d.in_out == true }
+ end
+
+ def excluded_date?(day)
+ self.dates.any?{ |d| d.date === day && d.in_out == false }
+ end
+
+ def include_in_overlap_dates?(day)
+ return false if self.excluded_date?(day)
+
+ self.all_dates.any?{ |d| d.date === day} \
+ && self.periods.any?{ |period| period.period_start <= day && day <= period.period_end && valid_days.include?(day.cwday) }
+ end
+
+ def include_in_periods?(day)
+ self.periods.any?{ |period| period.period_start <= day &&
+ day <= period.period_end &&
+ valid_days.include?(day.cwday) &&
+ ! excluded_date?(day) }
+ end
+
+ def state_update_periods state_periods
+ state_periods.each do |item|
+ period = self.find_period_by_id(item['id']) if item['id']
+ next if period && item['deleted'] && self.destroy_period(period)
+ period ||= self.build_period
+
+ period.period_start = Date.parse(item['period_start'])
+ period.period_end = Date.parse(item['period_end'])
+
+ period.save if period === ActiveRecord::Base && period.changed?
+
+ item['id'] = period.id
+ end
+
+ state_periods.delete_if {|item| item['deleted']}
+ end
+
+ def state_update state
+ update_attributes(self.class.state_permited_attributes(state))
+ self.tag_list = state['tags'].collect{|t| t['name']}.join(', ') if state['tags']
+ self.calendar_id = nil if self.respond_to?(:calendar_id) && !state['calendar']
+
+ days = state['day_types'].split(',')
+ Date::DAYNAMES.map(&:underscore).each do |name|
+ prefix = human_attribute_name(name).first(2)
+ send("#{name}=", days.include?(prefix))
+ end
+
+ cmonth = Date.parse(state['current_periode_range'])
+
+ state['current_month'].each do |d|
+ date = Date.parse(d['date'])
+ checked = d['include_date'] || d['excluded_date']
+ in_out = d['include_date'] ? true : false
+
+ date_id = saved_dates.key(date)
+ time_table_date = self.find_date_by_id(date_id) if date_id
+
+ next if !checked && !time_table_date
+ # Destroy date if no longer checked
+ next if !checked && destroy_date(time_table_date)
+
+ # Create new date
+ unless time_table_date
+ time_table_date = self.create_date in_out: in_out, date: date
+ end
+ # Update in_out
+ self.update_in_out time_table_date, in_out
+ end
+
+ self.state_update_periods state['time_table_periods']
+ self.save
+ end
+
+end
diff --git a/app/views/calendars/_form.html.slim b/app/views/calendars/_form.html.slim
deleted file mode 100644
index bf9f4f3a7..000000000
--- a/app/views/calendars/_form.html.slim
+++ /dev/null
@@ -1,53 +0,0 @@
-= simple_form_for [@workgroup, @calendar], html: { class: 'form-horizontal', id: 'calendar_form' }, wrapper: :horizontal_form do |f|
- .row
- .col-lg-12
- = f.input :name
- = f.input :short_name
-
- - if policy(@calendar).share?
- .form-group.has_switch
- = f.label :shared, class: 'col-sm-4 col-xs-5 control-label'
- = f.input :shared, as: :boolean, checked_value: true, unchecked_value: false, label: content_tag(:span, t("#{@calendar.shared}"), class: 'switch-label', data: {checkedValue: t('true'), uncheckedValue: t('false')}), wrapper_html: { class: 'col-sm-8 col-xs-7'}
-
- .separator
-
- .row
- .col-lg-12
- .subform
- .nested-head
- .wrapper
- div
- .form-group
- label.control-label
- = Calendar.human_attribute_name(:date)
- div
-
- = f.simple_fields_for :date_values do |date_value|
- = render 'date_value_fields', f: date_value
-
- .links.nested-linker
- = link_to_add_association t('simple_form.labels.calendar.add_a_date'), f, :date_values, class: 'btn btn-outline-primary'
-
- .separator
-
- .row
- .col-lg-12
- .subform
- .nested-head
- .wrapper
- div
- .form-group
- label.control-label
- = t('simple_form.labels.calendar.ranges.begin')
- div
- .form-group
- label.control-label
- = t('simple_form.labels.calendar.ranges.end')
- div
-
- = f.simple_fields_for :periods do |period|
- = render 'period_fields', f: period
- .links.nested-linker
- = link_to_add_association t('simple_form.labels.calendar.add_a_date_range'), f, :periods, class: 'btn btn-outline-primary'
-
- = f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'calendar_form'
diff --git a/app/views/calendars/_form_advanced.html.slim b/app/views/calendars/_form_advanced.html.slim
new file mode 100644
index 000000000..b4154166b
--- /dev/null
+++ b/app/views/calendars/_form_advanced.html.slim
@@ -0,0 +1,8 @@
+#periods
+
+= javascript_tag do
+ | window.actionType = "#{raw params[:action]}";
+ | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe};
+ | window.timetablesUrl = "#{calendar_url(@calendar).html_safe}";
+
+= javascript_pack_tag 'calendars/edit.js'
diff --git a/app/views/calendars/_form_simple.html.slim b/app/views/calendars/_form_simple.html.slim
new file mode 100644
index 000000000..2f469ada7
--- /dev/null
+++ b/app/views/calendars/_form_simple.html.slim
@@ -0,0 +1,56 @@
+.row
+ .col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-10.col-sm-offset-1
+ = simple_form_for @calendar, html: { class: 'form-horizontal', id: 'calendar_form' }, wrapper: :horizontal_form do |f|
+ .row
+ .col-lg-12
+ = f.input :name
+ = f.input :short_name
+
+ - if policy(@calendar).share?
+ .form-group.has_switch
+ = f.label :shared, class: 'col-sm-4 col-xs-5 control-label'
+ = f.input :shared, as: :boolean, checked_value: true, unchecked_value: false, label: content_tag(:span, t("#{@calendar.shared}"), class: 'switch-label', data: {checkedValue: t('true'), uncheckedValue: t('false')}), wrapper_html: { class: 'col-sm-8 col-xs-7'}
+
+ .separator
+
+ - unless has_feature?('application_days_on_calendars')
+ .row
+ .col-lg-12
+ .subform
+ .nested-head
+ .wrapper
+ div
+ .form-group
+ label.control-label
+ = Calendar.human_attribute_name(:date)
+ div
+
+ = f.simple_fields_for :date_values do |date_value|
+ = render 'date_value_fields', f: date_value
+
+ .links.nested-linker
+ = link_to_add_association t('simple_form.labels.calendar.add_a_date'), f, :date_values, class: 'btn btn-outline-primary'
+
+ .separator
+
+ .row
+ .col-lg-12
+ .subform
+ .nested-head
+ .wrapper
+ div
+ .form-group
+ label.control-label
+ = t('simple_form.labels.calendar.ranges.begin')
+ div
+ .form-group
+ label.control-label
+ = t('simple_form.labels.calendar.ranges.end')
+ div
+
+ = f.simple_fields_for :periods do |period|
+ = render 'period_fields', f: period
+ .links.nested-linker
+ = link_to_add_association t('simple_form.labels.calendar.add_a_date_range'), f, :periods, class: 'btn btn-outline-primary'
+
+ = f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'calendar_form'
diff --git a/app/views/calendars/edit.html.slim b/app/views/calendars/edit.html.slim
index a1af5e257..79ab1f5d0 100644
--- a/app/views/calendars/edit.html.slim
+++ b/app/views/calendars/edit.html.slim
@@ -2,6 +2,7 @@
- page_header_content_for @calendar
.page_content
.container-fluid
- .row
- .col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-10.col-sm-offset-1
- = render 'form'
+ - if has_feature?('application_days_on_calendars')
+ = render 'form_advanced'
+ - else
+ = render 'form_simple'
diff --git a/app/views/calendars/month.rabl b/app/views/calendars/month.rabl
new file mode 100644
index 000000000..1584db44c
--- /dev/null
+++ b/app/views/calendars/month.rabl
@@ -0,0 +1,9 @@
+object @calendar
+
+node do |tt|
+ {
+ name: I18n.l(@date, format: '%B'),
+ days: tt.month_inspect(@date),
+ day_types: %w(monday tuesday wednesday thursday friday saturday sunday).select{ |d| tt.send(d) }.map{ |d| tt.human_attribute_name(d).first(2)}.join('')
+ }
+end
diff --git a/app/views/calendars/new.html.slim b/app/views/calendars/new.html.slim
index c1e084913..5657a0c55 100644
--- a/app/views/calendars/new.html.slim
+++ b/app/views/calendars/new.html.slim
@@ -1,6 +1,4 @@
- breadcrumb :calendars, @workgroup
.page_content
.container-fluid
- .row
- .col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-10.col-sm-offset-1
- = render 'form'
+ = render 'form_simple'
diff --git a/app/views/calendars/show.html.slim b/app/views/calendars/show.html.slim
index cd2be2bd1..cec4f66a5 100644
--- a/app/views/calendars/show.html.slim
+++ b/app/views/calendars/show.html.slim
@@ -11,3 +11,14 @@
'Organisation' => resource.organisation.name,
Calendar.human_attribute_name(:dates) => resource.dates.collect{|d| l(d, format: :short)}.join(', ').html_safe,
Calendar.human_attribute_name(:date_ranges) => resource.periods.map{|d| t('validity_range', debut: l(d.begin, format: :short), end: l(d.end, format: :short))}.join('
').html_safe }
+
+ - if has_feature?('application_days_on_calendars')
+ .row
+ .col-lg-12.mb-sm
+ .pagination.pull-right
+ = @year
+ .page_links
+ = link_to '', calendar_path(@calendar, year: (@year - 1)), class: 'previous_page'
+ = link_to '', calendar_path(@calendar, year: (@year + 1)), class: 'next_page'
+
+ = render 'time_tables/show_time_table', time_table: @calendar
diff --git a/app/views/calendars/show.rabl b/app/views/calendars/show.rabl
new file mode 100644
index 000000000..295d97528
--- /dev/null
+++ b/app/views/calendars/show.rabl
@@ -0,0 +1,22 @@
+object @calendar
+
+attributes :id
+node do |tt|
+ {
+ comment: tt.name,
+ time_table_bounding: tt.presenter.time_table_bounding,
+ day_types: %w(monday tuesday wednesday thursday friday saturday sunday).select{ |d| tt.send(d) }.map{ |d| tt.human_attribute_name(d).first(2)}.join(''),
+ current_month: tt.month_inspect(Date.today),
+ periode_range: month_periode_enum(3),
+ current_periode_range: Date.today.beginning_of_month,
+ short_id: tt.object_id,
+ }
+end
+
+child(:periods, object_root: false, root: :time_table_periods) do
+ attributes :id, :period_start, :period_end
+end
+
+child(:all_dates, object_root: false, root: :time_table_dates) do
+ attributes :id, :date, :in_out
+end
diff --git a/app/views/time_tables/_show_time_table.html.slim b/app/views/time_tables/_show_time_table.html.slim
index ebfe9d283..102dbfad7 100644
--- a/app/views/time_tables/_show_time_table.html.slim
+++ b/app/views/time_tables/_show_time_table.html.slim
@@ -2,24 +2,10 @@
- (1..12).each do |month|
.col-lg-3.col-md-4.col-sm-4.col-xs-6
= new_alt_calendar(year: @year, month: month, first_day_of_week: 1, calendar_title: "#{I18n.t("date.month_names")[month]}", show_today: false) do |d|
- / - if @time_table.excluded_date?(d)
- / - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day excluded_date"}]
- - if @time_table.include_in_overlap_dates?(d)
- - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day overlaped_date", title: 'Voir'}]
- - elsif @time_table.include_in_dates?(d)
- - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day selected_date", title: 'Voir'}]
- - elsif @time_table.include_in_periods?(d)
- - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day selected_period", title: 'Voir'}]
-
-/ .row
-/ .col-lg-12
-/ / wip
-/ - if @time_table.dates.where("in_out = true").present?
-/ h3.time_table_dates = @time_table.human_attribute_name("dates")
-/ .dates.content
-/ == render "time_tables/dates"
-/
-/ - if @time_table.dates.where("in_out = false").present?
-/ h3.time_table_dates = @time_table.human_attribute_name("excluded_dates")
-/ .excluded_dates.content
-/ == render "time_tables/excluded_dates"
+ - edit_url = [:edit, @referential, time_table].compact
+ - if time_table.include_in_overlap_dates?(d)
+ - [link_to(d.mday, edit_url), {class: "day overlaped_date", title: 'Voir'}]
+ - elsif time_table.include_in_dates?(d)
+ - [link_to(d.mday, edit_url), {class: "day selected_date", title: 'Voir'}]
+ - elsif time_table.include_in_periods?(d)
+ - [link_to(d.mday, edit_url), {class: "day selected_period", title: 'Voir'}]
diff --git a/app/views/time_tables/show.html.slim b/app/views/time_tables/show.html.slim
index 6d15323f3..e038b73ca 100644
--- a/app/views/time_tables/show.html.slim
+++ b/app/views/time_tables/show.html.slim
@@ -24,4 +24,4 @@
= link_to '', referential_time_table_path(@referential, @time_table, year: (@year - 1)), class: 'previous_page'
= link_to '', referential_time_table_path(@referential, @time_table, year: (@year + 1)), class: 'next_page'
- = render 'show_time_table'
+ = render 'show_time_table', time_table: @time_table
diff --git a/config/locales/calendars.en.yml b/config/locales/calendars.en.yml
index a2110d053..c3df413af 100644
--- a/config/locales/calendars.en.yml
+++ b/config/locales/calendars.en.yml
@@ -69,6 +69,13 @@ en:
dates: Dates
shared: Shared
organisation: Organisation
+ monday: "Monday"
+ tuesday: "Tuesday"
+ wednesday: "Wednesday"
+ thursday: "Thursday"
+ friday: "Friday"
+ saturday: "Saturday"
+ sunday: "Sunday"
errors:
models:
calendar:
diff --git a/config/locales/calendars.fr.yml b/config/locales/calendars.fr.yml
index f9eaf1be5..6fd265925 100644
--- a/config/locales/calendars.fr.yml
+++ b/config/locales/calendars.fr.yml
@@ -69,6 +69,13 @@ fr:
dates: Dates
shared: Partagé
organisation: Organisation
+ monday: "Lundi"
+ tuesday: "Mardi"
+ wednesday: "Mercredi"
+ thursday: "Jeudi"
+ friday: "Vendredi"
+ saturday: "Samedi"
+ sunday: "Dimanche"
errors:
models:
calendar:
diff --git a/config/routes.rb b/config/routes.rb
index 07370ee6d..5fc39ba92 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -111,9 +111,13 @@ ChouetteIhm::Application.routes.draw do
resources :companies
resources :networks
end
+
resources :workgroups do
resources :calendars do
get :autocomplete, on: :collection, controller: 'autocomplete_calendars'
+ member do
+ get 'month', defaults: { format: :json }
+ end
end
end
@@ -121,7 +125,7 @@ ChouetteIhm::Application.routes.draw do
resources :autocomplete_stop_areas, only: [:show, :index] do
get 'around', on: :member
end
- resources :autocomplete_purchase_windows, only: [:index]
+ resources :autocomplete_purchase_windows, only: [:index]
get :select_compliance_control_set
post :validate, on: :member
resources :autocomplete_time_tables, only: [:index]
diff --git a/db/migrate/20180124124215_add_excluded_dates_to_calendars.rb b/db/migrate/20180124124215_add_excluded_dates_to_calendars.rb
new file mode 100644
index 000000000..b98b50717
--- /dev/null
+++ b/db/migrate/20180124124215_add_excluded_dates_to_calendars.rb
@@ -0,0 +1,5 @@
+class AddExcludedDatesToCalendars < ActiveRecord::Migration
+ def change
+ add_column :calendars, :excluded_dates, :date, array: true
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 231bea9ba..b696cfc98 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,6 @@
#
# It's strongly recommended that you check this file into your version control system.
-
ActiveRecord::Schema.define(version: 20180126134944) do
# These are extensions that must be enabled in order to support this database
diff --git a/spec/models/calendar_spec.rb b/spec/models/calendar_spec.rb
index 86ce565cd..3cffd0f8a 100644
--- a/spec/models/calendar_spec.rb
+++ b/spec/models/calendar_spec.rb
@@ -32,7 +32,11 @@ RSpec.describe Calendar, :type => :model do
describe 'validations' do
it 'validates that dates and date_ranges do not overlap' do
- expect(build(:calendar, dates: [Date.today], date_ranges: [Date.today..Date.tomorrow])).to_not be_valid
+ expect(build(:calendar, dates: [Date.today.beginning_of_week], date_ranges: [Date.today.beginning_of_week..Date.today])).to_not be_valid
+ end
+
+ it 'validates that dates and date_ranges do not overlap but allow for days not in the list' do
+ expect(build(:calendar, dates: [Date.today.beginning_of_week], date_ranges: [Date.today.beginning_of_week..Date.today], int_day_types: Calendar::THURSDAY)).to be_valid
end
it 'validates that there are no duplicates in dates' do
@@ -52,4 +56,108 @@ RSpec.describe Calendar, :type => :model do
end
end
+ describe "Update state" do
+ def calendar_to_state calendar
+ calendar.slice('id').tap do |item|
+ item['comment'] = calendar.name
+ item['day_types'] = "Di,Lu,Ma,Me,Je,Ve,Sa"
+ item['current_month'] = calendar.month_inspect(Date.today.beginning_of_month)
+ item['current_periode_range'] = Date.today.beginning_of_month.to_s
+ item['time_table_periods'] = calendar.periods.map{|p| {'id': p.id, 'period_start': p.period_start.to_s, 'period_end': p.period_end.to_s}}
+ end
+ end
+
+ subject(:calendar){ create :calendar }
+ let(:state) { calendar_to_state subject }
+
+ it 'should update time table periods association' do
+ period = state['time_table_periods'].first
+ period['period_start'] = (Date.today - 1.month).to_s
+ period['period_end'] = (Date.today + 1.month).to_s
+
+ subject.state_update_periods state['time_table_periods']
+ ['period_end', 'period_start'].each do |prop|
+ expect(subject.reload.periods.first.send(prop).to_s).to eq(period[prop])
+ end
+ end
+
+ it 'should create time table periods association' do
+ state['time_table_periods'] << {
+ 'id' => false,
+ 'period_start' => (Date.today + 1.year).to_s,
+ 'period_end' => (Date.today + 2.year).to_s
+ }
+
+ expect {
+ subject.state_update_periods state['time_table_periods']
+ }.to change {subject.periods.count}.by(1)
+ expect(state['time_table_periods'].last['id']).to eq subject.reload.periods.last.id
+ end
+
+ it 'should delete time table periods association' do
+ state['time_table_periods'].first['deleted'] = true
+ expect {
+ subject.state_update_periods state['time_table_periods']
+ }.to change {subject.periods.count}.by(-1)
+ end
+
+ it 'should update name' do
+ state['comment'] = "Edited timetable name"
+ subject.state_update state
+ expect(subject.reload.name).to eq state['comment']
+ end
+
+ it 'should update day_types' do
+ state['day_types'] = "Di,Lu,Je,Ma"
+ subject.state_update state
+ expect(subject.reload.valid_days).to include(7, 1, 4, 2)
+ expect(subject.reload.valid_days).not_to include(3, 5, 6)
+ end
+
+ it 'should delete date if date is set to neither include or excluded date' do
+ updated = state['current_month'].map do |day|
+ day['include_date'] = false if day['include_date']
+ end
+
+ expect {
+ subject.state_update state
+ }.to change {subject.dates.count}.by(-updated.compact.count)
+ end
+
+ it 'should update date if date is set to excluded date' do
+ updated = state['current_month'].map do |day|
+ next unless day['include_date']
+ day['include_date'] = false
+ day['excluded_date'] = true
+ end
+
+ subject.state_update state
+ expect(subject.reload.excluded_days.count).to eq (updated.compact.count)
+ end
+
+ it 'should create new include date' do
+ day = state['current_month'].find{|d| !d['excluded_date'] && !d['include_date'] }
+ date = Date.parse(day['date'])
+ day['include_date'] = true
+ expect(subject.included_days).not_to include(date)
+
+ expect {
+ subject.state_update state
+ }.to change {subject.dates.count}.by(1)
+ expect(subject.reload.included_days).to include(date)
+ end
+
+ it 'should create new exclude date' do
+ day = state['current_month'].find{|d| !d['excluded_date'] && !d['include_date']}
+ date = Date.parse(day['date'])
+ day['excluded_date'] = true
+ expect(subject.excluded_days).not_to include(date)
+
+ expect {
+ subject.state_update state
+ }.to change {subject.all_dates.count}.by(1)
+ expect(subject.reload.excluded_days).to include(date)
+ end
+ end
+
end
--
cgit v1.2.3
From 29656560af22c0a13daf2638717a75c695fc21a6 Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 24 Jan 2018 17:18:31 +0100
Subject: Refs #5682; Fix timetables bulk update
---
app/models/concerns/timetable_support.rb | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/app/models/concerns/timetable_support.rb b/app/models/concerns/timetable_support.rb
index 8c49723fe..d2bc99d51 100644
--- a/app/models/concerns/timetable_support.rb
+++ b/app/models/concerns/timetable_support.rb
@@ -100,8 +100,7 @@ module TimetableSupport
period.period_start = Date.parse(item['period_start'])
period.period_end = Date.parse(item['period_end'])
-
- period.save if period === ActiveRecord::Base && period.changed?
+ period.save if period.is_a?(ActiveRecord::Base) && period.changed?
item['id'] = period.id
end
--
cgit v1.2.3
From 1aa2965d049b6ec1c56a580bcb4dac1b50c72b4e Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 31 Jan 2018 15:47:06 +0100
Subject: Refs #5796: Add some legroom in the JourneyPatterns editor
---
app/assets/stylesheets/modules/_jp_collection.sass | 7 ++++++-
app/javascript/journey_patterns/components/JourneyPattern.js | 2 +-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/app/assets/stylesheets/modules/_jp_collection.sass b/app/assets/stylesheets/modules/_jp_collection.sass
index b4370a5ac..46ea3fb6e 100644
--- a/app/assets/stylesheets/modules/_jp_collection.sass
+++ b/app/assets/stylesheets/modules/_jp_collection.sass
@@ -121,6 +121,11 @@
.totals
color: $blue
padding-top: 4px
+ margin-left: -5px
+ margin-right: -5px
+ span
+ white-space: nowrap
+ padding: 0 5px
i
padding-right: 3px
@@ -219,7 +224,7 @@
input
display: inline-block
- width: 40px
+ width: 50px
border: none
margin-right: 5px
color: black
diff --git a/app/javascript/journey_patterns/components/JourneyPattern.js b/app/javascript/journey_patterns/components/JourneyPattern.js
index 01734f3a3..35765b99a 100644
--- a/app/javascript/journey_patterns/components/JourneyPattern.js
+++ b/app/javascript/journey_patterns/components/JourneyPattern.js
@@ -109,7 +109,7 @@ export default class JourneyPattern extends Component{
}
else{
let hours = parseInt(time/60)
- return hours + " h " + (time - 60*hours) + " min"
+ return hours + " h " + (time - 60*hours)
}
}
--
cgit v1.2.3
From e0288495f2d30154ac3b9ba462aa23c0f07fd205 Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 31 Jan 2018 16:09:55 +0100
Subject: Refs #5796; Fix dropdown menu
---
app/assets/stylesheets/components/_buttons.sass | 77 +++++++++++++------------
app/assets/stylesheets/components/_tables.sass | 2 +-
2 files changed, 40 insertions(+), 39 deletions(-)
diff --git a/app/assets/stylesheets/components/_buttons.sass b/app/assets/stylesheets/components/_buttons.sass
index 93f9907a5..2881cee3e 100644
--- a/app/assets/stylesheets/components/_buttons.sass
+++ b/app/assets/stylesheets/components/_buttons.sass
@@ -142,47 +142,48 @@ table, .table
margin: 0
border-radius: 0
box-shadow: 0 0 3px rgba($darkgrey, 0.25)
- > ul
- padding: 0
- margin: 0
- > li > a, > li > button
- padding: 5px 15px
- white-space: nowrap
- padding: 5px 15px
- font-weight: normal
- line-height: $line-height
- display: block
- font-size: 14px
- &:hover, &:focus
- text-decoration: none
- background-color: whitesmoke
- outline: none
- &:not(:first-child)
+ & > ul:not(:first-child)
+ position: relative
+ margin-top: 11px
+ &:before
+ content: ''
+ display: block
+ position: absolute
+ left: 15px
+ right: 15px
+ top: -6px
+ height: 1px
+ background-color: $grey
+
+ ul.dropdown-menu, .dropdown-menu > ul
+ padding: 0
+ margin: 0
+ > li > a, > li > button
+ padding: 5px 15px
+ white-space: nowrap
+ padding: 5px 15px
+ font-weight: normal
+ line-height: $line-height
+ display: block
+ font-size: 14px
+ &:hover, &:focus
+ text-decoration: none
+ background-color: whitesmoke
+ outline: none
+
+ > li.delete-action
+ > a, > button
+ display: block
position: relative
- margin-top: 11px
- &:before
- content: ''
- display: block
- position: absolute
- left: 15px
- right: 15px
- top: -6px
- height: 1px
- background-color: $grey
-
- > li.delete-action
+ .fa:first-child
+ margin-right: 0.5em
+
+ & + li.delete-action
> a, > button
- display: block
- position: relative
- .fa:first-child
- margin-right: 0.5em
-
- & + li.delete-action
- > a, > button
- margin-top: 0
- &:before
- display: none
+ margin-top: 0
+ &:before
+ display: none
&.table-2entries .t2e-item
diff --git a/app/assets/stylesheets/components/_tables.sass b/app/assets/stylesheets/components/_tables.sass
index 119a38c07..35e1122f3 100644
--- a/app/assets/stylesheets/components/_tables.sass
+++ b/app/assets/stylesheets/components/_tables.sass
@@ -372,7 +372,7 @@
white-space: nowrap
// border-right: 1px solid rgba($grey, 0.5)
max-width: 100%
- min-width: 280px
+ min-width: 330px
padding-right: 1px
.t2e-item
--
cgit v1.2.3
From 890d9997258f0e522c862b8443da12113126d1fe Mon Sep 17 00:00:00 2001
From: Zog
Date: Thu, 1 Feb 2018 10:34:40 +0100
Subject: Refs #5798 @3h; Show return journeys on the journeys' editor.
---
app/assets/stylesheets/components/_forms.sass | 11 +++-
app/controllers/vehicle_journeys_controller.rb | 65 ++++++++++++----------
app/javascript/helpers/stop_area_header_manager.js | 5 ++
app/javascript/packs/vehicle_journeys/index.js | 3 +-
app/javascript/vehicle_journeys/actions/index.js | 17 ++++--
app/javascript/vehicle_journeys/components/App.js | 1 +
.../vehicle_journeys/components/VehicleJourney.js | 6 +-
.../vehicle_journeys/components/VehicleJourneys.js | 41 +++++++++++---
.../components/tools/EditVehicleJourney.js | 8 ++-
.../containers/VehicleJourneysList.js | 8 ++-
.../containers/tools/EditVehicleJourney.js | 1 +
app/javascript/vehicle_journeys/reducers/index.js | 3 +
.../reducers/returnVehicleJourneys.js | 11 ++++
app/models/chouette/journey_pattern.rb | 3 +-
app/views/vehicle_journeys/index.html.slim | 6 ++
15 files changed, 134 insertions(+), 55 deletions(-)
create mode 100644 app/javascript/vehicle_journeys/reducers/returnVehicleJourneys.js
diff --git a/app/assets/stylesheets/components/_forms.sass b/app/assets/stylesheets/components/_forms.sass
index 998703ef0..ba5bbbde1 100644
--- a/app/assets/stylesheets/components/_forms.sass
+++ b/app/assets/stylesheets/components/_forms.sass
@@ -256,8 +256,15 @@ table, .table
&.table-2entries .t2e-item
> .th
position: relative
-
- > .checkbox
+ > .st_action
+ list-style-type: none
+ button
+ border-radius: 50%
+ background: $blue
+ color: white
+ border: none
+
+ > .checkbox, > .st_action
position: absolute
right: 0
top: 0
diff --git a/app/controllers/vehicle_journeys_controller.rb b/app/controllers/vehicle_journeys_controller.rb
index ed6ba6ed1..e031e4952 100644
--- a/app/controllers/vehicle_journeys_controller.rb
+++ b/app/controllers/vehicle_journeys_controller.rb
@@ -50,36 +50,8 @@ class VehicleJourneysController < ChouetteController
format.html do
load_missions
load_custom_fields
- @stop_points_list = []
- @stop_points_list = route.stop_points.includes(:stop_area).map do |sp|
- {
- :id => sp.stop_area.id,
- :route_id => sp.try(:route_id),
- :object_id => sp.try(:objectid),
- :position => sp.try(:position),
- :for_boarding => sp.try(:for_boarding),
- :for_alighting => sp.try(:for_alighting),
- :name => sp.stop_area.try(:name),
- :time_zone_offset => sp.stop_area.try(:time_zone_offset),
- :time_zone_formatted_offset => sp.stop_area.try(:time_zone_formatted_offset),
- :zip_code => sp.stop_area.try(:zip_code),
- :city_name => sp.stop_area.try(:city_name),
- :comment => sp.stop_area.try(:comment),
- :area_type => sp.stop_area.try(:area_type),
- :area_type_i18n => I18n.t(sp.stop_area.try(:area_type), scope: 'area_types.label'),
- :area_kind => sp.stop_area.try(:kind),
- :stop_area_id => sp.stop_area_id,
- :registration_number => sp.stop_area.try(:registration_number),
- :nearest_topic_name => sp.stop_area.try(:nearest_topic_name),
- :fare_code => sp.stop_area.try(:fare_code),
- :longitude => sp.stop_area.try(:longitude),
- :latitude => sp.stop_area.try(:latitude),
- :long_lat_type => sp.stop_area.try(:long_lat_type),
- :country_code => sp.stop_area.try(:country_code),
- :country_name => sp.stop_area.try(:country_name),
- :street_name => sp.stop_area.try(:street_name)
- }
- end
+ @stop_points_list = map_stop_points(route.stop_points)
+ @return_stop_points_list = map_stop_points(route.opposite_route&.stop_points) if has_feature?(:vehicle_journeys_return_route)
@transport_mode = route.line['transport_mode']
@transport_submode = route.line['transport_submode']
@@ -185,6 +157,39 @@ class VehicleJourneysController < ChouetteController
@custom_fields = current_workgroup.custom_fields_definitions
end
+ def map_stop_points points
+ (points&.includes(:stop_area) || []).map do |sp|
+ {
+ :id => sp.stop_area.id,
+ :route_id => sp.try(:route_id),
+ :object_id => sp.try(:objectid),
+ :area_object_id => sp.stop_area.try(:objectid),
+ :position => sp.try(:position),
+ :for_boarding => sp.try(:for_boarding),
+ :for_alighting => sp.try(:for_alighting),
+ :name => sp.stop_area.try(:name),
+ :time_zone_offset => sp.stop_area.try(:time_zone_offset),
+ :time_zone_formatted_offset => sp.stop_area.try(:time_zone_formatted_offset),
+ :zip_code => sp.stop_area.try(:zip_code),
+ :city_name => sp.stop_area.try(:city_name),
+ :comment => sp.stop_area.try(:comment),
+ :area_type => sp.stop_area.try(:area_type),
+ :area_type_i18n => I18n.t(sp.stop_area.try(:area_type), scope: 'area_types.label'),
+ :area_kind => sp.stop_area.try(:kind),
+ :stop_area_id => sp.stop_area_id,
+ :registration_number => sp.stop_area.try(:registration_number),
+ :nearest_topic_name => sp.stop_area.try(:nearest_topic_name),
+ :fare_code => sp.stop_area.try(:fare_code),
+ :longitude => sp.stop_area.try(:longitude),
+ :latitude => sp.stop_area.try(:latitude),
+ :long_lat_type => sp.stop_area.try(:long_lat_type),
+ :country_code => sp.stop_area.try(:country_code),
+ :country_name => sp.stop_area.try(:country_name),
+ :street_name => sp.stop_area.try(:street_name)
+ }
+ end
+ end
+
def load_missions
@all_missions = route.journey_patterns.count > 10 ? [] : route.journey_patterns.map do |item|
{
diff --git a/app/javascript/helpers/stop_area_header_manager.js b/app/javascript/helpers/stop_area_header_manager.js
index 2c820caf9..5b18e2f63 100644
--- a/app/javascript/helpers/stop_area_header_manager.js
+++ b/app/javascript/helpers/stop_area_header_manager.js
@@ -42,6 +42,11 @@ export default class StopAreaHeaderManager {
let index = this.ids_list.indexOf(object_id)
let sp = this.stopPointsList[index]
let previousBreakpoint = this.stopPointsList[index - 1]
+ if(sp == undefined){
+ console.log("STOP_POINT NOT FOUND: " + object_id)
+ console.log("AVAILABLE IDS:" + this.ids_list)
+ return
+ }
if(index == 0 || (sp[attribute_to_check] != previousBreakpoint[attribute_to_check])){
showHeadline = true
headline = this.hasFeature('long_distance_routes') ? sp.country_name : sp.city_name
diff --git a/app/javascript/packs/vehicle_journeys/index.js b/app/javascript/packs/vehicle_journeys/index.js
index aa5738d59..e6867cb17 100644
--- a/app/javascript/packs/vehicle_journeys/index.js
+++ b/app/javascript/packs/vehicle_journeys/index.js
@@ -60,6 +60,7 @@ var initialState = {
},
vehicleJourneys: [],
stopPointsList: window.stopPoints,
+ returnStopPointsList: window.returnStopPoints,
pagination: {
page : 1,
totalCount: 0,
@@ -99,7 +100,7 @@ let store = createStore(
render(
-
+
,
document.getElementById('vehicle_journeys_wip')
)
diff --git a/app/javascript/vehicle_journeys/actions/index.js b/app/javascript/vehicle_journeys/actions/index.js
index 8970c6025..74a333b53 100644
--- a/app/javascript/vehicle_journeys/actions/index.js
+++ b/app/javascript/vehicle_journeys/actions/index.js
@@ -13,8 +13,8 @@ const actions = {
exitEditMode: () => ({
type: "EXIT_EDIT_MODE"
}),
- receiveVehicleJourneys : (json) => ({
- type: "RECEIVE_VEHICLE_JOURNEYS",
+ receiveVehicleJourneys : (json, returnJourneys) => ({
+ type: (returnJourneys ? "RECEIVE_RETURN_VEHICLE_JOURNEYS" : "RECEIVE_VEHICLE_JOURNEYS"),
json
}),
receiveErrors : (json) => ({
@@ -290,10 +290,17 @@ const actions = {
type: 'RECEIVE_TOTAL_COUNT',
total
}),
- fetchVehicleJourneys : (dispatch, currentPage, nextPage, queryString) => {
+ fetchVehicleJourneys : (dispatch, currentPage, nextPage, queryString, url) => {
+ let returnJourneys = false
if(currentPage == undefined){
currentPage = 1
}
+ if(url == undefined){
+ url = window.location.pathname
+ }
+ else{
+ returnJourneys = true
+ }
let vehicleJourneys = []
let page
switch (nextPage) {
@@ -315,7 +322,7 @@ const actions = {
str = '.json?page=' + page.toString()
sep = '&'
}
- let urlJSON = window.location.pathname + str
+ let urlJSON = url + str
if (queryString){
urlJSON = urlJSON + sep + queryString
}
@@ -375,7 +382,7 @@ const actions = {
)
}
window.currentItemsLength = vehicleJourneys.length
- dispatch(actions.receiveVehicleJourneys(vehicleJourneys))
+ dispatch(actions.receiveVehicleJourneys(vehicleJourneys, returnJourneys))
dispatch(actions.receiveTotalCount(json.total))
}
})
diff --git a/app/javascript/vehicle_journeys/components/App.js b/app/javascript/vehicle_journeys/components/App.js
index 44559c7c6..5ac284438 100644
--- a/app/javascript/vehicle_journeys/components/App.js
+++ b/app/javascript/vehicle_journeys/components/App.js
@@ -22,6 +22,7 @@ export default function App() {
+ {window.returnRouteUrl &&
}
diff --git a/app/javascript/vehicle_journeys/components/VehicleJourney.js b/app/javascript/vehicle_journeys/components/VehicleJourney.js
index 2b5783dda..e7d4b5b30 100644
--- a/app/javascript/vehicle_journeys/components/VehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/VehicleJourney.js
@@ -1,6 +1,7 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import actions from '../actions'
+import EditVehicleJourney from '../containers/tools/EditVehicleJourney'
export default class VehicleJourney extends Component {
constructor(props) {
@@ -80,7 +81,7 @@ export default class VehicleJourney extends Component {
{purchase_windows.length > 3 && + {purchase_windows.length - 3} }
}
-
+ {!this.props.disabled &&
-
+
}
+ {this.props.disabled &&
}
{this.props.value.vehicle_journey_at_stops.map((vj, i) =>
diff --git a/app/javascript/vehicle_journeys/components/VehicleJourneys.js b/app/javascript/vehicle_journeys/components/VehicleJourneys.js
index 256ca81f9..ae852b35a 100644
--- a/app/javascript/vehicle_journeys/components/VehicleJourneys.js
+++ b/app/javascript/vehicle_journeys/components/VehicleJourneys.js
@@ -8,14 +8,36 @@ export default class VehicleJourneys extends Component {
constructor(props){
super(props)
this.headerManager = new StopAreaHeaderManager(
- _.map(this.props.stopPointsList, (sp)=>{return sp.object_id}),
- this.props.stopPointsList,
+ _.map(this.stopPoints(), (sp)=>{return sp.object_id}),
+ this.stopPoints(),
this.props.filters.features
)
}
+ isReturn() {
+ return this.props.routeUrl != undefined
+ }
+
+ vehicleJourneysList() {
+ if(this.isReturn()){
+ return this.props.returnVehicleJourneys
+ }
+ else{
+ return this.props.vehicleJourneys
+ }
+ }
+
+ stopPoints() {
+ if(this.isReturn()){
+ return this.props.returnStopPointsList
+ }
+ else{
+ return this.props.stopPointsList
+ }
+ }
+
componentDidMount() {
- this.props.onLoadFirstPage(this.props.filters)
+ this.props.onLoadFirstPage(this.props.filters, this.props.routeUrl)
}
hasFeature(key) {
@@ -89,10 +111,10 @@ export default class VehicleJourneys extends Component {
)}
- { this.props.vehicleJourneys.errors && this.props.vehicleJourneys.errors.length && _.some(this.props.vehicleJourneys, 'errors') && (
+ { this.vehicleJourneysList().errors && this.vehicleJourneysList().errors.length && _.some(this.vehicleJourneysList(), 'errors') && (
Erreur :
- {this.props.vehicleJourneys.map((vj, index) =>
+ {this.vehicleJourneysList().map((vj, index) =>
vj.errors && vj.errors.map((err, i) => {
return (
@@ -104,7 +126,7 @@ export default class VehicleJourneys extends Component {
)}
- 0) ? '' : ' no_result')}>
+
0) ? '' : ' no_result')}>
ID course
@@ -114,7 +136,7 @@ export default class VehicleJourneys extends Component {
Calendriers
{ this.hasFeature('purchase_windows') &&
Calendriers Commerciaux
}
- {this.props.stopPointsList.map((sp, i) =>{
+ {this.stopPoints().map((sp, i) =>{
return (
{this.headerManager.stopPointHeader(sp.object_id)}
@@ -125,17 +147,18 @@ export default class VehicleJourneys extends Component {
- {this.props.vehicleJourneys.map((vj, index) =>
+ {this.vehicleJourneysList().map((vj, index) =>
)}
diff --git a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js
index 2893422f8..f814c0459 100644
--- a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js
@@ -23,6 +23,10 @@ export default class EditVehicleJourney extends Component {
}
}
+ getSelected() {
+ return this.props.vehicleJourney ? [this.props.vehicleJourney] : actions.getSelected(this.props.vehicleJourneys)
+ }
+
render() {
if(this.props.status.isFetching == true) {
return false
@@ -35,10 +39,10 @@ export default class EditVehicleJourney extends Component {
this.props.onOpenEditModal(actions.getSelected(this.props.vehicleJourneys)[0])}
+ onClick={() => this.props.onOpenEditModal(this.getSelected()[0])}
>
diff --git a/app/javascript/vehicle_journeys/containers/VehicleJourneysList.js b/app/javascript/vehicle_journeys/containers/VehicleJourneysList.js
index 38ab9f6d3..76d1c3a78 100644
--- a/app/javascript/vehicle_journeys/containers/VehicleJourneysList.js
+++ b/app/javascript/vehicle_journeys/containers/VehicleJourneysList.js
@@ -6,17 +6,19 @@ const mapStateToProps = (state) => {
return {
editMode: state.editMode,
vehicleJourneys: state.vehicleJourneys,
+ returnVehicleJourneys: state.returnVehicleJourneys,
status: state.status,
filters: state.filters,
- stopPointsList: state.stopPointsList
+ stopPointsList: state.stopPointsList,
+ returnStopPointsList: state.returnStopPointsList
}
}
const mapDispatchToProps = (dispatch) => {
return {
- onLoadFirstPage: (filters) =>{
+ onLoadFirstPage: (filters, routeUrl) =>{
dispatch(actions.fetchingApi())
- actions.fetchVehicleJourneys(dispatch, undefined, undefined, filters.queryString)
+ actions.fetchVehicleJourneys(dispatch, undefined, undefined, filters.queryString, routeUrl)
},
onUpdateTime: (e, subIndex, index, timeUnit, isDeparture, isArrivalsToggled) => {
dispatch(actions.updateTime(e.target.value, subIndex, index, timeUnit, isDeparture, isArrivalsToggled))
diff --git a/app/javascript/vehicle_journeys/containers/tools/EditVehicleJourney.js b/app/javascript/vehicle_journeys/containers/tools/EditVehicleJourney.js
index c2eabcc10..a851b6e7d 100644
--- a/app/javascript/vehicle_journeys/containers/tools/EditVehicleJourney.js
+++ b/app/javascript/vehicle_journeys/containers/tools/EditVehicleJourney.js
@@ -18,6 +18,7 @@ const mapDispatchToProps = (dispatch) => {
dispatch(actions.closeModal())
},
onOpenEditModal: (vj) =>{
+ console.log({vj})
dispatch(actions.openEditModal(vj))
},
onEditVehicleJourney: (data, selectedCompany) =>{
diff --git a/app/javascript/vehicle_journeys/reducers/index.js b/app/javascript/vehicle_journeys/reducers/index.js
index 1963f7c6d..95ac9c7e1 100644
--- a/app/javascript/vehicle_journeys/reducers/index.js
+++ b/app/javascript/vehicle_journeys/reducers/index.js
@@ -1,5 +1,6 @@
import { combineReducers } from 'redux'
import vehicleJourneys from './vehicleJourneys'
+import returnVehicleJourneys from './returnVehicleJourneys'
import pagination from './pagination'
import modal from './modal'
import status from './status'
@@ -11,12 +12,14 @@ import custom_fields from './custom_fields'
const vehicleJourneysApp = combineReducers({
vehicleJourneys,
+ returnVehicleJourneys,
pagination,
modal,
status,
filters,
editMode,
stopPointsList,
+ returnStopPointsList: stopPointsList,
missions,
custom_fields
})
diff --git a/app/javascript/vehicle_journeys/reducers/returnVehicleJourneys.js b/app/javascript/vehicle_journeys/reducers/returnVehicleJourneys.js
new file mode 100644
index 000000000..db3c71d17
--- /dev/null
+++ b/app/javascript/vehicle_journeys/reducers/returnVehicleJourneys.js
@@ -0,0 +1,11 @@
+import _ from 'lodash'
+import actions from '../actions'
+
+export default function returnVehicleJourneys(state = [], action) {
+ switch (action.type) {
+ case 'RECEIVE_RETURN_VEHICLE_JOURNEYS':
+ return [...action.json]
+ default:
+ return state
+ }
+}
diff --git a/app/models/chouette/journey_pattern.rb b/app/models/chouette/journey_pattern.rb
index 55faaf997..a81f4e9ce 100644
--- a/app/models/chouette/journey_pattern.rb
+++ b/app/models/chouette/journey_pattern.rb
@@ -160,12 +160,13 @@ module Chouette
def full_schedule?
full = true
- stop_points.inject(nil) do |start, finish|
+ stop_points.order(:position).inject(nil) do |start, finish|
next finish unless start.present?
costs = costs_between(start, finish)
full = false unless costs.present?
full = false unless costs[:distance] && costs[:distance] > 0
full = false unless costs[:time] && costs[:time] > 0
+ p "#{start.stop_area_id}-#{finish.stop_area_id}" unless full
finish
end
full
diff --git a/app/views/vehicle_journeys/index.html.slim b/app/views/vehicle_journeys/index.html.slim
index ce56f9332..caa8450a0 100644
--- a/app/views/vehicle_journeys/index.html.slim
+++ b/app/views/vehicle_journeys/index.html.slim
@@ -17,6 +17,7 @@
= javascript_tag do
| window.route_id = #{params[:route_id]};
| window.stopPoints = #{(@stop_points_list.to_json).html_safe};
+ | window.returnStopPoints = #{(@return_stop_points_list.to_json).html_safe};
| window.jpOrigin = #{(@jp_origin.present? ? @jp_origin.attributes.update({full_schedule: @jp_origin.full_schedule?}).to_json : "null").html_safe};
| window.jpOriginStopPoints = #{(@jp_origin_stop_points.to_json).html_safe};
| window.transportMode = #{(@transport_mode.to_json).html_safe};
@@ -30,4 +31,9 @@
| window.custom_fields = #{(@custom_fields.to_json).html_safe};
| window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe};
+- if has_feature?(:vehicle_journeys_return_route)
+ = javascript_tag do
+ | window.returnRouteUrl = "#{(@route.opposite_route && url_for([@referential, @route.line, @route.opposite_route, :vehicle_journeys]) || "").html_safe}";
+
+
= javascript_pack_tag 'vehicle_journeys/index.js'
--
cgit v1.2.3
From f78b950171da76c9306a4bf927ca8e83308ce262 Mon Sep 17 00:00:00 2001
From: Zog
Date: Thu, 1 Feb 2018 10:37:44 +0100
Subject: :fire: log
---
app/javascript/vehicle_journeys/containers/tools/EditVehicleJourney.js | 1 -
app/models/chouette/journey_pattern.rb | 1 -
2 files changed, 2 deletions(-)
diff --git a/app/javascript/vehicle_journeys/containers/tools/EditVehicleJourney.js b/app/javascript/vehicle_journeys/containers/tools/EditVehicleJourney.js
index a851b6e7d..c2eabcc10 100644
--- a/app/javascript/vehicle_journeys/containers/tools/EditVehicleJourney.js
+++ b/app/javascript/vehicle_journeys/containers/tools/EditVehicleJourney.js
@@ -18,7 +18,6 @@ const mapDispatchToProps = (dispatch) => {
dispatch(actions.closeModal())
},
onOpenEditModal: (vj) =>{
- console.log({vj})
dispatch(actions.openEditModal(vj))
},
onEditVehicleJourney: (data, selectedCompany) =>{
diff --git a/app/models/chouette/journey_pattern.rb b/app/models/chouette/journey_pattern.rb
index a81f4e9ce..aa9fdb810 100644
--- a/app/models/chouette/journey_pattern.rb
+++ b/app/models/chouette/journey_pattern.rb
@@ -166,7 +166,6 @@ module Chouette
full = false unless costs.present?
full = false unless costs[:distance] && costs[:distance] > 0
full = false unless costs[:time] && costs[:time] > 0
- p "#{start.stop_area_id}-#{finish.stop_area_id}" unless full
finish
end
full
--
cgit v1.2.3
From 3f538cbd57d42b47f7c19e22d3a7bedc980a69ca Mon Sep 17 00:00:00 2001
From: Alban Peignier
Date: Thu, 1 Feb 2018 11:00:52 +0100
Subject: Change path in capistrano default_env to make bundle available for
webpacker compiler. Refs #5803
---
config/deploy.rb | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/config/deploy.rb b/config/deploy.rb
index d541f2581..1ea1613de 100644
--- a/config/deploy.rb
+++ b/config/deploy.rb
@@ -7,10 +7,12 @@ set :scm, :git
set :repository, "git@github.com:AF83/stif-boiv.git"
set :deploy_to, "/var/www/stif-boiv"
set :use_sudo, false
+set :ruby_version, "2.3.0"
default_run_options[:pty] = true
set :group_writable, true
-set :bundle_cmd, "/var/lib/gems/2.3.0/bin/bundle"
-set :rake, "#{bundle_cmd} exec rake"
+set :bundle_cmd, "/var/lib/gems/#{ruby_version}/bin/bundle"
+oset :rake, "#{bundle_cmd} exec rake"
+set :default_env, { path: "/var/lib/gems/#{ruby_version}/bin:$PATH" }
set :keep_releases, -> { fetch(:kept_releases, 5) }
after "deploy:restart", "deploy:cleanup"
@@ -29,7 +31,7 @@ require 'whenever/capistrano'
#after 'deploy:finalize_update', 'npm:install'
# Whenever
-set :whenever_variables, ->{ "'environment=#{fetch :whenever_environment}&bundle_command=bin/bundle exec&additionnal_path=/var/lib/gems/2.3.0/bin'" } # invoke bin/bundle to use 'correct' ruby environment
+set :whenever_variables, ->{ "'environment=#{fetch :whenever_environment}&bundle_command=bin/bundle exec&additionnal_path=/var/lib/gems/#{ruby_version}/bin'" } # invoke bin/bundle to use 'correct' ruby environment
set :whenever_command, "sudo /usr/local/sbin/whenever-sudo" # use sudo to change www-data crontab
set :whenever_user, "www-data" # use www-data crontab
--
cgit v1.2.3
From 38cadb07b47648c3d9ea2424a4b62229d0f468d3 Mon Sep 17 00:00:00 2001
From: Alban Peignier
Date: Thu, 1 Feb 2018 11:02:46 +0100
Subject: Add env variable to disable ci:jest if needed. Refs #5802
---
lib/tasks/ci.rake | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/tasks/ci.rake b/lib/tasks/ci.rake
index 3e73b7a3b..82619d04b 100644
--- a/lib/tasks/ci.rake
+++ b/lib/tasks/ci.rake
@@ -38,7 +38,7 @@ namespace :ci do
end
task :jest => "ci:assets" do
- sh "node_modules/.bin/jest"
+ sh "node_modules/.bin/jest" unless ["CHOUETTE_JEST_DISABLED"]
end
desc "Deploy after CI"
--
cgit v1.2.3
From 5c45c5d9ab4a7a7d64c4a73c7908861824fd8ee4 Mon Sep 17 00:00:00 2001
From: Alban Peignier
Date: Thu, 1 Feb 2018 11:13:17 +0100
Subject: Fixes typo in deploy.rb. Refs #5803
---
config/deploy.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config/deploy.rb b/config/deploy.rb
index 1ea1613de..6a5d07d79 100644
--- a/config/deploy.rb
+++ b/config/deploy.rb
@@ -11,7 +11,7 @@ set :ruby_version, "2.3.0"
default_run_options[:pty] = true
set :group_writable, true
set :bundle_cmd, "/var/lib/gems/#{ruby_version}/bin/bundle"
-oset :rake, "#{bundle_cmd} exec rake"
+set :rake, "#{bundle_cmd} exec rake"
set :default_env, { path: "/var/lib/gems/#{ruby_version}/bin:$PATH" }
set :keep_releases, -> { fetch(:kept_releases, 5) }
--
cgit v1.2.3
From 387450bd2a929d4a8ae6cc77182859f8c8587786 Mon Sep 17 00:00:00 2001
From: Luc Donnet
Date: Thu, 1 Feb 2018 11:31:56 +0100
Subject: Fix yarn installation with no production for ci and force yarn
install before jest launch du to webpacker bug
---
lib/tasks/ci.rake | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/tasks/ci.rake b/lib/tasks/ci.rake
index 82619d04b..13d7b8d73 100644
--- a/lib/tasks/ci.rake
+++ b/lib/tasks/ci.rake
@@ -3,7 +3,7 @@ namespace :ci do
task :setup do
cp "config/database/jenkins.yml", "config/database.yml"
sh "RAILS_ENV=test rake db:drop db:create db:migrate"
- sh "yarn --production --no-progress install"
+ sh "yarn --no-progress install"
end
def git_branch
@@ -38,6 +38,7 @@ namespace :ci do
end
task :jest => "ci:assets" do
+ sh "yarn --no-progress install" # Hack to force install jest after webpack
sh "node_modules/.bin/jest" unless ["CHOUETTE_JEST_DISABLED"]
end
--
cgit v1.2.3
From f9a4d3b6f0360071e8b15d18345a4b9bc279d12c Mon Sep 17 00:00:00 2001
From: Alban Peignier
Date: Thu, 1 Feb 2018 11:35:32 +0100
Subject: Use default_environment (for capistrano 2). Refs #5803
---
config/deploy.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config/deploy.rb b/config/deploy.rb
index 6a5d07d79..a67fbcd13 100644
--- a/config/deploy.rb
+++ b/config/deploy.rb
@@ -12,7 +12,7 @@ default_run_options[:pty] = true
set :group_writable, true
set :bundle_cmd, "/var/lib/gems/#{ruby_version}/bin/bundle"
set :rake, "#{bundle_cmd} exec rake"
-set :default_env, { path: "/var/lib/gems/#{ruby_version}/bin:$PATH" }
+set :default_environment, { path: "/var/lib/gems/#{ruby_version}/bin:$PATH" }
set :keep_releases, -> { fetch(:kept_releases, 5) }
after "deploy:restart", "deploy:cleanup"
--
cgit v1.2.3
From 4329ed3aa9d64ecbed44d1b70f9101a8f4653748 Mon Sep 17 00:00:00 2001
From: Alban Peignier
Date: Thu, 1 Feb 2018 13:11:55 +0100
Subject: Use upcase PATH variable in :default_environment. Refs #5803
---
config/deploy.rb | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/config/deploy.rb b/config/deploy.rb
index a67fbcd13..7e385cebc 100644
--- a/config/deploy.rb
+++ b/config/deploy.rb
@@ -14,6 +14,10 @@ set :bundle_cmd, "/var/lib/gems/#{ruby_version}/bin/bundle"
set :rake, "#{bundle_cmd} exec rake"
set :default_environment, { path: "/var/lib/gems/#{ruby_version}/bin:$PATH" }
+set :default_environment, {
+ 'PATH' => "/var/lib/gems/#{ruby_version}/bin:$PATH"
+}
+
set :keep_releases, -> { fetch(:kept_releases, 5) }
after "deploy:restart", "deploy:cleanup"
--
cgit v1.2.3
From 3577ea93c9d0e4475da9cef47c86d2880715909c Mon Sep 17 00:00:00 2001
From: Alban Peignier
Date: Thu, 1 Feb 2018 13:12:24 +0100
Subject: Remove first :default_environment. Refs #5803
---
config/deploy.rb | 2 --
1 file changed, 2 deletions(-)
diff --git a/config/deploy.rb b/config/deploy.rb
index 7e385cebc..9be023adc 100644
--- a/config/deploy.rb
+++ b/config/deploy.rb
@@ -12,8 +12,6 @@ default_run_options[:pty] = true
set :group_writable, true
set :bundle_cmd, "/var/lib/gems/#{ruby_version}/bin/bundle"
set :rake, "#{bundle_cmd} exec rake"
-set :default_environment, { path: "/var/lib/gems/#{ruby_version}/bin:$PATH" }
-
set :default_environment, {
'PATH' => "/var/lib/gems/#{ruby_version}/bin:$PATH"
}
--
cgit v1.2.3
From 5a43a7f610395a6c4a09163959c4987c7a61bd28 Mon Sep 17 00:00:00 2001
From: Alban Peignier
Date: Thu, 1 Feb 2018 13:39:00 +0100
Subject: Revert webpacker to 3.0.2. Refs #5807
---
Gemfile | 3 ++-
Gemfile.lock | 6 +++---
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/Gemfile b/Gemfile
index c378820b3..e1943e659 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,3 +1,4 @@
+# coding: utf-8
source 'https://rubygems.org'
# Use https for github
@@ -15,7 +16,7 @@ gem 'uglifier', '~> 2.7.2'
gem 'coffee-rails', '~> 4.0.0'
# Webpacker
-gem 'webpacker', '~> 3.0'
+gem 'webpacker', '3.0.2'
# Use jquery as the JavaScript library
gem 'jquery-rails', '~> 3.1.4' # Update to v4 for Rails 4.2
diff --git a/Gemfile.lock b/Gemfile.lock
index ba86a911f..3a2314857 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -562,7 +562,7 @@ GEM
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff
- webpacker (3.2.1)
+ webpacker (3.0.2)
activesupport (>= 4.2)
rack-proxy (>= 0.6.1)
railties (>= 4.2)
@@ -698,10 +698,10 @@ DEPENDENCIES
transpec
uglifier (~> 2.7.2)
webmock
- webpacker (~> 3.0)
+ webpacker (= 3.0.2)
whenever!
will_paginate
will_paginate-bootstrap
BUNDLED WITH
- 1.16.0
+ 1.16.1
--
cgit v1.2.3
From 6fb07ac6da9c98a8643c40fbe38360153100be83 Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 29 Jan 2018 16:38:50 +0100
Subject: Refs #5762; Make coordinates optional on stop areas
---
app/models/chouette/stop_area.rb | 4 +---
app/views/stop_areas/_form.html.slim | 2 +-
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb
index d7d5c2eb2..c6feaf940 100644
--- a/app/models/chouette/stop_area.rb
+++ b/app/models/chouette/stop_area.rb
@@ -106,9 +106,7 @@ module Chouette
end
end
- def local_id
- id.to_s
- end
+ alias_method :local_id, :user_objectid
def children_in_depth
return [] if self.children.empty?
diff --git a/app/views/stop_areas/_form.html.slim b/app/views/stop_areas/_form.html.slim
index aa156f7bd..1bc3e77ef 100644
--- a/app/views/stop_areas/_form.html.slim
+++ b/app/views/stop_areas/_form.html.slim
@@ -23,7 +23,7 @@
- unless @stop_area.projection.blank? or @stop_area.projection_type_label.empty?
= f.input :projection_xy, :label => t("activerecord.attributes.stop_area.projection_xy", :projection => @referential.projection_type_label), :input_html => {:title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.projection_xy")}
- = f.input :coordinates, :input_html => {:title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.coordinates")}, required: true
+ = f.input :coordinates, :input_html => {:title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.coordinates")}
= f.input :street_name
= f.input :zip_code, :input_html => {:title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.zip_code")}
= f.input :city_name, required: format_restriction_for_locales(@referential) == '.hub', :input_html => {:title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.city_name")}
--
cgit v1.2.3
From ec5a557df43d16294f55a1c11e9a581b55126695 Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 29 Jan 2018 16:46:08 +0100
Subject: Refs #5762; Disable default position for stops
---
app/controllers/stop_areas_controller.rb | 2 --
1 file changed, 2 deletions(-)
diff --git a/app/controllers/stop_areas_controller.rb b/app/controllers/stop_areas_controller.rb
index 8d424b8d1..076de922c 100644
--- a/app/controllers/stop_areas_controller.rb
+++ b/app/controllers/stop_areas_controller.rb
@@ -95,7 +95,6 @@ class StopAreasController < ChouetteController
def edit
authorize stop_area
edit! do
- stop_area.position ||= stop_area.default_position
map.editable = true
end
end
@@ -107,7 +106,6 @@ class StopAreasController < ChouetteController
def update
authorize stop_area
- stop_area.position ||= stop_area.default_position
map.editable = true
update!
--
cgit v1.2.3
From 827dd381446e850330d5a85d13979e40d06fe186 Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 29 Jan 2018 16:56:06 +0100
Subject: Refs #5762; Update JS to accomodate stops without location
---
app/javascript/helpers/routes_map.coffee | 28 ++++++++++++++++------------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/app/javascript/helpers/routes_map.coffee b/app/javascript/helpers/routes_map.coffee
index 85def1390..6834406fc 100644
--- a/app/javascript/helpers/routes_map.coffee
+++ b/app/javascript/helpers/routes_map.coffee
@@ -30,20 +30,24 @@ class RoutesMap
geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(stops[stops.length - 1].longitude), parseFloat(stops[stops.length - 1].latitude)]))
})
]
+
+ prevStop = null
stops.forEach (stop, i) =>
- if i < stops.length - 1
- geoColLns.push new ol.Feature
- geometry: new ol.geom.LineString([
- ol.proj.fromLonLat([parseFloat(stops[i].longitude), parseFloat(stops[i].latitude)]),
- ol.proj.fromLonLat([parseFloat(stops[i + 1].longitude), parseFloat(stops[i + 1].latitude)])
- ])
+ if stop.longitude && stop.latitude
+ if prevStop
+ geoColLns.push new ol.Feature
+ geometry: new ol.geom.LineString([
+ ol.proj.fromLonLat([parseFloat(prevStop.longitude), parseFloat(prevStop.latitude)]),
+ ol.proj.fromLonLat([parseFloat(stop.longitude), parseFloat(stop.latitude)])
+ ])
+ prevStop = stop
- geoColPts.push(new ol.Feature({
- geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(stop.longitude), parseFloat(stop.latitude)]))
- }))
- unless @seenStopIds.indexOf(stop.stoparea_id) > 0
- @area.push [parseFloat(stop.longitude), parseFloat(stop.latitude)]
- @seenStopIds.push stop.stoparea_id
+ geoColPts.push(new ol.Feature({
+ geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(stop.longitude), parseFloat(stop.latitude)]))
+ }))
+ unless @seenStopIds.indexOf(stop.stoparea_id) > 0
+ @area.push [parseFloat(stop.longitude), parseFloat(stop.latitude)]
+ @seenStopIds.push stop.stoparea_id
vectorPtsLayer = new ol.layer.Vector({
source: new ol.source.Vector({
--
cgit v1.2.3
From 3c4e0b97d2c2502412817b5c99989f98821fc207 Mon Sep 17 00:00:00 2001
From: Zog
Date: Thu, 1 Feb 2018 13:55:21 +0100
Subject: Fix css
---
app/assets/stylesheets/OpenLayers/custom.sass | 1 -
1 file changed, 1 deletion(-)
diff --git a/app/assets/stylesheets/OpenLayers/custom.sass b/app/assets/stylesheets/OpenLayers/custom.sass
index 5a3612f99..fa874d924 100644
--- a/app/assets/stylesheets/OpenLayers/custom.sass
+++ b/app/assets/stylesheets/OpenLayers/custom.sass
@@ -18,7 +18,6 @@
cursor: pointer
color: $blue
white-space: nowrap
- max-width: 33%
&:hover
background: $orange
--
cgit v1.2.3
From 47520607ee5a91fbba206aff4e72dd25293e1541 Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 29 Jan 2018 16:25:08 +0100
Subject: Refs #5758 @1h; Add localized names to StopAreas
---
Gemfile | 1 +
Gemfile.lock | 3 +++
app/assets/stylesheets/application.sass | 2 ++
app/controllers/stop_areas_controller.rb | 1 +
app/helpers/stop_areas_helper.rb | 6 ++++--
app/models/chouette/stop_area.rb | 7 +++++++
app/views/stop_areas/_form.html.slim | 6 +++++-
app/views/stop_areas/show.html.slim | 6 ++++--
config/initializers/countries.rb | 3 +++
db/migrate/20180129141656_add_localized_names_to_stop_areas.rb | 5 +++++
db/schema.rb | 1 +
11 files changed, 36 insertions(+), 5 deletions(-)
create mode 100644 config/initializers/countries.rb
create mode 100644 db/migrate/20180129141656_add_localized_names_to_stop_areas.rb
diff --git a/Gemfile b/Gemfile
index e1943e659..bb1a42df0 100644
--- a/Gemfile
+++ b/Gemfile
@@ -102,6 +102,7 @@ gem 'font-awesome-sass', '~> 4.7'
gem 'will_paginate-bootstrap'
gem 'gretel'
gem 'country_select'
+gem 'flag-icons-rails'
# Format Output
gem 'json'
diff --git a/Gemfile.lock b/Gemfile.lock
index 3a2314857..ffa63b535 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -236,6 +236,8 @@ GEM
ffi (1.9.18)
ffi-geos (1.2.0)
ffi (>= 1.0.0)
+ flag-icons-rails (2.5.0)
+ sass (~> 3.2)
font-awesome-sass (4.7.0)
sass (>= 3.2)
formtastic (3.1.5)
@@ -625,6 +627,7 @@ DEPENDENCIES
faraday (~> 0.9.1)
faraday_middleware (~> 0.9.1)
ffaker (~> 2.1.0)
+ flag-icons-rails
font-awesome-sass (~> 4.7)
formtastic (= 3.1.5)
georuby (= 2.3.0)
diff --git a/app/assets/stylesheets/application.sass b/app/assets/stylesheets/application.sass
index 50f8b64cb..3f8467efe 100644
--- a/app/assets/stylesheets/application.sass
+++ b/app/assets/stylesheets/application.sass
@@ -19,3 +19,5 @@
@import 'modules/vj_collection'
@import 'modules/timetables'
@import 'modules/import_messages'
+
+@import 'flag-icon'
diff --git a/app/controllers/stop_areas_controller.rb b/app/controllers/stop_areas_controller.rb
index 076de922c..41a1a8c6d 100644
--- a/app/controllers/stop_areas_controller.rb
+++ b/app/controllers/stop_areas_controller.rb
@@ -202,6 +202,7 @@ class StopAreasController < ChouetteController
:waiting_time,
:zip_code,
:kind,
+ localized_names: Chouette::StopArea::AVAILABLE_LOCALIZATIONS
)
end
diff --git a/app/helpers/stop_areas_helper.rb b/app/helpers/stop_areas_helper.rb
index 3e04fac7d..05ae042f5 100644
--- a/app/helpers/stop_areas_helper.rb
+++ b/app/helpers/stop_areas_helper.rb
@@ -11,6 +11,10 @@ module StopAreasHelper
( " " + " " + name + " " + localization + " ").html_safe
end
+ def label_for_country country, txt=nil
+ "#{txt} ".html_safe
+ end
+
def genealogical_title
return t("stop_areas.genealogical.genealogical_routing") if @stop_area.stop_area_type == 'itl'
t("stop_areas.genealogical.genealogical")
@@ -33,12 +37,10 @@ module StopAreasHelper
@stop_area.stop_area_type == 'stop_place' || @stop_area.stop_area_type == 'commercial_stop_point'
end
-
def pair_key(access_link)
"#{access_link.access_point.id}-#{access_link.stop_area.id}"
end
-
def geo_data(sa, sar)
if sa.long_lat_type.nil?
content_tag :span, '-'
diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb
index c6feaf940..bb8747faa 100644
--- a/app/models/chouette/stop_area.rb
+++ b/app/models/chouette/stop_area.rb
@@ -12,6 +12,8 @@ module Chouette
enumerize :area_type, in: Chouette::AreaType::ALL
enumerize :kind, in: %i(commercial non_commercial)
+ AVAILABLE_LOCALIZATIONS = %i(gb nl de fr it es)
+
with_options dependent: :destroy do |assoc|
assoc.has_many :stop_points
assoc.has_many :access_points
@@ -50,6 +52,11 @@ module Chouette
:nearest_topic_name, :comment, :long_lat_type, :zip_code, :city_name, :url, :time_zone]
end
+ def localized_names
+ val = read_attribute(:localized_names) || {}
+ Hash[*AVAILABLE_LOCALIZATIONS.map{|k| [k, val[k.to_s]]}.flatten]
+ end
+
def parent_area_type_must_be_greater
return unless self.parent
diff --git a/app/views/stop_areas/_form.html.slim b/app/views/stop_areas/_form.html.slim
index 1bc3e77ef..c2b9a7f4f 100644
--- a/app/views/stop_areas/_form.html.slim
+++ b/app/views/stop_areas/_form.html.slim
@@ -6,8 +6,12 @@
/= @map.to_html
= f.input :id, as: :hidden
= f.input :name, :input_html => {:title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.name")}
+ .form-group
+ .col-sm-3.col-xs-5
+ .col-sm-9.col-xs-7
+ - f.object.localized_names.each do |k, v|
+ .col-md-6= f.input "localized_names[#{k}]", input_html: {value: v}, label: label_for_country(k)
= f.input :kind, as: :radio_buttons, checked: @stop_area.kind, :input_html => {:disabled => !@stop_area.new_record?}, :include_blank => false, item_wrapper_class: 'radio-inline', wrapper: :horizontal_form, disabled: !@stop_area.new_record?
-
.slave data-master="[name='stop_area[kind]']" data-value="commercial"
= f.input :parent_id, as: :select, :collection => [f.object.parent_id], input_html: { data: { select2_ajax: 'true', url: autocomplete_stop_area_referential_stop_areas_path(@stop_area_referential), initvalue: {id: f.object.parent_id, text: f.object.parent.try(:full_name)}}}
- %i(non_commercial commercial).each do |kind|
diff --git a/app/views/stop_areas/show.html.slim b/app/views/stop_areas/show.html.slim
index b0896c1e0..67f309cef 100644
--- a/app/views/stop_areas/show.html.slim
+++ b/app/views/stop_areas/show.html.slim
@@ -7,10 +7,12 @@
.row
.col-lg-6.col-md-6.col-sm-12.col-xs-12
- attributes = { t('id_reflex') => @stop_area.get_objectid.short_id }
+ - @stop_area.localized_names.each do |k, v|
+ - attributes.merge!({label_for_country(k, @stop_area.human_attribute_name(:name)) => v }) if v.present?
- attributes.merge!({ @stop_area.human_attribute_name(:parent) => @stop_area.parent ? link_to(@stop_area.parent.name, stop_area_referential_stop_area_path(@stop_area_referential, @stop_area.parent)) : "-" }) if @stop_area.commercial?
- attributes.merge!({ @stop_area.human_attribute_name(:stop_area_type) => Chouette::AreaType.find(@stop_area.area_type).try(:label),
- @stop_area.human_attribute_name(:registration_number) => @stop_area.registration_number,
- })
+ @stop_area.human_attribute_name(:registration_number) => @stop_area.registration_number
+ })
- attributes.merge!(@stop_area.human_attribute_name(:waiting_time) => @stop_area.waiting_time_text) if has_feature?(:stop_area_waiting_time)
- attributes.merge!({ "Coordonnées" => geo_data(@stop_area, @stop_area_referential),
@stop_area.human_attribute_name(:zip_code) => @stop_area.zip_code,
diff --git a/config/initializers/countries.rb b/config/initializers/countries.rb
new file mode 100644
index 000000000..7f2b5c9db
--- /dev/null
+++ b/config/initializers/countries.rb
@@ -0,0 +1,3 @@
+ISO3166.configure do |config|
+ config.locales = (I18n.available_locales + Chouette::StopArea::AVAILABLE_LOCALIZATIONS).uniq
+end
diff --git a/db/migrate/20180129141656_add_localized_names_to_stop_areas.rb b/db/migrate/20180129141656_add_localized_names_to_stop_areas.rb
new file mode 100644
index 000000000..320ce739a
--- /dev/null
+++ b/db/migrate/20180129141656_add_localized_names_to_stop_areas.rb
@@ -0,0 +1,5 @@
+class AddLocalizedNamesToStopAreas < ActiveRecord::Migration
+ def change
+ add_column :stop_areas, :localized_names, :jsonb
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index b696cfc98..51cb44d17 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -791,6 +791,7 @@ ActiveRecord::Schema.define(version: 20180126134944) do
t.string "stif_type"
t.integer "waiting_time"
t.string "kind"
+ t.jsonb "localized_names"
end
add_index "stop_areas", ["name"], name: "index_stop_areas_on_name", using: :btree
--
cgit v1.2.3
From 9db4ffe5d56bd95444b03d62d0a138822424c4f2 Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 29 Jan 2018 20:48:04 +0100
Subject: Refs #5758; Add corresponding feature `stop_area_localized_names`
---
app/views/stop_areas/_form.html.slim | 7 +++++++
app/views/stop_areas/show.html.slim | 7 +++++--
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/app/views/stop_areas/_form.html.slim b/app/views/stop_areas/_form.html.slim
index c2b9a7f4f..67af39dc6 100644
--- a/app/views/stop_areas/_form.html.slim
+++ b/app/views/stop_areas/_form.html.slim
@@ -6,6 +6,13 @@
/= @map.to_html
= f.input :id, as: :hidden
= f.input :name, :input_html => {:title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.name")}
+ - if has_feature?(:stop_area_localized_names)
+ .form-group
+ .col-sm-3.col-xs-5
+ .col-sm-9.col-xs-7
+ - f.object.localized_names.each do |k, v|
+ .col-md-6= f.input "localized_names[#{k}]", input_html: {value: v}, label: label_for_country(k)
+
.form-group
.col-sm-3.col-xs-5
.col-sm-9.col-xs-7
diff --git a/app/views/stop_areas/show.html.slim b/app/views/stop_areas/show.html.slim
index 67f309cef..300d714e8 100644
--- a/app/views/stop_areas/show.html.slim
+++ b/app/views/stop_areas/show.html.slim
@@ -7,12 +7,15 @@
.row
.col-lg-6.col-md-6.col-sm-12.col-xs-12
- attributes = { t('id_reflex') => @stop_area.get_objectid.short_id }
- - @stop_area.localized_names.each do |k, v|
- - attributes.merge!({label_for_country(k, @stop_area.human_attribute_name(:name)) => v }) if v.present?
+
+ - if has_feature?(:stop_area_localized_names)
+ - @stop_area.localized_names.each do |k, v|
+ - attributes.merge!({label_for_country(k, @stop_area.human_attribute_name(:name)) => v }) if v.present?
- attributes.merge!({ @stop_area.human_attribute_name(:parent) => @stop_area.parent ? link_to(@stop_area.parent.name, stop_area_referential_stop_area_path(@stop_area_referential, @stop_area.parent)) : "-" }) if @stop_area.commercial?
- attributes.merge!({ @stop_area.human_attribute_name(:stop_area_type) => Chouette::AreaType.find(@stop_area.area_type).try(:label),
@stop_area.human_attribute_name(:registration_number) => @stop_area.registration_number
})
+
- attributes.merge!(@stop_area.human_attribute_name(:waiting_time) => @stop_area.waiting_time_text) if has_feature?(:stop_area_waiting_time)
- attributes.merge!({ "Coordonnées" => geo_data(@stop_area, @stop_area_referential),
@stop_area.human_attribute_name(:zip_code) => @stop_area.zip_code,
--
cgit v1.2.3
From ea8c633d45b97e41894ea8c691a6b3ae434eb770 Mon Sep 17 00:00:00 2001
From: Teddy Wing
Date: Thu, 1 Feb 2018 15:20:43 +0100
Subject: ReferentialVehicleJourneys#index: Fix `nil` error on `stop_area_ids`
This wasn't checking that `params[:q]` was present before trying to
access `[:stop_area_ids]`, and thus caused an error on the page when no
filters were applied.
Refs #5809
---
app/controllers/referential_vehicle_journeys_controller.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/controllers/referential_vehicle_journeys_controller.rb b/app/controllers/referential_vehicle_journeys_controller.rb
index a199157dd..2ce28a5cc 100644
--- a/app/controllers/referential_vehicle_journeys_controller.rb
+++ b/app/controllers/referential_vehicle_journeys_controller.rb
@@ -23,7 +23,7 @@ class ReferentialVehicleJourneysController < ChouetteController
@vehicle_journeys ||= @q.result.order(:published_journey_name).includes(:vehicle_journey_at_stops).paginate page: params[:page], per_page: params[:per_page] || 10
@all_companies = Chouette::Company.where("id IN (#{@referential.vehicle_journeys.select(:company_id).to_sql})").distinct
@all_stop_areas = Chouette::StopArea.where("id IN (#{@referential.vehicle_journeys.joins(:stop_areas).select("stop_areas.id").to_sql})").distinct
- stop_area_ids = params[:q][:stop_area_ids].select(&:present?)
+ stop_area_ids = params[:q].try(:[], :stop_area_ids).try(:select, &:present?)
@filters_stop_areas = Chouette::StopArea.find(stop_area_ids) if stop_area_ids.present? && stop_area_ids.size <= 2
end
--
cgit v1.2.3
From 7120ef13351868898d9c01e7f9d2264a04d4136a Mon Sep 17 00:00:00 2001
From: Zog
Date: Thu, 1 Feb 2018 15:27:33 +0100
Subject: Fix broken TimeTableDecorator
---
app/decorators/time_table_decorator.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/decorators/time_table_decorator.rb b/app/decorators/time_table_decorator.rb
index 9a56fc2ee..95b1fd959 100644
--- a/app/decorators/time_table_decorator.rb
+++ b/app/decorators/time_table_decorator.rb
@@ -11,7 +11,7 @@ class TimeTableDecorator < AF83::Decorator
end
instance_decorator.edit_action_link do |l|
- l.href { [context[:referential], object] }
+ l.href { [:edit, context[:referential], object] }
end
instance_decorator.action_link if: ->{ object.calendar }, secondary: true do |l|
--
cgit v1.2.3
From 505e3b3e9cc69c79f9ce4359916449a06e082bea Mon Sep 17 00:00:00 2001
From: Teddy Wing
Date: Wed, 31 Jan 2018 19:40:59 +0100
Subject: ReferentialVehicleJourneys#index: Add 'line' filter
Filter vehicle journeys by their associated route's line.
The `with_line_id` scope is modeled on `with_stop_area_ids`.
The HTML filter is modeled on the line filter from
`app/views/workbenches/_filters.html.slim`.
Refs #5576
---
.../referential_vehicle_journeys_controller.rb | 1 +
app/models/chouette/vehicle_journey.rb | 11 ++++++++++-
.../referential_vehicle_journeys/_filters.html.slim | 17 +++++++++++++++++
3 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/app/controllers/referential_vehicle_journeys_controller.rb b/app/controllers/referential_vehicle_journeys_controller.rb
index 2ce28a5cc..935b52d93 100644
--- a/app/controllers/referential_vehicle_journeys_controller.rb
+++ b/app/controllers/referential_vehicle_journeys_controller.rb
@@ -16,6 +16,7 @@ class ReferentialVehicleJourneysController < ChouetteController
def collection
@q ||= end_of_association_chain
+ @q = @q.with_line_id(params[:q][:line_id]) if params[:q] && params[:q][:line_id]
@q = @q.with_stop_area_ids(params[:q][:stop_area_ids]) if params[:q] && params[:q][:stop_area_ids]
@q = ransack_period_range(scope: @q, error_message: t('vehicle_journeys.errors.purchase_window'), query: :in_purchase_window, prefix: :purchase_window)
@q = ransack_period_range(scope: @q, error_message: t('vehicle_journeys.errors.time_table'), query: :with_matching_timetable, prefix: :time_table)
diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb
index 1756a7098..918ca07aa 100644
--- a/app/models/chouette/vehicle_journey.rb
+++ b/app/models/chouette/vehicle_journey.rb
@@ -52,6 +52,10 @@ module Chouette
end
}
+ scope :with_line_id, ->(id) {
+ joins(:route).where(routes: { line_id: id })
+ }
+
scope :in_purchase_window, ->(range){
purchase_windows = Chouette::PurchaseWindow.overlap_dates(range)
sql = purchase_windows.joins(:vehicle_journeys).select('vehicle_journeys.id').uniq.to_sql
@@ -59,8 +63,9 @@ module Chouette
}
# We need this for the ransack object in the filters
- ransacker :stop_area_ids
+ ransacker :line_id
ransacker :purchase_window_date_gt
+ ransacker :stop_area_ids
# returns VehicleJourneys with at least 1 day in their time_tables
# included in the given range
@@ -375,5 +380,9 @@ module Chouette
')
.where('"time_tables_vehicle_journeys"."vehicle_journey_id" IS NULL')
end
+
+ def self.lines
+ Chouette::Line.joins(routes: :vehicle_journeys).distinct
+ end
end
end
diff --git a/app/views/referential_vehicle_journeys/_filters.html.slim b/app/views/referential_vehicle_journeys/_filters.html.slim
index bfb5b77dd..838150d2c 100644
--- a/app/views/referential_vehicle_journeys/_filters.html.slim
+++ b/app/views/referential_vehicle_journeys/_filters.html.slim
@@ -15,6 +15,23 @@
= f.input :company_id_eq_any, collection: @all_companies.select(:id, :name).order(name: :asc), as: :check_boxes, label: false, label_method: lambda{|l| ("" + l.name + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}
- else
= f.input :company_id_eq_any, collection: [[I18n.t('companies.search_no_results_for_filter'), nil]], as: :check_boxes, label: false, disabled: true, required: false, wrapper_html: { class: 'checkbox_list disabled'}
+
+ .form-group.togglable
+ = f.label Chouette::Line.model_name.human,
+ required: false,
+ class: 'control-label'
+ .inputs.form-inline.checkbox_list
+ = f.input :line_id,
+ as: :select,
+ collection: @vehicle_journeys.lines,
+ input_html: { \
+ 'data-select2ed': 'true',
+ 'data-select2ed-placeholder': t('referentials.filters.line') \
+ },
+ label: false,
+ label_method: :display_name,
+ wrapper_html: { class: 'select2ed' }
+
.form-group.togglable.name-filter
= f.label Chouette::VehicleJourney.human_attribute_name(:published_journey_name), required: false, class: 'control-label'
.inputs.form-inline.checkbox_list
--
cgit v1.2.3
From 4cf5dc7f1d1f2a0867e288918d08762d2e35c251 Mon Sep 17 00:00:00 2001
From: Teddy Wing
Date: Thu, 1 Feb 2018 10:57:44 +0100
Subject: ReferentialVehicleJourneys#index: Add padding to line filter
Add some padding inside the drop-down so that the filter select box
doesn't run up against the sides of the drop-down.
Refs #5576
---
app/views/referential_vehicle_journeys/_filters.html.slim | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/views/referential_vehicle_journeys/_filters.html.slim b/app/views/referential_vehicle_journeys/_filters.html.slim
index 838150d2c..077c40de7 100644
--- a/app/views/referential_vehicle_journeys/_filters.html.slim
+++ b/app/views/referential_vehicle_journeys/_filters.html.slim
@@ -20,7 +20,7 @@
= f.label Chouette::Line.model_name.human,
required: false,
class: 'control-label'
- .inputs.form-inline.checkbox_list
+ .form-inline.filter_menu
= f.input :line_id,
as: :select,
collection: @vehicle_journeys.lines,
@@ -30,7 +30,7 @@
},
label: false,
label_method: :display_name,
- wrapper_html: { class: 'select2ed' }
+ wrapper_html: { class: 'filter_menu-item select2ed' }
.form-group.togglable.name-filter
= f.label Chouette::VehicleJourney.human_attribute_name(:published_journey_name), required: false, class: 'control-label'
--
cgit v1.2.3
From 0cf9a848266fde870330ceff2bf312d04036a28b Mon Sep 17 00:00:00 2001
From: Teddy Wing
Date: Thu, 1 Feb 2018 11:52:48 +0100
Subject: ReferentialVehicleJourneys#index: Pre-fill line select filter
Pre-fill this box with the value from `params[:q]` so users can see
their selected line after filtering.
For some reason Select2 wants to keep it selected even after clicking
"Effacer". Not sure what that's about, but the HTML `` clearly
doesn't have a `selected` attribute/option.
Refs #5576
---
app/views/referential_vehicle_journeys/_filters.html.slim | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/views/referential_vehicle_journeys/_filters.html.slim b/app/views/referential_vehicle_journeys/_filters.html.slim
index 077c40de7..53084017b 100644
--- a/app/views/referential_vehicle_journeys/_filters.html.slim
+++ b/app/views/referential_vehicle_journeys/_filters.html.slim
@@ -24,6 +24,7 @@
= f.input :line_id,
as: :select,
collection: @vehicle_journeys.lines,
+ selected: params[:q] && params[:q][:line_id],
input_html: { \
'data-select2ed': 'true',
'data-select2ed-placeholder': t('referentials.filters.line') \
--
cgit v1.2.3
From 6a3005bd6194f4f6055ce8f92ca75126b9b0aeb5 Mon Sep 17 00:00:00 2001
From: Teddy Wing
Date: Thu, 1 Feb 2018 11:57:40 +0100
Subject: _select2.sass: Prevent drop-down arrow from overlapping selection
When the text of the current selection was very long, it could extend to
the end of the input, the farthest right:
+-------------------+
| Long text is long |
+-------------------+
The problem is that the arrow indicating you can click on the input to
bring up a drop-down list of options would cover the "g" in "long" in
the above example (well, not exactly because of proportional width
characters, but you get the idea).
Fix the overlap by overriding Bootstrap Select2's style from
app/assets/stylesheets/vendor/select2-bootstrap.css:306-309, which looks
like this:
.select2-container--bootstrap .select2-selection--single .select2-selection__rendered {
color: #555555;
padding: 0;
}
Obviously, the padding is wrong. We need some right padding to give room
for the arrow. What are you thinking Bootstrap Select2?
Refs #5576
---
app/assets/stylesheets/components/_select2.sass | 3 +++
1 file changed, 3 insertions(+)
diff --git a/app/assets/stylesheets/components/_select2.sass b/app/assets/stylesheets/components/_select2.sass
index 38603e11a..f31387c9f 100644
--- a/app/assets/stylesheets/components/_select2.sass
+++ b/app/assets/stylesheets/components/_select2.sass
@@ -79,6 +79,9 @@
.select2-search--inline .select2-search__field
height: 28px
+ .select2-selection__rendered
+ padding-right: 20px
+
.select2-container--bootstrap .select2-selection
border-color: rgba($grey, 0.3)
--
cgit v1.2.3
From 57d8808a835dda23baaeaa41e800748d8faa028e Mon Sep 17 00:00:00 2001
From: Teddy Wing
Date: Thu, 1 Feb 2018 12:31:52 +0100
Subject: ReferentialVehicleJourneys#index: Use ransack filter for line id
I went with this custom filter because I couldn't get it to work with a
symbol-based filter in the template. But Johan suggested trying it and I
guess it works. Not sure what I was doing that didn't work before.
Refs #5576
---
app/controllers/referential_vehicle_journeys_controller.rb | 1 -
app/models/chouette/vehicle_journey.rb | 5 -----
app/views/referential_vehicle_journeys/_filters.html.slim | 2 +-
3 files changed, 1 insertion(+), 7 deletions(-)
diff --git a/app/controllers/referential_vehicle_journeys_controller.rb b/app/controllers/referential_vehicle_journeys_controller.rb
index 935b52d93..2ce28a5cc 100644
--- a/app/controllers/referential_vehicle_journeys_controller.rb
+++ b/app/controllers/referential_vehicle_journeys_controller.rb
@@ -16,7 +16,6 @@ class ReferentialVehicleJourneysController < ChouetteController
def collection
@q ||= end_of_association_chain
- @q = @q.with_line_id(params[:q][:line_id]) if params[:q] && params[:q][:line_id]
@q = @q.with_stop_area_ids(params[:q][:stop_area_ids]) if params[:q] && params[:q][:stop_area_ids]
@q = ransack_period_range(scope: @q, error_message: t('vehicle_journeys.errors.purchase_window'), query: :in_purchase_window, prefix: :purchase_window)
@q = ransack_period_range(scope: @q, error_message: t('vehicle_journeys.errors.time_table'), query: :with_matching_timetable, prefix: :time_table)
diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb
index 918ca07aa..30b8903a1 100644
--- a/app/models/chouette/vehicle_journey.rb
+++ b/app/models/chouette/vehicle_journey.rb
@@ -52,10 +52,6 @@ module Chouette
end
}
- scope :with_line_id, ->(id) {
- joins(:route).where(routes: { line_id: id })
- }
-
scope :in_purchase_window, ->(range){
purchase_windows = Chouette::PurchaseWindow.overlap_dates(range)
sql = purchase_windows.joins(:vehicle_journeys).select('vehicle_journeys.id').uniq.to_sql
@@ -63,7 +59,6 @@ module Chouette
}
# We need this for the ransack object in the filters
- ransacker :line_id
ransacker :purchase_window_date_gt
ransacker :stop_area_ids
diff --git a/app/views/referential_vehicle_journeys/_filters.html.slim b/app/views/referential_vehicle_journeys/_filters.html.slim
index 53084017b..67bb60e8d 100644
--- a/app/views/referential_vehicle_journeys/_filters.html.slim
+++ b/app/views/referential_vehicle_journeys/_filters.html.slim
@@ -21,7 +21,7 @@
required: false,
class: 'control-label'
.form-inline.filter_menu
- = f.input :line_id,
+ = f.input :route_line_id_eq,
as: :select,
collection: @vehicle_journeys.lines,
selected: params[:q] && params[:q][:line_id],
--
cgit v1.2.3
From 0df4fa90c1365fab181e864ea751b6d7b6894a88 Mon Sep 17 00:00:00 2001
From: Teddy Wing
Date: Thu, 1 Feb 2018 12:40:09 +0100
Subject: VehicleJourney.lines: Change query to only get lines for route
Johan recommended using an `IN` query to only get the lines in the
current scope. I assumed I'd be covered by the schema and how only the
lines for the current referential are in the schema, but this is
probably a more reasonable way to get associated lines.
Refs #5576
---
app/models/chouette/vehicle_journey.rb | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb
index 30b8903a1..6146d5be8 100644
--- a/app/models/chouette/vehicle_journey.rb
+++ b/app/models/chouette/vehicle_journey.rb
@@ -377,7 +377,8 @@ module Chouette
end
def self.lines
- Chouette::Line.joins(routes: :vehicle_journeys).distinct
+ lines_query = joins(:route).select("routes.line_id").to_sql
+ Chouette::Line.where("id IN (#{lines_query})")
end
end
end
--
cgit v1.2.3
From 21b42cc6ed91aeb24ead3b3daca31f256ccf9758 Mon Sep 17 00:00:00 2001
From: Zog
Date: Thu, 1 Feb 2018 15:55:00 +0100
Subject: :fire: log
---
app/javascript/helpers/master_slave.coffee | 2 --
1 file changed, 2 deletions(-)
diff --git a/app/javascript/helpers/master_slave.coffee b/app/javascript/helpers/master_slave.coffee
index 4866a55e3..81bebe36a 100644
--- a/app/javascript/helpers/master_slave.coffee
+++ b/app/javascript/helpers/master_slave.coffee
@@ -3,8 +3,6 @@ class MasterSlave
$(selector).find('[data-master]').each (i, slave)->
$slave = $(slave)
master = $($slave.data().master)
- console.log $slave
- console.log $slave.find("input:disabled, select:disabled")
$slave.find("input:disabled, select:disabled").attr "data-slave-force-disabled", "true"
toggle = ->
val = master.filter(":checked").val() if master.filter("[type=radio]").length > 0
--
cgit v1.2.3
From eec283434fac6110149eadf9e468cc37aa9981d1 Mon Sep 17 00:00:00 2001
From: Zog
Date: Thu, 1 Feb 2018 15:56:32 +0100
Subject: Refs #5758; Set a default kind for StopAreas
---
app/models/chouette/stop_area.rb | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb
index bb8747faa..cf2afbc73 100644
--- a/app/models/chouette/stop_area.rb
+++ b/app/models/chouette/stop_area.rb
@@ -47,6 +47,10 @@ module Chouette
validate :parent_area_type_must_be_greater
validate :area_type_of_right_kind
+ after_initialize do
+ self.kind ||= :commercial
+ end
+
def self.nullable_attributes
[:registration_number, :street_name, :country_code, :fare_code,
:nearest_topic_name, :comment, :long_lat_type, :zip_code, :city_name, :url, :time_zone]
--
cgit v1.2.3
From 40ea013722331cd5c9335167a8f3e41e80e2f8d8 Mon Sep 17 00:00:00 2001
From: Zog
Date: Thu, 1 Feb 2018 16:21:33 +0100
Subject: Refs #5758; Fix messed rebase
---
app/views/stop_areas/_form.html.slim | 5 -----
app/views/stop_areas/show.html.slim | 5 ++---
2 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/app/views/stop_areas/_form.html.slim b/app/views/stop_areas/_form.html.slim
index 67af39dc6..9897a27ac 100644
--- a/app/views/stop_areas/_form.html.slim
+++ b/app/views/stop_areas/_form.html.slim
@@ -13,11 +13,6 @@
- f.object.localized_names.each do |k, v|
.col-md-6= f.input "localized_names[#{k}]", input_html: {value: v}, label: label_for_country(k)
- .form-group
- .col-sm-3.col-xs-5
- .col-sm-9.col-xs-7
- - f.object.localized_names.each do |k, v|
- .col-md-6= f.input "localized_names[#{k}]", input_html: {value: v}, label: label_for_country(k)
= f.input :kind, as: :radio_buttons, checked: @stop_area.kind, :input_html => {:disabled => !@stop_area.new_record?}, :include_blank => false, item_wrapper_class: 'radio-inline', wrapper: :horizontal_form, disabled: !@stop_area.new_record?
.slave data-master="[name='stop_area[kind]']" data-value="commercial"
= f.input :parent_id, as: :select, :collection => [f.object.parent_id], input_html: { data: { select2_ajax: 'true', url: autocomplete_stop_area_referential_stop_areas_path(@stop_area_referential), initvalue: {id: f.object.parent_id, text: f.object.parent.try(:full_name)}}}
diff --git a/app/views/stop_areas/show.html.slim b/app/views/stop_areas/show.html.slim
index 300d714e8..a4e14a272 100644
--- a/app/views/stop_areas/show.html.slim
+++ b/app/views/stop_areas/show.html.slim
@@ -13,9 +13,8 @@
- attributes.merge!({label_for_country(k, @stop_area.human_attribute_name(:name)) => v }) if v.present?
- attributes.merge!({ @stop_area.human_attribute_name(:parent) => @stop_area.parent ? link_to(@stop_area.parent.name, stop_area_referential_stop_area_path(@stop_area_referential, @stop_area.parent)) : "-" }) if @stop_area.commercial?
- attributes.merge!({ @stop_area.human_attribute_name(:stop_area_type) => Chouette::AreaType.find(@stop_area.area_type).try(:label),
- @stop_area.human_attribute_name(:registration_number) => @stop_area.registration_number
- })
-
+ @stop_area.human_attribute_name(:registration_number) => @stop_area.registration_number,
+ })
- attributes.merge!(@stop_area.human_attribute_name(:waiting_time) => @stop_area.waiting_time_text) if has_feature?(:stop_area_waiting_time)
- attributes.merge!({ "Coordonnées" => geo_data(@stop_area, @stop_area_referential),
@stop_area.human_attribute_name(:zip_code) => @stop_area.zip_code,
--
cgit v1.2.3
From 1e691dec5e86fcaf7982801ecfc32b67f560b27f Mon Sep 17 00:00:00 2001
From: Alban Peignier
Date: Thu, 1 Feb 2018 18:52:33 +0100
Subject: Fixes vehicle_journeys#index spec
---
spec/views/vehicle_journeys/index.html.slim_spec.rb | 1 +
1 file changed, 1 insertion(+)
diff --git a/spec/views/vehicle_journeys/index.html.slim_spec.rb b/spec/views/vehicle_journeys/index.html.slim_spec.rb
index 7f0a9c5aa..920067fa9 100644
--- a/spec/views/vehicle_journeys/index.html.slim_spec.rb
+++ b/spec/views/vehicle_journeys/index.html.slim_spec.rb
@@ -13,6 +13,7 @@ describe "/vehicle_journeys/index", :type => :view do
allow(view).to receive(:link_with_search).and_return("#")
allow(view).to receive(:collection).and_return(vehicle_journeys)
allow(view).to receive(:current_referential).and_return(referential)
+ allow(view).to receive(:has_feature?).and_return(true)
controller.request.path_parameters[:referential_id] = referential.id
render
end
--
cgit v1.2.3
From ce7ea85b3922d97b54d90f458eb59c269359e2b3 Mon Sep 17 00:00:00 2001
From: Alban Peignier
Date: Thu, 1 Feb 2018 19:37:49 +0100
Subject: Prevent problem with StopArea#kind. Refs #5817
---
app/views/referential_vehicle_journeys/_filters.html.slim | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/referential_vehicle_journeys/_filters.html.slim b/app/views/referential_vehicle_journeys/_filters.html.slim
index 67bb60e8d..3a9b0a4ef 100644
--- a/app/views/referential_vehicle_journeys/_filters.html.slim
+++ b/app/views/referential_vehicle_journeys/_filters.html.slim
@@ -41,7 +41,7 @@
= f.input :published_journey_name_lteq, label: false, wrapper_html: { class: 'w45'}
.form-group.togglable
= f.label Chouette::StopArea.model_name.human.pluralize, required: false, class: 'control-label'
- = f.input :stop_area_ids, collection: @all_stop_areas.select(:id, :name).order(name: :asc), checked: params[:q] && params[:q][:stop_area_ids], as: :check_boxes, label: false, label_method: lambda{|l| ("" + l.name + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}, multiple: true
+ = f.input :stop_area_ids, collection: @all_stop_areas.select(:id, :name, :kind).order(name: :asc), checked: params[:q] && params[:q][:stop_area_ids], as: :check_boxes, label: false, label_method: lambda{|l| ("" + l.name + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}, multiple: true
.form-group.togglable
= f.label Chouette::VehicleJourney.human_attribute_name(:purchase_window), class: 'control-label'
.filter_menu
--
cgit v1.2.3
From 941338da24b611074682fa6bccf712992abf9389 Mon Sep 17 00:00:00 2001
From: Alban Peignier
Date: Thu, 1 Feb 2018 22:26:00 +0100
Subject: Define @year in CalendarsController as expected by view. Refs #5682
---
app/controllers/calendars_controller.rb | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb
index 3b7b6de15..75d4cbd09 100644
--- a/app/controllers/calendars_controller.rb
+++ b/app/controllers/calendars_controller.rb
@@ -18,6 +18,7 @@ class CalendarsController < ChouetteController
def show
show! do
+ @year = params[:year] ? params[:year].to_i : Date.today.cwyear
@calendar = @calendar.decorate(context: {
workgroup: workgroup
})
--
cgit v1.2.3
From a66ec04b130baa732b24b059961a58bac33f670c Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 2 Feb 2018 09:39:08 +0100
Subject: Refs #5825 @1h; Fix info window behaviour on VJs editor
---
app/javascript/vehicle_journeys/actions/index.js | 4 +++
.../vehicle_journeys/components/VehicleJourney.js | 5 ++--
.../components/tools/EditVehicleJourney.js | 33 +++++++++++++---------
.../components/tools/VehicleJourneyInfoButton.js | 30 ++++++++++++++++++++
.../containers/tools/VehicleJourneyInfoButton.js | 20 +++++++++++++
app/javascript/vehicle_journeys/reducers/modal.js | 9 ++++++
6 files changed, 86 insertions(+), 15 deletions(-)
create mode 100644 app/javascript/vehicle_journeys/components/tools/VehicleJourneyInfoButton.js
create mode 100644 app/javascript/vehicle_journeys/containers/tools/VehicleJourneyInfoButton.js
diff --git a/app/javascript/vehicle_journeys/actions/index.js b/app/javascript/vehicle_journeys/actions/index.js
index 74a333b53..bb4ccf417 100644
--- a/app/javascript/vehicle_journeys/actions/index.js
+++ b/app/javascript/vehicle_journeys/actions/index.js
@@ -69,6 +69,10 @@ const actions = {
type : 'EDIT_VEHICLEJOURNEY_MODAL',
vehicleJourney
}),
+ openInfoModal : (vehicleJourney) => ({
+ type : 'INFO_VEHICLEJOURNEY_MODAL',
+ vehicleJourney
+ }),
openNotesEditModal : (vehicleJourney) => ({
type : 'EDIT_NOTES_VEHICLEJOURNEY_MODAL',
vehicleJourney
diff --git a/app/javascript/vehicle_journeys/components/VehicleJourney.js b/app/javascript/vehicle_journeys/components/VehicleJourney.js
index e7d4b5b30..99a458f50 100644
--- a/app/javascript/vehicle_journeys/components/VehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/VehicleJourney.js
@@ -2,6 +2,7 @@ import React, { Component } from 'react'
import PropTypes from 'prop-types'
import actions from '../actions'
import EditVehicleJourney from '../containers/tools/EditVehicleJourney'
+import VehicleJourneyInfoButton from '../containers/tools/VehicleJourneyInfoButton'
export default class VehicleJourney extends Component {
constructor(props) {
@@ -60,7 +61,7 @@ export default class VehicleJourney extends Component {
- ($(e.target).parents("a").length == 0) && this.props.onSelectVehicleJourney(this.props.index)
+ !this.props.disabled && ($(e.target).parents("a").length == 0) && this.props.onSelectVehicleJourney(this.props.index)
}
>
{this.props.value.short_id || '-'}
@@ -93,7 +94,7 @@ export default class VehicleJourney extends Component {
>
}
- {this.props.disabled && }
+ {this.props.disabled && }
{this.props.value.vehicle_journey_at_stops.map((vj, i) =>
diff --git a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js
index f814c0459..f6a0e3c61 100644
--- a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js
@@ -7,6 +7,7 @@ import CustomFieldsInputs from './CustomFieldsInputs'
export default class EditVehicleJourney extends Component {
constructor(props) {
super(props)
+ this.updateValue = this.updateValue.bind(this)
}
handleSubmit() {
@@ -23,8 +24,14 @@ export default class EditVehicleJourney extends Component {
}
}
- getSelected() {
- return this.props.vehicleJourney ? [this.props.vehicleJourney] : actions.getSelected(this.props.vehicleJourneys)
+ updateValue(attribute, e) {
+ this.props.modal.modalProps.vehicleJourney[attribute] = e.target.value
+ actions.resetValidation(e.currentTarget)
+ this.forceUpdate()
+ }
+
+ editMode() {
+ return !this.props.modal.modalProps.info && this.props.editMode
}
render() {
@@ -39,10 +46,10 @@ export default class EditVehicleJourney extends Component {
this.props.onOpenEditModal(this.getSelected()[0])}
+ onClick={() => this.props.onOpenEditModal(actions.getSelected(this.props.vehicleJourneys)[0])}
>
@@ -67,9 +74,9 @@ export default class EditVehicleJourney extends Component {
type='text'
ref='published_journey_name'
className='form-control'
- disabled={!this.props.editMode}
- defaultValue={this.props.modal.modalProps.vehicleJourney.published_journey_name}
- onKeyDown={(e) => actions.resetValidation(e.currentTarget)}
+ disabled={!this.editMode()}
+ value={this.props.modal.modalProps.vehicleJourney.published_journey_name}
+ onChange={(e) => this.updateValue('published_journey_name', e)}
/>
@@ -94,9 +101,9 @@ export default class EditVehicleJourney extends Component {
type='text'
ref='published_journey_identifier'
className='form-control'
- disabled={!this.props.editMode}
- defaultValue={this.props.modal.modalProps.vehicleJourney.published_journey_identifier}
- onKeyDown={(e) => actions.resetValidation(e.currentTarget)}
+ disabled={!this.editMode()}
+ value={this.props.modal.modalProps.vehicleJourney.published_journey_identifier}
+ onChange={(e) => this.updateValue('published_journey_identifier', e)}
/>
@@ -105,7 +112,7 @@ export default class EditVehicleJourney extends Component {
Transporteur
this.props.onSelect2Company(e)}
onUnselect2Company = {() => this.props.onUnselect2Company()}
@@ -152,13 +159,13 @@ export default class EditVehicleJourney extends Component {
this.custom_fields[code]["value"] = value}
- disabled={!this.props.editMode}
+ disabled={!this.editMode()}
/>
{
- this.props.editMode &&
+ this.editMode() &&
+ this.props.onOpenEditModal(this.props.vehicleJourney)}
+ >
+
+
+
+ )
+ }
+}
+
+VehicleJourneyInfoButton.propTypes = {
+ onOpenEditModal: PropTypes.func.isRequired,
+ vehicleJourney: PropTypes.object.isRequired,
+}
diff --git a/app/javascript/vehicle_journeys/containers/tools/VehicleJourneyInfoButton.js b/app/javascript/vehicle_journeys/containers/tools/VehicleJourneyInfoButton.js
new file mode 100644
index 000000000..19010c312
--- /dev/null
+++ b/app/javascript/vehicle_journeys/containers/tools/VehicleJourneyInfoButton.js
@@ -0,0 +1,20 @@
+import actions from '../../actions'
+import { connect } from 'react-redux'
+import VehicleJourneyInfoButtonComponent from '../../components/tools/VehicleJourneyInfoButton'
+
+const mapStateToProps = (state, ownProps) => {
+ return {
+ }
+}
+
+const mapDispatchToProps = (dispatch) => {
+ return {
+ onOpenEditModal: (vj) =>{
+ dispatch(actions.openInfoModal(vj))
+ },
+ }
+}
+
+const VehicleJourneyInfoButton = connect(mapStateToProps, mapDispatchToProps)(VehicleJourneyInfoButtonComponent)
+
+export default VehicleJourneyInfoButton
diff --git a/app/javascript/vehicle_journeys/reducers/modal.js b/app/javascript/vehicle_journeys/reducers/modal.js
index fb7e16547..bcfc6ea0b 100644
--- a/app/javascript/vehicle_journeys/reducers/modal.js
+++ b/app/javascript/vehicle_journeys/reducers/modal.js
@@ -37,6 +37,15 @@ export default function modal(state = {}, action) {
},
confirmModal: {}
}
+ case 'INFO_VEHICLEJOURNEY_MODAL':
+ return {
+ type: 'edit',
+ modalProps: {
+ vehicleJourney: action.vehicleJourney,
+ info: true
+ },
+ confirmModal: {}
+ }
case 'EDIT_CALENDARS_VEHICLEJOURNEY_MODAL':
vehicleJourneysModal = JSON.parse(JSON.stringify(action.vehicleJourneys))
let uniqTimetables = []
--
cgit v1.2.3
From b9b9d8141e9e5869680604559770f09d840b0683 Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 2 Feb 2018 09:46:06 +0100
Subject: Refs #5830; Fix RouteDecorator's duplicate action
---
app/decorators/route_decorator.rb | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/decorators/route_decorator.rb b/app/decorators/route_decorator.rb
index 75ef20d63..fa6367924 100644
--- a/app/decorators/route_decorator.rb
+++ b/app/decorators/route_decorator.rb
@@ -61,6 +61,7 @@ class RouteDecorator < AF83::Decorator
policy: :duplicate
) do |l|
l.content h.t('routes.duplicate.title')
+ l.method :post
l.href do
h.duplicate_referential_line_route_path(
context[:referential],
--
cgit v1.2.3
From ae06f709d3937ec31e4883bcf0e97be5ca69ebc0 Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 2 Feb 2018 10:03:28 +0100
Subject: Refs #5825; Fix pagination
---
app/javascript/vehicle_journeys/actions/index.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/app/javascript/vehicle_journeys/actions/index.js b/app/javascript/vehicle_journeys/actions/index.js
index bb4ccf417..4ca8bd73b 100644
--- a/app/javascript/vehicle_journeys/actions/index.js
+++ b/app/javascript/vehicle_journeys/actions/index.js
@@ -387,7 +387,9 @@ const actions = {
}
window.currentItemsLength = vehicleJourneys.length
dispatch(actions.receiveVehicleJourneys(vehicleJourneys, returnJourneys))
- dispatch(actions.receiveTotalCount(json.total))
+ if(!returnJourneys){
+ dispatch(actions.receiveTotalCount(json.total))
+ }
}
})
},
--
cgit v1.2.3
From 1f38551f95bf59cef23eca5af95a71ed51056aa5 Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 2 Feb 2018 10:55:05 +0100
Subject: Fix jest specs
---
app/javascript/time_tables/actions/index.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/javascript/time_tables/actions/index.js b/app/javascript/time_tables/actions/index.js
index 70f548174..4a36ec4e1 100644
--- a/app/javascript/time_tables/actions/index.js
+++ b/app/javascript/time_tables/actions/index.js
@@ -1,5 +1,5 @@
-import range from 'lodash/range'
import assign from 'lodash/assign'
+import range from 'lodash/range'
import reject from 'lodash/reject'
import some from 'lodash/some'
import every from 'lodash/every'
--
cgit v1.2.3
From 0d620e6ad68ac1e1bcc393f3b87c4bf4259b2531 Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 2 Feb 2018 11:55:27 +0100
Subject: Refs 5832; Fix bug on ReferentialVehicleJourneys#index filters
By default a value was always set on the "Line" filter, yielding
misleading results.
---
.../_filters.html.slim | 1 +
spec/models/chouette/vehicle_journey_spec.rb | 42 ++++++++++++++++++++++
2 files changed, 43 insertions(+)
diff --git a/app/views/referential_vehicle_journeys/_filters.html.slim b/app/views/referential_vehicle_journeys/_filters.html.slim
index 3a9b0a4ef..d3cb9eb4b 100644
--- a/app/views/referential_vehicle_journeys/_filters.html.slim
+++ b/app/views/referential_vehicle_journeys/_filters.html.slim
@@ -23,6 +23,7 @@
.form-inline.filter_menu
= f.input :route_line_id_eq,
as: :select,
+ include_blank: t(".all"),
collection: @vehicle_journeys.lines,
selected: params[:q] && params[:q][:line_id],
input_html: { \
diff --git a/spec/models/chouette/vehicle_journey_spec.rb b/spec/models/chouette/vehicle_journey_spec.rb
index e9ffddd2a..909d6582d 100644
--- a/spec/models/chouette/vehicle_journey_spec.rb
+++ b/spec/models/chouette/vehicle_journey_spec.rb
@@ -24,6 +24,48 @@ describe Chouette::VehicleJourney, :type => :model do
it_behaves_like 'checksum support', :vehicle_journey
end
+ describe "#with_stop_area_ids" do
+ subject(:result){Chouette::VehicleJourney.with_stop_area_ids(ids)}
+ let(:ids){[]}
+ let(:common_stop_area){ create :stop_area}
+ let!(:journey_1){ create :vehicle_journey }
+ let!(:journey_2){ create :vehicle_journey }
+
+ before(:each) do
+ journey_1.journey_pattern.stop_points.last.update_attribute :stop_area_id, common_stop_area.id
+ journey_2.journey_pattern.stop_points.last.update_attribute :stop_area_id, common_stop_area.id
+ expect(journey_1.stop_areas).to include(common_stop_area)
+ expect(journey_2.stop_areas).to include(common_stop_area)
+ end
+ context "with no value" do
+ it "should return all journeys" do
+ expect(result).to eq Chouette::VehicleJourney.all
+ end
+ end
+
+ context "with a single value" do
+ let(:ids){[journey_1.stop_areas.first.id]}
+ it "should return all journeys" do
+ expect(result).to eq [journey_1]
+ end
+
+ context "with a common area" do
+ let(:ids){[common_stop_area.id]}
+ it "should return all journeys" do
+ expect(result).to eq [journey_1, journey_2]
+ end
+ end
+ end
+
+ context "with a couple of values" do
+ let(:ids){[journey_1.stop_areas.first.id, common_stop_area.id]}
+ it "should return only the matching journeys" do
+ expect(result).to eq [journey_1]
+ end
+ end
+
+ end
+
describe '#in_purchase_window' do
let(:start_date){2.month.ago.to_date}
let(:end_date){1.month.ago.to_date}
--
cgit v1.2.3
From 401754ecbe63e65736697c14123c6a21b2d34157 Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 2 Feb 2018 12:43:55 +0100
Subject: Refs #5832 @1h; Show active filters
---
app/assets/stylesheets/components/_forms.sass | 9 +++++++++
app/helpers/search_helper.rb | 15 +++++++++++++++
app/views/calendars/_filters.html.slim | 6 +++---
app/views/compliance_check_sets/_filters.html.slim | 8 ++++----
app/views/compliance_checks/_filters.html.slim | 8 ++++----
app/views/compliance_control_sets/_filters.html.slim | 10 +++++-----
app/views/compliance_controls/_filters.html.slim | 8 ++++----
app/views/imports/_filters.html.slim | 6 +++---
app/views/lines/_filters.html.slim | 10 +++++-----
app/views/purchase_windows/_filters.html.slim | 4 ++--
app/views/referential_lines/_filters.html.slim | 4 ++--
app/views/referential_vehicle_journeys/_filters.html.slim | 14 +++++++-------
app/views/referentials/_filters.html.slim | 8 ++++----
app/views/routing_constraint_zones/_filters.html.slim | 4 ++--
app/views/stop_areas/_filters.html.slim | 10 +++++-----
app/views/time_tables/_filter.html.slim | 6 +++---
app/views/workbenches/_filters.html.slim | 10 +++++-----
17 files changed, 82 insertions(+), 58 deletions(-)
diff --git a/app/assets/stylesheets/components/_forms.sass b/app/assets/stylesheets/components/_forms.sass
index ba5bbbde1..caa8ac0e4 100644
--- a/app/assets/stylesheets/components/_forms.sass
+++ b/app/assets/stylesheets/components/_forms.sass
@@ -457,6 +457,15 @@ table, .table
margin: 0
min-height: 41px
padding: 5px 15px
+ &.active
+ &:after
+ position: absolute
+ top: 0
+ left: 0
+ right: 0
+ height: 4px
+ background: $blue
+ content: ""
&.per-page-select
padding-top: 10px
.selected
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index f4976ea53..be70d974d 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -8,4 +8,19 @@ module SearchHelper
link_to name, params.deep_merge("q" => search,:page => 1), html_options
end
+ def filter_item_class q, key
+ active = false
+ if q.present? && q[key].present?
+ val = q[key]
+ if val.is_a?(Array)
+ active = val.any? &:present?
+ elsif val.is_a?(Hash)
+ active = val.values.any? &:present?
+ else
+ active = true
+ end
+ end
+ active ? 'active' : 'inactive'
+ end
+
end
diff --git a/app/views/calendars/_filters.html.slim b/app/views/calendars/_filters.html.slim
index c1d8c47f7..35441b053 100644
--- a/app/views/calendars/_filters.html.slim
+++ b/app/views/calendars/_filters.html.slim
@@ -1,19 +1,19 @@
= 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
+ .input-group.search_bar class=filter_item_class(params[:q], :name_or_short_name_cont)
= f.search_field :name_or_short_name_cont, class: 'form-control', placeholder: 'Indiquez un nom/nom court de calendrier...'
span.input-group-btn
button.btn.btn-default#search_btn type='submit'
span.fa.fa-search
.ffg-row
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :shared_true)
= f.label Calendar.human_attribute_name(:shared), required: false, class: 'control-label'
.form-group.checkbox_list
= f.input :shared_true, as: :boolean, label: ("Oui ").html_safe, wrapper_html: { class: 'checkbox-wrapper' }
= f.input :shared_false, as: :boolean, label: ("Non ").html_safe, wrapper_html: { class: 'checkbox-wrapper' }
- .form-group
+ .form-group class=filter_item_class(params[:q], :contains_date)
= f.label Calendar.human_attribute_name(:date), class: 'control-label'
= f.input :contains_date, as: :date, label: false, wrapper_html: { class: 'date smart_date' }, class: 'form-control', include_blank: true
diff --git a/app/views/compliance_check_sets/_filters.html.slim b/app/views/compliance_check_sets/_filters.html.slim
index bf929bc08..e413a6cdd 100644
--- a/app/views/compliance_check_sets/_filters.html.slim
+++ b/app/views/compliance_check_sets/_filters.html.slim
@@ -1,23 +1,23 @@
= search_form_for @q_for_form, url: workbench_compliance_check_sets_path(@workbench), builder: SimpleForm::FormBuilder, class: 'form form-filter' do |f|
.ffg-row
- .input-group.search_bar
+ .input-group.search_bar class=filter_item_class(params[:q], :referential_name_cont)
= f.search_field :referential_name_cont, class: 'form-control', placeholder: t('compliance_check_sets.filters.name')
span.input-group-btn
button.btn.btn-default type='submit'
span.fa.fa-search
.ffg-row
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :parent_type_eq_any)
= f.label t('activerecord.attributes.compliance_check_set.assigned_to'), required: false, class: 'control-label'
= f.input :parent_type_eq_any, collection: ComplianceCheckSet.order('parent_type'), as: :check_boxes, label: false, label_method: lambda {|w| ("#{w} ").html_safe}, required: false, wrapper_html: {class: 'checkbox_list'}
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :created_at)
= f.label Import.human_attribute_name(:created_at), required: false, class: 'control-label'
.filter_menu
= f.simple_fields_for :created_at do |p|
= p.input :start_date, as: :date, label: false, wrapper_html: {class: 'date smart_date filter_menu-item'}, default: @begin_range, include_blank: @begin_range ? false : true
= p.input :end_date, as: :date, label: false, wrapper_html: {class: 'date smart_date filter_menu-item'}, default: @end_range, include_blank: @end_range ? false : true
.form-group.search
- .input-group.search_bar
+ .input-group.search_bar class=filter_item_class(params[:q], :compliance_control_set_name_cont)
= f.search_field :compliance_control_set_name_cont, class: 'form-control', placeholder: t('compliance_check_sets.filters.name_compliance_control_set')
span.input-group-btn
button.btn.btn-default type='submit'
diff --git a/app/views/compliance_checks/_filters.html.slim b/app/views/compliance_checks/_filters.html.slim
index 0d747da27..40e45dd92 100644
--- a/app/views/compliance_checks/_filters.html.slim
+++ b/app/views/compliance_checks/_filters.html.slim
@@ -5,7 +5,7 @@
class: 'form form-filter' do |f|
.ffg-row
- .input-group.search_bar
+ .input-group.search_bar class=filter_item_class(params[:q], :name_cont)
= f.search_field :name_cont,
class: 'form-control',
placeholder: t('compliance_checks.filters.name')
@@ -14,7 +14,7 @@
span.fa.fa-search
.ffg-row
- .form-group.togglable#compliance_check_block-filter
+ .form-group.togglable#compliance_check_block-filter class=filter_item_class(params[:q], :compliance_check_block_id_eq_any)
= f.label t('activerecord.models.compliance_check_block.one'), required: false, class: 'control-label'
= f.input :compliance_check_block_id_eq_any,
collection: @compliance_check_set.compliance_check_blocks,
@@ -23,7 +23,7 @@
label_method: lambda {|w| ("#{transport_mode_text(w)} ").html_safe},
required: false,
wrapper_html: {class: 'checkbox_list'}
- .form-group.togglable#subclass-filter
+ .form-group.togglable#subclass-filter class=filter_item_class(params[:q], :origin_code_cont_any)
= f.label t('compliance_checks.filters.subclass'), required: false, class: 'control-label'
= f.input :origin_code_cont_any,
collection: subclass_selection_list,
@@ -32,7 +32,7 @@
label_method: lambda {|w| ("#{w.first} ").html_safe},
required: false,
wrapper_html: {class: 'checkbox_list'}
- .form-group.togglable#severity-filter
+ .form-group.togglable#severity-filter class=filter_item_class(params[:q], :criticity_eq_any)
= f.label t('compliance_checks.filters.criticity'), required: false, class: 'control-label'
= f.input :criticity_eq_any,
collection: ComplianceControl.criticities,
diff --git a/app/views/compliance_control_sets/_filters.html.slim b/app/views/compliance_control_sets/_filters.html.slim
index 6a5d3ac44..4348defac 100644
--- a/app/views/compliance_control_sets/_filters.html.slim
+++ b/app/views/compliance_control_sets/_filters.html.slim
@@ -1,16 +1,16 @@
= search_form_for @q_for_form, url: compliance_control_sets_path, builder: SimpleForm::FormBuilder, class: 'form form-filter' do |f|
.ffg-row
- .input-group.search_bar
+ .input-group.search_bar class=filter_item_class(params[:q], :name_cont)
= f.search_field :name_cont, class: 'form-control', placeholder: t('compliance_control_sets.filters.name')
span.input-group-btn
button.btn.btn-default type='submit'
span.fa.fa-search
.ffg-row
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :organisation_name_eq_any)
= f.label t('activerecord.models.organisation.one'), required: false, class: 'control-label'
= f.input :organisation_name_eq_any, collection: organisations_filters_values, as: :check_boxes, label: false, label_method: lambda {|w| ("#{w.name} ").html_safe}, required: false, wrapper_html: {class: 'checkbox_list'}
-
- .form-group.togglable
+
+ .form-group.togglable class=filter_item_class(params[:q], :updated_at)
= f.label Import.human_attribute_name(:updated_at), required: false, class: 'control-label'
.filter_menu
= f.simple_fields_for :updated_at do |p|
@@ -19,4 +19,4 @@
.actions
= link_to t('actions.erase'), @compliance_control_set, class: 'btn btn-link'
- = f.submit t('actions.filter'), class: 'btn btn-default', id: 'compliance_control_set_filter_btn'
\ No newline at end of file
+ = f.submit t('actions.filter'), class: 'btn btn-default', id: 'compliance_control_set_filter_btn'
diff --git a/app/views/compliance_controls/_filters.html.slim b/app/views/compliance_controls/_filters.html.slim
index d38da5d2d..f6b9970f2 100644
--- a/app/views/compliance_controls/_filters.html.slim
+++ b/app/views/compliance_controls/_filters.html.slim
@@ -5,7 +5,7 @@
class: 'form form-filter' do |f|
.ffg-row
- .input-group.search_bar
+ .input-group.search_bar class=filter_item_class(params[:q], :name_cont)
= f.search_field :name_cont,
class: 'form-control',
placeholder: t('compliance_controls.filters.name')
@@ -14,7 +14,7 @@
span.fa.fa-search
.ffg-row
- .form-group.togglable#compliance_control_block-filter
+ .form-group.togglable#compliance_control_block-filter class=filter_item_class(params[:q], :compliance_control_block_id_eq_any)
= f.label t('activerecord.models.compliance_control_block.one'), required: false, class: 'control-label'
= f.input :compliance_control_block_id_eq_any,
collection: @compliance_control_set.compliance_control_blocks,
@@ -23,7 +23,7 @@
label_method: lambda {|w| ("#{transport_mode_text(w)} ").html_safe},
required: false,
wrapper_html: {class: 'checkbox_list'}
- .form-group.togglable#subclass-filter
+ .form-group.togglable#subclass-filter class=filter_item_class(params[:q], :origin_code_cont_any)
= f.label t('compliance_controls.filters.subclass'), required: false, class: 'control-label'
= f.input :origin_code_cont_any,
collection: subclass_selection_list,
@@ -32,7 +32,7 @@
label_method: lambda {|w| ("#{w.first} ").html_safe},
required: false,
wrapper_html: {class: 'checkbox_list'}
- .form-group.togglable#severity-filter
+ .form-group.togglable#severity-filter class=filter_item_class(params[:q], :criticity_eq_any)
= f.label t('compliance_controls.filters.criticity'), required: false, class: 'control-label'
= f.input :criticity_eq_any,
collection: ComplianceControl.criticities,
diff --git a/app/views/imports/_filters.html.slim b/app/views/imports/_filters.html.slim
index b1f23e2c8..25c0d10d9 100644
--- a/app/views/imports/_filters.html.slim
+++ b/app/views/imports/_filters.html.slim
@@ -1,17 +1,17 @@
= search_form_for @q, url: workbench_imports_path(@workbench), html: { method: :get, class: 'form form-filter' } do |f|
.ffg-row
- .input-group.search_bar
+ .input-group.search_bar class=filter_item_class(params[:q], :name_or_creator_cont)
= f.search_field :name_or_creator_cont, class: 'form-control', placeholder: t('imports.filters.name_or_creator_cont')
span.input-group-btn
button.btn.btn-default#search_btn type='submit'
span.fa.fa-search
.ffg-row
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :status_eq_any)
= f.label Import.human_attribute_name(:status), required: false, class: 'control-label'
= f.input :status_eq_any, collection: %w(pending successful warning failed), as: :check_boxes, label: false, label_method: lambda{|l| ("" + import_status(l) + " ").html_safe}, required: false, wrapper_html: { class: "checkbox_list"}
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :started_at)
= f.label Import.human_attribute_name(:started_at), required: false, class: 'control-label'
.filter_menu
= f.simple_fields_for :started_at do |p|
diff --git a/app/views/lines/_filters.html.slim b/app/views/lines/_filters.html.slim
index e3674656a..67ba297cf 100644
--- a/app/views/lines/_filters.html.slim
+++ b/app/views/lines/_filters.html.slim
@@ -1,25 +1,25 @@
= search_form_for @q, url: line_referential_lines_path(@line_referential), html: {method: :get}, class: 'form form-filter' do |f|
.ffg-row
- .input-group.search_bar
+ .input-group.search_bar class=filter_item_class(params[:q], :name_or_number_or_objectid_cont)
= f.search_field :name_or_number_or_objectid_cont, placeholder: t('lines.index.name_or_number_or_objectid'), class: 'form-control'
span.input-group-btn
button.btn.btn-default#search-btn type='submit'
span.fa.fa-search
.ffg-row
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :network_id_eq_any)
= f.label Chouette::Line.human_attribute_name(:network_id), required: false, class: 'control-label'
= f.input :network_id_eq_any, collection: @line_referential.networks.order(name: :asc), as: :check_boxes, label: false, label_method: lambda{|l| ("" + l.name + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :company_id_eq_any)
= f.label Chouette::Line.human_attribute_name(:company_id), required: false, class: 'control-label'
= f.input :company_id_eq_any, collection: @line_referential.companies.order(name: :asc), as: :check_boxes, label: false, label_method: lambda{|l| ("" + l.name + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :transport_mode_eq_any)
= f.label Chouette::Line.human_attribute_name(:transport_mode), required: false, class: 'control-label'
= f.input :transport_mode_eq_any, collection: StifTransportModeEnumerations.sorted_transport_modes, as: :check_boxes, label: false, label_method: lambda{|l| ("" + t("enumerize.transport_mode.#{l}") + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :transport_submode_eq_any)
= f.label Chouette::Line.human_attribute_name(:transport_submode), required: false, class: 'control-label'
= f.input :transport_submode_eq_any, collection: StifTransportSubmodeEnumerations.sorted_transport_submodes, as: :check_boxes, label: false, label_method: lambda{|l| ("" + t("enumerize.transport_submode.#{l}") + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}
diff --git a/app/views/purchase_windows/_filters.html.slim b/app/views/purchase_windows/_filters.html.slim
index 4d7c8ce26..eedbf31d5 100644
--- a/app/views/purchase_windows/_filters.html.slim
+++ b/app/views/purchase_windows/_filters.html.slim
@@ -1,12 +1,12 @@
= search_form_for @q, url: referential_purchase_windows_path, builder: SimpleForm::FormBuilder, html: { method: :get, class: 'form form-filter' } do |f|
.ffg-row
- .input-group.search_bar
+ .input-group.search_bar class=filter_item_class(params[:q], :name_cont)
= f.search_field :name_cont, class: 'form-control', placeholder: t('purchase_windows.index.filter_placeholder')
span.input-group-btn
button.btn.btn-default#search_btn type='submit'
span.fa.fa-search
- .form-group
+ .form-group class=filter_item_class(params[:q], :contains_date)
= f.label Chouette::PurchaseWindow.human_attribute_name(:date), class: 'control-label'
= f.input :contains_date, as: :date, label: false, wrapper_html: { class: 'date smart_date' }, class: 'form-control', default: @date, include_blank: @date ? false : true
diff --git a/app/views/referential_lines/_filters.html.slim b/app/views/referential_lines/_filters.html.slim
index 379d6234f..501f61c16 100644
--- a/app/views/referential_lines/_filters.html.slim
+++ b/app/views/referential_lines/_filters.html.slim
@@ -1,13 +1,13 @@
= search_form_for @q, url: referential_line_path(@referential, @line), class: 'form form-filter' do |f|
.ffg-row
- .input-group.search_bar
+ .input-group.search_bar class=filter_item_class(params[:q], :name_or_objectid_cont)
= f.search_field :name_or_objectid_cont, class: 'form-control', placeholder: "Indiquez un nom d'itinéraire ou un ID..."
span.input-group-btn
button.btn.btn-default#search-btn type='submit'
span.fa.fa-search
.ffg-row
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :wayback_eq_any)
= f.label Chouette::Route.human_attribute_name(:wayback), required: false, class: 'control-label'
= f.input :wayback_eq_any, class: 'form-control', collection: Chouette::Route.wayback.values, as: :check_boxes, label: false, required: false, wrapper_html: { class: 'checkbox_list'}, label_method: lambda{|l| ("" + t("enumerize.route.wayback.#{l}") + " ").html_safe}
diff --git a/app/views/referential_vehicle_journeys/_filters.html.slim b/app/views/referential_vehicle_journeys/_filters.html.slim
index d3cb9eb4b..bd8245e39 100644
--- a/app/views/referential_vehicle_journeys/_filters.html.slim
+++ b/app/views/referential_vehicle_journeys/_filters.html.slim
@@ -9,14 +9,14 @@
.form-group.per-page-select
= I18n.t("simple_form.per_page")
= %w(10 50 100).each_with_index.map{ |v, i| (params[:per_page] == v || params[:per_page].nil? && i == 0) ? "#{v} " : link_to(v, referential_vehicle_journeys_path(@referential, q: params[:q], per_page: v)) }.join(' - ').html_safe
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :company_id_eq_any)
= f.label Chouette::VehicleJourney.human_attribute_name(:company), required: false, class: 'control-label'
- if @all_companies.present?
= f.input :company_id_eq_any, collection: @all_companies.select(:id, :name).order(name: :asc), as: :check_boxes, label: false, label_method: lambda{|l| ("" + l.name + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}
- else
= f.input :company_id_eq_any, collection: [[I18n.t('companies.search_no_results_for_filter'), nil]], as: :check_boxes, label: false, disabled: true, required: false, wrapper_html: { class: 'checkbox_list disabled'}
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :route_line_id_eq)
= f.label Chouette::Line.model_name.human,
required: false,
class: 'control-label'
@@ -25,7 +25,7 @@
as: :select,
include_blank: t(".all"),
collection: @vehicle_journeys.lines,
- selected: params[:q] && params[:q][:line_id],
+ selected: params[:q] && params[:q][:route_line_id_eq],
input_html: { \
'data-select2ed': 'true',
'data-select2ed-placeholder': t('referentials.filters.line') \
@@ -34,22 +34,22 @@
label_method: :display_name,
wrapper_html: { class: 'filter_menu-item select2ed' }
- .form-group.togglable.name-filter
+ .form-group.togglable.name-filter class=filter_item_class(params[:q], :published_journey_name_gteq)
= f.label Chouette::VehicleJourney.human_attribute_name(:published_journey_name), required: false, class: 'control-label'
.inputs.form-inline.checkbox_list
= f.input :published_journey_name_gteq, label: false, wrapper_html: { class: 'w45'}
.form-group.w10.to= I18n.t('vehicle_journeys.form.to')
= f.input :published_journey_name_lteq, label: false, wrapper_html: { class: 'w45'}
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :stop_area_ids)
= f.label Chouette::StopArea.model_name.human.pluralize, required: false, class: 'control-label'
= f.input :stop_area_ids, collection: @all_stop_areas.select(:id, :name, :kind).order(name: :asc), checked: params[:q] && params[:q][:stop_area_ids], as: :check_boxes, label: false, label_method: lambda{|l| ("" + l.name + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}, multiple: true
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :purchase_window)
= f.label Chouette::VehicleJourney.human_attribute_name(:purchase_window), class: 'control-label'
.filter_menu
= f.simple_fields_for :purchase_window do |p|
= p.input :start_date, as: :date, label: t('simple_form.from'), wrapper_html: { class: 'date smart_date filter_menu-item' }, default: @purchase_window_begin_range, include_blank: @purchase_window_begin_range ? false : true
= p.input :end_date, as: :date, label: t('simple_form.to'), wrapper_html: { class: 'date smart_date filter_menu-item' }, default: @purchase_window_end_range, include_blank: @purchase_window_end_range ? false : true
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :time_table)
= f.label Chouette::TimeTable.model_name.human, class: 'control-label'
.filter_menu
= f.simple_fields_for :time_table do |p|
diff --git a/app/views/referentials/_filters.html.slim b/app/views/referentials/_filters.html.slim
index 93fa679df..190e70ebe 100644
--- a/app/views/referentials/_filters.html.slim
+++ b/app/views/referentials/_filters.html.slim
@@ -1,21 +1,21 @@
= search_form_for @q, url: referential_path(@referential.id), class: 'form form-filter' do |f|
.ffg-row
- .input-group.search_bar
+ .input-group.search_bar class=filter_item_class(params[:q], :name_or_number_or_objectid_cont)
= f.search_field :name_or_number_or_objectid_cont, class: 'form-control', placeholder: t('.name_or_number_or_objectid')
span.input-group-btn
button.btn.btn-default type='submit'
span.fa.fa-search
.ffg-row
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :transport_mode_eq_any)
= f.label Chouette::Line.human_attribute_name(:transport_mode), required: false, class: 'control-label'
= f.input :transport_mode_eq_any, collection: @referential.lines.pluck(:transport_mode).uniq.compact, as: :check_boxes, label: false, label_method: lambda{|l| ("" + t("enumerize.transport_mode.#{l}") + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list' }
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :network_id_eq_any)
= f.label t('activerecord.attributes.referential.networks'), required: false, class: 'control-label'
= f.input :network_id_eq_any, collection: LineReferential.first.networks.order('name').pluck(:id), as: :check_boxes, label: false, label_method: lambda{|l| ("#{LineReferential.first.networks.find(l).name} ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list' }
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :company_id_eq_any)
= f.label t('activerecord.attributes.referential.companies'), required: false, class: 'control-label'
= f.input :company_id_eq_any, collection: LineReferential.first.companies.order('name').pluck(:id), as: :check_boxes, label: false, label_method: lambda{|l| ("#{LineReferential.first.companies.find(l).name} ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list' }
diff --git a/app/views/routing_constraint_zones/_filters.html.slim b/app/views/routing_constraint_zones/_filters.html.slim
index 433dde4ab..74e299a8b 100644
--- a/app/views/routing_constraint_zones/_filters.html.slim
+++ b/app/views/routing_constraint_zones/_filters.html.slim
@@ -1,13 +1,13 @@
= search_form_for @q, url: referential_line_routing_constraint_zones_path(@referential, @line), class: 'form form-filter' do |f|
.ffg-row
- .input-group.search_bar
+ .input-group.search_bar class=filter_item_class(params[:q], :name_or_objectid_cont)
= f.search_field :name_or_objectid_cont, class: 'form-control', placeholder: "Indiquez un nom d'ITL ou un ID..."
span.input-group-btn
button.btn.btn-default#search-btn type='submit'
span.fa.fa-search
.ffg-row
- .form-group
+ .form-group class=filter_item_class(params[:q], :route_id_eq)
= f.label 'Itinéraire associé', required: false, class: 'control-label'
= f.input :route_id_eq, as: :select, collection: @line.routing_constraint_zones.pluck(:route_id).uniq, label: false, label_method: lambda { |r| @line.routing_constraint_zones.find_by(route_id: r).route_name }, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': 'Indiquez un itinéraire...' }, wrapper_html: { class: 'select2ed'}
diff --git a/app/views/stop_areas/_filters.html.slim b/app/views/stop_areas/_filters.html.slim
index 90368dff4..1d71d477a 100644
--- a/app/views/stop_areas/_filters.html.slim
+++ b/app/views/stop_areas/_filters.html.slim
@@ -1,18 +1,18 @@
= search_form_for @q, url: stop_area_referential_stop_areas_path(@stop_area_referential), html: {method: :get}, class: 'form form-filter' do |f|
.ffg-row
- .input-group.search_bar
+ .input-group.search_bar class=filter_item_class(params[:q], :name_or_objectid_cont)
= f.search_field :name_or_objectid_cont, placeholder: t('.name_or_objectid'), class: 'form-control'
span.input-group-btn
button.btn.btn-default#search-btn type='submit'
span.fa.fa-search
.ffg-row
- = f.input :zip_code_cont, placeholder: t('.zip_code'), label: Chouette::StopArea.human_attribute_name(:zip_code), required: false
- = f.input :city_name_cont, placeholder: t('.city_name'), label: Chouette::StopArea.human_attribute_name(:city_name), required: false
+ = f.input :zip_code_cont, placeholder: t('.zip_code'), label: Chouette::StopArea.human_attribute_name(:zip_code), required: false, wrapper_html: {class: filter_item_class(params[:q], :zip_code_cont)}
+ = f.input :city_name_cont, placeholder: t('.city_name'), label: Chouette::StopArea.human_attribute_name(:city_name), required: false, wrapper_html: {class: filter_item_class(params[:q], :city_name_cont)}
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :area_type_eq_any)
= f.label Chouette::StopArea.human_attribute_name(:area_type), required: false, class: 'control-label'
- = f.input :area_type_eq_any, collection: Chouette::AreaType.options, as: :check_boxes, label: false, label_method: lambda{|w| ("" + w[0] + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list' }
+ = f.input :area_type_eq_any, checked: params[:q][:area_type_eq_any], collection: Chouette::AreaType.options, as: :check_boxes, label: false, label_method: lambda{|w| ("" + w[0] + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list' }
.actions
= link_to 'Effacer', @workbench, class: 'btn btn-link'
diff --git a/app/views/time_tables/_filter.html.slim b/app/views/time_tables/_filter.html.slim
index 11e9987c4..030036a13 100644
--- a/app/views/time_tables/_filter.html.slim
+++ b/app/views/time_tables/_filter.html.slim
@@ -1,17 +1,17 @@
= search_form_for @q, url: referential_time_tables_path(@referential), html: { method: :get, class: 'form form-filter' } do |f|
.ffg-row
- .input-group.search_bar
+ .input-group.search_bar class=filter_item_class(params[:q], :comment_cont)
= f.text_field :comment_cont, :placeholder => "#{t('time_tables.index.comment')}", class: 'form-control'
span.input-group-btn
button.btn.btn-default type='submit'
span.fa.fa-search
.ffg-row
- .form-group
+ .form-group class=filter_item_class(params[:q], :tag_search)
= f.label Chouette::TimeTable.human_attribute_name(:tag_search), required: false, class: 'control-label'
= f.input :tag_search, as: :tags, collection: Chouette::TimeTable.tags_on(:tags).pluck(:name), label: false, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': 'Indiquez une étiquette...' }, wrapper_html: { class: 'select2ed'}, include_blank: false, selected: params[:q] ? params[:q]['tag_search'] : nil
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :bounding_dates)
= f.label Chouette::TimeTable.human_attribute_name(:bounding_dates), required: false, class: 'control-label'
.filter_menu
= f.simple_fields_for :bounding_dates do |p|
diff --git a/app/views/workbenches/_filters.html.slim b/app/views/workbenches/_filters.html.slim
index 491749515..c9dd13d96 100644
--- a/app/views/workbenches/_filters.html.slim
+++ b/app/views/workbenches/_filters.html.slim
@@ -1,23 +1,23 @@
= search_form_for @q_for_form, url: workbench_path(@workbench.id), builder: SimpleForm::FormBuilder, class: 'form form-filter' do |f|
.ffg-row
- .input-group.search_bar
+ .input-group.search_bar class=filter_item_class(params[:q], :name_cont)
= f.search_field :name_cont, class: 'form-control', placeholder: t('referentials.filters.name')
span.input-group-btn
button.btn.btn-default type='submit'
span.fa.fa-search
.ffg-row
- .form-group
+ .form-group class=filter_item_class(params[:q], :associated_lines_id_eq)
= f.label t('activerecord.models.line.one').upcase, required: false, class: 'control-label'
= f.input :associated_lines_id_eq, as: :select, collection: @workbench.lines.includes(:company).order(:name), input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': t('referentials.filters.line') }, label: false, label_method: :display_name, wrapper_html: { class: 'select2ed'}
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :archived_at_not_null)
= f.label Referential.human_attribute_name(:status), required: false, class: 'control-label'
.form-group.checkbox_list
= f.input :archived_at_not_null, label: ("#{t('activerecord.attributes.referential.archived_at')} ").html_safe, as: :boolean, wrapper_html: { class: 'checkbox-wrapper' }
= f.input :archived_at_null, label: ("#{t('activerecord.attributes.referential.archived_at_null')} ").html_safe, as: :boolean, wrapper_html: { class: 'checkbox-wrapper' }
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :organisation_name_eq_any)
= f.label t('activerecord.models.organisation.one'), required: false, class: 'control-label'
= f.input :organisation_name_eq_any,
collection: @workbench.workgroup.organisations.order('name').pluck(:name),
@@ -27,7 +27,7 @@
required: false,
wrapper_html: { class: 'checkbox_list' }
- .form-group.togglable
+ .form-group.togglable class=filter_item_class(params[:q], :validity_period)
= f.label Referential.human_attribute_name(:validity_period), required: false, class: 'control-label'
.filter_menu
= f.simple_fields_for :validity_period do |p|
--
cgit v1.2.3
From 3404e2967e9b0aca7bac43eeb4f11d4280248e24 Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 2 Feb 2018 13:08:51 +0100
Subject: Refs #5835; Timetables inherit application days from calendars
---
app/controllers/time_tables_controller.rb | 2 +-
spec/controllers/time_tables_controller_spec.rb | 29 +++++++++++++++++++++++++
2 files changed, 30 insertions(+), 1 deletion(-)
create mode 100644 spec/controllers/time_tables_controller_spec.rb
diff --git a/app/controllers/time_tables_controller.rb b/app/controllers/time_tables_controller.rb
index 0707b9648..0dcadad1e 100644
--- a/app/controllers/time_tables_controller.rb
+++ b/app/controllers/time_tables_controller.rb
@@ -36,7 +36,6 @@ class TimeTablesController < ChouetteController
def create
tt_params = time_table_params
if tt_params[:calendar_id] && tt_params[:calendar_id] != ""
- %i(monday tuesday wednesday thursday friday saturday sunday).map { |d| tt_params[d] = true }
calendar = Calendar.find(tt_params[:calendar_id])
tt_params[:calendar_id] = nil if tt_params.has_key?(:dates_attributes) || tt_params.has_key?(:periods_attributes)
end
@@ -45,6 +44,7 @@ class TimeTablesController < ChouetteController
@time_table = created_from ? created_from.duplicate : Chouette::TimeTable.new(tt_params)
if calendar
+ @time_table.int_day_types = calendar.int_day_types
calendar.dates.each_with_index do |date, i|
@time_table.dates << Chouette::TimeTableDate.new(date: date, position: i, in_out: true)
end
diff --git a/spec/controllers/time_tables_controller_spec.rb b/spec/controllers/time_tables_controller_spec.rb
new file mode 100644
index 000000000..85f2c10e4
--- /dev/null
+++ b/spec/controllers/time_tables_controller_spec.rb
@@ -0,0 +1,29 @@
+RSpec.describe TimeTablesController, :type => :controller do
+ login_user
+
+ describe 'POST create' do
+ let(:request){ post :create, referential_id: referential.id, time_table: time_table_params }
+ let(:time_table_params){{comment: "test"}}
+
+ it "should create a timetable" do
+ expect{request}.to change{ Chouette::TimeTable.count }.by 1
+ expect(Chouette::TimeTable.last.comment).to eq "test"
+ %i(monday tuesday wednesday thursday friday saturday sunday).each do |d|
+ expect(Chouette::TimeTable.last.send(d)).to be_falsy
+ end
+ end
+
+ context "when given a calendar" do
+ let(:calendar){ create :calendar, int_day_types: Calendar::MONDAY | Calendar::SUNDAY }
+ let(:time_table_params){{comment: "test", calendar_id: calendar.id}}
+ it "should create a timetable" do
+ expect{request}.to change{ Chouette::TimeTable.count }.by 1
+ expect(Chouette::TimeTable.last.comment).to eq "test"
+ expect(Chouette::TimeTable.last.calendar).to eq calendar
+ %i(monday tuesday wednesday thursday friday saturday sunday).each do |d|
+ expect(Chouette::TimeTable.last.send(d)).to eq calendar.send(d)
+ end
+ end
+ end
+ end
+end
--
cgit v1.2.3
From b52ebf8920692125b3dde83893d1c7c5b43eeeec Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 19 Jan 2018 08:22:24 +0100
Subject: Refs #3542 @4h; First UI
Still missing:
- Pagination
- Filters
---
.../components/_referential_overview.sass | 171 ++++++++++++++++
app/helpers/referentials_helper.rb | 5 +
app/services/referential_overview.rb | 218 +++++++++++++++++++++
app/views/referentials/_overview.html.slim | 31 +++
app/views/referentials/show.html.slim | 2 +
config/locales/referentials.en.yml | 5 +
config/locales/referentials.fr.yml | 5 +
spec/services/referential_overview_spec.rb | 154 +++++++++++++++
8 files changed, 591 insertions(+)
create mode 100644 app/assets/stylesheets/components/_referential_overview.sass
create mode 100644 app/services/referential_overview.rb
create mode 100644 app/views/referentials/_overview.html.slim
create mode 100644 spec/services/referential_overview_spec.rb
diff --git a/app/assets/stylesheets/components/_referential_overview.sass b/app/assets/stylesheets/components/_referential_overview.sass
new file mode 100644
index 000000000..0af5a99f7
--- /dev/null
+++ b/app/assets/stylesheets/components/_referential_overview.sass
@@ -0,0 +1,171 @@
+.referential-overview
+ display: flex
+ margin-top: 50px
+ $left-size: 100px
+ .head
+ height: $left-size
+ border-top: 1px solid $lightgrey
+ .line
+ height: 80px
+ .left
+ flex: 0 0
+ background: $lightgrey
+ min-width: $left-size
+ overflow: hidden
+ border-right: 1px solid white
+ .head
+ position: relative
+ border-bottom: 1px solid white
+ border-right: 1px solid $lightgrey
+ .dates, .lines
+ position: absolute
+ font-size: 0.8em
+ z-index: 2
+ .dates
+ right: 20px
+ top: 20px
+ .lines
+ left: 20px
+ bottom: 20px
+ &:after
+ position: absolute
+ border-left: ($left-size - 2px)/2 solid transparent
+ border-bottom: ($left-size - 2px)/2 solid transparent
+ border-right: ($left-size - 2px)/2 solid white
+ border-top: ($left-size - 2px)/2 solid white
+ z-index: 1
+ top: 0
+ right: 0
+ width: 0
+ content: ""
+ .line
+ padding: 15px 10px 10px
+ border-bottom: 1px solid white
+ font-size: 0.8em
+ &:last-child
+ border-bottom: 1px solid $grey
+ .number
+ border-radius: 100px
+ display: inline-block
+ width: 20px
+ height: 20px
+ text-align: center
+ padding-top: 1px
+ text-decoration: none
+ color: black
+ border: 1px solid $grey
+ .name
+ display: inline-block
+ width: $left-size - 50px()
+ white-space: nowrap
+ line-height: 20px
+ margin-left: 5px
+ text-overflow: ellipsis
+ overflow: hidden
+ vertical-align: bottom
+ color: black
+ text-decoration: none
+
+ .company, .mode
+ font-size: 0.9em
+ margin-top: 5px
+ white-space: nowrap
+ text-overflow: ellipsis
+ overflow: hidden
+
+ .mode
+ margin-top: 0
+ text-transform: uppercase
+ color: $grey
+ font-weight: bold
+ .right
+ flex: 1 1
+ overflow-x: scroll
+ overflow-y: hidden
+ .head
+ white-space: nowrap
+ .week
+ display: inline-block
+ position: relative
+ height: 100%
+ .week-span
+ left: 5px
+ top: 10px
+ right: 30px
+ white-space: nowrap
+ overflow: hidden
+ text-overflow: ellipsis
+ position: absolute
+
+ .week-number
+ background-color: lightgrey
+ color: white
+ position: absolute
+ top: 0
+ right: 0
+ padding: 2px 4px
+
+ &:after
+ position: absolute
+ right: 0
+ top: 0
+ bottom: 0
+ background: $grey
+ width: 1px
+ content: ""
+
+ .days
+ position: relative
+ top: 50%
+ height: 50%
+ border-top: 1px solid $grey
+ border-bottom: 1px solid $grey
+
+ .day
+ float: left
+ border-left: 1px solid $grey
+ box-sizing: border-box
+ padding-left: 5px
+ padding-top: 3px
+ position: relative
+ height: 100%
+ .name, .number
+ position: absolute
+ left: 10px
+ right: 10px
+ top: 50%
+ transform: translateY(-50%)
+ margin-top: 10px
+ .name
+ font-weight: bold
+ font-size: 0.8em
+ margin-top: -10px
+ &:first-child
+ border: none
+ &.weekend
+ background: $lightgrey
+
+ .line
+ border-bottom: 1px solid $grey
+ position: relative
+ overflow: hidden
+
+ .period
+ height: 100%
+ top: 0
+ background: rgb(219, 249, 196)
+ position: absolute
+ &:before
+ content: ""
+ border-right: 1px dashed $grey
+ top: -100%
+ bottom: -100%
+ position: absolute
+ right: -1px
+ z-index: 10
+ &.empty
+ background: rgb(244, 67, 67)
+ background: repeating-linear-gradient(-45deg, #f5e1cf,#f5e1cf 10px,#e49393 10px,#e49393 20px)
+ &.accepted
+ background: #f19039
+ background: repeating-linear-gradient(-45deg, #f5e1cf,#f5e1cf 10px,#f19039 10px,#f19039 20px)
diff --git a/app/helpers/referentials_helper.rb b/app/helpers/referentials_helper.rb
index 01e5a5879..8251377aa 100644
--- a/app/helpers/referentials_helper.rb
+++ b/app/helpers/referentials_helper.rb
@@ -10,4 +10,9 @@ module ReferentialsHelper
t('true')
end
end
+
+ def referential_overview referential
+ service = ReferentialOverview.new referential, self
+ render partial: "referentials/overview", locals: {referential: referential, overview: service}
+ end
end
diff --git a/app/services/referential_overview.rb b/app/services/referential_overview.rb
new file mode 100644
index 000000000..5b0e144db
--- /dev/null
+++ b/app/services/referential_overview.rb
@@ -0,0 +1,218 @@
+class ReferentialOverview
+ attr_reader :h
+
+ def initialize referential, h
+ @referential = referential
+ @page = 1
+ @h = h
+ end
+
+ def lines
+ @referential.metadatas_lines.includes(:company).page(@page).map{|l| Line.new(l, @referential, period.first, h)}
+ end
+
+ def period
+ @period ||= @referential.metadatas_period || []
+ end
+
+ def weeks
+ @weeks = {}
+ period.map do |d|
+ @weeks[Week.key(d)] ||= Week.new(d, period.last, h)
+ end
+ @weeks.values
+ end
+
+ class Line
+ attr_reader :h
+ attr_reader :referential_line
+
+ delegate :name, :number, :company, :color, :transport_mode, to: :referential_line
+
+ def initialize line, referential, start, h
+ @referential_line = line
+ @referential = referential
+ @start = start
+ @h = h
+ end
+
+ def period
+ @period ||= @referential.metadatas_period || []
+ end
+
+ def referential_periods
+ @referential_periods ||= @referential.metadatas.include_lines([@referential_line.id]).map(&:periodes).flatten.sort{|p1, p2| p1.first <=> p2.first}
+ end
+
+ def periods
+ @periods ||= begin
+ periods = referential_periods.flatten.map{|p| Period.new p, @start, h}
+ periods = fill_periods periods
+ periods = merge_periods periods
+ periods
+ end
+ end
+
+ def fill_periods periods
+ [].tap do |out|
+ previous = OpenStruct.new(end: period.first - 1.day)
+ (periods + [OpenStruct.new(start: period.last + 1.day)]).each do |p|
+ if p.start > previous.end + 1.day
+ out << Period.new((previous.end+1.day..p.start-1.day), @start, h).tap{|p| p.empty = true}
+ end
+ out << p if p.respond_to?(:end)
+ previous = p
+ end
+ end
+ end
+
+ def merge_periods periods
+ [].tap do |out|
+ current = periods.first
+ periods[1..-1].each do |p|
+ if p.start <= current.end
+ current.end = p.end
+ else
+ out << current
+ current = p
+ end
+ end
+ out << current
+ end
+ end
+
+ def width
+ period.count * Day::WIDTH
+ end
+
+ def html_style
+ {
+ width: "#{width}px"
+ }.map{|k, v| "#{k}: #{v}"}.join("; ")
+ end
+
+ def html_class
+ out = []
+ out
+ end
+
+ class Period
+ attr_accessor :empty
+ attr_accessor :h
+
+ def initialize period, start, h
+ @period = period
+ @start = start
+ @empty = false
+ @h = h
+ end
+
+ def start
+ @period.first
+ end
+
+ def end
+ @period.last
+ end
+
+ def end= val
+ @period = (start..val)
+ end
+
+ def width
+ @period.count * Day::WIDTH
+ end
+
+ def left
+ (@period.first - @start).to_i * Day::WIDTH
+ end
+
+ def html_style
+ {
+ width: "#{width}px",
+ left: "#{left}px",
+ }.map{|k, v| "#{k}: #{v}"}.join("; ")
+ end
+
+ def empty?
+ @empty
+ end
+
+ def accepted?
+ @period.count < 7
+ end
+
+ def title
+ h.l(self.start, format: :short) + " - " + h.l(self.end, format: :short)
+ end
+
+ def html_class
+ out = []
+ out << "empty" if empty?
+ out << "accepted" if accepted?
+ out
+ end
+ end
+ end
+
+ class Week
+ attr_reader :h
+ attr_reader :start_date
+ attr_reader :end_date
+
+ def initialize start_date, boundary, h
+ @start_date = start_date.to_date
+ @end_date = [start_date.end_of_week, boundary].min.to_date
+ @h = h
+ end
+
+ def self.key date
+ date.beginning_of_week.to_s
+ end
+
+ def span
+ h.l(@start_date, format: "#{@start_date.day}-#{@end_date.day} %b")
+ end
+
+ def number
+ h.l(@start_date, format: "%W")
+ end
+
+ def period
+ (@start_date..@end_date)
+ end
+
+ def days
+ period.map {|d| Day.new d, h }
+ end
+ end
+
+ class Day
+ attr_reader :h
+
+ WIDTH=50
+
+ def initialize date, h
+ @date = date
+ @h = h
+ end
+
+ def html_style
+ {width: "#{WIDTH}px"}.map{|k, v| "#{k}: #{v}"}.join("; ")
+ end
+
+ def html_class
+ out = []
+ out << "weekend" if [0, 6].include?(@date.wday)
+ out
+ end
+
+ def short_name
+ h.l(@date, format: "%a")
+ end
+
+ def number
+ @date.day
+ end
+ end
+end
diff --git a/app/views/referentials/_overview.html.slim b/app/views/referentials/_overview.html.slim
new file mode 100644
index 000000000..03c72752e
--- /dev/null
+++ b/app/views/referentials/_overview.html.slim
@@ -0,0 +1,31 @@
+.referential-overview
+ .left
+ .head
+ .dates= I18n.t("referentials.overview.head.dates")
+ .lines= I18n.t("referentials.overview.head.lines")
+ .lines
+ - overview.lines.each do |line|
+ .line
+ a.number style="background-color: #{line.color.present? ? "##{line.color}" : 'whitesmoke'}" title=line.name
+ = line.number
+ - unless line.number == line.name
+ a.name title=line.name
+ = line.name
+ .company= line.company&.name
+ .mode= line.transport_mode
+ .right
+ .head
+ - overview.weeks.each do |week|
+ .week
+ .week-span= week.span
+ .week-number= week.number
+ .days
+ - week.days.each do |day|
+ .day style=day.html_style class=day.html_class
+ .name= day.short_name
+ .number= day.number
+ .lines
+ - overview.lines.each do |line|
+ .line style=line.html_style class=line.html_class
+ - line.periods.each do |period|
+ .period style=period.html_style class=period.html_class title=period.title
diff --git a/app/views/referentials/show.html.slim b/app/views/referentials/show.html.slim
index 6c88f5b81..289e802d7 100644
--- a/app/views/referentials/show.html.slim
+++ b/app/views/referentials/show.html.slim
@@ -67,6 +67,8 @@
= replacement_msg t('referential_lines.search_no_results')
+ = referential_overview resource
+
/ Modal(s)
= modalbox 'purgeModal' do
= simple_form_for [@referential, CleanUp.new] do |f|
diff --git a/config/locales/referentials.en.yml b/config/locales/referentials.en.yml
index eb8eae98d..dd7f776fd 100644
--- a/config/locales/referentials.en.yml
+++ b/config/locales/referentials.en.yml
@@ -48,6 +48,11 @@ en:
overlapped_referential: "%{referential} cover the same perimeter"
overlapped_period: "Another period is on the same period"
short_period: Min period length is two days
+ overview:
+ head:
+ dates: Dates
+ lines: Lignes
+
activerecord:
models:
referential:
diff --git a/config/locales/referentials.fr.yml b/config/locales/referentials.fr.yml
index 37af8a4eb..48b98214e 100644
--- a/config/locales/referentials.fr.yml
+++ b/config/locales/referentials.fr.yml
@@ -48,6 +48,11 @@ fr:
overlapped_referential: "%{referential} couvre le même périmètre d'offre"
overlapped_period: "Une autre période chevauche cette période"
short_period: "La durée minimum d'une période est de deux jours"
+ overview:
+ head:
+ dates: Dates
+ lines: Lignes
+
activerecord:
models:
referential:
diff --git a/spec/services/referential_overview_spec.rb b/spec/services/referential_overview_spec.rb
new file mode 100644
index 000000000..39a90360a
--- /dev/null
+++ b/spec/services/referential_overview_spec.rb
@@ -0,0 +1,154 @@
+RSpec.describe ReferentialOverview do
+
+ subject{ described_class }
+
+end
+
+RSpec.describe ReferentialOverview::Week do
+
+ describe "#initialize" do
+ it "should respect the boundary" do
+ week = ReferentialOverview::Week.new(Time.now.beginning_of_week, 1.week.from_now, {})
+ expect(week.start_date).to eq Time.now.beginning_of_week.to_date
+ expect(week.end_date).to eq Time.now.end_of_week.to_date
+
+ week = ReferentialOverview::Week.new(Time.now.beginning_of_week, Time.now, {})
+ expect(week.start_date).to eq Time.now.beginning_of_week.to_date
+ expect(week.end_date).to eq Time.now.to_date
+ end
+ end
+end
+
+RSpec.describe ReferentialOverview::Line do
+
+ let(:ref_line){create(:line)}
+ let(:referential){create(:referential)}
+ let(:start){2.days.ago}
+ let(:period_1){(10.days.ago..8.days.ago)}
+ let(:period_2){(5.days.ago..1.days.ago)}
+
+ subject(:line){ReferentialOverview::Line.new ref_line, referential, start, {}}
+
+ before(:each) do
+ create(:referential_metadata, referential: referential, line_ids: [ref_line.id], periodes: [period_1, period_2].compact)
+ end
+
+ describe "#width" do
+ it "should have the right value" do
+ expect(line.width).to eq ReferentialOverview::Day::WIDTH * referential.metadatas_period.count
+ end
+ end
+
+ describe "#periods" do
+ context "when the periodes are split into several metadatas" do
+ let(:period_2){nil}
+ before do
+ create(:referential_metadata, referential: referential, line_ids: [ref_line.id], periodes: [(17.days.ago..11.days.ago)])
+ end
+ it "should find them all" do
+ expect(line.periods.count).to eq 2
+ expect(line.periods[0].empty?).to be_falsy
+ expect(line.periods[1].empty?).to be_falsy
+ end
+
+ context "when the periodes overlap" do
+ let(:period_2){nil}
+ before do
+ create(:referential_metadata, referential: referential, line_ids: [ref_line.id], periodes: [(17.days.ago..9.days.ago)])
+ end
+ it "should merge them" do
+ expect(line.periods.count).to eq 1
+ expect(line.periods[0].empty?).to be_falsy
+ expect(line.periods[0].start).to eq 17.days.ago.to_date
+ expect(line.periods[0].end).to eq 8.days.ago.to_date
+ end
+ end
+ end
+ end
+
+ describe "#fill_periods" do
+ it "should fill the voids" do
+ expect(line.periods.count).to eq 3
+ expect(line.periods[0].empty?).to be_falsy
+ expect(line.periods[1].empty?).to be_truthy
+ expect(line.periods[1].accepted?).to be_truthy
+ expect(line.periods[2].empty?).to be_falsy
+ end
+
+ context "with no void" do
+ let(:period_1){(10.days.ago..8.days.ago)}
+ let(:period_2){(7.days.ago..1.days.ago)}
+
+ it "should find no void" do
+ expect(line.periods.count).to eq 2
+ expect(line.periods[0].empty?).to be_falsy
+ expect(line.periods[1].empty?).to be_falsy
+ end
+ end
+
+ context "with a large void" do
+ let(:period_1){(20.days.ago..19.days.ago)}
+ let(:period_2){(2.days.ago..1.days.ago)}
+
+ it "should fill the void" do
+ expect(line.periods.count).to eq 3
+ expect(line.periods[0].empty?).to be_falsy
+ expect(line.periods[1].empty?).to be_truthy
+ expect(line.periods[1].accepted?).to be_falsy
+ expect(line.periods[2].empty?).to be_falsy
+ end
+ end
+
+ context "with a void at the end" do
+ before do
+ create(:referential_metadata, referential: referential, periodes: [(2.days.ago..1.days.ago)])
+ end
+ let(:period_1){(20.days.ago..19.days.ago)}
+ let(:period_2){nil}
+
+ it "should fill the void" do
+ expect(line.periods.count).to eq 2
+ expect(line.periods[0].empty?).to be_falsy
+ expect(line.periods[1].empty?).to be_truthy
+ expect(line.periods[1].accepted?).to be_falsy
+ expect(line.periods[1].end).to eq 1.days.ago.to_date
+ end
+ end
+
+ context "with a void at the beginning" do
+ before do
+ create(:referential_metadata, referential: referential, periodes: [(200.days.ago..199.days.ago)])
+ end
+ let(:period_1){(20.days.ago..19.days.ago)}
+ let(:period_2){nil}
+
+ it "should fill the void" do
+ expect(line.periods.count).to eq 2
+ expect(line.periods[0].start).to eq 200.days.ago.to_date
+ expect(line.periods[0].empty?).to be_truthy
+ expect(line.periods[0].accepted?).to be_falsy
+ expect(line.periods[1].empty?).to be_falsy
+ end
+ end
+ end
+end
+
+RSpec.describe ReferentialOverview::Line::Period do
+
+ let(:period){(1.day.ago.to_date..Time.now.to_date)}
+ let(:start){2.days.ago}
+
+ subject(:line_period){ReferentialOverview::Line::Period.new period, start, nil}
+
+ describe "#width" do
+ it "should have the right value" do
+ expect(line_period.width).to eq ReferentialOverview::Day::WIDTH * 2
+ end
+ end
+
+ describe "#left" do
+ it "should have the right value" do
+ expect(line_period.width).to eq ReferentialOverview::Day::WIDTH * 1
+ end
+ end
+end
--
cgit v1.2.3
From 604e1c8f3077c83cc8d083e7d952fa411d8adb16 Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 19 Jan 2018 08:50:52 +0100
Subject: Refs #3542; Adds pagination
---
.../components/_referential_overview.sass | 307 +++++++++++----------
app/helpers/pagination_helper.rb | 2 +-
app/services/referential_overview.rb | 21 +-
app/views/referentials/_overview.html.slim | 63 +++--
4 files changed, 207 insertions(+), 186 deletions(-)
diff --git a/app/assets/stylesheets/components/_referential_overview.sass b/app/assets/stylesheets/components/_referential_overview.sass
index 0af5a99f7..5fae8080c 100644
--- a/app/assets/stylesheets/components/_referential_overview.sass
+++ b/app/assets/stylesheets/components/_referential_overview.sass
@@ -1,171 +1,172 @@
.referential-overview
- display: flex
- margin-top: 50px
- $left-size: 100px
- .head
- height: $left-size
- border-top: 1px solid $lightgrey
- .line
- height: 80px
- .left
- flex: 0 0
- background: $lightgrey
- min-width: $left-size
- overflow: hidden
- border-right: 1px solid white
+ .overview-table
+ display: flex
+ margin-top: 50px
+ $left-size: 100px
.head
- position: relative
- border-bottom: 1px solid white
- border-right: 1px solid $lightgrey
- .dates, .lines
- position: absolute
- font-size: 0.8em
- z-index: 2
- .dates
- right: 20px
- top: 20px
- .lines
- left: 20px
- bottom: 20px
- &:after
- position: absolute
- border-left: ($left-size - 2px)/2 solid transparent
- border-bottom: ($left-size - 2px)/2 solid transparent
- border-right: ($left-size - 2px)/2 solid white
- border-top: ($left-size - 2px)/2 solid white
- z-index: 1
- top: 0
- right: 0
- width: 0
- content: ""
+ height: $left-size
+ border-top: 1px solid $lightgrey
.line
- padding: 15px 10px 10px
- border-bottom: 1px solid white
- font-size: 0.8em
- &:last-child
- border-bottom: 1px solid $grey
- .number
- border-radius: 100px
- display: inline-block
- width: 20px
- height: 20px
- text-align: center
- padding-top: 1px
- text-decoration: none
- color: black
- border: 1px solid $grey
- .name
- display: inline-block
- width: $left-size - 50px()
- white-space: nowrap
- line-height: 20px
- margin-left: 5px
- text-overflow: ellipsis
- overflow: hidden
- vertical-align: bottom
- color: black
- text-decoration: none
-
- .company, .mode
- font-size: 0.9em
- margin-top: 5px
- white-space: nowrap
- text-overflow: ellipsis
- overflow: hidden
-
- .mode
- margin-top: 0
- text-transform: uppercase
- color: $grey
- font-weight: bold
- .right
- flex: 1 1
- overflow-x: scroll
- overflow-y: hidden
- .head
- white-space: nowrap
- .week
- display: inline-block
+ height: 80px
+ .left
+ flex: 0 0
+ background: $lightgrey
+ min-width: $left-size
+ overflow: hidden
+ border-right: 1px solid white
+ .head
position: relative
- height: 100%
- .week-span
- left: 5px
- top: 10px
- right: 30px
- white-space: nowrap
- overflow: hidden
- text-overflow: ellipsis
- position: absolute
-
- .week-number
- background-color: lightgrey
- color: white
+ border-bottom: 1px solid white
+ border-right: 1px solid $lightgrey
+ .dates, .lines
position: absolute
- top: 0
- right: 0
- padding: 2px 4px
-
+ font-size: 0.8em
+ z-index: 2
+ .dates
+ right: 20px
+ top: 20px
+ .lines
+ left: 20px
+ bottom: 20px
&:after
position: absolute
- right: 0
+ border-left: ($left-size - 2px)/2 solid transparent
+ border-bottom: ($left-size - 2px)/2 solid transparent
+ border-right: ($left-size - 2px)/2 solid white
+ border-top: ($left-size - 2px)/2 solid white
+ z-index: 1
top: 0
- bottom: 0
- background: $grey
- width: 1px
+ right: 0
+ width: 0
content: ""
-
- .days
- position: relative
- top: 50%
- height: 50%
- border-top: 1px solid $grey
+ .line
+ padding: 15px 10px 10px
+ border-bottom: 1px solid white
+ font-size: 0.8em
+ &:last-child
border-bottom: 1px solid $grey
+ .number
+ border-radius: 100px
+ display: inline-block
+ width: 20px
+ height: 20px
+ text-align: center
+ padding-top: 1px
+ text-decoration: none
+ color: black
+ border: 1px solid $grey
+ .name
+ display: inline-block
+ width: $left-size - 50px()
+ white-space: nowrap
+ line-height: 20px
+ margin-left: 5px
+ text-overflow: ellipsis
+ overflow: hidden
+ vertical-align: bottom
+ color: black
+ text-decoration: none
- .day
- float: left
- border-left: 1px solid $grey
- box-sizing: border-box
- padding-left: 5px
- padding-top: 3px
+ .company, .mode
+ font-size: 0.9em
+ margin-top: 5px
+ white-space: nowrap
+ text-overflow: ellipsis
+ overflow: hidden
+
+ .mode
+ margin-top: 0
+ text-transform: uppercase
+ color: $grey
+ font-weight: bold
+ .right
+ flex: 1 1
+ overflow-x: scroll
+ overflow-y: hidden
+ .head
+ white-space: nowrap
+ .week
+ display: inline-block
position: relative
height: 100%
- .name, .number
+ .week-span
+ left: 5px
+ top: 10px
+ right: 30px
+ white-space: nowrap
+ overflow: hidden
+ text-overflow: ellipsis
position: absolute
- left: 10px
- right: 10px
+
+ .week-number
+ background-color: lightgrey
+ color: white
+ position: absolute
+ top: 0
+ right: 0
+ padding: 2px 4px
+
+ &:after
+ position: absolute
+ right: 0
+ top: 0
+ bottom: 0
+ background: $grey
+ width: 1px
+ content: ""
+
+ .days
+ position: relative
top: 50%
- transform: translateY(-50%)
- margin-top: 10px
- .name
- font-weight: bold
- font-size: 0.8em
- margin-top: -10px
- &:first-child
- border: none
- &.weekend
- background: $lightgrey
+ height: 50%
+ border-top: 1px solid $grey
+ border-bottom: 1px solid $grey
- .line
- border-bottom: 1px solid $grey
- position: relative
- overflow: hidden
+ .day
+ float: left
+ border-left: 1px solid $grey
+ box-sizing: border-box
+ padding-left: 5px
+ padding-top: 3px
+ position: relative
+ height: 100%
+ .name, .number
+ position: absolute
+ left: 10px
+ right: 10px
+ top: 50%
+ transform: translateY(-50%)
+ margin-top: 10px
+ .name
+ font-weight: bold
+ font-size: 0.8em
+ margin-top: -10px
+ &:first-child
+ border: none
+ &.weekend
+ background: $lightgrey
+
+ .line
+ border-bottom: 1px solid $grey
+ position: relative
+ overflow: hidden
- .period
- height: 100%
- top: 0
- background: rgb(219, 249, 196)
- position: absolute
- &:before
- content: ""
- border-right: 1px dashed $grey
- top: -100%
- bottom: -100%
+ .period
+ height: 100%
+ top: 0
+ background: rgb(219, 249, 196)
position: absolute
- right: -1px
- z-index: 10
- &.empty
- background: rgb(244, 67, 67)
- background: repeating-linear-gradient(-45deg, #f5e1cf,#f5e1cf 10px,#e49393 10px,#e49393 20px)
- &.accepted
- background: #f19039
- background: repeating-linear-gradient(-45deg, #f5e1cf,#f5e1cf 10px,#f19039 10px,#f19039 20px)
+ &:before
+ content: ""
+ border-right: 1px dashed $grey
+ top: -100%
+ bottom: -100%
+ position: absolute
+ right: -1px
+ z-index: 10
+ &.empty
+ background: rgb(244, 67, 67)
+ background: repeating-linear-gradient(-45deg, #f5e1cf,#f5e1cf 10px,#e49393 10px,#e49393 20px)
+ &.accepted
+ background: #f19039
+ background: repeating-linear-gradient(-45deg, #f5e1cf,#f5e1cf 10px,#f19039 10px,#f19039 20px)
diff --git a/app/helpers/pagination_helper.rb b/app/helpers/pagination_helper.rb
index 02eec39dc..9b6042377 100644
--- a/app/helpers/pagination_helper.rb
+++ b/app/helpers/pagination_helper.rb
@@ -25,7 +25,7 @@ module PaginationHelper
if collection.total_pages > 1
links = content_tag :div, '', class: 'page_links' do
- will_paginate collection, container: false, page_links: false, previous_label: '', next_label: ''
+ will_paginate collection, container: false, page_links: false, previous_label: '', next_label: '', param_name: collection.try(:pagination_param_name)
end
content_tag :div, pinfos.concat(links).html_safe, class: "pagination #{cls}"
diff --git a/app/services/referential_overview.rb b/app/services/referential_overview.rb
index 5b0e144db..14e917bbe 100644
--- a/app/services/referential_overview.rb
+++ b/app/services/referential_overview.rb
@@ -1,14 +1,16 @@
class ReferentialOverview
attr_reader :h
+ PER_PAGE = 10
+
def initialize referential, h
@referential = referential
- @page = 1
+ @page = h.params[pagination_param_name]&.to_i || 1
@h = h
end
def lines
- @referential.metadatas_lines.includes(:company).page(@page).map{|l| Line.new(l, @referential, period.first, h)}
+ referential_lines.includes(:company).map{|l| Line.new(l, @referential, period.first, h)}
end
def period
@@ -23,6 +25,21 @@ class ReferentialOverview
@weeks.values
end
+ def referential_lines
+ @referential.metadatas_lines.page(@page).per_page(PER_PAGE)
+ end
+
+ ### Pagination
+
+ delegate :empty?, :first, :total_pages, :size, :total_entries, :offset, :length, to: :referential_lines
+ def current_page
+ @page
+ end
+
+ def pagination_param_name
+ "referential_#{@referential.slug}_overview"
+ end
+
class Line
attr_reader :h
attr_reader :referential_line
diff --git a/app/views/referentials/_overview.html.slim b/app/views/referentials/_overview.html.slim
index 03c72752e..6dd129405 100644
--- a/app/views/referentials/_overview.html.slim
+++ b/app/views/referentials/_overview.html.slim
@@ -1,31 +1,34 @@
.referential-overview
- .left
- .head
- .dates= I18n.t("referentials.overview.head.dates")
- .lines= I18n.t("referentials.overview.head.lines")
- .lines
- - overview.lines.each do |line|
- .line
- a.number style="background-color: #{line.color.present? ? "##{line.color}" : 'whitesmoke'}" title=line.name
- = line.number
- - unless line.number == line.name
- a.name title=line.name
- = line.name
- .company= line.company&.name
- .mode= line.transport_mode
- .right
- .head
- - overview.weeks.each do |week|
- .week
- .week-span= week.span
- .week-number= week.number
- .days
- - week.days.each do |day|
- .day style=day.html_style class=day.html_class
- .name= day.short_name
- .number= day.number
- .lines
- - overview.lines.each do |line|
- .line style=line.html_style class=line.html_class
- - line.periods.each do |period|
- .period style=period.html_style class=period.html_class title=period.title
+ .overview-table
+ .left
+ .head
+ .dates= I18n.t("referentials.overview.head.dates")
+ .lines= I18n.t("referentials.overview.head.lines")
+ .lines
+ - overview.lines.each do |line|
+ .line
+ a.number style="background-color: #{line.color.present? ? "##{line.color}" : 'whitesmoke'}" title=line.name
+ = line.number
+ - unless line.number == line.name
+ a.name title=line.name
+ = line.name
+ .company= line.company&.name
+ .mode= line.transport_mode
+ .right
+ .head
+ - overview.weeks.each do |week|
+ .week
+ .week-span= week.span
+ .week-number= week.number
+ .days
+ - week.days.each do |day|
+ .day style=day.html_style class=day.html_class
+ .name= day.short_name
+ .number= day.number
+ .lines
+ - overview.lines.each do |line|
+ .line style=line.html_style class=line.html_class
+ - line.periods.each do |period|
+ .period style=period.html_style class=period.html_class title=period.title
+
+ = new_pagination overview, 'pull-right'
--
cgit v1.2.3
From 04f123b9fa324c77c3ebfaa199164e65d575c9ad Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 19 Jan 2018 10:17:43 +0100
Subject: Refs #3542 @1h; Add Time navigation
---
.../components/_referential_overview.sass | 44 +++++++++++---
.../packs/referential_overview/overview.js | 1 +
app/javascript/referential_overview/index.coffee | 69 ++++++++++++++++++++++
app/services/referential_overview.rb | 7 ++-
app/views/referentials/_overview.html.slim | 47 ++++++++++-----
config/locales/referentials.en.yml | 5 +-
config/locales/referentials.fr.yml | 3 +
7 files changed, 151 insertions(+), 25 deletions(-)
create mode 100644 app/javascript/packs/referential_overview/overview.js
create mode 100644 app/javascript/referential_overview/index.coffee
diff --git a/app/assets/stylesheets/components/_referential_overview.sass b/app/assets/stylesheets/components/_referential_overview.sass
index 5fae8080c..a25c49272 100644
--- a/app/assets/stylesheets/components/_referential_overview.sass
+++ b/app/assets/stylesheets/components/_referential_overview.sass
@@ -1,11 +1,22 @@
.referential-overview
+ margin-top: 50px
+ .time-travel
+ background-color: $grey
+ padding: 10px
+ float: right
+ border-top-left-radius: 10px
+ border-top-right-radius: 10px
+ a.btn:first-child
+ border-right: 1px solid $grey
+ a.btn:last-child
+ border-left: 1px solid $grey
.overview-table
+ border: 1px solid $grey
+ clear: both
display: flex
- margin-top: 50px
$left-size: 100px
.head
height: $left-size
- border-top: 1px solid $lightgrey
.line
height: 80px
.left
@@ -16,7 +27,7 @@
border-right: 1px solid white
.head
position: relative
- border-bottom: 1px solid white
+ border-bottom: 1px solid $grey
border-right: 1px solid $lightgrey
.dates, .lines
position: absolute
@@ -41,10 +52,10 @@
content: ""
.line
padding: 15px 10px 10px
- border-bottom: 1px solid white
+ border-bottom: 1px solid $grey
font-size: 0.8em
&:last-child
- border-bottom: 1px solid $grey
+ border-bottom: none
.number
border-radius: 100px
display: inline-block
@@ -81,8 +92,9 @@
font-weight: bold
.right
flex: 1 1
- overflow-x: scroll
- overflow-y: hidden
+ overflow: hidden
+ .inner
+ transition: margin 0.5s
.head
white-space: nowrap
.week
@@ -145,11 +157,29 @@
border: none
&.weekend
background: $lightgrey
+ &.today, &:hover
+ color: $blue
+ background-color: transparentize($blue, 0.7)
+ &:after
+ content: ""
+ left: -1px
+ right: -1px
+ top: 100%
+ height: 10000px
+ background-color: transparentize($blue, 0.7)
+ position: absolute
+ z-index: 4
+ &:hover
+ background-color: transparentize(white, 0.7)
+ &:after
+ background-color: transparentize(white, 0.7)
.line
border-bottom: 1px solid $grey
position: relative
overflow: hidden
+ &:last-child
+ border-bottom: none
.period
height: 100%
diff --git a/app/javascript/packs/referential_overview/overview.js b/app/javascript/packs/referential_overview/overview.js
new file mode 100644
index 000000000..59c326e9a
--- /dev/null
+++ b/app/javascript/packs/referential_overview/overview.js
@@ -0,0 +1 @@
+import ReferentialOverview from '../../referential_overview'
diff --git a/app/javascript/referential_overview/index.coffee b/app/javascript/referential_overview/index.coffee
new file mode 100644
index 000000000..8dd0e3561
--- /dev/null
+++ b/app/javascript/referential_overview/index.coffee
@@ -0,0 +1,69 @@
+class TimeTravel
+ constructor: (@overview)->
+ @container = @overview.container.find('.time-travel')
+ @todayBt = @container.find(".today")
+ @prevBt = @container.find(".prev-page")
+ @nextBt = @container.find(".next-page")
+ @initButtons()
+
+ initButtons: ->
+ @prevBt.click (e)=>
+ @overview.prevPage()
+ e.preventDefault()
+ false
+
+ @nextBt.click (e)=>
+ @overview.nextPage()
+ e.preventDefault()
+ false
+
+ @todayBt.click (e)=>
+ today = new Date()
+ month = today.getMonth() + 1
+ month = "0#{month}" if month < 10
+ day = today.getDate()
+ day = "0#{month}" if day < 10
+ @overview.showDay "#{today.getFullYear()}-#{month}-#{day}"
+ e.preventDefault()
+ false
+
+ scrolledTo: (progress)->
+ console.log "scrolledTo: #{progress*100}%"
+ @prevBt.removeClass 'disabled'
+ @nextBt.removeClass 'disabled'
+ @prevBt.addClass 'disabled' if progress == 0
+ @nextBt.addClass 'disabled' if progress == 1
+
+class window.ReferentialOverview
+ constructor: (selector)->
+ @container = $(selector)
+ @timeTravel = new TimeTravel(this)
+ @currentOffset = 0
+
+ showDay: (date)->
+ day = @container.find(".day.#{date}")
+ offset = day.offset().left
+ parentOffset = @container.find(".right .inner").offset().left
+ @scrollTo parentOffset - offset
+
+ currentOffset: ->
+ @container.find(".right .inner").offset().left
+
+ prevPage: ->
+ @scrollTo @currentOffset + @container.find(".right").width()
+
+ nextPage: ->
+ @scrollTo @currentOffset - @container.find(".right").width()
+
+ minOffset: ->
+ @_minOffset ||= @container.find(".right").width() - @container.find(".right .line").width()
+ @_minOffset
+
+ scrollTo: (offset)->
+ @currentOffset = offset
+ @currentOffset = Math.max(@currentOffset, @minOffset())
+ @currentOffset = Math.min(@currentOffset, 0)
+ @container.find(".right .inner").css "margin-left": "#{@currentOffset}px"
+ @timeTravel.scrolledTo 1 - (@minOffset() - @currentOffset) / @minOffset()
+
+export default ReferentialOverview
diff --git a/app/services/referential_overview.rb b/app/services/referential_overview.rb
index 14e917bbe..1fafae8ca 100644
--- a/app/services/referential_overview.rb
+++ b/app/services/referential_overview.rb
@@ -17,6 +17,10 @@ class ReferentialOverview
@period ||= @referential.metadatas_period || []
end
+ def includes_today?
+ period.include? Time.now.to_date
+ end
+
def weeks
@weeks = {}
period.map do |d|
@@ -219,8 +223,9 @@ class ReferentialOverview
end
def html_class
- out = []
+ out = [h.l(@date, format: "%Y-%m-%d")]
out << "weekend" if [0, 6].include?(@date.wday)
+ out << "today" if @date == Time.now.to_date
out
end
diff --git a/app/views/referentials/_overview.html.slim b/app/views/referentials/_overview.html.slim
index 6dd129405..26958d152 100644
--- a/app/views/referentials/_overview.html.slim
+++ b/app/views/referentials/_overview.html.slim
@@ -1,4 +1,8 @@
-.referential-overview
+.referential-overview id=overview.pagination_param_name
+ .time-travel.btn-group
+ = link_to I18n.t("referentials.overview.head.prev_page"), '#', class: "prev-page btn btn-default"
+ = link_to I18n.t("referentials.overview.head.today"), '#', class: "today btn btn-default #{overview.includes_today? ? '' : 'disabled'}"
+ = link_to I18n.t("referentials.overview.head.next_page"), '#', class: "next-page btn btn-default"
.overview-table
.left
.head
@@ -15,20 +19,31 @@
.company= line.company&.name
.mode= line.transport_mode
.right
- .head
- - overview.weeks.each do |week|
- .week
- .week-span= week.span
- .week-number= week.number
- .days
- - week.days.each do |day|
- .day style=day.html_style class=day.html_class
- .name= day.short_name
- .number= day.number
- .lines
- - overview.lines.each do |line|
- .line style=line.html_style class=line.html_class
- - line.periods.each do |period|
- .period style=period.html_style class=period.html_class title=period.title
+ .inner
+ .head
+ - overview.weeks.each do |week|
+ .week
+ .week-span= week.span
+ .week-number= week.number
+ .days
+ - week.days.each do |day|
+ .day style=day.html_style class=day.html_class
+ .name= day.short_name
+ .number= day.number
+ .lines
+ - overview.lines.each do |line|
+ .line style=line.html_style class=line.html_class
+ - line.periods.each do |period|
+ .period style=period.html_style class=period.html_class title=period.title
= new_pagination overview, 'pull-right'
+
+- content_for :javascript do
+ = javascript_pack_tag 'referential_overview/overview.js'
+
+ javascript:
+ overview_id = "#{overview.pagination_param_name}";
+
+ coffee:
+ $ =>
+ new ReferentialOverview("##{overview_id}")
diff --git a/config/locales/referentials.en.yml b/config/locales/referentials.en.yml
index dd7f776fd..b7483c0aa 100644
--- a/config/locales/referentials.en.yml
+++ b/config/locales/referentials.en.yml
@@ -52,7 +52,10 @@ en:
head:
dates: Dates
lines: Lignes
-
+ today: Today
+ prev_page: Prev. page
+ next_page: Next page
+
activerecord:
models:
referential:
diff --git a/config/locales/referentials.fr.yml b/config/locales/referentials.fr.yml
index 48b98214e..3485413f1 100644
--- a/config/locales/referentials.fr.yml
+++ b/config/locales/referentials.fr.yml
@@ -52,6 +52,9 @@ fr:
head:
dates: Dates
lines: Lignes
+ today: Aujourd'hui
+ prev_page: Page précédente
+ next_page: Page suivante
activerecord:
models:
--
cgit v1.2.3
From 58200ddc709c06f6bbc62cd6c954bb110abf9343 Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 19 Jan 2018 11:16:44 +0100
Subject: Refs #3542 @1h; Adds filters
---
.../components/_referential_overview.sass | 32 ++++++++++++++++++++--
app/javascript/referential_overview/index.coffee | 1 -
app/services/referential_overview.rb | 26 ++++++++++++++----
app/views/referentials/_overview.html.slim | 31 ++++++++++++++++++---
4 files changed, 78 insertions(+), 12 deletions(-)
diff --git a/app/assets/stylesheets/components/_referential_overview.sass b/app/assets/stylesheets/components/_referential_overview.sass
index a25c49272..2d903a2d7 100644
--- a/app/assets/stylesheets/components/_referential_overview.sass
+++ b/app/assets/stylesheets/components/_referential_overview.sass
@@ -1,15 +1,43 @@
.referential-overview
margin-top: 50px
- .time-travel
- background-color: $grey
+ .time-travel, .filters
+ background-color: $lightgrey
padding: 10px
float: right
border-top-left-radius: 10px
border-top-right-radius: 10px
+ .time-travel
a.btn:first-child
border-right: 1px solid $grey
+ margin-right: 1px
a.btn:last-child
border-left: 1px solid $grey
+ max-width: 33%
+ .filters
+ float: left
+ max-width: 66%
+ padding: 0
+ background: transparentize(#cbac3e, 0.8)
+ border: 1px solid $grey
+ border-bottom: none
+ form
+ background: transparent
+ display: flex
+ .ffg-row
+ border-color: $grey
+ .form-group
+ border-color: $grey
+ width: auto
+ flex: 1 1
+ padding: 11px
+ .input-group-btn
+ right: 10px
+ &.togglable
+ padding-top: 12px
+ padding-bottom: 11px
+ &:before
+ top: 7px
+
.overview-table
border: 1px solid $grey
clear: both
diff --git a/app/javascript/referential_overview/index.coffee b/app/javascript/referential_overview/index.coffee
index 8dd0e3561..6128d7c98 100644
--- a/app/javascript/referential_overview/index.coffee
+++ b/app/javascript/referential_overview/index.coffee
@@ -28,7 +28,6 @@ class TimeTravel
false
scrolledTo: (progress)->
- console.log "scrolledTo: #{progress*100}%"
@prevBt.removeClass 'disabled'
@nextBt.removeClass 'disabled'
@prevBt.addClass 'disabled' if progress == 0
diff --git a/app/services/referential_overview.rb b/app/services/referential_overview.rb
index 1fafae8ca..ccfe0617a 100644
--- a/app/services/referential_overview.rb
+++ b/app/services/referential_overview.rb
@@ -1,16 +1,17 @@
class ReferentialOverview
attr_reader :h
+ attr_reader :referential
PER_PAGE = 10
- def initialize referential, h
+ def initialize referential, h=nil
@referential = referential
- @page = h.params[pagination_param_name]&.to_i || 1
+ @page = h && h.params[pagination_param_name]&.to_i || 1
@h = h
end
def lines
- referential_lines.includes(:company).map{|l| Line.new(l, @referential, period.first, h)}
+ filtered_lines.includes(:company).map{|l| Line.new(l, @referential, period.first, h)}
end
def period
@@ -30,20 +31,35 @@ class ReferentialOverview
end
def referential_lines
- @referential.metadatas_lines.page(@page).per_page(PER_PAGE)
+ @referential.metadatas_lines
+ end
+
+ def filtered_lines
+ search.result.page(@page).per_page(PER_PAGE)
end
### Pagination
- delegate :empty?, :first, :total_pages, :size, :total_entries, :offset, :length, to: :referential_lines
+ delegate :empty?, :first, :total_pages, :size, :total_entries, :offset, :length, to: :filtered_lines
def current_page
@page
end
+ ### search
+ def search
+ lines = referential_lines
+ lines = lines.search h.params[search_param_name]
+ lines
+ end
+
def pagination_param_name
"referential_#{@referential.slug}_overview"
end
+ def search_param_name
+ "q_#{pagination_param_name}"
+ end
+
class Line
attr_reader :h
attr_reader :referential_line
diff --git a/app/views/referentials/_overview.html.slim b/app/views/referentials/_overview.html.slim
index 26958d152..bccd35aae 100644
--- a/app/views/referentials/_overview.html.slim
+++ b/app/views/referentials/_overview.html.slim
@@ -1,4 +1,24 @@
.referential-overview id=overview.pagination_param_name
+ .filters
+ = search_form_for overview.search, as: overview.search_param_name, url: "", html: {method: :get}, class: 'form form-filter' do |f|
+ .ffg-row
+ .form-group.input-group.search_bar
+ = f.search_field :name_or_number_or_objectid_cont, placeholder: t('lines.index.name_or_number_or_objectid'), class: 'form-control'
+ span.input-group-btn
+ button.btn.btn-default#search-btn type='submit'
+ span.fa.fa-search
+ .form-group.togglable
+ = f.label Chouette::Line.human_attribute_name(:company_id), required: false, class: 'control-label'
+ = f.input :company_id_eq_any, collection: overview.referential.companies.order(name: :asc), as: :check_boxes, label: false, label_method: lambda{|l| ("" + l.name + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}
+
+ .form-group.togglable
+ = f.label Chouette::Line.human_attribute_name(:transport_mode), required: false, class: 'control-label'
+ = f.input :transport_mode_eq_any, collection: StifTransportModeEnumerations.sorted_transport_modes, as: :check_boxes, label: false, label_method: lambda{|l| ("" + t("enumerize.transport_mode.#{l}") + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}
+
+ .actions
+ = link_to 'Effacer', @workbench, class: 'btn btn-link'
+ = f.submit 'Filtrer', class: 'btn btn-default'
+
.time-travel.btn-group
= link_to I18n.t("referentials.overview.head.prev_page"), '#', class: "prev-page btn btn-default"
= link_to I18n.t("referentials.overview.head.today"), '#', class: "today btn btn-default #{overview.includes_today? ? '' : 'disabled'}"
@@ -31,10 +51,13 @@
.name= day.short_name
.number= day.number
.lines
- - overview.lines.each do |line|
- .line style=line.html_style class=line.html_class
- - line.periods.each do |period|
- .period style=period.html_style class=period.html_class title=period.title
+ - if overview.lines.any?
+ - overview.lines.each do |line|
+ .line style=line.html_style class=line.html_class
+ - line.periods.each do |period|
+ .period style=period.html_style class=period.html_class title=period.title
+ - else
+ = replacement_msg t('referential_lines.search_no_results')
= new_pagination overview, 'pull-right'
--
cgit v1.2.3
From 242d406edd5c14645d8e0080ce6bb3f2a6313383 Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 19 Jan 2018 12:18:12 +0100
Subject: Refs #3542 @1h; Add sticky header
---
.../components/_referential_overview.sass | 64 ++++++++++++++++++++--
app/javascript/referential_overview/index.coffee | 23 +++++++-
app/views/referentials/_overview.html.slim | 3 -
3 files changed, 80 insertions(+), 10 deletions(-)
diff --git a/app/assets/stylesheets/components/_referential_overview.sass b/app/assets/stylesheets/components/_referential_overview.sass
index 2d903a2d7..77f60a8e7 100644
--- a/app/assets/stylesheets/components/_referential_overview.sass
+++ b/app/assets/stylesheets/components/_referential_overview.sass
@@ -1,4 +1,5 @@
.referential-overview
+ $left-size: 100px
margin-top: 50px
.time-travel, .filters
background-color: $lightgrey
@@ -42,7 +43,6 @@
border: 1px solid $grey
clear: both
display: flex
- $left-size: 100px
.head
height: $left-size
.line
@@ -87,13 +87,17 @@
.number
border-radius: 100px
display: inline-block
- width: 20px
+ min-width: 20px
height: 20px
text-align: center
- padding-top: 1px
+ padding: 1px 4px
text-decoration: none
color: black
border: 1px solid $grey
+ max-width: 100%
+ white-space: nowrap
+ text-overflow: ellipsis
+ overflow: hidden
.name
display: inline-block
width: $left-size - 50px()
@@ -121,14 +125,28 @@
.right
flex: 1 1
overflow: hidden
- .inner
- transition: margin 0.5s
+ .inner .lines
+ transition: margin-left 0.5s
.head
white-space: nowrap
+ position: relative
+ &:after, &:before
+ opacity: 0
+ transition: opacity 0.5s
+ content: ""
+ position: absolute
+ left: -1000px
+ right: 100%
+ top: 0px
+ bottom: 0
+ background: $darkblue
+ z-index: 11
+ border-top: 1px solid white
.week
display: inline-block
position: relative
height: 100%
+ transition: margin 0.5s
.week-span
left: 5px
top: 10px
@@ -155,6 +173,9 @@
width: 1px
content: ""
+ &:last-child:after
+ display: none
+
.days
position: relative
top: 50%
@@ -221,10 +242,41 @@
bottom: -100%
position: absolute
right: -1px
- z-index: 10
+ z-index: 3
&.empty
background: rgb(244, 67, 67)
background: repeating-linear-gradient(-45deg, #f5e1cf,#f5e1cf 10px,#e49393 10px,#e49393 20px)
&.accepted
background: #f19039
background: repeating-linear-gradient(-45deg, #f5e1cf,#f5e1cf 10px,#f19039 10px,#f19039 20px)
+
+ &.sticky
+ .time-travel
+ position: fixed
+ bottom: 0
+ z-index: 15
+ right: 35px
+
+ .overview-table .right
+ .lines
+ margin-top: $left-size
+ .head
+ position: fixed
+ top: 80px
+ z-index: 10
+ background: white
+ height: 50px
+ right: 51px
+ left: 51px + $left-size
+ // overflow-x: hidden
+ &:after, &:before
+ opacity: 1
+ &:after
+ left: 100%
+ right: -1000px
+ .week-span, .week-number
+ display: none
+ .days
+ height: 100%
+ top: 0
+ border-top: 1px solid white
diff --git a/app/javascript/referential_overview/index.coffee b/app/javascript/referential_overview/index.coffee
index 6128d7c98..c9a266dea 100644
--- a/app/javascript/referential_overview/index.coffee
+++ b/app/javascript/referential_overview/index.coffee
@@ -38,6 +38,8 @@ class window.ReferentialOverview
@container = $(selector)
@timeTravel = new TimeTravel(this)
@currentOffset = 0
+ $(document).scroll (e)=>
+ @documentScroll(e)
showDay: (date)->
day = @container.find(".day.#{date}")
@@ -48,6 +50,11 @@ class window.ReferentialOverview
currentOffset: ->
@container.find(".right .inner").offset().left
+ top: ->
+ @_top ||= @container.find('.days').offset().top - 80
+ bottom: ->
+ @_bottom ||= @top() + @container.height() - 50
+
prevPage: ->
@scrollTo @currentOffset + @container.find(".right").width()
@@ -62,7 +69,21 @@ class window.ReferentialOverview
@currentOffset = offset
@currentOffset = Math.max(@currentOffset, @minOffset())
@currentOffset = Math.min(@currentOffset, 0)
- @container.find(".right .inner").css "margin-left": "#{@currentOffset}px"
+ @container.find(".right .inner .lines").css "margin-left": "#{@currentOffset}px"
+ @container.find(".head .week:first-child").css "margin-left", "#{@currentOffset}px"
@timeTravel.scrolledTo 1 - (@minOffset() - @currentOffset) / @minOffset()
+
+ documentScroll: (e)->
+ if @sticky
+ if e.pageY < @top() || e.pageY > @bottom()
+ @container.removeClass "sticky"
+ @sticky = false
+ else
+ if e.pageY > @top() && e.pageY < @bottom()
+ @sticky = true
+ @container.addClass "sticky"
+
+
+
export default ReferentialOverview
diff --git a/app/views/referentials/_overview.html.slim b/app/views/referentials/_overview.html.slim
index bccd35aae..e9a799764 100644
--- a/app/views/referentials/_overview.html.slim
+++ b/app/views/referentials/_overview.html.slim
@@ -33,9 +33,6 @@
.line
a.number style="background-color: #{line.color.present? ? "##{line.color}" : 'whitesmoke'}" title=line.name
= line.number
- - unless line.number == line.name
- a.name title=line.name
- = line.name
.company= line.company&.name
.mode= line.transport_mode
.right
--
cgit v1.2.3
From 1602453b169decf6adb386db1cba321c96ec2188 Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 19 Jan 2018 14:59:08 +0100
Subject: Refs #3542, Fix specs
---
spec/services/referential_overview_spec.rb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/spec/services/referential_overview_spec.rb b/spec/services/referential_overview_spec.rb
index 39a90360a..0ce29643c 100644
--- a/spec/services/referential_overview_spec.rb
+++ b/spec/services/referential_overview_spec.rb
@@ -136,7 +136,7 @@ end
RSpec.describe ReferentialOverview::Line::Period do
let(:period){(1.day.ago.to_date..Time.now.to_date)}
- let(:start){2.days.ago}
+ let(:start){2.days.ago.to_date}
subject(:line_period){ReferentialOverview::Line::Period.new period, start, nil}
@@ -148,7 +148,7 @@ RSpec.describe ReferentialOverview::Line::Period do
describe "#left" do
it "should have the right value" do
- expect(line_period.width).to eq ReferentialOverview::Day::WIDTH * 1
+ expect(line_period.left).to eq ReferentialOverview::Day::WIDTH * 1
end
end
end
--
cgit v1.2.3
From 4b2c708793241707666032b79f65aa771a109c60 Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 19 Jan 2018 16:42:19 +0100
Subject: Refs #3542 @2h; Various UI improvements (hopefully)
---
app/assets/stylesheets/base/_config.sass | 1 +
.../components/_referential_overview.sass | 86 ++++++++++++++++------
app/javascript/referential_overview/index.coffee | 19 ++++-
app/views/merges/show.html.slim | 3 +
app/views/referentials/_overview.html.slim | 11 +--
config/locales/referentials.fr.yml | 4 +-
6 files changed, 94 insertions(+), 30 deletions(-)
diff --git a/app/assets/stylesheets/base/_config.sass b/app/assets/stylesheets/base/_config.sass
index 2c226357f..0fff1dd9c 100644
--- a/app/assets/stylesheets/base/_config.sass
+++ b/app/assets/stylesheets/base/_config.sass
@@ -17,6 +17,7 @@ $blue: #007fbb
$darkgrey: #4b4b4b
$grey: #a4a4a4
$lightgrey: lighten($grey, 25)
+$lightergrey: lighten($lightgrey,5)
$green: #70b12b
$red: #da2f36
diff --git a/app/assets/stylesheets/components/_referential_overview.sass b/app/assets/stylesheets/components/_referential_overview.sass
index 77f60a8e7..af1baf4ec 100644
--- a/app/assets/stylesheets/components/_referential_overview.sass
+++ b/app/assets/stylesheets/components/_referential_overview.sass
@@ -1,12 +1,26 @@
.referential-overview
$left-size: 100px
+ $line-height: 57px
margin-top: 50px
+ overflow: hidden
.time-travel, .filters
- background-color: $lightgrey
+ background-color: $lightergrey
padding: 10px
float: right
border-top-left-radius: 10px
border-top-right-radius: 10px
+ border: 1px solid $lightgrey
+ border-bottom: none
+ position: relative
+ &:after
+ position: absolute
+ content: ""
+ left: 0
+ top: 100%
+ right: 0
+ height: 10px
+ box-shadow: 0 0 10px rgba(0,0,0,0.5)
+ z-index: 1
.time-travel
a.btn:first-child
border-right: 1px solid $grey
@@ -18,9 +32,6 @@
float: left
max-width: 66%
padding: 0
- background: transparentize(#cbac3e, 0.8)
- border: 1px solid $grey
- border-bottom: none
form
background: transparent
display: flex
@@ -30,7 +41,7 @@
border-color: $grey
width: auto
flex: 1 1
- padding: 11px
+ padding: 12px 11px 11px
.input-group-btn
right: 10px
&.togglable
@@ -40,16 +51,19 @@
top: 7px
.overview-table
+ position: relative
+ z-index: 2
border: 1px solid $grey
clear: both
display: flex
+ background: white
.head
height: $left-size
.line
- height: 80px
+ height: $line-height
.left
flex: 0 0
- background: $lightgrey
+ background: $lightergrey
min-width: $left-size
overflow: hidden
border-right: 1px solid white
@@ -79,7 +93,7 @@
width: 0
content: ""
.line
- padding: 15px 10px 10px
+ padding: 5px 10px
border-bottom: 1px solid $grey
font-size: 0.8em
&:last-child
@@ -112,13 +126,11 @@
.company, .mode
font-size: 0.9em
- margin-top: 5px
white-space: nowrap
text-overflow: ellipsis
overflow: hidden
-
+ margin-top: -2px
.mode
- margin-top: 0
text-transform: uppercase
color: $grey
font-weight: bold
@@ -132,7 +144,7 @@
position: relative
&:after, &:before
opacity: 0
- transition: opacity 0.5s
+ // transition: opacity 0.5s
content: ""
position: absolute
left: -1000px
@@ -148,8 +160,8 @@
height: 100%
transition: margin 0.5s
.week-span
- left: 5px
- top: 10px
+ left: 15px
+ top: 15px
right: 30px
white-space: nowrap
overflow: hidden
@@ -157,8 +169,8 @@
position: absolute
.week-number
- background-color: lightgrey
- color: white
+ background-color: $lightgrey
+ color: $grey
position: absolute
top: 0
right: 0
@@ -205,7 +217,7 @@
&:first-child
border: none
&.weekend
- background: $lightgrey
+ background: $lightergrey
&.today, &:hover
color: $blue
background-color: transparentize($blue, 0.7)
@@ -227,14 +239,40 @@
border-bottom: 1px solid $grey
position: relative
overflow: hidden
+
&:last-child
border-bottom: none
.period
height: 100%
top: 0
- background: rgb(219, 249, 196)
+ background: #aedd8a
position: absolute
+ box-shadow: 0 0 10px rgba(0,0,0,0.5)
+ z-index: 2
+ .title
+ position: absolute
+ left: 12px
+ top: 50%
+ margin-top: -6px
+ transform: translateY(-50%)
+ background-color: transparentize(white, 0.5)
+ padding: 5px
+ font-size: 0.7em
+ border-radius: 5px
+ transition: margin-left 0.5s
+ max-width: calc(100% - 24px)
+ margin-right: 12px
+ &:after
+ content: ""
+ position: absolute
+ bottom: 1px
+ left: 0
+ right: 0
+ height: 10px
+ background: white
+ opacity: 0.25
+ z-index: 3
&:before
content: ""
border-right: 1px dashed $grey
@@ -242,13 +280,19 @@
bottom: -100%
position: absolute
right: -1px
- z-index: 3
+ z-index: 4
+ &:hover
+ &:after
+ opacity: 0.5
+ .title
+ background-color: transparentize(white, 0.2)
&.empty
+ z-index: 1
background: rgb(244, 67, 67)
- background: repeating-linear-gradient(-45deg, #f5e1cf,#f5e1cf 10px,#e49393 10px,#e49393 20px)
+ background: repeating-linear-gradient(-45deg, #f5e1cf,#f5e1cf 12px,#e49393 12px,#e49393 25px)
&.accepted
background: #f19039
- background: repeating-linear-gradient(-45deg, #f5e1cf,#f5e1cf 10px,#f19039 10px,#f19039 20px)
+ background: repeating-linear-gradient(-45deg, #f5e1cf,#f5e1cf 12px,#f19039 12px,#f19039 25px)
&.sticky
.time-travel
diff --git a/app/javascript/referential_overview/index.coffee b/app/javascript/referential_overview/index.coffee
index c9a266dea..31a689273 100644
--- a/app/javascript/referential_overview/index.coffee
+++ b/app/javascript/referential_overview/index.coffee
@@ -40,11 +40,12 @@ class window.ReferentialOverview
@currentOffset = 0
$(document).scroll (e)=>
@documentScroll(e)
+ @documentScroll pageY: $(document).scrollTop()
showDay: (date)->
day = @container.find(".day.#{date}")
offset = day.offset().left
- parentOffset = @container.find(".right .inner").offset().left
+ parentOffset = @currentOffset
@scrollTo parentOffset - offset
currentOffset: ->
@@ -72,7 +73,21 @@ class window.ReferentialOverview
@container.find(".right .inner .lines").css "margin-left": "#{@currentOffset}px"
@container.find(".head .week:first-child").css "margin-left", "#{@currentOffset}px"
@timeTravel.scrolledTo 1 - (@minOffset() - @currentOffset) / @minOffset()
-
+ setTimeout =>
+ @movePeriodTitles()
+ , 600
+
+ movePeriodTitles: ->
+ @_right_offset ||= @container.find('.right').offset().left
+ @container.find(".shifted").removeClass("shifted").css "margin-left", 0
+ @container.find(".right .line").each (i, l) =>
+ $(l).find(".period").each (i, _p) =>
+ p = $(_p)
+ offset = parseInt(p.css("left")) + @currentOffset
+ if offset < 0 && - offset < p.width()
+ offset = Math.min(-offset, p.width() - 100)
+ p.find(".title").addClass("shifted").css "margin-left", offset + "px"
+ return
documentScroll: (e)->
if @sticky
diff --git a/app/views/merges/show.html.slim b/app/views/merges/show.html.slim
index 47e5aa029..a94552c0d 100644
--- a/app/views/merges/show.html.slim
+++ b/app/views/merges/show.html.slim
@@ -12,3 +12,6 @@
@merge.class.human_attribute_name(:created_at) => @merge.created_at ? l(@merge.created_at) : '-',
@merge.class.human_attribute_name(:started_at) => @merge.started_at ? l(@merge.started_at) : '-',
@merge.class.human_attribute_name(:ended_at) => @merge.ended_at ? l(@merge.ended_at) : '-' }
+
+ - if resource.output.current
+ = referential_overview resource.output.current
diff --git a/app/views/referentials/_overview.html.slim b/app/views/referentials/_overview.html.slim
index e9a799764..20bfd6c15 100644
--- a/app/views/referentials/_overview.html.slim
+++ b/app/views/referentials/_overview.html.slim
@@ -9,18 +9,18 @@
span.fa.fa-search
.form-group.togglable
= f.label Chouette::Line.human_attribute_name(:company_id), required: false, class: 'control-label'
- = f.input :company_id_eq_any, collection: overview.referential.companies.order(name: :asc), as: :check_boxes, label: false, label_method: lambda{|l| ("" + l.name + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}
+ = f.input :company_id_eq_any, collection: overview.referential_lines.map(&:company).uniq.sort_by(&:name), as: :check_boxes, label: false, label_method: lambda{|l| ("" + l.name + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}
.form-group.togglable
= f.label Chouette::Line.human_attribute_name(:transport_mode), required: false, class: 'control-label'
- = f.input :transport_mode_eq_any, collection: StifTransportModeEnumerations.sorted_transport_modes, as: :check_boxes, label: false, label_method: lambda{|l| ("" + t("enumerize.transport_mode.#{l}") + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}
+ = f.input :transport_mode_eq_any, collection: overview.referential_lines.map(&:transport_mode).uniq.sort, as: :check_boxes, label: false, label_method: lambda{|l| ("" + t("enumerize.transport_mode.#{l}") + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}
.actions
= link_to 'Effacer', @workbench, class: 'btn btn-link'
= f.submit 'Filtrer', class: 'btn btn-default'
.time-travel.btn-group
- = link_to I18n.t("referentials.overview.head.prev_page"), '#', class: "prev-page btn btn-default"
+ = link_to I18n.t("referentials.overview.head.prev_page"), '#', class: "prev-page btn btn-default disabled"
= link_to I18n.t("referentials.overview.head.today"), '#', class: "today btn btn-default #{overview.includes_today? ? '' : 'disabled'}"
= link_to I18n.t("referentials.overview.head.next_page"), '#', class: "next-page btn btn-default"
.overview-table
@@ -34,7 +34,7 @@
a.number style="background-color: #{line.color.present? ? "##{line.color}" : 'whitesmoke'}" title=line.name
= line.number
.company= line.company&.name
- .mode= line.transport_mode
+ .mode= t("enumerize.transport_mode.#{line.transport_mode}")
.right
.inner
.head
@@ -52,7 +52,8 @@
- overview.lines.each do |line|
.line style=line.html_style class=line.html_class
- line.periods.each do |period|
- .period style=period.html_style class=period.html_class title=period.title
+ .period style=period.html_style class=period.html_class
+ .title=period.title
- else
= replacement_msg t('referential_lines.search_no_results')
diff --git a/config/locales/referentials.fr.yml b/config/locales/referentials.fr.yml
index 3485413f1..53183a4c2 100644
--- a/config/locales/referentials.fr.yml
+++ b/config/locales/referentials.fr.yml
@@ -53,8 +53,8 @@ fr:
dates: Dates
lines: Lignes
today: Aujourd'hui
- prev_page: Page précédente
- next_page: Page suivante
+ prev_page: ←
+ next_page: →
activerecord:
models:
--
cgit v1.2.3
From 93fec402cf45aa3bd14a6a764d91a374bbb10b32 Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 19 Jan 2018 17:29:50 +0100
Subject: Refs #3542; Add a date lookup
---
.../components/_referential_overview.sass | 64 +++++++++++++---------
app/javascript/referential_overview/index.coffee | 11 +++-
app/views/referentials/_overview.html.slim | 13 +++--
3 files changed, 58 insertions(+), 30 deletions(-)
diff --git a/app/assets/stylesheets/components/_referential_overview.sass b/app/assets/stylesheets/components/_referential_overview.sass
index af1baf4ec..5abbb47cd 100644
--- a/app/assets/stylesheets/components/_referential_overview.sass
+++ b/app/assets/stylesheets/components/_referential_overview.sass
@@ -1,14 +1,14 @@
.referential-overview
$left-size: 100px
- $line-height: 57px
+ $line-height: 60px
margin-top: 50px
overflow: hidden
.time-travel, .filters
background-color: $lightergrey
padding: 10px
float: right
- border-top-left-radius: 10px
- border-top-right-radius: 10px
+ border-top-left-radius: 4px
+ border-top-right-radius: 4px
border: 1px solid $lightgrey
border-bottom: none
position: relative
@@ -22,12 +22,32 @@
box-shadow: 0 0 10px rgba(0,0,0,0.5)
z-index: 1
.time-travel
+ padding-top: 4px
+ padding-bottom: 4px
a.btn:first-child
- border-right: 1px solid $grey
margin-right: 1px
a.btn:last-child
- border-left: 1px solid $grey
+ margin-right: 1px
+
max-width: 33%
+ .btn-group, .form-group
+ position: relative
+ z-index: 2
+ .form-group
+ margin-left: 10px
+ margin-bottom: 0
+ display: inline-block
+ input
+ padding: 6px 5px
+ border: 1px solid $lightgrey
+ outline: none
+ height: 34px
+ border-radius: 4px
+ padding-right: 25px
+ a
+ padding: 4px
+ margin-top: 2px
+ margin-left: -25px
.filters
float: left
max-width: 66%
@@ -41,14 +61,14 @@
border-color: $grey
width: auto
flex: 1 1
- padding: 12px 11px 11px
+ padding: 4px 11px 5px
.input-group-btn
right: 10px
&.togglable
- padding-top: 12px
- padding-bottom: 11px
+ padding-top: 6px
+ padding-bottom: 5px
&:before
- top: 7px
+ top: 0px
.overview-table
position: relative
@@ -93,7 +113,7 @@
width: 0
content: ""
.line
- padding: 5px 10px
+ padding: 7px 10px
border-bottom: 1px solid $grey
font-size: 0.8em
&:last-child
@@ -218,7 +238,7 @@
border: none
&.weekend
background: $lightergrey
- &.today, &:hover
+ &.selected, &:hover
color: $blue
background-color: transparentize($blue, 0.7)
&:after
@@ -256,7 +276,7 @@
top: 50%
margin-top: -6px
transform: translateY(-50%)
- background-color: transparentize(white, 0.5)
+ background-color: transparentize(white, 0.25)
padding: 5px
font-size: 0.7em
border-radius: 5px
@@ -273,19 +293,6 @@
background: white
opacity: 0.25
z-index: 3
- &:before
- content: ""
- border-right: 1px dashed $grey
- top: -100%
- bottom: -100%
- position: absolute
- right: -1px
- z-index: 4
- &:hover
- &:after
- opacity: 0.5
- .title
- background-color: transparentize(white, 0.2)
&.empty
z-index: 1
background: rgb(244, 67, 67)
@@ -293,6 +300,12 @@
&.accepted
background: #f19039
background: repeating-linear-gradient(-45deg, #f5e1cf,#f5e1cf 12px,#f19039 12px,#f19039 25px)
+ &:hover
+ z-index: 3
+ &:after
+ opacity: 0.5
+ .title
+ background-color: transparentize(white, 0.1)
&.sticky
.time-travel
@@ -300,6 +313,7 @@
bottom: 0
z-index: 15
right: 35px
+ box-shadow: 0 0 10px rgba(0,0,0,0.5)
.overview-table .right
.lines
diff --git a/app/javascript/referential_overview/index.coffee b/app/javascript/referential_overview/index.coffee
index 31a689273..0e6541421 100644
--- a/app/javascript/referential_overview/index.coffee
+++ b/app/javascript/referential_overview/index.coffee
@@ -4,6 +4,8 @@ class TimeTravel
@todayBt = @container.find(".today")
@prevBt = @container.find(".prev-page")
@nextBt = @container.find(".next-page")
+ @searchDateBt = @container.find("a.search-date")
+ @searchDateInput = @container.find("input.date-search")
@initButtons()
initButtons: ->
@@ -27,6 +29,11 @@ class TimeTravel
e.preventDefault()
false
+ @searchDateBt.click (e)=>
+ @overview.showDay @searchDateInput.val() if @searchDateInput.val().length > 0
+ e.preventDefault()
+ false
+
scrolledTo: (progress)->
@prevBt.removeClass 'disabled'
@nextBt.removeClass 'disabled'
@@ -44,8 +51,10 @@ class window.ReferentialOverview
showDay: (date)->
day = @container.find(".day.#{date}")
+ @container.find(".day.selected").removeClass('selected')
+ day.addClass "selected"
offset = day.offset().left
- parentOffset = @currentOffset
+ parentOffset = @currentOffset + @container.find(".right").offset().left
@scrollTo parentOffset - offset
currentOffset: ->
diff --git a/app/views/referentials/_overview.html.slim b/app/views/referentials/_overview.html.slim
index 20bfd6c15..c35d4d5f5 100644
--- a/app/views/referentials/_overview.html.slim
+++ b/app/views/referentials/_overview.html.slim
@@ -19,10 +19,15 @@
= link_to 'Effacer', @workbench, class: 'btn btn-link'
= f.submit 'Filtrer', class: 'btn btn-default'
- .time-travel.btn-group
- = link_to I18n.t("referentials.overview.head.prev_page"), '#', class: "prev-page btn btn-default disabled"
- = link_to I18n.t("referentials.overview.head.today"), '#', class: "today btn btn-default #{overview.includes_today? ? '' : 'disabled'}"
- = link_to I18n.t("referentials.overview.head.next_page"), '#', class: "next-page btn btn-default"
+ .time-travel
+ .btn-group
+ = link_to I18n.t("referentials.overview.head.prev_page"), '#', class: "prev-page btn btn-default disabled"
+ = link_to I18n.t("referentials.overview.head.today"), '#', class: "today btn btn-default #{overview.includes_today? ? '' : 'disabled'}"
+ = link_to I18n.t("referentials.overview.head.next_page"), '#', class: "next-page btn btn-default"
+ .form-group
+ input.date-search type="date" min=overview.period.first max=overview.period.last
+ a.search-date href='#'
+ span.fa.fa-search
.overview-table
.left
.head
--
cgit v1.2.3
From a69c33870f3c8790a19265d8065a1ee5e2e7364b Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 22 Jan 2018 10:49:35 +0100
Subject: Refs #3542; Better display for short referentials
---
app/assets/stylesheets/base/_utilities.sass | 2 +-
app/assets/stylesheets/components/_referential_overview.sass | 7 ++++++-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/app/assets/stylesheets/base/_utilities.sass b/app/assets/stylesheets/base/_utilities.sass
index 24f2038f0..fbda5630d 100644
--- a/app/assets/stylesheets/base/_utilities.sass
+++ b/app/assets/stylesheets/base/_utilities.sass
@@ -44,7 +44,7 @@
// Empty zones
=emptyzone($col1, $col2)
- background-image: linear-gradient(-45deg, $col1 25%, $col2 25%, $col2 50%, $col1 50%, $col1 75%, $col2 75%, transparent)
+ background-image: linear-gradient(-45deg, $col1 25%, $col2 25%, $col2 50%, $col1 50%, $col1 75%, $col2 75%, $col2)
background-size: 40px 40px
.cellwrap
diff --git a/app/assets/stylesheets/components/_referential_overview.sass b/app/assets/stylesheets/components/_referential_overview.sass
index 5abbb47cd..2bd875f5e 100644
--- a/app/assets/stylesheets/components/_referential_overview.sass
+++ b/app/assets/stylesheets/components/_referential_overview.sass
@@ -76,8 +76,9 @@
border: 1px solid $grey
clear: both
display: flex
- background: white
+ +emptyzone($lightgrey, $lightergrey)
.head
+
height: $left-size
.line
height: $line-height
@@ -162,6 +163,7 @@
.head
white-space: nowrap
position: relative
+ z-index: 3
&:after, &:before
opacity: 0
// transition: opacity 0.5s
@@ -179,6 +181,8 @@
position: relative
height: 100%
transition: margin 0.5s
+ background: white
+ box-shadow: 0 -10px 10px rgba(0,0,0,0.5)
.week-span
left: 15px
top: 15px
@@ -259,6 +263,7 @@
border-bottom: 1px solid $grey
position: relative
overflow: hidden
+ box-shadow: 0 -10px 10px rgba(0,0,0,0.5)
&:last-child
border-bottom: none
--
cgit v1.2.3
From 154c26a3849b8c90b66045df0a7d06d64de521ad Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 22 Jan 2018 10:53:41 +0100
Subject: Refs #3542; Add an anchor to filters URLs
---
app/views/referentials/_overview.html.slim | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/views/referentials/_overview.html.slim b/app/views/referentials/_overview.html.slim
index c35d4d5f5..143784800 100644
--- a/app/views/referentials/_overview.html.slim
+++ b/app/views/referentials/_overview.html.slim
@@ -1,6 +1,6 @@
.referential-overview id=overview.pagination_param_name
.filters
- = search_form_for overview.search, as: overview.search_param_name, url: "", html: {method: :get}, class: 'form form-filter' do |f|
+ = search_form_for overview.search, as: overview.search_param_name, url: "##{overview.pagination_param_name}", html: {method: :get}, class: 'form form-filter' do |f|
.ffg-row
.form-group.input-group.search_bar
= f.search_field :name_or_number_or_objectid_cont, placeholder: t('lines.index.name_or_number_or_objectid'), class: 'form-control'
@@ -16,7 +16,7 @@
= f.input :transport_mode_eq_any, collection: overview.referential_lines.map(&:transport_mode).uniq.sort, as: :check_boxes, label: false, label_method: lambda{|l| ("" + t("enumerize.transport_mode.#{l}") + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}
.actions
- = link_to 'Effacer', @workbench, class: 'btn btn-link'
+ = link_to 'Effacer', url_for() + "##{overview.pagination_param_name}", class: 'btn btn-link'
= f.submit 'Filtrer', class: 'btn btn-default'
.time-travel
--
cgit v1.2.3
From 123da9addd584e4fb86520cb54d8266a9869b8cf Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 24 Jan 2018 15:40:25 +0100
Subject: Refs #3542; Small css fix
---
app/assets/stylesheets/components/_referential_overview.sass | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/app/assets/stylesheets/components/_referential_overview.sass b/app/assets/stylesheets/components/_referential_overview.sass
index 2bd875f5e..0beb8ab67 100644
--- a/app/assets/stylesheets/components/_referential_overview.sass
+++ b/app/assets/stylesheets/components/_referential_overview.sass
@@ -182,7 +182,8 @@
height: 100%
transition: margin 0.5s
background: white
- box-shadow: 0 -10px 10px rgba(0,0,0,0.5)
+ &:last-child
+ box-shadow: 0 -10px 10px rgba(0,0,0,0.5)
.week-span
left: 15px
top: 15px
--
cgit v1.2.3
From 40960d78ad2e5a85b4acec5d7588beb69538b61a Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 2 Feb 2018 14:58:50 +0100
Subject: Refs #5417; Update parents checksum when children are created or
updated
---
app/models/chouette/time_table.rb | 3 +++
app/models/chouette/vehicle_journey.rb | 2 ++
app/models/concerns/checksum_support.rb | 23 ++++++++++++++++++++++-
spec/models/chouette/time_table_spec.rb | 23 ++++++++++++++++++++++-
spec/models/chouette/vehicle_journey_spec.rb | 10 ++++++++++
5 files changed, 59 insertions(+), 2 deletions(-)
diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb
index 8113457ec..7b69aefb6 100644
--- a/app/models/chouette/time_table.rb
+++ b/app/models/chouette/time_table.rb
@@ -47,6 +47,9 @@ module Chouette
end
end
+ has_checksum_children TimeTableDate
+ has_checksum_children TimeTablePeriod
+
def self.object_id_key
"Timetable"
end
diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb
index 6146d5be8..1971061a2 100644
--- a/app/models/chouette/vehicle_journey.rb
+++ b/app/models/chouette/vehicle_journey.rb
@@ -108,6 +108,8 @@ module Chouette
end
end
+ has_checksum_children VehicleJourneyAtStop
+
def set_default_values
if number.nil?
self.number = 0
diff --git a/app/models/concerns/checksum_support.rb b/app/models/concerns/checksum_support.rb
index ff73c87a3..a76995b0f 100644
--- a/app/models/concerns/checksum_support.rb
+++ b/app/models/concerns/checksum_support.rb
@@ -3,9 +3,21 @@ module ChecksumSupport
SEPARATOR = '|'
VALUE_FOR_NIL_ATTRIBUTE = '-'
- included do
+ included do |into|
before_save :set_current_checksum_source, :update_checksum
Referential.register_model_with_checksum self
+ into.extend ClassMethods
+ end
+
+ module ClassMethods
+ def has_checksum_children klass, opts={}
+ parent_class = self
+ relation = opts[:relation] || self.model_name.singular
+ klass.after_save do
+ parent = self.send(relation)
+ parent&.update_checksum_without_callbacks!
+ end
+ end
end
def checksum_attributes
@@ -34,4 +46,13 @@ module ChecksumSupport
update checksum: Digest::SHA256.new.hexdigest(checksum_source)
end
end
+
+ def update_checksum_without_callbacks!
+ set_current_checksum_source
+ _checksum = Digest::SHA256.new.hexdigest(checksum_source)
+ if _checksum != self.checksum
+ self.checksum = _checksum
+ self.class.where(id: self.id).update_all(checksum: _checksum) unless self.new_record?
+ end
+ end
end
diff --git a/spec/models/chouette/time_table_spec.rb b/spec/models/chouette/time_table_spec.rb
index 28197984e..30e201c4d 100644
--- a/spec/models/chouette/time_table_spec.rb
+++ b/spec/models/chouette/time_table_spec.rb
@@ -926,7 +926,7 @@ end
end
end
end
-
+
describe "#validity_out_between?" do
let(:empty_tm) {build(:time_table)}
it "should be false if empty calendar" do
@@ -1050,6 +1050,27 @@ end
describe 'checksum' do
it_behaves_like 'checksum support', :time_table
+ it "changes when a date is updated" do
+ time_table = create(:time_table)
+ expect{time_table.dates.last.update_attribute(:date, Time.now)}.to change{time_table.reload.checksum}
+ end
+
+ it "changes when a date is added" do
+ time_table = create(:time_table)
+ expect(time_table).to receive(:update_checksum_without_callbacks!).at_least(:once).and_call_original
+ expect{create(:time_table_date, time_table: time_table)}.to change{time_table.checksum}
+ end
+
+ it "changes when a period is updated" do
+ time_table = create(:time_table)
+ expect{time_table.periods.last.update_attribute(:period_start, Time.now)}.to change{time_table.reload.checksum}
+ end
+
+ it "changes when a period is added" do
+ time_table = create(:time_table)
+ expect(time_table).to receive(:update_checksum_without_callbacks!).at_least(:once).and_call_original
+ expect{create(:time_table_period, time_table: time_table)}.to change{time_table.checksum}
+ end
end
describe "#excluded_days" do
diff --git a/spec/models/chouette/vehicle_journey_spec.rb b/spec/models/chouette/vehicle_journey_spec.rb
index 909d6582d..76ee1e74d 100644
--- a/spec/models/chouette/vehicle_journey_spec.rb
+++ b/spec/models/chouette/vehicle_journey_spec.rb
@@ -22,6 +22,16 @@ describe Chouette::VehicleJourney, :type => :model do
describe 'checksum' do
it_behaves_like 'checksum support', :vehicle_journey
+ it "changes when a vjas is updated" do
+ vehicle_journey = create(:vehicle_journey)
+ expect{vehicle_journey.vehicle_journey_at_stops.last.update_attribute(:departure_time, Time.now)}.to change{vehicle_journey.reload.checksum}
+ end
+
+ it "changes when a vjas is added" do
+ vehicle_journey = create(:vehicle_journey)
+ expect(vehicle_journey).to receive(:update_checksum_without_callbacks!).at_least(:once).and_call_original
+ expect{create(:vehicle_journey_at_stop, vehicle_journey: vehicle_journey)}.to change{vehicle_journey.checksum}
+ end
end
describe "#with_stop_area_ids" do
--
cgit v1.2.3
From d4fc23715f75e071d432666f0557bc6031efa036 Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 2 Feb 2018 17:54:07 +0100
Subject: Refs #5417; Fix specs
---
app/models/chouette/time_table.rb | 8 ++++++--
app/models/chouette/vehicle_journey.rb | 4 +++-
spec/models/chouette/time_table_spec.rb | 13 ++++++++++++-
3 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb
index 7b69aefb6..15b22b671 100644
--- a/app/models/chouette/time_table.rb
+++ b/app/models/chouette/time_table.rb
@@ -42,8 +42,12 @@ module Chouette
def checksum_attributes
[].tap do |attrs|
attrs << self.int_day_types
- attrs << self.dates.map(&:checksum).map(&:to_s).sort
- attrs << self.periods.map(&:checksum).map(&:to_s).sort
+ dates = self.dates
+ dates += TimeTableDate.where(time_table_id: self.id)
+ attrs << dates.map(&:checksum).map(&:to_s).sort
+ periods = self.periods
+ periods += TimeTablePeriod.where(time_table_id: self.id)
+ attrs << periods.map(&:checksum).map(&:to_s).sort
end
end
diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb
index 1971061a2..4a6ba3f75 100644
--- a/app/models/chouette/vehicle_journey.rb
+++ b/app/models/chouette/vehicle_journey.rb
@@ -104,7 +104,9 @@ module Chouette
attrs << self.published_journey_identifier
attrs << self.try(:company).try(:get_objectid).try(:local_id)
attrs << self.footnotes.map(&:checksum).sort
- attrs << self.vehicle_journey_at_stops.sort_by { |s| s.stop_point&.position }.map(&:checksum).sort
+ vjas = self.vehicle_journey_at_stops
+ vjas += VehicleJourneyAtStop.where(vehicle_journey_id: self.id)
+ attrs << vjas.uniq.sort_by { |s| s.stop_point&.position }.map(&:checksum).sort
end
end
diff --git a/spec/models/chouette/time_table_spec.rb b/spec/models/chouette/time_table_spec.rb
index 30e201c4d..a501f234a 100644
--- a/spec/models/chouette/time_table_spec.rb
+++ b/spec/models/chouette/time_table_spec.rb
@@ -1050,6 +1050,17 @@ end
describe 'checksum' do
it_behaves_like 'checksum support', :time_table
+
+ it "handles newly built dates and periods" do
+ time_table = build(:time_table)
+ time_table.periods.build period_start: Time.now, period_end: 1.month.from_now
+ time_table.dates.build date: Time.now
+ time_table.save!
+ expect{time_table.update_checksum!}.to_not change{time_table.checksum}
+ expect(time_table.dates.count).to eq 1
+ expect(time_table.periods.count).to eq 1
+ end
+
it "changes when a date is updated" do
time_table = create(:time_table)
expect{time_table.dates.last.update_attribute(:date, Time.now)}.to change{time_table.reload.checksum}
@@ -1058,7 +1069,7 @@ end
it "changes when a date is added" do
time_table = create(:time_table)
expect(time_table).to receive(:update_checksum_without_callbacks!).at_least(:once).and_call_original
- expect{create(:time_table_date, time_table: time_table)}.to change{time_table.checksum}
+ expect{create(:time_table_date, time_table: time_table, date: 1.year.ago)}.to change{time_table.checksum}
end
it "changes when a period is updated" do
--
cgit v1.2.3
From 4c89c581c9dbb1a58365b25a9789a747346e8992 Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 5 Feb 2018 11:11:41 +0100
Subject: Refs #5844; Add missing translation
---
config/locales/imports.en.yml | 1 +
config/locales/imports.fr.yml | 1 +
2 files changed, 2 insertions(+)
diff --git a/config/locales/imports.en.yml b/config/locales/imports.en.yml
index d9f1984fe..f843eea47 100644
--- a/config/locales/imports.en.yml
+++ b/config/locales/imports.en.yml
@@ -7,6 +7,7 @@ en:
error_period_filter: "End date must be greater or equal than begin date"
actions:
new: "New import"
+ create: "New import"
show: "Import report"
download: "Download original file"
destroy: "Destroy"
diff --git a/config/locales/imports.fr.yml b/config/locales/imports.fr.yml
index 9795b2190..c24f08e76 100644
--- a/config/locales/imports.fr.yml
+++ b/config/locales/imports.fr.yml
@@ -7,6 +7,7 @@ fr:
error_period_filter: "La date de fin doit être supérieure ou égale à la date de début"
actions:
new: "Nouvel import"
+ create: "Nouvel import"
show: "Rapport d'import"
download: "Téléch. fichier source"
destroy: "Supprimer cet import"
--
cgit v1.2.3
From c0cd54efd584c8875ee6e04fc39c8f09cc1f1e4c Mon Sep 17 00:00:00 2001
From: Zog
Date: Tue, 6 Feb 2018 11:54:19 +0100
Subject: Fix StopAreas filters when no filter is present
---
app/views/stop_areas/_filters.html.slim | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/stop_areas/_filters.html.slim b/app/views/stop_areas/_filters.html.slim
index 1d71d477a..00369d3ed 100644
--- a/app/views/stop_areas/_filters.html.slim
+++ b/app/views/stop_areas/_filters.html.slim
@@ -12,7 +12,7 @@
.form-group.togglable class=filter_item_class(params[:q], :area_type_eq_any)
= f.label Chouette::StopArea.human_attribute_name(:area_type), required: false, class: 'control-label'
- = f.input :area_type_eq_any, checked: params[:q][:area_type_eq_any], collection: Chouette::AreaType.options, as: :check_boxes, label: false, label_method: lambda{|w| ("" + w[0] + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list' }
+ = f.input :area_type_eq_any, checked: params[:q] && params[:q][:area_type_eq_any], collection: Chouette::AreaType.options, as: :check_boxes, label: false, label_method: lambda{|w| ("" + w[0] + " ").html_safe}, required: false, wrapper_html: { class: 'checkbox_list' }
.actions
= link_to 'Effacer', @workbench, class: 'btn btn-link'
--
cgit v1.2.3
From a6134639f361629726283f0e2544fd948d552e0b Mon Sep 17 00:00:00 2001
From: Zog
Date: Tue, 6 Feb 2018 12:48:57 +0100
Subject: Fix checksum-related specs
---
spec/models/chouette/vehicle_journey_spec.rb | 2 +-
spec/support/checksum_support.rb | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/spec/models/chouette/vehicle_journey_spec.rb b/spec/models/chouette/vehicle_journey_spec.rb
index 76ee1e74d..7279980a3 100644
--- a/spec/models/chouette/vehicle_journey_spec.rb
+++ b/spec/models/chouette/vehicle_journey_spec.rb
@@ -62,7 +62,7 @@ describe Chouette::VehicleJourney, :type => :model do
context "with a common area" do
let(:ids){[common_stop_area.id]}
it "should return all journeys" do
- expect(result).to eq [journey_1, journey_2]
+ expect(result.to_a.sort).to eq [journey_1, journey_2].sort
end
end
end
diff --git a/spec/support/checksum_support.rb b/spec/support/checksum_support.rb
index 14ea3c55e..e02d9f9f3 100644
--- a/spec/support/checksum_support.rb
+++ b/spec/support/checksum_support.rb
@@ -42,12 +42,12 @@ shared_examples 'checksum support' do |factory_name|
end
it 'should trigger set_current_checksum_source on save' do
- expect(instance).to receive(:set_current_checksum_source)
+ expect(instance).to receive(:set_current_checksum_source).at_least(:once)
instance.save
end
it 'should trigger update_checksum on save' do
- expect(instance).to receive(:update_checksum)
+ expect(instance).to receive(:update_checksum).at_least(:once)
instance.save
end
end
--
cgit v1.2.3
From 180e0f55efe5aa7aa080e4f8f4c0c044c71dafa3 Mon Sep 17 00:00:00 2001
From: cedricnjanga
Date: Mon, 5 Feb 2018 06:27:24 -0800
Subject: Refs #5565 Remove the application name on the error pages
---
app/views/errors/forbidden.html.slim | 2 +-
app/views/errors/server_error.html.slim | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/views/errors/forbidden.html.slim b/app/views/errors/forbidden.html.slim
index 23ea67eff..8c35b46a8 100644
--- a/app/views/errors/forbidden.html.slim
+++ b/app/views/errors/forbidden.html.slim
@@ -9,7 +9,7 @@
p
strong = "Désolé, la page demandée la page n'est pas accessible avec votre profil utilisateur."
- p = "Vous pouvez néanmoins continuer à utiliser l'application IBOO."
+ p = "Vous pouvez néanmoins continuer à utiliser l'application."
- else
p
diff --git a/app/views/errors/server_error.html.slim b/app/views/errors/server_error.html.slim
index 189a48760..529ad73e8 100644
--- a/app/views/errors/server_error.html.slim
+++ b/app/views/errors/server_error.html.slim
@@ -9,7 +9,7 @@
p
strong = "Désolé, une erreur est survenue."
- p = "Vous pouvez néanmoins continuer à utiliser l'application IBOO."
+ p = "Vous pouvez néanmoins continuer à utiliser l'application."
- else
p
--
cgit v1.2.3
From 74d28c64603c70dc5463c9bc72954b886760f6cd 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/helpers/table_builder_helper/url.rb | 2 +-
db/schema.rb | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/app/helpers/table_builder_helper/url.rb b/app/helpers/table_builder_helper/url.rb
index 0e3dce0aa..57172301c 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?(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
diff --git a/db/schema.rb b/db/schema.rb
index 51cb44d17..94223b7d4 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -93,6 +93,7 @@ ActiveRecord::Schema.define(version: 20180126134944) do
t.integer "workgroup_id", limit: 8
t.integer "int_day_types"
t.date "excluded_dates", array: true
+ t.integer "workgroup_id", limit: 8
end
add_index "calendars", ["organisation_id"], name: "index_calendars_on_organisation_id", using: :btree
--
cgit v1.2.3
From 388fe8128caf7c36a7c4c89380a98bb5530955d1 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 | 32 ++++++++++++++++++++
app/helpers/table_builder_helper/url.rb | 2 +-
app/views/calendars/_form.html.slim | 53 +++++++++++++++++++++++++++++++++
3 files changed, 86 insertions(+), 1 deletion(-)
create mode 100644 app/views/calendars/_form.html.slim
diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb
index 75d4cbd09..cc160a98e 100644
--- a/app/controllers/calendars_controller.rb
+++ b/app/controllers/calendars_controller.rb
@@ -1,4 +1,5 @@
class CalendarsController < ChouetteController
+ include WorkgroupSupport
include PolicyChecker
include TimeTablesHelper
@@ -54,10 +55,18 @@ class CalendarsController < ChouetteController
private
def decorate_calendars(calendars)
+<<<<<<< HEAD
CalendarDecorator.decorate(
calendars,
context: {
workgroup: workgroup
+=======
+ ModelDecorator.decorate(
+ calendars,
+ with: CalendarDecorator,
+ context: {
+ workgroup: current_workgroup
+>>>>>>> update calendar build_links for table builder
}
)
end
@@ -82,17 +91,30 @@ class CalendarsController < ChouetteController
helper_method :workgroup
def resource
+<<<<<<< HEAD
@calendar ||= workgroup.calendars.where('(organisation_id = ? OR shared = ?)', current_organisation.id, true).find_by_id(params[:id])
+=======
+<<<<<<< HEAD
+ @calendar = Calendar.where('organisation_id = ? OR shared = true', current_organisation.id).find_by_id(params[:id]).decorate
+=======
+ @calendar = Calendar.where('(organisation_id = ? OR shared = ?) AND workgroup_id = ?', current_organisation.id).find_by_id(params[:id], true, @workgroup.id)
+>>>>>>> update calendar build_links for table builder
+>>>>>>> update calendar build_links for table builder
end
def build_resource
super.tap do |calendar|
+<<<<<<< HEAD
calendar.workgroup = workgroup
+=======
+ calendar.workgroup = current_workgroup
+>>>>>>> update calendar build_links for table builder
calendar.organisation = current_organisation
end
end
def collection
+<<<<<<< HEAD
@calendars ||= begin
scope = workgroup.calendars.where('(organisation_id = ? OR shared = ?)', current_organisation.id, true)
scope = shared_scope(scope)
@@ -101,6 +123,16 @@ class CalendarsController < ChouetteController
calendars = calendars.order(sort_column + ' ' + sort_direction) if sort_column && sort_direction
calendars = calendars.paginate(page: params[:page])
end
+=======
+ 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])
+>>>>>>> update calendar build_links for table builder
end
def ransack_contains_date
diff --git a/app/helpers/table_builder_helper/url.rb b/app/helpers/table_builder_helper/url.rb
index 57172301c..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
diff --git a/app/views/calendars/_form.html.slim b/app/views/calendars/_form.html.slim
new file mode 100644
index 000000000..bf9f4f3a7
--- /dev/null
+++ b/app/views/calendars/_form.html.slim
@@ -0,0 +1,53 @@
+= simple_form_for [@workgroup, @calendar], html: { class: 'form-horizontal', id: 'calendar_form' }, wrapper: :horizontal_form do |f|
+ .row
+ .col-lg-12
+ = f.input :name
+ = f.input :short_name
+
+ - if policy(@calendar).share?
+ .form-group.has_switch
+ = f.label :shared, class: 'col-sm-4 col-xs-5 control-label'
+ = f.input :shared, as: :boolean, checked_value: true, unchecked_value: false, label: content_tag(:span, t("#{@calendar.shared}"), class: 'switch-label', data: {checkedValue: t('true'), uncheckedValue: t('false')}), wrapper_html: { class: 'col-sm-8 col-xs-7'}
+
+ .separator
+
+ .row
+ .col-lg-12
+ .subform
+ .nested-head
+ .wrapper
+ div
+ .form-group
+ label.control-label
+ = Calendar.human_attribute_name(:date)
+ div
+
+ = f.simple_fields_for :date_values do |date_value|
+ = render 'date_value_fields', f: date_value
+
+ .links.nested-linker
+ = link_to_add_association t('simple_form.labels.calendar.add_a_date'), f, :date_values, class: 'btn btn-outline-primary'
+
+ .separator
+
+ .row
+ .col-lg-12
+ .subform
+ .nested-head
+ .wrapper
+ div
+ .form-group
+ label.control-label
+ = t('simple_form.labels.calendar.ranges.begin')
+ div
+ .form-group
+ label.control-label
+ = t('simple_form.labels.calendar.ranges.end')
+ div
+
+ = f.simple_fields_for :periods do |period|
+ = render 'period_fields', f: period
+ .links.nested-linker
+ = link_to_add_association t('simple_form.labels.calendar.add_a_date_range'), f, :periods, class: 'btn btn-outline-primary'
+
+ = f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'calendar_form'
--
cgit v1.2.3
From eaa3c0156f8774ef396854ef4819e27815720d6d 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 | 34 ++-------------------------------
1 file changed, 2 insertions(+), 32 deletions(-)
diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb
index cc160a98e..3018b48e1 100644
--- a/app/controllers/calendars_controller.rb
+++ b/app/controllers/calendars_controller.rb
@@ -1,5 +1,4 @@
class CalendarsController < ChouetteController
- include WorkgroupSupport
include PolicyChecker
include TimeTablesHelper
@@ -8,6 +7,8 @@ class CalendarsController < ChouetteController
respond_to :html
respond_to :json, only: :show
respond_to :js, only: :index
+
+ belongs_to :workgroup
belongs_to :workgroup
@@ -55,18 +56,10 @@ class CalendarsController < ChouetteController
private
def decorate_calendars(calendars)
-<<<<<<< HEAD
CalendarDecorator.decorate(
calendars,
context: {
workgroup: workgroup
-=======
- ModelDecorator.decorate(
- calendars,
- with: CalendarDecorator,
- context: {
- workgroup: current_workgroup
->>>>>>> update calendar build_links for table builder
}
)
end
@@ -91,30 +84,17 @@ class CalendarsController < ChouetteController
helper_method :workgroup
def resource
-<<<<<<< HEAD
@calendar ||= workgroup.calendars.where('(organisation_id = ? OR shared = ?)', current_organisation.id, true).find_by_id(params[:id])
-=======
-<<<<<<< HEAD
- @calendar = Calendar.where('organisation_id = ? OR shared = true', current_organisation.id).find_by_id(params[:id]).decorate
-=======
- @calendar = Calendar.where('(organisation_id = ? OR shared = ?) AND workgroup_id = ?', current_organisation.id).find_by_id(params[:id], true, @workgroup.id)
->>>>>>> update calendar build_links for table builder
->>>>>>> update calendar build_links for table builder
end
def build_resource
super.tap do |calendar|
-<<<<<<< HEAD
calendar.workgroup = workgroup
-=======
- calendar.workgroup = current_workgroup
->>>>>>> update calendar build_links for table builder
calendar.organisation = current_organisation
end
end
def collection
-<<<<<<< HEAD
@calendars ||= begin
scope = workgroup.calendars.where('(organisation_id = ? OR shared = ?)', current_organisation.id, true)
scope = shared_scope(scope)
@@ -123,16 +103,6 @@ class CalendarsController < ChouetteController
calendars = calendars.order(sort_column + ' ' + sort_direction) if sort_column && sort_direction
calendars = calendars.paginate(page: params[:page])
end
-=======
- 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])
->>>>>>> update calendar build_links for table builder
end
def ransack_contains_date
--
cgit v1.2.3
From a261ce4c824ad8ffecca7b4fb98aaa3b68ba529c 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 | 4 ++--
app/helpers/table_builder_helper.rb | 1 -
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb
index 3018b48e1..75e7a4ddd 100644
--- a/app/controllers/calendars_controller.rb
+++ b/app/controllers/calendars_controller.rb
@@ -7,7 +7,7 @@ class CalendarsController < ChouetteController
respond_to :html
respond_to :json, only: :show
respond_to :js, only: :index
-
+
belongs_to :workgroup
belongs_to :workgroup
@@ -127,4 +127,4 @@ class CalendarsController < ChouetteController
scope
end
-end
\ No newline at end of file
+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(
--
cgit v1.2.3
From 98369b4395a5b11d7184f97d211eecc387f6ca2f 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 | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb
index 75e7a4ddd..91c91f0ca 100644
--- a/app/controllers/calendars_controller.rb
+++ b/app/controllers/calendars_controller.rb
@@ -1,4 +1,5 @@
class CalendarsController < ChouetteController
+ include WorkgroupSupport
include PolicyChecker
include TimeTablesHelper
--
cgit v1.2.3
From ee63b07c01a1a32bb0d2619e9d4f1bf100fc1d1a 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 | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb
index 91c91f0ca..925e88e41 100644
--- a/app/controllers/calendars_controller.rb
+++ b/app/controllers/calendars_controller.rb
@@ -1,5 +1,4 @@
class CalendarsController < ChouetteController
- include WorkgroupSupport
include PolicyChecker
include TimeTablesHelper
@@ -128,4 +127,4 @@ class CalendarsController < ChouetteController
scope
end
-end
+end
\ No newline at end of file
--
cgit v1.2.3
From 3fa91b720184edfe319081230decc13f695072b2 Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 26 Jan 2018 16:17:22 +0100
Subject: Refs #5750 @1h; Add a "kind" attribute to StopAreas
This determines if the StopArea is commercial or not
The useless fields are hidden in the form for the non-commercials ones
---
app/models/chouette/stop_area.rb | 6 ++++++
db/schema.rb | 5 +++--
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb
index cf2afbc73..565fa5f4b 100644
--- a/app/models/chouette/stop_area.rb
+++ b/app/models/chouette/stop_area.rb
@@ -117,7 +117,13 @@ module Chouette
end
end
+<<<<<<< HEAD
alias_method :local_id, :user_objectid
+=======
+ def local_id
+ id.to_s
+ end
+>>>>>>> Refs #5750 @1h; Add a "kind" attribute to StopAreas
def children_in_depth
return [] if self.children.empty?
diff --git a/db/schema.rb b/db/schema.rb
index 94223b7d4..99c02594a 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -15,9 +15,10 @@ ActiveRecord::Schema.define(version: 20180126134944) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
- enable_extension "postgis"
enable_extension "hstore"
+ enable_extension "postgis"
enable_extension "unaccent"
+ enable_extension "objectid"
create_table "access_links", id: :bigserial, force: :cascade do |t|
t.integer "access_point_id", limit: 8
@@ -93,7 +94,6 @@ ActiveRecord::Schema.define(version: 20180126134944) do
t.integer "workgroup_id", limit: 8
t.integer "int_day_types"
t.date "excluded_dates", array: true
- t.integer "workgroup_id", limit: 8
end
add_index "calendars", ["organisation_id"], name: "index_calendars_on_organisation_id", using: :btree
@@ -120,6 +120,7 @@ ActiveRecord::Schema.define(version: 20180126134944) do
t.datetime "updated_at"
t.date "end_date"
t.string "date_type"
+ t.string "mode"
end
add_index "clean_ups", ["referential_id"], name: "index_clean_ups_on_referential_id", using: :btree
--
cgit v1.2.3
From b4ea175349adaffe4c797c7077865b2dd1c0fc20 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/helpers/table_builder_helper/url.rb | 2 +-
db/schema.rb | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/helpers/table_builder_helper/url.rb b/app/helpers/table_builder_helper/url.rb
index 0e3dce0aa..57172301c 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?(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
diff --git a/db/schema.rb b/db/schema.rb
index 99c02594a..4e78658c2 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: 20180126134944) do
+ActiveRecord::Schema.define(version: 20180123174450) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
--
cgit v1.2.3
From 5e7506b377ea13ee5326371fb4ac9e592252cf37 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 | 1 +
app/helpers/table_builder_helper/url.rb | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb
index 925e88e41..aa79c3cf8 100644
--- a/app/controllers/calendars_controller.rb
+++ b/app/controllers/calendars_controller.rb
@@ -1,4 +1,5 @@
class CalendarsController < ChouetteController
+ include WorkgroupSupport
include PolicyChecker
include TimeTablesHelper
diff --git a/app/helpers/table_builder_helper/url.rb b/app/helpers/table_builder_helper/url.rb
index 57172301c..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
--
cgit v1.2.3
From 65ac4e0cf99b5cd40d0e0b052a43427910867a18 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 | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb
index aa79c3cf8..f029b66f7 100644
--- a/app/controllers/calendars_controller.rb
+++ b/app/controllers/calendars_controller.rb
@@ -1,5 +1,4 @@
class CalendarsController < ChouetteController
- include WorkgroupSupport
include PolicyChecker
include TimeTablesHelper
@@ -8,6 +7,8 @@ class CalendarsController < ChouetteController
respond_to :html
respond_to :json, only: :show
respond_to :js, only: :index
+
+ belongs_to :workgroup
belongs_to :workgroup
--
cgit v1.2.3
From 19cc1417ab9dc16380a11b53cb35454096354187 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 | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb
index f029b66f7..a9f792bd0 100644
--- a/app/controllers/calendars_controller.rb
+++ b/app/controllers/calendars_controller.rb
@@ -7,7 +7,7 @@ class CalendarsController < ChouetteController
respond_to :html
respond_to :json, only: :show
respond_to :js, only: :index
-
+
belongs_to :workgroup
belongs_to :workgroup
@@ -129,4 +129,4 @@ class CalendarsController < ChouetteController
scope
end
-end
\ No newline at end of file
+end
--
cgit v1.2.3
From 6fed156aac403fdd3dd8aeb4c023dd0fb7adec21 Mon Sep 17 00:00:00 2001
From: cedricnjanga
Date: Tue, 6 Feb 2018 06:19:46 -0800
Subject: Remove workgroup_support concern
---
app/controllers/concerns/workgroup_support.rb | 12 ------------
1 file changed, 12 deletions(-)
delete mode 100644 app/controllers/concerns/workgroup_support.rb
diff --git a/app/controllers/concerns/workgroup_support.rb b/app/controllers/concerns/workgroup_support.rb
deleted file mode 100644
index a3b49bb12..000000000
--- a/app/controllers/concerns/workgroup_support.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-module WorkgroupSupport
- extend ActiveSupport::Concern
-
- included do
- before_action :find_workgroup
- end
-
- def find_workgroup
- @workgroup ||= Workgroup.find params[:workgroup_id]
- end
-
-end
--
cgit v1.2.3
From ad7dfea7f280cdf0727dd3471a1f26db4197c394 Mon Sep 17 00:00:00 2001
From: cedricnjanga
Date: Tue, 6 Feb 2018 10:43:59 -0800
Subject: Update calendar form_simple according to workgroup
---
app/models/chouette/stop_area.rb | 6 ------
app/views/calendars/_form_simple.html.slim | 2 +-
db/schema.rb | 6 ++----
3 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb
index 565fa5f4b..cf2afbc73 100644
--- a/app/models/chouette/stop_area.rb
+++ b/app/models/chouette/stop_area.rb
@@ -117,13 +117,7 @@ module Chouette
end
end
-<<<<<<< HEAD
alias_method :local_id, :user_objectid
-=======
- def local_id
- id.to_s
- end
->>>>>>> Refs #5750 @1h; Add a "kind" attribute to StopAreas
def children_in_depth
return [] if self.children.empty?
diff --git a/app/views/calendars/_form_simple.html.slim b/app/views/calendars/_form_simple.html.slim
index 2f469ada7..ba18c765b 100644
--- a/app/views/calendars/_form_simple.html.slim
+++ b/app/views/calendars/_form_simple.html.slim
@@ -1,6 +1,6 @@
.row
.col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-10.col-sm-offset-1
- = 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/db/schema.rb b/db/schema.rb
index 4e78658c2..5ff0a9326 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,14 +11,13 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20180123174450) do
+ActiveRecord::Schema.define(version: 20180129141656) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
- enable_extension "hstore"
enable_extension "postgis"
+ enable_extension "hstore"
enable_extension "unaccent"
- enable_extension "objectid"
create_table "access_links", id: :bigserial, force: :cascade do |t|
t.integer "access_point_id", limit: 8
@@ -120,7 +119,6 @@ ActiveRecord::Schema.define(version: 20180123174450) do
t.datetime "updated_at"
t.date "end_date"
t.string "date_type"
- t.string "mode"
end
add_index "clean_ups", ["referential_id"], name: "index_clean_ups_on_referential_id", using: :btree
--
cgit v1.2.3
From 5a6533201e58e99f86a3b12d2abb9372460ee9b6 Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 7 Feb 2018 09:23:20 +0100
Subject: Refs #4126 @6h; Add i18n to JS
---
.gitignore | 2 ++
Gemfile | 1 +
Gemfile.lock | 3 +++
app/assets/javascripts/application.js | 3 +++
app/assets/javascripts/i18n/extended.coffee | 24 ++++++++++++++++++++++
app/assets/stylesheets/components/_tables.sass | 3 ++-
.../vehicle_journeys/components/ConfirmModal.js | 6 +++---
.../vehicle_journeys/components/Filters.js | 18 ++++++++--------
.../vehicle_journeys/components/VehicleJourney.js | 10 ++++-----
.../vehicle_journeys/components/VehicleJourneys.js | 18 ++++++++--------
.../components/tools/EditVehicleJourney.js | 2 +-
app/views/calendars/_form_advanced.html.slim | 2 +-
app/views/layouts/application.html.slim | 2 ++
app/views/routes/_form.html.slim | 2 +-
app/views/time_tables/edit.html.slim | 2 +-
app/views/time_tables/index.html.slim | 2 +-
app/views/vehicle_journeys/index.html.slim | 2 +-
app/views/workbenches/show.html.slim | 2 +-
config/environments/development.rb | 1 +
config/locales/en.yml | 5 +++++
config/locales/fr.yml | 4 ++++
config/locales/vehicle_journeys.en.yml | 15 ++++++++++++++
config/locales/vehicle_journeys.fr.yml | 16 +++++++++++++++
lib/tasks/ci.rake | 4 ++--
package.json | 4 ++++
spec/javascript/preprocessor.js | 15 ++++++++++++++
.../components/VehicleJourneys_spec.js | 7 +++++++
.../__snapshots__/VehicleJourneys_spec.js.snap | 20 +++++++++---------
28 files changed, 149 insertions(+), 46 deletions(-)
create mode 100644 app/assets/javascripts/i18n/extended.coffee
create mode 100644 spec/javascript/preprocessor.js
diff --git a/.gitignore b/.gitignore
index acdb5e230..dd4d057ef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,8 @@
/tmp
*~
public/assets/
+public/javascripts/i18n.js
+public/javascripts/translations.js
# for vim users
*.swp
diff --git a/Gemfile b/Gemfile
index bb1a42df0..db5202bdf 100644
--- a/Gemfile
+++ b/Gemfile
@@ -103,6 +103,7 @@ gem 'will_paginate-bootstrap'
gem 'gretel'
gem 'country_select'
gem 'flag-icons-rails'
+gem 'i18n-js'
# Format Output
gem 'json'
diff --git a/Gemfile.lock b/Gemfile.lock
index ffa63b535..41469d9c2 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -270,6 +270,8 @@ GEM
multi_xml (>= 0.5.2)
i18n (0.9.3)
concurrent-ruby (~> 1.0)
+ i18n-js (3.0.4)
+ i18n (~> 0.6, >= 0.6.6)
i18n-tasks (0.9.15)
activesupport (>= 4.0.2)
ast (>= 2.1.0)
@@ -636,6 +638,7 @@ DEPENDENCIES
gretel
has_array_of!
htmlbeautifier
+ i18n-js
i18n-tasks
inherited_resources
jbuilder (~> 2.0)
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 4c5aff22f..6a79f7e8e 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -22,3 +22,6 @@
//= require_directory .
// require('whatwg-fetch')
// require('babel-polyfill')
+//= require "i18n"
+//= require "i18n/extended"
+//= require "i18n/translations"
diff --git a/app/assets/javascripts/i18n/extended.coffee b/app/assets/javascripts/i18n/extended.coffee
new file mode 100644
index 000000000..aeb67bd09
--- /dev/null
+++ b/app/assets/javascripts/i18n/extended.coffee
@@ -0,0 +1,24 @@
+#= require i18n
+
+decorateI18n = (_i18n)->
+ _i18n.tc = (key, opts={}) ->
+ out = _i18n.t(key, opts)
+ out += " " if _i18n.locale == "fr"
+ out + ":"
+
+ _i18n.model_name = (model, opts={}) ->
+ last_key = if opts.plural then "other" else "one"
+ _i18n.t("activerecord.models.#{model}.#{last_key}")
+
+ _i18n.attribute_name = (model, attribute, opts={}) ->
+ _i18n.t("activerecord.attributes.#{model}.#{attribute}")
+
+ _i18n.enumerize = (enumerize, key, opts={}) ->
+ I18n.t("enumerize.#{enumerize}.#{key}")
+
+ _i18n
+
+module?.exports = decorateI18n
+
+if I18n?
+ decorateI18n(I18n)
diff --git a/app/assets/stylesheets/components/_tables.sass b/app/assets/stylesheets/components/_tables.sass
index 35e1122f3..5f8b06f09 100644
--- a/app/assets/stylesheets/components/_tables.sass
+++ b/app/assets/stylesheets/components/_tables.sass
@@ -9,7 +9,6 @@
font-weight: 700
border-bottom: 2px solid $darkgrey
vertical-align: middle
-
> a
position: relative
display: block
@@ -326,6 +325,8 @@
padding: 6px 8px
border-bottom: 2px solid rgba($grey, 0.5)
border-top: 1px solid rgba($grey, 0.5)
+ text-transform: capitalize
+
.td
position: relative
padding: 6px 8px
diff --git a/app/javascript/vehicle_journeys/components/ConfirmModal.js b/app/javascript/vehicle_journeys/components/ConfirmModal.js
index 3bfc852fb..75e8a3932 100644
--- a/app/javascript/vehicle_journeys/components/ConfirmModal.js
+++ b/app/javascript/vehicle_journeys/components/ConfirmModal.js
@@ -7,7 +7,7 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan
-
Voulez-vous valider vos modifications avant de changer de page?
+
{I18n.t('vehicle_journeys.vehicle_journeys_matrix.modal_confirm')}
)
-}
+}
ConfirmModal.propTypes = {
vehicleJourneys: PropTypes.array.isRequired,
modal: PropTypes.object.isRequired,
onModalAccept: PropTypes.func.isRequired,
onModalCancel: PropTypes.func.isRequired
-}
\ No newline at end of file
+}
diff --git a/app/javascript/vehicle_journeys/components/Filters.js b/app/javascript/vehicle_journeys/components/Filters.js
index 2bd912e3e..f8697c930 100644
--- a/app/javascript/vehicle_journeys/components/Filters.js
+++ b/app/javascript/vehicle_journeys/components/Filters.js
@@ -46,10 +46,10 @@ export default function Filters({filters, pagination, missions, onFilter, onRese
{/* Plage horaire */}
-
Plage horaire au départ de la course
+
{I18n.t("vehicle_journeys.form.departure_range.label")}
-
Début
+
{I18n.t("vehicle_journeys.form.departure_range.start")}
-
Fin
+
{I18n.t("vehicle_journeys.form.departure_range.end")}
-
Afficher les courses sans horaires
+
{I18n.t("vehicle_journeys.form.show_journeys_without_schedule")}
@@ -110,8 +110,8 @@ export default function Filters({filters, pagination, missions, onFilter, onRese
onChange={onToggleWithoutSchedule}
checked={filters.query.withoutSchedule}
>
-
- {filters.query.withoutSchedule ? 'Oui' : 'Non'}
+
+ {filters.query.withoutSchedule ? I18n.t("yes") : I18n.t("no")}
@@ -122,7 +122,7 @@ export default function Filters({filters, pagination, missions, onFilter, onRese
{/* Switch avec/sans calendrier */}
-
Afficher les courses avec calendrier
+
{I18n.t("vehicle_journeys.form.show_journeys_with_calendar")}
@@ -131,8 +131,8 @@ export default function Filters({filters, pagination, missions, onFilter, onRese
onChange={onToggleWithoutTimeTable}
checked={filters.query.withoutTimeTable}
>
-
- {filters.query.withoutTimeTable ? 'Oui' : 'Non'}
+
+ {filters.query.withoutTimeTable ? I18n.t("yes") : I18n.t("no")}
diff --git a/app/javascript/vehicle_journeys/components/VehicleJourney.js b/app/javascript/vehicle_journeys/components/VehicleJourney.js
index 99a458f50..4a9432231 100644
--- a/app/javascript/vehicle_journeys/components/VehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/VehicleJourney.js
@@ -23,7 +23,7 @@ export default class VehicleJourney extends Component {
let ttURL = refURL + '/time_tables/' + tt.id
return (
-
+
)
}
@@ -32,7 +32,7 @@ export default class VehicleJourney extends Component {
let ttURL = refURL + '/purchase_windows/' + tt.id
return (
-
+
)
}
@@ -65,7 +65,7 @@ export default class VehicleJourney extends Component {
}
>
{this.props.value.short_id || '-'}
-
{this.props.value.published_journey_name && this.props.value.published_journey_name != "non renseigné" ? this.props.value.published_journey_name : '-'}
+
{this.props.value.published_journey_name && this.props.value.published_journey_name != I18n.t('undefined') ? this.props.value.published_journey_name : '-'}
{this.props.value.journey_pattern.short_id || '-'}
{this.props.value.company ? this.props.value.company.name : '-'}
@@ -100,7 +100,7 @@ export default class VehicleJourney extends Component {
{this.props.filters.toggleArrivals &&
-
+
}
-
+
{(this.props.status.fetchSuccess == false) && (
- Erreur :
- la récupération des missions a rencontré un problème. Rechargez la page pour tenter de corriger le problème.
+ {I18n.tc("error")}
+ {I18n.t("vehicle_journeys.vehicle_journeys_matrix.fetching_error")}
)}
{ this.vehicleJourneysList().errors && this.vehicleJourneysList().errors.length && _.some(this.vehicleJourneysList(), 'errors') && (
-
Erreur :
+
{I18n.tc("error")}
{this.vehicleJourneysList().map((vj, index) =>
vj.errors && vj.errors.map((err, i) => {
return (
@@ -129,12 +129,12 @@ export default class VehicleJourneys extends Component {
0) ? '' : ' no_result')}>
-
ID course
-
Nom course
-
ID mission
-
Transporteur
-
Calendriers
- { this.hasFeature('purchase_windows') &&
Calendriers Commerciaux
}
+
{I18n.attribute_name("vehicle_journey", "id")}
+
{I18n.attribute_name("vehicle_journey", "name")}
+
{I18n.attribute_name("vehicle_journey", "journey_pattern_id")}
+
{I18n.model_name("company")}
+
{I18n.model_name("time_table", "plural": true)}
+ { this.hasFeature('purchase_windows') &&
{I18n.model_name("purchase_window", "plural": true)}
}
{this.stopPoints().map((sp, i) =>{
return (
diff --git a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js
index f6a0e3c61..bcfd4eb41 100644
--- a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js
@@ -128,7 +128,7 @@ export default class EditVehicleJourney extends Component {
diff --git a/app/views/calendars/_form_advanced.html.slim b/app/views/calendars/_form_advanced.html.slim
index b4154166b..e796e2e36 100644
--- a/app/views/calendars/_form_advanced.html.slim
+++ b/app/views/calendars/_form_advanced.html.slim
@@ -2,7 +2,7 @@
= javascript_tag do
| window.actionType = "#{raw params[:action]}";
- | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe};
+ // | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe};
| window.timetablesUrl = "#{calendar_url(@calendar).html_safe}";
= javascript_pack_tag 'calendars/edit.js'
diff --git a/app/views/layouts/application.html.slim b/app/views/layouts/application.html.slim
index 34b373295..3921c8701 100644
--- a/app/views/layouts/application.html.slim
+++ b/app/views/layouts/application.html.slim
@@ -13,6 +13,8 @@ html lang=I18n.locale
= javascript_pack_tag 'application'
= javascript_include_tag 'application'
+ = javascript_tag do
+ | I18n.locale = '#{I18n.locale}'
body
= render 'layouts/navigation/main_nav'
diff --git a/app/views/routes/_form.html.slim b/app/views/routes/_form.html.slim
index 29e5be3d2..81f719437 100644
--- a/app/views/routes/_form.html.slim
+++ b/app/views/routes/_form.html.slim
@@ -27,7 +27,7 @@
// Get JSON data for route stop points
= javascript_tag do
| window.itinerary_stop = "#{URI.escape(route_json_for_edit(@route))}";
- | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe};
+ // | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe};
/ StopPoints Reactux component
= javascript_pack_tag 'routes/edit.js'
diff --git a/app/views/time_tables/edit.html.slim b/app/views/time_tables/edit.html.slim
index e1c566ff4..d8cffb1b0 100644
--- a/app/views/time_tables/edit.html.slim
+++ b/app/views/time_tables/edit.html.slim
@@ -8,6 +8,6 @@
= javascript_tag do
| window.actionType = "#{raw params[:action]}";
- | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe};
+ // | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe};
= javascript_pack_tag 'time_tables/edit.js'
diff --git a/app/views/time_tables/index.html.slim b/app/views/time_tables/index.html.slim
index f58fbb5ea..6913712a0 100644
--- a/app/views/time_tables/index.html.slim
+++ b/app/views/time_tables/index.html.slim
@@ -61,6 +61,6 @@
= replacement_msg t('time_tables.search_no_results')
= javascript_tag do
- | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe};
+ // | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe};
= javascript_pack_tag 'date_filters'
diff --git a/app/views/vehicle_journeys/index.html.slim b/app/views/vehicle_journeys/index.html.slim
index caa8450a0..d53d8b50c 100644
--- a/app/views/vehicle_journeys/index.html.slim
+++ b/app/views/vehicle_journeys/index.html.slim
@@ -29,7 +29,7 @@
| window.features = #{raw @features};
| window.all_missions = #{(@all_missions.to_json).html_safe};
| window.custom_fields = #{(@custom_fields.to_json).html_safe};
- | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe};
+ // | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe};
- if has_feature?(:vehicle_journeys_return_route)
= javascript_tag do
diff --git a/app/views/workbenches/show.html.slim b/app/views/workbenches/show.html.slim
index a162ca334..aae34c51b 100644
--- a/app/views/workbenches/show.html.slim
+++ b/app/views/workbenches/show.html.slim
@@ -72,6 +72,6 @@
= replacement_msg t('referentials.search_no_results')
= javascript_tag do
- | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe};
+ // | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe};
= javascript_pack_tag 'date_filters'
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 1d2fee44f..446e72190 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -95,6 +95,7 @@ Rails.application.configure do
config.i18n.available_locales = [:fr, :en]
config.middleware.insert_after(ActionDispatch::Static, Rack::LiveReload) if ENV['LIVERELOAD']
+ config.middleware.use I18n::JS::Middleware
config.development_toolbar = false
if ENV['TOOLBAR'] && File.exists?("config/development_toolbar.rb")
config.development_toolbar = OpenStruct.new
diff --git a/config/locales/en.yml b/config/locales/en.yml
index e59960f95..d78d51dbe 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -3,6 +3,7 @@ en:
"false": "No"
"unknown": "Unknown"
+
time:
formats:
hour: "%Hh%M"
@@ -61,3 +62,7 @@ en:
reflex_data: 'Reflex datas'
objectid: 'ID'
brandname: IBOO
+ error: "Error"
+ undefined: 'undefined'
+ yes: yes
+ no: no
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 175b71ebc..d89c286af 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -61,3 +61,7 @@ fr:
reflex_data: 'Données Reflex'
objectid: 'ID'
brandname: IBOO
+ error: "Erreur"
+ undefined: 'non renseigné'
+ yes: oui
+ no: non
diff --git a/config/locales/vehicle_journeys.en.yml b/config/locales/vehicle_journeys.en.yml
index abb1da530..a1f20a7e8 100644
--- a/config/locales/vehicle_journeys.en.yml
+++ b/config/locales/vehicle_journeys.en.yml
@@ -2,6 +2,10 @@ en:
vehicle_journeys:
vehicle_journeys_matrix:
line_routes: "Line's routes"
+ fetching_error: "There has been a problem fetching the data. Please reload the page to try again."
+ show_timetable: 'Show calendar'
+ show_purchase_window: 'Show the purchase window'
+ modal_confirm: 'Do you want to save mofications before moving on to the next page ?'
vehicle_journey:
title_stopless: "Vehicle journey %{name}"
title: "Vehicle journey leaving from %{stop} at %{time}"
@@ -28,6 +32,8 @@ en:
stop_title: "Stop"
departure: "Departure"
arrival: "Arrival"
+ departure_at: "Departure at"
+ arrival_at: "Arrival at"
to_arrivals: "Copy departures to arrivals"
to_departures: "Copy arrivals to departures"
time_tables: "Associated calendars to vehicle journey"
@@ -35,6 +41,12 @@ en:
slide_title: "Shift all vehicle passing times"
set: "Set"
to: "at"
+ departure_range:
+ label: Journey departure range
+ start: Start
+ end: End
+ show_journeys_without_schedule: "Show journeys without schedule"
+ show_journeys_with_calendar: "Show journeys with calendar"
slide_departure: "departure time at first stop"
slide_arrival: "arrival time at first stop"
submit_timed: "Create vehicle journey"
@@ -81,6 +93,7 @@ en:
line: "Line"
route: "Route"
journey_pattern: "Journey Pattern"
+ journey_pattern_id: "Pattern ID"
time_tables: "Calendars"
time_slot: "Time Slot"
company: "Company"
@@ -112,6 +125,8 @@ en:
departure_time: "Departure"
arrival_time: "Arrival"
purchase_window: "Purchase availability"
+ name: "Journey Name"
+ id: "Journey ID"
errors:
models:
vehicle_journey:
diff --git a/config/locales/vehicle_journeys.fr.yml b/config/locales/vehicle_journeys.fr.yml
index ca8475812..be5be2382 100644
--- a/config/locales/vehicle_journeys.fr.yml
+++ b/config/locales/vehicle_journeys.fr.yml
@@ -2,6 +2,10 @@ fr:
vehicle_journeys:
vehicle_journeys_matrix:
line_routes: "Séquences d'arrêts de la ligne"
+ fetching_error: "La récupération des missions a rencontré un problème. Rechargez la page pour tenter de corriger le problème."
+ show_timetable: 'Voir le calendrier'
+ show_purchase_window: 'Voir le calendrier commercial'
+ modal_confirm: 'Voulez-vous valider vos modifications avant de changer de page?'
vehicle_journey:
title_stopless: "Course %{name}"
title: "Course partant de %{stop} à %{time}"
@@ -27,7 +31,10 @@ fr:
form:
stop_title: "Arrêt"
departure: "Départ"
+ departure_at: "Départ à"
arrival: "Arrivée"
+ arrival_at: "Arrivée à"
+ to_arrivals: "Copie départs vers arrivées"
to_arrivals: "Copie départs vers arrivées"
to_departures: "Copie arrivées vers départs"
time_tables: "Calendriers associés à la course"
@@ -35,6 +42,12 @@ fr:
slide_title: "Décaler l'ensemble des horaires de course"
set: "Fixer"
to: "à"
+ departure_range:
+ label: Plage horaire au départ de la course
+ start: Début
+ end: Fin
+ show_journeys_without_schedule: "Afficher les courses sans horaires"
+ show_journeys_with_calendar: "Afficher les courses avec calendrier"
slide_departure: "horaire de départ au 1° arrêt à"
slide_arrival: "horaire d'arrivée au 1° arrêt à"
submit_timed: "Créer course"
@@ -81,6 +94,7 @@ fr:
line: "Ligne"
route: "Séquence d'arrêt"
journey_pattern: "Mission"
+ journey_pattern_id: "ID Mission"
time_tables: "Calendriers"
time_slot: "Fréquence"
company: "Transporteur"
@@ -112,6 +126,8 @@ fr:
departure_time: "Départ"
arrival_time: "Arrivée"
purchase_window: "Disponibilité commerciale"
+ name: "Nom Course"
+ id: "ID Course"
errors:
models:
vehicle_journey:
diff --git a/lib/tasks/ci.rake b/lib/tasks/ci.rake
index 13d7b8d73..889a5c0ad 100644
--- a/lib/tasks/ci.rake
+++ b/lib/tasks/ci.rake
@@ -38,7 +38,7 @@ namespace :ci do
end
task :jest => "ci:assets" do
- sh "yarn --no-progress install" # Hack to force install jest after webpack
+ sh "yarn --no-progress install" # Hack to force install jest after webpack
sh "node_modules/.bin/jest" unless ["CHOUETTE_JEST_DISABLED"]
end
@@ -59,4 +59,4 @@ namespace :ci do
end
desc "Run continuous integration tasks (spec, ...)"
-task :ci => ["ci:setup", "ci:spec", "ci:jest", "cucumber", "ci:check_security", "ci:deploy", "ci:clean"]
+task :ci => ["ci:setup", "ci:spec", "i18n:js:export", "ci:jest", "cucumber", "ci:check_security", "ci:deploy", "ci:clean"]
diff --git a/package.json b/package.json
index e80f5231e..25b158e3d 100644
--- a/package.json
+++ b/package.json
@@ -49,6 +49,10 @@
"roots": [
"
/spec/javascript"
],
+ "transform": {
+ "^.+\\.coffee$": "/spec/javascript/preprocessor.js",
+ "^.+\\.jsx?$": "babel-jest"
+ },
"testEnvironment": "jest-environment-jsdom-global",
"setupFiles": [
"/spec/javascript/spec_helper.js",
diff --git a/spec/javascript/preprocessor.js b/spec/javascript/preprocessor.js
new file mode 100644
index 000000000..a2de8e4be
--- /dev/null
+++ b/spec/javascript/preprocessor.js
@@ -0,0 +1,15 @@
+'use strict';
+
+var coffee = require('coffeescript');
+
+module.exports = {
+ process: function(src, filename) {
+ if (coffee.helpers.isCoffee(filename)) {
+ return coffee.compile(src, {
+ 'bare': false,
+ 'inlineMap': true
+ })
+ }
+ return src;
+ }
+};
diff --git a/spec/javascript/vehicle_journeys/components/VehicleJourneys_spec.js b/spec/javascript/vehicle_journeys/components/VehicleJourneys_spec.js
index 87151c64b..2a84cb9ca 100644
--- a/spec/javascript/vehicle_journeys/components/VehicleJourneys_spec.js
+++ b/spec/javascript/vehicle_journeys/components/VehicleJourneys_spec.js
@@ -1,6 +1,13 @@
import React, { Component } from 'react'
import VehicleJourneys from '../../../../app/javascript/vehicle_journeys/components/VehicleJourneys'
import renderer from 'react-test-renderer'
+import fs from 'fs'
+
+import I18n from '../../../../public/javascripts/i18n'
+import decorateI18n from '../../../../app/assets/javascripts/i18n/extended.coffee'
+window.I18n = decorateI18n(I18n)
+I18n.locale = "fr"
+eval(fs.readFileSync('./public/javascripts/translations.js')+'')
describe('stopPointHeader', () => {
set('features', () => {
diff --git a/spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap b/spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap
index 703f727d7..cdd34cbbd 100644
--- a/spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap
+++ b/spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap
@@ -19,19 +19,19 @@ exports[`stopPointHeader should display the city name 1`] = `
- ID course
+ ID Course
- Nom course
+ Nom Course
- ID mission
+ ID Mission
- Transporteur
+ transporteur
- Calendriers
+ calendrier
- ID course
+ ID Course
- Nom course
+ Nom Course
- ID mission
+ ID Mission
- Transporteur
+ transporteur
- Calendriers
+ calendrier
- Liste des horaires {minVJ} à {maxVJ} sur {pagination.totalCount}
-
+ {I18n.t("vehicle_journeys.vehicle_journeys_matrix.pagination", {minVJ, maxVJ, total:pagination.totalCount})}
\ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys.snap b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys.snap
index 06e60d910..83531ac0e 100644
--- a/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys.snap
+++ b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys.snap
@@ -3,5 +3,7 @@
Dernière mise à jour le 01/01/2000
-
+
\ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_create.snap b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_create.snap
index 4f0f8352d..e5d309b96 100644
--- a/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_create.snap
+++ b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_create.snap
@@ -4,6 +4,6 @@
Dernière mise à jour le 01/01/2000
\ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_destroy.snap b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_destroy.snap
index 49ead7d2a..d90198391 100644
--- a/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_destroy.snap
+++ b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_destroy.snap
@@ -4,6 +4,6 @@
Dernière mise à jour le 01/01/2000
\ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_update.snap b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_update.snap
index 9d8b4f276..32d46beda 100644
--- a/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_update.snap
+++ b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_update.snap
@@ -7,6 +7,6 @@
\ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_update.snap b/spec/views/referentials/__snapshots__/referentials/show_update.snap
index 9d8b4f276..32d46beda 100644
--- a/spec/views/referentials/__snapshots__/referentials/show_update.snap
+++ b/spec/views/referentials/__snapshots__/referentials/show_update.snap
@@ -7,6 +7,6 @@
\ No newline at end of file
diff --git a/spec/views/referentials/show.html.erb_spec.rb b/spec/views/referentials/show.html.erb_spec.rb
index 9aaa762fe..ea3bc1fe1 100644
--- a/spec/views/referentials/show.html.erb_spec.rb
+++ b/spec/views/referentials/show.html.erb_spec.rb
@@ -28,22 +28,6 @@ describe "referentials/show", type: :view do
allow(referential).to receive(:referential_read_only?){ readonly }
end
- it "should not present edit button" do
- expect(rendered).to_not have_selector("a[href=\"#{view.edit_referential_path(referential)}\"]")
- end
-
- with_permission "referentials.update" do
- it "should present edit button" do
- expect(rendered).to have_selector("a[href=\"#{view.edit_referential_path(referential)}\"]")
- end
-
- context "with a readonly referential" do
- let(:readonly){ true }
- it "should not present edit button" do
- expect(rendered).to_not have_selector("a[href=\"#{view.edit_referential_path(referential)}\"]")
- end
- end
- end
describe "action links" do
set_invariant "referential.object.full_name", "referential_full_name"
--
cgit v1.2.3
From 34dca4bbfc60b17a1648d8af34d592ec7c58c0ca Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 9 Feb 2018 10:52:01 +0100
Subject: Refs 5669; Fix specs
---
spec/support/pundit/pundit_view_policy.rb | 1 +
spec/views/companies/__snapshots__/companies/show_destroy.snap | 2 +-
spec/views/lines/__snapshots__/lines/show_destroy.snap | 2 +-
spec/views/lines/show.html.erb_spec.rb | 2 +-
4 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/spec/support/pundit/pundit_view_policy.rb b/spec/support/pundit/pundit_view_policy.rb
index 058f1f6ed..63970de02 100644
--- a/spec/support/pundit/pundit_view_policy.rb
+++ b/spec/support/pundit/pundit_view_policy.rb
@@ -11,6 +11,7 @@ module Pundit
allow(view).to receive(:current_user) { current_user }
allow(view).to receive(:current_organisation).and_return(organisation)
allow(view).to receive(:current_offer_workbench).and_return(current_offer_workbench)
+ allow(view).to receive(:current_workgroup).and_return(current_offer_workbench.workgroup)
allow(view).to receive(:has_feature?){ |f| features.include?(f)}
allow(view).to receive(:user_signed_in?).and_return true
allow(view).to receive(:policy) do |instance|
diff --git a/spec/views/companies/__snapshots__/companies/show_destroy.snap b/spec/views/companies/__snapshots__/companies/show_destroy.snap
index 5799faf8e..5d574e460 100644
--- a/spec/views/companies/__snapshots__/companies/show_destroy.snap
+++ b/spec/views/companies/__snapshots__/companies/show_destroy.snap
@@ -3,5 +3,5 @@
Transporteur Company Name
Dernière mise à jour le 23/01/2018 Par web service
-
+
\ No newline at end of file
diff --git a/spec/views/lines/__snapshots__/lines/show_destroy.snap b/spec/views/lines/__snapshots__/lines/show_destroy.snap
index dbfba7c66..8ed08a90d 100644
--- a/spec/views/lines/__snapshots__/lines/show_destroy.snap
+++ b/spec/views/lines/__snapshots__/lines/show_destroy.snap
@@ -4,6 +4,6 @@
Dernière mise à jour le 23/01/2018 Par web service
\ No newline at end of file
diff --git a/spec/views/lines/show.html.erb_spec.rb b/spec/views/lines/show.html.erb_spec.rb
index aeae62e98..effdcd014 100644
--- a/spec/views/lines/show.html.erb_spec.rb
+++ b/spec/views/lines/show.html.erb_spec.rb
@@ -23,7 +23,7 @@ describe "/lines/show", :type => :view do
describe "action links" do
set_invariant "line_referential.id", "99"
- set_invariant "line.id", "99"
+ set_invariant "line.object.id", "99"
set_invariant "line.object.name", "Name"
set_invariant "line.company.id", "99"
set_invariant "line.network.id", "99"
--
cgit v1.2.3
From c608e69bb3908de4c319689fa8232cff4a046b86 Mon Sep 17 00:00:00 2001
From: Luc Donnet
Date: Fri, 9 Feb 2018 11:14:18 +0100
Subject: Fix display compliance_check_sets#index for referential destroyed
Refs #5874 @1
---
app/views/compliance_check_sets/index.html.slim | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/views/compliance_check_sets/index.html.slim b/app/views/compliance_check_sets/index.html.slim
index ead467174..31ad31e5b 100644
--- a/app/views/compliance_check_sets/index.html.slim
+++ b/app/views/compliance_check_sets/index.html.slim
@@ -23,9 +23,9 @@
), \
TableBuilderHelper::Column.new( \
key: :associated_object, \
- attribute: Proc.new{|n| n.referential.name}, \
+ attribute: Proc.new{|n| n.referential.present? ? n.referential.name : ''}, \
link_to: lambda do |compliance_check_set| \
- referential_path(compliance_check_set.referential_id) \
+ compliance_check_set.referential.present? ? referential_path(compliance_check_set.referential_id) : '#' \
end \
), \
TableBuilderHelper::Column.new( \
--
cgit v1.2.3
From 5152b611d62849c7f9bac24f1708aba6a651fe75 Mon Sep 17 00:00:00 2001
From: Alban Peignier
Date: Thu, 1 Feb 2018 23:51:21 +0100
Subject: Remove Referential#stop_areas to use stop_areas has_many through.
Refs #5824
---
app/models/referential.rb | 4 ----
1 file changed, 4 deletions(-)
diff --git a/app/models/referential.rb b/app/models/referential.rb
index baaa354da..f64db4ebf 100644
--- a/app/models/referential.rb
+++ b/app/models/referential.rb
@@ -153,10 +153,6 @@ class Referential < ActiveRecord::Base
end
end
- def stop_areas
- Chouette::StopArea.all
- end
-
def access_points
Chouette::AccessPoint.all
end
--
cgit v1.2.3
From 07090fa73906d46da046dddce689802be884ec8a Mon Sep 17 00:00:00 2001
From: Alban Peignier
Date: Thu, 1 Feb 2018 23:52:06 +0100
Subject: Add table name in unaccent request (to avoid problem with
Referential#stop_areas has_many through. Refs #5824
---
app/controllers/autocomplete_stop_areas_controller.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/controllers/autocomplete_stop_areas_controller.rb b/app/controllers/autocomplete_stop_areas_controller.rb
index d82fa316a..79154a6e0 100644
--- a/app/controllers/autocomplete_stop_areas_controller.rb
+++ b/app/controllers/autocomplete_stop_areas_controller.rb
@@ -21,7 +21,7 @@ class AutocompleteStopAreasController < ChouetteController
scope = StopAreaPolicy::Scope.new(current_user, scope).search_scope(search_scope)
end
args = [].tap{|arg| 4.times{arg << "%#{params[:q]}%"}}
- @stop_areas = scope.where("unaccent(name) ILIKE unaccent(?) OR unaccent(city_name) ILIKE unaccent(?) OR registration_number ILIKE ? OR objectid ILIKE ?", *args).limit(50)
+ @stop_areas = scope.where("unaccent(stop_areas.name) ILIKE unaccent(?) OR unaccent(stop_areas.city_name) ILIKE unaccent(?) OR stop_areas.registration_number ILIKE ? OR stop_areas.objectid ILIKE ?", *args).limit(50)
@stop_areas
end
--
cgit v1.2.3
From 23882d8e525a63d15b4dca1731b2184984621f52 Mon Sep 17 00:00:00 2001
From: Zog
Date: Fri, 2 Feb 2018 10:20:22 +0100
Subject: Refs #5824; Fix specs
---
spec/controllers/api/v1/stop_area_controller_spec.rb | 9 ++++-----
spec/controllers/autocomplete_stop_areas_controller_spec.rb | 6 +++---
spec/features/access_points_spec.rb | 2 +-
spec/features/referential_stop_areas_spec.rb | 2 +-
4 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/spec/controllers/api/v1/stop_area_controller_spec.rb b/spec/controllers/api/v1/stop_area_controller_spec.rb
index eb0c87661..1ad71a95a 100644
--- a/spec/controllers/api/v1/stop_area_controller_spec.rb
+++ b/spec/controllers/api/v1/stop_area_controller_spec.rb
@@ -18,16 +18,15 @@ describe Api::V1::StopAreasController, :type => :controller do
end
end
describe "GET #index, :q => { :name_cont => 'aa'}" do
- let!(:sa1) { create(:stop_area, :name => "aaa") }
- let!(:sa2) { create(:stop_area, :name => "aab") }
- let!(:sa3) { create(:stop_area, :name => "abb") }
+ let!(:sa1) { create(:stop_area, :name => "aaa", stop_area_referential: referential.stop_area_referential) }
+ let!(:sa2) { create(:stop_area, :name => "aab", stop_area_referential: referential.stop_area_referential) }
+ let!(:sa3) { create(:stop_area, :name => "abb", stop_area_referential: referential.stop_area_referential) }
before :each do
config_formatted_request_with_authorization( "application/json")
- get :index, :q => { :name_cont => "aa"}
+ get :index, :q => { :name_cont => "aa"}
end
it "should assign expected stop_areas" do
expect(assigns[:stop_areas].map(&:name).sort).to eq([ sa1.name, sa2.name])
end
end
end
-
diff --git a/spec/controllers/autocomplete_stop_areas_controller_spec.rb b/spec/controllers/autocomplete_stop_areas_controller_spec.rb
index 2af471361..e8733518c 100644
--- a/spec/controllers/autocomplete_stop_areas_controller_spec.rb
+++ b/spec/controllers/autocomplete_stop_areas_controller_spec.rb
@@ -4,9 +4,9 @@ RSpec.describe AutocompleteStopAreasController, type: :controller do
login_user
let(:referential) { Referential.first }
- let!(:stop_area) { create :stop_area, name: 'écolà militaire' }
- let!(:zdep_stop_area) { create :stop_area, area_type: "zdep" }
- let!(:not_zdep_stop_area) { create :stop_area, area_type: "lda" }
+ let!(:stop_area) { create :stop_area, name: 'écolà militaire', stop_area_referential: referential.stop_area_referential }
+ let!(:zdep_stop_area) { create :stop_area, area_type: "zdep", stop_area_referential: referential.stop_area_referential }
+ let!(:not_zdep_stop_area) { create :stop_area, area_type: "lda", stop_area_referential: referential.stop_area_referential }
describe 'GET #index' do
it 'should be successful' do
diff --git a/spec/features/access_points_spec.rb b/spec/features/access_points_spec.rb
index c16039d67..890906de7 100644
--- a/spec/features/access_points_spec.rb
+++ b/spec/features/access_points_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
describe "Access points", :type => :feature do
login_user
- let!(:stop_area) { create(:stop_area) }
+ let!(:stop_area) { create(:stop_area, stop_area_referential: referential.stop_area_referential) }
let!(:access_points) { Array.new(2) { create(:access_point, :stop_area => stop_area) } }
subject { access_points.first }
diff --git a/spec/features/referential_stop_areas_spec.rb b/spec/features/referential_stop_areas_spec.rb
index 0dc7951a7..5e70857e7 100644
--- a/spec/features/referential_stop_areas_spec.rb
+++ b/spec/features/referential_stop_areas_spec.rb
@@ -5,7 +5,7 @@ describe 'ReferentialStopAreas', type: :feature do
login_user
let(:referential) { Referential.first }
- let(:stop_area_referential) { create :stop_area_referential }
+ let(:stop_area_referential) { referential.stop_area_referential }
let!(:stop_areas) { Array.new(2) { create :stop_area, stop_area_referential: stop_area_referential } }
describe 'index' do
--
cgit v1.2.3
From 8f8ab427914c39fdfb0648978d4fdff25ccfdc63 Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 5 Feb 2018 09:50:46 +0100
Subject: Refs #5824; Add specs (and fix some)
---
.../controllers/autocomplete_stop_areas_controller_spec.rb | 14 +++++++++++---
spec/factories/chouette_stop_areas.rb | 8 ++++++++
spec/models/calendar_spec.rb | 2 +-
3 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/spec/controllers/autocomplete_stop_areas_controller_spec.rb b/spec/controllers/autocomplete_stop_areas_controller_spec.rb
index e8733518c..e0d1cd714 100644
--- a/spec/controllers/autocomplete_stop_areas_controller_spec.rb
+++ b/spec/controllers/autocomplete_stop_areas_controller_spec.rb
@@ -4,9 +4,11 @@ RSpec.describe AutocompleteStopAreasController, type: :controller do
login_user
let(:referential) { Referential.first }
- let!(:stop_area) { create :stop_area, name: 'écolà militaire', stop_area_referential: referential.stop_area_referential }
- let!(:zdep_stop_area) { create :stop_area, area_type: "zdep", stop_area_referential: referential.stop_area_referential }
- let!(:not_zdep_stop_area) { create :stop_area, area_type: "lda", stop_area_referential: referential.stop_area_referential }
+ let(:other_referential) { create :referential }
+ let!(:stop_area) { create :stop_area, name: 'écolà militaire', referential: referential }
+ let!(:other_referential_stop_area) { create :stop_area, name: 'écolà militaire', referential: other_referential }
+ let!(:zdep_stop_area) { create :stop_area, area_type: "zdep", referential: referential }
+ let!(:not_zdep_stop_area) { create :stop_area, area_type: "lda", referential: referential }
describe 'GET #index' do
it 'should be successful' do
@@ -14,6 +16,12 @@ RSpec.describe AutocompleteStopAreasController, type: :controller do
expect(response).to be_success
end
+ it "should filter stop areas based on referential" do
+ get :index, referential_id: referential.id
+ expect(assigns(:stop_areas)).to include(stop_area)
+ expect(assigns(:stop_areas)).to_not include(other_referential_stop_area)
+ end
+
context 'search by name' do
it 'should be successful' do
get :index, referential_id: referential.id, q: 'écolà', :format => :json
diff --git a/spec/factories/chouette_stop_areas.rb b/spec/factories/chouette_stop_areas.rb
index 9b4764781..dab135ca6 100644
--- a/spec/factories/chouette_stop_areas.rb
+++ b/spec/factories/chouette_stop_areas.rb
@@ -10,6 +10,14 @@ FactoryGirl.define do
association :stop_area_referential
+ transient do
+ referential nil
+ end
+
+ before(:create) do |stop_area, evaluator|
+ stop_area.stop_area_referential = evaluator.referential.stop_area_referential if evaluator.referential
+ end
+
trait :deactivated do
deleted_at { 1.hour.ago }
end
diff --git a/spec/models/calendar_spec.rb b/spec/models/calendar_spec.rb
index 3cffd0f8a..a5c0a7471 100644
--- a/spec/models/calendar_spec.rb
+++ b/spec/models/calendar_spec.rb
@@ -36,7 +36,7 @@ RSpec.describe Calendar, :type => :model do
end
it 'validates that dates and date_ranges do not overlap but allow for days not in the list' do
- expect(build(:calendar, dates: [Date.today.beginning_of_week], date_ranges: [Date.today.beginning_of_week..Date.today], int_day_types: Calendar::THURSDAY)).to be_valid
+ expect(build(:calendar, dates: [Date.today.beginning_of_week - 1.week], date_ranges: [(Date.today.beginning_of_week - 1.week)..Date.today], int_day_types: Calendar::THURSDAY)).to be_valid
end
it 'validates that there are no duplicates in dates' do
--
cgit v1.2.3
From 42cff5c818140b193eb90fbb40b31e8a0c708207 Mon Sep 17 00:00:00 2001
From: Teddy Wing
Date: Fri, 9 Feb 2018 12:21:30 +0100
Subject: checksum_support.rb: Add test that checksum is the same on update
Ensure the checksum doesn't change when we save it (and thus call
`#update_checksum`) if the source hasn't changed.
Refs #5416
---
spec/support/checksum_support.rb | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/spec/support/checksum_support.rb b/spec/support/checksum_support.rb
index 760955274..f8dffb1b7 100644
--- a/spec/support/checksum_support.rb
+++ b/spec/support/checksum_support.rb
@@ -75,4 +75,12 @@ shared_examples 'checksum support' do
expect(subject).to receive(:update_checksum).at_least(:once)
subject.save
end
+
+ it "doesn't change the checksum on save if the source hasn't been changed" do
+ checksum = subject.checksum
+
+ subject.save
+
+ expect(subject.checksum).to eq(checksum)
+ end
end
--
cgit v1.2.3
From ae36ee8a9270540cea2b0bea70b0f7c46a1818ef Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 7 Feb 2018 09:23:20 +0100
Subject: Refs #4126 @6h; Add i18n to JS
---
.gitignore | 2 ++
Gemfile | 1 +
Gemfile.lock | 3 +++
app/assets/javascripts/application.js | 3 +++
app/assets/javascripts/i18n/extended.coffee | 24 ++++++++++++++++++++++
app/assets/stylesheets/components/_tables.sass | 3 ++-
.../vehicle_journeys/components/ConfirmModal.js | 6 +++---
.../vehicle_journeys/components/Filters.js | 18 ++++++++--------
.../vehicle_journeys/components/VehicleJourney.js | 10 ++++-----
.../vehicle_journeys/components/VehicleJourneys.js | 18 ++++++++--------
.../components/tools/EditVehicleJourney.js | 2 +-
app/views/calendars/_form_advanced.html.slim | 2 +-
app/views/layouts/application.html.slim | 2 ++
app/views/routes/_form.html.slim | 2 +-
app/views/time_tables/edit.html.slim | 2 +-
app/views/time_tables/index.html.slim | 2 +-
app/views/vehicle_journeys/index.html.slim | 2 +-
app/views/workbenches/show.html.slim | 2 +-
config/environments/development.rb | 1 +
config/locales/en.yml | 5 +++++
config/locales/fr.yml | 4 ++++
config/locales/vehicle_journeys.en.yml | 15 ++++++++++++++
config/locales/vehicle_journeys.fr.yml | 16 +++++++++++++++
lib/tasks/ci.rake | 4 ++--
package.json | 4 ++++
spec/javascript/preprocessor.js | 15 ++++++++++++++
.../components/VehicleJourneys_spec.js | 7 +++++++
.../__snapshots__/VehicleJourneys_spec.js.snap | 20 +++++++++---------
28 files changed, 149 insertions(+), 46 deletions(-)
create mode 100644 app/assets/javascripts/i18n/extended.coffee
create mode 100644 spec/javascript/preprocessor.js
diff --git a/.gitignore b/.gitignore
index acdb5e230..dd4d057ef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,8 @@
/tmp
*~
public/assets/
+public/javascripts/i18n.js
+public/javascripts/translations.js
# for vim users
*.swp
diff --git a/Gemfile b/Gemfile
index bb1a42df0..db5202bdf 100644
--- a/Gemfile
+++ b/Gemfile
@@ -103,6 +103,7 @@ gem 'will_paginate-bootstrap'
gem 'gretel'
gem 'country_select'
gem 'flag-icons-rails'
+gem 'i18n-js'
# Format Output
gem 'json'
diff --git a/Gemfile.lock b/Gemfile.lock
index 805ee460d..a6f54f9cb 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -271,6 +271,8 @@ GEM
multi_xml (>= 0.5.2)
i18n (0.9.3)
concurrent-ruby (~> 1.0)
+ i18n-js (3.0.4)
+ i18n (~> 0.6, >= 0.6.6)
i18n-tasks (0.9.15)
activesupport (>= 4.0.2)
ast (>= 2.1.0)
@@ -638,6 +640,7 @@ DEPENDENCIES
gretel
has_array_of!
htmlbeautifier
+ i18n-js
i18n-tasks
inherited_resources
jbuilder (~> 2.0)
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 4c5aff22f..6a79f7e8e 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -22,3 +22,6 @@
//= require_directory .
// require('whatwg-fetch')
// require('babel-polyfill')
+//= require "i18n"
+//= require "i18n/extended"
+//= require "i18n/translations"
diff --git a/app/assets/javascripts/i18n/extended.coffee b/app/assets/javascripts/i18n/extended.coffee
new file mode 100644
index 000000000..aeb67bd09
--- /dev/null
+++ b/app/assets/javascripts/i18n/extended.coffee
@@ -0,0 +1,24 @@
+#= require i18n
+
+decorateI18n = (_i18n)->
+ _i18n.tc = (key, opts={}) ->
+ out = _i18n.t(key, opts)
+ out += " " if _i18n.locale == "fr"
+ out + ":"
+
+ _i18n.model_name = (model, opts={}) ->
+ last_key = if opts.plural then "other" else "one"
+ _i18n.t("activerecord.models.#{model}.#{last_key}")
+
+ _i18n.attribute_name = (model, attribute, opts={}) ->
+ _i18n.t("activerecord.attributes.#{model}.#{attribute}")
+
+ _i18n.enumerize = (enumerize, key, opts={}) ->
+ I18n.t("enumerize.#{enumerize}.#{key}")
+
+ _i18n
+
+module?.exports = decorateI18n
+
+if I18n?
+ decorateI18n(I18n)
diff --git a/app/assets/stylesheets/components/_tables.sass b/app/assets/stylesheets/components/_tables.sass
index 35e1122f3..5f8b06f09 100644
--- a/app/assets/stylesheets/components/_tables.sass
+++ b/app/assets/stylesheets/components/_tables.sass
@@ -9,7 +9,6 @@
font-weight: 700
border-bottom: 2px solid $darkgrey
vertical-align: middle
-
> a
position: relative
display: block
@@ -326,6 +325,8 @@
padding: 6px 8px
border-bottom: 2px solid rgba($grey, 0.5)
border-top: 1px solid rgba($grey, 0.5)
+ text-transform: capitalize
+
.td
position: relative
padding: 6px 8px
diff --git a/app/javascript/vehicle_journeys/components/ConfirmModal.js b/app/javascript/vehicle_journeys/components/ConfirmModal.js
index 3bfc852fb..75e8a3932 100644
--- a/app/javascript/vehicle_journeys/components/ConfirmModal.js
+++ b/app/javascript/vehicle_journeys/components/ConfirmModal.js
@@ -7,7 +7,7 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan
-
Voulez-vous valider vos modifications avant de changer de page?
+
{I18n.t('vehicle_journeys.vehicle_journeys_matrix.modal_confirm')}
)
-}
+}
ConfirmModal.propTypes = {
vehicleJourneys: PropTypes.array.isRequired,
modal: PropTypes.object.isRequired,
onModalAccept: PropTypes.func.isRequired,
onModalCancel: PropTypes.func.isRequired
-}
\ No newline at end of file
+}
diff --git a/app/javascript/vehicle_journeys/components/Filters.js b/app/javascript/vehicle_journeys/components/Filters.js
index 2bd912e3e..f8697c930 100644
--- a/app/javascript/vehicle_journeys/components/Filters.js
+++ b/app/javascript/vehicle_journeys/components/Filters.js
@@ -46,10 +46,10 @@ export default function Filters({filters, pagination, missions, onFilter, onRese
{/* Plage horaire */}
-
Plage horaire au départ de la course
+
{I18n.t("vehicle_journeys.form.departure_range.label")}
-
Début
+
{I18n.t("vehicle_journeys.form.departure_range.start")}
-
Fin
+
{I18n.t("vehicle_journeys.form.departure_range.end")}
-
Afficher les courses sans horaires
+
{I18n.t("vehicle_journeys.form.show_journeys_without_schedule")}
@@ -110,8 +110,8 @@ export default function Filters({filters, pagination, missions, onFilter, onRese
onChange={onToggleWithoutSchedule}
checked={filters.query.withoutSchedule}
>
-
- {filters.query.withoutSchedule ? 'Oui' : 'Non'}
+
+ {filters.query.withoutSchedule ? I18n.t("yes") : I18n.t("no")}
@@ -122,7 +122,7 @@ export default function Filters({filters, pagination, missions, onFilter, onRese
{/* Switch avec/sans calendrier */}
-
Afficher les courses avec calendrier
+
{I18n.t("vehicle_journeys.form.show_journeys_with_calendar")}
@@ -131,8 +131,8 @@ export default function Filters({filters, pagination, missions, onFilter, onRese
onChange={onToggleWithoutTimeTable}
checked={filters.query.withoutTimeTable}
>
-
- {filters.query.withoutTimeTable ? 'Oui' : 'Non'}
+
+ {filters.query.withoutTimeTable ? I18n.t("yes") : I18n.t("no")}
diff --git a/app/javascript/vehicle_journeys/components/VehicleJourney.js b/app/javascript/vehicle_journeys/components/VehicleJourney.js
index 99a458f50..4a9432231 100644
--- a/app/javascript/vehicle_journeys/components/VehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/VehicleJourney.js
@@ -23,7 +23,7 @@ export default class VehicleJourney extends Component {
let ttURL = refURL + '/time_tables/' + tt.id
return (
-
+
)
}
@@ -32,7 +32,7 @@ export default class VehicleJourney extends Component {
let ttURL = refURL + '/purchase_windows/' + tt.id
return (
-
+
)
}
@@ -65,7 +65,7 @@ export default class VehicleJourney extends Component {
}
>
{this.props.value.short_id || '-'}
-
{this.props.value.published_journey_name && this.props.value.published_journey_name != "non renseigné" ? this.props.value.published_journey_name : '-'}
+
{this.props.value.published_journey_name && this.props.value.published_journey_name != I18n.t('undefined') ? this.props.value.published_journey_name : '-'}
{this.props.value.journey_pattern.short_id || '-'}
{this.props.value.company ? this.props.value.company.name : '-'}
@@ -100,7 +100,7 @@ export default class VehicleJourney extends Component {
{this.props.filters.toggleArrivals &&
-
+
}
-
+
{(this.props.status.fetchSuccess == false) && (
- Erreur :
- la récupération des missions a rencontré un problème. Rechargez la page pour tenter de corriger le problème.
+ {I18n.tc("error")}
+ {I18n.t("vehicle_journeys.vehicle_journeys_matrix.fetching_error")}
)}
{ this.vehicleJourneysList().errors && this.vehicleJourneysList().errors.length && _.some(this.vehicleJourneysList(), 'errors') && (
-
Erreur :
+
{I18n.tc("error")}
{this.vehicleJourneysList().map((vj, index) =>
vj.errors && vj.errors.map((err, i) => {
return (
@@ -129,12 +129,12 @@ export default class VehicleJourneys extends Component {
0) ? '' : ' no_result')}>
-
ID course
-
Nom course
-
ID mission
-
Transporteur
-
Calendriers
- { this.hasFeature('purchase_windows') &&
Calendriers Commerciaux
}
+
{I18n.attribute_name("vehicle_journey", "id")}
+
{I18n.attribute_name("vehicle_journey", "name")}
+
{I18n.attribute_name("vehicle_journey", "journey_pattern_id")}
+
{I18n.model_name("company")}
+
{I18n.model_name("time_table", "plural": true)}
+ { this.hasFeature('purchase_windows') &&
{I18n.model_name("purchase_window", "plural": true)}
}
{this.stopPoints().map((sp, i) =>{
return (
diff --git a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js
index f6a0e3c61..bcfd4eb41 100644
--- a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js
@@ -128,7 +128,7 @@ export default class EditVehicleJourney extends Component {
diff --git a/app/views/calendars/_form_advanced.html.slim b/app/views/calendars/_form_advanced.html.slim
index b4154166b..e796e2e36 100644
--- a/app/views/calendars/_form_advanced.html.slim
+++ b/app/views/calendars/_form_advanced.html.slim
@@ -2,7 +2,7 @@
= javascript_tag do
| window.actionType = "#{raw params[:action]}";
- | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe};
+ // | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe};
| window.timetablesUrl = "#{calendar_url(@calendar).html_safe}";
= javascript_pack_tag 'calendars/edit.js'
diff --git a/app/views/layouts/application.html.slim b/app/views/layouts/application.html.slim
index 34b373295..3921c8701 100644
--- a/app/views/layouts/application.html.slim
+++ b/app/views/layouts/application.html.slim
@@ -13,6 +13,8 @@ html lang=I18n.locale
= javascript_pack_tag 'application'
= javascript_include_tag 'application'
+ = javascript_tag do
+ | I18n.locale = '#{I18n.locale}'
body
= render 'layouts/navigation/main_nav'
diff --git a/app/views/routes/_form.html.slim b/app/views/routes/_form.html.slim
index 29e5be3d2..81f719437 100644
--- a/app/views/routes/_form.html.slim
+++ b/app/views/routes/_form.html.slim
@@ -27,7 +27,7 @@
// Get JSON data for route stop points
= javascript_tag do
| window.itinerary_stop = "#{URI.escape(route_json_for_edit(@route))}";
- | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe};
+ // | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe};
/ StopPoints Reactux component
= javascript_pack_tag 'routes/edit.js'
diff --git a/app/views/time_tables/edit.html.slim b/app/views/time_tables/edit.html.slim
index e1c566ff4..d8cffb1b0 100644
--- a/app/views/time_tables/edit.html.slim
+++ b/app/views/time_tables/edit.html.slim
@@ -8,6 +8,6 @@
= javascript_tag do
| window.actionType = "#{raw params[:action]}";
- | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe};
+ // | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe};
= javascript_pack_tag 'time_tables/edit.js'
diff --git a/app/views/time_tables/index.html.slim b/app/views/time_tables/index.html.slim
index f58fbb5ea..6913712a0 100644
--- a/app/views/time_tables/index.html.slim
+++ b/app/views/time_tables/index.html.slim
@@ -61,6 +61,6 @@
= replacement_msg t('time_tables.search_no_results')
= javascript_tag do
- | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe};
+ // | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe};
= javascript_pack_tag 'date_filters'
diff --git a/app/views/vehicle_journeys/index.html.slim b/app/views/vehicle_journeys/index.html.slim
index caa8450a0..d53d8b50c 100644
--- a/app/views/vehicle_journeys/index.html.slim
+++ b/app/views/vehicle_journeys/index.html.slim
@@ -29,7 +29,7 @@
| window.features = #{raw @features};
| window.all_missions = #{(@all_missions.to_json).html_safe};
| window.custom_fields = #{(@custom_fields.to_json).html_safe};
- | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe};
+ // | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe};
- if has_feature?(:vehicle_journeys_return_route)
= javascript_tag do
diff --git a/app/views/workbenches/show.html.slim b/app/views/workbenches/show.html.slim
index a162ca334..aae34c51b 100644
--- a/app/views/workbenches/show.html.slim
+++ b/app/views/workbenches/show.html.slim
@@ -72,6 +72,6 @@
= replacement_msg t('referentials.search_no_results')
= javascript_tag do
- | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe};
+ // | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe};
= javascript_pack_tag 'date_filters'
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 1d2fee44f..446e72190 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -95,6 +95,7 @@ Rails.application.configure do
config.i18n.available_locales = [:fr, :en]
config.middleware.insert_after(ActionDispatch::Static, Rack::LiveReload) if ENV['LIVERELOAD']
+ config.middleware.use I18n::JS::Middleware
config.development_toolbar = false
if ENV['TOOLBAR'] && File.exists?("config/development_toolbar.rb")
config.development_toolbar = OpenStruct.new
diff --git a/config/locales/en.yml b/config/locales/en.yml
index e59960f95..d78d51dbe 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -3,6 +3,7 @@ en:
"false": "No"
"unknown": "Unknown"
+
time:
formats:
hour: "%Hh%M"
@@ -61,3 +62,7 @@ en:
reflex_data: 'Reflex datas'
objectid: 'ID'
brandname: IBOO
+ error: "Error"
+ undefined: 'undefined'
+ yes: yes
+ no: no
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 175b71ebc..d89c286af 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -61,3 +61,7 @@ fr:
reflex_data: 'Données Reflex'
objectid: 'ID'
brandname: IBOO
+ error: "Erreur"
+ undefined: 'non renseigné'
+ yes: oui
+ no: non
diff --git a/config/locales/vehicle_journeys.en.yml b/config/locales/vehicle_journeys.en.yml
index abb1da530..a1f20a7e8 100644
--- a/config/locales/vehicle_journeys.en.yml
+++ b/config/locales/vehicle_journeys.en.yml
@@ -2,6 +2,10 @@ en:
vehicle_journeys:
vehicle_journeys_matrix:
line_routes: "Line's routes"
+ fetching_error: "There has been a problem fetching the data. Please reload the page to try again."
+ show_timetable: 'Show calendar'
+ show_purchase_window: 'Show the purchase window'
+ modal_confirm: 'Do you want to save mofications before moving on to the next page ?'
vehicle_journey:
title_stopless: "Vehicle journey %{name}"
title: "Vehicle journey leaving from %{stop} at %{time}"
@@ -28,6 +32,8 @@ en:
stop_title: "Stop"
departure: "Departure"
arrival: "Arrival"
+ departure_at: "Departure at"
+ arrival_at: "Arrival at"
to_arrivals: "Copy departures to arrivals"
to_departures: "Copy arrivals to departures"
time_tables: "Associated calendars to vehicle journey"
@@ -35,6 +41,12 @@ en:
slide_title: "Shift all vehicle passing times"
set: "Set"
to: "at"
+ departure_range:
+ label: Journey departure range
+ start: Start
+ end: End
+ show_journeys_without_schedule: "Show journeys without schedule"
+ show_journeys_with_calendar: "Show journeys with calendar"
slide_departure: "departure time at first stop"
slide_arrival: "arrival time at first stop"
submit_timed: "Create vehicle journey"
@@ -81,6 +93,7 @@ en:
line: "Line"
route: "Route"
journey_pattern: "Journey Pattern"
+ journey_pattern_id: "Pattern ID"
time_tables: "Calendars"
time_slot: "Time Slot"
company: "Company"
@@ -112,6 +125,8 @@ en:
departure_time: "Departure"
arrival_time: "Arrival"
purchase_window: "Purchase availability"
+ name: "Journey Name"
+ id: "Journey ID"
errors:
models:
vehicle_journey:
diff --git a/config/locales/vehicle_journeys.fr.yml b/config/locales/vehicle_journeys.fr.yml
index ca8475812..be5be2382 100644
--- a/config/locales/vehicle_journeys.fr.yml
+++ b/config/locales/vehicle_journeys.fr.yml
@@ -2,6 +2,10 @@ fr:
vehicle_journeys:
vehicle_journeys_matrix:
line_routes: "Séquences d'arrêts de la ligne"
+ fetching_error: "La récupération des missions a rencontré un problème. Rechargez la page pour tenter de corriger le problème."
+ show_timetable: 'Voir le calendrier'
+ show_purchase_window: 'Voir le calendrier commercial'
+ modal_confirm: 'Voulez-vous valider vos modifications avant de changer de page?'
vehicle_journey:
title_stopless: "Course %{name}"
title: "Course partant de %{stop} à %{time}"
@@ -27,7 +31,10 @@ fr:
form:
stop_title: "Arrêt"
departure: "Départ"
+ departure_at: "Départ à"
arrival: "Arrivée"
+ arrival_at: "Arrivée à"
+ to_arrivals: "Copie départs vers arrivées"
to_arrivals: "Copie départs vers arrivées"
to_departures: "Copie arrivées vers départs"
time_tables: "Calendriers associés à la course"
@@ -35,6 +42,12 @@ fr:
slide_title: "Décaler l'ensemble des horaires de course"
set: "Fixer"
to: "à"
+ departure_range:
+ label: Plage horaire au départ de la course
+ start: Début
+ end: Fin
+ show_journeys_without_schedule: "Afficher les courses sans horaires"
+ show_journeys_with_calendar: "Afficher les courses avec calendrier"
slide_departure: "horaire de départ au 1° arrêt à"
slide_arrival: "horaire d'arrivée au 1° arrêt à"
submit_timed: "Créer course"
@@ -81,6 +94,7 @@ fr:
line: "Ligne"
route: "Séquence d'arrêt"
journey_pattern: "Mission"
+ journey_pattern_id: "ID Mission"
time_tables: "Calendriers"
time_slot: "Fréquence"
company: "Transporteur"
@@ -112,6 +126,8 @@ fr:
departure_time: "Départ"
arrival_time: "Arrivée"
purchase_window: "Disponibilité commerciale"
+ name: "Nom Course"
+ id: "ID Course"
errors:
models:
vehicle_journey:
diff --git a/lib/tasks/ci.rake b/lib/tasks/ci.rake
index 13d7b8d73..889a5c0ad 100644
--- a/lib/tasks/ci.rake
+++ b/lib/tasks/ci.rake
@@ -38,7 +38,7 @@ namespace :ci do
end
task :jest => "ci:assets" do
- sh "yarn --no-progress install" # Hack to force install jest after webpack
+ sh "yarn --no-progress install" # Hack to force install jest after webpack
sh "node_modules/.bin/jest" unless ["CHOUETTE_JEST_DISABLED"]
end
@@ -59,4 +59,4 @@ namespace :ci do
end
desc "Run continuous integration tasks (spec, ...)"
-task :ci => ["ci:setup", "ci:spec", "ci:jest", "cucumber", "ci:check_security", "ci:deploy", "ci:clean"]
+task :ci => ["ci:setup", "ci:spec", "i18n:js:export", "ci:jest", "cucumber", "ci:check_security", "ci:deploy", "ci:clean"]
diff --git a/package.json b/package.json
index e80f5231e..25b158e3d 100644
--- a/package.json
+++ b/package.json
@@ -49,6 +49,10 @@
"roots": [
"
/spec/javascript"
],
+ "transform": {
+ "^.+\\.coffee$": "/spec/javascript/preprocessor.js",
+ "^.+\\.jsx?$": "babel-jest"
+ },
"testEnvironment": "jest-environment-jsdom-global",
"setupFiles": [
"/spec/javascript/spec_helper.js",
diff --git a/spec/javascript/preprocessor.js b/spec/javascript/preprocessor.js
new file mode 100644
index 000000000..a2de8e4be
--- /dev/null
+++ b/spec/javascript/preprocessor.js
@@ -0,0 +1,15 @@
+'use strict';
+
+var coffee = require('coffeescript');
+
+module.exports = {
+ process: function(src, filename) {
+ if (coffee.helpers.isCoffee(filename)) {
+ return coffee.compile(src, {
+ 'bare': false,
+ 'inlineMap': true
+ })
+ }
+ return src;
+ }
+};
diff --git a/spec/javascript/vehicle_journeys/components/VehicleJourneys_spec.js b/spec/javascript/vehicle_journeys/components/VehicleJourneys_spec.js
index 87151c64b..2a84cb9ca 100644
--- a/spec/javascript/vehicle_journeys/components/VehicleJourneys_spec.js
+++ b/spec/javascript/vehicle_journeys/components/VehicleJourneys_spec.js
@@ -1,6 +1,13 @@
import React, { Component } from 'react'
import VehicleJourneys from '../../../../app/javascript/vehicle_journeys/components/VehicleJourneys'
import renderer from 'react-test-renderer'
+import fs from 'fs'
+
+import I18n from '../../../../public/javascripts/i18n'
+import decorateI18n from '../../../../app/assets/javascripts/i18n/extended.coffee'
+window.I18n = decorateI18n(I18n)
+I18n.locale = "fr"
+eval(fs.readFileSync('./public/javascripts/translations.js')+'')
describe('stopPointHeader', () => {
set('features', () => {
diff --git a/spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap b/spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap
index 703f727d7..cdd34cbbd 100644
--- a/spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap
+++ b/spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap
@@ -19,19 +19,19 @@ exports[`stopPointHeader should display the city name 1`] = `
- ID course
+ ID Course
- Nom course
+ Nom Course
- ID mission
+ ID Mission
- Transporteur
+ transporteur
- Calendriers
+ calendrier
- ID course
+ ID Course
- Nom course
+ Nom Course
- ID mission
+ ID Mission
- Transporteur
+ transporteur
- Calendriers
+ calendrier
- Liste des horaires {minVJ} à {maxVJ} sur {pagination.totalCount}
-
+ {I18n.t("vehicle_journeys.vehicle_journeys_matrix.pagination", {minVJ, maxVJ, total:pagination.totalCount})}