diff --git a/assets/src/scripts/d3-rendering/alerts.js b/assets/src/scripts/d3-rendering/alerts.js index 8616aaf18ff6f1a6270eac8ca958bb409b12224d..6782acf758f2b2eb0922c957b26158fc8f385e73 100644 --- a/assets/src/scripts/d3-rendering/alerts.js +++ b/assets/src/scripts/d3-rendering/alerts.js @@ -6,12 +6,14 @@ * @param {String} kind - should be 'success', 'warning', 'error', or 'info' * @param {String} title * @param {String} body + * @param {String} useSlim */ -const drawAlert = function(elem, {kind, title, body}) { +const drawAlert = function(elem, {kind, title, body, useSlim}) { elem.select('.usa-alert').remove(); if (title || body) { const alertDiv = elem.append('div') - .attr('class', `usa-alert usa-alert--${kind}`); + .attr('class', `usa-alert usa-alert--${kind}`) + .classed('usa-alert--slim', useSlim); const alertBody = alertDiv.append('div') .attr('class', 'usa-alert__body'); if (title) { @@ -34,11 +36,12 @@ const drawAlert = function(elem, {kind, title, body}) { * @param {String} title * @param {String} body */ -export const drawSuccessAlert = function(elem, {title, body}) { +export const drawSuccessAlert = function(elem, {title, body, useSlim}) { drawAlert(elem, { kind:'success', title, - body + body, + useSlim }); }; @@ -49,11 +52,12 @@ export const drawSuccessAlert = function(elem, {title, body}) { * @param {String} title * @param {String} body */ -export const drawInfoAlert = function(elem, {title, body}) { +export const drawInfoAlert = function(elem, {title, body, useSlim}) { drawAlert(elem, { kind: 'info', title, - body + body, + useSlim }); }; @@ -64,11 +68,12 @@ export const drawInfoAlert = function(elem, {title, body}) { * @param {String} title * @param {String} body */ -export const drawWarningAlert = function(elem, {title, body}) { +export const drawWarningAlert = function(elem, {title, body, useSlim}) { drawAlert(elem, { kind: 'warning', title, - body + body, + useSlim }); }; @@ -79,10 +84,11 @@ export const drawWarningAlert = function(elem, {title, body}) { * @param {String} title * @param {String} body */ -export const drawErrorAlert = function(elem, {title, body}) { +export const drawErrorAlert = function(elem, {title, body, useSlim}) { drawAlert(elem, { kind: 'error', title, - body + body, + useSlim }); }; \ No newline at end of file diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/download-links.js b/assets/src/scripts/monitoring-location/components/hydrograph/download-links.js index a693279bf6523b9e37cb9dcd8057ddc5a87d34a1..8c78006669de33f9d687da5221468c0e0cdc1b92 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/download-links.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/download-links.js @@ -2,6 +2,7 @@ * Module with functions for processing and structuring download link URLs */ +import {select} from 'd3-selection'; import {DateTime} from 'luxon'; import {createStructuredSelector} from 'reselect'; @@ -11,11 +12,13 @@ import {getServiceURL, getServiceURLMetaData} from 'ui/web-services/instantaneou import {getServiceURLStatistics} from 'ui/web-services/statistics-data'; import {getServiceURLSGroundwater} from 'ui/web-services/groundwater-levels'; +import {drawErrorAlert} from 'd3render/alerts'; import {appendInfoTooltip} from 'd3render/info-tooltip'; + import {getInputsForRetrieval} from 'ml/selectors/hydrograph-state-selector'; import {getTimeRange, getMedianStatisticsData, getGroundwaterLevels, getIVData} from 'ml/selectors/hydrograph-data-selector'; - +import {hasVisibleIVData, hasVisibleMedianStatisticsData, hasVisibleGroundwaterLevels} from './selectors/time-series-data'; /** * Creates a set of links with dynamically populated URLs so that users can download data that is related to the * current hydrograph. @@ -154,3 +157,94 @@ export const drawDownloadLinks = function(elem, store, siteno) { compareIVData: getIVData('compare') }))); }; + +const drawCheckbox = function(container, inputID, label, value) { + const checkboxContainer = container.append('div') + .attr('class', 'usa-checkbox'); + checkboxContainer.append('input') + .attr('class', 'usa-checkbox__input') + .attr('id', inputID) + .attr('type', 'checkbox') + .attr('value', value); + checkboxContainer.append('label') + .attr('class', 'usa-checkbox__label') + .attr('for', inputID) + .text(label); +}; + +const drawCheckboxes = function(container, { + hasVisiblePrimaryIVData, + hasVisibleCompareIVData, + hasVisibleMedianData, + hasVisibleGroundwaterLevels +}) { + container.select('.download-checkbox-container').remove(); + const checkboxContainer = container.append('div') + .attr('class', 'download-checkbox-container'); + if (hasVisiblePrimaryIVData) { + checkboxContainer.call(drawCheckbox, 'download-primary-iv-data', 'Current IV', 'primary'); + } + if (hasVisibleCompareIVData) { + checkboxContainer.call(drawCheckbox, 'download-compare-iv-data', 'Prior year IV', 'compare'); + } + if (hasVisibleMedianData) { + checkboxContainer.call(drawCheckbox, 'download-median-data', 'Median', 'median'); + } + if (hasVisibleGroundwaterLevels) { + checkboxContainer.call(drawCheckbox, 'download-field-visits', 'Field visits', 'groundwater-levels'); + } + checkboxContainer.call(drawCheckbox, 'download-site-meta-data', 'About this location', 'site'); +}; + +export const drawDownloadForm = function(container, store, siteno) { + const formContainer = container.append('form') + .attr('class', 'usa-form') + .append('fieldset') + .attr('class', 'usa-fieldset'); + formContainer.append('legend') + .attr('class', 'usa-legend') + .text('Select data to be downloaded'); + formContainer.call(link(store, drawCheckboxes, createStructuredSelector({ + hasVisiblePrimaryIVData: hasVisibleIVData('primary'), + hasVisibleCompareIVData: hasVisibleIVData('compare'), + hasVisibleMedianData: hasVisibleMedianStatisticsData, + hasVisibleGroundwaterLevels: hasVisibleGroundwaterLevels + }))); + + const downloadButton = container.append('button') + .attr('class', 'usa-button download-selected-data') + .attr('ga-on', 'click') + .attr('ga-event-category', 'download-selected-data') + .attr('ga-event-action', 'download') + .on('click', function() { + container.selectAll('.alert-error-container').remove(); + const checkedInputs = formContainer.selectAll('input[type="checkbox"]:checked'); + if (checkedInputs.size()) { + checkedInputs.each(function() { + switch (select(this).attr('value')) { + case 'primary': + case 'compare': + case 'median': + case 'groundwater-levels': + case 'site': + console.log(`Downloading data for ${select(this).attr('value')}`); + break; + default: + console.log('Unexpected value'); + } + }); + } else { + container.insert('div', 'button') + .attr('class', 'alert-error-container') + .call(drawErrorAlert, { + body:'Please select one or more checkboxes', + useSlim: true + }); + } + }); + downloadButton.append('i') + .attr('class', 'fas fa-file-download') + .attr('aria-hidden', true) + .attr('role', 'img'); + downloadButton.append('span').text('Download'); +}; diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/index.js b/assets/src/scripts/monitoring-location/components/hydrograph/index.js index c488c5289b64e90a0c43582858d77e77f4a681b2..38c72cdd4147d3dac80d0ce7ea5f86d6cecb36a2 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/index.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/index.js @@ -22,8 +22,6 @@ import {getPreferredIVMethodID} from './selectors/time-series-data'; import {showDataIndicators} from './data-indicator'; import {drawDataTables} from './data-table'; -import {drawDownloadLinks} from './download-links'; -import {drawDateRangeControls} from './date-controls'; import {drawGraphBrush} from './graph-brush'; import {drawGraphControls} from './graph-controls'; import {drawTimeSeriesLegend} from './legend'; @@ -135,9 +133,6 @@ export const attachToNode = function(store, legendControlsContainer.call(drawGraphControls, store, siteno); nodeElem.select('.select-actions-container').call(drawSelectActions, store, siteno); - nodeElem.select('#iv-graph-list-container') - .call(drawDownloadLinks, store, siteno); - nodeElem.select('#iv-data-table-container') .call(drawDataTables, store); diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/select-actions.js b/assets/src/scripts/monitoring-location/components/hydrograph/select-actions.js index 88959ac1ad274c921a68e1e7dd6916710a738dfa..d9d450684345075cfa44236feb6bb26f13730c9d 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/select-actions.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/select-actions.js @@ -1,8 +1,9 @@ import {select} from 'd3-selection'; +import {getSelectedCustomDateRange, getSelectedDateRange} from 'ml/selectors/hydrograph-state-selector'; + import {drawDateRangeControls} from './date-controls'; -import {drawDownloadLinks} from './download-links'; -import {getSelectedCustomDateRange, getSelectedDateRange} from '../../selectors/hydrograph-state-selector'; +import {drawDownloadForm} from './download-links'; const appendButton = function(listContainer, {faIcon, buttonLabel, idOfDivToControl}) { const button = listContainer.append('li') @@ -64,5 +65,5 @@ export const drawSelectActions = function(container, store, siteno) { container.append('div') .attr('id', 'download-graph-data-container') .attr('hidden', true) - .call(drawDownloadLinks, store, siteno); + .call(drawDownloadForm, store, siteno); }; \ No newline at end of file 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 b8e8df831cd1bcf239fee92e09e7baf31cba8b14..dc43e165a9ad6517be352abc539afb62e8db4eb5 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 @@ -40,7 +40,7 @@ export const isVisible = memoize(dataKind => createSelector( * @param {String} dataKind - 'primary' or 'compare' * @return {Function} */ -const hasVisibleIVData = memoize(dataKind => createSelector( +export const hasVisibleIVData = memoize(dataKind => createSelector( isVisible(dataKind), getIVData(dataKind), getSelectedIVMethodID, @@ -50,13 +50,13 @@ const hasVisibleIVData = memoize(dataKind => createSelector( } )); -const hasVisibleMedianStatisticsData = createSelector( +export const hasVisibleMedianStatisticsData = createSelector( isVisible('median'), getMedianStatisticsData, (isVisible, medianStats) => isVisible && medianStats ? Object.keys(medianStats).length > 0 : false ); -const hasVisibleGroundwaterLevels = createSelector( +export const hasVisibleGroundwaterLevels = createSelector( getGroundwaterLevels, (gwLevels) => gwLevels && gwLevels.values ? gwLevels.values.length > 0 : false );