diff options
Diffstat (limited to 'app')
27 files changed, 552 insertions, 61 deletions
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 8bd3da2f9..45b7f55f6 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -36,16 +36,6 @@ class ApplicationController < ActionController::Base end helper_method :current_organisation - def current_offer_workbench - current_organisation.workbenches.find_by_name("Gestion de l'offre") - end - helper_method :current_offer_workbench - - def current_workgroup - current_offer_workbench.workgroup - end - helper_method :current_workgroup - def current_functional_scope functional_scope = current_organisation.sso_attributes.try(:[], "functional_scope") if current_organisation JSON.parse(functional_scope) if functional_scope diff --git a/app/controllers/referentials_controller.rb b/app/controllers/referentials_controller.rb index 0ed3f75dd..5267c15d8 100644 --- a/app/controllers/referentials_controller.rb +++ b/app/controllers/referentials_controller.rb @@ -1,5 +1,6 @@ class ReferentialsController < ChouetteController defaults :resource_class => Referential + before_action :load_workbench include PolicyChecker respond_to :html @@ -30,7 +31,7 @@ class ReferentialsController < ChouetteController def show resource.switch show! do |format| - @referential = @referential.decorate(context: { current_workbench_id: params[:current_workbench_id] } ) + @referential = @referential.decorate() @reflines = lines_collection.paginate(page: params[:page], per_page: 10) @reflines = ReferentialLineDecorator.decorate( @reflines, @@ -141,7 +142,6 @@ class ReferentialsController < ChouetteController if params[:from] source_referential = Referential.find(params[:from]) @referential = Referential.new_from(source_referential, current_functional_scope) - @referential.workbench_id = params[:current_workbench_id] end @referential.data_format = current_organisation.data_format @@ -175,4 +175,12 @@ class ReferentialsController < ChouetteController ) end + def load_workbench + @workbench ||= Workbench.find(params[:workbench_id]) if params[:workbench_id] + @workbench ||= resource&.workbench if params[:id] + @workbench + end + + alias_method :current_workbench, :load_workbench + helper_method :current_workbench end diff --git a/app/controllers/vehicle_journeys_controller.rb b/app/controllers/vehicle_journeys_controller.rb index 9dbb3bc43..14795227c 100644 --- a/app/controllers/vehicle_journeys_controller.rb +++ b/app/controllers/vehicle_journeys_controller.rb @@ -154,7 +154,7 @@ class VehicleJourneysController < ChouetteController private def load_custom_fields - @custom_fields = current_workgroup&.custom_fields_definitions || {} + @custom_fields = referential.workgroup&.custom_fields_definitions || {} end def map_stop_points points diff --git a/app/decorators/referential_decorator.rb b/app/decorators/referential_decorator.rb index 3132cbf92..41cad237d 100644 --- a/app/decorators/referential_decorator.rb +++ b/app/decorators/referential_decorator.rb @@ -22,12 +22,12 @@ class ReferentialDecorator < AF83::Decorator instance_decorator.action_link policy: :clone, secondary: :show do |l| l.content t('actions.clone') - l.href { h.new_referential_path(from: object.id, current_workbench_id: context[:current_workbench_id]) } + l.href { h.duplicate_workbench_referential_path(object) } end instance_decorator.action_link policy: :validate, secondary: :show do |l| l.content t('actions.validate') - l.href { h.referential_select_compliance_control_set_path(object.id) } + l.href { h.select_compliance_control_set_referential_path(object.id) } end instance_decorator.action_link policy: :archive, secondary: :show do |l| diff --git a/app/helpers/referentials_helper.rb b/app/helpers/referentials_helper.rb index 8251377aa..e464ec8a5 100644 --- a/app/helpers/referentials_helper.rb +++ b/app/helpers/referentials_helper.rb @@ -15,4 +15,14 @@ module ReferentialsHelper service = ReferentialOverview.new referential, self render partial: "referentials/overview", locals: {referential: referential, overview: service} end + + def mutual_workbench workbench + current_user.organisation.workbenches.where(workgroup_id: workbench.workgroup_id).last + end + + def duplicate_workbench_referential_path referential + workbench = mutual_workbench referential.workbench + raise "Missing workbench for referential #{referential.name}" unless workbench.present? + new_workbench_referential_path(workbench, from: referential.id) + end end diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js b/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js index 7ab85a1ea..72dbd0152 100644 --- a/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js +++ b/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js @@ -29,11 +29,11 @@ export default class BSelect4 extends Component { val = this.props.selection.selectedJPModal } } - if(this.useAjax()){ - val = val.published_name - } - else{ - if(val){ + if(val){ + if(this.useAjax()){ + val = val.published_name + } + else{ val = val.id } } diff --git a/app/models/chouette/company.rb b/app/models/chouette/company.rb index b3d40ab96..53e412600 100644 --- a/app/models/chouette/company.rb +++ b/app/models/chouette/company.rb @@ -15,6 +15,5 @@ module Chouette [:organizational_unit, :operating_department_name, :code, :phone, :fax, :email, :url, :time_zone] end - end end diff --git a/app/models/chouette/journey_pattern.rb b/app/models/chouette/journey_pattern.rb index aa9fdb810..830e985d9 100644 --- a/app/models/chouette/journey_pattern.rb +++ b/app/models/chouette/journey_pattern.rb @@ -170,5 +170,21 @@ module Chouette end full end + + def set_distances distances + raise "inconsistent data: #{distances.count} values for #{stop_points.count} stops" unless distances.count == stop_points.count + prev = distances[0].to_i + _costs = self.costs + distances[1..-1].each_with_index do |distance, i| + distance = distance.to_i + relative = distance - prev + prev = distance + start, stop = stop_points[i..i+1] + key = "#{start.stop_area_id}-#{stop.stop_area_id}" + _costs[key] ||= {} + _costs[key]["distance"] = relative + end + self.costs = _costs + end end end diff --git a/app/models/chouette/line.rb b/app/models/chouette/line.rb index ba2e2755d..d077d5c9d 100644 --- a/app/models/chouette/line.rb +++ b/app/models/chouette/line.rb @@ -41,6 +41,7 @@ module Chouette validates_presence_of :name + scope :by_text, ->(text) { where('lower(name) LIKE :t or lower(published_name) LIKE :t or lower(objectid) LIKE :t or lower(comment) LIKE :t or lower(number) LIKE :t', t: "%#{text.downcase}%") } @@ -80,6 +81,14 @@ module Chouette line_referential.companies.where(id: ([company_id] + Array(secondary_company_ids)).compact) end + def deactivate + self.deactivated = true + end + + def activate + self.deactivated = false + end + def deactivate! update_attribute :deactivated, true end diff --git a/app/models/chouette/purchase_window.rb b/app/models/chouette/purchase_window.rb index 334493015..157390a21 100644 --- a/app/models/chouette/purchase_window.rb +++ b/app/models/chouette/purchase_window.rb @@ -19,6 +19,7 @@ module Chouette scope :contains_date, ->(date) { where('date ? <@ any (date_ranges)', date) } scope :overlap_dates, ->(date_range) { where('daterange(?, ?) && any (date_ranges)', date_range.first, date_range.last + 1.day) } + scope :matching_dates, ->(date_range) { where('ARRAY[daterange(?, ?)] = date_ranges', date_range.first, date_range.last + 1.day) } def self.ransackable_scopes(auth_object = nil) [:contains_date] diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index 5cc5d8b0d..3729deb7d 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -185,6 +185,12 @@ module Chouette return true end + def full_journey_pattern + journey_pattern = journey_patterns.find_or_create_by registration_number: self.number, name: self.name + journey_pattern.stop_points = self.stop_points + journey_pattern + end + protected def self.vehicle_journeys_timeless(stop_point_id) diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb index bb8747faa..7170dd217 100644 --- a/app/models/chouette/stop_area.rb +++ b/app/models/chouette/stop_area.rb @@ -369,6 +369,14 @@ module Chouette !activated? end + def activate + self.deleted_at = nil + end + + def deactivate + self.deleted_at = Time.now + end + def activate! update_attribute :deleted_at, nil end @@ -384,8 +392,8 @@ module Chouette def country_name return unless country_code - country = ISO3166::Country[country_code] + return unless country country.translations[I18n.locale.to_s] || country.name end diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb index 15b22b671..b76de852a 100644 --- a/app/models/chouette/time_table.rb +++ b/app/models/chouette/time_table.rb @@ -44,10 +44,10 @@ module Chouette attrs << self.int_day_types dates = self.dates dates += TimeTableDate.where(time_table_id: self.id) - attrs << dates.map(&:checksum).map(&:to_s).sort + attrs << dates.map(&:checksum).map(&:to_s).uniq.sort periods = self.periods periods += TimeTablePeriod.where(time_table_id: self.id) - attrs << periods.map(&:checksum).map(&:to_s).sort + attrs << periods.map(&:checksum).map(&:to_s).uniq.sort end end diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb index 1963797d2..6209993de 100644 --- a/app/models/chouette/vehicle_journey.rb +++ b/app/models/chouette/vehicle_journey.rb @@ -143,7 +143,7 @@ module Chouette attrs << self.try(:company).try(:get_objectid).try(:local_id) attrs << self.footnotes.map(&:checksum).sort vjas = self.vehicle_journey_at_stops - vjas += VehicleJourneyAtStop.where(vehicle_journey_id: self.id) + vjas += VehicleJourneyAtStop.where(vehicle_journey_id: self.id) unless self.new_record? attrs << vjas.uniq.sort_by { |s| s.stop_point&.position }.map(&:checksum).sort end end diff --git a/app/models/chouette/vehicle_journey_at_stop.rb b/app/models/chouette/vehicle_journey_at_stop.rb index eda711ade..3b4f35f13 100644 --- a/app/models/chouette/vehicle_journey_at_stop.rb +++ b/app/models/chouette/vehicle_journey_at_stop.rb @@ -41,7 +41,7 @@ module Chouette :arrival_day_offset, I18n.t( 'vehicle_journey_at_stops.errors.day_offset_must_not_exceed_max', - short_id: vehicle_journey.get_objectid.short_id, + short_id: vehicle_journey&.get_objectid&.short_id, max: DAY_OFFSET_MAX + 1 ) ) @@ -52,7 +52,7 @@ module Chouette :departure_day_offset, I18n.t( 'vehicle_journey_at_stops.errors.day_offset_must_not_exceed_max', - short_id: vehicle_journey.get_objectid.short_id, + short_id: vehicle_journey&.get_objectid&.short_id, max: DAY_OFFSET_MAX + 1 ) ) @@ -69,8 +69,8 @@ module Chouette def checksum_attributes [].tap do |attrs| - attrs << self.departure_time.try(:to_s, :time) - attrs << self.arrival_time.try(:to_s, :time) + attrs << self.departure_time&.utc.try(:to_s, :time) + attrs << self.arrival_time&.utc.try(:to_s, :time) attrs << self.departure_day_offset.to_s attrs << self.arrival_day_offset.to_s end diff --git a/app/models/chouette/vehicle_journey_at_stops_day_offset.rb b/app/models/chouette/vehicle_journey_at_stops_day_offset.rb index b2cb90d11..7497cd72c 100644 --- a/app/models/chouette/vehicle_journey_at_stops_day_offset.rb +++ b/app/models/chouette/vehicle_journey_at_stops_day_offset.rb @@ -11,13 +11,19 @@ module Chouette @at_stops.inject(nil) do |prior_stop, stop| next stop if prior_stop.nil? - if stop.arrival_time < prior_stop.departure_time || - stop.arrival_time < prior_stop.arrival_time + # we only compare time of the day, not actual times + stop_arrival_time = stop.arrival_time - stop.arrival_time.to_date.to_time + stop_departure_time = stop.departure_time - stop.departure_time.to_date.to_time + prior_stop_arrival_time = prior_stop.arrival_time - prior_stop.arrival_time.to_date.to_time + prior_stop_departure_time = prior_stop.departure_time - prior_stop.departure_time.to_date.to_time + + if stop_arrival_time < prior_stop_departure_time || + stop_arrival_time < prior_stop_arrival_time arrival_offset += 1 end - if stop.departure_time < stop.arrival_time || - stop.departure_time < prior_stop.departure_time + if stop_departure_time < stop_arrival_time || + stop_departure_time < prior_stop_departure_time departure_offset += 1 end @@ -39,4 +45,4 @@ module Chouette save end end -end
\ No newline at end of file +end diff --git a/app/models/organisation.rb b/app/models/organisation.rb index da7d1fcf3..e8fb4e060 100644 --- a/app/models/organisation.rb +++ b/app/models/organisation.rb @@ -80,4 +80,8 @@ class Organisation < ActiveRecord::Base features && features.include?(feature.to_s) end + def default_workbench + workbenches.default + end + end diff --git a/app/models/referential.rb b/app/models/referential.rb index 509e0412f..09c2e7d34 100644 --- a/app/models/referential.rb +++ b/app/models/referential.rb @@ -51,7 +51,9 @@ class Referential < ActiveRecord::Base belongs_to :stop_area_referential validates_presence_of :stop_area_referential has_many :stop_areas, through: :stop_area_referential + belongs_to :workbench + delegate :workgroup, to: :workbench, allow_nil: true belongs_to :referential_suite diff --git a/app/models/simple_importer.rb b/app/models/simple_importer.rb new file mode 100644 index 000000000..b824d596d --- /dev/null +++ b/app/models/simple_importer.rb @@ -0,0 +1,422 @@ +class SimpleImporter < ActiveRecord::Base + attr_accessor :configuration + + def self.define name + @importers ||= {} + configuration = Configuration.new name + yield configuration + configuration.validate! + @importers[name.to_sym] = configuration + end + + def self.find_configuration name + @importers ||= {} + configuration = @importers[name.to_sym] + raise "Importer not found: #{name}" unless configuration + configuration + end + + def initialize *args + super *args + self.configuration = self.class.find_configuration self.configuration_name + self.journal ||= [] + end + + def configure + new_config = configuration.duplicate + yield new_config + new_config.validate! + self.configuration = new_config + end + + def context + self.configuration.context + end + + def resolve col_name, value, &block + val = block.call(value) + return val if val.present? + @resolution_queue[[col_name.to_s, value]].push({record: @current_record, attribute: @current_attribute, block: block}) + nil + end + + def import opts={} + @verbose = opts.delete :verbose + + + @resolution_queue = Hash.new{|h,k| h[k] = []} + @errors = [] + @messages = [] + @number_of_lines = 0 + @padding = 1 + @current_line = 0 + fail_with_error "File not found: #{self.filepath}" do + @number_of_lines = CSV.read(self.filepath, self.configuration.csv_options).length + @padding = [1, Math.log(@number_of_lines, 10).ceil()].max + end + + + self.configuration.before_actions(:parsing).each do |action| action.call self end + + @statuses = "" + + if ENV["NO_TRANSACTION"] + process_csv_file + else + ActiveRecord::Base.transaction do + process_csv_file + end + end + self.status ||= :success + rescue FailedImport + self.status = :failed + ensure + self.save! + end + + def fail_with_error msg=nil, opts={} + begin + yield + rescue => e + msg = msg.call if msg.is_a?(Proc) + custom_print "\nFAILED: \n errors: #{msg}\n exception: #{e.message}\n#{e.backtrace.join("\n")}", color: :red unless self.configuration.ignore_failures + push_in_journal({message: msg, error: e.message, event: :error, kind: :error}) + @new_status = colorize("x", :red) + if self.configuration.ignore_failures + raise FailedRow if opts[:abort_row] + else + raise FailedImport + end + end + end + + def encode_string s + s.encode("utf-8").force_encoding("utf-8") + end + + def dump_csv_from_context + filepath = "./#{self.configuration_name}_#{Time.now.strftime "%y%m%d%H%M"}.csv" + # for some reason, context[:csv].to_csv does not work + CSV.open(filepath, 'w') do |csv| + header = true + context[:csv].each do |row| + csv << row.headers if header + csv << row.fields + header = false + end + end + log "CSV file dumped in #{filepath}" + end + + def log msg, opts={} + msg = colorize msg, opts[:color] if opts[:color] + if opts[:append] + @messages[-1] = (@messages[-1] || "") + msg + else + @messages << msg + end + print_state + end + + protected + + def process_csv_file + self.configuration.before_actions(:all).each do |action| action.call self end + log "Starting import ...", color: :green + + (context[:csv] || CSV.read(filepath, self.configuration.csv_options)).each do |row| + @current_row = row + @new_status = nil + begin + handle_row row + fail_with_error ->(){ @current_record.errors.messages } do + new_record = @current_record&.new_record? + @new_status ||= new_record ? colorize("✓", :green) : colorize("-", :orange) + @event = new_record ? :creation : :update + self.configuration.before_actions(:each_save).each do |action| + action.call self, @current_record + end + ### This could fail if the record has a mandatory relation which is not yet resolved + ### TODO: do not attempt to save if the current record if waiting for resolution + ### and fail at the end if there remains unresolved relations + if @current_record + if self.configuration.ignore_failures + unless @current_record.save + @new_status = colorize("x", :red) + push_in_journal({message: "errors: #{@current_record.errors.messages}", error: "invalid record", event: :error, kind: :error}) + end + else + @current_record.save! + end + end + self.configuration.after_actions(:each_save).each do |action| + action.call self, @current_record + end + end + rescue FailedRow + @new_status = colorize("x", :red) + end + push_in_journal({event: @event, kind: :log}) if @current_record&.valid? + @statuses += @new_status + self.configuration.columns.each do |col| + if @current_record && col.name && @resolution_queue.any? + val = @current_record.send col[:attribute] + (@resolution_queue.delete([col.name, val]) || []).each do |res| + record = res[:record] + attribute = res[:attribute] + value = res[:block].call(val, record) + record.send "#{attribute}=", value + record.save! + end + end + end + print_state + @current_line += 1 + end + + begin + self.configuration.after_actions(:all).each do |action| + action.call self + end + rescue FailedRow + end + end + + def handle_row row + if self.configuration.get_custom_handler + instance_exec(row, &self.configuration.get_custom_handler) + else + fail_with_error "", abort_row: true do + @current_record = self.configuration.find_record row + self.configuration.columns.each do |col| + @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) + val = instance_exec(row[col.name], &val) + else + val = row[col.name] + end + else + push_in_journal({event: :column_not_found, message: "Column not found: #{col.name}", kind: :warning}) + self.status ||= :success_with_warnings + end + end + + if val.nil? && col.required? + raise "MISSING VALUE FOR COLUMN #{col.name}" + end + val = encode_string(val) if val.is_a?(String) + @current_record.send "#{@current_attribute}=", val if val + end + end + end + end + + def push_in_journal data + line = @current_line + 1 + line += 1 if configuration.headers + self.journal.push data.update(line: line, row: @current_row) + if data[:kind] == :error || data[:kind] == :warning + @errors.push data + end + end + + def colorize txt, color + color = { + red: "31", + green: "32", + orange: "33", + }[color] || "33" + "\e[#{color}m#{txt}\e[0m" + end + + def print_state + return unless @verbose + + @status_width ||= begin + term_width = %x(tput cols).to_i + term_width - @padding - 10 + rescue + 100 + end + + @status_height ||= begin + term_height = %x(tput lines).to_i + term_height - 3 + rescue + 50 + end + + full_status = @statuses || "" + full_status = full_status.last(@status_width*10) || "" + padding_size = [(@number_of_lines - @current_line - 1), (@status_width - full_status.size/10)].min + full_status = "#{full_status}#{"."*[padding_size, 0].max}" + + msg = "#{"%#{@padding}d" % (@current_line + 1)}/#{@number_of_lines}: #{full_status}" + + lines_count = [(@status_height / 2) - 3, 1].max + + if @messages.any? + msg += "\n\n" + msg += colorize "=== MESSAGES (#{@messages.count}) ===\n", :green + msg += "[...]\n" if @messages.count > lines_count + msg += @messages.last(lines_count).join("\n") + msg += "\n"*[lines_count-@messages.count, 0].max + end + + if @errors.any? + msg += "\n\n" + msg += colorize "=== ERRORS (#{@errors.count}) ===\n", :red + msg += "[...]\n" if @errors.count > lines_count + msg += @errors.last(lines_count).map do |j| + kind = j[:kind] + kind = colorize(kind, kind == :error ? :red : :orange) + encode_string "[#{kind}]\t\tL#{j[:line]}\t#{j[:error]}\t\t#{j[:message]}" + end.join("\n") + end + custom_print msg, clear: true + end + + def custom_print msg, opts={} + return unless @verbose + out = "" + msg = colorize(msg, opts[:color]) if opts[:color] + puts "\e[H\e[2J" if opts[:clear] + out += msg + print out + end + + class FailedImport < RuntimeError + end + + class FailedRow < RuntimeError + end + + class Configuration + attr_accessor :model, :headers, :separator, :key, :context, :encoding, :ignore_failures, :scope + attr_reader :columns + + def initialize import_name, opts={} + @import_name = import_name + @key = opts[:key] || "id" + @headers = opts.has_key?(:headers) ? opts[:headers] : true + @separator = opts[:separator] || "," + @encoding = opts[:encoding] + @columns = opts[:columns] || [] + @model = opts[:model] + @custom_handler = opts[:custom_handler] + @before = opts[:before] + @after = opts[:after] + @ignore_failures = opts[:ignore_failures] + @context = opts[:context] || {} + @scope = opts[:scope] + end + + def duplicate + Configuration.new @import_name, self.options + end + + def options + { + key: @key, + headers: @headers, + separator: @separator, + encoding: @encoding, + columns: @columns.map(&:duplicate), + model: model, + custom_handler: @custom_handler, + before: @before, + after: @after, + ignore_failures: @ignore_failures, + context: @context, + scope: @scope + } + end + + def validate! + raise "Incomplete configuration, missing model for #{@import_name}" unless model.present? + end + + def attribute_for_col col_name + column = self.columns.find{|c| c.name == col_name} + column && column[:attribute] || col_name + end + + def record_scope + _scope = @scope + _scope = instance_exec(&_scope) if _scope.is_a?(Proc) + _scope || model + end + + def find_record attrs + record_scope.find_or_initialize_by(attribute_for_col(@key) => attrs[@key.to_s]) + end + + def csv_options + { + headers: self.headers, + col_sep: self.separator, + encoding: self.encoding + } + end + + def add_column name, opts={} + @columns.push Column.new({name: name.to_s}.update(opts)) + end + + def add_value attribute, value + @columns.push Column.new({attribute: attribute, value: value}) + end + + def before group=:all, &block + @before ||= Hash.new{|h, k| h[k] = []} + @before[group].push block + end + + def after group=:all, &block + @after ||= Hash.new{|h, k| h[k] = []} + @after[group].push block + end + + def before_actions group=:all + @before ||= Hash.new{|h, k| h[k] = []} + @before[group] + end + + def after_actions group=:all + @after ||= Hash.new{|h, k| h[k] = []} + @after[group] + end + + def custom_handler &block + @custom_handler = block + end + + def get_custom_handler + @custom_handler + end + + class Column + attr_accessor :name + def initialize opts={} + @name = opts[:name] + @options = opts + @options[:attribute] ||= @name + end + + def duplicate + Column.new @options.dup + end + + def required? + !!@options[:required] + end + + def [](key) + @options[key] + end + end + end +end diff --git a/app/models/user.rb b/app/models/user.rb index 1342f60ed..31e634415 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -15,6 +15,7 @@ class User < ActiveRecord::Base # Setup accessible (or protected) attributes for your model # attr_accessible :email, :password, :current_password, :password_confirmation, :remember_me, :name, :organisation_attributes belongs_to :organisation + has_many :workbenches, through: :organisation accepts_nested_attributes_for :organisation validates :organisation, :presence => true diff --git a/app/models/workbench.rb b/app/models/workbench.rb index b80fa64ac..eb53af7aa 100644 --- a/app/models/workbench.rb +++ b/app/models/workbench.rb @@ -1,4 +1,6 @@ class Workbench < ActiveRecord::Base + DEFAULT_WORKBENCH_NAME = "Gestion de l'offre" + include ObjectidFormatterSupport belongs_to :organisation belongs_to :line_referential @@ -40,6 +42,11 @@ class Workbench < ActiveRecord::Base end end + def self.default + self.last if self.count == 1 + where(name: DEFAULT_WORKBENCH_NAME).last + end + private def initialize_output diff --git a/app/views/dashboards/_dashboard.html.slim b/app/views/dashboards/_dashboard.html.slim index 05257a766..7f78934a6 100644 --- a/app/views/dashboards/_dashboard.html.slim +++ b/app/views/dashboards/_dashboard.html.slim @@ -14,25 +14,25 @@ - if workbench.referentials.present? .list-group - workbench.referentials.limit(5).each do |referential| - = link_to referential.name, referential_path(referential, workbench_id: referential.workbench_id, current_workbench_id: workbench.id), class: 'list-group-item' + = 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 - = link_to I18n.t("activerecord.models.calendar", count: @dashboard.current_organisation.calendars.size), workgroup_calendars_path(current_workgroup) - div - = link_to '', workgroup_calendars_path(current_workgroup), class: ' fa fa-chevron-right pull-right' - - if @dashboard.current_organisation.calendars.present? - .list-group - - @dashboard.current_organisation.calendars.order("updated_at desc").limit(5).each do |calendar| - = link_to calendar.name, workgroup_calendars_path(current_workgroup, calendar), class: 'list-group-item' - - else - .panel-body - em.small.text-muted - = t('dasboard.calendars.none') + .panel.panel-default + .panel-heading + h3.panel-title.with_actions + = link_to I18n.t("activerecord.models.calendar", count: @dashboard.current_organisation.calendars.size), workgroup_calendars_path(workbench.workgroup) + div + = link_to '', workgroup_calendars_path(workbench.workgroup), class: ' fa fa-chevron-right pull-right' + - if @dashboard.current_organisation.calendars.present? + .list-group + - @dashboard.current_organisation.calendars.order("updated_at desc").limit(5).each do |calendar| + = link_to calendar.name, workgroup_calendars_path(workbench.workgroup, calendar), class: 'list-group-item' + - else + .panel-body + em.small.text-muted + = t('dasboard.calendars.none') .col-lg-6.col-md-6.col-sm-6.col-xs-12 .panel.panel-default 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 1b7293d21..cb0698cf8 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 @@ -24,14 +24,14 @@ #miTwo.panel-collapse.collapse .list-group - - if current_user - = link_to workbench_path(current_offer_workbench), class: "list-group-item #{params[:controller] == 'workbenches' ? 'active' : ''}" do + - current_user.workbenches.each do |current_workbench| + = link_to workbench_path(current_workbench), class: "list-group-item #{params[:controller] == 'workbenches' ? 'active' : ''}" do span Jeux de données - = link_to workbench_imports_path(current_offer_workbench), class: "list-group-item #{(params[:controller] == 'imports') ? 'active' : ''}" do + = link_to workbench_imports_path(current_workbench), class: "list-group-item #{(params[:controller] == 'imports') ? 'active' : ''}" do span Import - = link_to workgroup_calendars_path(current_workgroup), class: 'list-group-item' do + = 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_offer_workbench), class: 'list-group-item' do + = link_to workbench_compliance_check_sets_path(current_workbench), class: 'list-group-item' do span Rapport de contrôle = link_to compliance_control_sets_path, class: 'list-group-item' do span Jeux de contrôle diff --git a/app/views/referentials/_form.html.slim b/app/views/referentials/_form.html.slim index 9927f05bd..1e59ab566 100644 --- a/app/views/referentials/_form.html.slim +++ b/app/views/referentials/_form.html.slim @@ -1,4 +1,6 @@ -= simple_form_for @referential, html: {class: 'form-horizontal', id: 'referential_form'}, wrapper: :horizontal_form do |form| +- url = @referential.new_record? ? [@workbench, @referential] : [@referential] + += simple_form_for @referential, url: url, html: {class: 'form-horizontal', id: 'referential_form'}, wrapper: :horizontal_form do |form| .row .col-lg-12 diff --git a/app/views/referentials/select_compliance_control_set.html.slim b/app/views/referentials/select_compliance_control_set.html.slim index 87a888c0a..69c87aab2 100644 --- a/app/views/referentials/select_compliance_control_set.html.slim +++ b/app/views/referentials/select_compliance_control_set.html.slim @@ -2,7 +2,7 @@ .container-fluid .row .col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-10.col-sm-offset-1 - = form_tag validate_referential_path(params[:referential_id]), {class: 'form-horizontal', id: 'select_compliance_control_set', wrapper: :horizontal_form} do + = form_tag validate_referential_path(@referential), {class: 'form-horizontal', id: 'select_compliance_control_set', wrapper: :horizontal_form} do .row .col-lg-12 .form-group diff --git a/app/views/stif/dashboards/_dashboard.html.slim b/app/views/stif/dashboards/_dashboard.html.slim index c28696a94..83a2106bb 100644 --- a/app/views/stif/dashboards/_dashboard.html.slim +++ b/app/views/stif/dashboards/_dashboard.html.slim @@ -47,7 +47,7 @@ - if @dashboard.referentials.present? .list-group - @dashboard.referentials.first(5).each_with_index do |referential, i| - = link_to referential.name, referential_path(referential, workbench_id: referential.workbench_id, current_workbench_id: @dashboard.workbench.id), class: 'list-group-item' if i < 6 + = link_to referential.name, referential_path(referential), class: 'list-group-item' if i < 6 - else .panel-body @@ -60,12 +60,12 @@ span.badge.ml-xs = @dashboard.calendars.count if @dashboard.calendars.present? div - = link_to '', workgroup_calendars_path(current_workgroup), class: ' fa fa-chevron-right pull-right', title: t('.see') + = link_to '', workgroup_calendars_path(@dashboard.workbench.workgroup), class: ' fa fa-chevron-right pull-right', title: t('.see') - if @dashboard.calendars.present? .list-group - @dashboard.calendars.first(5).each_with_index do |calendar, i| - = link_to calendar.name, workgroup_calendar_path(current_workgroup, calendar), class: 'list-group-item' if i < 6 + = link_to calendar.name, workgroup_calendar_path(@dashboard.workbench.workgroup, calendar), class: 'list-group-item' if i < 6 - else .panel-body diff --git a/app/views/workbenches/show.html.slim b/app/views/workbenches/show.html.slim index aae34c51b..159aa8ea2 100644 --- a/app/views/workbenches/show.html.slim +++ b/app/views/workbenches/show.html.slim @@ -5,7 +5,7 @@ .col-lg-12.text-right - if policy(Referential).create? = link_to t('actions.import'), workbench_imports_path(@workbench), class: 'btn btn-primary' - = link_to t('actions.add'), new_referential_path(workbench_id: @workbench), class: 'btn btn-primary' + = link_to t('actions.add'), new_workbench_referential_path(@workbench), class: 'btn btn-primary' = link_to t('workbenches.actions.show_output'), workbench_output_path(@workbench), class: 'btn btn-primary' .page_content @@ -25,7 +25,7 @@ key: :name, \ attribute: 'name', \ link_to: lambda do |referential| \ - referential_path(referential, current_workbench_id: params[:id]) \ + referential_path(referential) \ end \ ), \ TableBuilderHelper::Column.new( \ |
