From 21e4815e28e450cc1cdd4a3b26eec1252e9d6db6 Mon Sep 17 00:00:00 2001
From: mbucknell <mbucknell@usgs.gov>
Date: Mon, 22 Mar 2021 10:54:14 -0500
Subject: [PATCH] Added an additional parameter to alerts to allow a slim
 alert. Code now draws the appropriate checkboxes and the clicking the
 download button detects which boxes have been checked.

---
 assets/src/scripts/d3-rendering/alerts.js     | 26 +++--
 .../components/hydrograph/download-links.js   | 96 ++++++++++++++++++-
 .../components/hydrograph/index.js            |  5 -
 .../components/hydrograph/select-actions.js   |  7 +-
 .../hydrograph/selectors/time-series-data.js  |  6 +-
 5 files changed, 118 insertions(+), 22 deletions(-)

diff --git a/assets/src/scripts/d3-rendering/alerts.js b/assets/src/scripts/d3-rendering/alerts.js
index 8616aaf18..6782acf75 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 a693279bf..8c7800666 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 c488c5289..38c72cdd4 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 88959ac1a..d9d450684 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 b8e8df831..dc43e165a 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
 );
-- 
GitLab