const NAV = [ { id: 'setup', label: 'Setup', icon: ( ) }, { id: 'baseline', label: 'Baseline', icon: ( ) }, { id: 'forecast', label: 'Forecast', icon: ( ) }, ] // The forecasts are listed here, above the steps, rather than offered as a // dropdown in the status bar. Two reasons: a scenario is a thing you open, not // a setting you change, and the status bar is otherwise read-only, so a control // sitting in it did not read as one. // // Not nested under the Forecast button, which is where this started: Baseline // works on the same version, so hanging it off one step would either // misrepresent the scope or duplicate the list under two. It reads // "what am I working on" and then "what step am I on". // // The source is deliberately absent. `gs.osm_skinny` means nothing to someone // editing a forecast, and a version already carries its source, so choosing a // forecast settles it. Picking the source is a Setup concern and the status bar // only offers it there. export default function Sidebar({ view, setView, expanded, setExpanded, versions = [], versionId, setVersionId, sourceId, setSourceId, }) { const selected = versions.find(v => String(v.id) === String(versionId)) function pick(v) { // The source comes with the forecast. This is the whole reason the source // needs no control of its own outside Setup: every version carries its // source_id, so choosing one settles both. Set first, so the version is not // briefly validated against the outgoing source's list. if (v.source_id != null && String(v.source_id) !== String(sourceId)) { setSourceId(String(v.source_id)) } setVersionId(String(v.id)) // Setup is the one step a version means nothing to, so choosing one there // is a statement of intent to go and work on it. if (view === 'setup') setView('forecast') } return (