Browse Source

Port react-select@1 to @2

dev
sipp11 7 years ago
parent
commit
59e257c2be
  1. 4
      package.json
  2. 65
      src/components/First.js
  3. 34
      src/components/RouteForm.js
  4. 20
      src/components/StopForm.js
  5. 83
      src/components/StopTimeForm.js
  6. 31
      src/components/TripForm.js
  7. 6
      src/components/parts/HorizontalSelect.js
  8. 5
      src/components/parts/Select.js
  9. 60
      src/constants/choices.js
  10. 2
      src/container/Geo.js
  11. 2
      src/container/Main.js
  12. 7
      src/reducers/agency.js
  13. 13
      src/utils/index.js

4
package.json

@ -5,7 +5,7 @@
"dependencies": { "dependencies": {
"ajv": "^6.5.1", "ajv": "^6.5.1",
"axios": "^0.18.0", "axios": "^0.18.0",
"leaflet": "^1.3.1", "leaflet": "^1.3.2",
"leaflet-draw": "^1.0.2", "leaflet-draw": "^1.0.2",
"lodash": "^4.17.10", "lodash": "^4.17.10",
"moment": "^2.22.2", "moment": "^2.22.2",
@ -17,7 +17,7 @@
"react-redux": "^5.0.7", "react-redux": "^5.0.7",
"react-router-dom": "^4.3.1", "react-router-dom": "^4.3.1",
"react-scripts": "1.1.4", "react-scripts": "1.1.4",
"react-select": "^1.2.1", "react-select": "^2.0.0-beta.7",
"redux": "^4.0.0", "redux": "^4.0.0",
"redux-api-middleware": "^2.3.0", "redux-api-middleware": "^2.3.0",
"redux-logger": "^3.0.6", "redux-logger": "^3.0.6",

65
src/components/First.js

@ -0,0 +1,65 @@
import React, { Component } from 'react'
import { components } from 'react-select'
import AsyncSelect from 'react-select/lib/Async'
const cbStopOptions = (inputValue, callback) => {
fetch(`https://api.goth.app/v1/stop/?search=${inputValue}`)
.then((response) => response.json())
.then((json) => {
callback(json.results.map(ele => Object.assign(ele, {
value: ele.id, label: ele.name
})))
})
}
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>
);
};
class First extends Component {
state = { inputValue: '' }
handleInputChange = (newValue) => {
console.log("inputChange", newValue)
const inputValue = newValue.replace(/\W/g, '')
this.setState({ inputValue })
return inputValue
}
render() {
return (
<div>
<br />
<br />
<br />
<AsyncSelect
cacheOptions={true}
defaultOptions
defaultValue={{value: '1', label: 'test'}}
loadOptions={cbStopOptions}
components={{ Option }}
onChange={(item, evt) => {
console.log('on change', item, evt)
if (evt.action === 'select-option') {
console.log('select something', item)
return Object.assign(item, {value: item.name})
}
console.log('?')
return item
}}
onInputChange={this.handleInputChange}
/>
</div>
)
}
}
export default First

34
src/components/RouteForm.js

