sipp11 6 years ago
parent
commit
8d311d5070
  1. 17
      src/components/FareAttributesForm.js
  2. 4
      src/components/FareList.js
  3. 65
      src/components/FareRulesForm.js
  4. 16
      src/components/StopForm.js
  5. 41
      src/components/parts/SelectOptions.js
  6. 4
      src/constants/Api.js
  7. 15
      src/reducers/farerule.js
  8. 11
      src/utils/index.js

17
src/components/FareAttributesForm.js

@ -17,23 +17,12 @@ import {
PaymentMethodChoices, TransferChoices PaymentMethodChoices, TransferChoices
} from '../constants/choices' } from '../constants/choices'
import { getItemFromList, getAgencyAsyncSelect } from '../utils' import { getItemFromList, getAgencyAsyncSelect } from '../utils'
import { AgencyOption } from './parts/SelectOptions'
const StyledFareAttributesForm = styled.div` const StyledFareAttributesForm = styled.div`
padding: 1rem; padding: 1rem;
background: #fafafa; background: #fafafa;
`; `
const AgencyOption = (props) => {
const { agency_id, name } = props.data
return (
<components.Option {...props}>
<code>{agency_id}</code> {name}
</components.Option>
)
}
class FareAttributesForm extends Component { class FareAttributesForm extends Component {
@ -159,7 +148,7 @@ class FareAttributesForm extends Component {
let evt = { let evt = {
target: { target: {
name: 'agency', name: 'agency',
value: resp, value: resp.value,
}} }}
this.handleChange(evt) this.handleChange(evt)
} }

4
src/components/FareList.js

@ -120,8 +120,8 @@ class FareList extends Component {
<div className="level-item has-text-centered"> <div className="level-item has-text-centered">
<div> <div>
<p className="heading">Route ID</p> <p className="heading">Route ID</p>
<p className="title"> <p>
{farerule.results[i].route_id || '-'} {farerule.results[i].route && farerule.results[i].route.route_id || '-'}
</p> </p>
</div> </div>
</div> </div>

65
src/components/FareRulesForm.js

@ -9,55 +9,28 @@ import {
deleteFareRule deleteFareRule
} from '../actions/fare' } from '../actions/fare'
import store from '../store' import store from '../store'
import Input from './parts/Input'
import AsyncSelect from 'react-select/lib/Async' import AsyncSelect from 'react-select/lib/Async'
import { components } from 'react-select'
import { import {
getStopsAsyncSelect, getStopsAsyncSelect,
getFareAttrAsyncSelect, getFareAttrAsyncSelect,
getRouteAsyncSelect getRouteAsyncSelect
} from '../utils' } from '../utils'
import {
StopOption, FareAttrOption, RouteOption
} from './parts/SelectOptions'
const StyledFareRulesForm = styled.div` const StyledFareRulesForm = styled.div`
padding: 1rem; padding: 1rem;
background: #fafafa; background: #fafafa;
`; `
const StopOption = (props) => {
const { stop_id, name } = props.data
return (
<components.Option {...props}>
<code>{stop_id}</code> {name}
</components.Option>
)
}
const FareAttrOption = (props) => {
const { fare_id, price, currency_type } = props.data
return (
<components.Option {...props}>
<code>{fare_id}</code> {price} {currency_type}
</components.Option>
)
}
const RouteOption = (props) => {
const { route_id, short_name, long_name} = props.data
return (
<components.Option {...props}>
<code>{route_id}</code> {short_name}
<br/>{long_name}
</components.Option>
)
}
class FareRulesForm extends Component { class FareRulesForm extends Component {
state = { state = {
id: null, id: null,
fare_id: "", fare: null,
route_id: "", // optinal route: null, // optinal
origin_id: "", origin_id: "",
destination_id: "", destination_id: "",
contains_id: "", contains_id: "",
@ -127,7 +100,7 @@ class FareRulesForm extends Component {
let evt = { let evt = {
target: { target: {
name: 'fare', name: 'fare',
value: resp, value: resp.value,
}} }}
this.handleChange(evt) this.handleChange(evt)
} }
@ -136,19 +109,19 @@ class FareRulesForm extends Component {
</div> </div>
<div className="field"> <div className="field">
<label className="label">Route</label> <label className="label">Route <i>optional</i></label>
<AsyncSelect <AsyncSelect
cacheOptions={true} cacheOptions={true}
defaultOptions defaultOptions
defaultValue={one.route_id && {value: one.route_id, label: one.route_id}} defaultValue={one.route && {value: one.route, label: one.route.route_id}}
loadOptions={getRouteAsyncSelect} loadOptions={getRouteAsyncSelect}
components={{ Option: RouteOption }} components={{ Option: RouteOption }}
onChange={(resp, evt) => { onChange={(resp, evt) => {
if (evt.action === 'select-option') { if (evt.action === 'select-option') {
let evt = { let evt = {
target: { target: {
name: 'route_id', name: 'route',
value: resp.route_id, value: resp.value,
}} }}
this.handleChange(evt) this.handleChange(evt)
} }
@ -169,7 +142,7 @@ class FareRulesForm extends Component {
let evt = { let evt = {
target: { target: {
name: 'origin_id', name: 'origin_id',
value: resp.stop_id, value: resp.value.stop_id,
}} }}
this.handleChange(evt) this.handleChange(evt)
} }
@ -178,9 +151,10 @@ class FareRulesForm extends Component {
</div> </div>
<div className="field"> <div className="field">
<label className="label">Destination ID</label> <label className="label">Destination ID (or IDs)</label>
<AsyncSelect <AsyncSelect
cacheOptions={true} isMulti
cacheOptions
defaultOptions defaultOptions
defaultValue={one.destination_id && {value: one.destination_id, label: one.destination_id}} defaultValue={one.destination_id && {value: one.destination_id, label: one.destination_id}}
loadOptions={getStopsAsyncSelect} loadOptions={getStopsAsyncSelect}
@ -190,7 +164,7 @@ class FareRulesForm extends Component {
let evt = { let evt = {
target: { target: {
name: 'destination_id', name: 'destination_id',
value: resp.stop_id, value: resp.map(el => el.value.stop_id),
}} }}
this.handleChange(evt) this.handleChange(evt)
} }
@ -199,8 +173,9 @@ class FareRulesForm extends Component {
</div> </div>
<div className="field"> <div className="field">
<label className="label">Contains ID</label> <label className="label">Contains ID (or IDs)</label>
<AsyncSelect <AsyncSelect
isMulti
cacheOptions={true} cacheOptions={true}
defaultOptions defaultOptions
defaultValue={one.contains_id && {value: one.contains_id, label: one.contains_id}} defaultValue={one.contains_id && {value: one.contains_id, label: one.contains_id}}
@ -211,13 +186,15 @@ class FareRulesForm extends Component {
let evt = { let evt = {
target: { target: {
name: 'contains_id', name: 'contains_id',
value: resp.stop_id, value: resp.map(el => el.value.stop_id),
}} }}
this.handleChange(evt) this.handleChange(evt)
} }
}} }}
/> />
</div> </div>
<p>When having multiple destinations or contains, multiple fare rule records will be created automatically. Nothing differs from adding multiple records manually, it only saves time. !! only works with CREATE, UPDATE will throw 500</p>
</div> </div>
<div className="field is-grouped"> <div className="field is-grouped">

16
src/components/StopForm.js

@ -16,21 +16,13 @@ import {
StopLocationTypes, StopWheelChairInfo StopLocationTypes, StopWheelChairInfo
} from '../constants/choices' } from '../constants/choices'
import { getItemFromList, getStopsAsyncSelect } from '../utils' import { getItemFromList, getStopsAsyncSelect } from '../utils'
import { StopOption } from './parts/SelectOptions'
const StyledStopForm = styled.div` const StyledStopForm = styled.div`
padding: 1rem; padding: 1rem;
background: #fafafa; background: #fafafa;
` `
const Option = (props) => {
const { stop_id, name, stop_desc } = props.data
return (
<components.Option {...props}>
<code>{stop_id}</code> {name}
{stop_desc.length > 0 && <small><br />{stop_desc}</small>}
</components.Option>
)
}
// TODO: need to deal with shapes // TODO: need to deal with shapes
@ -278,13 +270,13 @@ class StopForm extends Component {
defaultOptions defaultOptions
defaultValue={null} defaultValue={null}
loadOptions={getStopsAsyncSelect} loadOptions={getStopsAsyncSelect}
components={{ Option }} components={{ Option: StopOption }}
onChange={(item, evt) => { onChange={(resp, evt) => {
if (evt.action === 'select-option') { if (evt.action === 'select-option') {
let evt = { let evt = {
target: { target: {
name: 'mergeWith', name: 'mergeWith',
value: item, value: resp.value,
}} }}
this.handleChange(evt) this.handleChange(evt)
} }

41
src/components/parts/SelectOptions.js

@ -0,0 +1,41 @@
import React from 'react'
import { components } from 'react-select'
export const StopOption = (props) => {
const { stop_id, name, stop_desc } = props.data.value
return (
<components.Option {...props}>
<code>{stop_id}</code> {name}
{stop_desc.length > 0 && <small><br />{stop_desc}</small>}
</components.Option>
)
}
export const FareAttrOption = (props) => {
const { fare_id, price, currency_type } = props.data.value
return (
<components.Option {...props}>
<code>{fare_id}</code> {price} {currency_type}
</components.Option>
)
}
export const RouteOption = (props) => {
const { route_id, short_name, long_name} = props.data.value
return (
<components.Option {...props}>
<code>{route_id}</code> {short_name}
<br/>{long_name}
</components.Option>
)
}
export const AgencyOption = (props) => {
const { agency_id, name } = props.data.value
return (
<components.Option {...props}>
<code>{agency_id}</code> {name}
</components.Option>
)
}

4
src/constants/Api.js

@ -1,6 +1,6 @@
// export const URL = process.env.API_URL || '//localhost:8000' export const URL = process.env.API_URL || '//localhost:8000'
export const URL = process.env.API_URL || 'https://api.goth.app' // export const URL = process.env.API_URL || 'https://api.goth.app'
export const API_PREFIX = process.env.API_PREFIX || '/v1' export const API_PREFIX = process.env.API_PREFIX || '/v1'
export const API_URL = `${URL}${API_PREFIX}` export const API_URL = `${URL}${API_PREFIX}`
export const LOGIN = '/api-token-auth/' export const LOGIN = '/api-token-auth/'

15
src/reducers/farerule.js

@ -45,14 +45,21 @@ const fareRule = (state = fareRuleInitState, action) => {
] ]
} }
case FARERULE_CREATE: case FARERULE_CREATE:
let r
/* check if it's array by
- action.payload instanceof Array
- Array.isArray(action.payload)
*/
if (Array.isArray(action.payload)) {
r = [...state.results, ...action.payload]
} else {
r = [...state.results, action.payload]
}
return { return {
...state, ...state,
fetching: false, fetching: false,
count: state.count + 1, count: state.count + 1,
results: [ results: r,
...state.results,
action.payload,
]
} }
case FARERULE_DELETE: case FARERULE_DELETE:
const deleteInd = state.results.findIndex(ele => ele.id === action.meta.id) const deleteInd = state.results.findIndex(ele => ele.id === action.meta.id)

11
src/utils/index.js

@ -2,6 +2,7 @@ import { CancelToken } from 'axios'
import { apiClient } from './ApiClient' import { apiClient } from './ApiClient'
import polyUtil from 'polyline-encoded' import polyUtil from 'polyline-encoded'
export const decodeGeoJson = (encodedOne) => { export const decodeGeoJson = (encodedOne) => {
if (typeof encodedOne.coordinates === "string") if (typeof encodedOne.coordinates === "string")
encodedOne.coordinates = polyUtil.decode(encodedOne.coordinates) encodedOne.coordinates = polyUtil.decode(encodedOne.coordinates)
@ -34,8 +35,8 @@ export const getStopsAsyncSelect = (inputValue, callback) => {
apiClient(`/stop/?search=${inputValue}`, { cancelToken }) apiClient(`/stop/?search=${inputValue}`, { cancelToken })
.then((resp) => { .then((resp) => {
callback(resp.data.results.map(i => ({ callback(resp.data.results.map(i => ({
...i, value: {...i},
label: i.name label: `${i.stop_id}-${i.name}`
}))) })))
}) })
} }
@ -52,7 +53,7 @@ export const getFareAttrAsyncSelect = (inputValue, callback) => {
apiClient(`/fare-attribute/?search=${inputValue}`, { cancelToken }) apiClient(`/fare-attribute/?search=${inputValue}`, { cancelToken })
.then((resp) => { .then((resp) => {
callback(resp.data.results.map(i => ({ callback(resp.data.results.map(i => ({
...i, value: {...i},
label: i.fare_id label: i.fare_id
}))) })))
}) })
@ -70,7 +71,7 @@ export const getRouteAsyncSelect = (inputValue, callback) => {
apiClient(`/route/?search=${inputValue}`, { cancelToken }) apiClient(`/route/?search=${inputValue}`, { cancelToken })
.then((resp) => { .then((resp) => {
callback(resp.data.results.map(i => ({ callback(resp.data.results.map(i => ({
...i, value: {...i},
label: i.route_id label: i.route_id
}))) })))
}) })
@ -88,7 +89,7 @@ export const getAgencyAsyncSelect = (inputValue, callback) => {
apiClient(`/agency/?search=${inputValue}`, { cancelToken }) apiClient(`/agency/?search=${inputValue}`, { cancelToken })
.then((resp) => { .then((resp) => {
callback(resp.data.results.map(i => ({ callback(resp.data.results.map(i => ({
...i, value: {...i},
label: i.name label: i.name
}))) })))
}) })

Loading…
Cancel
Save