Skip to content

Commit

Permalink
fix(pattern): improve styling of pattern stop list and scroll bars
Browse files Browse the repository at this point in the history
fixes #151
  • Loading branch information
landonreed committed May 15, 2018
1 parent bbe0425 commit 15bc8b2
Show file tree
Hide file tree
Showing 12 changed files with 309 additions and 191 deletions.
2 changes: 1 addition & 1 deletion lib/editor/components/EditorInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export default class EditorInput extends Component {
<div style={{marginBottom: '10px'}}>Drop {activeComponent} image here, or click to select image to upload.</div>
{activeEntity && activeEntity[field.name]
? <img
alt='agency branding'
alt={field.name}
className='img-responsive'
src={activeEntity[field.name]} />
: null
Expand Down
84 changes: 44 additions & 40 deletions lib/editor/components/EntityDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,16 @@ export default class EntityDetails extends Component {
offset: PropTypes.number,
tableData: PropTypes.object,
entityEdited: PropTypes.bool,
subComponent: PropTypes.string
subComponent: PropTypes.string,
validationErrors: PropTypes.array
}

state = {}

_hasValidationIssue = field => {
return this.props.validationErrors.find(e => e.field === field.name)
}

_toggleFareRules = (editFareRules) => this.setState({editFareRules})

render () {
Expand Down Expand Up @@ -84,53 +89,52 @@ export default class EntityDetails extends Component {
)
}
const {zones, zoneOptions} = getZones(getTableById(tableData, 'stop'), activeEntity)
const rowIndex = 0
const currentTable = getEditorTable(activeComponent)
const renderDefault = subComponent !== 'trippattern' && !this.state.editFareRules && activeComponent !== 'scheduleexception'
const inputs = renderDefault && currentTable.fields.map((field, colIndex) => (
<EditorInput
field={field}
currentValue={activeEntity[field.name]}
key={`${rowIndex}-${colIndex}`}
approveGtfsDisabled={approveGtfsDisabled}
zoneOptions={zoneOptions}
isNotValid={validationErrors.find(e => e.field === field.name)}
{...this.props} />
))
const detailsBody = (
<div
className='entity-details-body'
style={{height: '80%', overflowY: 'scroll'}}>
{/* Render relevant form based on entity type */}
{subComponent === 'trippattern'
? <ActiveTripPatternList
showConfirmModal={showConfirmModal} />
: this.state.editFareRules && activeEntity
? <FareRulesForm
zones={zones}
zoneOptions={zoneOptions}
{...this.props} />
: activeComponent === 'scheduleexception'
? <ScheduleExceptionForm {...this.props} />
: <div>
<Form>
{inputs}
</Form>
</div>
}
</div>
)
// Render the default form if not viewing trip patterns, schedule exceptions,
// or fare rules.
const renderDefault = subComponent !== 'trippattern' &&
!this.state.editFareRules &&
activeComponent !== 'scheduleexception'
return (
<div style={panelStyle}>
<div
className='entity-details'
style={{height: '100%'}}>
<div className='entity-details'>
<EntityDetailsHeader
validationErrors={validationErrors}
editFareRules={this.state.editFareRules}
toggleEditFareRules={this._toggleFareRules}
{...this.props} />
{detailsBody}
{/* Entity Details Body */}
<div className='entity-details-body'>
{/* Render relevant form based on entity type */}
{subComponent === 'trippattern'
? <ActiveTripPatternList
showConfirmModal={showConfirmModal} />
: this.state.editFareRules && activeEntity
? <FareRulesForm
zones={zones}
zoneOptions={zoneOptions}
{...this.props} />
: activeComponent === 'scheduleexception'
? <ScheduleExceptionForm {...this.props} />
: <div>
<Form>
{/* Editor Inputs */}
{renderDefault && currentTable.fields
.map((field, i) => (
<EditorInput
field={field}
currentValue={activeEntity[field.name]}
key={`${activeComponent}-${activeEntity.id}-${i}`}
approveGtfsDisabled={approveGtfsDisabled}
zoneOptions={zoneOptions}
isNotValid={this._hasValidationIssue(field)}
{...this.props} />
))
}
</Form>
</div>
}
</div>
</div>
</div>
)
Expand Down
162 changes: 91 additions & 71 deletions lib/editor/components/EntityDetailsHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Icon from '@conveyal/woonerf/components/icon'
import React, {Component, PropTypes} from 'react'
import {Badge, Button, ButtonGroup, Tooltip, OverlayTrigger, Nav, NavItem} from 'react-bootstrap'

import {getEntityBounds, getEntityName, getTableById} from '../util/gtfs'
import {getEntityBounds, getEntityName} from '../util/gtfs'
import {entityIsNew} from '../util/objects'
import {GTFS_ICONS} from '../util/ui'

Expand All @@ -20,7 +20,6 @@ export default class EntityDetailsHeader extends Component {
setActiveEntity: PropTypes.func,
subEntity: PropTypes.number,
subComponent: PropTypes.string,
tableData: PropTypes.object,
toggleEditFareRules: PropTypes.func,
updateMapSetting: PropTypes.func,
validationErrors: PropTypes.array
Expand Down Expand Up @@ -61,14 +60,26 @@ export default class EntityDetailsHeader extends Component {
_showFareRules = () => this.props.toggleEditFareRules(true)

_showRoute = () => {
const {activeComponent, activeEntity, feedSource, setActiveEntity, subComponent} = this.props
const {
activeComponent,
activeEntity,
feedSource,
setActiveEntity,
subComponent
} = this.props
if (subComponent === 'trippattern') {
setActiveEntity(feedSource.id, activeComponent, activeEntity)
}
}

_showTripPatterns = () => {
const {activeComponent, activeEntity, feedSource, setActiveEntity, subComponent} = this.props
const {
activeComponent,
activeEntity,
feedSource,
setActiveEntity,
subComponent
} = this.props
if (subComponent !== 'trippattern') {
setActiveEntity(feedSource.id, activeComponent, activeEntity, 'trippattern')
}
Expand All @@ -83,7 +94,6 @@ export default class EntityDetailsHeader extends Component {
mapState,
subComponent,
subEntityId,
tableData,
validationErrors
} = this.props
const validationTooltip = (
Expand All @@ -93,28 +103,28 @@ export default class EntityDetailsHeader extends Component {
))}
</Tooltip>
)
const entityName = activeComponent === 'feedinfo' ? 'Feed Info' : getEntityName(activeEntity)
const hasErrors = validationErrors.length > 0
const entityName = activeComponent === 'feedinfo'
? 'Feed Info'
: getEntityName(activeEntity)
const icon = GTFS_ICONS.find(i => i.id === activeComponent)
const zoomDisabled = activeEntity && !subComponent ? mapState.target === activeEntity.id : mapState.target === subEntityId
const zoomDisabled = activeEntity && !subComponent
? mapState.target === activeEntity.id
: mapState.target === subEntityId
const iconName = icon ? icon.icon : null
const nameWidth = activeComponent === 'stop' || activeComponent === 'route'
? '130px'
: '170px'
const entityNameStyle = {
width: nameWidth,
paddingTop: '8px',
display: 'inline-block',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
overflow: 'hidden'
}
? '176px'
: '210px'
return (
<div style={{height: '100px'}}>
<h5 style={{width: '100%', marginBottom: '0px'}}>
<div className='entity-details-header'>
<h5 className='entity-details-heading'>
{/* Zoom, undo, and save buttons */}
<ButtonGroup className='pull-right'>
{activeComponent === 'stop' || activeComponent === 'route'
? <OverlayTrigger rootClose placement='bottom' overlay={<Tooltip id='tooltip'>Zoom to {activeComponent}</Tooltip>}>
? <OverlayTrigger
rootClose
placement='bottom'
overlay={<Tooltip id='tooltip'>Zoom to {activeComponent}</Tooltip>}>
<Button
bsSize='small'
disabled={zoomDisabled}
Expand All @@ -124,62 +134,72 @@ export default class EntityDetailsHeader extends Component {
</OverlayTrigger>
: null
}
<OverlayTrigger rootClose placement='bottom' overlay={<Tooltip id='tooltip'>Undo changes</Tooltip>}>
<OverlayTrigger
rootClose
placement='bottom'
overlay={<Tooltip id='tooltip'>Undo changes</Tooltip>}>
<Button
bsSize='small'
disabled={!entityEdited}
onClick={this._onClickUndo}>
<Icon type='undo' />
</Button>
</OverlayTrigger>
<OverlayTrigger rootClose placement='bottom' overlay={<Tooltip id='tooltip'>Save changes</Tooltip>}>
<OverlayTrigger
rootClose
placement='bottom'
overlay={<Tooltip id='tooltip'>Save changes</Tooltip>}>
<Button
bsSize='small'
disabled={!entityEdited || validationErrors.length > 0}
disabled={!entityEdited || hasErrors}
onClick={this._onClickSave}>
<Icon type='floppy-o' />
</Button>
</OverlayTrigger>
</ButtonGroup>
{/* Entity Icon */}
<span style={{position: 'relative', top: '-4px'}}>
{activeComponent === 'route' && activeEntity
? <span className='fa-stack'>
<Icon type='square' style={{color: `#${activeEntity.route_color ? activeEntity.route_color : 'fff'}`}} className='fa-stack-2x' />
<Icon type='bus' style={{color: `#${activeEntity.route_text_color ? activeEntity.route_text_color : '000'}`}} className='fa-stack-1x' />
</span>
: iconName
? <span className='fa-stack'>
<Icon type='square' className='fa-stack-2x' />
<Icon type={iconName} className='fa-inverse fa-stack-1x' />
</span>
// schedule exception icon if no icon found
: <span className='fa-stack'>
<Icon type='calendar' className='fa-stack-1x' />
<Icon type='ban' className='text-danger fa-stack-2x' />
</span>
}
</span>
{' '}
{/* Entity name */}
<span
title={entityName}
style={entityNameStyle}>
{entityName}
<span className='entity-details-title' style={{width: nameWidth}}>
{/* Entity Icon */}
<span style={{position: 'relative', top: '-4px'}}>
{activeComponent === 'route'
? <span className='fa-stack'>
<Icon
type='square'
style={{color: `#${activeEntity.route_color || 'fff'}`}}
className='fa-stack-2x' />
<Icon
type='bus'
style={{color: `#${activeEntity.route_text_color || '000'}`}}
className='fa-stack-1x' />
</span>
: iconName
? <span className='fa-stack'>
<Icon type='square' className='fa-stack-2x' />
<Icon type={iconName} className='fa-inverse fa-stack-1x' />
</span>
// schedule exception icon if no icon found
: <span className='fa-stack'>
<Icon type='calendar' className='fa-stack-1x' />
<Icon type='ban' className='text-danger fa-stack-2x' />
</span>
}
</span>
{' '}
{/* Entity name */}
<span
title={entityName}
className='entity-details-name'>
{entityName}
</span>
</span>
</h5>
{/* FIXME: check for null feed info needs to be fixed */}
{!getTableById(tableData, activeComponent, false) && activeComponent === 'feedinfo'
? <small>Complete feed info to begin editing GTFS.</small>
: null
}
{/* Validation issues */}
<p style={{marginBottom: '2px'}}>
<small style={{marginTop: '3px'}} className='pull-right'>
<em className='text-muted'>* denotes required field</em>
</small>
<small className={`${validationErrors.length > 0 ? ' text-danger' : ' text-success'}`}>
{validationErrors.length > 0
<small
className={`${hasErrors ? ' text-danger' : ' text-success'}`}>
{hasErrors
? <span>
<Icon type='times-circle' />
{' '}
Expand Down Expand Up @@ -217,22 +237,22 @@ export default class EntityDetailsHeader extends Component {
</OverlayTrigger>
</Nav>
: activeComponent === 'fare'
? <Nav style={{marginBottom: '5px'}} bsStyle='pills' justified>
<NavItem
eventKey={'fare'}
active={!editFareRules}
onClick={this._showFareAttributes}>
Attributes
</NavItem>
<NavItem
eventKey={'rules'}
disabled={!activeEntity || entityIsNew(activeEntity)}
active={editFareRules}
onClick={this._showFareRules}>
Rules
</NavItem>
</Nav>
: null
? <Nav style={{marginBottom: '5px'}} bsStyle='pills' justified>
<NavItem
eventKey={'fare'}
active={!editFareRules}
onClick={this._showFareAttributes}>
Attributes
</NavItem>
<NavItem
eventKey={'rules'}
disabled={!activeEntity || entityIsNew(activeEntity)}
active={editFareRules}
onClick={this._showFareRules}>
Rules
</NavItem>
</Nav>
: null
}
</div>
)
Expand Down
1 change: 1 addition & 0 deletions lib/editor/components/EntityList.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ export default class EntityList extends Component {
headerHeight={20}
rowHeight={25}
style={{outline: 'none'}}
className='EntityList'
scrollToIndex={activeIndex}
sortBy={sort.key}
sortDirection={sort.direction}
Expand Down
2 changes: 1 addition & 1 deletion lib/editor/components/GtfsEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ export default class GtfsEditor extends Component {
getGtfsEntityIndex={this._getGtfsEntityIndex} />
: null
return (
<div>
<div className='GtfsEditor'>
<Title>{this.getEditorTitle()}</Title>
<EditorSidebar
activeComponent={activeComponent}
Expand Down
Loading

0 comments on commit 15bc8b2

Please sign in to comment.