@ -5,8 +5,13 @@ import { Redirect, Link } from 'react-router-dom'
import Input from './parts/Input' import Input from './parts/Input'
import Select from './parts/Select' import Select from './parts/Select'
import { updateRoute, createRoute, deleteRoute } from '../actions/route'; import {
getRoute, updateRoute,
createRoute, deleteRoute
} from '../actions/route';
import store from '../store' import store from '../store'
import { getItemFromList } from '../utils'
import { RouteTypeChoices } from '../constants/choices'
const StyledRouteForm = styled.div` const StyledRouteForm = styled.div`
padding: 1rem; padding: 1rem;
@ -66,6 +71,13 @@ class RouteForm extends Component {
this.setState({justSubmit: true}) this.setState({justSubmit: true})
} }
componentDidMount() {
const { routeId } = this.props.match.params
const { fetching, count } = this.props.route
if (routeId !== undefined && count === 0 && !fetching)
store.dispatch(getRoute(`route_id=${routeId}`))
}
static getDerivedStateFromProps(props, state) { static getDerivedStateFromProps(props, state) {
// if form is ready, then nothing else to do // if form is ready, then nothing else to do
if (state.agency !== null || state.id !== null) if (state.agency !== null || state.id !== null)
@ -85,8 +97,11 @@ class RouteForm extends Component {
} else if (routeId !== undefined && state.id === null) { } else if (routeId !== undefined && state.id === null) {
// this is for editing route // this is for editing route
const ones = props.route.results.filter(ele => ele.route_id === routeId) const ones = props.route.results.filter(ele => ele.route_id === routeId)
props.updateBreadcrumb({ agencyId, routeId }) if (ones.length > 0) {
return ones[0] props.updateBreadcrumb({ agencyId, routeId })
return ones[0]
}
return null
} }
return null return null
} }
@ -132,18 +147,9 @@ class RouteForm extends Component {
<Select <Select
label="Route Type" label="Route Type"
fieldName="route_type" fieldName="route_type"
value={one.route_type || ''} value={getItemFromList(one.route_type, RouteTypeChoices)}
handleChange={this.handleChange} handleChange={this.handleChange}
choices={[ choices={RouteTypeChoices} />
{ value: '0', label: 'Tram, Light rail' },
{ value: '1', label: 'Subway (within metro area)' },
{ value: '2', label: 'Rail' },
{ value: '3', label: 'Bus' },
{ value: '4', label: 'Ferry' },
{ value: '5', label: 'Cable car' },
{ value: '6', label: 'Gondola' },
{ value: '7', label: 'Funicular (steep inclines)' },
]} />
<Input <Input
label="Route URL" label="Route URL"

20
src/components/StopForm.js

@ -10,6 +10,10 @@ import {
} from '../actions' } from '../actions'
import { updateStop, createStop, deleteStop, getStop } from '../actions/stop' import { updateStop, createStop, deleteStop, getStop } from '../actions/stop'
import store from '../store' import store from '../store'
import {
StopLocationTypes, StopWheelChairInfo
} from '../constants/choices'
import { getItemFromList } from '../utils'
const StyledStopForm = styled.div` const StyledStopForm = styled.div`
padding: 1rem; padding: 1rem;
@ -194,13 +198,9 @@ class StopForm extends Component {
<Select <Select
label="Location Type" label="Location Type"
fieldName="location_type" fieldName="location_type"
value={one.location_type || '0'} value={getItemFromList(one.location_type, StopLocationTypes)}
handleChange={this.handleChange} handleChange={this.handleChange}
choices={[ choices={StopLocationTypes} />
{ value: '0', label: 'Stop' },
{ value: '1', label: 'Station' },
{ value: '2', label: 'Station Entrance/Exit' },
]} />
<Input <Input
label="Timezone" label="Timezone"
@ -212,13 +212,9 @@ class StopForm extends Component {
<Select <Select
label="Wheelchair" label="Wheelchair"
fieldName="wheelchair_boarding" fieldName="wheelchair_boarding"
value={one.wheelchair_boarding || '0'} value={getItemFromList(one.wheelchair_boarding, StopWheelChairInfo)}
handleChange={this.handleChange} handleChange={this.handleChange}
choices={[ choices={StopWheelChairInfo} />
{ value: '0', label: 'No information' },
{ value: '1', label: 'Possible (partially or fully)' },
{ value: '2', label: 'Not possible' },
]} />
{/* <Input {/* <Input
label="Parent Station" label="Parent Station"

83
src/components/StopTimeForm.js

@ -1,6 +1,7 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import styled from 'styled-components' import styled from 'styled-components'
import Select from 'react-select' import AsyncSelect from 'react-select/lib/Async'
import { components } from 'react-select'
import Input from './parts/Input' import Input from './parts/Input'
import OurSelect from './parts/Select' import OurSelect from './parts/Select'
@ -9,6 +10,10 @@ import {
} from '../actions/stoptime' } from '../actions/stoptime'
import store from '../store' import store from '../store'
import { API_URL } from '../constants/Api' import { API_URL } from '../constants/Api'
import {
PickUpTypes, DropOffTypes, TimePointChoices
} from '../constants/choices'
import { getItemFromList } from '../utils'
const StyleBox = styled.div` const StyleBox = styled.div`
padding: 5px; padding: 5px;
@ -16,6 +21,17 @@ background: white;
margin-bottom: 1rem; margin-bottom: 1rem;
` `
const Option = (props) => {
console.log('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>
)
}
class StopTimeForm extends Component { class StopTimeForm extends Component {
state = { state = {
@ -64,13 +80,14 @@ class StopTimeForm extends Component {
return null return null
} }
getStops = (inputValue) => { getStops = (inputValue, callback) => {
if (!inputValue) { fetch(`${API_URL}/stop/?search=${inputValue}`)
return Promise.resolve({ options: [] });
}
return fetch(`${API_URL}/stop/?search=${inputValue}`)
.then((response) => response.json()) .then((response) => response.json())
.then((json) => ({ options: json.results })) .then((json) => {
callback(json.results.map(ele => Object.assign(ele, {
value: ele.id, label: ele.name
})))
})
} }
render() { render() {
@ -86,19 +103,22 @@ class StopTimeForm extends Component {
<div className="field"> <div className="field">
<label className="label">Stop</label> <label className="label">Stop</label>
<Select.Async <AsyncSelect
value={this.state.stop} cacheOptions={true}
labelKey="stop_id" defaultOptions
valueKey="id" defaultValue={item.stop && Object.assign(item.stop, {
filterOptionunion={false} label: item.stop.name})}
loadOptions={this.getStops} loadOptions={this.getStops}
onChange={(data) => { components={{ Option }}
let evt = { onChange={(item, evt) => {
target: { if (evt.action === 'select-option') {
name: 'stop', let evt = {
value: data, target: {
}} name: 'stop',
return this.handleChange(evt) value: item,
}}
this.handleChange(evt)
}
}} }}
/> />
</div> </div>
@ -126,38 +146,25 @@ class StopTimeForm extends Component {
label="Pickup Type" label="Pickup Type"
type="text" type="text"
fieldName="pickup_type" fieldName="pickup_type"
value={item.pickup_type || '0'} value={getItemFromList(item.pickup_type, PickUpTypes, '0')}
handleChange={this.handleChange} handleChange={this.handleChange}
choices={[ choices={PickUpTypes} />
{ value: '0', label: 'Regularly scheduled pickup' },
{ value: '1', label: 'No pickup' },
{ value: '2', label: 'Arrange pickup' },
{ value: '3', label: 'Contact driver' },
]} />
<OurSelect <OurSelect
label="Drop off Type" label="Drop off Type"
type="text" type="text"
fieldName="pickup_type" fieldName="pickup_type"
value={item.pickup_type || '0'} value={getItemFromList(item.drop_off_type, DropOffTypes, '0')}
handleChange={this.handleChange} handleChange={this.handleChange}
choices={[ choices={DropOffTypes} />
{ value: '0', label: 'Regularly scheduled dropoff' },
{ value: '1', label: 'No drop off' },
{ value: '2', label: 'Arrange drop off' },
{ value: '3', label: 'Contact driver' },
]} />
<OurSelect <OurSelect
label="Timepoint" label="Timepoint"
type="text" type="text"
fieldName="timepoint" fieldName="timepoint"
value={item.timepoint || '1'} value={getItemFromList(item.timepoint, TimePointChoices, '1')}
handleChange={this.handleChange} handleChange={this.handleChange}
choices={[ choices={TimePointChoices} />
{ value: '0', label: 'times are considered approximate.' },
{ value: '1', label: 'times are considered exact.' },
]} />
<div className="field is-grouped"> <div className="field is-grouped">
<div className="control"> <div className="control">

31
src/components/TripForm.js

@ -12,6 +12,12 @@ import { getCalendar } from '../actions/calendar'
import { getRoute } from '../actions' import { getRoute } from '../actions'
import { getStopTime } from '../actions/stoptime' import { getStopTime } from '../actions/stoptime'
import store from '../store' import store from '../store'
import {
DirectionChoices, WheelChairAccessibles,
BikeAllowanceChoices
} from '../constants/choices'
import { getItemFromList } from '../utils'
const StyledTripForm = styled.div` const StyledTripForm = styled.div`
padding: 1rem; padding: 1rem;
@ -134,7 +140,7 @@ class TripForm extends Component {
label="Service" label="Service"
type="text" type="text"
fieldName="service" fieldName="service"
value={one.service} value={one.service && Object.assign(one.service, {label: one.service.service_id})}
handleChange={this.handleChange} handleChange={this.handleChange}
choices={calendar.results.map(ele => ({ value: ele.id, label: ele.service_id }))} />} choices={calendar.results.map(ele => ({ value: ele.id, label: ele.service_id }))} />}
@ -142,12 +148,9 @@ class TripForm extends Component {
label="Direction ID" label="Direction ID"
type="text" type="text"
fieldName="direction_id" fieldName="direction_id"
value={one.direction_id || ''} value={getItemFromList(one.direction_id, DirectionChoices)}
handleChange={this.handleChange} handleChange={this.handleChange}
choices={[ choices={DirectionChoices} />
{ value: '0', label: 'outbound' },
{ value: '1', label: 'inbound' },
]} />
<HorizontalInput <HorizontalInput
label="Block ID" label="Block ID"
@ -160,25 +163,17 @@ class TripForm extends Component {
label="Wheelchair Accessible" label="Wheelchair Accessible"
type="text" type="text"
fieldName="wheelchair_accessible" fieldName="wheelchair_accessible"
value={one.wheelchair_accessible || '0'} value={getItemFromList(one.wheelchair_accessible, WheelChairAccessibles, '0')}
handleChange={this.handleChange} handleChange={this.handleChange}
choices={[ choices={WheelChairAccessibles} />
{ value: '0', label: 'No information' },
{ value: '1', label: 'Yes' },
{ value: '2', label: 'Not possible' },
]} />
<HorizontalSelect <HorizontalSelect
label="Bike Allowance" label="Bike Allowance"
type="text" type="text"
fieldName="bike_allowed" fieldName="bike_allowed"
value={one.bike_allowed || '0'} value={getItemFromList(one.bike_allowed, BikeAllowanceChoices, '0')}
handleChange={this.handleChange} handleChange={this.handleChange}
choices={[ choices={BikeAllowanceChoices} />
{ value: '0', label: 'No information' },
{ value: '1', label: 'Yes' },
{ value: '2', label: 'Not possible' },
]} />
</div> </div>
<div className="field is-grouped"> <div className="field is-grouped">
<div className="control"> <div className="control">

6
src/components/parts/HorizontalSelect.js

@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import Select from 'react-select' import Select from 'react-select'
import 'react-select/dist/react-select.css' // import 'react-select/dist/react-select.css'
const HorizontalInput = (props) => ( const HorizontalInput = (props) => (
@ -11,11 +11,11 @@ const HorizontalInput = (props) => (
<div className="field-body"> <div className="field-body">
<div className="field"> <div className="field">
<Select <Select
className="control" defaultOptions
classNamePrefix="control"
name={props.fieldName} name={props.fieldName}
value={props.value} value={props.value}
onChange={(data) => { onChange={(data) => {
console.log('change', data)
let evt = { let evt = {
target: { target: {
name: props.fieldName, name: props.fieldName,

5
src/components/parts/Select.js

@ -1,13 +1,14 @@
import React from 'react' import React from 'react'
import Select from 'react-select' import Select from 'react-select'
import 'react-select/dist/react-select.css' // import 'react-select/dist/react-select.css'
const NormalSelect = (props) => ( const NormalSelect = (props) => (
<div className="field"> <div className="field">
<label className="label">{props.label}</label> <label className="label">{props.label}</label>
<Select <Select
className="control" defaultOptions
classNamePrefix="control"
name={props.fieldName} name={props.fieldName}
value={props.value} value={props.value}
onChange={(data) => { onChange={(data) => {

60
src/constants/choices.js

@ -0,0 +1,60 @@
export const RouteTypeChoices = [
{ value: '0', label: 'Tram, Light rail' },
{ value: '1', label: 'Subway (within metro area)' },
{ value: '2', label: 'Rail' },
{ value: '3', label: 'Bus' },
{ value: '4', label: 'Ferry' },
{ value: '5', label: 'Cable car' },
{ value: '6', label: 'Gondola' },
{ value: '7', label: 'Funicular (steep inclines)' },
]
export const StopLocationTypes = [
{ value: '0', label: 'Stop' },
{ value: '1', label: 'Station' },
{ value: '2', label: 'Station Entrance/Exit' },
]
export const StopWheelChairInfo = [
{ value: '0', label: 'No information' },
{ value: '1', label: 'Possible (partially or fully)' },
{ value: '2', label: 'Not possible' },
]
export const DropOffTypes = [
{ value: '0', label: 'Regularly scheduled dropoff' },
{ value: '1', label: 'No drop off' },
{ value: '2', label: 'Arrange drop off' },
{ value: '3', label: 'Contact driver' },
]
export const TimePointChoices = [
{ value: '0', label: 'times are considered approximate.' },
{ value: '1', label: 'times are considered exact.' },
]
export const PickUpTypes = [
{ value: '0', label: 'Regularly scheduled pickup' },
{ value: '1', label: 'No pickup' },
{ value: '2', label: 'Arrange pickup' },
{ value: '3', label: 'Contact driver' },
]
export const DirectionChoices = [
{ value: '0', label: 'outbound' },
{ value: '1', label: 'inbound' },
]
export const WheelChairAccessibles = [
{ value: '0', label: 'No information' },
{ value: '1', label: 'Yes' },
{ value: '2', label: 'Not possible' },
]
export const BikeAllowanceChoices = [
{ value: '0', label: 'No information' },
{ value: '1', label: 'Yes' },
{ value: '2', label: 'Not possible' },
]

2
src/container/Geo.js

@ -6,7 +6,7 @@ import {
Map, TileLayer, CircleMarker, ZoomControl, Map, TileLayer, CircleMarker, ZoomControl,
FeatureGroup, GeoJSON, Marker } from 'react-leaflet' FeatureGroup, GeoJSON, Marker } from 'react-leaflet'
// import { EditControl } from 'react-leaflet-draw' // import { EditControl } from 'react-leaflet-draw'
import L from 'leaflet' import * as L from 'leaflet'
import { loggedIn } from '../reducers/auth' import { loggedIn } from '../reducers/auth'
import { import {

2
src/container/Main.js

@ -4,6 +4,7 @@ import { Redirect, Route, Switch } from 'react-router-dom'
import { loggedIn } from '../reducers/auth' import { loggedIn } from '../reducers/auth'
import { getAgency } from '../actions' import { getAgency } from '../actions'
import First from '../components/First'
import Nav from '../components/Nav' import Nav from '../components/Nav'
import Footer from '../components/Footer' import Footer from '../components/Footer'
import CalendarForm from '../components/CalendarForm' import CalendarForm from '../components/CalendarForm'
@ -50,6 +51,7 @@ class Main extends Component {
<Route exact path={`${match.url}calendar/new`} component={CalendarForm} /> <Route exact path={`${match.url}calendar/new`} component={CalendarForm} />
<Route exact path={`${match.url}calendar/:serviceId`} component={CalendarForm} /> <Route exact path={`${match.url}calendar/:serviceId`} component={CalendarForm} />
<Route exact path={`${match.url}calendar`} component={CalendarList} /> <Route exact path={`${match.url}calendar`} component={CalendarList} />
<Route path={`${match.url}`} component={First} />
</Switch> </Switch>
</div> </div>
<Footer /> <Footer />

7
src/reducers/agency.js

@ -1,6 +1,7 @@
import { import {
AGENCY_CREATE, AGENCY_DELETE, AGENCY_UPDATE, AGENCY_CREATE, AGENCY_DELETE, AGENCY_UPDATE,
AGENCY_REQUEST, AGENCY_SUCCESS, AGENCY_FAILURE, AGENCY_REQUEST, AGENCY_SUCCESS, AGENCY_FAILURE,
GEO_POLYGON_RESET,
} from '../constants/ActionTypes' } from '../constants/ActionTypes'
@ -12,6 +13,12 @@ const agencyInitState = {
} }
const agency = (state = agencyInitState, action) => { const agency = (state = agencyInitState, action) => {
switch(action.type) { switch(action.type) {
// somehow search fetching stuck we need some way to reset that
case GEO_POLYGON_RESET:
return {
...state,
fetching: false,
}
case AGENCY_REQUEST: case AGENCY_REQUEST:
return { return {
...state, ...state,

13
src/utils/index.js

@ -0,0 +1,13 @@
export const getItemFromList = (targetValue, list, defaultValue) => {
if (!targetValue && defaultValue === undefined)
return ''
let f = list.filter(ele => ele.value === targetValue)
if (f.length > 0)
return f[0]
// default value
f = list.filter(ele => ele.value === defaultValue)
if (f.length > 0)
return f[0]
return ''
}
Loading…
Cancel
Save