diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ff9b7edf9bc36823916ec121ea2834da902790f..a1b3367ba3f68ef01f0f26ee514ac6700308241f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased](https://github.com/usgs/waterdataui/compare/waterdataui-1.2.0...master) ### Added - Daily statistical data will now appear under the parameter selection list. +- Data tables accordion shows a table for a secondary instantaneous value parameter data when a second parameter (that has data) is selected. ### Changed - Data download component was converted to Vue. diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/index.test.js b/assets/src/scripts/monitoring-location/components/hydrograph/index.test.js index 9d3f23c635dfbb7df616e977c5f74a94f8b6d3ef..27000191180dae06b53a821961bc87fc4ce0d01e 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/index.test.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/index.test.js @@ -364,7 +364,8 @@ describe('monitoring-location/components/hydrograph module', () => { }); it('should have data tables for hydrograph data', () => { - expect(select('#iv-table-container').size()).toBe(1); + expect(select('#iv-primary-table-container').size()).toBe(1); + expect(select('#iv-secondary-table-container').size()).toBe(1); expect(select('#gw-table-container').size()).toBe(1); }); @@ -477,7 +478,8 @@ describe('monitoring-location/components/hydrograph module', () => { }); it('should not have data tables for hydrograph data', () => { - expect(select('#iv-table-container').size()).toBe(0); + expect(select('#iv-primary-table-container').size()).toBe(0); + expect(select('#iv-secondary-table-container').size()).toBe(0); expect(select('#gw-table-container').size()).toBe(0); }); diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/mock-hydrograph-state.js b/assets/src/scripts/monitoring-location/components/hydrograph/mock-hydrograph-state.js index 111cfe58f8385eb3c4f2ecc39dea8abb449d4049..cdb613fc691d8e1351e54da33a97e0977644ec0d 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/mock-hydrograph-state.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/mock-hydrograph-state.js @@ -43,6 +43,34 @@ export const TEST_PRIMARY_IV_DATA = { } }; +export const TEST_SECONDARY_IV_DATA = { + parameter: { + parameterCode: '00065', + name: 'Gage height, ft', + description: 'Gage height, feet', + unit: 'ft' + }, + values: { + '57465': { + points: [ + {value: '3', qualifiers: ['A'], dateTime: 1582560900000}, + {value: '3.2', qualifiers: ['A'], dateTime: 1582561800000}, + {value: null, qualifiers: ['A', 'ICE'], dateTime: 1582562700000}, + {value: null, qualifiers: ['A', 'ICE'], dateTime: 1582569900000}, + {value: '4', qualifiers: ['E'], dateTime: 1582570800000}, + {value: '5.8', qualifiers: ['E'], dateTime: 1600617600000}, + {value: '7', qualifiers: ['E'], dateTime: 1600618500000}, + {value: '6.5', qualifiers: ['P'], dateTime: 1600619400000}, + {value: '5.9', qualifiers: ['P'], dateTime: 1600620300000} + ], + method: { + methodID: '57465', + methodDescription: '' + } + } + } +}; + export const TEST_STATS_DATA = { '153885': [ {month_nu: 2, day_nu: 24, p50_va: 16, ts_id: '153885', loc_web_ds: 'Method1', begin_yr: '2011', end_yr: '2020', max_va_yr: '2020', diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/selectors/iv-data.js b/assets/src/scripts/monitoring-location/components/hydrograph/selectors/iv-data.js index c1c481d5c9bc93e8003ce5cf09186921307fe741..32e2d4417d1acde4543eaf9b208c1287ca9af106 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/selectors/iv-data.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/selectors/iv-data.js @@ -7,7 +7,7 @@ import {createSelector} from 'reselect'; import config from 'ui/config'; -import {getIVData, getIVPrimaryParameter} from 'ml/selectors/hydrograph-data-selector'; +import {getIVData, getIVParameter} from 'ml/selectors/hydrograph-data-selector'; import {getSelectedIVMethodID} from 'ml/selectors/hydrograph-state-selector'; const MASKED_QUALIFIERS = { @@ -181,7 +181,7 @@ export const getIVDataRange = memoize(dataKind => createSelector( */ export const getIVTableData = memoize(dataKind => createSelector( getIVDataPoints(dataKind), - getIVPrimaryParameter, + getIVParameter(dataKind), (ivData, parameter) => { if (!ivData) { return []; diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/selectors/time-series-data.js b/assets/src/scripts/monitoring-location/components/hydrograph/selectors/time-series-data.js index b28857c30f7029357fa4505c6f90ec4584d099a2..760d8bd835b0beafbc7251a04001f2bbc0dc8dcd 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/selectors/time-series-data.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/selectors/time-series-data.js @@ -5,10 +5,11 @@ import {createSelector} from 'reselect'; import config from 'ui/config'; import {getSelectedGroundwaterLevels} from 'ml/selectors/groundwater-level-field-visits-selector'; -import {getIVData, getStatisticsData, getPrimaryMethods, getIVPrimaryParameter, +import {getIVData, getStatisticsData, getPrimaryMethods, getIVParameter, getTimeRange } from 'ml/selectors/hydrograph-data-selector'; import {getSelectedIVMethodID, isCompareIVDataVisible, isMedianDataVisible} from 'ml/selectors/hydrograph-state-selector'; +import {isSecondaryIVDataVisible} from '../../../selectors/hydrograph-state-selector'; const formatTime = function(timeInMillis) { return DateTime.fromMillis(timeInMillis, {zone: config.locationTimeZone}).toFormat('L/d/yyyy tt ZZZ'); @@ -19,7 +20,7 @@ const formatTime = function(timeInMillis) { * parameter that is currently displayed in the hydrograph or null if no data. */ export const getPrimaryParameter = createSelector( - getIVPrimaryParameter, + getIVParameter('primary'), getSelectedGroundwaterLevels, (ivParameter, gwLevels) => { return ivParameter ? ivParameter : gwLevels ? gwLevels.parameter : null; @@ -28,16 +29,19 @@ export const getPrimaryParameter = createSelector( /** * Returns a Redux selector function which returns whether the dataKind time series is visible - * @param {String} dataKind - 'primary', 'compare', 'median' + * @param {String} dataKind - 'primary', 'secondary', 'compare', or 'median' * @return {Function} */ export const isVisible = memoize(dataKind => createSelector( + isSecondaryIVDataVisible, isCompareIVDataVisible, isMedianDataVisible, - (compareVisible, medianVisible) => { + (secondaryVisible, compareVisible, medianVisible) => { switch (dataKind) { case 'primary': return true; + case 'secondary': + return secondaryVisible; case 'compare': return compareVisible; case 'median': diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/selectors/time-series-data.test.js b/assets/src/scripts/monitoring-location/components/hydrograph/selectors/time-series-data.test.js index 29bf496357224b13d2b46d13a68884d17394268a..787667bf4b56b016c83f1460a30c8dddf4e3ee01 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/selectors/time-series-data.test.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/selectors/time-series-data.test.js @@ -64,6 +64,7 @@ const TEST_STATE = { hydrographState: { selectedParameterCode: '72019', showCompareIVData: false, + showSecondaryIVData: false, showMedianData: false, selectedIVMethodID: '252055' } @@ -75,6 +76,7 @@ describe('monitoring-location/components/hydrograph/selectors/time-series-data m it('Returns whether the time series is visible', () => { expect(isVisible('primary')(TEST_STATE)).toBe(true); expect(isVisible('compare')(TEST_STATE)).toBe(false); + expect(isVisible('secondary')(TEST_STATE)).toBe(false); expect(isVisible('compare')({ ...TEST_STATE, hydrographState: { @@ -90,6 +92,13 @@ describe('monitoring-location/components/hydrograph/selectors/time-series-data m showMedianData: true } })).toBe(true); + expect(isVisible('secondary')({ + ...TEST_STATE, + hydrographState: { + ...TEST_STATE.hydrographState, + showSecondaryIVData: true + } + })).toBe(true); }); }); @@ -265,6 +274,7 @@ describe('monitoring-location/components/hydrograph/selectors/time-series-data m all: [] }, hydrographState: { + showSecondaryIVData: false, showCompareIVData: false, showMedianData: true } @@ -294,6 +304,7 @@ describe('monitoring-location/components/hydrograph/selectors/time-series-data m all: [] }, hydrographState: { + showSecondaryIVData: false, showCompareIVData: false, showMedianData: true, selectedIVMethodID: '90649' diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/data-table.test.js b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/data-table.test.js index 9a18e0ad2aff9411631b9e10af47a6460b7428a9..e092e4d5bde75d3be08b13c1962de9ec1bfcea19 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/data-table.test.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/data-table.test.js @@ -7,7 +7,7 @@ import config from 'ui/config'; import {configureStore} from 'ml/store'; -import {TEST_PRIMARY_IV_DATA, TEST_GW_LEVELS} from '../mock-hydrograph-state'; +import {TEST_PRIMARY_IV_DATA, TEST_GW_LEVELS, TEST_SECONDARY_IV_DATA} from '../mock-hydrograph-state'; import DataTable from './data-table.vue'; import DownloadData from './download-data.vue'; @@ -51,7 +51,8 @@ describe('monitoring-location/components/hydrograph/components/data-table.vue', } }); - expect(wrapper.find('#iv-table-container').isVisible()).toBe(true); + expect(wrapper.find('#iv-primary-table-container').isVisible()).toBe(true); + expect(wrapper.find('#iv-secondary-table-container').isVisible()).toBe(false); expect(wrapper.find('#gw-table-container').isVisible()).toBe(true); }); @@ -88,7 +89,8 @@ describe('monitoring-location/components/hydrograph/components/data-table.vue', } }); - expect(wrapper.find('#iv-table-container').isVisible()).toBe(true); + expect(wrapper.find('#iv-primary-table-container').isVisible()).toBe(true); + expect(wrapper.find('#iv-secondary-table-container').isVisible()).toBe(false); expect(wrapper.find('#gw-table-container').isVisible()).toBe(false); }); @@ -124,7 +126,48 @@ describe('monitoring-location/components/hydrograph/components/data-table.vue', } }); - expect(wrapper.find('#iv-table-container').isVisible()).toBe(false); + expect(wrapper.find('#iv-primary-table-container').isVisible()).toBe(false); + expect(wrapper.find('#iv-secondary-table-container').isVisible()).toBe(false); + expect(wrapper.find('#gw-table-container').isVisible()).toBe(true); + }); + + it('Shows both IV primary and secondary parameter selection tables and GW data table', () => { + store = configureStore({ + hydrographData: { + currentTimeRange: { + start: 1582560000000, + end: 1600620000000 + }, + primaryIVData: TEST_PRIMARY_IV_DATA, + secondaryIVData: TEST_SECONDARY_IV_DATA + }, + groundwaterLevelData: { + all: [TEST_GW_LEVELS] + }, + hydrographState: { + showSecondaryIVData: true, + selectedParameterCode: '72019', + selectedIVMethodID: '90649' + } + }); + + wrapper = mount(DataTable, { + global: { + plugins: [ + [ReduxConnectVue, { + store, + mapDispatchToPropsFactory: (actionCreators) => (dispatch) => bindActionCreators(actionCreators, dispatch), + mapStateToPropsFactory: createStructuredSelector + }] + ], + provide: { + store: store + } + } + }); + + expect(wrapper.find('#iv-primary-table-container').isVisible()).toBe(true); + expect(wrapper.find('#iv-secondary-table-container').isVisible()).toBe(true); expect(wrapper.find('#gw-table-container').isVisible()).toBe(true); }); diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/data-table.vue b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/data-table.vue index fa0b8057f7806ec21569dedc569ef47d88641394..029cb8c200470de6dc1cd2f70ce214edd47b069f 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/data-table.vue +++ b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/data-table.vue @@ -1,15 +1,27 @@ <template> <div id="iv-hydrograph-data-table-container"> <div - v-show="currentIVData.IVData.length" - id="iv-table-container" + v-show="currentPrimaryIVData.IVData.length" + id="iv-primary-table-container" > <PaginatedTable - :data-set="currentIVData.IVData" + :data-set="currentPrimaryIVData.IVData" :headers="ivColumnHeadings" :key-order="ivValueNames" :sort-by="['dateTime']" - :title="`${currentIVData.name} -- instantaneous value data`" + :title="`${currentPrimaryIVData.name} -- instantaneous value data`" + /> + </div> + <div + v-show="currentSecondaryIVData.IVData.length && isSecondaryParameterSelected" + id="iv-secondary-table-container" + > + <PaginatedTable + :data-set="currentSecondaryIVData.IVData" + :headers="ivColumnHeadings" + :key-order="ivValueNames" + :sort-by="['dateTime']" + :title="`${currentSecondaryIVData.name} -- instantaneous value data`" /> </div> <div @@ -66,6 +78,7 @@ import config from 'ui/config.js'; import {getIVTableData} from '../selectors/iv-data'; import {getGroundwaterLevelsTableData} from '../selectors/discrete-data'; +import {isVisible} from '../selectors/time-series-data'; import DownloadData from './download-data.vue'; import PaginatedTable from './paginated-table.vue'; @@ -77,8 +90,6 @@ export default { PaginatedTable }, setup() { - const downloadIcon = `${config.STATIC_URL}img/sprite.svg#file_download`; - const showDownloadContainer = ref(false); const COLUMN_HEADINGS = { iv: ['Time', 'Result', 'Approval', 'Masks'], gw: ['Time', 'Result', 'Accuracy', 'Approval', 'Qualifiers'] @@ -99,17 +110,20 @@ export default { return result; }; - const getIVData = createSelector( - getIVTableData('primary'), - (data) => { + const getIVData = dataKind => createSelector( + getIVTableData(dataKind), + (data) => { - return { - IVData: data.map(object => filter(object, VALUE_NAMES.iv)), - name: data.length ? data[0].parameterName : '' + return { + IVData: data.map(object => filter(object, VALUE_NAMES.iv)), + name: data.length ? data[0].parameterName : '' }; - } + } ); + const getPrimaryIVData = getIVData('primary'); + const getSecondaryIVData = getIVData('secondary'); + const getGWData = createSelector( getGroundwaterLevelsTableData, (data) => { @@ -122,10 +136,15 @@ export default { ); const state = useState({ - currentIVData: getIVData, + isSecondaryParameterSelected: isVisible('secondary'), + currentPrimaryIVData: getPrimaryIVData, + currentSecondaryIVData: getSecondaryIVData, currentGWData: getGWData }); + const downloadIcon = `${config.STATIC_URL}img/sprite.svg#file_download`; + const showDownloadContainer = ref(false); + const toggleDownloadContainer = function() { showDownloadContainer.value = !showDownloadContainer.value; }; diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/parameter-selection.test.js b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/parameter-selection.test.js index 12565ea8c022f94619a618586ee07e4f77b83adf..f793f04bc9a1efca023e314ccfd36c88e012d46a 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/parameter-selection.test.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/parameter-selection.test.js @@ -57,6 +57,7 @@ describe('monitoring-location/components/hydrograph/vue-components/parameter-sel }, hydrographParameters: TEST_HYDROGRAPH_PARAMETERS, hydrographState: { + showSecondaryIVData: true, selectedTimeSpan: 'P7D', selectedParameterCode: '72019', selectedIVMethodID: '90649' diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/parameter-selection.vue b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/parameter-selection.vue index 265a6ce829ea443d0492efc16000d12d31183e93..89c3e7ac6b23c61801459dca5d45763b0630005d 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/parameter-selection.vue +++ b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/parameter-selection.vue @@ -91,11 +91,12 @@ import config from 'ui/config'; import {getInputsForRetrieval, getSelectedParameterCode} from 'ml/selectors/hydrograph-state-selector'; -import {setSelectedParameterCode, setSelectedIVMethodID} from 'ml/store/hydrograph-state'; +import {setSecondaryIVDataVisibility, setSelectedParameterCode, setSelectedIVMethodID} from 'ml/store/hydrograph-state'; import {retrieveHydrographData} from 'ml/store/hydrograph-data'; import {getAvailableParameters} from '../selectors/parameter-data'; import {getSortedIVMethods} from '../selectors/time-series-data'; +import {isVisible} from '../selectors/time-series-data'; import {showDataIndicators} from '../data-indicator'; @@ -135,13 +136,15 @@ export default { const state = useState({ parameters: getAvailableParameterData, sortedIvMethods: getSortedIVMethods, - selectedParameterCode: getSelectedParameterCode + selectedParameterCode: getSelectedParameterCode, + isSecondaryParameterSelected: isVisible('secondary') }); const actions = useActions({ setSelectedParameterCode, setSelectedIVMethodID, - retrieveHydrographData + retrieveHydrographData, + setSecondaryIVDataVisibility }); // Second parameter selection code @@ -165,7 +168,7 @@ export default { const buttonDetail = { id: `second-parameter-radio-button-${parameter.parameterCode}`, label: parameter.description, - checked: parameterCodeOfSecondaryRadioButton === parameter.parameterCode, + checked: state.isSecondaryParameterSelected.value && parameterCodeOfSecondaryRadioButton === parameter.parameterCode, actionValue: { secondaryParameterCode: parameter.parameterCode } @@ -193,8 +196,7 @@ export default { function selectParameter(parameterCode) { if (parameterCodeOfSecondaryRadioButton === expandedParameterCode.value) { isShowSecondParameterOptionsChecked.value = false; - // TODO: Hide second parameter visibility -- perhaps as part of WDFN-732 - console.log(`Primary button clicked, ${parameterCode}, is same as secondary selection. Remove second parameter from graph`); + actions.setSecondaryIVDataVisibility(false); } actions.setSelectedParameterCode(parameterCode); diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/secondary-parameter-controls.test.js b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/secondary-parameter-controls.test.js index 3ceb186a8e1fb7c1a91b0c571b8e7f5848afeecb..787675f09788730463659b6e20c6972724a6d453 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/secondary-parameter-controls.test.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/secondary-parameter-controls.test.js @@ -1,16 +1,17 @@ -import {shallowMount} from '@vue/test-utils'; - -import USWDSCheckbox from 'ui/uswds-components/checkbox.vue'; -import USWDSRadioButtonSet from 'ui/uswds-components/radio-button-set.vue'; - -import SecondaryParameterControls from './secondary-parameter-controls.vue'; +import {enableFetchMocks, disableFetchMocks} from 'jest-fetch-mock'; import ReduxConnectVue from 'redux-connect-vue'; +import {configureStore} from 'ml/store'; import {bindActionCreators} from 'redux'; import {createStructuredSelector} from 'reselect'; -import {TEST_HYDROGRAPH_PARAMETERS, TEST_PRIMARY_IV_DATA} from '../mock-hydrograph-state'; -import {configureStore} from 'ml/store'; +import {shallowMount} from '@vue/test-utils'; +import * as utils from 'ui/utils'; +import {TEST_HYDROGRAPH_PARAMETERS, TEST_PRIMARY_IV_DATA} from '../mock-hydrograph-state'; +import SecondaryParameterControls from './secondary-parameter-controls.vue'; + +import USWDSCheckbox from 'ui/uswds-components/checkbox.vue'; +import USWDSRadioButtonSet from 'ui/uswds-components/radio-button-set.vue'; describe('monitoring-location/components/hydrograph/vue-components/secondary-parameter-controls', () => { const parameterList = [ @@ -32,15 +33,28 @@ describe('monitoring-location/components/hydrograph/vue-components/secondary-par } ]; + beforeAll(() => { + enableFetchMocks(); + }); + + afterAll(() => { + disableFetchMocks(); + }); + let wrapper; let store; const TEST_STATE = { hydrographData: { - primaryIVData: TEST_PRIMARY_IV_DATA + primaryIVData: TEST_PRIMARY_IV_DATA, + currentTimeRange: { + start: 1613413736967, + end: 1614018536967 + } }, hydrographParameters: TEST_HYDROGRAPH_PARAMETERS, hydrographState: { + showSecondaryIVData: true, selectedTimeSpan: 'P7D', selectedParameterCode: '72019', selectedIVMethodID: '90649' @@ -60,7 +74,8 @@ describe('monitoring-location/components/hydrograph/vue-components/secondary-par }] ], provide: { - store: store + store: store, + siteno: '07144100' } }, props: { @@ -97,6 +112,8 @@ describe('monitoring-location/components/hydrograph/vue-components/secondary-par }); it('expects clicking a radio button will emit the correct event', async() => { + utils.mediaQuery = jest.fn().mockReturnValue(true); + fetch.mockResponse(JSON.stringify({})); const radioButtonSetComponent = wrapper.findComponent(USWDSRadioButtonSet); await radioButtonSetComponent.vm.$emit('updateValue', { @@ -121,7 +138,8 @@ describe('monitoring-location/components/hydrograph/vue-components/secondary-par }] ], provide: { - store: store + store: store, + siteno: '07144100' } }, props: { diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/secondary-parameter-controls.vue b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/secondary-parameter-controls.vue index a45a637fa644c1e4a763512c8c341da9a947e909..8d303ecb7f14913dfb4d4f0c9510dfc7c46d6556 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/secondary-parameter-controls.vue +++ b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/secondary-parameter-controls.vue @@ -20,15 +20,17 @@ </template> <script> -import {ref} from 'vue'; +import {ref, inject} from 'vue'; import {useActions} from 'redux-connect-vue'; -import {setCompareDataVisibility, setMedianDataVisibility} from 'ml/store/hydrograph-state'; +import {setSecondaryIVDataVisibility, setCompareDataVisibility, setMedianDataVisibility} from 'ml/store/hydrograph-state'; +import {retrieveSecondParameterIVData} from 'ml/store/hydrograph-data'; +import {getTimeRange} from 'ml/selectors/hydrograph-data-selector'; +import {showDataIndicators} from '../data-indicator'; import USWDSCheckbox from 'ui/uswds-components/checkbox.vue'; import USWDSRadioButtonSet from 'ui/uswds-components/radio-button-set.vue'; - export default { name: 'SecondaryParameterControls', components: { @@ -46,9 +48,14 @@ export default { } }, setup(props, {emit}) { + const reduxStore = inject('store'); + const siteNumber = inject('siteno'); + const actions = useActions({ + setSecondaryIVDataVisibility, setCompareDataVisibility, - setMedianDataVisibility + setMedianDataVisibility, + retrieveSecondParameterIVData }); const showSecondParameterList = ref(false); @@ -58,14 +65,12 @@ export default { const isBoxChecked = !props.isShowSecondParameterOptionsChecked; if (!isBoxChecked) { + actions.setSecondaryIVDataVisibility(false); emit('disableEnableMedianAndCompare', false); emit('checkedRadioButton', { secondaryParameterCode: '' }); - // TODO: Hide second parameter visibility -- perhaps as part of WDFN-732 - console.log('check box unchecked: clear any second parameter data from graph '); } - emit('checkedCheckBox', isBoxChecked); }; @@ -76,12 +81,24 @@ export default { }; const graphSecondParameter = function(buttonData) { + actions.setSecondaryIVDataVisibility(true); disableCompareAndMedianButtons(); emit('checkedRadioButton', buttonData); - // TODO: Add data to state -- part of WDFN-735 - // TODO: Graph data on hydrograph -- part of WDFN-735 - console.log(`Radio button, ${buttonData.secondaryParameterCode} clicked: fetch data and then run graphing code using secondary parameter ${buttonData.secondaryParameterCode}`); - }; + + const reduxState = reduxStore.getState(); + const currentTimeRange = getTimeRange('current')(reduxState); + showDataIndicators(true, reduxStore); + actions.retrieveSecondParameterIVData( + siteNumber, + { + parameterCode: buttonData.secondaryParameterCode, + startTime: currentTimeRange.start, + endTime: currentTimeRange.end + } + ).then(() => { + showDataIndicators(false, reduxStore); + }); + }; return { showSecondParameterList, diff --git a/assets/src/scripts/monitoring-location/selectors/flood-data-selector.js b/assets/src/scripts/monitoring-location/selectors/flood-data-selector.js index cd0571db61275647c1de11677c99bc5049529b51..c093e5a8fcb998e9e6afb9aa320b9276528237fd 100644 --- a/assets/src/scripts/monitoring-location/selectors/flood-data-selector.js +++ b/assets/src/scripts/monitoring-location/selectors/flood-data-selector.js @@ -2,7 +2,7 @@ import {createSelector} from 'reselect'; import config from 'ui/config'; -import {getIVPrimaryParameter} from './hydrograph-data-selector'; +import {getIVParameter} from './hydrograph-data-selector'; export const getFloodStages = state => state.floodData.stages || []; @@ -33,7 +33,7 @@ export const hasFloodLevels = createSelector( */ export const showFloodLevels = createSelector( hasFloodLevels, - getIVPrimaryParameter, + getIVParameter('primary'), (hasFloodLevels, parameter) => hasFloodLevels && parameter && parameter.parameterCode === config.GAGE_HEIGHT_PARAMETER_CODE ); diff --git a/assets/src/scripts/monitoring-location/selectors/hydrograph-data-selector.js b/assets/src/scripts/monitoring-location/selectors/hydrograph-data-selector.js index f0e0ec006772c186e4951618fed2ac9f85e8f657..1d3684aa748460b6dce5311095d5a0d8134c1cac 100644 --- a/assets/src/scripts/monitoring-location/selectors/hydrograph-data-selector.js +++ b/assets/src/scripts/monitoring-location/selectors/hydrograph-data-selector.js @@ -21,7 +21,7 @@ export const getTimeRange = memoize((timeRangeKind) => state => state.hydrograph /* *Returns a selector function which returns the IV data for the dataKind - * @param {String} dataKind - 'primary' or 'compare' + * @param {String} dataKind - 'primary', 'secondary' or 'compare' * @return {Function} */ export const getIVData = memoize((dataKind) => state => state.hydrographData[`${dataKind}IVData`] || null); @@ -38,8 +38,8 @@ export const getStatisticsData = state => state.hydrographData.statisticsData || * and is an Object containing the parameter code, name, description, and unit * @return {Function} */ -export const getIVPrimaryParameter = createSelector( - getIVData('primary'), +export const getIVParameter = dataKind => createSelector( + getIVData(dataKind), (ivData) => { let parameter = null; if (ivData) { diff --git a/assets/src/scripts/monitoring-location/selectors/hydrograph-data-selector.test.js b/assets/src/scripts/monitoring-location/selectors/hydrograph-data-selector.test.js index ea75eb453296832ab0ed60fafda054528c634595..3132b037133143d31cd0889893aa88f7d1aeaea8 100644 --- a/assets/src/scripts/monitoring-location/selectors/hydrograph-data-selector.test.js +++ b/assets/src/scripts/monitoring-location/selectors/hydrograph-data-selector.test.js @@ -1,6 +1,6 @@ import config from 'ui/config'; -import {getThresholds, getTimeRange, getIVData, getStatisticsData, getIVPrimaryParameter, +import {getThresholds, getTimeRange, getIVData, getStatisticsData, getIVParameter, getPrimaryMethods, getPrimaryMedianStatisticsData, getPrimaryMedianStatisticsValueRange } from './hydrograph-data-selector'; @@ -25,6 +25,24 @@ describe('monitoring-location/selectors/hydrograph-data-selectors', () => { } }; + const TEST_SECONDARY_IV_DATA = { + parameter: { + parameterCode: '00065', + name: 'Gage height, feet', + description: 'Gage height, feet', + unit: 'ft' + }, + values: { + '43043': { + points: [ + {value: '3.3', dateTime: 1613421000000}, + {value: '3.6', dateTime: 1613421900000}, + {value: '3.9', dateTime: 1613422800000}], + method: {methodID: '43043'} + } + } + }; + const TEST_COMPARE_IV_DATA = { parameter: { parameterCode: '00060', @@ -135,15 +153,24 @@ describe('monitoring-location/selectors/hydrograph-data-selectors', () => { expect(getIVData('primary')({ hydrographData: { primaryIVData: TEST_PRIMARY_IV_DATA, + secondaryIVData: TEST_SECONDARY_IV_DATA, compareIVData: TEST_COMPARE_IV_DATA } })).toEqual(TEST_PRIMARY_IV_DATA); expect(getIVData('compare')({ hydrographData: { primaryIVData: TEST_PRIMARY_IV_DATA, + secondaryIVData: TEST_SECONDARY_IV_DATA, compareIVData: TEST_COMPARE_IV_DATA } })).toEqual(TEST_COMPARE_IV_DATA); + expect(getIVData('secondary')({ + hydrographData: { + primaryIVData: TEST_PRIMARY_IV_DATA, + secondaryIVData: TEST_SECONDARY_IV_DATA, + compareIVData: TEST_COMPARE_IV_DATA + } + })).toEqual(TEST_SECONDARY_IV_DATA); }); }); @@ -163,15 +190,15 @@ describe('monitoring-location/selectors/hydrograph-data-selectors', () => { }); }); - describe('getIVPrimaryParameter', () => { + describe('getIVParameter', () => { it('Returns null if no IV levels are defined', () => { - expect(getIVPrimaryParameter({ + expect(getIVParameter('primary') ({ hydrographData: {} })).toBeNull(); }); it('Returns the parameter from IV if defined', () => { - expect(getIVPrimaryParameter({ + expect(getIVParameter('primary') ({ hydrographData: { primaryIVData: TEST_PRIMARY_IV_DATA } diff --git a/assets/src/scripts/monitoring-location/selectors/hydrograph-state-selector.js b/assets/src/scripts/monitoring-location/selectors/hydrograph-state-selector.js index ee41bb03ae4648e49b110919ad338e62f0fad10b..d6012c89ea81566823deb9e65d51cc379a9617c2 100644 --- a/assets/src/scripts/monitoring-location/selectors/hydrograph-state-selector.js +++ b/assets/src/scripts/monitoring-location/selectors/hydrograph-state-selector.js @@ -11,6 +11,7 @@ import {getPeriodOfRecord} from 'ml/parameter-code-utils'; */ export const isCompareIVDataVisible = state => state.hydrographState.showCompareIVData || false; export const isMedianDataVisible = state => state.hydrographState.showMedianData || false; +export const isSecondaryIVDataVisible = state => state.hydrographState.showSecondaryIVData || false; export const getSelectedTimeSpan = state => state.hydrographState.selectedTimeSpan || null; export const getSelectedParameterCode = state => state.hydrographState.selectedParameterCode || null; export const getSelectedIVMethodID = state => state.hydrographState.selectedIVMethodID || null; diff --git a/assets/src/scripts/monitoring-location/selectors/hydrograph-state-selector.test.js b/assets/src/scripts/monitoring-location/selectors/hydrograph-state-selector.test.js index 84302231c384724838027472c9f93ad409aa075c..28cb3db7e37ca4c735a45de1e775e3f18c247e4f 100644 --- a/assets/src/scripts/monitoring-location/selectors/hydrograph-state-selector.test.js +++ b/assets/src/scripts/monitoring-location/selectors/hydrograph-state-selector.test.js @@ -1,6 +1,6 @@ import config from 'ui/config'; -import {isCompareIVDataVisible, isMedianDataVisible, getSelectedTimeSpan, getSelectedParameterCode, +import {isCompareIVDataVisible, isSecondaryIVDataVisible, isMedianDataVisible, getSelectedTimeSpan, getSelectedParameterCode, getSelectedIVMethodID, getGraphCursorOffset, getGraphBrushOffset, getInputsForRetrieval } from './hydrograph-state-selector'; @@ -22,6 +22,22 @@ describe('monitoring-location/selectors/hydrograph-state-selector', () => { }); }); + describe('isSecondaryIVDataVisible', () => { + it('returns false if no secondary parameter data should be shown on graph--ie, not in application state', () => { + expect(isSecondaryIVDataVisible({ + hydrographState: {} + })).toBe(false); + }); + + it('Returns true if secondary parameter data should be shown on graph--ie, is true in application state', () => { + expect(isSecondaryIVDataVisible({ + hydrographState: { + showSecondaryIVData: true + } + })).toBe(true); + }); + }); + describe('isMedianDataVisible', () => { it('returns false if no median data visible', () => { expect(isMedianDataVisible({ diff --git a/assets/src/scripts/monitoring-location/store/hydrograph-data.js b/assets/src/scripts/monitoring-location/store/hydrograph-data.js index 30a6be974d33b91aa0d7afb7be61efb0c89fe711..b5efd99b277898b2fc0990677d47faf4dcdd1be8 100644 --- a/assets/src/scripts/monitoring-location/store/hydrograph-data.js +++ b/assets/src/scripts/monitoring-location/store/hydrograph-data.js @@ -206,6 +206,24 @@ export const retrievePriorYearIVData = function(siteno, {parameterCode, startTim }; }; +/* + * Asynchronous Redux action to fetch the IV data for the second parameter on hydrograph using siteno, parameterCode and startTime/endTime + * @param {String} siteno + * @param {String} parameterCode + * @param {String} startTime - Epoch time + * @param {String} endTime - EpochTime + * @return {Function} that returns a Promise + */ +export const retrieveSecondParameterIVData = function(siteno, {parameterCode, startTime, endTime}) { + return function(dispatch) { + return dispatch(retrieveIVData(siteno, 'secondary', { + parameterCode: parameterCode, + startTime: DateTime.fromMillis(startTime, {zone: config.locationTimeZone}).toISO(), + endTime: DateTime.fromMillis(endTime, {zone: config.locationTimeZone}).toISO() + })); + }; +}; + /* * Asynchronous Redux action to fetch the median for siteno and parameterCode * @param {String} siteno diff --git a/assets/src/scripts/monitoring-location/store/hydrograph-data.test.js b/assets/src/scripts/monitoring-location/store/hydrograph-data.test.js index 8a84a68950e10a5c0628d72ab7d42c599ffacc90..3688543143eca984378ac70eb3b02539e3caadb1 100644 --- a/assets/src/scripts/monitoring-location/store/hydrograph-data.test.js +++ b/assets/src/scripts/monitoring-location/store/hydrograph-data.test.js @@ -20,7 +20,8 @@ import { hydrographDataReducer, retrieveHydrographData, retrieveStatistics, - retrievePriorYearIVData + retrievePriorYearIVData, + retrieveSecondParameterIVData } from './hydrograph-data'; @@ -456,6 +457,51 @@ describe('monitoring-location/store/hydrograph-data', () => { }); }); + describe('retrieveSecondParameterIVData', () => { + beforeEach(() => { + ivDataService.fetchTimeSeries = + jest.fn().mockReturnValue(Promise.resolve(JSON.parse(MOCK_IV_DATA))); + sensorThingsService.fetchDataFromSensorThings = + jest.fn().mockReturnValue(Promise.resolve(JSON.parse(MOCK_SENSOR_THINGS_DATA))); + config.ivPeriodOfRecord = { + '00060': {begin_date: '2010-01-01', end_date: '2020-01-01'} + }; + + return store.dispatch(retrieveHydrographData('11112222', 'USGS', { + parameterCode: '00060', + period: 'P7D', + startTime: null, + endTime: null, + loadCompare: false + }, + false + )); + }); + + it('Expects a call to retrieveSecondParameterIVData fetches the expected data', () => { + const currentTimeRange = store.getState().hydrographData.currentTimeRange; + return store.dispatch(retrieveSecondParameterIVData('11112222', { + parameterCode: '00060', + startTime: currentTimeRange.start, + endTime: currentTimeRange.end + })).then(() => { + const hydrographData = store.getState().hydrographData; + + const mockIVCalls = ivDataService.fetchTimeSeries.mock.calls; + expect(mockIVCalls).toHaveLength(2); + expect(mockIVCalls[1][0]).toEqual({ + siteno: '11112222', + parameterCode: '00060', + period: undefined, + startTime: '2021-02-03T12:00:00.000-06:00', + endTime: '2021-02-10T12:00:00.000-06:00' + }); + + expect(hydrographData.secondaryIVData).toBeDefined(); + }); + }); + }); + describe('retrieveStatistics', () => { beforeEach(() => { ivDataService.fetchTimeSeries = diff --git a/assets/src/scripts/monitoring-location/store/hydrograph-state.js b/assets/src/scripts/monitoring-location/store/hydrograph-state.js index bc5b09a5dcd4a1fc98d219b8b2c9241f7a454cd0..de21dcedf2096b9a2e1afc4bb2b280bf14f8b346 100644 --- a/assets/src/scripts/monitoring-location/store/hydrograph-state.js +++ b/assets/src/scripts/monitoring-location/store/hydrograph-state.js @@ -6,6 +6,7 @@ const GW_SHORTCUT_DURATIONS = config.GW_SHORTCUT_BUTTONS.map(button => button.ti export const INITIAL_STATE = { showCompareIVData: false, showMedianData : false, + showSecondaryIVData: false, selectedTimeSpan: 'P7D', selectedParameterCode: null, selectedIVMethodID: null, @@ -25,6 +26,18 @@ export const setCompareDataVisibility = function(show) { }; }; +/* + * Synchronous action to set the visibility of the secondary parameter data + * @param {Boolean} show + * @return {Object} - Redux action + */ +export const setSecondaryIVDataVisibility = function(show) { + return { + type: 'SET_SECONDARY_IV_DATA_VISIBILITY', + show + }; +}; + /* * Synchronous action to set the visibility of the median data * @param {Boolean} show @@ -130,6 +143,12 @@ export const hydrographStateReducer = function(hydrographState = INITIAL_STATE, showMedianData: action.show }; + case 'SET_SECONDARY_IV_DATA_VISIBILITY': + return { + ...hydrographState, + showSecondaryIVData: action.show + }; + case 'SET_SELECTED_PARAMETER_CODE': hasIVData = config.ivPeriodOfRecord && action.parameterCode in config.ivPeriodOfRecord; hasGWData = config.gwPeriodOfRecord && action.parameterCode in config.gwPeriodOfRecord;