aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/controllers/referential_vehicle_journeys_controller.rb17
-rw-r--r--app/decorators/referential_decorator.rb25
-rw-r--r--app/models/chouette/vehicle_journey_at_stop.rb11
-rw-r--r--app/views/referential_vehicle_journeys/_filters.html.slim11
-rw-r--r--app/views/referential_vehicle_journeys/index.html.slim58
-rw-r--r--config/breadcrumbs.rb5
-rw-r--r--config/locales/vehicle_journeys.en.yml8
-rw-r--r--config/locales/vehicle_journeys.fr.yml8
-rw-r--r--config/routes.rb2
-rw-r--r--spec/controllers/referential_vehicle_journeys_controller_spec.rb43
10 files changed, 182 insertions, 6 deletions
diff --git a/app/controllers/referential_vehicle_journeys_controller.rb b/app/controllers/referential_vehicle_journeys_controller.rb
new file mode 100644
index 000000000..ad08699a5
--- /dev/null
+++ b/app/controllers/referential_vehicle_journeys_controller.rb
@@ -0,0 +1,17 @@
+#
+# Browse all VehicleJourneys of the Referential
+#
+class ReferentialVehicleJourneysController < ChouetteController
+ include ReferentialSupport
+ defaults :resource_class => Chouette::VehicleJourney, collection_name: :vehicle_journeys
+
+ requires_feature :referential_vehicle_journeys
+
+ private
+
+ def collection
+ @q ||= end_of_association_chain.ransack(params[:q])
+ @vehicle_journeys ||= @q.result.includes(:vehicle_journey_at_stops).paginate page: params[:page], per_page: 10
+ end
+
+end
diff --git a/app/decorators/referential_decorator.rb b/app/decorators/referential_decorator.rb
index 4103790aa..9ebb6f330 100644
--- a/app/decorators/referential_decorator.rb
+++ b/app/decorators/referential_decorator.rb
@@ -3,12 +3,19 @@ class ReferentialDecorator < Draper::Decorator
def action_links
policy = h.policy(object)
- links = [
- Link.new(
- content: h.t('time_tables.index.title'),
- href: h.referential_time_tables_path(object)
+ links = []
+
+ if has_feature?(:referential_vehicle_journeys)
+ links << Link.new(
+ content: h.t('referential_vehicle_journeys.index.title'),
+ href: h.referential_vehicle_journeys_path(object)
)
- ]
+ end
+
+ links << Link.new(
+ content: h.t('time_tables.index.title'),
+ href: h.referential_time_tables_path(object)
+ )
if policy.clone?
links << Link.new(
@@ -63,4 +70,12 @@ class ReferentialDecorator < Draper::Decorator
links
end
+
+ private
+
+ # TODO move to a base Decorator (ApplicationDecorator)
+ def has_feature?(*feature)
+ h.has_feature?(*features) rescue false
+ end
+
end
diff --git a/app/models/chouette/vehicle_journey_at_stop.rb b/app/models/chouette/vehicle_journey_at_stop.rb
index 6f0119e74..6b3c1e7de 100644
--- a/app/models/chouette/vehicle_journey_at_stop.rb
+++ b/app/models/chouette/vehicle_journey_at_stop.rb
@@ -75,5 +75,14 @@ module Chouette
attrs << self.arrival_day_offset.to_s
end
end
+
+ def departure
+ departure_time.utc.strftime "%H:%M" if departure_time
+ end
+
+ def arrival
+ arrival_time.utc.strftime "%H:%M" if arrival_time
+ end
+
end
-end \ No newline at end of file
+end
diff --git a/app/views/referential_vehicle_journeys/_filters.html.slim b/app/views/referential_vehicle_journeys/_filters.html.slim
new file mode 100644
index 000000000..963da8cea
--- /dev/null
+++ b/app/views/referential_vehicle_journeys/_filters.html.slim
@@ -0,0 +1,11 @@
+= search_form_for @q, url: referential_vehicle_journeys_path(@referential), html: {method: :get}, class: 'form form-filter' do |f|
+ .ffg-row
+ .input-group.search_bar
+ = f.search_field :published_journey_name_or_objectid_cont, placeholder: t('.published_journey_name_or_objectid'), class: 'form-control'
+ span.input-group-btn
+ button.btn.btn-default#search-btn type='submit'
+ span.fa.fa-search
+
+ .actions
+ = link_to 'Effacer', referential_vehicle_journeys_path(@referential), class: 'btn btn-link'
+ = f.submit 'Filtrer', class: 'btn btn-default'
diff --git a/app/views/referential_vehicle_journeys/index.html.slim b/app/views/referential_vehicle_journeys/index.html.slim
new file mode 100644
index 000000000..394f4a3f7
--- /dev/null
+++ b/app/views/referential_vehicle_journeys/index.html.slim
@@ -0,0 +1,58 @@
+- breadcrumb :referential_vehicle_journeys, @referential
+- content_for :page_header_title, t('.title')
+
+.page_content
+ .container-fluid
+ - if params[:q].present? or @vehicle_journeys.present?
+ .row
+ .col-lg-12
+ = render 'filters'
+
+ - if @vehicle_journeys.present?
+ .row
+ .col-lg-12
+ .select_table
+ = table_builder_2 @vehicle_journeys,
+ [ \
+ TableBuilderHelper::Column.new( \
+ name: t('objectid'), \
+ attribute: Proc.new { |n| n.get_objectid.short_id }, \
+ sortable: false \
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :published_journey_name, \
+ attribute: 'published_journey_name', \
+ link_to: lambda do |vehicle_journey| \
+ referential_line_route_vehicle_journeys_path(@referential, vehicle_journey.route.line, vehicle_journey.route) \
+ end, \
+ sortable: false \
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :line, \
+ attribute: Proc.new {|v| v.route.line.name}, \
+ sortable: false \
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :route, \
+ attribute: Proc.new {|v| v.route.name}, \
+ sortable: false \
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :departure_time, \
+ attribute: Proc.new {|v| v.vehicle_journey_at_stops.first&.departure }, \
+ sortable: false \
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :arrival_time, \
+ attribute: Proc.new {|v| v.vehicle_journey_at_stops.last&.arrival }, \
+ sortable: false \
+ ), \
+ ],
+ cls: 'table has-filter has-search'
+
+ = new_pagination @vehicle_journeys, 'pull-right'
+
+ - unless @vehicle_journeys.any?
+ .row.mt-xs
+ .col-lg-12
+ = replacement_msg t('.search_no_results')
diff --git a/config/breadcrumbs.rb b/config/breadcrumbs.rb
index eb285b731..9a748cb21 100644
--- a/config/breadcrumbs.rb
+++ b/config/breadcrumbs.rb
@@ -41,6 +41,11 @@ crumb :referential_group_of_line do |referential, group_of_line|
parent :referential_group_of_lines, referential
end
+crumb :referential_vehicle_journeys do |referential|
+ link I18n.t('referential_vehicle_journeys.index.title'), referential_vehicle_journeys_path(referential)
+ parent :referential, referential
+end
+
crumb :time_tables do |referential|
link I18n.t('time_tables.index.title'), referential_time_tables_path(referential)
parent :referential, referential
diff --git a/config/locales/vehicle_journeys.en.yml b/config/locales/vehicle_journeys.en.yml
index 7f3871fbf..1c1f6c6bd 100644
--- a/config/locales/vehicle_journeys.en.yml
+++ b/config/locales/vehicle_journeys.en.yml
@@ -106,6 +106,8 @@ en:
updated_at: Updated at
creator_id: "Created by"
footnote_ids: "Footnotes"
+ departure_time: "Departure"
+ arrival_time: "Arrival"
errors:
models:
vehicle_journey:
@@ -126,3 +128,9 @@ en:
hub:
vehicle_journey:
objectid: "[prefix]:VehicleJourney:[unique_key] : prefix contains only alphanumerical or underscore characters, unique_key accepts also minus character. Maximum length of the unique key = 8."
+ referential_vehicle_journeys:
+ index:
+ title: "Vehicle Journeys"
+ search_no_results: "No vehicle journey match your search"
+ filters:
+ published_journey_name_or_objectid: "Search by name or by ID..."
diff --git a/config/locales/vehicle_journeys.fr.yml b/config/locales/vehicle_journeys.fr.yml
index ed4b1c30a..5749f8f10 100644
--- a/config/locales/vehicle_journeys.fr.yml
+++ b/config/locales/vehicle_journeys.fr.yml
@@ -106,6 +106,8 @@ fr:
updated_at: "Edité le"
creator_id: "Créé par"
footnote_ids: "Notes de bas de page"
+ departure_time: "Départ"
+ arrival_time: "Arrivée"
errors:
models:
vehicle_journey:
@@ -126,3 +128,9 @@ fr:
hub:
vehicle_journey:
objectid: "[prefixe]:VehicleJourney:[clé_unique] caractères autorisés : alphanumériques et 'souligné' pour le préfixe, la clé unique accepte en plus le 'moins'. Longueur maximale de la clé unique = 8."
+ referential_vehicle_journeys:
+ index:
+ title: "Courses"
+ search_no_results: "Aucune course ne correspond à votre recherche"
+ filters:
+ published_journey_name_or_objectid: "Indiquez le nom ou l'ID..."
diff --git a/config/routes.rb b/config/routes.rb
index 65fa62557..6668aa402 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -156,6 +156,8 @@ ChouetteIhm::Application.routes.draw do
resources :routing_constraint_zones
end
+ resources :vehicle_journeys, controller: 'referential_vehicle_journeys', only: [:index]
+
resources :import_tasks, :only => [:new, :create]
resources :export_tasks, :only => [:new, :create] do
collection do
diff --git a/spec/controllers/referential_vehicle_journeys_controller_spec.rb b/spec/controllers/referential_vehicle_journeys_controller_spec.rb
new file mode 100644
index 000000000..842a6665e
--- /dev/null
+++ b/spec/controllers/referential_vehicle_journeys_controller_spec.rb
@@ -0,0 +1,43 @@
+require "rails_helper"
+
+RSpec.describe ReferentialVehicleJourneysController, type: :controller do
+ login_user
+
+ before do
+ @user.organisation.update features: %w{referential_vehicle_journeys}
+ end
+
+ describe 'GET #index' do
+ it 'should be successful' do
+ get :index, referential_id: referential
+ expect(response).to be_success
+ end
+
+ it "refuse access when organisation does not have the feature 'referential_vehicle_journeys'" do
+ @user.organisation.update features: []
+
+ expect do
+ get :index, referential_id: referential
+ end.to raise_error(FeatureChecker::NotAuthorizedError)
+ end
+
+ it 'define Ransack search (alias @q)' do
+ get :index, referential_id: referential
+ expect(assigns[:q]).to be_an_instance_of(Ransack::Search)
+ end
+
+ it 'define @vehicle_journeys collection' do
+ vehicle_journey = FactoryGirl.create :vehicle_journey
+ get :index, referential_id: referential
+ expect(assigns[:vehicle_journeys]).to include(vehicle_journey)
+ end
+
+ it 'paginage @vehicle_journeys collection' do
+ FactoryGirl.create :vehicle_journey
+
+ get :index, referential_id: referential
+ expect(assigns[:vehicle_journeys].total_entries).to be(1)
+ end
+ end
+
+end