diff --git a/src/components/earthengine/Collection.js b/src/components/earthengine/Collection.js index 88b0b7bc5..8448b9a03 100644 --- a/src/components/earthengine/Collection.js +++ b/src/components/earthengine/Collection.js @@ -18,6 +18,17 @@ const collectionFilters = { ], }; +const styles = { + year: { + width: '35%', + paddingRight: 16, + boxSizing: 'border-box', + }, + period: { + width: '65%', + }, +}; + export class CollectionSelect extends Component { static propTypes = { id: PropTypes.string.isRequired, @@ -30,6 +41,11 @@ export class CollectionSelect extends Component { style: PropTypes.object, }; + state = { + years: null, + year: null, + }; + componentDidMount() { const { id, collections, loadEarthEngineCollection } = this.props; @@ -38,20 +54,73 @@ export class CollectionSelect extends Component { } } + componentDidUpdate(prevProps) { + const { id, filter, collections } = this.props; + + if (id && collections[id] !== prevProps.collections[id]) { + const yearItems = collections[id] + .filter(item => item.year) + .map(item => item.year); + + if (yearItems.length) { + // Get unique years + const years = [...new Set(yearItems)].map(year => ({ + id: year, + name: year.toString(), + })); + + // Get year from saved filter or select the most recent + const year = filter + ? Number(filter[0].arguments[1].substring(0, 4)) + : years[0].id; + + this.setState({ years, year }); + } + } + } + render() { - const { - id, - filter, - label, - collections, - onChange, - style, - errorText, - } = this.props; - - const items = collections[id]; + const { id, filter, label, collections, style, errorText } = this.props; + + const { years, year } = this.state; + + const items = year + ? collections[id].filter(item => item.year === year) + : collections[id]; + const value = filter && filter[0].arguments[1]; + return ( +
+ {years && ( + + )} + +
+ ); + } + + onYearChange = year => { + this.setState({ year: year.id }); + this.props.onChange(null, null); + }; + + onPeriodChange = period => { + const { id, onChange } = this.props; const collectionFilter = collectionFilters[id] || (index => [ @@ -61,20 +130,8 @@ export class CollectionSelect extends Component { }, ]); - return ( - - onChange(period.name, collectionFilter(period.id)) - } - style={style} - errorText={!value && errorText ? errorText : null} - /> - ); - } + onChange(period.name, collectionFilter(period.id)); + }; } export default connect( diff --git a/src/epics/earthEngine.js b/src/epics/earthEngine.js index 8e7451117..538995407 100644 --- a/src/epics/earthEngine.js +++ b/src/epics/earthEngine.js @@ -68,10 +68,15 @@ const collections = { resolve( data.features.map(f => ({ id: f.id, + year: new Date( + f.properties['system:time_start'] + ).getFullYear(), name: formatStartEndDate( f.properties['system:time_start'], - f.properties['system:time_end'] - 7200001 - ), // Minus 2 hrs to end the day before + f.properties['system:time_end'] - 7200001, // Minus 2 hrs to end the day before + null, + false + ), })) ) ); @@ -90,10 +95,15 @@ const collections = { resolve( data.features.map(f => ({ id: f.id, + year: new Date( + f.properties['system:time_start'] + ).getFullYear(), name: formatStartEndDate( f.properties['system:time_start'], - f.properties['system:time_end'] - 7200001 - ), // Minus 2 hrs to end the day before + f.properties['system:time_end'] - 7200001, // Minus 2 hrs to end the day before + null, + false + ), })) ) ); diff --git a/src/util/time.js b/src/util/time.js index 96e6fd58d..db077b754 100644 --- a/src/util/time.js +++ b/src/util/time.js @@ -51,12 +51,13 @@ export const hasIntlSupport = * Formats a date string or timestamp to the default display format: 13 Aug 2018 (en locale) * @param {String} dateString * @param {String} locale + * @param {Boolean} showYear * @returns {String} */ -export const formatLocaleDate = (dateString, locale) => +export const formatLocaleDate = (dateString, locale, showYear = true) => hasIntlSupport ? new Intl.DateTimeFormat(locale || i18n.language || DEFAULT_LOCALE, { - year: 'numeric', + year: showYear ? 'numeric' : undefined, month: 'short', day: 'numeric', }).format(toDate(dateString)) @@ -67,13 +68,15 @@ export const formatLocaleDate = (dateString, locale) => * @param {String|Number} startDate * @param {String|Number} endDate * @param {String} locale + * @param {Boolean} showYear * @returns {String} */ -export const formatStartEndDate = (startDate, endDate, locale) => { +export const formatStartEndDate = (startDate, endDate, locale, showYear) => { const loc = locale || i18n.language || DEFAULT_LOCALE; - return `${formatLocaleDate(startDate, loc)} - ${formatLocaleDate( + return `${formatLocaleDate(startDate, loc, showYear)} - ${formatLocaleDate( endDate, - locale + locale, + showYear )}`; };