diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ea39355327ada560864a747e3bb9ae933dd03216..469548ba0bc8139e012efd1de3ae00299228f24a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -11,6 +11,12 @@ stages: # it appears this is necessary whenever there is a never rule - when: on_success +.install_npm_dependencies: + before_script: + - cd assets + - npm config set -- '//code.usgs.gov/api/v4/packages/npm/:_authToken' "${CI_JOB_TOKEN}" + - npm install + python_unit_test: extends: .base_rules image: public.ecr.aws/bitnami/python:3.8 @@ -53,12 +59,12 @@ python_lint: - "wdfn-server/waterdata/**/*.py" javascript_test: - extends: .base_rules + extends: + - .base_rules + - .install_npm_dependencies image: public.ecr.aws/bitnami/node:16 stage: test script: - - cd assets - - npm install - npm run test artifacts: reports: @@ -77,12 +83,12 @@ javascript_test: when: on_success static_asset_lint: - extends: .base_rules + extends: + - .base_rules + - .install_npm_dependencies image: public.ecr.aws/bitnami/node:16 stage: test script: - - cd assets - - npm install - npm run lint rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" diff --git a/CHANGELOG.md b/CHANGELOG.md index 31df32dc91c770f0a3735ace0bf791ca7cbd4f4b..f72dd6b3698c300fed425774cd8c23a537c34440 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Hydrograph Graph Brush is now implemented with a Vue component. - Multiple parameter codes can only be selected for parameter codes with IV data available. - Feature flags for hydrologic pages, state county pages, cameras groundwater levels and SIMS removed. +- The USWDS checkbox and alert components are now implemented in a separate library. ### Fixed - Parameter codes with multiple methods will now show statistical data for each method available. diff --git a/assets/.eslintrc b/assets/.eslintrc index c12a76e5737e76ae99f4b0b94fd0cae4286650ac..7a7d7f55c431b33085c0f660b1a9f8fc6b165aec 100644 --- a/assets/.eslintrc +++ b/assets/.eslintrc @@ -12,7 +12,7 @@ "extends": [ "eslint:recommended", "plugin:jest/recommended", - "plugin:vue/recommended" + "plugin:vue/vue3-recommended" ], "rules": { "array-bracket-spacing": ["error", "never"], diff --git a/assets/.npmrc b/assets/.npmrc new file mode 100644 index 0000000000000000000000000000000000000000..e10e3dfbf33e5d0be4dcd91c1f7d3da2aae84803 --- /dev/null +++ b/assets/.npmrc @@ -0,0 +1 @@ +@wma:registry=https://code.usgs.gov/api/v4/packages/npm/ diff --git a/assets/package-lock.json b/assets/package-lock.json index f41d4149a1fef09296312924125aad220781f611..d232f6984d3282eed96daee45f0594c60cef04e3 100644 --- a/assets/package-lock.json +++ b/assets/package-lock.json @@ -9,6 +9,7 @@ "version": "1.3.0dev", "license": "CC0-1.0", "dependencies": { + "@wma/wdfn-vue-components": "0.1.0", "autotrack": "2.4.1", "d3-array": "3.2.0", "d3-axis": "3.0.0", @@ -32,7 +33,7 @@ "redux-thunk": "2.4.1", "reselect": "4.1.6", "vue": "3.2.37", - "wdfn-viz": "3.2.1" + "wdfn-viz": "3.2.0" }, "devDependencies": { "@babel/preset-env": "7.18.6", @@ -3321,9 +3322,9 @@ } }, "node_modules/@uswds/uswds": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@uswds/uswds/-/uswds-3.0.2.tgz", - "integrity": "sha512-I3as7QlcCN9hOya9P8mB/Z3HKZOOueT45fDmJ2r+LnkmhxCAkTLSsqmiFsXTcHNcbcllQSbGtpYsBf0/nOYlWw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@uswds/uswds/-/uswds-3.0.1.tgz", + "integrity": "sha512-O2WHvWjKJwy10UJV9srimCBFMHenvnWDtP3LelMpTCV2AxgO1j/zYPn2SWpK116X/SuiIZk9hycbBroJQ6eH4w==", "dependencies": { "classlist-polyfill": "1.0.3", "domready": "1.0.8", @@ -3555,6 +3556,18 @@ "node": ">=4" } }, + "node_modules/@wma/wdfn-vue-components": { + "version": "0.1.0", + "resolved": "https://code.usgs.gov/api/v4/projects/8428/packages/npm/@wma/wdfn-vue-components/-/@wma/wdfn-vue-components-0.1.0.tgz", + "integrity": "sha1-TcKbpPmYqwM9CiPZCDXTgh56K0k=", + "dependencies": { + "@uswds/uswds": "3.0.1", + "vue": "3.2.37" + }, + "engines": { + "node": ">= 16" + } + }, "node_modules/abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", @@ -17072,11 +17085,11 @@ } }, "node_modules/wdfn-viz": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/wdfn-viz/-/wdfn-viz-3.2.1.tgz", - "integrity": "sha512-pQQHfHsa++sfj9AQVK08xXmm0gTkmOBMBuEO4Nq9HhFw0v08wr6DuD1F275b7rR6Sp7LTEX+UkDBU24bQLh7Ag==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/wdfn-viz/-/wdfn-viz-3.2.0.tgz", + "integrity": "sha512-Lwda3jg8efG/K9v8G1+ybvDOyQgwDU92CXFpsE0oau99yr+Rkj6XImybKXea9P4QFMo2Ar0ff7paS5MoQh+zvA==", "dependencies": { - "@uswds/uswds": "3.0.2" + "@uswds/uswds": "3.0.1" }, "engines": { "node": ">= 12" @@ -19762,9 +19775,9 @@ } }, "@uswds/uswds": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@uswds/uswds/-/uswds-3.0.2.tgz", - "integrity": "sha512-I3as7QlcCN9hOya9P8mB/Z3HKZOOueT45fDmJ2r+LnkmhxCAkTLSsqmiFsXTcHNcbcllQSbGtpYsBf0/nOYlWw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@uswds/uswds/-/uswds-3.0.1.tgz", + "integrity": "sha512-O2WHvWjKJwy10UJV9srimCBFMHenvnWDtP3LelMpTCV2AxgO1j/zYPn2SWpK116X/SuiIZk9hycbBroJQ6eH4w==", "requires": { "classlist-polyfill": "1.0.3", "domready": "1.0.8", @@ -19951,6 +19964,15 @@ } } }, + "@wma/wdfn-vue-components": { + "version": "0.1.0", + "resolved": "https://code.usgs.gov/api/v4/projects/8428/packages/npm/@wma/wdfn-vue-components/-/@wma/wdfn-vue-components-0.1.0.tgz", + "integrity": "sha1-TcKbpPmYqwM9CiPZCDXTgh56K0k=", + "requires": { + "@uswds/uswds": "3.0.1", + "vue": "3.2.37" + } + }, "abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", @@ -30303,11 +30325,11 @@ } }, "wdfn-viz": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/wdfn-viz/-/wdfn-viz-3.2.1.tgz", - "integrity": "sha512-pQQHfHsa++sfj9AQVK08xXmm0gTkmOBMBuEO4Nq9HhFw0v08wr6DuD1F275b7rR6Sp7LTEX+UkDBU24bQLh7Ag==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/wdfn-viz/-/wdfn-viz-3.2.0.tgz", + "integrity": "sha512-Lwda3jg8efG/K9v8G1+ybvDOyQgwDU92CXFpsE0oau99yr+Rkj6XImybKXea9P4QFMo2Ar0ff7paS5MoQh+zvA==", "requires": { - "@uswds/uswds": "3.0.2" + "@uswds/uswds": "3.0.1" } }, "webidl-conversions": { diff --git a/assets/package.json b/assets/package.json index 9316ae94dd12c41afa9eab9ea75de633fb8ef819..83130948672d00653acacc62f8e47dacbd160d61 100644 --- a/assets/package.json +++ b/assets/package.json @@ -80,6 +80,7 @@ "vite": "3.0.0" }, "dependencies": { + "@wma/wdfn-vue-components": "0.1.0", "autotrack": "2.4.1", "d3-array": "3.2.0", "d3-axis": "3.0.0", @@ -103,6 +104,6 @@ "redux-thunk": "2.4.1", "reselect": "4.1.6", "vue": "3.2.37", - "wdfn-viz": "3.2.1" + "wdfn-viz": "3.2.0" } } diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/method-picker.js b/assets/src/scripts/monitoring-location/components/hydrograph/method-picker.js deleted file mode 100644 index 9cfb1e125d26303793e122dd64e12ccd4a99484d..0000000000000000000000000000000000000000 --- a/assets/src/scripts/monitoring-location/components/hydrograph/method-picker.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Pick list for methods module - */ - -import {select} from 'd3-selection'; - -import {appendInfoTooltip} from 'd3render/info-tooltip'; - -import {setSelectedIVMethodID} from 'ml/store/hydrograph-state'; - - -/** - * Draw the method picker. Remove the previous method picker and determine whether a new method - * picker is needed before rendering the picker within the expanion constainer for the selected - * parameterCode. - * @param {D3 selection} container - An HTML element to serve as the base for attaching other elements. - * @param {Object} sortedIVMethods - An object containing the parameter code and the list of sorted methods to be - * used for rendering. - * @param {Redux store} store - A complex JavaScript object that maps the current state of the application. - */ -export const drawMethodPicker = function(container, sortedIVMethods, store) { - container.select('#primary-sampling-method-row').remove(); - - if (!sortedIVMethods || sortedIVMethods.methods.length < 2) { - return; - } - - const hasMethodsWithNoPointsInTimeRange = sortedIVMethods.methods.filter(method => method.pointCount === 0).length !== 0; - // Find parameter expansion container - const rowContainer = container.select(`#expansion-container-row-${sortedIVMethods.parameterCode}`); - const gridRowSamplingMethodSelection = rowContainer.append('div') - .attr('id', 'primary-sampling-method-row') - .attr('class', 'grid-container grid-row-inner'); - const methodSelectionContainer = gridRowSamplingMethodSelection.append('div') - .attr('class', 'grid-row method-selection-row'); - const pickerContainer = methodSelectionContainer.append('div') - .attr('id', 'ts-method-select-container'); - - pickerContainer.append('label') - .attr('class', 'usa-label') - .attr('for', 'method-picker') - .text('Sampling Methods/Sub-locations:') - .call(appendInfoTooltip, 'The names used in dropdown menu are often specific to a particular monitoring ' + - 'location and describe sampling details used to distinguish time-series of the same type--examples ' + - 'include variations in physical location and sensor type.'); - - if (hasMethodsWithNoPointsInTimeRange) { - pickerContainer.append('span') - .attr('id', 'no-data-points-note') - .text(' note - some methods/sub-locations are disabled, because there are no data points for these in ' + - 'your selected time span'); - } - - const picker = pickerContainer.append('select') - .attr('class', 'usa-select ') - .attr('id', 'method-picker') - .on('change', function(event) { - event.stopPropagation(); - store.dispatch(setSelectedIVMethodID(select(this).property('value'))); - }); - sortedIVMethods.methods.forEach((method, index) => { - picker.append('option') - .text(`${method.methodDescription}`) - .attr('class', 'method-option') - .attr('selected', index === 0 ? true : null) - .attr('value', method.methodID) - .attr('disabled', method.pointCount === 0 ? true : null); - }); -}; diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/method-picker.test.js b/assets/src/scripts/monitoring-location/components/hydrograph/method-picker.test.js deleted file mode 100644 index c40241b4b11e5fbe52784b9e8aee3860034a212d..0000000000000000000000000000000000000000 --- a/assets/src/scripts/monitoring-location/components/hydrograph/method-picker.test.js +++ /dev/null @@ -1,118 +0,0 @@ -import {select} from 'd3-selection'; - -import * as utils from 'ui/utils'; - -import {configureStore} from 'ml/store'; - -import {getSortedIVMethods} from './selectors/time-series-data'; - -import {drawMethodPicker} from './method-picker'; -import {TEST_PRIMARY_IV_DATA} from './mock-hydrograph-state'; - -describe('monitoring-location/components/hydrograph/method-picker', () => { - utils.mediaQuery = jest.fn().mockReturnValue(true); - - describe('drawMethodPicker', () => { - const TEST_STATE = { - hydrographData: { - primaryIVData: TEST_PRIMARY_IV_DATA - } - }; - let div; - beforeEach(() => { - div = select('body').append('div'); - div.append('div').attr('id', 'expansion-container-row-72019'); - }); - - afterEach(() => { - div.remove(); - }); - - it('Creates a picker and sets the currentMethodID to preferred method id', () => { - let store = configureStore(TEST_STATE); - div.call(drawMethodPicker, getSortedIVMethods('primary')(store.getState()), store); - - expect(div.select('select').property('value')).toEqual('90649'); - }); - - it('Expects if the data has only one method then the picker will be not be drawn', () => { - let store = configureStore({ - ...TEST_STATE, - hydrographData: { - primaryIVData: { - ...TEST_STATE.hydrographData.primaryIVData, - values: { - '90649': { - ...TEST_PRIMARY_IV_DATA.values['90649'] - } - } - } - } - }); - div.call(drawMethodPicker, getSortedIVMethods('primary')(store.getState()), store); - - expect(div.select('#primary-sampling-method-row').size()).toBe(0); - }); - - it('Expects the methods will be in order from most to least points', () => { - let store = configureStore({ - ...TEST_STATE - }); - div.call(drawMethodPicker, getSortedIVMethods('primary')(store.getState()), store); - const allOptionElements = div.selectAll('option'); - expect(allOptionElements['_groups'][0][0].getAttribute('value')).toBe('90649'); - expect(allOptionElements['_groups'][0][1].getAttribute('value')).toBe('252055'); - }); - - it('Expects that there will be a message if some of the methods have no points', () => { - let store = configureStore({ - ...TEST_STATE - }); - div.call(drawMethodPicker, getSortedIVMethods('primary')(store.getState()), store); - - expect(div.select('#no-data-points-note')['_groups'][0][0].innerHTML).toContain('some methods/sub-locations are disabled'); - }); - - it('Expects that there will be a tooltip message', () => { - let store = configureStore({ - ...TEST_STATE - }); - div.call(drawMethodPicker, getSortedIVMethods('primary')(store.getState()), store); - - expect(div.select('.usa-tooltip__body')['_groups'][0][0].innerHTML).toContain('The names used in ' + - 'dropdown menu are often specific to a particular monitoring location and describe sampling ' + - 'details used to distinguish time-series of the same type--examples include variations in physical' + - ' location and sensor type.'); - }); - - it('Expects that there will NOT be a message all of the methods have points', () => { - let store = configureStore({ - ...TEST_STATE, - hydrographData: { - primaryIVData: { - ...TEST_STATE.hydrographData.primaryIVData, - values: { - '90649': { - ...TEST_PRIMARY_IV_DATA.values['90649'] - }, - '252055': { - points: [ - {value: '25.6', qualifiers: ['E'], dateTime: 1600618500000}, - {value: '26.5', qualifiers: ['P'], dateTime: 1600619400000}, - {value: '25.9', qualifiers: ['P'], dateTime: 1600620300000} - ], - method: { - methodDescription: 'From multiparameter sonde', - methodID: '252055' - } - } - } - } - } - }); - div.call(drawMethodPicker, getSortedIVMethods('primary')(store.getState()), store); - - expect(div.select('#no-data-points-note').size()).toBe(0); - }); - }); -}); diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/download-data.test.js b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/download-data.test.js index dc9dfc5818ad9726f963d0bb3ad57ec01e541b9f..2b49540ab43cb3e551920cf85fd85e4837bbf203 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/download-data.test.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/download-data.test.js @@ -1,3 +1,8 @@ +import {mount} from '@vue/test-utils'; +import ReduxConnectVue from 'redux-connect-vue'; +import {createStructuredSelector} from 'reselect'; + +import {USWDSAlert} from '@wma/wdfn-vue-components'; import config from 'ui/config'; @@ -12,12 +17,8 @@ import { TEST_GW_LEVELS, TEST_SECONDARY_IV_DATA } from '../mock-hydrograph-state'; -import {mount} from '@vue/test-utils'; -import ReduxConnectVue from 'redux-connect-vue'; -import {createStructuredSelector} from 'reselect'; import DownloadData from './download-data.vue'; -import USWDSAlert from 'ui/uswds-components/alert.vue'; describe('monitoring-location/components/hydrograph/vue-components/download-data', () => { config.SITE_DATA_ENDPOINT = 'https://fakeserviceroot.com/nwis/site'; diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/download-data.vue b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/download-data.vue index 8d86fb35ab33ab3c018ab22b1ee982343851c703..e9df548f71af83d064ea092e9caed6217be2c394 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/download-data.vue +++ b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/download-data.vue @@ -169,21 +169,25 @@ </template> <script> +import {DateTime} from 'luxon'; import {useState} from 'redux-connect-vue'; import {computed, ref, inject} from 'vue'; -import {DateTime} from 'luxon'; +import {USWDSAlert} from '@wma/wdfn-vue-components'; + import config from 'ui/config.js'; -import USWDSAlert from 'ui/uswds-components/alert.vue'; -import {getTimeRange} from 'ml/selectors/hydrograph-data-selector'; import {getIVServiceURL, getSiteMetaDataServiceURL} from 'ui/web-services/instantaneous-values'; import {getStatisticsServiceURL} from 'ui/web-services/statistics-data'; import {getGroundwaterServiceURL} from 'ui/web-services/groundwater-levels'; -import {getPrimaryParameter} from 'ml/components/hydrograph/selectors/time-series-data'; -import {getSelectedSecondaryParameterCode} from 'ml/selectors/hydrograph-state-selector'; import {isCalculatedTemperature} from 'ml/parameter-code-utils'; + +import {getTimeRange} from 'ml/selectors/hydrograph-data-selector'; +import {getSelectedSecondaryParameterCode} from 'ml/selectors/hydrograph-state-selector'; + +import {getPrimaryParameter} from 'ml/components/hydrograph/selectors/time-series-data'; + import { hasVisibleGroundwaterLevels, hasVisibleIVData, diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/graph-controls.vue b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/graph-controls.vue index e578efc8ad8c3a356955cd82ea5edcd28efa09df..ab7efa5914a06ae5d9cea132ea23ba79cf8f434b 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/graph-controls.vue +++ b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/graph-controls.vue @@ -7,7 +7,7 @@ value="compare" :is-checked="compareChecked" :is-checkbox-disabled="!compareEnabled" - @toggleCheckbox="selectCompare" + @toggle-checkbox="selectCompare" /> <USWDSCheckbox id="iv-median-timeseries-checkbox" @@ -16,7 +16,7 @@ value="median" :is-checked="medianChecked" :is-checkbox-disabled="!medianEnabled" - @toggleCheckbox="selectMedian" + @toggle-checkbox="selectMedian" /> </div> </template> @@ -26,11 +26,14 @@ import {useActions, useState} from 'redux-connect-vue'; import {createSelector} from 'reselect'; import {inject} from 'vue'; +import {USWDSCheckbox} from '@wma/wdfn-vue-components'; + import config from 'ui/config'; -import USWDSCheckbox from 'ui/uswds-components/checkbox.vue'; -import {getSelectedParameterCode, getSelectedSecondaryParameterCode, getSelectedTimeSpan} from 'ml/selectors/hydrograph-state-selector'; import {getTimeRange} from 'ml/selectors/hydrograph-data-selector'; +import {getSelectedParameterCode, getSelectedSecondaryParameterCode, + getSelectedTimeSpan} from 'ml/selectors/hydrograph-state-selector'; + import {retrieveStatistics, retrievePriorYearIVData} from 'ml/store/hydrograph-data'; import {setCompareDataVisibility, setMedianDataVisibility} from 'ml/store/hydrograph-state'; 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 18b2469ceddd9725bdbd3a7bd94f6de1a4aefb85..2a710fa7acdbb34547bcd9a808d97a5fb41afc61 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 @@ -25,7 +25,7 @@ :parameter-code="parameter.parameterCode" :is-expanded="parameter.parameterCode === expandedParameterCode" :id-for-expansion-row="`expansion-row-${parameter.parameterCode}`" - @toggleExpansionRow="toggleExpansionRow" + @toggle-expansion-row="toggleExpansionRow" /> </div> <div class="usa-radio"> @@ -65,14 +65,14 @@ <MethodPicker v-if="sortedIvMethods && parameter.parameterCode === sortedIvMethods.parameterCode && sortedIvMethods.methods.length > 1" :sorted-iv-methods="sortedIvMethods" - @selectMethod="updateSelectedMethod" + @select-method="updateSelectedMethod" /> <SecondaryParameterControls v-if="enabledForSecondaryParameter(parameter.parameterCode)" :parameter-list="secondaryParameterButtonList" :is-second-parameter-options-checked="isSecondParameterOptionsChecked" - @setCheckBoxStatus="setCheckBoxStatus" + @set-check-box-status="setCheckBoxStatus" /> </div> </div> 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 cd845d8c58d89fed858048c319541d71c4e96e2b..d2b2f25a628a74b589488ca84a17dfa0bcc3782e 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 @@ -5,13 +5,15 @@ import {bindActionCreators} from 'redux'; import {createStructuredSelector} from 'reselect'; import {shallowMount} from '@vue/test-utils'; +import {USWDSCheckbox} from '@wma/wdfn-vue-components'; + import * as utils from 'ui/utils'; +import USWDSRadioButtonSet from 'ui/uswds-components/radio-button-set.vue'; + 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'; +import SecondaryParameterControls from './secondary-parameter-controls.vue'; describe('monitoring-location/components/hydrograph/vue-components/secondary-parameter-controls', () => { const parameterList = [ 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 8ae8fd4ab08f697be0c84164b0824ecba0af33e9..b092a0ab9302da13742ff7ef186707fc8fa0eee3 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 @@ -6,7 +6,7 @@ name="second-parameter-checkbox" value="graphSecondParameter" :is-checked="isSecondParameterOptionsChecked" - @toggleCheckbox="showSecondParameterOptions" + @toggle-checkbox="showSecondParameterOptions" /> <USWDSRadioButtonSet @@ -14,24 +14,28 @@ button-set-name="second-parameter-radio-button-set" legend-text="Available secondary data types" :button-list="parameterList" - @updateValue="graphSecondParameter" + @update-value="graphSecondParameter" /> </div> </template> <script> -import {inject} from 'vue'; import {useActions, useState} from 'redux-connect-vue'; +import {inject} from 'vue'; + +import {USWDSCheckbox} from '@wma/wdfn-vue-components'; + +import USWDSRadioButtonSet from 'ui/uswds-components/radio-button-set.vue'; import {getInputsForRetrieval} from 'ml/selectors/hydrograph-state-selector'; + import {setSelectedSecondaryParameterCode, setCompareDataVisibility, setMedianDataVisibility, setSelectedSecondaryIVMethodID} from 'ml/store/hydrograph-state'; import {retrieveHydrographData, addIVHydrographData} from 'ml/store/hydrograph-data'; + import {showDataIndicators} from '../data-indicator'; import {getPreferredIVMethodID} from '../selectors/time-series-data'; -import USWDSCheckbox from 'ui/uswds-components/checkbox.vue'; -import USWDSRadioButtonSet from 'ui/uswds-components/radio-button-set.vue'; export default { name: 'SecondaryParameterControls', @@ -49,6 +53,7 @@ export default { required: true } }, + emits: ['setCheckBoxStatus'], setup(props, {emit}) { const reduxStore = inject('store'); const siteNumber = inject('siteno'); diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/time-span-controls.test.js b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/time-span-controls.test.js index 6cb10f73865ebb2fbb2a963fb779521ac39e4e23..ee776e098db464649aacbf307f33ab64e9f93a7c 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/time-span-controls.test.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/time-span-controls.test.js @@ -6,7 +6,8 @@ import ReduxConnectVue from 'redux-connect-vue'; import {createStructuredSelector} from 'reselect'; import {shallowMount} from '@vue/test-utils'; -import USWDSAlert from 'ui/uswds-components/alert.vue'; +import {USWDSAlert} from '@wma/wdfn-vue-components'; + import USWDSDatePicker from 'ui/uswds-components/date-picker.vue'; import * as utils from 'ui/utils'; diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/time-span-controls.vue b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/time-span-controls.vue index 7f9b2ec77a1486571fd6fd51f1fd8089ea4e947c..0c0ae33ad325ee7ec6df3545e072db4b07743e4d 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/time-span-controls.vue +++ b/assets/src/scripts/monitoring-location/components/hydrograph/vue-components/time-span-controls.vue @@ -15,7 +15,7 @@ :max-date="startMaxDate" :range-date="startRangeDate" :date-value="startDate" - @changeDate="updateStartDate" + @change-date="updateStartDate" /> <USWDSDatePicker id="end-date" @@ -28,7 +28,7 @@ :max-date="endMaxDate" :range-date="endRangeDate" :date-value="endDate" - @changeDate="updateEndDate" + @change-date="updateEndDate" /> </div> <USWDSAlert @@ -94,9 +94,10 @@ import {DateTime} from 'luxon'; import {useActions, useState} from 'redux-connect-vue'; import {ref, computed, inject, watchEffect} from 'vue'; +import {USWDSAlert} from '@wma/wdfn-vue-components'; + import config from 'ui/config.js'; -import USWDSAlert from 'ui/uswds-components/alert.vue'; import USWDSDatePicker from 'ui/uswds-components/date-picker.vue'; import {clearGraphBrushOffset, setSelectedTimeSpan} from 'ml/store/hydrograph-state'; diff --git a/assets/src/scripts/uswds-components/alert.test.js b/assets/src/scripts/uswds-components/alert.test.js deleted file mode 100644 index 802310d4dff5b9e0d508d2395ae35c474bfebc77..0000000000000000000000000000000000000000 --- a/assets/src/scripts/uswds-components/alert.test.js +++ /dev/null @@ -1,119 +0,0 @@ -import {mount} from '@vue/test-utils'; - -import USWDSAlert from './alert.vue'; - - -describe('components/uswds/alert', () => { - it('expects a success message', () => { - const wrapper = mount(USWDSAlert, { - slots: { - default: '<p class="usa-alert__text">content</p>' - }, - propsData: { - alertType: 'success', - alertTitle: 'This Alert' - } - }); - const wrapperClasses = wrapper.classes(); - expect(wrapper.find('.usa-alert__body').exists()).toBe(true); - expect(wrapper.find('.usa-alert__heading').text()).toContain('This Alert'); - expect(wrapperClasses).toContain('usa-alert--success'); - expect(wrapperClasses).not.toContain('usa-alert--slim'); - expect(wrapperClasses).not.toContain('usa-alert--no-icon'); - expect(wrapper.find('.usa-alert__text').text()).toBe('content'); - }); - - it('expects a error message with no alert icon', () => { - const wrapper = mount(USWDSAlert, { - slots: { - default: '<p>content</p>' - }, - props: { - alertType: 'error', - showAlertIcon: false - } - }); - - - expect(wrapper.find('.usa-alert__body').exists()).toBe(true); - expect(wrapper.find('.usa-alert__heading').exists()).toBe(false); - const wrapperClasses = wrapper.classes(); - expect(wrapperClasses).toContain('usa-alert--error'); - expect(wrapperClasses).toContain('usa-alert--no-icon'); - }); - - it('expects a info message', () => { - const wrapper = mount(USWDSAlert, { - slots: { - default: '<p>content</p>' - }, - props: { - alertType: 'info', - alertTitle: 'Notice' - } - }); - - expect(wrapper.find('.usa-alert__body').exists()).toBe(true); - expect(wrapper.find('.usa-alert__body').text()).toContain('Notice'); - expect(wrapper.classes()).toContain('usa-alert--info'); - }); - - it('expects that the alert component will be slim', () => { - const wrapper = mount(USWDSAlert, { - slots: { - default: '<p>content</p>' - }, - props: { - alertType: 'info', - slimAlert: true - } - }); - - const wrapperClasses = wrapper.classes(); - expect(wrapperClasses).toContain('usa-alert--info'); - expect(wrapperClasses).toContain('usa-alert--slim'); - }); - - it('expects no close button', () => { - const wrapper = mount(USWDSAlert, { - slots: { - default: '<p>content</p>' - }, - props: { - alertType: 'info' - } - }); - - expect(wrapper.findAll('button')).toHaveLength(0); - }); - - it('expects a close icon', () => { - const wrapper = mount(USWDSAlert, { - slots: { - default: '<p>content</p>' - }, - props: { - alertType: 'info', - showClose: true, - staticRoot: '/fake/' - } - }); - expect(wrapper.findAll('.message-close')).toHaveLength(1); - expect(wrapper.find('.message-close').html()).toContain('/fake/'); - }); - - it('expects a click on the close button to emit event', async() => { - const wrapper = mount(USWDSAlert, { - slots: { - default: '<p>content</p>' - }, - props: { - alertType: 'info', - showClose: true - } - }); - expect(wrapper.findAll('.message-close')).toHaveLength(1); - await wrapper.find('.message-close').trigger('click'); - expect(wrapper.emitted().closeAlert).toHaveLength(1); - }); -}); diff --git a/assets/src/scripts/uswds-components/alert.vue b/assets/src/scripts/uswds-components/alert.vue deleted file mode 100644 index 0a27e72f9c4ac283804af0ce185154412951220b..0000000000000000000000000000000000000000 --- a/assets/src/scripts/uswds-components/alert.vue +++ /dev/null @@ -1,77 +0,0 @@ -<template> - <div - class="usa-alert" - :class="`usa-alert--${alertType}${slimAlert ? ' usa-alert--slim' : ''} ${showAlertIcon ? '' : 'usa-alert--no-icon'}`" - > - <div class="usa-alert__body"> - <h4 - v-if="alertTitle" - class="usa-alert__heading" - > - {{ alertTitle }} - </h4> - <!-- @slot markup should start with tag with the class set to usa-alert__text --> - <slot /> - <svg - v-if="showClose" - class="usa-icon message-close" - aria-label="close-icon" - role="img" - @click="$emit('closeAlert', $event)" - > - <use :xlink:href="closeIcon" /> - </svg> - </div> - </div> -</template> - -<script> -/** - * @vue-prop {String} - alertType, A USWDS Alert message type (info, warning, error, or success) - * @vue-prop {Boolean} - slimAlert - set to true if the alert should be shown without the icon, defaults to false - * @vue-prop {Boolean} - showAlertIcon - Set to false if the alert icon should not be shown, defaults to true and will - * be ignored if slimAlert is set to true. - * @vue-prop {Boolean} - showClose, show or hide the close button - * @vue-prop {String} - alertTitle, main title for the alert - * @vue-prop {String} - staticRoot - path to the root of the static assets, defaults to the empty string - * @vue-computed {String} - closeIcon, URL for the close 'X' icon - * @vue-event closeAlert - event emitted when alert close is clicked - */ -export default { - name: 'USWDSAlert', - props: { - alertType: { - type: String, - default: 'error', - validator: function(value) { - return ['info', 'success', 'warning', 'error'].includes(value); - } - }, - slimAlert: { - type: Boolean, - default: false - }, - showAlertIcon: { - type: Boolean, - default: true - }, - showClose: { - type: Boolean, - default: false - }, - alertTitle: { - type: String, - default: '' - }, - staticRoot: { - type: String, - default: '' - } - }, - computed: { - closeIcon() { - return `${this.staticRoot}img/sprite.svg#close`; - } - } -}; -</script> diff --git a/assets/src/scripts/uswds-components/checkbox.test.js b/assets/src/scripts/uswds-components/checkbox.test.js deleted file mode 100644 index 1f7321f40563830bb3d3067909a9d5933a57fe9f..0000000000000000000000000000000000000000 --- a/assets/src/scripts/uswds-components/checkbox.test.js +++ /dev/null @@ -1,86 +0,0 @@ -import {mount} from '@vue/test-utils'; - -import USWDSCheckbox from './checkbox.vue'; - -describe('uswds-components/checkbox', () => { - it('Expects a properly rendered unchecked USWDS checkbox', () => { - const wrapper = mount(USWDSCheckbox, { - props: { - label: 'This checkbox', - name: 'checkbox-name', - value: 'yes', - id: 'my-unique-id' - } - }); - - const checkbox = wrapper.find('.usa-checkbox__input'); - const checkboxLabel = wrapper.find('.usa-checkbox__label'); - expect(checkbox.attributes('id')).toBe('my-unique-id'); - expect(checkbox.attributes('name')).toBe('checkbox-name'); - expect(checkbox.attributes('value')).toBe('yes'); - expect(checkbox.element.checked).toBe(false); - expect(checkboxLabel.attributes('for')).toBe('my-unique-id'); - expect(checkboxLabel.text()).toBe('This checkbox'); - }); - - it('Expects a checkbox that is initial checked', () => { - const wrapper = mount(USWDSCheckbox, { - props: { - label: 'This checkbox', - name: 'checkbox-name', - value: 'yes', - id: 'my-unique-id', - isChecked: true - } - }); - - const checkbox = wrapper.find('.usa-checkbox__input'); - expect(checkbox.element.checked).toBe(true); - }); - - it('Expect to emit a toggleCheckbox event if the checkbox is clicked', async() => { - const wrapper = mount(USWDSCheckbox, { - props: { - label: 'This checkbox', - name: 'checkbox-name', - value: 'yes', - id: 'my-unique-id' - } - }); - const checkbox = wrapper.find('.usa-checkbox__input'); - checkbox.setChecked(true); - - expect(wrapper.emitted('toggleCheckbox')[0][0]).toBe(true); - - checkbox.setChecked(false); - - expect(wrapper.emitted('toggleCheckbox')[1][0]).toBe(false); - }); - - it('Expect checkbox to be disabled when prop true', () => { - const wrapper = mount(USWDSCheckbox, { - props: { - label: 'This checkbox', - name: 'checkbox-name', - value: 'yes', - id: 'my-unique-id', - isCheckboxDisabled: true - } - }); - const checkboxInput = wrapper.find('input'); - expect(checkboxInput.attributes('disabled')).toBeDefined(); - }); - - it('Expect checkbox to be enabled by default', () => { - const wrapper = mount(USWDSCheckbox, { - props: { - label: 'This checkbox', - name: 'checkbox-name', - value: 'yes', - id: 'my-unique-id' - } - }); - const checkboxInput = wrapper.find('input'); - expect(checkboxInput.attributes('disabled')).not.toBeDefined(); - }); -}); diff --git a/assets/src/scripts/uswds-components/checkbox.vue b/assets/src/scripts/uswds-components/checkbox.vue deleted file mode 100644 index 1dbf39c419ac3e928d25c45eb78112a2bb0867d4..0000000000000000000000000000000000000000 --- a/assets/src/scripts/uswds-components/checkbox.vue +++ /dev/null @@ -1,71 +0,0 @@ -<template> - <div class="usa-checkbox"> - <input - :id="id" - class="usa-checkbox__input" - type="checkbox" - :name="name" - :value="value" - :checked="isChecked" - :disabled="isCheckboxDisabled" - @change="toggleCheckbox" - > - <label - class="usa-checkbox__label" - :for="id" - > - {{ label }} - </label> - </div> -</template> - -<script> -/* - * @vue-prop {String} label - * @vue-prop {String} name - * @vue-prop {String} value - * @vue-prop {String} id - should be unique with the DOM - * @vue-prop {Boolean} isChecked - defaults to false - * @vue-prop {Boolean} isCheckboxDisabled - checkbox disabled when set to true, default is false - * @vue-event {DOM Event} toggleCheckbox - */ -export default { - name: 'USWDSCheckbox', - props: { - label: { - type: String, - required: true - }, - name: { - type: String, - required: true - }, - value: { - type: String, - required: true - }, - id: { - type: String, - required: true - }, - isChecked: { - type: Boolean, - default: false - }, - isCheckboxDisabled: { - type: Boolean, - default: false - } - }, - emits: ['toggleCheckbox'], - setup(props, {emit}) { - function toggleCheckbox(ev) { - emit('toggleCheckbox', ev.currentTarget.checked); - } - - return { - toggleCheckbox - }; - } -}; -</script> diff --git a/assets/src/scripts/uswds-components/radio-button-set.vue b/assets/src/scripts/uswds-components/radio-button-set.vue index 78867b1e75fd613791abda61a3321f47190d14c3..28f8da9d4b89b0312153d84dc5489b6fbd0b8853 100644 --- a/assets/src/scripts/uswds-components/radio-button-set.vue +++ b/assets/src/scripts/uswds-components/radio-button-set.vue @@ -59,6 +59,7 @@ export default { default: '' } }, + emits: ['updateValue'], setup(props, {emit}) { const updateValue = function(value) { emit('updateValue', value);