diff options
| author | Zog | 2018-03-07 11:35:25 +0100 |
|---|---|---|
| committer | Zog | 2018-03-12 12:00:14 +0100 |
| commit | 1245099459bd3d7dce71fdf0d7c95b2377a0034e (patch) | |
| tree | c17f2c4bd68fc6ad4eedead96e1106954d7093e4 | |
| parent | 0b9269780989dbd69a9be9d63670aab12050cf60 (diff) | |
| download | chouette-core-1245099459bd3d7dce71fdf0d7c95b2377a0034e.tar.bz2 | |
Refs #6133; First Crud for exports
36 files changed, 446 insertions, 251 deletions
diff --git a/app/controllers/concerns/iev_interfaces.rb b/app/controllers/concerns/iev_interfaces.rb new file mode 100644 index 000000000..590482c7f --- /dev/null +++ b/app/controllers/concerns/iev_interfaces.rb @@ -0,0 +1,65 @@ +module IevInterfaces + extend ActiveSupport::Concern + + included do + before_action only: [:index] { set_date_time_params("started_at", DateTime) } + before_action :ransack_status_params, only: [:index] + respond_to :html + belongs_to :workbench + end + + def show + show! do + instance_variable_set "@#{collection_name.singularize}", resource.decorate(context: { + workbench: @workbench + }) + end + end + + def index + index! do |format| + format.html { + if collection.out_of_bounds? + redirect_to params.merge(:page => 1) + end + collection = decorate_collection(collection) + } + end + end + + protected + def collection + scope = parent.send(collection_name).where(type: "#{resource_class.parent.name}::Workbench") + + scope = self.ransack_period_range(scope: scope, error_message: t("#{collection_name}.filters.error_period_filter"), query: :where_started_at_in) + + @q = scope.search(params[:q]) + + unless instance_variable_get "@#{collection_name}" + coll = if sort_column && sort_direction + @q.result(distinct: true).order(sort_column + ' ' + sort_direction).paginate(page: params[:page], per_page: 10) + else + @q.result(distinct: true).order(:name).paginate(page: params[:page], per_page: 10) + end + instance_variable_set "@#{collection_name}", decorate_collection(coll) + end + instance_variable_get "@#{collection_name}" + end + + private + def ransack_status_params + if params[:q] + return params[:q].delete(:status_eq_any) if params[:q][:status_eq_any].empty? || ( (resource_class.status.values & params[:q][:status_eq_any]).length >= 4 ) + params[:q][:status_eq_any].push("new", "running") if params[:q][:status_eq_any].include?("pending") + params[:q][:status_eq_any].push("aborted", "canceled") if params[:q][:status_eq_any].include?("failed") + end + end + + def sort_column + parent.imports.column_names.include?(params[:sort]) ? params[:sort] : 'created_at' + end + + def sort_direction + %w[asc desc].include?(params[:direction]) ? params[:direction] : 'desc' + end +end diff --git a/app/controllers/exports_controller.rb b/app/controllers/exports_controller.rb index 095720aa0..1b947299f 100644 --- a/app/controllers/exports_controller.rb +++ b/app/controllers/exports_controller.rb @@ -1,74 +1,41 @@ -require 'will_paginate/array' -require 'open-uri' - class ExportsController < ChouetteController - include ReferentialSupport - # defaults :resource_class => Export - # - # respond_to :html, :only => [:show, :index, :destroy, :exported_file] - # respond_to :js, :only => [:index] - # belongs_to :referential - # - # def index - # begin - # index! - # rescue Ievkit::Error, Faraday::Error => error - # logger.error("Iev failure : #{error.message}") - # flash[:error] = t(error.locale_for_error) - # redirect_to referential_path(@referential) - # end - # end - # - # def show - # begin - # show! - # rescue Ievkit::Error, Faraday::Error => error - # logger.error("Iev failure : #{error.message}") - # flash[:error] = t(error.locale_for_error) - # redirect_to referential_path(@referential) - # end - # end - # - # def destroy - # begin - # destroy! - # rescue Ievkit::Error, Faraday::Error => error - # logger.error("Iev failure : #{error.message}") - # flash[:error] = t(error.locale_for_error) - # redirect_to referential_path(@referential) - # end - # end - # - # def exported_file - # # WARNING : files under 10kb in size get treated as StringIO by OpenUri - # # http://stackoverflow.com/questions/10496874/why-does-openuri-treat-files-under-10kb-in-size-as-stringio - # OpenURI::Buffer.send :remove_const, 'StringMax' if OpenURI::Buffer.const_defined?('StringMax') - # OpenURI::Buffer.const_set 'StringMax', 0 - # begin - # send_file open(resource.file_path), { :type => "application/#{resource.filename_extension}", :disposition => "attachment", :filename => resource.filename } - # rescue Ievkit::Error, Faraday::Error => error - # logger.error("Iev failure : #{error.message}") - # flash[:error] = t(error.locale_for_error) - # redirect_to referential_path(@referential) - # end - # end - # - # protected - # - # def export_service - # ExportService.new(@referential) - # end - # - # def resource - # @export ||= export_service.find( params[:id] ) - # @line_items = @export.report.line_items - # if @line_items.size > 500 - # @line_items = @line_items.paginate(page: params[:page], per_page: 20) - # end - # @export - # end - # - # def collection - # @exports ||= export_service.all.sort_by{ |export| export.created_at }.reverse.paginate(:page => params[:page]) - # end + include PolicyChecker + include RansackDateFilter + include IevInterfaces + skip_before_action :authenticate_user!, only: [:upload] + defaults resource_class: Export::Base, collection_name: 'exports', instance_name: 'export' + + def upload + if params[:token] == resource.token_download + send_file resource.file.path + else + user_not_authorized + end + end + + private + + def build_resource + @export ||= Export::Workbench.new(*resource_params) do |export| + export.workbench = parent + export.creator = current_user.name + end + end + + def export_params + params.require(:export).permit( + :name, + :type, + :referential_id + ) + end + + def decorate_collection(exports) + ExportDecorator.decorate( + exports, + context: { + workbench: @workbench + } + ) + end end diff --git a/app/controllers/imports_controller.rb b/app/controllers/imports_controller.rb index 3ebbeb665..f95b6acf1 100644 --- a/app/controllers/imports_controller.rb +++ b/app/controllers/imports_controller.rb @@ -1,31 +1,9 @@ class ImportsController < ChouetteController include PolicyChecker include RansackDateFilter - before_action only: [:index] { set_date_time_params("started_at", DateTime) } + include IevInterfaces skip_before_action :authenticate_user!, only: [:download] defaults resource_class: Import::Base, collection_name: 'imports', instance_name: 'import' - before_action :ransack_status_params, only: [:index] - respond_to :html - belongs_to :workbench - - def show - show! do - @import = @import.decorate(context: { - workbench: @workbench - }) - end - end - - def index - index! do |format| - format.html { - if collection.out_of_bounds? - redirect_to params.merge(:page => 1) - end - @imports = decorate_imports(@imports) - } - end - end def download if params[:token] == resource.token_download @@ -35,31 +13,8 @@ class ImportsController < ChouetteController end end - protected - def collection - scope = parent.imports.where(type: "Import::Workbench") - - scope = self.ransack_period_range(scope: scope, error_message: t('imports.filters.error_period_filter'), query: :where_started_at_in) - - @q = scope.search(params[:q]) - - if sort_column && sort_direction - @imports ||= @q.result(distinct: true).order(sort_column + ' ' + sort_direction).paginate(page: params[:page], per_page: 10) - else - @imports ||= @q.result(distinct: true).order(:name).paginate(page: params[:page], per_page: 10) - end - end - private - def ransack_status_params - if params[:q] - return params[:q].delete(:status_eq_any) if params[:q][:status_eq_any].empty? || ( (Import::Base.status.values & params[:q][:status_eq_any]).length >= 4 ) - params[:q][:status_eq_any].push("new", "running") if params[:q][:status_eq_any].include?("pending") - params[:q][:status_eq_any].push("aborted", "canceled") if params[:q][:status_eq_any].include?("failed") - end - end - def build_resource @import ||= Import::Workbench.new(*resource_params) do |import| import.workbench = parent @@ -76,14 +31,7 @@ class ImportsController < ChouetteController ) end - def sort_column - parent.imports.column_names.include?(params[:sort]) ? params[:sort] : 'created_at' - end - def sort_direction - %w[asc desc].include?(params[:direction]) ? params[:direction] : 'desc' - end - - def decorate_imports(imports) + def decorate_collection(imports) ImportDecorator.decorate( imports, context: { diff --git a/app/decorators/export_decorator.rb b/app/decorators/export_decorator.rb new file mode 100644 index 000000000..26682f383 --- /dev/null +++ b/app/decorators/export_decorator.rb @@ -0,0 +1,21 @@ +class ExportDecorator < AF83::Decorator + decorates Export::Base + + set_scope { context[:workbench] } + + define_instance_method :export_status_css_class do + cls ='' + cls = 'overheaded-success' if object.status == 'successful' + cls = 'overheaded-warning' if object.status == 'warning' + cls = 'overheaded-danger' if %w[failed aborted canceled].include? object.status + cls + end + + create_action_link do |l| + l.content t('exports.actions.new') + end + + with_instance_decorator do |instance_decorator| + instance_decorator.show_action_link + end +end diff --git a/app/decorators/import/base_decorator.rb b/app/decorators/import_decorator.rb index 8c10479c6..a20dfbc42 100644 --- a/app/decorators/import/base_decorator.rb +++ b/app/decorators/import_decorator.rb @@ -1,4 +1,4 @@ -class Import::BaseDecorator < AF83::Decorator +class ImportDecorator < AF83::Decorator decorates Import::Base set_scope { context[:workbench] } diff --git a/app/helpers/table_builder_helper/column.rb b/app/helpers/table_builder_helper/column.rb index ff6f2f36f..907707670 100644 --- a/app/helpers/table_builder_helper/column.rb +++ b/app/helpers/table_builder_helper/column.rb @@ -28,7 +28,9 @@ module TableBuilderHelper return @name if @name.present? # Transform `Chouette::Line` into "line" - model_key = model.to_s.demodulize.underscore + model_key = model.to_s.underscore + model_key.gsub! 'chouette/', '' + model_key.gsub! '/', '.' I18n.t("activerecord.attributes.#{model_key}.#{@key}") end diff --git a/app/models/concerns/iev_interfaces/task.rb b/app/models/concerns/iev_interfaces/task.rb index b142850fb..c84c588b6 100644 --- a/app/models/concerns/iev_interfaces/task.rb +++ b/app/models/concerns/iev_interfaces/task.rb @@ -7,7 +7,6 @@ module IevInterfaces::Task belongs_to :referential mount_uploader :file, ImportUploader - validates :file, presence: true has_many :children, foreign_key: :parent_id, class_name: self.name, dependent: :destroy @@ -17,8 +16,8 @@ module IevInterfaces::Task validates :name, presence: true validates_presence_of :workbench, :creator - has_many :messages, class_name: messages_class_name, dependent: :destroy, foreign_key: :import_id - has_many :resources, class_name: resources_class_name, dependent: :destroy, foreign_key: :import_id + has_many :messages, class_name: messages_class_name, dependent: :destroy, foreign_key: "#{messages_class_name.split('::').first.downcase}_id" + has_many :resources, class_name: resources_class_name, dependent: :destroy, foreign_key: "#{resources_class_name.split('::').first.downcase}_id" scope :where_started_at_in, ->(period_range) do where('started_at BETWEEN :begin AND :end', begin: period_range.begin, end: period_range.end) diff --git a/app/models/export/base.rb b/app/models/export/base.rb index d809055db..844c66d82 100644 --- a/app/models/export/base.rb +++ b/app/models/export/base.rb @@ -12,7 +12,7 @@ class Export::Base < ActiveRecord::Base include IevInterfaces::Task def self.model_name - ActiveModel::Name.new Export::Base, Export::Base, "Export::Base" + ActiveModel::Name.new Export::Base, Export::Base, "Export" end private diff --git a/app/models/export/workbench.rb b/app/models/export/workbench.rb new file mode 100644 index 000000000..a4b14cf55 --- /dev/null +++ b/app/models/export/workbench.rb @@ -0,0 +1,7 @@ +class Export::Workbench < Export::Base + after_commit :launch_worker, :on => :create + + def launch_worker + # WorkbenchImportWorker.perform_async(id) + end +end diff --git a/app/models/import/base.rb b/app/models/import/base.rb index e2ae129be..73d06d968 100644 --- a/app/models/import/base.rb +++ b/app/models/import/base.rb @@ -1,5 +1,6 @@ class Import::Base < ActiveRecord::Base self.table_name = "imports" + validates :file, presence: true def self.messages_class_name "Import::Message" @@ -12,7 +13,7 @@ class Import::Base < ActiveRecord::Base include IevInterfaces::Task def self.model_name - ActiveModel::Name.new Import::Base, Import::Base, "Import::Base" + ActiveModel::Name.new Import::Base, Import::Base, "Import" end def child_change diff --git a/app/models/workbench.rb b/app/models/workbench.rb index 44415f102..b5f4673bb 100644 --- a/app/models/workbench.rb +++ b/app/models/workbench.rb @@ -14,6 +14,7 @@ class Workbench < ActiveRecord::Base has_many :group_of_lines, through: :line_referential has_many :stop_areas, through: :stop_area_referential has_many :imports, class_name: Import::Base + has_many :exports, class_name: Export::Base has_many :workbench_imports, class_name: Import::Workbench has_many :compliance_check_sets has_many :compliance_control_sets diff --git a/app/policies/export_policy.rb b/app/policies/export_policy.rb new file mode 100644 index 000000000..e667f3207 --- /dev/null +++ b/app/policies/export_policy.rb @@ -0,0 +1,15 @@ +class ExportPolicy < ApplicationPolicy + class Scope < Scope + def resolve + scope + end + end + + def create? + user.has_permission?('exports.create') + end + + def update? + user.has_permission?('exports.update') + end +end diff --git a/app/policies/import/base_policy.rb b/app/policies/import_policy.rb index 62345e452..512bfc8ac 100644 --- a/app/policies/import/base_policy.rb +++ b/app/policies/import_policy.rb @@ -1,4 +1,4 @@ -class Import::BasePolicy < ApplicationPolicy +class ImportPolicy < ApplicationPolicy class Scope < Scope def resolve scope diff --git a/app/views/exports/_export.html.slim b/app/views/exports/_export.html.slim deleted file mode 100644 index f1f7e9753..000000000 --- a/app/views/exports/_export.html.slim +++ /dev/null @@ -1,20 +0,0 @@ -#index_item.panel.panel-default.export - .panel-heading - .panel-title.clearfix - span.pull-right - = link_to referential_export_path(@referential, export.id), :method => :delete, :data => {:confirm => t('exports.actions.destroy_confirm')}, class: 'btn btn-danger btn-sm' do - span.fa.fa-trash-o - - h5 - = link_to( referential_export_path(@referential, export.id), :class => "preview", :title => "#{Export.model_name.human.capitalize} #{export.name}") do - = job_status_title(export) - - .panel-body - p - = link_to( font_awesome_classic_tag("fa-file-#{export.filename_extension}-o") + t("exports.show.exported_file"), exported_file_referential_export_path(@referential, export.id) ) if export.file_path - - .panel-footer - = export_attributes_tag(export) - .history - = l export.created_at, :format => "%d/%m/%Y %H:%M" - = " | #{export.user_name}"
\ No newline at end of file diff --git a/app/views/exports/_exports.html.slim b/app/views/exports/_exports.html.slim deleted file mode 100644 index 7a0461def..000000000 --- a/app/views/exports/_exports.html.slim +++ /dev/null @@ -1,9 +0,0 @@ -.page_info - span.search = t("will_paginate.page_entries_info.search") - = page_entries_info @exports - -.exports.paginated_content - = paginated_content @exports, "exports/export" - -.pagination - = will_paginate @exports, :container => false, renderer: RemoteBootstrapPaginationLinkRenderer
\ No newline at end of file diff --git a/app/views/exports/_form.html.slim b/app/views/exports/_form.html.slim new file mode 100644 index 000000000..c4748b5f9 --- /dev/null +++ b/app/views/exports/_form.html.slim @@ -0,0 +1,7 @@ += simple_form_for export, as: :export, url: workbench_exports_path(workbench), html: {class: 'form-horizontal', id: 'wb_export_form'}, wrapper: :horizontal_form do |form| + + .row + .col-lg-12 + = form.input :name + + = form.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'wb_export_form' diff --git a/app/views/exports/index.html.slim b/app/views/exports/index.html.slim index bbcb2a5a7..f97b07231 100644 --- a/app/views/exports/index.html.slim +++ b/app/views/exports/index.html.slim @@ -1,10 +1,44 @@ -= title_tag t('.title') +- breadcrumb :exports, @workbench -.warning = t('.warning') +.page_content + .container-fluid + - if params[:q].present? or collection.any? + .row + .col-lg-12 + = render 'shared/iev_interfaces/filters' -#exports = render 'exports' + - if collection.any? + .row + .col-lg-12 + = table_builder_2 collection, + [ \ + TableBuilderHelper::Column.new( \ + key: :status, \ + attribute: Proc.new { |n| export_status(n.status) }, \ + ), \ + TableBuilderHelper::Column.new( \ + key: :started_at, \ + attribute: Proc.new { |n| l(n.started_at, format: :long) if n.started_at }, \ + ), \ + TableBuilderHelper::Column.new( \ + key: :name, \ + attribute: 'name', \ + link_to: lambda do |export| \ + workbench_export_path(@workbench, export) \ + end \ + ), \ + TableBuilderHelper::Column.new( \ + key: :creator, \ + attribute: 'creator' \ + ) \ + ], + cls: 'table has-search' -- content_for :sidebar do - ul.actions - li - = link_to t('exports.actions.new'), new_referential_export_task_path(@referential), class: 'add'
\ No newline at end of file + = new_pagination collection, 'pull-right' + + - unless collection.any? + .row.mt-xs + .col-lg-12 + = replacement_msg t('exports.search_no_results') + += javascript_pack_tag 'date_filters' diff --git a/app/views/exports/index.js.slim b/app/views/exports/index.js.slim deleted file mode 100644 index b9a413b1b..000000000 --- a/app/views/exports/index.js.slim +++ /dev/null @@ -1 +0,0 @@ -| $('#exports').html("#{escape_javascript(render('exports'))}");
\ No newline at end of file diff --git a/app/views/exports/new.html.slim b/app/views/exports/new.html.slim new file mode 100644 index 000000000..f62386caf --- /dev/null +++ b/app/views/exports/new.html.slim @@ -0,0 +1,7 @@ +- breadcrumb :exports, @workbench + +.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', export: @export, workbench: @workbench diff --git a/app/views/exports/show.html.slim b/app/views/exports/show.html.slim index 1631e0e7e..dab50ced8 100644 --- a/app/views/exports/show.html.slim +++ b/app/views/exports/show.html.slim @@ -1,26 +1,60 @@ -.title.row - .col-md-8 - = title_tag job_status_title(@export) +- breadcrumb :export, @workbench, @export - .col-md-4 - = export_attributes_tag(@export) +- page_header_content_for @export -- if @export.report.failure_code? - .alert.alert-danger - = t("iev.failure.#{@export.report.failure_code}") +.page_content + .container-fluid + .row + .col-lg-6.col-md-6.col-sm-12.col-xs-12 + = definition_list t('metadatas'), { 'Récupération des données' => '-', "Nom de l'archive" => @export.try(:file_identifier)} -.progress_bars - = progress_bar_tag(@export) + .row + .col-lg-12 + .error_messages + = render 'shared/iev_interfaces/messages', messages: @export.messages -.export_show - .links - = link_to( font_awesome_classic_tag("fa-file-#{@export.filename_extension}-o") + t("exports.show.exported_file"), exported_file_referential_export_path(@referential, @export.id) ) if @export.file_path - - = render partial: "shared/ie_report.html", locals: { job: @export, line_items: @line_items } - -- content_for :sidebar do - ul.actions - li - = link_to t('exports.actions.destroy'), referential_export_path(@referential, @export.id), :method => :delete, :data => {:confirm => t('exports.actions.destroy_confirm')}, class: 'remove' - - = history_tag(@export)
\ No newline at end of file + - if @export.children.any? + .row + .col-lg-12 + = table_builder_2 @export.children, + [ \ + TableBuilderHelper::Column.new( \ + name: 'Nom du jeu de données', \ + attribute: 'name', \ + sortable: false, \ + link_to: lambda do |export| \ + referential_path(export.referential) if export.referential.present? \ + end \ + ), \ + TableBuilderHelper::Column.new( \ + key: :status, \ + attribute: Proc.new { |n| export_status(n.status) }, \ + sortable: false, \ + link_to: lambda do |export| \ + workbench_export_export_resources_path(export.workbench_id, export) \ + end \ + ), \ + TableBuilderHelper::Column.new( \ + name: 'Contrôle STIF', \ + attribute: '', \ + sortable: false, \ + ), \ + TableBuilderHelper::Column.new( \ + name: 'Contrôle organisation', \ + attribute: '', \ + sortable: false, \ + ) \ + ], + cls: 'table', + overhead: [ \ + {}, \ + { \ + title: "#{@export.children_succeedeed} jeu de données validé sur #{@export.children.count} présent(s) dans l'archive", \ + width: 1, \ + cls: "#{@export.export_status_css_class} full-border" \ + }, { \ + title: 'Bilan des jeux de contrôles d\'export <span title="Lorem ipsum..." class="fa fa-lg fa-info-circle text-info"></span>', \ + width: 2, \ + cls: 'overheaded-default colspan="2"' \ + } \ + ] diff --git a/app/views/imports/_import_messages.html.slim b/app/views/imports/_import_messages.html.slim deleted file mode 100644 index af10b23e5..000000000 --- a/app/views/imports/_import_messages.html.slim +++ /dev/null @@ -1,8 +0,0 @@ -- if import_messages.any? - ul.list-unstyled.import_message-list - - import_messages.each do | import_message | - li - span(class="#{bootstrap_class_for_message_criticity import_message.criticity}") - = t( ['import_messages', - 'compliance_check_messages', - import_message.message_key].join('.'), import_message.message_attributes.symbolize_keys) diff --git a/app/views/imports/index.html.slim b/app/views/imports/index.html.slim index 4fc077bd6..3dff4d80e 100644 --- a/app/views/imports/index.html.slim +++ b/app/views/imports/index.html.slim @@ -2,15 +2,15 @@ .page_content .container-fluid - - if params[:q].present? or @imports.any? + - if params[:q].present? or collection.any? .row .col-lg-12 - = render 'filters' + = render 'shared/iev_interfaces/filters' - if @imports.any? .row .col-lg-12 - = table_builder_2 @imports, + = table_builder_2 collection, [ \ TableBuilderHelper::Column.new( \ key: :status, \ @@ -34,9 +34,9 @@ ], cls: 'table has-search' - = new_pagination @imports, 'pull-right' + = new_pagination collection, 'pull-right' - - unless @imports.any? + - unless collection.any? .row.mt-xs .col-lg-12 = replacement_msg t('imports.search_no_results') diff --git a/app/views/imports/show.html.slim b/app/views/imports/show.html.slim index 7a9d02077..48a4f334c 100644 --- a/app/views/imports/show.html.slim +++ b/app/views/imports/show.html.slim @@ -11,7 +11,7 @@ .row .col-lg-12 .error_messages - = render 'import_messages', import_messages: @import.messages + = render 'shared/iev_interfaces/messages', messages: @import.messages - if @import.children.any? .row 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 cb0698cf8..02614dcab 100644 --- a/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim +++ b/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim @@ -29,6 +29,8 @@ span Jeux de données = link_to workbench_imports_path(current_workbench), class: "list-group-item #{(params[:controller] == 'imports') ? 'active' : ''}" do span Import + = link_to workbench_exports_path(current_workbench), class: "list-group-item #{(params[:controller] == 'exports') ? 'active' : ''}" do + span Export = link_to workgroup_calendars_path(current_workbench.workgroup), class: 'list-group-item' do span Modèles de calendrier = link_to workbench_compliance_check_sets_path(current_workbench), class: 'list-group-item' do diff --git a/app/views/layouts/navigation/_page_header.html.slim b/app/views/layouts/navigation/_page_header.html.slim index e407e53da..49f56544b 100644 --- a/app/views/layouts/navigation/_page_header.html.slim +++ b/app/views/layouts/navigation/_page_header.html.slim @@ -1,6 +1,5 @@ - action_links = resource.action_links(params[:action]) rescue nil - action_links ||= decorated_collection.action_links(params[:action]) rescue nil - .page_header .container-fluid .row @@ -13,7 +12,7 @@ h1 = yield :page_header_title - else - if defined?(resource_class) - h1 = t("#{resource_class.model_name.name.underscore.pluralize}.#{params[:action]}.title") + h1 = t("#{resource_class.model_name.name.underscore.gsub('/', '.').pluralize}.#{params[:action]}.title") .col-lg-3.col-md-4.col-sm-5.col-xs-5.text-right .page-action diff --git a/app/views/imports/_filters.html.slim b/app/views/shared/iev_interfaces/_filters.html.slim index 25c0d10d9..9b114c38d 100644 --- a/app/views/imports/_filters.html.slim +++ b/app/views/shared/iev_interfaces/_filters.html.slim @@ -8,11 +8,11 @@ .ffg-row .form-group.togglable class=filter_item_class(params[:q], :status_eq_any) - = f.label Import.human_attribute_name(:status), required: false, class: 'control-label' + = f.label Import::Base.human_attribute_name(:status), required: false, class: 'control-label' = f.input :status_eq_any, collection: %w(pending successful warning failed), as: :check_boxes, label: false, label_method: lambda{|l| ("<span>" + import_status(l) + "</span>").html_safe}, required: false, wrapper_html: { class: "checkbox_list"} .form-group.togglable class=filter_item_class(params[:q], :started_at) - = f.label Import.human_attribute_name(:started_at), required: false, class: 'control-label' + = f.label Import::Base.human_attribute_name(:started_at), required: false, class: 'control-label' .filter_menu = f.simple_fields_for :started_at do |p| = p.input :start_date, as: :date, label: false, wrapper_html: { class: 'date smart_date filter_menu-item' }, default: @begin_range, include_blank: @begin_range ? false : true diff --git a/app/views/shared/iev_interfaces/_messages.html.slim b/app/views/shared/iev_interfaces/_messages.html.slim new file mode 100644 index 000000000..bb6eea9f9 --- /dev/null +++ b/app/views/shared/iev_interfaces/_messages.html.slim @@ -0,0 +1,7 @@ +- if messages.any? + ul.list-unstyled.import_message-list + - messages.each do | message | + li + div(class="#{bootstrap_class_for_message_criticity message.criticity}") + = t( [message.class.name.underscore.gsub('/', '_').pluralize, + message.message_key].join('.'), message.message_attributes.symbolize_keys) diff --git a/config/breadcrumbs.rb b/config/breadcrumbs.rb index adcbb0b6f..87d6f5846 100644 --- a/config/breadcrumbs.rb +++ b/config/breadcrumbs.rb @@ -111,11 +111,21 @@ crumb :imports do |workbench| parent :workbench, workbench end +crumb :exports do |workbench| + link I18n.t('exports.index.title'), workbench_exports_path(workbench) + parent :workbench, workbench +end + crumb :import do |workbench, import| link breadcrumb_name(import), workbench_import_path(workbench, import) parent :imports, workbench end +crumb :export do |workbench, export| + link breadcrumb_name(export), workbench_export_path(workbench, export) + parent :exports, workbench +end + crumb :import_resources do |import, import_resources| link I18n.t('import_resources.index.title'), workbench_import_import_resources_path(import.workbench, import.parent) parent :import, import.workbench, import.parent diff --git a/config/locales/exports.en.yml b/config/locales/exports.en.yml index 2a47fba54..73d49b1f8 100644 --- a/config/locales/exports.en.yml +++ b/config/locales/exports.en.yml @@ -1,25 +1,32 @@ en: exports: + search_no_results: "No export matching your query" + filters: + referential: "Select data space..." + name_or_creator_cont: "Select an export or creator name..." + error_period_filter: "End date must be greater or equal than begin date" actions: new: "New export" + create: "New export" + show: "Export report" + download: "Download original file" destroy: "Destroy" destroy_confirm: "Are you sure you want destroy this export?" - new: - title: "New export" - all: "All" - flash: "Export task on queue, refresh page to see progression" index: title: "Exports" warning: "" + new: + title: "Generate a new export" + create: + title: "Generate a new export" show: + title: "Export %{name}" report: "Report" - exported_file: "Exported file" - statuses: - started: "Started" - scheduled: "Processing ..." - terminated: "Completed" - canceled: "Canceled" - aborted: "Failed" + exported_file: "Original file" + compliance_check: "Validation report" + compliance_check_of: "Validation of export: " + export_of_validation: "Export of the validation" + compliance_check_task: "Validate Report" severities: info: "Information" uncheck: "Unchecked" @@ -27,7 +34,7 @@ en: warning: "Warning" error: "Error" fatal: "Fatal" - activemodel: + activerecord: models: export: zero: "export" @@ -37,6 +44,10 @@ en: zero: "export" one: "Neptune export" other: "exports" + csv_export: + zero: "export" + one: "CSV export" + other: "exports" gtfs_export: zero: "export" one: "GTFS export" @@ -44,4 +55,34 @@ en: netex_export: zero: "export" one: "NeTEx export" - other: "exports"
\ No newline at end of file + other: "exports" + errors: + models: + export: + base: + attributes: + file: + wrong_file_extension: "The exported file must be a zip file" + attributes: + attrs: &attrs + resources: "File to export" + created_at: "Created on" + started_at: "Started at" + name: "Name" + status: "Status" + creator: "Creator" + references_type: "Data to be exported" + no_save: "No save" + object_id_prefix: "Neptune Id prefix" + max_distance_for_commercial: "Max distance for commercial stop" + max_distance_for_connection_link: "Max distance for connection link" + ignore_last_word: "ignore last word" + ignore_end_chars: "ignore last chars" + export: + <<: *attrs + base: + <<: *attrs + flash: + exports: + create: + notice: "The export is in progress. Please wait and refresh the page in a few moments." diff --git a/config/locales/exports.fr.yml b/config/locales/exports.fr.yml index 2d7cc0259..c5b8a5e3b 100644 --- a/config/locales/exports.fr.yml +++ b/config/locales/exports.fr.yml @@ -1,33 +1,43 @@ fr: - exports: + exports: &exports + search_no_results: "Aucun export ne correspond à votre recherche" + filters: + referential: "Sélectionnez un jeu de données..." + name_or_creator_cont: "Indiquez un nom d'export ou d'opérateur..." + error_period_filter: "La date de fin doit être supérieure ou égale à la date de début" actions: new: "Nouvel export" + create: "Nouvel export" + show: "Rapport d'export" + download: "Téléch. fichier source" destroy: "Supprimer cet export" destroy_confirm: "Etes vous sûr de supprimer cet export ?" - new: - title: "Nouvel export" - all: "Toutes" - flash: "La demande d'export est mise en file d'attente, veuillez rafraichir régulièrement la page pour en suivre la progression" index: title: "Exports" warning: "" + new: + title: "Générer un export" + create: + title: "Générer un export" show: + title: "Export %{name}" report: "Rapport" - exported_file: "Fichier exporté" - statuses: - started: "En file d'attente..." - scheduled: "En cours..." - terminated: "Achevé" - canceled: "Annulé" - aborted: "Echoué" + exported_file: "Fichier source" + compliance_check: "Test de conformité" + compliance_check_of: "Validation de l'export : " + export_of_validation: "L'export de la validation" + compliance_check_task: "Validation" severities: info: "Information" - uncheck: "Non disponible" + uncheck: "Non testé" ok: "Ok" warning: "Alerte" error: "Erreur" fatal: "Fatal" - activemodel: + export: + base: + <<: *exports + activerecord: models: export: zero: "export" @@ -35,7 +45,11 @@ fr: other: "exports" neptune_export: zero: "export" - one: "export neptune" + one: "export Neptune" + other: "exports" + csv_export: + zero: "export" + one: "export CSV" other: "exports" gtfs_export: zero: "export" @@ -45,3 +59,33 @@ fr: zero: "export" one: "export NeTEx" other: "exports" + errors: + models: + export: + base: + attributes: + file: + wrong_file_extension: "Le fichier exporté doit être au format zip" + attributes: + attrs: &attrs + resources: "Fichier à exporter" + created_at: "Créé le" + started_at: Démarrage + name: "Nom de l'export" + status: "Etat" + creator: "Opérateur" + no_save: "Pas de sauvegarde" + references_type: "Données à exporter" + object_id_prefix: "Préfixe d'identifiants" + max_distance_for_commercial: "Distance max pour créer les zones" + max_distance_for_connection_link: "Distance max pour créer les correspondances" + ignore_last_word: "ignorer le dernier mot" + ignore_end_chars: "ignorer les n derniers caractères" + export: + <<: *attrs + base: + <<: *attrs + flash: + exports: + create: + notice: "L'export est en cours, veuillez patienter. Actualiser votre page si vous voulez voir l'avancement de votre traitement." diff --git a/config/locales/import_messages.en.yml b/config/locales/import_messages.en.yml index aad4fb772..bc06c46f0 100644 --- a/config/locales/import_messages.en.yml +++ b/config/locales/import_messages.en.yml @@ -1,5 +1,5 @@ en: - import_messages: + import_message: corrupt_zip_file: "The zip file %{source_filename} is corrupted and cannot be read" inconsistent_zip_file: "The zip file %{source_filename} contains unexpected directories: %{spurious_dirs}, which are ignored" referential_creation: "Le référentiel n'a pas pu être créé car un référentiel existe déjà sur les mêmes périodes et lignes" @@ -50,4 +50,4 @@ en: 2_netexstif_servicejourneypattern_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourneyPattern d'identifiant %{source_objectid} doit contenir au moins 2 StopPointInJourneyPattern" 2_netexstif_servicejourneypattern_3_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourneyPattern d'identifiant %{source_objectid} n'a pas de valeur pour l'attribut ServiceJourneyPatternType" 2_netexstif_servicejourneypattern_3_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourneyPattern d'identifiant %{source_objectid} a une valeur interdite %{error_value} pour l'attribut ServiceJourneyPatternType différente de 'passenger'" - 2_netexstif_servicejourneypattern_4: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number}, objet ServiceJourneyPattern d'identifiant %{source_objectid} : les attributs 'order' des StopPointInJourneyPattern ne sont pas croissants."
\ No newline at end of file + 2_netexstif_servicejourneypattern_4: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number}, objet ServiceJourneyPattern d'identifiant %{source_objectid} : les attributs 'order' des StopPointInJourneyPattern ne sont pas croissants." diff --git a/config/locales/import_resources.en.yml b/config/locales/import_resources.en.yml index 5f0f3213e..3e737f9bc 100644 --- a/config/locales/import_resources.en.yml +++ b/config/locales/import_resources.en.yml @@ -1,5 +1,5 @@ en: - import_resources: + import_resources: &resources index: title: "NeTEx conformity" table_state: "%{lines_imported} line(s) imported on %{lines_in_zipfile} presents in zipfile" diff --git a/config/locales/imports.en.yml b/config/locales/imports.en.yml index b0644acd3..d0db87fb1 100644 --- a/config/locales/imports.en.yml +++ b/config/locales/imports.en.yml @@ -59,11 +59,12 @@ en: errors: models: import: - attributes: - file: - wrong_file_extension: "The imported file must be a zip file" + base: + attributes: + file: + wrong_file_extension: "The imported file must be a zip file" attributes: - import: + attrs: &attrs resources: "File to import" created_at: "Created on" started_at: "Started at" @@ -77,6 +78,10 @@ en: max_distance_for_connection_link: "Max distance for connection link" ignore_last_word: "ignore last word" ignore_end_chars: "ignore last chars" + import: + <<: *attrs + base: + <<: *attrs flash: imports: create: diff --git a/config/locales/imports.fr.yml b/config/locales/imports.fr.yml index 2380eac45..40272889a 100644 --- a/config/locales/imports.fr.yml +++ b/config/locales/imports.fr.yml @@ -1,5 +1,5 @@ fr: - imports: + imports: &imports search_no_results: "Aucun import ne correspond à votre recherche" filters: referential: "Sélectionnez un jeu de données..." @@ -34,6 +34,9 @@ fr: warning: "Alerte" error: "Erreur" fatal: "Fatal" + import: + base: + <<: *imports activerecord: models: import: @@ -59,11 +62,12 @@ fr: errors: models: import: - attributes: - file: - wrong_file_extension: "Le fichier importé doit être au format zip" + base: + attributes: + file: + wrong_file_extension: "Le fichier importé doit être au format zip" attributes: - import: + attrs: &attrs resources: "Fichier à importer" created_at: "Créé le" started_at: Démarrage @@ -77,6 +81,12 @@ fr: max_distance_for_connection_link: "Distance max pour créer les correspondances" ignore_last_word: "ignorer le dernier mot" ignore_end_chars: "ignorer les n derniers caractères" + + import: + <<: *attrs + base: + <<: *attrs + flash: imports: create: diff --git a/config/routes.rb b/config/routes.rb index b6934936b..6313b5678 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -11,6 +11,12 @@ ChouetteIhm::Application.routes.draw do resources :import_messages, only: [:index] end end + resources :exports do + post :upload, on: :member + resources :export_resources, only: [:index] do + resources :export_messages, only: [:index] + end + end resources :compliance_check_sets, only: [:index, :show] do get :executed, on: :member resources :compliance_checks, only: [:show] diff --git a/lib/stif/permission_translator.rb b/lib/stif/permission_translator.rb index 9e0feb9b8..09a7c610c 100644 --- a/lib/stif/permission_translator.rb +++ b/lib/stif/permission_translator.rb @@ -21,6 +21,7 @@ module Stif calendars footnotes imports + exports merges journey_patterns referentials |
