diff --git a/src/actions/layerEdit.js b/src/actions/layerEdit.js index e6fd006ad..234e047e9 100644 --- a/src/actions/layerEdit.js +++ b/src/actions/layerEdit.js @@ -234,10 +234,10 @@ export const setOrgUnitMode = (mode) => ({ payload: mode, }) -// Set layer params (EE) -export const setParams = (params) => ({ - type: types.LAYER_EDIT_PARAMS_SET, - payload: params, +// Set layer style (EE) +export const setStyle = (payload) => ({ + type: types.LAYER_EDIT_STYLE_SET, + payload, }) // Set collection filter (EE) diff --git a/src/components/core/ColorScaleSelect.js b/src/components/core/ColorScaleSelect.js index ee3d735ac..da15ed51b 100644 --- a/src/components/core/ColorScaleSelect.js +++ b/src/components/core/ColorScaleSelect.js @@ -14,11 +14,11 @@ const ColorScaleSelect = ({ palette, width, onChange, className }) => { const [isOpen, setIsOpen] = useState(false) const anchorRef = useRef() - const bins = palette.split(',').length + const bins = palette.length // palette.split(',').length const scale = getColorScale(palette) const onColorScaleSelect = (scale) => { - const classes = palette.split(',').length + const classes = palette.length // palette.split(',').length onChange(getColorPalette(scale, classes)) setIsOpen(false) } @@ -61,7 +61,7 @@ const ColorScaleSelect = ({ palette, width, onChange, className }) => { } ColorScaleSelect.propTypes = { - palette: PropTypes.string.isRequired, + palette: PropTypes.array.isRequired, onChange: PropTypes.func.isRequired, className: PropTypes.string, width: PropTypes.number, diff --git a/src/components/edit/earthEngine/EarthEngineDialog.js b/src/components/edit/earthEngine/EarthEngineDialog.js index 57ae97730..ab85f8c97 100644 --- a/src/components/edit/earthEngine/EarthEngineDialog.js +++ b/src/components/edit/earthEngine/EarthEngineDialog.js @@ -20,6 +20,7 @@ import { defaultFilters, translateFilters, } from '../../../util/earthEngine.js' +import { incrementDate } from '../../../util/time.js' import { Help, Tab, Tabs } from '../../core/index.js' import OrgUnitSelect from '../../orgunits/OrgUnitSelect.js' import styles from '../styles/LayerDialog.module.css' @@ -38,7 +39,6 @@ const EarthEngineDialog = (props) => { datasetId, band, rows, - params, style, filter, areaRadius, @@ -57,6 +57,7 @@ const EarthEngineDialog = (props) => { description, notice, periodType, + periodReducer, bands, filters = defaultFilters, unit, @@ -87,11 +88,23 @@ const EarthEngineDialog = (props) => { // console.log('setFilterFromPeriod', periodType, period, filters) if (period) { - periodFilter = translateFilters( - filters, - // periodType === 'yearly' ? String(period.year) : period.id - period.id - ) + const { id, startDate, endDate } = period + + if (startDate && endDate) { + // console.log('endDate', endDate, incrementDate(endDate)) + + periodFilter = translateFilters( + filters, + startDate, + incrementDate(endDate) + ) + } else { + periodFilter = translateFilters( + filters, + // periodType === 'yearly' ? String(period.year) : period.id + period.id + ) + } // TODO: Make more flexible periodFilter[0].id = period.id @@ -99,6 +112,8 @@ const EarthEngineDialog = (props) => { periodFilter[0].year = period.year } + // console.log('setFilterFromPeriod', period, filters, periodFilter) + setFilter(periodFilter) }, [periodType, filters, setFilter] @@ -266,7 +281,8 @@ const EarthEngineDialog = (props) => { datasetId={datasetId} periodType={periodType} period={period} - periods={periods} + // periods={periods} + periodReducer={periodReducer} filters={filters} onChange={setFilterFromPeriod} errorText={ @@ -279,7 +295,7 @@ const EarthEngineDialog = (props) => { {tab === 'style' && ( )} @@ -305,7 +321,7 @@ EarthEngineDialog.propTypes = { params: PropTypes.shape({ max: PropTypes.number.isRequired, min: PropTypes.number.isRequired, - palette: PropTypes.string.isRequired, + palette: PropTypes.array.isRequired, }), rows: PropTypes.array, } diff --git a/src/components/edit/earthEngine/LegendPreview.js b/src/components/edit/earthEngine/LegendPreview.js index f84c04baa..cc8cf7488 100644 --- a/src/components/edit/earthEngine/LegendPreview.js +++ b/src/components/edit/earthEngine/LegendPreview.js @@ -5,11 +5,11 @@ import { createLegend } from '../../../loaders/earthEngineLoader.js' import LegendItem from '../../legend/LegendItem.js' import styles from '../styles/LayerDialog.module.css' -const paramsAreValid = ({ min, max }) => +const styleIsValid = ({ min, max }) => !Number.isNaN(min) && !Number.isNaN(max) && max > min -const LegendPreview = ({ params }) => { - const legend = paramsAreValid(params) && createLegend(params) +const LegendPreview = ({ style }) => { + const legend = styleIsValid(style) && createLegend(style) return legend ? (
@@ -28,10 +28,10 @@ const LegendPreview = ({ params }) => { } LegendPreview.propTypes = { - params: PropTypes.shape({ + style: PropTypes.shape({ max: PropTypes.number.isRequired, min: PropTypes.number.isRequired, - palette: PropTypes.string.isRequired, + palette: PropTypes.array.isRequired, }), } diff --git a/src/components/edit/earthEngine/PeriodReducer.js b/src/components/edit/earthEngine/PeriodReducer.js index 10d902ad6..5f5a09ae9 100644 --- a/src/components/edit/earthEngine/PeriodReducer.js +++ b/src/components/edit/earthEngine/PeriodReducer.js @@ -2,15 +2,49 @@ import i18n from '@dhis2/d2-i18n' import { CircularLoader } from '@dhis2/ui' import PropTypes from 'prop-types' import React, { useState, useMemo, useCallback, useEffect } from 'react' +import { SelectField, DatePicker } from '../../core/index.js' import PeriodTypeSelect from '../../periods/PeriodTypeSelect.js' import PeriodSelect from '../../periods/PeriodSelect.js' import StartEndDates from '../../periods/StartEndDates.js' import { START_END_DATES } from '../../../constants/periods.js' import { getTimeRange } from '../../../util/earthEngine.js' +// TOOD: Remove reducers that are less relevant +const periodReducers = [ + { + id: 'mean', + name: i18n.t('Mean'), + }, + { + id: 'min', + name: i18n.t('Min'), + }, + { + id: 'max', + name: i18n.t('Max'), + }, + { + id: 'median', + name: i18n.t('Median'), + }, + { + id: 'count', + name: i18n.t('Count'), + }, + { + id: 'mode', + name: i18n.t('Mode'), + }, + { + id: 'product', + name: i18n.t('Product'), + }, +] + const EarthEnginePeriodReducer = ({ datasetId, period, + reducer, onChange, errorText, className, @@ -18,6 +52,13 @@ const EarthEnginePeriodReducer = ({ const [periodType, setPeriodType] = useState() const [dateRange, setDateRange] = useState() + const onPeriodChange = useCallback( + (period) => onChange(period ? { ...period, periodType } : null), + [periodType, onChange] + ) + + const onStartEndDateChange = useCallback(() => {}, []) + useEffect(() => { getTimeRange(datasetId).then(setDateRange) }, [datasetId]) @@ -29,24 +70,53 @@ const EarthEnginePeriodReducer = ({ value={periodType} onChange={(period) => setPeriodType(period.id)} /> - {dateRange && - periodType && - (periodType === START_END_DATES ? ( - - ) : ( - - ))} + {dateRange && periodType ? ( + <> + {periodType === START_END_DATES ? ( + <> + + + + + ) : ( + + )} + {periodType !== 'DAILY' && ( + + )} + + ) : ( +
{i18n.t('Loading periods')}
+ )}
) } diff --git a/src/components/edit/earthEngine/PeriodTab.js b/src/components/edit/earthEngine/PeriodTab.js index 3c84410d4..c05d4cefa 100644 --- a/src/components/edit/earthEngine/PeriodTab.js +++ b/src/components/edit/earthEngine/PeriodTab.js @@ -11,7 +11,7 @@ const EarthEnginePeriodTab = ({ filters, periodType, period, - periods, + periodReducer, onChange, errorText, className, @@ -22,6 +22,7 @@ const EarthEnginePeriodTab = ({ @@ -45,7 +46,7 @@ EarthEnginePeriodTab.propTypes = { className: PropTypes.string, errorText: PropTypes.string, period: PropTypes.object, - periods: PropTypes.oneOfType([PropTypes.array, PropTypes.object]), + // periods: PropTypes.oneOfType([PropTypes.array, PropTypes.object]), } export default EarthEnginePeriodTab diff --git a/src/components/edit/earthEngine/StyleSelect.js b/src/components/edit/earthEngine/StyleSelect.js index 383f959ad..05e0964f0 100644 --- a/src/components/edit/earthEngine/StyleSelect.js +++ b/src/components/edit/earthEngine/StyleSelect.js @@ -2,7 +2,7 @@ import i18n from '@dhis2/d2-i18n' import PropTypes from 'prop-types' import React, { useState, useCallback } from 'react' import { connect } from 'react-redux' -import { setParams } from '../../../actions/layerEdit.js' +import { setStyle } from '../../../actions/layerEdit.js' import { getColorScale, getColorPalette } from '../../../util/colors.js' import { NumberField, ColorScaleSelect } from '../../core/index.js' import styles from '../styles/LayerDialog.module.css' @@ -10,9 +10,9 @@ import styles from '../styles/LayerDialog.module.css' const minSteps = 3 const maxSteps = 9 -const StyleSelect = ({ unit, params, setParams }) => { - const { min, max, palette } = params - const [steps, setSteps] = useState(palette.split(',').length) +const StyleSelect = ({ unit, style, setStyle }) => { + const { min, max, palette } = style + const [steps, setSteps] = useState(palette.length) const onStepsChange = useCallback( (steps) => { @@ -21,13 +21,13 @@ const StyleSelect = ({ unit, params, setParams }) => { const newPalette = getColorPalette(scale, steps) if (newPalette) { - setParams({ palette: newPalette }) + setStyle({ palette: newPalette }) } } setSteps(steps) }, - [palette, setParams] + [palette, setStyle] ) let warningText @@ -57,13 +57,13 @@ const StyleSelect = ({ unit, params, setParams }) => { setParams({ min: parseInt(min) })} + onChange={(min) => setStyle({ min: parseInt(min) })} className={styles.flexInnerColumn} /> setParams({ max: parseInt(max) })} + onChange={(max) => setStyle({ max: parseInt(max) })} className={styles.flexInnerColumn} /> { )}
setParams({ palette })} + palette={style.palette} + onChange={(palette) => setStyle({ palette })} width={260} />
@@ -90,15 +90,15 @@ const StyleSelect = ({ unit, params, setParams }) => { } StyleSelect.propTypes = { - setParams: PropTypes.func.isRequired, + setStyle: PropTypes.func.isRequired, unit: PropTypes.string.isRequired, - params: PropTypes.shape({ + style: PropTypes.shape({ max: PropTypes.number.isRequired, min: PropTypes.number.isRequired, - palette: PropTypes.string.isRequired, + palette: PropTypes.array.isRequired, }), } export default connect(null, { - setParams, + setStyle, })(StyleSelect) diff --git a/src/components/edit/earthEngine/StyleTab.js b/src/components/edit/earthEngine/StyleTab.js index 21024f371..130b4c6fc 100644 --- a/src/components/edit/earthEngine/StyleTab.js +++ b/src/components/edit/earthEngine/StyleTab.js @@ -6,26 +6,26 @@ import styles from '../styles/LayerDialog.module.css' import LegendPreview from './LegendPreview.js' import StyleSelect from './StyleSelect.js' -const StyleTab = ({ unit, params, hasOrgUnitField }) => ( +const StyleTab = ({ unit, style, hasOrgUnitField }) => (
- {params && } + {style && }
- {params && } + {style && }
) StyleTab.propTypes = { hasOrgUnitField: PropTypes.bool.isRequired, unit: PropTypes.string, - params: PropTypes.shape({ + style: PropTypes.shape({ max: PropTypes.number.isRequired, min: PropTypes.number.isRequired, - palette: PropTypes.string.isRequired, + palette: PropTypes.array.isRequired, }), } diff --git a/src/components/map/layers/earthEngine/EarthEngineLayer.js b/src/components/map/layers/earthEngine/EarthEngineLayer.js index f1ebc4337..7b4bb62a0 100644 --- a/src/components/map/layers/earthEngine/EarthEngineLayer.js +++ b/src/components/map/layers/earthEngine/EarthEngineLayer.js @@ -102,7 +102,7 @@ export default class EarthEngineLayer extends Layer { attribution, filter, // filter: periodFilter, - // periodReducer: 'mean', + periodReducer, methods, mosaic, name, diff --git a/src/constants/actionTypes.js b/src/constants/actionTypes.js index 0621cafb0..f1a083bdb 100644 --- a/src/constants/actionTypes.js +++ b/src/constants/actionTypes.js @@ -117,7 +117,7 @@ export const LAYER_EDIT_RENDERING_STRATEGY_SET = export const LAYER_EDIT_AGGREGATION_TYPE_SET = 'LAYER_EDIT_AGGREGATION_TYPE_SET' export const LAYER_EDIT_DATA_ELEMENT_GROUP_SET = 'LAYER_EDIT_DATA_ELEMENT_GROUP_SET' -export const LAYER_EDIT_PARAMS_SET = 'LAYER_EDIT_PARAMS_SET' +export const LAYER_EDIT_STYLE_SET = 'LAYER_EDIT_STYLE_SET' export const LAYER_EDIT_FILTER_SET = 'LAYER_EDIT_FILTER_SET' export const LAYER_EDIT_LABELS_SET = 'LAYER_EDIT_LABELS_SET' export const LAYER_EDIT_LABEL_TEMPLATE = 'LAYER_EDIT_LABEL_TEMPLATE' diff --git a/src/reducers/layerEdit.js b/src/reducers/layerEdit.js index f40823e43..325d38552 100644 --- a/src/reducers/layerEdit.js +++ b/src/reducers/layerEdit.js @@ -318,7 +318,8 @@ const layerEdit = (state = null, action) => { newState = { ...state, colorScale: action.colorScale, - classes: action.colorScale.split(',').length, + // classes: action.colorScale.split(',').length, + classes: action.colorScale.length, } if (newState.styleDataItem) { @@ -440,11 +441,11 @@ const layerEdit = (state = null, action) => { band: action.payload, } - case types.LAYER_EDIT_PARAMS_SET: + case types.LAYER_EDIT_STYLE_SET: return { ...state, - params: { - ...state.params, + style: { + ...state.style, ...action.payload, }, } diff --git a/src/util/colors.js b/src/util/colors.js index 37ad87c3d..1bcc25229 100644 --- a/src/util/colors.js +++ b/src/util/colors.js @@ -39,14 +39,14 @@ export const colorScales = [ // Returns a color brewer scale for a number of classes export const getColorPalette = (scale, classes) => { - return colorbrewer[scale][classes].join(',') + return colorbrewer[scale][classes] // .join(',') } // Returns color scale name for a palette export const getColorScale = (palette) => { - const classes = palette.split(',').length + const classes = palette.length // palette.split(',').length return colorScales.find( - (name) => colorbrewer[name][classes].join(',') === palette + (name) => colorbrewer[name][classes].join(',') === palette.join(',') ) } diff --git a/src/util/earthEngine.js b/src/util/earthEngine.js index 574675e6a..9082fa972 100644 --- a/src/util/earthEngine.js +++ b/src/util/earthEngine.js @@ -143,11 +143,13 @@ export const getPeriods = async (eeId, periodType, filters) => { return features.map(getPeriod) } +const oneDayInMilliseconds = 24 * 60 * 60 * 1000 + export const getTimeRange = async (eeId) => { const eeWorker = await getWorkerInstance() return eeWorker.getTimeRange(eeId).then(({ min, max }) => ({ firstDate: min ? formatDate(min) : null, - lastDate: max ? formatDate(max) : null, + lastDate: max ? formatDate(max - oneDayInMilliseconds) : null, })) } diff --git a/src/util/legend.js b/src/util/legend.js index 9048f8572..b7bb74838 100644 --- a/src/util/legend.js +++ b/src/util/legend.js @@ -73,7 +73,7 @@ export const getAutomaticLegendItems = ( colorScale = defaultColorScale ) => { const items = data.length ? getLegendItems(data, method, classes) : [] - const colors = colorScale.split(',') + const colors = colorScale // .split(',') return items.map((item, index) => ({ ...item, diff --git a/src/util/time.js b/src/util/time.js index e4d305b55..e4b659c1d 100644 --- a/src/util/time.js +++ b/src/util/time.js @@ -131,3 +131,9 @@ export const getStartEndDateError = (startDateStr, endDateStr) => { * @returns {Number} */ export const getYear = (date) => toDate(date || new Date()).getFullYear() + +export const incrementDate = (date, increment = 1) => { + const dateObj = toDate(date) + dateObj.setDate(dateObj.getDate() + increment) + return formatDate(dateObj) +}