aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/images/favicon.icobin1406 -> 5430 bytes
-rw-r--r--app/assets/javascripts/modal_confirmation.js31
-rw-r--r--app/assets/stylesheets/application.sass3
-rw-r--r--app/assets/stylesheets/components/_forms.sass8
-rw-r--r--app/assets/stylesheets/modules/_vj_collection.sass94
-rw-r--r--app/controllers/companies_controller.rb4
-rw-r--r--app/controllers/compliance_check_messages_controller.rb6
-rw-r--r--app/controllers/import_messages_controller.rb2
-rw-r--r--app/controllers/import_resources_controller.rb9
-rw-r--r--app/controllers/imports_controller.rb9
-rw-r--r--app/controllers/referential_vehicle_journeys_controller.rb4
-rw-r--r--app/controllers/stop_areas_controller.rb21
-rw-r--r--app/controllers/workbenches_controller.rb2
-rw-r--r--app/controllers/workgroups_controller.rb13
-rw-r--r--app/decorators/compliance_control_decorator.rb4
-rw-r--r--app/decorators/compliance_control_set_decorator.rb2
-rw-r--r--app/decorators/line_decorator.rb6
-rw-r--r--app/decorators/network_decorator.rb4
-rw-r--r--app/decorators/purchase_window_decorator.rb2
-rw-r--r--app/decorators/referential_line_decorator.rb6
-rw-r--r--app/decorators/referential_network_decorator.rb4
-rw-r--r--app/decorators/route_decorator.rb12
-rw-r--r--app/decorators/routing_constraint_zone_decorator.rb2
-rw-r--r--app/decorators/stop_area_decorator.rb14
-rw-r--r--app/decorators/stop_area_referential_decorator.rb4
-rw-r--r--app/decorators/stop_point_decorator.rb4
-rw-r--r--app/helpers/exports_helper.rb2
-rw-r--r--app/helpers/imports_helper.rb26
-rw-r--r--app/helpers/menus_helper.rb20
-rw-r--r--app/helpers/stop_areas_helper.rb21
-rw-r--r--app/helpers/table_builder_helper.rb26
-rw-r--r--app/helpers/vehicle_journeys_helper.rb12
-rw-r--r--app/javascript/helpers/polyfills.js1
-rw-r--r--app/javascript/vehicle_journeys/actions/index.js10
-rw-r--r--app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js3
-rw-r--r--app/javascript/vehicle_journeys/reducers/vehicleJourneys.js4
-rw-r--r--app/models/chouette/route.rb3
-rw-r--r--app/models/chouette/stop_area.rb30
-rw-r--r--app/models/clean_up.rb25
-rw-r--r--app/models/compliance_check_set.rb9
-rw-r--r--app/models/concerns/checksum_support.rb7
-rw-r--r--app/models/concerns/custom_fields_support.rb2
-rw-r--r--app/models/concerns/iev_interfaces/resource.rb20
-rw-r--r--app/models/concerns/iev_interfaces/task.rb26
-rw-r--r--app/models/import/base.rb9
-rw-r--r--app/models/import/gtfs.rb46
-rw-r--r--app/models/import/netex.rb61
-rw-r--r--app/models/import/resource.rb44
-rw-r--r--app/models/import/workbench.rb10
-rw-r--r--app/models/merge.rb25
-rw-r--r--app/models/referential.rb3
-rw-r--r--app/models/simple_importer.rb16
-rw-r--r--app/models/simple_interface.rb7
-rw-r--r--app/models/simple_interfaces_group.rb4
-rw-r--r--app/models/workbench.rb14
-rw-r--r--app/models/workgroup.rb34
-rw-r--r--app/policies/workbench_policy.rb2
-rw-r--r--app/policies/workgroup_policy.rb19
-rw-r--r--app/services/referential_consolidated.rb124
-rw-r--r--app/services/route_way_cost_calculator.rb2
-rw-r--r--app/views/companies/show.html.slim2
-rw-r--r--app/views/compliance_check_sets/show.html.slim1
-rw-r--r--app/views/compliance_control_sets/show.html.slim5
-rw-r--r--app/views/dashboards/_dashboard.html.slim18
-rw-r--r--app/views/devise/invitations/edit.html.slim5
-rw-r--r--app/views/devise/invitations/new.html.slim19
-rw-r--r--app/views/import_resources/show.html.slim52
-rw-r--r--app/views/imports/import/_gtf.html.slim43
-rw-r--r--app/views/imports/import/_netex.html.slim45
-rw-r--r--app/views/imports/import/_workbench.html.slim55
-rw-r--r--app/views/imports/show.html.slim57
-rw-r--r--app/views/layouts/navigation/_main_nav_left_content.html.slim97
-rw-r--r--app/views/layouts/navigation/_main_nav_left_content_stif.html.slim149
-rw-r--r--app/views/lines/_form.html.slim2
-rw-r--r--app/views/referential_stop_areas/show.html.slim2
-rw-r--r--app/views/referential_vehicle_journeys/_consolidated.html.slim49
-rw-r--r--app/views/referential_vehicle_journeys/_consolidated_line.html.slim119
-rw-r--r--app/views/referential_vehicle_journeys/_filters.html.slim14
-rw-r--r--app/views/referential_vehicle_journeys/_list.html.slim49
-rw-r--r--app/views/referential_vehicle_journeys/index.html.slim52
-rw-r--r--app/views/referentials/_filters.html.slim4
-rw-r--r--app/views/routes/show.html.slim4
-rw-r--r--app/views/routing_constraint_zones/index.html.slim4
-rw-r--r--app/views/routing_constraint_zones/show.html.slim6
-rw-r--r--app/views/stop_areas/_filters.html.slim34
-rw-r--r--app/views/stop_areas/index.html.slim2
-rw-r--r--app/views/stop_areas/show.html.slim2
-rw-r--r--app/views/workbenches/_form.html.slim11
-rw-r--r--app/views/workbenches/edit.html.slim2
-rw-r--r--app/views/workgroups/_form.html.slim17
-rw-r--r--app/views/workgroups/edit.html.slim8
-rw-r--r--app/workers/compliance_control_set_copy_worker.rb3
-rw-r--r--app/workers/route_way_cost_worker.rb6
-rw-r--r--app/workers/workbench_import_worker/object_state_updater.rb17
94 files changed, 1437 insertions, 455 deletions
diff --git a/app/assets/images/favicon.ico b/app/assets/images/favicon.ico
index ac6bc298d..7029bd04e 100644
--- a/app/assets/images/favicon.ico
+++ b/app/assets/images/favicon.ico
Binary files differ
diff --git a/app/assets/javascripts/modal_confirmation.js b/app/assets/javascripts/modal_confirmation.js
new file mode 100644
index 000000000..e82a8a81b
--- /dev/null
+++ b/app/assets/javascripts/modal_confirmation.js
@@ -0,0 +1,31 @@
+$(document).ready(() => {
+ $.rails.allowAction = (link) => {
+ let message = link.data('confirm')
+ if (!message) return true
+ showConfirmModal(link)
+ return false
+ }
+
+ let showConfirmModal = (link) => {
+ let message = link.data('confirm')
+ let html = `<div class="modal fade" id="confirmationDialog" tabindex="1" role="dialog">
+ <div class="modal-container">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h4 class="modal-title"> ${I18n.t('warning')} </h4>
+ </div>
+ <div class="modal-body">
+ <p>${message}</p>
+ </div>
+ <div class="modal-footer">
+ <a data-dismiss="modal" class="btn">${I18n.t('cancel')}</a>
+ <a data-dismiss="modal" class="btn btn-primary" data-method=${link.data('method')} href=${link.attr('href')}>${I18n.t('ok')}</a>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div> `
+ $(html).modal()
+ }
+}) \ No newline at end of file
diff --git a/app/assets/stylesheets/application.sass b/app/assets/stylesheets/application.sass
index 3f8467efe..632ade179 100644
--- a/app/assets/stylesheets/application.sass
+++ b/app/assets/stylesheets/application.sass
@@ -21,3 +21,6 @@
@import 'modules/import_messages'
@import 'flag-icon'
+
+span.fa + span
+ margin-left: 0.2em
diff --git a/app/assets/stylesheets/components/_forms.sass b/app/assets/stylesheets/components/_forms.sass
index b13c5fc23..e7aa31fab 100644
--- a/app/assets/stylesheets/components/_forms.sass
+++ b/app/assets/stylesheets/components/_forms.sass
@@ -507,10 +507,10 @@ table, .table
right: 15px
top: 50%
padding: 0
- margin-top: -13px
z-index: 1
+ transform: translateY(-50%)
- .btn
+ *:not(.btn-group) > .btn
color: $blue
font-weight: 700
background-color: transparent
@@ -718,6 +718,10 @@ table, .table
> .form-group:last-child
border-right: none
+ @for $i from 1 through 99
+ &.w#{$i}
+ display: inline-block
+
// Form group date
.form-group.date
.form-inline
diff --git a/app/assets/stylesheets/modules/_vj_collection.sass b/app/assets/stylesheets/modules/_vj_collection.sass
index 3ff0828ea..9bb19f75f 100644
--- a/app/assets/stylesheets/modules/_vj_collection.sass
+++ b/app/assets/stylesheets/modules/_vj_collection.sass
@@ -2,7 +2,7 @@
// VJ Collection //
//-----------------//
-#vehicle_journeys_wip
+#vehicle_journeys_wip, .consolidated-view
.table-2entries
.t2e-head
> .td
@@ -218,3 +218,95 @@
// Reset default behaviour
.form-control
border-color: #ccc
+
+.consolidated-view
+ $highlighted: #d4ba32
+ .togglable
+ &.ready
+ transition: all 0.5s
+ &:not(.open)
+ min-height: 0 !important
+ padding: 0 !important
+ margin: 0 !important
+ border: none
+
+ .line
+ & > .head
+ font-size: 2em
+ text-transform: capitalize
+ border-top: 3px solid black
+ border-bottom: 3px solid black
+ padding-left: 10px
+ margin-top: 10px
+ .routes
+ .route
+ background: #F9F9F9
+ & > .head
+ &.highlighted
+ .pull-right, span.fa
+ color: $highlighted !important
+ a
+ padding: 15px
+ color: black
+ font-size: 1.2em
+ text-transform: capitalize
+ display: block
+ text-decoration: none
+ &:hover
+ background-color: #F0F0F0
+ .fa
+ color: $red
+ transition: transform 0.1s
+ &.active .fa
+ transform: rotate(180deg)
+ .pull-right
+ font-size: 0.9em
+ text-transform: lowercase
+ .vehicle-journeys
+ display: block
+ overflow: hidden
+ margin-bottom: 0px
+ & > *
+ display: inline-block
+ & > *
+ overflow: hidden
+ min-width: 0
+ &.open
+ margin-bottom: 40px
+
+ .highlighted
+ background-color: lighten($highlighted, 20%) !important
+ .disabled
+ color: #bbb
+ .t2e-item-list .t2e-item
+ .th
+ min-width: 100px
+ max-width: 150px
+ & > div
+ text-overflow: ellipsis
+ overflow: hidden
+ white-space: nowrap
+ .td
+ text-align: center
+ &:hover:after
+ position: absolute
+ height: 100%
+ bottom: 0
+ left: -10000px
+ right: -10000px
+ content: ""
+ background-color: $red
+ opacity: 0.1
+ z-index: 10
+ &.headlined:hover:after
+ height: 50%
+
+
+ .table-2entries > .t2e-head > .td > div > span::after
+ bottom: -6px !important
+
+ .table.table-2entries .t2e-item-list .t2e-item
+ background-color: #F9F9F9
+
+ .table.table-2entries .td > div.headlined::before
+ border-right: none
diff --git a/app/controllers/companies_controller.rb b/app/controllers/companies_controller.rb
index 2c32ed3a5..c359dfd6d 100644
--- a/app/controllers/companies_controller.rb
+++ b/app/controllers/companies_controller.rb
@@ -44,9 +44,9 @@ class CompaniesController < ChouetteController
ids = @q.result(:distinct => true).pluck(:id)
scope = scope.where(id: ids)
if sort_column && sort_direction
- @companies ||= scope.order(sort_column + ' ' + sort_direction).paginate(:page => params[:page])
+ @companies ||= scope.order("lower(#{sort_column})" + ' ' + sort_direction).paginate(:page => params[:page])
else
- @companies ||= scope.order(:name).paginate(:page => params[:page])
+ @companies ||= scope.order('lower(name)').paginate(:page => params[:page])
end
end
diff --git a/app/controllers/compliance_check_messages_controller.rb b/app/controllers/compliance_check_messages_controller.rb
index 36745981e..db551cca5 100644
--- a/app/controllers/compliance_check_messages_controller.rb
+++ b/app/controllers/compliance_check_messages_controller.rb
@@ -7,7 +7,7 @@ class ComplianceCheckMessagesController < ChouetteController
def index
index! do |format|
format.csv {
- send_data ComplianceCheckMessageExport.new(compliance_check_messages: collection).to_csv(:col_sep => "\;", :quote_char=>'"', force_quotes: true, server_url: request.base_url) , :filename => "compliance_check_set_errors_#{line_code}_#{Date.today.to_s}.csv"
+ send_data ComplianceCheckMessageExport.new(compliance_check_messages: collection).to_csv(:col_sep => "\;", :quote_char=>'"', force_quotes: true, server_url: request.base_url) , :filename => "#{t('compliance_check_messages.compliance_check_set_errors')}_#{line_code}_#{Time.now.strftime('%d-%m-%Y_%H-%M')}.csv"
}
end
end
@@ -22,10 +22,10 @@ class ComplianceCheckMessagesController < ChouetteController
end
def compliance_check_resource
- ComplianceCheckResource.find(params[:compliance_check_resource_id])
+ ComplianceCheckResource.find(params[:compliance_check_resource_id])
end
- private
+ private
def line_code
Chouette::Line.find_by_objectid("#{compliance_check_resource.reference}").get_objectid.local_id
diff --git a/app/controllers/import_messages_controller.rb b/app/controllers/import_messages_controller.rb
index e9a071177..9f61940a3 100644
--- a/app/controllers/import_messages_controller.rb
+++ b/app/controllers/import_messages_controller.rb
@@ -9,7 +9,7 @@ class ImportMessagesController < ChouetteController
def index
index! do |format|
format.csv {
- send_data Import::MessageExport.new(:import_messages => @import_messages).to_csv(:col_sep => "\;", :quote_char=>'"', force_quotes: true) , :filename => "import_errors_#{@import_resource.name.gsub('.xml', '')}_#{Date.today.to_s}.csv"
+ send_data Import::MessageExport.new(:import_messages => @import_messages).to_csv(:col_sep => "\;", :quote_char=>'"', force_quotes: true) , :filename => "#{t('import_messages.import_errors')}_#{@import_resource.name.gsub('.xml', '')}_#{Time.now.strftime("%d-%m-%Y_%H-%M")}.csv"
}
end
end
diff --git a/app/controllers/import_resources_controller.rb b/app/controllers/import_resources_controller.rb
index 1535fd171..46f8f0337 100644
--- a/app/controllers/import_resources_controller.rb
+++ b/app/controllers/import_resources_controller.rb
@@ -24,6 +24,15 @@ class ImportResourcesController < ChouetteController
@import_resources ||= parent.resources
end
+ def resource
+ @import ||= Import::Base.find params[:import_id]
+ @import_resource ||= begin
+ import_resource = Import::Resource.find params[:id]
+ raise ActiveRecord::RecordNotFound unless import_resource.import == @import
+ import_resource
+ end
+ end
+
private
def decorate_import_resources(import_resources)
diff --git a/app/controllers/imports_controller.rb b/app/controllers/imports_controller.rb
index 8d7a723a0..b98d7da8d 100644
--- a/app/controllers/imports_controller.rb
+++ b/app/controllers/imports_controller.rb
@@ -4,6 +4,7 @@ class ImportsController < ChouetteController
include IevInterfaces
skip_before_action :authenticate_user!, only: [:download]
defaults resource_class: Import::Base, collection_name: 'imports', instance_name: 'import'
+ before_action :notify_parents
def download
if params[:token] == resource.token_download
@@ -18,7 +19,7 @@ class ImportsController < ChouetteController
def index_model
Import::Workbench
end
-
+
def build_resource
@import ||= Import::Workbench.new(*resource_params) do |import|
import.workbench = parent
@@ -43,4 +44,10 @@ class ImportsController < ChouetteController
}
)
end
+
+ def notify_parents
+ if Rails.env.development?
+ ParentNotifier.new(Import::Base).notify_when_finished
+ end
+ end
end
diff --git a/app/controllers/referential_vehicle_journeys_controller.rb b/app/controllers/referential_vehicle_journeys_controller.rb
index 14f7909b9..111d39c2b 100644
--- a/app/controllers/referential_vehicle_journeys_controller.rb
+++ b/app/controllers/referential_vehicle_journeys_controller.rb
@@ -42,9 +42,9 @@ class ReferentialVehicleJourneysController < ChouetteController
@q = @q.ransack(params[:q])
@vehicle_journeys ||= @q.result
@vehicle_journeys = parse_order @vehicle_journeys
- @vehicle_journeys = @vehicle_journeys.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
-
+ @consolidated = ReferentialConsolidated.new @vehicle_journeys, params
+ @vehicle_journeys = @vehicle_journeys.paginate page: params[:page], per_page: params[:per_page] || 10
end
def parse_order scope
diff --git a/app/controllers/stop_areas_controller.rb b/app/controllers/stop_areas_controller.rb
index 734152c64..38363e8ef 100644
--- a/app/controllers/stop_areas_controller.rb
+++ b/app/controllers/stop_areas_controller.rb
@@ -120,7 +120,6 @@ class StopAreasController < ChouetteController
def collection
scope = parent.present? ? parent.stop_areas : referential.stop_areas
- scope = ransack_status(scope)
@q = scope.search(params[:q])
if sort_column && sort_direction
@@ -206,24 +205,4 @@ class StopAreasController < ChouetteController
] + permitted_custom_fields_params(Chouette::StopArea.custom_fields(stop_area_referential.workgroup))
params.require(:stop_area).permit(fields)
end
-
- # Fake ransack filter
- def ransack_status scope
- return scope unless params[:q].try(:[], :status)
- return scope if params[:q][:status].values.uniq.length == 1
-
- @status = {
- in_creation: params[:q][:status]['in_creation'] == 'true',
- confirmed: params[:q][:status]['confirmed'] == 'true',
- deactivated: params[:q][:status]['deactivated'] == 'true',
- }
-
- scope = Chouette::StopArea.where(
- "confirmed_at #{(@status[:confirmed] || @status[:deactivated]) ? "IS NOT NULL" : "IS NULL"}
- AND deleted_at #{@status[:deactivated] ? "IS NOT NULL" : "IS NULL"}"
- )
-
- params[:q].delete :status
- scope
- end
end
diff --git a/app/controllers/workbenches_controller.rb b/app/controllers/workbenches_controller.rb
index 43415ff60..d4dfdebe3 100644
--- a/app/controllers/workbenches_controller.rb
+++ b/app/controllers/workbenches_controller.rb
@@ -42,7 +42,7 @@ class WorkbenchesController < ChouetteController
private
def workbench_params
- params.require(:workbench).permit(:import_compliance_control_set_id, :merge_compliance_control_set_id)
+ params.require(:workbench).permit(compliance_control_set_ids: @workbench.workgroup.compliance_control_sets_by_workbench.keys)
end
def resource
diff --git a/app/controllers/workgroups_controller.rb b/app/controllers/workgroups_controller.rb
new file mode 100644
index 000000000..3acea248d
--- /dev/null
+++ b/app/controllers/workgroups_controller.rb
@@ -0,0 +1,13 @@
+class WorkgroupsController < ChouetteController
+ defaults resource_class: Workgroup
+
+ include PolicyChecker
+
+ def show
+ redirect_to "/"
+ end
+
+ def workgroup_params
+ params[:workgroup].permit(workbenches_attributes: [:id, compliance_control_set_ids: @workgroup.compliance_control_sets_by_workgroup.keys])
+ end
+end
diff --git a/app/decorators/compliance_control_decorator.rb b/app/decorators/compliance_control_decorator.rb
index fd2dbd9ce..7cdb4a890 100644
--- a/app/decorators/compliance_control_decorator.rb
+++ b/app/decorators/compliance_control_decorator.rb
@@ -5,7 +5,7 @@ class ComplianceControlDecorator < AF83::Decorator
with_instance_decorator do |instance_decorator|
instance_decorator.show_action_link do |l|
- l.content h.t('compliance_control_sets.actions.show')
+ l.content t('compliance_control_sets.actions.show')
l.href do
h.compliance_control_set_compliance_control_path(
object.compliance_control_set.id,
@@ -17,7 +17,7 @@ class ComplianceControlDecorator < AF83::Decorator
instance_decorator.edit_action_link
instance_decorator.destroy_action_link do |l|
- l.data confirm: h.t('compliance_controls.actions.destroy_confirm')
+ l.data confirm: t('compliance_controls.actions.destroy_confirm')
end
end
diff --git a/app/decorators/compliance_control_set_decorator.rb b/app/decorators/compliance_control_set_decorator.rb
index b16a06886..ad38c492c 100644
--- a/app/decorators/compliance_control_set_decorator.rb
+++ b/app/decorators/compliance_control_set_decorator.rb
@@ -20,7 +20,7 @@ class ComplianceControlSetDecorator < AF83::Decorator
instance_decorator.destroy_action_link do |l|
l.content h.destroy_link_content
l.href { h.compliance_control_set_path(object.id) }
- l.data confirm: h.t('compliance_control_sets.actions.destroy_confirm')
+ l.data confirm: t('compliance_control_sets.actions.destroy_confirm')
end
end
end
diff --git a/app/decorators/line_decorator.rb b/app/decorators/line_decorator.rb
index 077978c36..0fdb7cc0b 100644
--- a/app/decorators/line_decorator.rb
+++ b/app/decorators/line_decorator.rb
@@ -44,7 +44,7 @@ class LineDecorator < AF83::Decorator
l.content { h.deactivate_link_content('lines.actions.deactivate') }
l.href { h.deactivate_line_referential_line_path(context[:line_referential], object) }
l.method :put
- l.data confirm: h.t('lines.actions.deactivate_confirm')
+ l.data {{ confirm: h.t('lines.actions.deactivate_confirm') }}
l.add_class "delete-action"
end
@@ -52,13 +52,13 @@ class LineDecorator < AF83::Decorator
l.content { h.activate_link_content('lines.actions.activate') }
l.href { h.activate_line_referential_line_path(context[:line_referential], object) }
l.method :put
- l.data confirm: h.t('lines.actions.activate_confirm')
+ l.data {{ confirm: h.t('lines.actions.activate_confirm') }}
l.add_class "delete-action"
end
instance_decorator.destroy_action_link do |l|
l.content { h.destroy_link_content('lines.actions.destroy') }
- l.data confirm: h.t('lines.actions.destroy_confirm')
+ l.data {{ confirm: h.t('lines.actions.destroy_confirm') }}
l.add_class "delete-action"
end
end
diff --git a/app/decorators/network_decorator.rb b/app/decorators/network_decorator.rb
index ea0f73dc2..55cd37082 100644
--- a/app/decorators/network_decorator.rb
+++ b/app/decorators/network_decorator.rb
@@ -25,8 +25,8 @@ class NetworkDecorator < AF83::Decorator
end
instance_decorator.destroy_action_link do |l|
- l.content h.destroy_link_content('networks.actions.destroy')
- l.data confirm: h.t('networks.actions.destroy_confirm')
+ l.content { h.destroy_link_content('networks.actions.destroy') }
+ l.data {{ confirm: h.t('networks.actions.destroy_confirm') }}
end
end
end
diff --git a/app/decorators/purchase_window_decorator.rb b/app/decorators/purchase_window_decorator.rb
index 9b58577b2..8e6ca9d36 100644
--- a/app/decorators/purchase_window_decorator.rb
+++ b/app/decorators/purchase_window_decorator.rb
@@ -15,7 +15,7 @@ class PurchaseWindowDecorator < AF83::Decorator
instance_decorator.edit_action_link
instance_decorator.destroy_action_link do |l|
- l.data confirm: h.t('purchase_windows.actions.destroy_confirm')
+ l.data confirm: 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 3ac846d76..4416e133e 100644
--- a/app/decorators/referential_line_decorator.rb
+++ b/app/decorators/referential_line_decorator.rb
@@ -13,12 +13,12 @@ class ReferentialLineDecorator < AF83::Decorator
instance_decorator.show_action_link
instance_decorator.action_link secondary: true do |l|
- l.content Chouette::Line.human_attribute_name(:footnotes)
+ l.content Chouette::Line.tmf(:footnotes)
l.href { h.referential_line_footnotes_path(context[:referential], object) }
end
instance_decorator.action_link secondary: true do |l|
- l.content h.t('routing_constraint_zones.index.title')
+ l.content t('routing_constraint_zones.index.title')
l.href do
h.referential_line_routing_constraint_zones_path(
scope,
@@ -36,7 +36,7 @@ class ReferentialLineDecorator < AF83::Decorator
},
secondary: true
) do |l|
- l.content h.t('routes.actions.new')
+ l.content t('routes.actions.new')
l.href { h.new_referential_line_route_path(scope, object) }
end
end
diff --git a/app/decorators/referential_network_decorator.rb b/app/decorators/referential_network_decorator.rb
index c508452c0..f8c656e7c 100644
--- a/app/decorators/referential_network_decorator.rb
+++ b/app/decorators/referential_network_decorator.rb
@@ -20,8 +20,8 @@ class ReferentialNetworkDecorator < AF83::Decorator
end
instance_decorator.destroy_action_link do |l|
- l.content h.destroy_link_content('networks.actions.destroy')
- l.data confirm: h.t('networks.actions.destroy_confirm')
+ l.content { h.destroy_link_content('networks.actions.destroy') }
+ l.data confirm: t('networks.actions.destroy_confirm')
end
end
end
diff --git a/app/decorators/route_decorator.rb b/app/decorators/route_decorator.rb
index 646bc1620..801e139b0 100644
--- a/app/decorators/route_decorator.rb
+++ b/app/decorators/route_decorator.rb
@@ -18,7 +18,7 @@ class RouteDecorator < AF83::Decorator
if: ->() { object.stop_points.any? },
secondary: :show
) do |l|
- l.content h.t('journey_patterns.actions.index')
+ l.content t('journey_patterns.actions.index')
l.href do
[
context[:referential],
@@ -33,7 +33,7 @@ class RouteDecorator < AF83::Decorator
if: ->() { object.journey_patterns.present? },
secondary: :show
) do |l|
- l.content h.t('vehicle_journeys.actions.index')
+ l.content t('vehicle_journeys.actions.index')
l.href do
[
context[:referential],
@@ -45,7 +45,7 @@ class RouteDecorator < AF83::Decorator
end
instance_decorator.action_link secondary: :show do |l|
- l.content h.t('vehicle_journey_exports.new.title')
+ l.content t('vehicle_journey_exports.new.title')
l.href do
h.referential_line_route_vehicle_journey_exports_path(
context[:referential],
@@ -60,7 +60,7 @@ class RouteDecorator < AF83::Decorator
secondary: :show,
policy: :duplicate
) do |l|
- l.content h.t('routes.duplicate.title')
+ l.content t('routes.duplicate.title')
l.method :post
l.href do
h.duplicate_referential_line_route_path(
@@ -76,7 +76,7 @@ class RouteDecorator < AF83::Decorator
policy: :create_opposite,
if: ->{h.has_feature?(:create_opposite_routes)}
) do |l|
- l.content h.t('routes.create_opposite.title')
+ l.content t('routes.create_opposite.title')
l.method :post
l.disabled { object.opposite_route.present? }
l.href do
@@ -90,7 +90,7 @@ class RouteDecorator < AF83::Decorator
end
instance_decorator.destroy_action_link do |l|
- l.data confirm: h.t('routes.actions.destroy_confirm')
+ l.data confirm: t('routes.actions.destroy_confirm')
end
end
end
diff --git a/app/decorators/routing_constraint_zone_decorator.rb b/app/decorators/routing_constraint_zone_decorator.rb
index de73068be..3ff286cc1 100644
--- a/app/decorators/routing_constraint_zone_decorator.rb
+++ b/app/decorators/routing_constraint_zone_decorator.rb
@@ -21,7 +21,7 @@ class RoutingConstraintZoneDecorator < AF83::Decorator
instance_decorator.edit_action_link
instance_decorator.destroy_action_link do |l|
- l.data confirm: h.t('routing_constraint_zones.actions.destroy_confirm')
+ l.data confirm: t('routing_constraint_zones.actions.destroy_confirm')
end
end
end
diff --git a/app/decorators/stop_area_decorator.rb b/app/decorators/stop_area_decorator.rb
index 525681971..c7f10b13b 100644
--- a/app/decorators/stop_area_decorator.rb
+++ b/app/decorators/stop_area_decorator.rb
@@ -11,11 +11,11 @@ class StopAreaDecorator < AF83::Decorator
instance_decorator.show_action_link
instance_decorator.edit_action_link do |l|
- l.content h.t('stop_areas.actions.edit')
+ l.content t('stop_areas.actions.edit')
end
instance_decorator.action_link policy: :deactivate, secondary: true do |l|
- l.content h.deactivate_link_content('stop_areas.actions.deactivate')
+ l.content { h.deactivate_link_content('stop_areas.actions.deactivate') }
l.href do
h.deactivate_stop_area_referential_stop_area_path(
object.stop_area_referential,
@@ -23,12 +23,12 @@ class StopAreaDecorator < AF83::Decorator
)
end
l.method :put
- l.data confirm: h.t('stop_areas.actions.deactivate_confirm')
+ l.data confirm: t('stop_areas.actions.deactivate_confirm')
l.add_class 'delete-action'
end
instance_decorator.action_link policy: :activate, secondary: true do |l|
- l.content h.activate_link_content('stop_areas.actions.activate')
+ l.content { h.activate_link_content('stop_areas.actions.activate') }
l.href do
h.activate_stop_area_referential_stop_area_path(
object.stop_area_referential,
@@ -36,13 +36,13 @@ class StopAreaDecorator < AF83::Decorator
)
end
l.method :put
- l.data confirm: h.t('stop_areas.actions.activate_confirm')
+ l.data confirm: t('stop_areas.actions.activate_confirm')
l.add_class 'delete-action'
end
instance_decorator.destroy_action_link do |l|
- l.content h.destroy_link_content('stop_areas.actions.destroy')
- l.data confirm: h.t('stop_areas.actions.destroy_confirm')
+ l.content { h.destroy_link_content('stop_areas.actions.destroy') }
+ l.data confirm: t('stop_areas.actions.destroy_confirm')
end
end
diff --git a/app/decorators/stop_area_referential_decorator.rb b/app/decorators/stop_area_referential_decorator.rb
index d30501ec9..36e45abca 100644
--- a/app/decorators/stop_area_referential_decorator.rb
+++ b/app/decorators/stop_area_referential_decorator.rb
@@ -5,9 +5,9 @@ class StopAreaReferentialDecorator < AF83::Decorator
instance_decorator.action_link policy: :synchronize, primary: :show do |l|
l.content t('actions.sync')
- l.href { h. sync_stop_area_referential_path(object.id) }
+ l.href { h.sync_stop_area_referential_path(object.id) }
l.method :post
end
-
+
end
end
diff --git a/app/decorators/stop_point_decorator.rb b/app/decorators/stop_point_decorator.rb
index 4ff5bce9c..575938fa2 100644
--- a/app/decorators/stop_point_decorator.rb
+++ b/app/decorators/stop_point_decorator.rb
@@ -4,8 +4,8 @@ class StopPointDecorator < AF83::Decorator
with_instance_decorator do |instance_decorator|
instance_decorator.show_action_link do |l|
l.href do
- h.referential_stop_area_path(
- object.referential,
+ h.stop_area_referential_stop_area_path(
+ object.stop_area.stop_area_referential,
object.stop_area
)
end
diff --git a/app/helpers/exports_helper.rb b/app/helpers/exports_helper.rb
index 2e784ad35..f30a80ed9 100644
--- a/app/helpers/exports_helper.rb
+++ b/app/helpers/exports_helper.rb
@@ -17,7 +17,7 @@ module ExportsHelper
message.message_attributes["text"]
else
t([message.class.name.underscore.gsub('/', '_').pluralize, message.message_key].join('.'), message.message_attributes&.symbolize_keys || {})
- end
+ end.html_safe
end
def fields_for_export_task_format(form)
diff --git a/app/helpers/imports_helper.rb b/app/helpers/imports_helper.rb
index 140660153..f06d77eca 100644
--- a/app/helpers/imports_helper.rb
+++ b/app/helpers/imports_helper.rb
@@ -2,33 +2,49 @@
module ImportsHelper
# Import statuses helper
- def import_status(status)
- if %w[new running pending].include? status
+ def import_status(status, verbose: false, default_status: nil)
+ status ||= default_status
+ return unless status
+ status = status.to_s.downcase
+ out = if %w[new running pending].include? status
content_tag :span, '', class: "fa fa-clock-o"
else
cls =''
cls = 'success' if status == 'successful'
+ cls = 'success' if status == 'ok'
cls = 'warning' if status == 'warning'
- cls = 'danger' if %w[failed aborted canceled].include? status
+ cls = 'danger' if %w[failed aborted canceled error].include? status
content_tag :span, '', class: "fa fa-circle text-#{cls}"
end
+ if verbose
+ out += content_tag :span do
+ txt = "imports.status.#{status}".t(fallback: "")
+ end
+ end
+ out
end
# Compliance check set messages
def bootstrap_class_for_message_criticity message_criticity
- case message_criticity
- when "error"
+ case message_criticity.downcase
+ when "error", "aborted"
"alert alert-danger"
when "warning"
"alert alert-warning"
when "info"
"alert alert-info"
+ when "ok", "success"
+ "alert alert-success"
else
message_criticity.to_s
end
end
+ def import_message_content message
+ export_message_content message
+ end
+
##############################
#      TO CLEAN!!!
##############################
diff --git a/app/helpers/menus_helper.rb b/app/helpers/menus_helper.rb
new file mode 100644
index 000000000..81d55a944
--- /dev/null
+++ b/app/helpers/menus_helper.rb
@@ -0,0 +1,20 @@
+module MenusHelper
+ def main_nav_menu_item label, &block
+ @current_menu_item_count ||= 0
+ @current_menu_item_count += 1
+ content_tag :div, class: "menu-item panel" do
+ out = ""
+ out += content_tag(:div, class: "panel-heading") do
+ content_tag :h4, class: "panel-title" do
+ link_to label, "#menu-item-#{@current_menu_item_count}", data: {toggle: 'collapse', parent: '#menu-items'}, 'aria-expanded' => 'false'
+ end
+ end
+ out += content_tag(:div, class: "panel-collapse collapse", id: "menu-item-#{@current_menu_item_count}") do
+ content_tag :div, class: "list-group" do
+ capture(&block)
+ end
+ end
+ out.html_safe
+ end
+ end
+end
diff --git a/app/helpers/stop_areas_helper.rb b/app/helpers/stop_areas_helper.rb
index 314154fb7..d3e7dd2a4 100644
--- a/app/helpers/stop_areas_helper.rb
+++ b/app/helpers/stop_areas_helper.rb
@@ -75,16 +75,17 @@ module StopAreasHelper
t "formtastic.hints.stop_area.registration_number"
end
- def stop_area_status(stop_area)
- if stop_area.activated?
- content_tag(:span, nil, class: 'fa fa-check-circle fa-lg text-success') +
- t('activerecord.attributes.stop_area.confirmed')
- elsif stop_area.deactivated?
- content_tag(:span, nil, class: 'fa fa-exclamation-circle fa-lg text-danger') +
- t('activerecord.attributes.stop_area.deactivated')
- else
- content_tag(:span, nil, class: 'fa fa-pencil fa-lg text-info') +
- t('activerecord.attributes.stop_area.in_creation')
+ def stop_area_status(status)
+ case status
+ when :confirmed
+ content_tag(:span, nil, class: 'fa fa-check-circle fa-lg text-success') +
+ t('activerecord.attributes.stop_area.confirmed')
+ when :deactivated
+ content_tag(:span, nil, class: 'fa fa-exclamation-circle fa-lg text-danger') +
+ t('activerecord.attributes.stop_area.deactivated')
+ else
+ content_tag(:span, nil, class: 'fa fa-pencil fa-lg text-info') +
+ t('activerecord.attributes.stop_area.in_creation')
end
end
diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb
index e2aa2e9ea..0b24a9c05 100644
--- a/app/helpers/table_builder_helper.rb
+++ b/app/helpers/table_builder_helper.rb
@@ -153,7 +153,17 @@ module TableBuilderHelper
i = columns.index(column)
if overhead[i].blank?
- if (i > 0) && (overhead[i - 1][:width] > 1)
+ prev = nil
+ if i > 0
+ (i-1..0).each do |j|
+ o = overhead[j]
+ if (j + o[:width].to_i) >= i
+ prev = o
+ break
+ end
+ end
+ end
+ if prev
clsArrayH = overhead[i - 1][:cls].split
hcont << content_tag(:th, build_column_header(
@@ -225,7 +235,7 @@ module TableBuilderHelper
if column.linkable?
path = column.link_to(item)
- link = value.present? && path.present? ? link_to(value, path) : ""
+ link = value.present? && path.present? ? link_to(value, path) : value
if overhead.empty?
bcont << content_tag(:td, link, title: 'Voir', class: extra_class)
@@ -234,7 +244,17 @@ module TableBuilderHelper
i = columns.index(column)
if overhead[i].blank?
- if (i > 0) && (overhead[i - 1][:width] > 1)
+ prev = nil
+ if i > 0
+ (i-1..0).each do |j|
+ o = overhead[j]
+ if (j + o[:width].to_i) >= i
+ prev = o
+ break
+ end
+ end
+ end
+ if prev
clsArrayAlt = overhead[i - 1][:cls].split
bcont << content_tag(:td, link, title: 'Voir', class: td_cls(clsArrayAlt, extra_class))
diff --git a/app/helpers/vehicle_journeys_helper.rb b/app/helpers/vehicle_journeys_helper.rb
index 1cc865c62..4d7eb7002 100644
--- a/app/helpers/vehicle_journeys_helper.rb
+++ b/app/helpers/vehicle_journeys_helper.rb
@@ -69,4 +69,16 @@ module VehicleJourneysHelper
)
end
+ def vehicle_journey_stop_headline prev_sp, sp
+ if has_feature?(:long_distance_routes)
+ headline = prev_sp && prev_sp.stop_area.country_code
+ headline = sp.stop_area.country_code != headline
+ headline && sp.stop_area.country_name
+ else
+ headline = prev_sp && prev_sp.stop_area.city_name
+ headline = sp.stop_area.city_name != headline
+ headline && sp.stop_area.city_name
+ end
+ end
+
end
diff --git a/app/javascript/helpers/polyfills.js b/app/javascript/helpers/polyfills.js
index 93e3e9846..691fe04af 100644
--- a/app/javascript/helpers/polyfills.js
+++ b/app/javascript/helpers/polyfills.js
@@ -1,4 +1,5 @@
import 'promise-polyfill/src/polyfill'
import 'es6-symbol/implement'
import 'polyfill-array-includes'
+import 'babel-polyfill'
import 'whatwg-fetch'
diff --git a/app/javascript/vehicle_journeys/actions/index.js b/app/javascript/vehicle_journeys/actions/index.js
index 98594083d..8ac8b5ec5 100644
--- a/app/javascript/vehicle_journeys/actions/index.js
+++ b/app/javascript/vehicle_journeys/actions/index.js
@@ -379,11 +379,11 @@ const actions = {
vehicle_journey_at_stops: vjasWithDelta,
deletable: false,
selected: false,
- published_journey_name: val.published_journey_name || 'non renseigné',
- published_journey_identifier: val.published_journey_identifier || 'non renseigné',
- company: val.company || {name: 'non renseigné'},
- transport_mode: val.route.line.transport_mode || 'undefined',
- transport_submode: val.route.line.transport_submode || 'undefined'
+ published_journey_name: val.published_journey_name || '',
+ published_journey_identifier: val.published_journey_identifier || '',
+ company: val.company || {name: ''},
+ transport_mode: val.route.line.transport_mode || '',
+ transport_submode: val.route.line.transport_submode || ''
})
)
}
diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js b/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js
index cec39ab4e..a0438d7c5 100644
--- a/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js
+++ b/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js
@@ -58,7 +58,8 @@ export default class BSelect4 extends Component {
this.props.onSelect2JourneyPattern(e)
}
else{
- let data = JSON.parse(e.currentTarget.selectedOptions[0].dataset.item)
+ let option = e.currentTarget.options[e.currentTarget.selectedIndex]
+ let data = JSON.parse(option.dataset.item)
this.props.onSelect2JourneyPattern({params:
{
diff --git a/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js b/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
index ecb58e2ea..4931ab46e 100644
--- a/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
+++ b/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
@@ -66,10 +66,6 @@ const vehicleJourney= (state = {}, action, keep) => {
newVjas.departure_day_offset = 1
newVjas.arrival_day_offset = 1
}
- if(current_time.hour + offsetHours < 0){
- newVjas.departure_day_offset = -1
- newVjas.arrival_day_offset = -1
- }
}
else{
newVjas = {
diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb
index 7a8d043e0..949b18d6f 100644
--- a/app/models/chouette/route.rb
+++ b/app/models/chouette/route.rb
@@ -72,6 +72,9 @@ module Chouette
end
end
+ has_many :time_tables, :through => :vehicle_journeys
+ has_many :purchase_windows, :through => :vehicle_journeys
+
accepts_nested_attributes_for :stop_points, :allow_destroy => :true
validates_presence_of :name
diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb
index b933e1944..25a0010d8 100644
--- a/app/models/chouette/stop_area.rb
+++ b/app/models/chouette/stop_area.rb
@@ -383,6 +383,28 @@ module Chouette
end
end
+ def self.ransackable_scopes(auth_object = nil)
+ [:by_status]
+ end
+
+
+ def self.by_status(*statuses)
+ return Chouette::StopArea.all if statuses.reject(&:blank?).length == 3 || statuses.reject(&:blank?).empty?
+
+ status = {
+ in_creation: statuses.include?('in_creation'),
+ confirmed: statuses.include?('confirmed'),
+ deactivated: statuses.include?('deactivated'),
+ }
+
+ query = []
+ query << "deleted_at IS NOT NULL" if statuses.include?('deactivated')
+ query << "(confirmed_at IS NULL AND deleted_at IS NULL)" if statuses.include?('in_creation')
+ query << "(confirmed_at IS NOT NULL AND deleted_at IS NULL)" if statuses.include?('confirmed')
+
+ Chouette::StopArea.where(query.join(' OR '))
+ end
+
def activated?
!!(deleted_at.nil? && confirmed_at)
end
@@ -410,7 +432,7 @@ module Chouette
end
def status
- return :deleted if deleted_at
+ return :deactivated if deleted_at
return :confirmed if confirmed_at
:in_creation
@@ -418,7 +440,7 @@ module Chouette
def status=(status)
case status&.to_sym
- when :deleted
+ when :deactivated
deactivate
when :confirmed
activate
@@ -428,7 +450,7 @@ module Chouette
end
def self.statuses
- %i{in_creation confirmed deleted}
+ %i{in_creation confirmed deactivated}
end
def time_zone_offset
@@ -441,7 +463,7 @@ module Chouette
return unless ActiveSupport::TimeZone[time_zone].present?
ActiveSupport::TimeZone[time_zone].tzinfo.name
end
-
+
def country
return unless country_code
country = ISO3166::Country[country_code]
diff --git a/app/models/clean_up.rb b/app/models/clean_up.rb
index 0f73e07b2..9cf2389c9 100644
--- a/app/models/clean_up.rb
+++ b/app/models/clean_up.rb
@@ -16,6 +16,8 @@ class CleanUp < ApplicationModel
where(referential_id: referential.id)
end
+ attr_accessor :methods
+
def end_date_must_be_greater_that_begin_date
if self.end_date && self.date_type == 'between' && self.begin_date >= self.end_date
errors.add(:base, I18n.t('activerecord.errors.models.clean_up.invalid_period'))
@@ -43,17 +45,22 @@ class CleanUp < ApplicationModel
end
end
- destroy_vehicle_journeys_outside_referential
+ destroy_routes_outside_referential
# Disabled for the moment. See #5372
# destroy_time_tables_outside_referential
- destroy_vehicle_journeys
- destroy_journey_patterns
- destroy_routes
+ # Run caller-specified cleanup methods
+ run_methods
end
end
end
+ def run_methods
+ return if methods.nil?
+
+ methods.each { |method| send(method) }
+ end
+
def destroy_time_tables_between
time_tables = Chouette::TimeTable.where('end_date < ? AND start_date > ?', self.end_date, self.begin_date)
self.destroy_time_tables(time_tables)
@@ -100,9 +107,9 @@ class CleanUp < ApplicationModel
destroy_time_tables(time_tables)
end
- def destroy_vehicle_journeys_outside_referential
+ def destroy_routes_outside_referential
line_ids = referential.metadatas.pluck(:line_ids).flatten.uniq
- Chouette::VehicleJourney.joins(:route).where(["routes.line_id not in (?)", line_ids]).destroy_all
+ Chouette::Route.where(['line_id not in (?)', line_ids]).destroy_all
end
def destroy_vehicle_journeys
@@ -117,6 +124,12 @@ class CleanUp < ApplicationModel
Chouette::Route.where("id not in (select distinct route_id from journey_patterns)").destroy_all
end
+ def destroy_empty
+ destroy_vehicle_journeys
+ destroy_journey_patterns
+ destroy_routes
+ end
+
def overlapping_periods
self.end_date = self.begin_date if self.date_type != 'between'
Chouette::TimeTablePeriod.where('(period_start, period_end) OVERLAPS (?, ?)', self.begin_date, self.end_date)
diff --git a/app/models/compliance_check_set.rb b/app/models/compliance_check_set.rb
index 8b1dbdd68..f29ff4de5 100644
--- a/app/models/compliance_check_set.rb
+++ b/app/models/compliance_check_set.rb
@@ -26,6 +26,10 @@ class ComplianceCheckSet < ApplicationModel
%w(successful failed warning aborted canceled)
end
+ def successful?
+ status.to_s == "successful"
+ end
+
def self.abort_old
where(
'created_at < ? AND status NOT IN (?)',
@@ -68,6 +72,11 @@ class ComplianceCheckSet < ApplicationModel
end
update attributes
+ import_resource&.next_step
+ end
+
+ def import_resource
+ referential&.import_resources.main_resources.last
end
diff --git a/app/models/concerns/checksum_support.rb b/app/models/concerns/checksum_support.rb
index fe52604bb..86bbd1d00 100644
--- a/app/models/concerns/checksum_support.rb
+++ b/app/models/concerns/checksum_support.rb
@@ -10,19 +10,24 @@ module ChecksumSupport
end
module ClassMethods
+
def has_checksum_children klass, opts={}
parent_class = self
belongs_to = opts[:relation] || self.model_name.singular
has_many = opts[:relation] || self.model_name.plural
Rails.logger.debug "Define callback in #{klass} to update checksums #{self.model_name} (via #{has_many}/#{belongs_to})"
- klass.after_save do
+
+ child_update_parent = Proc.new do
parents = []
parents << self.send(belongs_to) if klass.reflections[belongs_to].present?
parents += self.send(has_many) if klass.reflections[has_many].present?
Rails.logger.debug "Request from #{klass.name} checksum updates for #{parents.count} #{parent_class} parent(s)"
parents.compact.each &:update_checksum_without_callbacks!
end
+
+ klass.after_save &child_update_parent
+ klass.after_destroy &child_update_parent
end
end
diff --git a/app/models/concerns/custom_fields_support.rb b/app/models/concerns/custom_fields_support.rb
index 6b6621d0c..f5a76f324 100644
--- a/app/models/concerns/custom_fields_support.rb
+++ b/app/models/concerns/custom_fields_support.rb
@@ -6,7 +6,7 @@ module CustomFieldsSupport
after_initialize :initialize_custom_fields
def self.custom_fields workgroup
- return [] unless workgroup
+ return CustomField.none unless workgroup
fields = CustomField.where(resource_type: self.name.split("::").last)
fields = fields.where(workgroup_id: workgroup.id)
fields
diff --git a/app/models/concerns/iev_interfaces/resource.rb b/app/models/concerns/iev_interfaces/resource.rb
index 7f8c3eefd..254f88a33 100644
--- a/app/models/concerns/iev_interfaces/resource.rb
+++ b/app/models/concerns/iev_interfaces/resource.rb
@@ -4,6 +4,24 @@ module IevInterfaces::Resource
included do
extend Enumerize
enumerize :status, in: %i(OK ERROR WARNING IGNORED), scope: true
- validates_presence_of :name, :resource_type, :reference
+ validates_presence_of :name, :resource_type
+ end
+
+ def update_status_from_importer importer_status
+ self.update status: status_from_importer(importer_status)
+ end
+
+ def status_from_importer importer_status
+ return nil unless importer_status.present?
+ {
+ new: nil,
+ pending: nil,
+ successful: :OK,
+ warning: :WARNING,
+ failed: :ERROR,
+ running: nil,
+ aborted: :ERROR,
+ canceled: :ERROR
+ }[importer_status.to_sym]
end
end
diff --git a/app/models/concerns/iev_interfaces/task.rb b/app/models/concerns/iev_interfaces/task.rb
index 6be33734b..e40808009 100644
--- a/app/models/concerns/iev_interfaces/task.rb
+++ b/app/models/concerns/iev_interfaces/task.rb
@@ -31,6 +31,16 @@ module IevInterfaces::Task
before_save :initialize_fields, on: :create
after_save :notify_parent
+
+ status.values.each do |s|
+ define_method "#{s}!" do
+ update status: s
+ end
+
+ define_method "#{s}?" do
+ status&.to_s == s
+ end
+ end
end
module ClassMethods
@@ -56,13 +66,14 @@ module IevInterfaces::Task
end
def notify_parent
- return unless self.class.finished_statuses.include?(status)
+ return false unless self.class.finished_statuses.include?(status)
- return unless parent.present?
- return if notified_parent_at
+ return false unless parent.present?
+ return false if notified_parent_at
parent.child_change
update_column :notified_parent_at, Time.now
+ true
end
def children_succeedeed
@@ -94,6 +105,10 @@ module IevInterfaces::Task
update attributes
end
+ def successful?
+ status.to_s == "successful"
+ end
+
def child_change
return if self.class.finished_statuses.include?(status)
update_status
@@ -112,9 +127,14 @@ module IevInterfaces::Task
def call_boiv_iev
Rails.logger.error("Begin IEV call for import")
+
+ # Java code expects tasks in NEW status
+ # Don't change status before calling iev
+
Net::HTTP.get iev_callback_url
Rails.logger.error("End IEV call for import")
rescue Exception => e
+ aborted!
logger.error "IEV server error : #{e.message}"
logger.error e.backtrace.inspect
end
diff --git a/app/models/import/base.rb b/app/models/import/base.rb
index f98e359d4..dcd710e58 100644
--- a/app/models/import/base.rb
+++ b/app/models/import/base.rb
@@ -32,8 +32,13 @@ class Import::Base < ApplicationModel
Rails.logger.info "update_referentials for #{inspect}"
return unless self.class.finished_statuses.include?(status)
- children.each do |import|
- import.referential.update(ready: true) if import.referential
+ # We treat all created referentials in a batch
+ # If a single fails, we consider they all failed
+ # Ohana means family !
+ if self.successful?
+ children.map(&:referential).compact.each &:active!
+ else
+ children.map(&:referential).compact.each &:failed!
end
end
diff --git a/app/models/import/gtfs.rb b/app/models/import/gtfs.rb
index ceb849bd8..9dab11f0e 100644
--- a/app/models/import/gtfs.rb
+++ b/app/models/import/gtfs.rb
@@ -1,19 +1,37 @@
class Import::Gtfs < Import::Base
after_commit :launch_worker, :on => :create
+ after_commit do
+ main_resource.update_status_from_importer self.status
+ true
+ end
+
def launch_worker
GtfsImportWorker.perform_async id
end
+ def main_resource
+ @resource ||= parent.resources.find_or_create_by(name: self.name, resource_type: "referential", reference: self.name) if parent
+ end
+
+ def next_step
+ main_resource&.next_step
+ end
+
+ def create_message args
+ (main_resource || self).messages.build args
+ end
+
def import
update status: 'running', started_at: Time.now
import_without_status
update status: 'successful', ended_at: Time.now
- referential&.ready!
+ referential&.active!
rescue Exception => e
update status: 'failed', ended_at: Time.now
Rails.logger.error "Error in GTFS import: #{e} #{e.backtrace.join('\n')}"
+ create_message criticity: :error, message_key: :full_text, message_attributes: {text: e.message}
referential&.failed!
ensure
notify_parent
@@ -35,6 +53,7 @@ class Import::Gtfs < Import::Base
workbench_id: workbench.id,
metadatas: [referential_metadata]
)
+ main_resource.update referential: referential if main_resource
end
def referential_metadata
@@ -131,17 +150,21 @@ class Import::Gtfs < Import::Base
end
def import_agencies
+ count = 0
Chouette::Company.transaction do
source.agencies.each do |agency|
company = line_referential.companies.find_or_initialize_by(registration_number: agency.id)
company.attributes = { name: agency.name }
save_model company
+ count += 1
end
end
+ create_message criticity: "info", message_key: "gtfs.agencies.imported", message_attributes: {count: count}
end
def import_stops
+ count = 0
Chouette::StopArea.transaction do
source.stops.each do |stop|
stop_area = stop_area_referential.stop_areas.find_or_initialize_by(registration_number: stop.id)
@@ -155,11 +178,14 @@ class Import::Gtfs < Import::Base
# TODO correct default timezone
save_model stop_area
+ count += 1
end
+ create_message criticity: "info", message_key: "gtfs.stops.imported", message_attributes: {count: count}
end
end
def import_routes
+ count = 0
Chouette::Line.transaction do
source.routes.each do |route|
line = line_referential.lines.find_or_initialize_by(registration_number: route.id)
@@ -178,7 +204,9 @@ class Import::Gtfs < Import::Base
line.url = route.url
save_model line
+ count += 1
end
+ create_message criticity: "info", message_key: "gtfs.routes.imported", message_attributes: {count: count}
end
end
@@ -187,6 +215,7 @@ class Import::Gtfs < Import::Base
end
def import_trips
+ count = 0
source.trips.each_slice(100) do |slice|
slice.each do |trip|
Chouette::Route.transaction do
@@ -205,18 +234,20 @@ class Import::Gtfs < Import::Base
vehicle_journey = journey_pattern.vehicle_journeys.build route: route
vehicle_journey.published_journey_name = trip.headsign.presence || trip.id
save_model vehicle_journey
+ count += 1
time_table = referential.time_tables.find_by(id: time_tables_by_service_id[trip.service_id]) if time_tables_by_service_id[trip.service_id]
if time_table
vehicle_journey.time_tables << time_table
else
- messages.create! criticity: "warning", message_key: "gtfs.trips.unkown_service_id", message_attributes: {service_id: trip.service_id}
+ create_message criticity: "warning", message_key: "gtfs.trips.unkown_service_id", message_attributes: {service_id: trip.service_id}
end
vehicle_journey_by_trip_id[trip.id] = vehicle_journey.id
end
end
end
+ create_message criticity: "info", message_key: "gtfs.trips.imported", message_attributes: {count: count}
end
def import_stop_times
@@ -262,6 +293,7 @@ class Import::Gtfs < Import::Base
end
def import_calendars
+ count = 0
source.calendars.each_slice(500) do |slice|
Chouette::TimeTable.transaction do
slice.each do |calendar|
@@ -272,11 +304,13 @@ class Import::Gtfs < Import::Base
time_table.periods.build period_start: calendar.start_date, period_end: calendar.end_date
save_model time_table
+ count += 1
time_tables_by_service_id[calendar.service_id] = time_table.id
end
end
end
+ create_message criticity: "info", message_key: "gtfs.calendars.imported", message_attributes: {count: count}
end
def import_calendar_dates
@@ -301,10 +335,10 @@ class Import::Gtfs < Import::Base
end
def notify_parent
- return unless parent.present?
- return if notified_parent_at
- parent.child_change
- update_column :notified_parent_at, Time.now
+ if super
+ main_resource.update_status_from_importer self.status
+ next_step
+ end
end
end
diff --git a/app/models/import/netex.rb b/app/models/import/netex.rb
index 49554ee90..753f9128d 100644
--- a/app/models/import/netex.rb
+++ b/app/models/import/netex.rb
@@ -2,16 +2,39 @@ require 'net/http'
class Import::Netex < Import::Base
before_destroy :destroy_non_ready_referential
- after_commit :call_iev_callback, on: :create
+ after_commit do
+ main_resource.update_status_from_importer self.status
+ true
+ end
before_save do
- self.status = 'aborted' unless referential
self.referential&.failed! if self.status == 'aborted' || self.status == 'failed'
end
validates_presence_of :parent
+ def main_resource
+ @resource ||= parent.resources.find_or_create_by(name: self.name, resource_type: "referential", reference: self.name)
+ end
+
+ def notify_parent
+ if super
+ main_resource.update_status_from_importer self.status
+ next_step
+ end
+ end
+
+ def next_step
+ main_resource.next_step
+ end
+
+ def create_message args
+ main_resource.messages.create args
+ end
+
def create_with_referential!
+ save unless persisted?
+
self.referential =
Referential.new(
name: self.name,
@@ -20,15 +43,37 @@ class Import::Netex < Import::Base
metadatas: [referential_metadata]
)
self.referential.save
- if self.referential.invalid?
+
+ if self.referential.valid?
+ main_resource.update referential: referential
+ call_iev_callback
+ save!
+ else
Rails.logger.info "Can't create referential for import #{self.id}: #{referential.inspect} #{referential.metadatas.inspect} #{referential.errors.messages}"
- if referential.metadatas.all?{|m| m.line_ids.present? && m.line_ids.empty?}
- parent.messages.create criticity: :error, message_key: "referential_creation_missing_lines", message_attributes: {referential_name: referential.name}
+
+ if referential.metadatas.all?{|m| m.line_ids.empty? && m.line_ids.empty?}
+ create_message criticity: :error, message_key: "referential_creation_missing_lines", message_attributes: {referential_name: referential.name}
+ elsif (overlapped_referential_ids = referential.overlapped_referential_ids).any?
+ overlapped = Referential.find overlapped_referential_ids.last
+ create_message(
+ criticity: :error,
+ message_key: "referential_creation_overlapping_existing_referential",
+ message_attributes: {
+ referential_name: referential.name,
+ overlapped_name: overlapped.name,
+ overlapped_url: Rails.application.routes.url_helpers.referential_path(overlapped)
+ }
+ )
else
- parent.messages.create criticity: :error, message_key: "referential_creation", message_attributes: {referential_name: referential.name}
+ create_message(
+ criticity: :error,
+ message_key: "referential_creation",
+ message_attributes: {referential_name: referential.name},
+ resource_attributes: referential.errors.messages
+ )
end
- else
- save!
+ self.referential = nil
+ aborted!
end
end
diff --git a/app/models/import/resource.rb b/app/models/import/resource.rb
index 1951daacd..43690755d 100644
--- a/app/models/import/resource.rb
+++ b/app/models/import/resource.rb
@@ -4,5 +4,49 @@ class Import::Resource < ApplicationModel
include IevInterfaces::Resource
belongs_to :import, class_name: Import::Base
+ belongs_to :referential
has_many :messages, class_name: "Import::Message", foreign_key: :resource_id
+
+ scope :main_resources, ->{ where(resource_type: "referential") }
+
+ def root_import
+ import = self.import
+ import = import.parent while import.parent
+ import
+ end
+
+ def next_step
+ if root_import.class == Import::Workbench
+
+ return unless netex_import&.successful?
+
+ workbench.workgroup.import_compliance_control_sets.map do |key, label|
+ next unless (control_set = workbench.compliance_control_set(key)).present?
+ compliance_check_set = workbench_import_check_set key
+ if compliance_check_set.nil?
+ ComplianceControlSetCopyWorker.perform_async control_set.id, referential_id, root_import.class.name, root_import.id
+ end
+ end
+ end
+ end
+
+ def workbench
+ import.workbench
+ end
+
+ def workgroup
+ workbench.workgroup
+ end
+
+ def netex_import
+ return unless self.resource_type == "referential"
+ import.children.where(name: self.reference).last
+ end
+
+ def workbench_import_check_set key
+ return unless referential.present?
+ control_set = referential.workbench.compliance_control_set(key)
+ return unless control_set.present?
+ referential.compliance_check_sets.where(compliance_control_set_id: control_set.id, referential_id: referential_id).last
+ end
end
diff --git a/app/models/import/workbench.rb b/app/models/import/workbench.rb
index 124b9b0d8..95d23fe5b 100644
--- a/app/models/import/workbench.rb
+++ b/app/models/import/workbench.rb
@@ -9,14 +9,18 @@ class Import::Workbench < Import::Base
end
end
+ # def main_resource
+ # @resource ||= resources.find_or_create_by(name: self.name, resource_type: "workbench_import")
+ # end
+
def import_gtfs
update_column :status, 'running'
update_column :started_at, Time.now
- Import::Gtfs.create! parent_id: self.id, workbench: workbench, file: File.new(file.path), name: "Import GTFS", creator: "Web service"
+ Import::Gtfs.create! parent_type: self.class.name, parent_id: self.id, workbench: workbench, file: File.new(file.path), name: "Import GTFS", creator: "Web service"
- update_column :status, 'successful'
- update_column :ended_at, Time.now
+ # update_column :status, 'successful'
+ # update_column :ended_at, Time.now
rescue Exception => e
Rails.logger.error "Error while processing GTFS file: #{e}"
diff --git a/app/models/merge.rb b/app/models/merge.rb
index 2824e1f83..aca2f4d4d 100644
--- a/app/models/merge.rb
+++ b/app/models/merge.rb
@@ -145,12 +145,19 @@ class Merge < ApplicationModel
end
end
+ referential_route_opposite_route_ids = referential.switch do
+ Hash[referential.routes.where('opposite_route_id is not null').pluck(:id, :opposite_route_id)]
+ end
+
referential_routing_constraint_zones_new_ids = {}
new.switch do
+ route_ids_mapping = {}
+
referential_routes.each do |route|
existing_route = new.routes.find_by line_id: route.line_id, checksum: route.checksum
if existing_route
+ route_ids_mapping[route.id] = existing_route.id
existing_route.merge_metadata_from route
else
objectid = Chouette::Route.where(objectid: route.objectid).exists? ? nil : route.objectid
@@ -159,7 +166,7 @@ class Merge < ApplicationModel
objectid: objectid,
# line_id is the same
# all other primary must be changed
- opposite_route_id: nil #FIXME
+ opposite_route_id: nil # merged after
)
new_route = new.routes.build attributes
@@ -179,6 +186,8 @@ class Merge < ApplicationModel
# We need to create StopPoints to known new primary keys
new_route.save!
+ route_ids_mapping[route.id] = new_route.id
+
old_stop_point_ids = route_stop_points.sort_by(&:position).map(&:id)
new_stop_point_ids = new_route.stop_points.sort_by(&:position).map(&:id)
@@ -225,6 +234,20 @@ class Merge < ApplicationModel
end
end
end
+
+ referential_route_opposite_route_ids.each do |route_id, opposite_route_id|
+ new_route_id = route_ids_mapping[route_id]
+ new_opposite_route_id = route_ids_mapping[opposite_route_id]
+
+ new_route = nil
+ if new_route_id && new_opposite_route_id
+ if new_route = new.routes.find_by(id: new_route_id)
+ new_route.update_column :opposite_route_id, new_opposite_route_id
+ end
+ end
+
+ Rails.logger.warn "Can't merge opposite route for Route #{route_id}" unless new_route
+ end
end
# JourneyPatterns
diff --git a/app/models/referential.rb b/app/models/referential.rb
index 792353a73..0c6e71d47 100644
--- a/app/models/referential.rb
+++ b/app/models/referential.rb
@@ -26,6 +26,7 @@ class Referential < ApplicationModel
has_one :user
has_many :api_keys, class_name: 'Api::V1::ApiKey', dependent: :destroy
+ has_many :import_resources, class_name: 'Import::Resource', dependent: :destroy
belongs_to :organisation
validates_presence_of :organisation
@@ -398,7 +399,7 @@ class Referential < ApplicationModel
query = "select distinct(public.referential_metadata.referential_id) FROM public.referential_metadata, unnest(line_ids) line, LATERAL unnest(periodes) period
WHERE public.referential_metadata.referential_id
- IN (SELECT public.referentials.id FROM public.referentials WHERE referentials.workbench_id = #{workbench_id} and referentials.archived_at is null and referentials.referential_suite_id is null #{not_myself})
+ IN (SELECT public.referentials.id FROM public.referentials WHERE referentials.workbench_id = #{workbench_id} and referentials.archived_at is null and referentials.referential_suite_id is null #{not_myself} AND referentials.failed_at IS NULL)
AND line in (#{line_ids.join(',')}) and (#{periods_query});"
self.class.connection.select_values(query).map(&:to_i)
diff --git a/app/models/simple_importer.rb b/app/models/simple_importer.rb
index 4cfe90cff..d47ff6a92 100644
--- a/app/models/simple_importer.rb
+++ b/app/models/simple_importer.rb
@@ -42,8 +42,10 @@ class SimpleImporter < SimpleInterface
end
def dump_csv_from_context
- dir = context[:logs_output_dir] || "log/importers"
- filepath = File.join dir, "#{self.configuration_name}_#{Time.now.strftime "%y%m%d%H%M"}.csv"
+ dir = @output_dir
+ FileUtils.mkdir_p dir
+
+ filepath = File.join dir, "#{self.configuration_name}_#{Time.now.strftime "%y%m%d%H%M"}_dump.csv"
# for some reason, context[:csv].to_csv does not work
CSV.open(filepath, 'w') do |csv|
header = true
@@ -131,14 +133,16 @@ class SimpleImporter < SimpleInterface
@current_attribute = col[:attribute]
val = col[:value]
if val.nil? || val.is_a?(Proc)
- if row.has_key? col.name
- if val.is_a?(Proc)
+ if val.is_a?(Proc)
+ if row.has_key? col.name
val = instance_exec(row[col.name], &val)
else
- val = row[col.name]
+ val = instance_exec(&val)
end
+ elsif row.has_key? col.name
+ val = row[col.name]
else
- push_in_journal({event: :column_not_found, message: "Column not found: #{col.name}", kind: :warning})
+ push_in_journal({event: :column_not_found, message: "Column not found: #{col.name || col.attribute}", kind: :warning})
self.status ||= :success_with_warnings
end
end
diff --git a/app/models/simple_interface.rb b/app/models/simple_interface.rb
index 7b04a07df..d5feafb07 100644
--- a/app/models/simple_interface.rb
+++ b/app/models/simple_interface.rb
@@ -97,13 +97,14 @@ class SimpleInterface < ApplicationModel
def write_output_to_csv
cols = %i(line kind event message error)
- if self.journal.size > 0 && self.journal.first[:row].present?
+ journal = self.journal && self.journal.map(&:symbolize_keys)
+ if journal && journal.size > 0 && journal.first[:row].present?
log "Writing output log"
FileUtils.mkdir_p @output_dir
- keys = self.journal.first[:row].map(&:first)
+ keys = journal.first[:row].map(&:first)
CSV.open(output_filepath, "w") do |csv|
csv << cols + keys
- self.journal.each do |j|
+ journal.each do |j|
csv << cols.map{|c| j[c]} + j[:row].map(&:last)
end
end
diff --git a/app/models/simple_interfaces_group.rb b/app/models/simple_interfaces_group.rb
index 808be6570..1e13bd0b5 100644
--- a/app/models/simple_interfaces_group.rb
+++ b/app/models/simple_interfaces_group.rb
@@ -30,7 +30,9 @@ class SimpleInterfacesGroup
name = "### #{self.name} ###"
centered_name = " " * ([width - name.size, 0].max / 2) + name
- banner = [centered_name, ""]
+ banner = [centered_name]
+ banner << "Output to: #{shared_options[:output_dir]}" if shared_options && shared_options[:output_dir]
+ banner << ""
banner << @interfaces.each_with_index.map do |interface, i|
if interface[:interface].status.present?
SimpleInterface.colorize interface[:name], SimpleInterface.status_color(interface[:interface].status)
diff --git a/app/models/workbench.rb b/app/models/workbench.rb
index 1c54e8904..1bca91c56 100644
--- a/app/models/workbench.rb
+++ b/app/models/workbench.rb
@@ -51,6 +51,20 @@ class Workbench < ApplicationModel
where(name: DEFAULT_WORKBENCH_NAME).last
end
+ # XXX
+ # def import_compliance_control_set
+ # import_compliance_control_set_id && ComplianceControlSet.find(import_compliance_control_set_id)
+ # end
+
+ def compliance_control_set key
+ id = (owner_compliance_control_set_ids || {})[key.to_s]
+ id.present? && ComplianceControlSet.find(id)
+ end
+
+ def compliance_control_set_ids=(compliance_control_set_ids)
+ self.owner_compliance_control_set_ids = (owner_compliance_control_set_ids || {}).merge compliance_control_set_ids
+ end
+
private
def initialize_output
diff --git a/app/models/workgroup.rb b/app/models/workgroup.rb
index 3e8409634..6bb03c7fa 100644
--- a/app/models/workgroup.rb
+++ b/app/models/workgroup.rb
@@ -1,6 +1,7 @@
class Workgroup < ApplicationModel
belongs_to :line_referential
belongs_to :stop_area_referential
+ belongs_to :owner, class_name: "Organisation"
has_many :workbenches
has_many :calendars
@@ -16,6 +17,8 @@ class Workgroup < ApplicationModel
has_many :custom_fields
+ accepts_nested_attributes_for :workbenches
+
def custom_fields_definitions
Hash[*custom_fields.map{|cf| [cf.code, cf]}.flatten]
end
@@ -23,4 +26,35 @@ class Workgroup < ApplicationModel
def has_export? export_name
export_types.include? export_name
end
+
+ def all_compliance_control_sets
+ %i(after_import
+ after_import_by_workgroup
+ before_merge
+ before_merge_by_workgroup
+ after_merge
+ after_merge_by_workgroup
+ automatic_by_workgroup
+ )
+ end
+
+ def compliance_control_sets_by_workgroup
+ compliance_control_sets_labels all_compliance_control_sets.grep(/by_workgroup$/)
+ end
+
+ def compliance_control_sets_by_workbench
+ compliance_control_sets_labels all_compliance_control_sets.grep_v(/by_workgroup$/)
+ end
+
+ def import_compliance_control_sets
+ compliance_control_sets_labels all_compliance_control_sets.grep(/^after_import/)
+ end
+
+ private
+ def compliance_control_sets_labels(keys)
+ keys.inject({}) do |h, k|
+ h[k] = "workgroups.compliance_control_sets.#{k}".t.capitalize
+ h
+ end
+ end
end
diff --git a/app/policies/workbench_policy.rb b/app/policies/workbench_policy.rb
index 7b925e91a..9f2279c38 100644
--- a/app/policies/workbench_policy.rb
+++ b/app/policies/workbench_policy.rb
@@ -6,6 +6,6 @@ class WorkbenchPolicy < ApplicationPolicy
end
def update?
- true
+ user.has_permission?('workbenches.update')
end
end
diff --git a/app/policies/workgroup_policy.rb b/app/policies/workgroup_policy.rb
new file mode 100644
index 000000000..01914bb51
--- /dev/null
+++ b/app/policies/workgroup_policy.rb
@@ -0,0 +1,19 @@
+class WorkgroupPolicy < ApplicationPolicy
+ class Scope < Scope
+ def resolve
+ scope
+ end
+ end
+
+ def create?
+ false
+ end
+
+ def desrtroy?
+ false
+ end
+
+ def update?
+ record.owner == user.organisation
+ end
+end
diff --git a/app/services/referential_consolidated.rb b/app/services/referential_consolidated.rb
new file mode 100644
index 000000000..465eab405
--- /dev/null
+++ b/app/services/referential_consolidated.rb
@@ -0,0 +1,124 @@
+class ReferentialConsolidated
+ attr_reader :params
+
+ def initialize vehicle_journeys, params
+ @vehicle_journeys = vehicle_journeys
+ @params = params
+ end
+
+ def paginated_lines
+ @paginated_lines ||= begin
+ line_ids = @vehicle_journeys.joins(route: :line).pluck('lines.id')
+ lines = Chouette::Line.where(id: line_ids).order(:name)
+ lines.paginate page: params[:page], per_page: params[:per_page] || 10
+ end
+ end
+
+ def lines
+ @lines ||= paginated_lines.to_a.map {|l| Line.new(self, l, @vehicle_journeys, params) }
+ end
+
+ def _should_highlight?
+ return false unless params[:q].present?
+ keys = params[:q].keys - ["stop_areas"]
+ params[:q].values_at(*keys).each do |value|
+ if value.is_a?(Hash)
+ return true if value.values.any?(&:present?)
+ elsif value.is_a?(Array)
+ return true if value.any?(&:present?)
+ else
+ if value.present?
+ return true
+ end
+ end
+ end
+ false
+ end
+
+ def should_highlight?
+ if @should_highlight.nil?
+ @should_highlight = _should_highlight?
+ end
+ @should_highlight
+ end
+
+ class Base
+ extend Forwardable
+ attr_reader :params
+ attr_reader :parent
+ attr_reader :ar_model
+
+ def initialize parent, ar_model, vehicle_journeys, params
+ @parent = parent
+ @ar_model = ar_model
+ @all_vehicle_journeys = vehicle_journeys
+ @params = params
+ end
+
+ def should_highlight?
+ parent.should_highlight?
+ end
+ end
+
+ class Line < Base
+ delegate name: :ar_model
+ delegate id: :ar_model
+
+ def routes
+ @routes ||= begin
+ ar_model.routes.order(:name).map {|r| Route.new(self, r, @all_vehicle_journeys, params) }
+ end
+ end
+ end
+
+ class Route < Base
+ def_delegators :ar_model, :name, :id, :time_tables, :purchase_windows, :stop_area_ids
+
+ def vehicle_journeys
+ @vehicle_journeys ||= begin
+ ar_model.vehicle_journeys.map {|vj| VehicleJourney.new(self, vj, @all_vehicle_journeys, params) }
+ end
+ end
+
+ def highlighted_journeys
+ @all_vehicle_journeys.joins(:journey_pattern).where(route_id: self.id)
+ end
+
+ def highlighted_count
+ highlighted_journeys.count
+ end
+
+ def highlighted?
+ matching_stop_areas = params[:q] && params[:q]["stop_areas"] && (params[:q]["stop_areas"].values & self.stop_area_ids.map(&:to_s)).present?
+ (should_highlight? || matching_stop_areas) && highlighted_journeys.exists?
+ end
+
+ def stop_points
+ @stop_points ||= ar_model.stop_points.map {|sp| StopPoint.new(self, sp, @all_vehicle_journeys, params) }
+ end
+ end
+
+ class VehicleJourney < Base
+ def_delegators :ar_model, :id, :published_journey_name, :journey_pattern, :time_tables, :purchase_windows, :vehicle_journey_at_stops, :time_table_ids, :purchase_window_ids, :route
+
+ def highlighted?
+ should_highlight? && @all_vehicle_journeys.where(id: self.id).exists?
+ end
+
+ def has_purchase_window? purchase_window
+ purchase_window_ids.include?(purchase_window.id)
+ end
+
+ def has_time_table? time_table
+ time_table_ids.include?(time_table.id)
+ end
+ end
+
+ class StopPoint < Base
+ def_delegators :ar_model, :id, :arrival_time, :departure_time, :name, :stop_area, :stop_area_id
+
+ def highlighted?
+ params[:q] && params[:q]["stop_areas"] && params[:q]["stop_areas"].values.any?{|v| v.to_s == stop_area_id.to_s}
+ end
+ end
+end
diff --git a/app/services/route_way_cost_calculator.rb b/app/services/route_way_cost_calculator.rb
index d41a2e59a..ca47a6772 100644
--- a/app/services/route_way_cost_calculator.rb
+++ b/app/services/route_way_cost_calculator.rb
@@ -8,5 +8,7 @@ class RouteWayCostCalculator
way_costs = TomTom.matrix(way_costs)
way_costs = WayCostCollectionJSONSerializer.dump(way_costs)
@route.update(costs: way_costs)
+ rescue TomTom::Errors::MatrixRemoteError => e
+ Rails.logger.error "TomTom::Matrix server error: #{e}"
end
end
diff --git a/app/views/companies/show.html.slim b/app/views/companies/show.html.slim
index 8960b92dd..6335d88da 100644
--- a/app/views/companies/show.html.slim
+++ b/app/views/companies/show.html.slim
@@ -6,7 +6,7 @@
.container-fluid
.row
.col-lg-6.col-md-6.col-sm-12.col-xs-12
- - attributes = { t('id_codif') => @company.try(:objectid).try(:local_id),
+ - attributes = { t('id_codif') => @company.get_objectid.try(:short_id),
Chouette::Company.human_attribute_name(:phone) => @company.phone,
Chouette::Company.human_attribute_name(:email) => @company.email,
Chouette::Company.human_attribute_name(:url) => @company.url }
diff --git a/app/views/compliance_check_sets/show.html.slim b/app/views/compliance_check_sets/show.html.slim
index 4e1a8e2f9..bf4642b21 100644
--- a/app/views/compliance_check_sets/show.html.slim
+++ b/app/views/compliance_check_sets/show.html.slim
@@ -9,6 +9,7 @@
= definition_list( t('metadatas'),
{ I18n.t("compliance_check_sets.show.metadatas.referential") => (@compliance_check_set.referential.nil? ? '' : link_to(@compliance_check_set.referential.name, referential_path(@compliance_check_set.referential)) ),
I18n.t("compliance_check_sets.show.metadatas.referential_type") => 'Jeu de données',
+ I18n.t("compliance_check_sets.show.metadatas.status") => import_status(@compliance_check_set.status, verbose: true),
I18n.t("compliance_check_sets.show.metadatas.compliance_check_set_executed") => link_to(@compliance_check_set.name, executed_workbench_compliance_check_set_path(@compliance_check_set.workbench_id, @compliance_check_set)),
I18n.t("compliance_check_sets.show.metadatas.compliance_control_owner") => @compliance_check_set.organisation.name,
I18n.t("compliance_check_sets.show.metadatas.import") => '' })
diff --git a/app/views/compliance_control_sets/show.html.slim b/app/views/compliance_control_sets/show.html.slim
index 729c1ce43..48c03d7c8 100644
--- a/app/views/compliance_control_sets/show.html.slim
+++ b/app/views/compliance_control_sets/show.html.slim
@@ -15,8 +15,9 @@
= render '/compliance_controls/filters'
/ compliance controls without block
- = render_compliance_control_block
- = render_compliance_controls(@direct_compliance_controls)
+ - unless params[:q].present? && @direct_compliance_controls.nil?
+ = render_compliance_control_block
+ = render_compliance_controls(@direct_compliance_controls)
/ compliance controls with block
- if params[:q] && params[:q][:compliance_control_block_id_eq_any].try(:present?)
diff --git a/app/views/dashboards/_dashboard.html.slim b/app/views/dashboards/_dashboard.html.slim
index ce869ee4a..18105041a 100644
--- a/app/views/dashboards/_dashboard.html.slim
+++ b/app/views/dashboards/_dashboard.html.slim
@@ -6,6 +6,24 @@
h3.panel-title.with_actions
div
= link_to t('dashboards.workbench.title', organisation: workbench.organisation.name), workbench_path(workbench)
+ span.badge.ml-xs = workbench.output.referentials.count if workbench.output.referentials.present?
+
+ div
+ = link_to '', workbench_path(workbench), class: ' fa fa-chevron-right pull-right', title: t('workbenches.index.offers.see')
+
+ - if workbench.output.referentials.present?
+ .list-group
+ - workbench.output.referentials.limit(5).each do |referential|
+ = link_to referential.name, referential_path(referential), class: 'list-group-item'
+ - else
+ .panel-body
+ em.small.text-muted = t('workbenches.index.offers.no_content')
+
+ .panel.panel-default
+ .panel-heading
+ h3.panel-title.with_actions
+ div
+ = link_to t('dashboards.workbench.title', organisation: workbench.organisation.name), workbench_path(workbench)
span.badge.ml-xs = workbench.all_referentials.uniq.count if workbench.all_referentials.present?
div
diff --git a/app/views/devise/invitations/edit.html.slim b/app/views/devise/invitations/edit.html.slim
index 7a22146c0..20c2f15c8 100644
--- a/app/views/devise/invitations/edit.html.slim
+++ b/app/views/devise/invitations/edit.html.slim
@@ -1,6 +1,5 @@
/ PageHeader
-
-- content_for :page_header_title, t('.title')
+- content_for :page_header_title, t('devise.registrations.edit.title')
/ PageContent
.page_content
@@ -16,4 +15,4 @@
= form.input :password, as: :password
= form.input :password_confirmation, as: :password
- = form.button :submit, value: t('devise.invitations.edit.submit_button'), class: 'btn-info btn-default formSubmitr', form: 'invitation_form'
+ = form.button :submit, value: t('actions.submit'), class: 'btn-info btn-default formSubmitr', form: 'invitation_form'
diff --git a/app/views/devise/invitations/new.html.slim b/app/views/devise/invitations/new.html.slim
index 87bfbf750..90f086c2b 100644
--- a/app/views/devise/invitations/new.html.slim
+++ b/app/views/devise/invitations/new.html.slim
@@ -1,10 +1,15 @@
-h2 = t('devise.invitations.new.header')
+- content_for :page_header_title, t('devise.registrations.new.title')
-= simple_form_for resource, as: resource_name, :url => invitation_path(resource_name), :html => {:method => :post, class: "form-horizontal"} do |form|
- = form.input :organisation_id, :as => :hidden, input_html: { :value => current_organisation.id }
+/ PageContent
+.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
+ = simple_form_for resource, as: resource_name, :url => invitation_path(resource_name), :html => {:method => :post, class: "form-horizontal", id: "new_user_form"} do |form|
+ = form.input :organisation_id, :as => :hidden, input_html: { :value => current_organisation.id }
- - resource.class.invite_key_fields.each do |field|
- = form.input field
+ - resource.class.invite_key_fields.each do |field|
+ = form.input field
- .form-actions
- = form.button :submit, value: t('devise.invitations.new.submit_button'), class: 'btn-info' \ No newline at end of file
+ .form-actions
+ = form.button :submit, value: t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'new_user_form' \ No newline at end of file
diff --git a/app/views/import_resources/show.html.slim b/app/views/import_resources/show.html.slim
new file mode 100644
index 000000000..7fd8b4456
--- /dev/null
+++ b/app/views/import_resources/show.html.slim
@@ -0,0 +1,52 @@
+- breadcrumb :import_resource, @import_resource
+
+.page_content.import_messages
+ .container-fluid
+ .row
+ .col-lg-12
+ - metadata = { 'Bilan d\'import' => link_to(@import_resource.root_import.name, workbench_import_path(@import_resource.root_import.workbench, @import_resource.root_import) ),
+ 'Jeu de données associé' => ( @import_resource.referential.present? ? link_to(@import_resource.referential.name, referential_path(@import_resource.referential)) : '-' ) }
+ - metadata = metadata.update({t('.status') => import_status(@import_resource.status, verbose: true) })
+ = definition_list t('metadatas'), metadata
+
+
+ .col-lg-12
+ .error_messages
+ = render 'shared/iev_interfaces/messages', messages: @import_resource.messages
+
+
+ // XXX
+ //- if @import_resource.children.present?
+ - if @import_resource&.netex_import&.resources.present?
+ .col-lg-12
+ h2 = t('.table_title')
+ .col-lg-12
+ = t('.table_explanation')
+ .col-lg-12
+ = table_builder_2 @import_resource.netex_import.resources.where(resource_type: :file),
+ [ \
+ TableBuilderHelper::Column.new( \
+ key: :name, \
+ attribute: 'name', \
+ sortable: false, \
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :status, \
+ attribute: Proc.new { |n| import_resource_status(n.status) }, \
+ sortable: false, \
+ ), \
+ TableBuilderHelper::Column.new( \
+ name: 'Résultat des tests' , \
+ attribute: Proc.new { |n| I18n.t('import_resources.index.metrics', n.metrics.deep_symbolize_keys) }, \
+ sortable: false, \
+ ), \
+ TableBuilderHelper::Column.new( \
+ name: 'Téléchargement' , \
+ attribute: Proc.new { |n| '<i class="fa fa-download" aria-hidden="true"></i>'.html_safe }, \
+ sortable: false, \
+ link_to: lambda do |import_resource| \
+ workbench_import_import_resource_import_messages_path(import_resource.import.workbench, import_resource.import, import_resource, format: 'csv' ) \
+ end \
+ ), \
+ ],
+ cls: 'table has-search'
diff --git a/app/views/imports/import/_gtf.html.slim b/app/views/imports/import/_gtf.html.slim
new file mode 100644
index 000000000..e50b45888
--- /dev/null
+++ b/app/views/imports/import/_gtf.html.slim
@@ -0,0 +1,43 @@
+- breadcrumb :gtfs_import, @workbench, @import
+
+.row
+ .col-lg-6.col-md-6.col-sm-12.col-xs-12
+ - metadata = {t('.status') => import_status(@import.status, verbose: true) }
+ - metadata = metadata.update({t('.referential') => @import.referential ? link_to(@import.referential.name, [@import.referential]) : "-" })
+ = definition_list t('metadatas'), metadata
+
+.col-lg-12
+ .error_messages
+ = render 'shared/iev_interfaces/messages', messages: @import.main_resource.messages
+
+- if @import.resources.any?
+ .col-lg-12
+ = table_builder_2 @import.resources,
+ [ \
+ TableBuilderHelper::Column.new( \
+ name: t('imports.show.referential_name'), \
+ attribute: 'name', \
+ sortable: false, \
+ link_to: lambda do |item| \
+ referential_path(item.referential) if item.referential.present? \
+ end \
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :status, \
+ attribute: Proc.new { |n| import_status(n.status, verbose: true, default_status: :pending) }, \
+ sortable: false, \
+ link_to: lambda do |item| \
+ item.netex_import.present? ? [@import.workbench, item.netex_import] : [@import.workbench, @import, item] \
+ end \
+ )\
+ ],
+ cls: 'table',
+ overhead: [ \
+ {}, \
+ {}, \
+ { \
+ title: I18n.t('imports.show.summary').html_safe, \
+ width: controls.size, \
+ cls: 'overheaded-default colspan="2"' \
+ } \
+ ]
diff --git a/app/views/imports/import/_netex.html.slim b/app/views/imports/import/_netex.html.slim
new file mode 100644
index 000000000..ab0ed20d7
--- /dev/null
+++ b/app/views/imports/import/_netex.html.slim
@@ -0,0 +1,45 @@
+- breadcrumb :netex_import, @workbench, @import
+
+.row
+ .col-lg-6.col-md-6.col-sm-12.col-xs-12
+ - metadata = {Import::Base.tmf(:status) => import_status(@import.status, verbose: true) }
+ - metadata = metadata.update({Import::Base.tmf(:referential) => @import.referential ? link_to(@import.referential.name, [@import.referential]) : "-" })
+ = definition_list t('metadatas'), metadata
+
+.col-lg-12
+ .error_messages
+ = render 'shared/iev_interfaces/messages', messages: @import.main_resource.messages
+
+- if @import.resources.present?
+ .col-lg-12
+ h2 = t('imports.show.netex.table_title')
+ .col-lg-12
+ = t('imports.show.netex.table_explanation')
+ .col-lg-12
+ = table_builder_2 @import.resources.where(resource_type: :file),
+ [ \
+ TableBuilderHelper::Column.new( \
+ key: :name, \
+ attribute: 'name', \
+ sortable: false, \
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :status, \
+ attribute: Proc.new { |n| import_resource_status(n.status) }, \
+ sortable: false, \
+ ), \
+ TableBuilderHelper::Column.new( \
+ name: t('imports.show.table.test_results') , \
+ attribute: Proc.new { |n| I18n.t('import_resources.index.metrics', n.metrics.deep_symbolize_keys) }, \
+ sortable: false, \
+ ), \
+ TableBuilderHelper::Column.new( \
+ name: t('imports.show.table.download') , \
+ attribute: Proc.new { |n| '<i class="fa fa-download" aria-hidden="true"></i>'.html_safe }, \
+ sortable: false, \
+ link_to: lambda do |import_resource| \
+ workbench_import_import_resource_import_messages_path(import_resource.import.workbench, import_resource.import, import_resource, format: 'csv' ) \
+ end \
+ ), \
+ ],
+ cls: 'table has-search'
diff --git a/app/views/imports/import/_workbench.html.slim b/app/views/imports/import/_workbench.html.slim
new file mode 100644
index 000000000..cbdf604c2
--- /dev/null
+++ b/app/views/imports/import/_workbench.html.slim
@@ -0,0 +1,55 @@
+- breadcrumb :import, @workbench, @import
+
+.row
+ .col-lg-6.col-md-6.col-sm-12.col-xs-12
+ - metadata = { t('.data_recovery') => '-', t('imports.show.filename') => @import.try(:file_identifier)}
+ - metadata = metadata.update({Import::Base.tmf(:status) => import_status(@import.status, verbose: true) })
+ = definition_list t('metadatas'), metadata
+
+.col-lg-12
+ .error_messages
+ = render 'shared/iev_interfaces/messages', messages: @import.messages
+
+ruby:
+ controls = @workbench.workgroup.import_compliance_control_sets.map do |key, label|
+ TableBuilderHelper::Column.new(
+ name: label,
+ attribute: Proc.new { |n| n.workbench.compliance_control_set(key).present? ? import_status(n.workbench_import_check_set(key)&.status, verbose: true, default_status: (n.status == "ERROR" ? :aborted : :pending)) : '-' },
+ sortable: false,
+ link_to: lambda do |item|
+ item.workbench_import_check_set(key).present? && [@import.workbench, item.workbench_import_check_set(key)]
+ end
+ )
+ end
+
+- if @import.resources.any?
+ .col-lg-12
+ = table_builder_2 @import.resources,
+ [ \
+ TableBuilderHelper::Column.new( \
+ name: t('imports.show.referential_name'), \
+ attribute: 'name', \
+ sortable: false, \
+ link_to: lambda do |item| \
+ referential_path(item.referential) if item.referential.present? \
+ end \
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :status, \
+ attribute: Proc.new { |n| import_status(n.netex_import&.status || n.status, verbose: true, default_status: :pending) }, \
+ sortable: false, \
+ link_to: lambda do |item| \
+ item.netex_import.present? ? [@import.workbench, item.netex_import] : [@import.workbench, @import, item] \
+ end \
+ ), *controls \
+ ],
+ cls: 'table',
+ overhead: [ \
+ {}, \
+ {}, \
+ controls.present? ? { \
+ title: I18n.t('imports.show.summary').html_safe, \
+ width: controls.size, \
+ cls: "overheaded-default colspan='#{controls.size}'" \
+ } : nil \
+ ].compact
diff --git a/app/views/imports/show.html.slim b/app/views/imports/show.html.slim
index 9d0a6423d..fb83e9a06 100644
--- a/app/views/imports/show.html.slim
+++ b/app/views/imports/show.html.slim
@@ -1,60 +1,5 @@
-- breadcrumb :import, @workbench, @import
-
- page_header_content_for @import
.page_content
.container-fluid
- .row
- .col-lg-6.col-md-6.col-sm-12.col-xs-12
- = definition_list t('metadatas'), { t('.data_recovery') => '-', t('.filename') => @import.try(:file_identifier)}
-
- .row
- .col-lg-12
- .error_messages
- = render 'shared/iev_interfaces/messages', messages: @import.messages
-
- - if @import.children.any?
- .row
- .col-lg-12
- = table_builder_2 @import.children,
- [ \
- TableBuilderHelper::Column.new( \
- name: t('.referential_name'), \
- attribute: 'name', \
- sortable: false, \
- link_to: lambda do |import| \
- referential_path(import.referential) if import.referential.present? \
- end \
- ), \
- TableBuilderHelper::Column.new( \
- key: :status, \
- attribute: Proc.new { |n| import_status(n.status) }, \
- sortable: false, \
- link_to: lambda do |import| \
- workbench_import_import_resources_path(import.workbench_id, import) \
- end \
- ), \
- TableBuilderHelper::Column.new( \
- name: t('.stif_control'), \
- attribute: '', \
- sortable: false, \
- ), \
- TableBuilderHelper::Column.new( \
- name: t('.organisation_control'), \
- attribute: '', \
- sortable: false, \
- ) \
- ],
- cls: 'table',
- overhead: [ \
- {}, \
- { \
- title: I18n.t('imports.show.results', count: @import.children_succeedeed, total: @import.children.count), \
- width: 1, \
- cls: "#{@import.import_status_css_class} full-border" \
- }, { \
- title: I18n.t('imports.show.summary').html_safe, \
- width: 2, \
- cls: 'overheaded-default colspan="2"' \
- } \
- ]
+ = render partial: "imports/#{@import.type.tableize.singularize}"
diff --git a/app/views/layouts/navigation/_main_nav_left_content.html.slim b/app/views/layouts/navigation/_main_nav_left_content.html.slim
index 0b55578a7..547c6fae7 100644
--- a/app/views/layouts/navigation/_main_nav_left_content.html.slim
+++ b/app/views/layouts/navigation/_main_nav_left_content.html.slim
@@ -2,63 +2,54 @@
- current_organisation.workbenches.each do |workbench|
#menu-items.panel-group
.menu-item.panel
- .panel-heading
- h4.panel-title
- = link_to '#miOne', data: {toggle: 'collapse', parent: '#menu-items'}, 'aria-expanded' => 'false' do
- = t('layouts.navbar.current_offer.other')
-
- #miOne.panel-collapse.collapse
- .list-group
- = link_to root_path, class: "list-group-item" do
- span = t('layouts.navbar.dashboard')
- = link_to workbench_output_path(workbench), class: 'list-group-item' do
- span = t('layouts.navbar.workbench_outputs.organisation')
- = link_to '#', class: 'list-group-item disabled' do
- span = t('layouts.navbar.workbench_outputs.workgroup')
+ = main_nav_menu_item 'layouts.navbar.current_offer.other'.t do
+ = link_to root_path, class: "list-group-item" do
+ span = 'layouts.navbar.dashboard'.t
+ = link_to workbench_output_path(workbench), class: 'list-group-item' do
+ span = 'layouts.navbar.workbench_outputs.organisation'.t
+ = link_to '#', class: 'list-group-item disabled' do
+ span = 'layouts.navbar.workbench_outputs.workgroup'.t
+ - if policy(workbench.workgroup).edit?
+ = link_to [:edit, workbench.workgroup], class: 'list-group-item' do
+ span = 'layouts.navbar.workbench_outputs.edit_workgroup'.t
.menu-item.panel
- .panel-heading
- h4.panel-title
- = link_to '#miTwo', data: {toggle: 'collapse', parent: '#menu-items'}, 'aria-expanded' => 'false' do
- - t('activerecord.models.workbench.one').capitalize
+ = main_nav_menu_item 'activerecord.models.workbench.one'.t.capitalize do
+ = link_to workbench_path(workbench), class: "list-group-item" do
+ span = 'activerecord.models.referential.other'.t.capitalize
+ = link_to workbench_imports_path(workbench), class: "list-group-item" do
+ span = 'activerecord.models.import.other'.t.capitalize
+ = link_to workbench_exports_path(workbench), class: "list-group-item" do
+ span = 'activerecord.models.export.other'.t.capitalize
+ = link_to workgroup_calendars_path(workbench.workgroup), class: 'list-group-item' do
+ span = 'activerecord.models.calendar.other'.t.capitalize
+ = link_to workbench_compliance_check_sets_path(workbench), class: 'list-group-item' do
+ span = 'activerecord.models.compliance_check_set.other'.t.capitalize
+ = link_to compliance_control_sets_path, class: 'list-group-item' do
+ span = 'activerecord.models.compliance_control_set.other'.t.capitalize
+ - if policy(workbench).edit?
+ = link_to [:edit, workbench], class: 'list-group-item' do
+ span = 'workbenches.edit.link'.t
- #miTwo.panel-collapse.collapse
- .list-group
- = link_to workbench_path(workbench), class: "list-group-item" do
- span = t('activerecord.models.referential.other').capitalize
- = link_to workbench_imports_path(workbench), class: "list-group-item" do
- span = t('activerecord.models.import.other').capitalize
- = link_to workbench_exports_path(workbench), class: "list-group-item" do
- span = t('activerecord.models.export.other').capitalize
- = link_to workgroup_calendars_path(workbench.workgroup), class: 'list-group-item' do
- span = t('activerecord.models.calendar.other').capitalize
- = link_to workbench_compliance_check_sets_path(workbench), class: 'list-group-item' do
- span = t('activerecord.models.compliance_check_set.other').capitalize
- = link_to compliance_control_sets_path, class: 'list-group-item' do
- span = t('activerecord.models.compliance_control_set.other').capitalize
-
.menu-item.panel
- .panel-heading
- h4.panel-title
- = link_to '#miFour', data: {toggle: 'collapse', parent: '#menu-items'}, 'aria-expanded' => 'false' do
- = t('layouts.navbar.line_referential')
-
- #miFour.panel-collapse.collapse
- .list-group
- = link_to line_referential_lines_path(workbench.line_referential), class: "list-group-item" do
- span = Chouette::Line.t.capitalize
- = link_to line_referential_networks_path(workbench.line_referential), class: "list-group-item" do
- span = Chouette::Network.t.capitalize
- = link_to line_referential_companies_path(workbench.line_referential), class: "list-group-item" do
- span = Chouette::Company.t.capitalize
+ = main_nav_menu_item 'layouts.navbar.line_referential'.t do
+ = link_to line_referential_lines_path(workbench.line_referential), class: "list-group-item" do
+ span = Chouette::Line.t.capitalize
+ = link_to line_referential_networks_path(workbench.line_referential), class: "list-group-item" do
+ span = Chouette::Network.t.capitalize
+ = link_to line_referential_companies_path(workbench.line_referential), class: "list-group-item" do
+ span = Chouette::Company.t.capitalize
.menu-item.panel
- .panel-heading
- h4.panel-title
- = link_to '#miFive', data: {toggle: 'collapse', parent: '#menu-items'}, 'aria-expanded' => 'false' do
- = t('layouts.navbar.stop_area_referential')
+ = main_nav_menu_item 'layouts.navbar.stop_area_referential'.t do
+ = link_to stop_area_referential_stop_areas_path(workbench.stop_area_referential), class: "list-group-item" do
+ span = Chouette::StopArea.t.capitalize
- #miFive.panel-collapse.collapse
- .list-group
- = link_to stop_area_referential_stop_areas_path(workbench.stop_area_referential), class: "list-group-item" do
- span = Chouette::StopArea.t.capitalize
+ .menu-item.panel
+ = main_nav_menu_item 'layouts.navbar.configuration'.t do
+ - if policy(workbench).edit?
+ = link_to [:edit, workbench], class: 'list-group-item' do
+ span = 'layouts.navbar.workbench_configuration'.t
+ - if policy(workbench.workgroup).edit?
+ = link_to [:edit, workbench.workgroup], class: 'list-group-item' do
+ span = 'layouts.navbar.workgroup_configuration'.t
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 9404eeae6..950c23580 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
@@ -1,95 +1,68 @@
- current_organisation.workbenches.each do |workbench|
#menu-items.panel-group
- .menu-item.panel
- .panel-heading
- h4.panel-title
- = link_to '#miOne', data: {toggle: 'collapse', parent: '#menu-items'}, 'aria-expanded' => 'false' do
- = t('layouts.navbar.current_offer.other')
+ = main_nav_menu_item 'layouts.navbar.current_offer.other'.t do
+ = link_to root_path, class: "list-group-item" do
+ span = t('layouts.navbar.dashboard')
+ = link_to workbench_output_path(workbench), class: 'list-group-item' do
+ span = t('layouts.navbar.workbench_outputs.organisation')
+ = link_to '#', class: 'list-group-item disabled' do
+ span = t('layouts.navbar.workbench_outputs.workgroup')
- #miOne.panel-collapse.collapse
- .list-group
- = link_to root_path, class: "list-group-item" do
- span = t('layouts.navbar.dashboard')
- = link_to workbench_output_path(workbench), class: 'list-group-item' do
- span = t('layouts.navbar.workbench_outputs.organisation')
- = link_to '#', class: 'list-group-item disabled' do
- span = t('layouts.navbar.workbench_outputs.workgroup')
+ = main_nav_menu_item 'activerecord.models.workbench.one'.t.capitalize do
+ = link_to workbench_path(workbench), class: "list-group-item" do
+ span = t('activerecord.models.referential.other').capitalize
+ = link_to workbench_imports_path(workbench), class: "list-group-item" do
+ span = t('activerecord.models.import.other').capitalize
+ = link_to workbench_exports_path(workbench), class: "list-group-item" do
+ span = t('activerecord.models.export.other').capitalize
+ = link_to workgroup_calendars_path(workbench.workgroup), class: 'list-group-item' do
+ span = t('activerecord.models.calendar.other').capitalize
+ = link_to workbench_compliance_check_sets_path(workbench), class: 'list-group-item' do
+ span = t('activerecord.models.compliance_check_set.other').capitalize
+ = link_to compliance_control_sets_path, class: 'list-group-item' do
+ span = t('activerecord.models.compliance_control_set.other').capitalize
- .menu-item.panel
- .panel-heading
- h4.panel-title
- = link_to '#miTwo', data: {toggle: 'collapse', parent: '#menu-items'}, 'aria-expanded' => 'false' do
- - t('activerecord.models.workbench.one').capitalize
+ = main_nav_menu_item 'layouts.navbar.line_referential'.t do
+ = link_to line_referential_path(workbench.line_referential), class: "list-group-item" do
+ span = t('layouts.navbar.sync_ilico')
+ = link_to line_referential_lines_path(workbench.line_referential), class: "list-group-item" do
+ span = Chouette::Line.t.capitalize
+ = link_to line_referential_networks_path(workbench.line_referential), class: "list-group-item" do
+ span = Chouette::Network.t.capitalize
+ = link_to line_referential_companies_path(workbench.line_referential), class: "list-group-item" do
+ span = Chouette::Company.t.capitalize
- #miTwo.panel-collapse.collapse
- .list-group
- = link_to workbench_path(workbench), class: "list-group-item" do
- span = t('activerecord.models.referential.other').capitalize
- = link_to workbench_imports_path(workbench), class: "list-group-item" do
- span = t('activerecord.models.import.other').capitalize
- = link_to workbench_exports_path(workbench), class: "list-group-item" do
- span = t('activerecord.models.export.other').capitalize
- = link_to workgroup_calendars_path(workbench.workgroup), class: 'list-group-item' do
- span = t('activerecord.models.calendar.other').capitalize
- = link_to workbench_compliance_check_sets_path(workbench), class: 'list-group-item' do
- span = t('activerecord.models.compliance_check_set.other').capitalize
- = link_to compliance_control_sets_path, class: 'list-group-item' do
- span = t('activerecord.models.compliance_control_set.other').capitalize
+ = main_nav_menu_item 'layouts.navbar.stop_area_referential'.t do
+ = link_to stop_area_referential_path(workbench.stop_area_referential), class: "list-group-item" do
+ span = t('layouts.navbar.sync_icar')
+ = link_to stop_area_referential_stop_areas_path(workbench.stop_area_referential), class: "list-group-item" do
+ span = Chouette::StopArea.t.capitalize
- .menu-item.panel
- .panel-heading
- h4.panel-title
- = link_to '#miFour', data: {toggle: 'collapse', parent: '#menu-items'}, 'aria-expanded' => 'false' do
- = t('layouts.navbar.line_referential')
+ = main_nav_menu_item 'layouts.navbar.configuration'.t do
+ - if policy(workbench).edit?
+ = link_to [:edit, workbench], class: 'list-group-item' do
+ span = t('layouts.navbar.workbench_configuration')
+ - if policy(workbench.workgroup).edit?
+ = link_to [:edit, workbench.workgroup], class: 'list-group-item' do
+ span = t('layouts.navbar.workgroup_configuration')
- #miFour.panel-collapse.collapse
- .list-group
- = link_to line_referential_path(workbench.line_referential), class: "list-group-item" do
- span = t('layouts.navbar.sync_ilico')
- = link_to line_referential_lines_path(workbench.line_referential), class: "list-group-item" do
- span = Chouette::Line.t.capitalize
- = link_to line_referential_networks_path(workbench.line_referential), class: "list-group-item" do
- span = Chouette::Network.t.capitalize
- = link_to line_referential_companies_path(workbench.line_referential), class: "list-group-item" do
- span = Chouette::Company.t.capitalize
-
- .menu-item.panel
- .panel-heading
- h4.panel-title
- = link_to '#miFive', data: {toggle: 'collapse', parent: '#menu-items'}, 'aria-expanded' => 'false' do
- = t('layouts.navbar.stop_area_referential')
-
- #miFive.panel-collapse.collapse
- .list-group
- = link_to stop_area_referential_path(workbench.stop_area_referential), class: "list-group-item" do
- span = t('layouts.navbar.sync_icar')
- = link_to stop_area_referential_stop_areas_path(workbench.stop_area_referential), class: "list-group-item" do
- span = Chouette::StopArea.t.capitalize
-
- .menu-item.panel
- .panel-heading
- h4.panel-title
- = link_to '#miSix', data: {toggle: 'collapse', parent: '#menu-items'}, 'aria-expanded' => 'false' do
- = t('layouts.navbar.tools')
-
- #miSix.panel-collapse.collapse
- .list-group
- = link_to Rails.application.config.try(:portal_url), target: '_blank', class: 'list-group-item' do
- span
- span.fa.fa-2x.fa-circle
- = t('layouts.navbar.portal')
-
- = link_to Rails.application.config.try(:codifligne_url), target: '_blank', class: 'list-group-item' do
- span
- span.fa.fa-2x.fa-circle
- = t('layouts.navbar.ilico')
-
- = link_to Rails.application.config.try(:reflex_url), target: '_blank', class: 'list-group-item' do
- span
- span.fa.fa-2x.fa-circle
- = t('layouts.navbar.icar')
-
- = link_to '#', target: '_blank', class: 'list-group-item' do
- span
- span.fa.fa-2x.fa-circle
- = t('layouts.navbar.support')
+ = main_nav_menu_item 'layouts.navbar.tools'.t do
+ = link_to Rails.application.config.try(:portal_url), target: '_blank', class: 'list-group-item' do
+ span
+ span.fa.fa-2x.fa-circle
+ = t('layouts.navbar.portal')
+
+ = link_to Rails.application.config.try(:codifligne_url), target: '_blank', class: 'list-group-item' do
+ span
+ span.fa.fa-2x.fa-circle
+ = t('layouts.navbar.ilico')
+
+ = link_to Rails.application.config.try(:reflex_url), target: '_blank', class: 'list-group-item' do
+ span
+ span.fa.fa-2x.fa-circle
+ = t('layouts.navbar.icar')
+
+ = link_to '#', target: '_blank', class: 'list-group-item' do
+ span
+ span.fa.fa-2x.fa-circle
+ = t('layouts.navbar.support')
diff --git a/app/views/lines/_form.html.slim b/app/views/lines/_form.html.slim
index 909d6512e..4623abf8a 100644
--- a/app/views/lines/_form.html.slim
+++ b/app/views/lines/_form.html.slim
@@ -4,7 +4,7 @@
= f.input :name
= f.input :network_id, as: :select, :collection => @line_referential.networks, include_blank: false
= f.input :company_id, as: :select, :collection => @line_referential.companies, include_blank: true
- = f.input :secondary_company_ids, :collection => @line_referential.companies, include_blank: false, input_html: { multiple: true, 'data-select2ed': true }, label: t('activerecord.attributes.line.secondary_company')
+ = f.input :secondary_company_ids, :collection => @line_referential.companies, include_blank: false, input_html: { multiple: true, 'data-select2ed': true }, label: Chouette::Line.tmf(:secondary_companies)
= f.input :published_name
= f.input :registration_number
= f.input :number
diff --git a/app/views/referential_stop_areas/show.html.slim b/app/views/referential_stop_areas/show.html.slim
index beee0383f..06096bbaa 100644
--- a/app/views/referential_stop_areas/show.html.slim
+++ b/app/views/referential_stop_areas/show.html.slim
@@ -7,7 +7,7 @@
.col-lg-6.col-md-6.col-sm-12.col-xs-12
= definition_list t('metadatas'),
{ t('id_reflex') => @stop_area.try(:user_objectid),
- Chouette::StopArea.tmf(:status) => stop_area_status(@stop_area),
+ Chouette::StopArea.tmf(:status) => stop_area_status(@stop_area.status),
Chouette::StopArea.tmf(:comment) => @stop_area.try(:comment),
Chouette::StopArea.tmf(:stop_area_type) => t("area_types.label.#{@stop_area.stop_area_type}"),
Chouette::StopArea.tmf(:registration_number) => @stop_area.registration_number,
diff --git a/app/views/referential_vehicle_journeys/_consolidated.html.slim b/app/views/referential_vehicle_journeys/_consolidated.html.slim
new file mode 100644
index 000000000..4a1866e8a
--- /dev/null
+++ b/app/views/referential_vehicle_journeys/_consolidated.html.slim
@@ -0,0 +1,49 @@
+.row.consolidated-view
+ - @consolidated.lines.each do |line|
+ = render partial: "consolidated_line", object: line
+ .col-md-12
+ = new_pagination @consolidated.paginated_lines, 'pull-right'
+
+coffee:
+ $('a.toggle-timetables').click (e)->
+ e.preventDefault()
+ $(e.target).toggleClass 'active'
+ $(e.target).parents('.table').find('.detailed-timetables').customToggle()
+
+ $('a.toggle-purchase-windows').click (e)->
+ e.preventDefault()
+ $(e.target).toggleClass 'active'
+ $(e.target).parents('.table').find('.detailed-purchase-windows').customToggle()
+
+ $('.route').find('.togglable.hidden').each (i, e)->
+ $e = $(e)
+ $e.removeClass 'hidden'
+ e.setAttribute 'data-original-height', $e.innerHeight()
+ e.setAttribute 'data-original-full-height', $e.outerHeight(true)
+ $e.css height: 0
+ $e.addClass 'ready'
+
+ $('a.toggle-route').click (e)->
+ e.preventDefault()
+ $(e.currentTarget).toggleClass 'active'
+ tab = $(e.currentTarget).parents('.route').find('.vehicle-journeys')
+ tab.customToggle()
+
+ $.fn.extend
+ customToggle: (propagate=true)->
+ height = parseFloat this.attr('data-original-height')
+ fullHeight = parseFloat this.attr('data-original-full-height')
+ if this.hasClass 'open'
+ this.css height: 0
+ this.removeClass 'open'
+ this.find('.togglable.open').customToggle(false)
+ this.find('a.active').removeClass 'active'
+ if propagate
+ for parent in this.parents(".togglable.open")
+ $(parent).height $(parent).height() - fullHeight
+ else
+ this.addClass 'open'
+ this.height height
+ if propagate
+ for parent in this.parents(".togglable.open")
+ $(parent).height $(parent).height() + fullHeight
diff --git a/app/views/referential_vehicle_journeys/_consolidated_line.html.slim b/app/views/referential_vehicle_journeys/_consolidated_line.html.slim
new file mode 100644
index 000000000..c73c65961
--- /dev/null
+++ b/app/views/referential_vehicle_journeys/_consolidated_line.html.slim
@@ -0,0 +1,119 @@
+.line.col-md-12
+ .head
+ span
+ = Chouette::Line.ts
+ | &nbsp;
+ strong= consolidated_line.name
+ .routes
+ - consolidated_line.routes.each do |route|
+ .route
+ .head class="#{route.highlighted? ? 'highlighted' : ''}"
+ = link_to '#', class: 'toggle-route' do
+ span.sb.sb-route
+ | &nbsp;
+ = Chouette::Route.ts
+ | &nbsp;
+ strong= route.name
+ .pull-right
+ = route.highlighted_count
+ | &nbsp;
+ = Chouette::VehicleJourney.t
+ | &nbsp;
+ span.fa.fa-angle-up
+ .table.table-2entries.vehicle-journeys.hidden.togglable
+ .t2e-head.w20
+ .th
+ div
+ strong= Chouette::VehicleJourney.tmf(:id)
+ div= Chouette::VehicleJourney.tmf(:name)
+ div= Chouette::VehicleJourney.tmf(:journey_pattern_id)
+ div
+ = link_to '#', class: 'toggle-purchase-windows detailed-timetables-bt' do
+ span.fa.fa-angle-up
+ = Chouette::PurchaseWindow.t
+ .detailed-purchase-windows.hidden.togglable
+ - route.purchase_windows.uniq.each do |tt|
+ div
+ p
+ = link_to [@referential, tt] do
+ span.fa.fa-calendar style={color: (tt.color ? tt.color : '#4B4B4B')}
+ | &nbsp;
+ = tt.name
+
+ p= tt.bounding_dates.split(' ').join(' > ')
+ div
+ = link_to '#', class: 'toggle-timetables detailed-timetables-bt' do
+ span.fa.fa-angle-up
+ = Chouette::TimeTable.t
+
+ .detailed-timetables.hidden.togglable
+ - route.time_tables.uniq.each do |tt|
+ div
+ p
+ = link_to [@referential, tt] do
+ span.fa.fa-calendar style={color: (tt.color ? tt.color : '#4B4B4B')}
+ | &nbsp;
+ = tt.display_day_types
+
+ p= tt.bounding_dates.split(' ').join(' > ')
+ - prev_sp = nil
+ - route.stop_points.each do |sp|
+ ruby:
+ headline = vehicle_journey_stop_headline prev_sp, sp
+ prev_sp = sp
+ .td class="#{sp.highlighted? ? 'highlighted' : ''}"
+ div title="#{sp.stop_area.city_name ? "#{sp.stop_area.city_name} (#{sp.stop_area.zip_code})" : ''}" data-headline=headline class=(headline.present? ? 'headlined' : '')
+ span
+ = sp.name
+ - if sp.stop_area.time_zone_formatted_offset
+ span.small
+ | &nbsp;
+ = "(#{sp.stop_area.time_zone_formatted_offset})"
+ .t2e-item-list.w80
+ div
+ - route.vehicle_journeys.each do |journey|
+ .t2e-item class="#{journey.highlighted? ? 'highlighted' : ''}"
+ .th
+ div
+ strong= link_to journey.id, [@referential, journey.route.line, journey.route, :vehicle_journeys]
+ div
+ = link_to journey.published_journey_name, [@referential, journey.route.line, journey.route, :vehicle_journeys], title: journey.published_journey_name
+ div= journey.journey_pattern.get_objectid.short_id
+ div
+ - journey.purchase_windows[0..3].each do |tt|
+ span.vj_tt
+ = link_to [@referential, tt], target: :blank do
+ span.fa.fa-calendar style="color: #{tt.color ? tt.color : '#4B4B4B'}"
+ - if journey.purchase_windows.size > 3
+ span.vj_tt = "+ #{journey.purchase_windows.size - 3}"
+ .detailed-purchase-windows.hidden.togglable
+ - route.purchase_windows.uniq.each do |tt|
+ div class=(journey.has_purchase_window?(tt) ? 'active' : 'inactive')
+ div
+ - journey.time_tables[0..3].each do |tt|
+ span.vj_tt
+ = link_to [@referential, tt], target: :blank do
+ span.fa.fa-calendar style="color: #{tt.color ? tt.color : '#4B4B4B'}"
+ - if journey.time_tables.size > 3
+ span.vj_tt = "+ #{journey.time_tables.size - 3}"
+ .detailed-timetables.hidden.togglable
+ - route.time_tables.uniq.each do |tt|
+ div class=(journey.has_time_table?(tt) ? 'active' : 'inactive')
+
+ - prev_sp = nil
+ - route.stop_points.each do |sp|
+ ruby:
+ headline = vehicle_journey_stop_headline prev_sp, sp
+ prev_sp = sp
+ vjas = journey.vehicle_journey_at_stops.where(stop_point_id: sp.id).last
+ .td class="#{vjas && sp.highlighted? ? 'highlighted' : ''} #{vjas.nil? ? 'disabled' : ''} #{headline.present? ? 'headlined' : ''}"
+ div title="#{sp.stop_area.city_name ? "#{sp.stop_area.city_name} (#{sp.stop_area.zip_code})" : ''}" data-headline=headline class=(headline.present? ? 'headlined' : '')
+ - if vjas.present?
+ - if vjas.departure_time == vjas.arrival_time
+ = vjas.departure_time.l(format: "%H:%M")
+ - else
+ = vjas.arrival_time.l(format: "%H:%M")
+ | &nbsp;-&nbsp;
+ = vjas.departure_time.l(format: "%H:%M")
+ - else
+ | 00:00
diff --git a/app/views/referential_vehicle_journeys/_filters.html.slim b/app/views/referential_vehicle_journeys/_filters.html.slim
index a6e289b97..31053c5ba 100644
--- a/app/views/referential_vehicle_journeys/_filters.html.slim
+++ b/app/views/referential_vehicle_journeys/_filters.html.slim
@@ -1,10 +1,20 @@
= search_form_for @q, url: referential_vehicle_journeys_path(@referential), html: {method: :get}, class: 'form form-filter' do |f|
- .ffg-row
+ input type="hidden" name="display" value=params[:display]
+ .ffg-row.w85
.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
+ .ffg-row.w15
+ - if has_feature?(:consolidated_offers)
+ .form-group
+ .btn-group
+ = link_to referential_vehicle_journeys_path(@referential, q: params[:q], display: :list), class: 'btn btn-default ' + (params[:display] != "consolidated" ? 'active' : '') do
+ span.fa.fa-align-justify
+ = link_to referential_vehicle_journeys_path(@referential, q: params[:q], display: :consolidated), class: 'btn btn-default ' + (params[:display] == "consolidated" ? 'active' : '') do
+ span.fa.fa-th-large
+
.ffg-row
.form-group.per-page-select
= I18n.t("simple_form.per_page")
@@ -73,5 +83,5 @@
.actions
- = link_to t('actions.erase'), referential_vehicle_journeys_path(@referential), class: 'btn btn-link'
+ = link_to t('actions.erase'), referential_vehicle_journeys_path(@referential, display: params[:display]), class: 'btn btn-link'
= f.submit t('actions.filter'), class: 'btn btn-default'
diff --git a/app/views/referential_vehicle_journeys/_list.html.slim b/app/views/referential_vehicle_journeys/_list.html.slim
new file mode 100644
index 000000000..74f8238f8
--- /dev/null
+++ b/app/views/referential_vehicle_journeys/_list.html.slim
@@ -0,0 +1,49 @@
+.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| \
+ vehicle_journey.published_journey_name ? referential_line_route_vehicle_journeys_path(@referential, vehicle_journey.route.line, vehicle_journey.route) : '' \
+ end, \
+ sortable: true \
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :line, \
+ attribute: Proc.new {|v| v.route.line.name}, \
+ sortable: true \
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :route, \
+ attribute: Proc.new {|v| v.route.name}, \
+ sortable: true \
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :departure_time, \
+ attribute: Proc.new {|v| v.vehicle_journey_at_stops.first&.departure_local }, \
+ sortable: true \
+ ), \
+ [@starting_stop, @ending_stop].compact.map{|stop| \
+ TableBuilderHelper::Column.new( \
+ attribute: Proc.new {|v| v.vehicle_journey_at_stops.where("stop_points.stop_area_id" => stop.id).last&.arrival_local }, \
+ sortable: false, \
+ name: stop.name \
+ )\
+ }, \
+ TableBuilderHelper::Column.new( \
+ key: :arrival_time, \
+ attribute: Proc.new {|v| v.vehicle_journey_at_stops.last&.arrival_local }, \
+ sortable: true, \
+ ), \
+ ].flatten.compact,
+ cls: 'table has-filter has-search'
+
+ = new_pagination @vehicle_journeys, 'pull-right'
diff --git a/app/views/referential_vehicle_journeys/index.html.slim b/app/views/referential_vehicle_journeys/index.html.slim
index 00f63cb65..d1d1dae07 100644
--- a/app/views/referential_vehicle_journeys/index.html.slim
+++ b/app/views/referential_vehicle_journeys/index.html.slim
@@ -9,55 +9,11 @@
= 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| \
- vehicle_journey.published_journey_name ? referential_line_route_vehicle_journeys_path(@referential, vehicle_journey.route.line, vehicle_journey.route) : '' \
- end, \
- sortable: true \
- ), \
- TableBuilderHelper::Column.new( \
- key: :line, \
- attribute: Proc.new {|v| v.route.line.name}, \
- sortable: true \
- ), \
- TableBuilderHelper::Column.new( \
- key: :route, \
- attribute: Proc.new {|v| v.route.name}, \
- sortable: true \
- ), \
- TableBuilderHelper::Column.new( \
- key: :departure_time, \
- attribute: Proc.new {|v| v.vehicle_journey_at_stops.first&.departure_local }, \
- sortable: true \
- ), \
- [@starting_stop, @ending_stop].compact.map{|stop| \
- TableBuilderHelper::Column.new( \
- attribute: Proc.new {|v| v.vehicle_journey_at_stops.where("stop_points.stop_area_id" => stop.id).last&.arrival_local }, \
- sortable: false, \
- name: stop.name \
- )\
- }, \
- TableBuilderHelper::Column.new( \
- key: :arrival_time, \
- attribute: Proc.new {|v| v.vehicle_journey_at_stops.last&.arrival_local }, \
- sortable: true, \
- ), \
- ].flatten.compact,
- cls: 'table has-filter has-search'
+ - if params[:display] == "consolidated" && has_feature?(:consolidated_offers)
+ = render partial: "consolidated"
+ - else
+ = render partial: "list"
- = new_pagination @vehicle_journeys, 'pull-right'
- unless @vehicle_journeys.any?
.row.mt-xs
diff --git a/app/views/referentials/_filters.html.slim b/app/views/referentials/_filters.html.slim
index 36db5bfb5..ebaefb0f2 100644
--- a/app/views/referentials/_filters.html.slim
+++ b/app/views/referentials/_filters.html.slim
@@ -14,12 +14,12 @@
- if (network_ids = @referential.lines.pluck(:network_id).uniq.compact).size > 1
.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: network_ids, as: :check_boxes, label: false, label_method: lambda{|l| ("<span>#{LineReferential.first.networks.find(l).name}</span>").html_safe}, required: false, wrapper_html: { class: 'checkbox_list' }
+ = f.input :network_id_eq_any, collection: network_ids, as: :check_boxes, label: false, label_method: lambda{|l| ("<span>#{Chouette::Network.find(l).name}</span>").html_safe}, required: false, wrapper_html: { class: 'checkbox_list' }
- if (company_ids = @referential.lines.pluck(:company_id).uniq.compact).size > 1
.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: company_ids, as: :check_boxes, label: false, label_method: lambda{|l| ("<span>#{LineReferential.first.companies.find(l).name}</span>").html_safe}, required: false, wrapper_html: { class: 'checkbox_list' }
+ = f.input :company_id_eq_any, collection: company_ids, as: :check_boxes, label: false, label_method: lambda{|l| ("<span>#{Chouette::Company.find(l).name}</span>").html_safe}, required: false, wrapper_html: { class: 'checkbox_list' }
.actions
= link_to t('actions.erase'), @workbench, class: 'btn btn-link'
diff --git a/app/views/routes/show.html.slim b/app/views/routes/show.html.slim
index aea824a89..615913faa 100644
--- a/app/views/routes/show.html.slim
+++ b/app/views/routes/show.html.slim
@@ -30,13 +30,13 @@
key: :name, \
attribute: Proc.new { |s| content_tag :span, s.stop_area&.name, class: s.stop_area&.area_type }, \
link_to: lambda do |stop_point| \
- referential_stop_area_path(@referential, stop_point.stop_area) \
+ stop_area_referential_stop_area_path(stop_point.stop_area.referential, stop_point.stop_area) \
end \
), \
TableBuilderHelper::Column.new( \
key: :status, \
name: Chouette::StopArea.tmf('status'), \
- attribute: Proc.new { |s| stop_area_status(s.try(:stop_area)) } \
+ attribute: Proc.new { |s| stop_area_status(s.try(:stop_area).try(:status) ) } \
), \
TableBuilderHelper::Column.new( \
key: :zip_code, \
diff --git a/app/views/routing_constraint_zones/index.html.slim b/app/views/routing_constraint_zones/index.html.slim
index 7e9fb12a3..a804de449 100644
--- a/app/views/routing_constraint_zones/index.html.slim
+++ b/app/views/routing_constraint_zones/index.html.slim
@@ -14,7 +14,7 @@
[ \
TableBuilderHelper::Column.new( \
name: t('objectid'), \
- attribute: Proc.new { |n| n.get_objectid.local_id }, \
+ attribute: Proc.new { |n| n.get_objectid.short_id }, \
sortable: false \
), \
TableBuilderHelper::Column.new( \
@@ -39,6 +39,8 @@
],
links: [:show],
cls: 'table has-filter has-search'
+
+ = new_pagination @routing_constraint_zones, 'pull-right'
- unless @routing_constraint_zones.any?
.row.mt-xs
diff --git a/app/views/routing_constraint_zones/show.html.slim b/app/views/routing_constraint_zones/show.html.slim
index 8c8e9b17a..55c952ae6 100644
--- a/app/views/routing_constraint_zones/show.html.slim
+++ b/app/views/routing_constraint_zones/show.html.slim
@@ -16,15 +16,15 @@
= table_builder_2 @routing_constraint_zone.route.stop_points,
[ \
TableBuilderHelper::Column.new( \
- name: "Arrêts de l'itinéraire", \
+ name: t('.route_stop_points'), \
attribute: 'name', \
link_to: lambda do |stop_point| \
referential_stop_area_path(@referential, stop_point.stop_area) \
end \
),
TableBuilderHelper::Column.new( \
- name: "Arrêts inclus dans l'ITL", \
- attribute: Proc.new{ |rsp| (@routing_constraint_zone.stop_point_ids.include? rsp.id) ? 'Oui' : 'Non' } \
+ name: t('.stop_points'), \
+ attribute: Proc.new{ |rsp| (@routing_constraint_zone.stop_point_ids.include? rsp.id) ? t('yes') : t('no') } \
) \
],
sortable: false,
diff --git a/app/views/stop_areas/_filters.html.slim b/app/views/stop_areas/_filters.html.slim
index cca48bb17..88ed6a772 100644
--- a/app/views/stop_areas/_filters.html.slim
+++ b/app/views/stop_areas/_filters.html.slim
@@ -9,38 +9,16 @@
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, 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)}
+ = f.input :zip_code_cont, placeholder: t('.zip_code'), label: Chouette::StopArea.tmf('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.tmf('city_name'), required: false, wrapper_html: {class: filter_item_class(params[:q], :city_name_cont)}
.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.label Chouette::StopArea.tmf('area_type'), required: false, class: 'control-label'
= 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| ("<span>" + w[0] + "</span>").html_safe}, required: false, wrapper_html: { class: 'checkbox_list' }
-
- .form-group.togglable class=filter_item_class(params[:q], :status)
+
+ .form-group.togglable class=filter_item_class(params[:q], :by_status)
= f.label Chouette::StopArea.tmf('status'), required: false, class: 'control-label'
- .form-group.checkbox_list
- = f.simple_fields_for :status do |p|
- = p.input :in_creation,
- label: ("<span>#{t('activerecord.attributes.stop_area.in_creation')}<span class='fa fa-pencil text-info'></span></span>").html_safe,
- as: :boolean,
- wrapper_html: { class: 'checkbox-wrapper' },
- checked_value: true,
- unchecked_value: false,
- input_html: { checked: @status.try(:[], :in_creation) }
- = p.input :confirmed,
- label: ("<span>#{t('activerecord.attributes.stop_area.confirmed')}<span class='fa fa-check-circle text-success'></span></span>").html_safe,
- as: :boolean,
- wrapper_html: { class: 'checkbox-wrapper' },
- checked_value: true,
- unchecked_value: false,
- input_html: { checked: @status.try(:[], :confirmed) }
- = p.input :deactivated,
- label: ("<span>#{t('activerecord.attributes.stop_area.deleted')}<span class='fa fa-exclamation-circle text-danger'></span></span>").html_safe,
- as: :boolean,
- wrapper_html: { class: 'checkbox-wrapper' },
- checked_value: true,
- unchecked_value: false,
- input_html: { checked: @status.try(:[], :deactivated) }
+ = f.input :by_status, checked: params[:q] && params[:q][:by_status], collection: [:in_creation, :confirmed, :deactivated], as: :check_boxes, label: false, label_method: lambda{|w| ("<span>" + stop_area_status(w) + "</span>").html_safe}, required: false, wrapper_html: { class: 'checkbox_list' }
.actions
= link_to t('actions.erase'), @workbench, class: 'btn btn-link'
diff --git a/app/views/stop_areas/index.html.slim b/app/views/stop_areas/index.html.slim
index 62b873c36..e5ca82ee2 100644
--- a/app/views/stop_areas/index.html.slim
+++ b/app/views/stop_areas/index.html.slim
@@ -33,7 +33,7 @@
), \
TableBuilderHelper::Column.new( \
key: :status, \
- attribute: Proc.new { |s| stop_area_status(s) } \
+ attribute: Proc.new { |s| stop_area_status(s.status) } \
), \
TableBuilderHelper::Column.new( \
key: :zip_code, \
diff --git a/app/views/stop_areas/show.html.slim b/app/views/stop_areas/show.html.slim
index c10d22bfb..c1965c161 100644
--- a/app/views/stop_areas/show.html.slim
+++ b/app/views/stop_areas/show.html.slim
@@ -21,7 +21,7 @@
Chouette::StopArea.tmf('city_name') => @stop_area.city_name,
Chouette::StopArea.tmf('country_code') => @stop_area.country_code.presence || '-',
Chouette::StopArea.tmf('time_zone') => @stop_area.time_zone.presence || '-',
- Chouette::StopArea.tmf('status') => stop_area_status(@stop_area),
+ Chouette::StopArea.tmf('status') => stop_area_status(@stop_area.status),
Chouette::StopArea.tmf('comment') => @stop_area.try(:comment),
})
- @stop_area.custom_fields.each do |code, field|
diff --git a/app/views/workbenches/_form.html.slim b/app/views/workbenches/_form.html.slim
index 534a5f378..c7b6fd4f3 100644
--- a/app/views/workbenches/_form.html.slim
+++ b/app/views/workbenches/_form.html.slim
@@ -1,9 +1,10 @@
-= simple_form_for @workbench, html: { class: 'form-horizontal', id: 'workbench_form' }, wrapper: :horizontal_form do |f|
+= title_tag t('activerecord.models.compliance_control_set.other')
+
+= simple_form_for @workbench, html: { class: 'form-horizontal', id: 'workbench_form' }, wrapper: :horizontal_form, title: "prout" do |f|
.row
.col-lg-12
- = f.input :import_compliance_control_set_id, as: :select, collection: current_organisation.compliance_control_sets, value_method: :id
- = f.input :merge_compliance_control_set_id, as: :select, collection: current_organisation.compliance_control_sets, value_method: :id
-
- .separator
+ = f.fields_for :compliance_control_set_ids do |ff|
+ - @workbench.workgroup.compliance_control_sets_by_workbench.each do |cc, label|
+ = ff.input cc, as: :select, collection: current_organisation.compliance_control_sets, value_method: :id, label: label, selected: @workbench.compliance_control_set(cc).try(:id).try(:to_s), include_blank: true
= f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'workbench_form'
diff --git a/app/views/workbenches/edit.html.slim b/app/views/workbenches/edit.html.slim
index 893024490..0774610e1 100644
--- a/app/views/workbenches/edit.html.slim
+++ b/app/views/workbenches/edit.html.slim
@@ -1,4 +1,4 @@
-- breadcrumb @workbench
+- breadcrumb :workbench_configure, @workbench
- page_header_content_for @workbench
.page_content
diff --git a/app/views/workgroups/_form.html.slim b/app/views/workgroups/_form.html.slim
new file mode 100644
index 000000000..52d1faca8
--- /dev/null
+++ b/app/views/workgroups/_form.html.slim
@@ -0,0 +1,17 @@
+= title_tag t('activerecord.models.compliance_control_set.other')
+
+= simple_form_for @workgroup, html: { class: 'form-horizontal', id: 'workgroup_form' }, wrapper: :horizontal_form do |f|
+ table.table
+ thead
+ th
+ - @workgroup.compliance_control_sets_by_workgroup.values.each do |cc|
+ th= cc
+ - @workgroup.workbenches.each_with_index do |w,i|
+ tr
+ th= w.organisation.name
+ - @workgroup.compliance_control_sets_by_workgroup.keys.each do |cc|
+ td
+ = hidden_field_tag "workgroup[workbenches_attributes][#{i}][id]", w.id
+ = select_tag "workgroup[workbenches_attributes][#{i}][compliance_control_set_ids][#{cc}]", options_from_collection_for_select(current_organisation.compliance_control_sets, :id, :name, w.compliance_control_set(cc).try(:id)), include_blank: true
+
+ = f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'workgroup_form'
diff --git a/app/views/workgroups/edit.html.slim b/app/views/workgroups/edit.html.slim
new file mode 100644
index 000000000..49847acf2
--- /dev/null
+++ b/app/views/workgroups/edit.html.slim
@@ -0,0 +1,8 @@
+- breadcrumb @workgroup
+- page_header_content_for @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'
diff --git a/app/workers/compliance_control_set_copy_worker.rb b/app/workers/compliance_control_set_copy_worker.rb
index d18bb0c88..b87f5ad8e 100644
--- a/app/workers/compliance_control_set_copy_worker.rb
+++ b/app/workers/compliance_control_set_copy_worker.rb
@@ -1,8 +1,9 @@
class ComplianceControlSetCopyWorker
include Sidekiq::Worker
- def perform(control_set_id, referential_id)
+ def perform(control_set_id, referential_id, parent_type = nil, parent_id = nil)
check_set = ComplianceControlSetCopier.new.copy(control_set_id, referential_id)
+ check_set.update parent_type: parent_type, parent_id: parent_id if parent_type && parent_id
begin
Net::HTTP.get(URI("#{Rails.configuration.iev_url}/boiv_iev/referentials/validator/new?id=#{check_set.id}"))
diff --git a/app/workers/route_way_cost_worker.rb b/app/workers/route_way_cost_worker.rb
index b62416c3d..5d8ed52f9 100644
--- a/app/workers/route_way_cost_worker.rb
+++ b/app/workers/route_way_cost_worker.rb
@@ -3,7 +3,11 @@ class RouteWayCostWorker
def perform(referential_id, route_id)
Referential.find(referential_id).switch
- route = Chouette::Route.find(route_id)
+ route = Chouette::Route.where(id: route_id).last
+ unless route.present?
+ Rails.logger.warn "RouteWayCost called on missing route ##{route_id}".red
+ return
+ end
# Prevent recursive worker spawning since this call updates the
# `costs` field of the route.
diff --git a/app/workers/workbench_import_worker/object_state_updater.rb b/app/workers/workbench_import_worker/object_state_updater.rb
index 1edc6b9a1..39d5f20b1 100644
--- a/app/workers/workbench_import_worker/object_state_updater.rb
+++ b/app/workers/workbench_import_worker/object_state_updater.rb
@@ -2,6 +2,11 @@
class WorkbenchImportWorker
module ObjectStateUpdater
+ def resource entry
+ @_resources ||= {}
+ @_resources[entry.name] ||= workbench_import.resources.find_or_create_by(name: entry.name, resource_type: "referential")
+ end
+
def update_object_state entry, count
workbench_import.update( total_steps: count )
update_spurious entry
@@ -14,44 +19,48 @@ class WorkbenchImportWorker
def update_foreign_lines entry
return if entry.foreign_lines.empty?
- workbench_import.messages.create(
+ resource(entry).messages.create(
criticity: :error,
message_key: 'foreign_lines_in_referential',
message_attributes: {
'source_filename' => workbench_import.file.file.file,
'foreign_lines' => entry.foreign_lines.join(', ')
})
+ resource(entry).update status: :ERROR
end
def update_spurious entry
return if entry.spurious.empty?
- workbench_import.messages.create(
+ resource(entry).messages.create(
criticity: :error,
message_key: 'inconsistent_zip_file',
message_attributes: {
'source_filename' => workbench_import.file.file.file,
'spurious_dirs' => entry.spurious.join(', ')
})
+ resource(entry).update status: :ERROR
end
def update_missing_calendar entry
return unless entry.missing_calendar
- workbench_import.messages.create(
+ resource(entry).messages.create(
criticity: :error,
message_key: 'missing_calendar_in_zip_file',
message_attributes: {
'source_filename' => entry.name
})
+ resource(entry).update status: :ERROR
end
def update_wrong_calendar entry
return unless entry.wrong_calendar
- workbench_import.messages.create(
+ resource(entry).messages.create(
criticity: :error,
message_key: 'wrong_calendar_in_zip_file',
message_attributes: {
'source_filename' => entry.name
})
+ resource(entry).update status: :ERROR
end
end
end