diff options
16 files changed, 101 insertions, 30 deletions
| diff --git a/app/controllers/journey_patterns_collections_controller.rb b/app/controllers/journey_patterns_collections_controller.rb index db92d48f3..c1a307464 100644 --- a/app/controllers/journey_patterns_collections_controller.rb +++ b/app/controllers/journey_patterns_collections_controller.rb @@ -25,6 +25,8 @@ class JourneyPatternsCollectionsController < ChouetteController      @q = @q.includes(:stop_points)      @ppage = 10      @journey_patterns ||= @q.paginate(page: params[:page], per_page: @ppage).order(:name) +    @custom_fields = Chouette::JourneyPattern.custom_fields_definitions(referential.workgroup) +      respond_to do |format|        format.json do          @journey_patterns = @journey_patterns.includes(stop_points: {stop_area: :stop_area_referential}) diff --git a/app/javascript/vehicle_journeys/components/tools/CustomFieldsInputs.js b/app/javascript/helpers/CustomFieldsInputs.js index 827c36b76..abc8097d5 100644 --- a/app/javascript/vehicle_journeys/components/tools/CustomFieldsInputs.js +++ b/app/javascript/helpers/CustomFieldsInputs.js @@ -34,8 +34,21 @@ export default class CustomFieldsInputs extends Component {          ref={'custom_fields.' + cf.code}          className='form-control'          disabled={this.props.disabled} -        defaultValue={cf.value} -        onChange={(e) => this.props.onUpdate(cf.code, e.target.value) } +        value={cf.value} +        onChange={(e) => {this.props.onUpdate(cf.code, e.target.value); this.forceUpdate()} } +        /> +    ) +  } + +  integerInput(cf){ +    return( +      <input +        type='number' +        ref={'custom_fields.' + cf.code} +        className='form-control' +        disabled={this.props.disabled} +        value={cf.value} +        onChange={(e) => {this.props.onUpdate(cf.code, e.target.value); this.forceUpdate()} }          />      )    } diff --git a/app/javascript/journey_patterns/components/CreateModal.js b/app/javascript/journey_patterns/components/CreateModal.js index 946c13d9c..51f6f6c1b 100644 --- a/app/javascript/journey_patterns/components/CreateModal.js +++ b/app/javascript/journey_patterns/components/CreateModal.js @@ -1,15 +1,17 @@  import React, { Component } from 'react'  import PropTypes from 'prop-types'  import actions from '../actions' +import CustomFieldsInputs from '../../helpers/CustomFieldsInputs'  export default class CreateModal extends Component {    constructor(props) {      super(props) +    this.custom_fields = _.assign({}, this.props.custom_fields)    }    handleSubmit() {      if(actions.validateFields(this.refs) == true) { -      this.props.onAddJourneyPattern(this.refs) +      this.props.onAddJourneyPattern(_.assign({}, this.refs, {custom_fields: this.custom_fields}))        this.props.onModalClose()        $('#NewJourneyPatternModal').modal('hide')      } @@ -78,8 +80,14 @@ export default class CreateModal extends Component {                                      />                                  </div>                                </div> +                              <CustomFieldsInputs +                                values={this.props.custom_fields} +                                onUpdate={(code, value) => this.custom_fields[code]["value"] = value} +                                disabled={false} +                              />                              </div>                            </div> +                            <div className='modal-footer'>                              <button                                className='btn btn-link' diff --git a/app/javascript/journey_patterns/components/EditModal.js b/app/javascript/journey_patterns/components/EditModal.js index 1960849fb..a23a57f96 100644 --- a/app/javascript/journey_patterns/components/EditModal.js +++ b/app/javascript/journey_patterns/components/EditModal.js @@ -1,19 +1,27 @@  import React, { Component } from 'react'  import PropTypes from 'prop-types'  import actions from '../actions' +import CustomFieldsInputs from '../../helpers/CustomFieldsInputs'  export default class EditModal extends Component {    constructor(props) {      super(props) +    this.updateValue = this.updateValue.bind(this)    }    handleSubmit() {      if(actions.validateFields(this.refs) == true) { -      this.props.saveModal(this.props.modal.modalProps.index, this.refs) +      this.props.saveModal(this.props.modal.modalProps.index, _.assign({}, this.refs, {custom_fields: this.custom_fields}))        $('#JourneyPatternModal').modal('hide')      }    } +  updateValue(attribute, e) { +    actions.resetValidation(e.currentTarget) +    this.props.modal.modalProps.journeyPattern[attribute] = e.target.value +    this.forceUpdate() +  } +    renderModalTitle() {      if (this.props.editMode) {        return ( @@ -28,6 +36,9 @@ export default class EditModal extends Component {    }    render() { +    if(this.props.modal.modalProps.journeyPattern){ +      this.custom_fields = _.assign({}, this.props.modal.modalProps.journeyPattern.custom_fields) +    }      return (        <div className={ 'modal fade ' + ((this.props.modal.type == 'edit') ? 'in' : '') } id='JourneyPatternModal'>          <div className='modal-container'> @@ -48,8 +59,8 @@ export default class EditModal extends Component {                          className='form-control'                          disabled={!this.props.editMode}                          id={this.props.modal.modalProps.index} -                        defaultValue={this.props.modal.modalProps.journeyPattern.name} -                        onKeyDown={(e) => actions.resetValidation(e.currentTarget)} +                        value={this.props.modal.modalProps.journeyPattern.name} +                        onChange={(e) => this.updateValue('name', e)}                          required                          />                      </div> @@ -64,8 +75,8 @@ export default class EditModal extends Component {                              className='form-control'                              disabled={!this.props.editMode}                              id={this.props.modal.modalProps.index} -                            defaultValue={this.props.modal.modalProps.journeyPattern.published_name} -                            onKeyDown={(e) => actions.resetValidation(e.currentTarget)} +                            value={this.props.modal.modalProps.journeyPattern.published_name} +                            onChange={(e) => this.updateValue('published_name', e)}                              required                              />                          </div> @@ -79,12 +90,19 @@ export default class EditModal extends Component {                              className='form-control'                              disabled={!this.props.editMode}                              id={this.props.modal.modalProps.index} -                            defaultValue={this.props.modal.modalProps.journeyPattern.registration_number} -                            onKeyDown={(e) => actions.resetValidation(e.currentTarget)} +                            value={this.props.modal.modalProps.journeyPattern.registration_number} +                            onChange={(e) => this.updateValue('registration_number', e)}                              />                          </div>                        </div>                      </div> +                    <div className='row'> +                      <CustomFieldsInputs +                        values={this.props.modal.modalProps.journeyPattern.custom_fields} +                        onUpdate={(code, value) => this.custom_fields[code]["value"] = value} +                        disabled={!this.props.editMode} +                      /> +                    </div>                      <div>                        <label className='control-label'>{I18n.attribute_name('journey_pattern', 'checksum')}</label>                          <input @@ -92,7 +110,7 @@ export default class EditModal extends Component {                          ref='checksum'                          className='form-control'                          disabled='disabled' -                        defaultValue={this.props.modal.modalProps.journeyPattern.checksum} +                        value={this.props.modal.modalProps.journeyPattern.checksum}                          />                      </div>                    </div> diff --git a/app/javascript/journey_patterns/containers/AddJourneyPattern.js b/app/javascript/journey_patterns/containers/AddJourneyPattern.js index b093fd111..9e85afd5e 100644 --- a/app/javascript/journey_patterns/containers/AddJourneyPattern.js +++ b/app/javascript/journey_patterns/containers/AddJourneyPattern.js @@ -7,7 +7,8 @@ const mapStateToProps = (state) => {      modal: state.modal,      journeyPatterns: state.journeyPatterns,      editMode: state.editMode, -    status: state.status +    status: state.status, +    custom_fields: state.custom_fields    }  } diff --git a/app/javascript/journey_patterns/containers/Modal.js b/app/javascript/journey_patterns/containers/Modal.js index 33ee8583c..fc04843e4 100644 --- a/app/javascript/journey_patterns/containers/Modal.js +++ b/app/javascript/journey_patterns/containers/Modal.js @@ -7,7 +7,8 @@ const mapStateToProps = (state) => {    return {      editMode: state.editMode,      modal: state.modal, -    journeyPattern: state.journeyPattern +    journeyPattern: state.journeyPattern, +    custom_fields: state.custom_fields,    }  } diff --git a/app/javascript/journey_patterns/reducers/index.js b/app/javascript/journey_patterns/reducers/index.js index 2ffaf86d4..d3a1d29a2 100644 --- a/app/javascript/journey_patterns/reducers/index.js +++ b/app/javascript/journey_patterns/reducers/index.js @@ -12,7 +12,8 @@ const journeyPatternsApp = combineReducers({    journeyPatterns,    pagination,    stopPointsList, -  modal +  modal, +  custom_fields: (state = [], action) => state  })  export default journeyPatternsApp diff --git a/app/javascript/journey_patterns/reducers/journeyPatterns.js b/app/javascript/journey_patterns/reducers/journeyPatterns.js index b046f2b38..1a6a27da6 100644 --- a/app/javascript/journey_patterns/reducers/journeyPatterns.js +++ b/app/javascript/journey_patterns/reducers/journeyPatterns.js @@ -103,7 +103,8 @@ export default function journeyPatterns (state = [], action)  {            return _.assign({}, j, {              name: action.data.name.value,              published_name: action.data.published_name.value, -            registration_number: action.data.registration_number.value +            registration_number: action.data.registration_number.value, +            custom_fields: action.data.custom_fields,            })          } else {            return j diff --git a/app/javascript/packs/journey_patterns/index.js b/app/javascript/packs/journey_patterns/index.js index 075eea13a..bd7df2634 100644 --- a/app/javascript/packs/journey_patterns/index.js +++ b/app/javascript/packs/journey_patterns/index.js @@ -34,7 +34,8 @@ var initialState = {      type: '',      modalProps: {},      confirmModal: {} -  } +  }, +  custom_fields: window.custom_fields  }  // const loggerMiddleware = createLogger() diff --git a/app/javascript/vehicle_journeys/components/tools/CreateModal.js b/app/javascript/vehicle_journeys/components/tools/CreateModal.js index f49b51f08..1d470cd43 100644 --- a/app/javascript/vehicle_journeys/components/tools/CreateModal.js +++ b/app/javascript/vehicle_journeys/components/tools/CreateModal.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'  import actions from '../../actions'  import MissionSelect2 from './select2s/MissionSelect2'  import CompanySelect2 from './select2s/CompanySelect2' -import CustomFieldsInputs from './CustomFieldsInputs' +import CustomFieldsInputs from '../../../helpers/CustomFieldsInputs'  export default class CreateModal extends Component {    constructor(props) { diff --git a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js index e4e266c79..60d982845 100644 --- a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js +++ b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js @@ -2,7 +2,7 @@ import React, { Component } from 'react'  import PropTypes from 'prop-types'  import actions from '../../actions'  import CompanySelect2 from './select2s/CompanySelect2' -import CustomFieldsInputs from './CustomFieldsInputs' +import CustomFieldsInputs from '../../../helpers/CustomFieldsInputs'  export default class EditVehicleJourney extends Component {    constructor(props) { diff --git a/app/models/chouette/journey_pattern.rb b/app/models/chouette/journey_pattern.rb index 830a6a808..5b5015107 100644 --- a/app/models/chouette/journey_pattern.rb +++ b/app/models/chouette/journey_pattern.rb @@ -2,6 +2,7 @@ module Chouette    class JourneyPattern < Chouette::TridentActiveRecord      has_metadata      include ChecksumSupport +    include CustomFieldsSupport      include JourneyPatternRestrictions      include ObjectidSupport @@ -52,12 +53,19 @@ module Chouette      end      def self.state_permited_attributes item -      { +      attrs = {          name: item['name'],          published_name: item['published_name'],          registration_number: item['registration_number'],          costs: item['costs']        } +      attrs["custom_field_values"] = Hash[ +        *(item["custom_fields"] || {}) +          .map { |k, v| [k, v["value"]] } +          .flatten +      ] + +      attrs      end      def self.state_create_instance route, item diff --git a/app/views/api/v1/journey_patterns/show.rabl b/app/views/api/v1/journey_patterns/show.rabl index aac66b6f3..d02781cfa 100644 --- a/app/views/api/v1/journey_patterns/show.rabl +++ b/app/views/api/v1/journey_patterns/show.rabl @@ -1,7 +1,7 @@  object @journey_pattern  extends "api/v1/trident_objects/show" -[:id, :name, :published_name, :registration_number, :comment, :checksum].each do |attr| +[:id, :name, :published_name, :registration_number, :comment, :checksum, :custom_fields].each do |attr|    attributes attr, :unless => lambda { |m| m.send( attr).nil?}  end diff --git a/app/views/journey_patterns_collections/show.html.slim b/app/views/journey_patterns_collections/show.html.slim index b389a1da7..38c7f1b1b 100644 --- a/app/views/journey_patterns_collections/show.html.slim +++ b/app/views/journey_patterns_collections/show.html.slim @@ -20,5 +20,6 @@    | window.perms = #{raw @perms};    | window.features = #{raw @features};    | window.routeCostsUrl = "#{costs_referential_line_route_url(@referential, @route.line, @route, format: :json).html_safe}"; - +  | window.custom_fields = #{(@custom_fields.to_json).html_safe}; +    = javascript_pack_tag 'journey_patterns/index.js' diff --git a/db/migrate/20180416065012_add_custom_field_values_to_journey_patterns.rb b/db/migrate/20180416065012_add_custom_field_values_to_journey_patterns.rb new file mode 100644 index 000000000..df114488c --- /dev/null +++ b/db/migrate/20180416065012_add_custom_field_values_to_journey_patterns.rb @@ -0,0 +1,5 @@ +class AddCustomFieldValuesToJourneyPatterns < ActiveRecord::Migration +  def change +    add_column :journey_patterns, :custom_field_values, :jsonb +  end +end diff --git a/db/schema.rb b/db/schema.rb index 7e0e9c2b5..d20c9f1f7 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,13 +11,14 @@  #  # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180319043333) do +ActiveRecord::Schema.define(version: 20180416065012) do    # These are extensions that must be enabled in order to support this database    enable_extension "plpgsql" -  enable_extension "postgis"    enable_extension "hstore" +  enable_extension "postgis"    enable_extension "unaccent" +  enable_extension "objectid"    create_table "access_links", id: :bigserial, force: :cascade do |t|      t.integer  "access_point_id",                        limit: 8 @@ -92,9 +93,9 @@ ActiveRecord::Schema.define(version: 20180319043333) do      t.integer   "organisation_id", limit: 8      t.datetime  "created_at"      t.datetime  "updated_at" -    t.integer   "workgroup_id",    limit: 8      t.integer   "int_day_types"      t.date      "excluded_dates",                            array: true +    t.integer   "workgroup_id",    limit: 8      t.jsonb     "metadata",                  default: {}    end @@ -121,6 +122,7 @@ ActiveRecord::Schema.define(version: 20180319043333) do      t.datetime "updated_at"      t.date     "end_date"      t.string   "date_type" +    t.string   "mode"    end    add_index "clean_ups", ["referential_id"], name: "index_clean_ups_on_referential_id", using: :btree @@ -143,10 +145,11 @@ ActiveRecord::Schema.define(version: 20180319043333) do      t.text     "import_xml"      t.datetime "created_at"      t.datetime "updated_at" -    t.jsonb    "custom_field_values" +    t.jsonb    "custom_field_values",                 default: {}      t.jsonb    "metadata",                            default: {}    end +  add_index "companies", ["line_referential_id", "registration_number"], name: "index_companies_on_referential_id_and_registration_number", using: :btree    add_index "companies", ["line_referential_id"], name: "index_companies_on_line_referential_id", using: :btree    add_index "companies", ["objectid"], name: "companies_objectid_key", unique: true, using: :btree    add_index "companies", ["registration_number"], name: "companies_registration_number_key", using: :btree @@ -441,7 +444,7 @@ ActiveRecord::Schema.define(version: 20180319043333) do    add_index "import_messages", ["resource_id"], name: "index_import_messages_on_resource_id", using: :btree    create_table "import_resources", id: :bigserial, force: :cascade do |t| -    t.integer  "import_id",     limit: 8 +    t.integer  "import_id",      limit: 8      t.string   "status"      t.datetime "created_at"      t.datetime "updated_at" @@ -449,9 +452,13 @@ ActiveRecord::Schema.define(version: 20180319043333) do      t.string   "reference"      t.string   "name"      t.hstore   "metrics" +    t.integer  "referential_id" +    t.integer  "parent_id"    end    add_index "import_resources", ["import_id"], name: "index_import_resources_on_import_id", using: :btree +  add_index "import_resources", ["parent_id"], name: "index_import_resources_on_parent_id", using: :btree +  add_index "import_resources", ["referential_id"], name: "index_import_resources_on_referential_id", using: :btree    create_table "imports", id: :bigserial, force: :cascade do |t|      t.string   "status" @@ -509,6 +516,7 @@ ActiveRecord::Schema.define(version: 20180319043333) do      t.string   "data_source_ref"      t.json     "costs"      t.jsonb    "metadata",                          default: {} +    t.jsonb    "custom_field_values"    end    add_index "journey_patterns", ["objectid"], name: "journey_patterns_objectid_key", unique: true, using: :btree @@ -585,6 +593,7 @@ ActiveRecord::Schema.define(version: 20180319043333) do      t.jsonb    "metadata",                                  default: {}    end +  add_index "lines", ["line_referential_id", "registration_number"], name: "index_lines_on_referential_id_and_registration_number", using: :btree    add_index "lines", ["line_referential_id"], name: "index_lines_on_line_referential_id", using: :btree    add_index "lines", ["objectid"], name: "lines_objectid_key", unique: true, using: :btree    add_index "lines", ["registration_number"], name: "lines_registration_number_key", using: :btree @@ -857,14 +866,15 @@ ActiveRecord::Schema.define(version: 20180319043333) do      t.integer  "waiting_time"      t.string   "kind"      t.jsonb    "localized_names" +    t.json     "custom_field_values"      t.datetime "confirmed_at" -    t.jsonb    "custom_field_values"      t.jsonb    "metadata",                                                            default: {}    end    add_index "stop_areas", ["name"], name: "index_stop_areas_on_name", using: :btree    add_index "stop_areas", ["objectid"], name: "stop_areas_objectid_key", unique: true, using: :btree    add_index "stop_areas", ["parent_id"], name: "index_stop_areas_on_parent_id", using: :btree +  add_index "stop_areas", ["stop_area_referential_id", "registration_number"], name: "index_stop_areas_on_referential_id_and_registration_number", using: :btree    add_index "stop_areas", ["stop_area_referential_id"], name: "index_stop_areas_on_stop_area_referential_id", using: :btree    create_table "stop_areas_stop_areas", id: false, force: :cascade do |t| @@ -1058,9 +1068,9 @@ ActiveRecord::Schema.define(version: 20180319043333) do    add_index "vehicle_journeys", ["route_id"], name: "index_vehicle_journeys_on_route_id", using: :btree    create_table "versions", id: :bigserial, force: :cascade do |t| -    t.string   "item_type",            null: false -    t.integer  "item_id",    limit: 8, null: false -    t.string   "event",                null: false +    t.string   "item_type",  null: false +    t.integer  "item_id",    null: false +    t.string   "event",      null: false      t.string   "whodunnit"      t.text     "object"      t.datetime "created_at" @@ -1114,6 +1124,7 @@ ActiveRecord::Schema.define(version: 20180319043333) do    add_foreign_key "compliance_controls", "compliance_control_blocks"    add_foreign_key "compliance_controls", "compliance_control_sets"    add_foreign_key "group_of_lines_lines", "group_of_lines", name: "groupofline_group_fkey", on_delete: :cascade +  add_foreign_key "import_resources", "referentials"    add_foreign_key "journey_frequencies", "timebands", on_delete: :nullify    add_foreign_key "journey_frequencies", "vehicle_journeys", on_delete: :nullify    add_foreign_key "journey_patterns", "routes", name: "jp_route_fkey", on_delete: :cascade | 
