From 1d662d59dad936c18aa171e260ba55fde69ae6cd Mon Sep 17 00:00:00 2001 From: CD Cabrera Date: Wed, 24 Feb 2021 01:47:41 -0500 Subject: [PATCH] fix(graphCard): ent-3507 expose start, end for date query (#589) * graphCard, expose start, end query to allow alt granularity dropdown * openshiftView, productView, Rhel, Satellite, props updates * viewReducer, queryTypes, graphCardSelectors, expose start, end query --- .../__snapshots__/graphCard.test.js.snap | 8 +-- .../graphCard/__tests__/graphCard.test.js | 24 ++++++-- src/components/graphCard/graphCard.js | 18 +++--- .../__snapshots__/openshiftView.test.js.snap | 6 ++ src/components/openshiftView/openshiftView.js | 10 +++- .../productViewRhel.test.js.snap | 2 + .../productViewSatellite.test.js.snap | 2 + src/components/productView/productView.js | 4 +- src/components/productView/productViewRhel.js | 6 +- .../productView/productViewSatellite.js | 6 +- .../toolbarFieldGranularity.test.js.snap | 22 +++++-- .../toolbar/toolbarFieldGranularity.js | 27 +++++++-- .../__snapshots__/viewReducer.test.js.snap | 58 +++++++++++++++++++ .../reducers/__tests__/viewReducer.test.js | 2 + src/redux/reducers/viewReducer.js | 28 +++++++++ src/redux/selectors/graphCardSelectors.js | 4 +- .../__snapshots__/index.test.js.snap | 8 +++ src/redux/types/queryTypes.js | 2 + 18 files changed, 196 insertions(+), 41 deletions(-) diff --git a/src/components/graphCard/__tests__/__snapshots__/graphCard.test.js.snap b/src/components/graphCard/__tests__/__snapshots__/graphCard.test.js.snap index be07b7c20..a71dd7871 100644 --- a/src/components/graphCard/__tests__/__snapshots__/graphCard.test.js.snap +++ b/src/components/graphCard/__tests__/__snapshots__/graphCard.test.js.snap @@ -133,7 +133,7 @@ exports[`GraphCard Component should render a non-connected component: non-connec dataSets={Array []} domain={Object {}} height={275} - key="chart_{\\"granularity\\":\\"daily\\"}" + key="chart_{\\"granularity\\":\\"daily\\",\\"ending\\":\\"2021-02-24T23:59:59.999Z\\",\\"beginning\\":\\"2021-01-25T00:00:00.000Z\\"}" padding={ Object { "bottom": 75, @@ -290,7 +290,7 @@ exports[`GraphCard Component should render multiple states: error with 403 statu } domain={Object {}} height={275} - key="chart_{\\"granularity\\":\\"daily\\"}" + key="chart_{\\"granularity\\":\\"daily\\",\\"ending\\":\\"2019-06-26T23:59:59.999Z\\",\\"beginning\\":\\"2019-05-25T00:00:00.000Z\\"}" padding={ Object { "bottom": 75, @@ -411,7 +411,7 @@ exports[`GraphCard Component should render multiple states: error with 500 statu } domain={Object {}} height={275} - key="chart_{\\"granularity\\":\\"daily\\"}" + key="chart_{\\"granularity\\":\\"daily\\",\\"ending\\":\\"2019-06-26T23:59:59.999Z\\",\\"beginning\\":\\"2019-05-25T00:00:00.000Z\\"}" padding={ Object { "bottom": 75, @@ -532,7 +532,7 @@ exports[`GraphCard Component should render multiple states: fulfilled 1`] = ` } domain={Object {}} height={275} - key="chart_{\\"granularity\\":\\"daily\\"}" + key="chart_{\\"granularity\\":\\"daily\\",\\"ending\\":\\"2019-06-26T23:59:59.999Z\\",\\"beginning\\":\\"2019-05-25T00:00:00.000Z\\"}" padding={ Object { "bottom": 75, diff --git a/src/components/graphCard/__tests__/graphCard.test.js b/src/components/graphCard/__tests__/graphCard.test.js index 0bd3e4d91..59df35a8c 100644 --- a/src/components/graphCard/__tests__/graphCard.test.js +++ b/src/components/graphCard/__tests__/graphCard.test.js @@ -10,7 +10,11 @@ import { describe('GraphCard Component', () => { it('should render a non-connected component', () => { const props = { - query: { [RHSM_API_QUERY_TYPES.GRANULARITY]: GRANULARITY_TYPES.DAILY }, + query: { + [RHSM_API_QUERY_TYPES.GRANULARITY]: GRANULARITY_TYPES.DAILY, + [RHSM_API_QUERY_TYPES.END_DATE]: '2021-02-24T23:59:59.999Z', + [RHSM_API_QUERY_TYPES.START_DATE]: '2021-01-25T00:00:00.000Z' + }, productId: 'lorem' }; const component = shallow(); @@ -20,7 +24,11 @@ describe('GraphCard Component', () => { it('should render multiple states', () => { const props = { - query: { [RHSM_API_QUERY_TYPES.GRANULARITY]: GRANULARITY_TYPES.DAILY }, + query: { + [RHSM_API_QUERY_TYPES.GRANULARITY]: GRANULARITY_TYPES.DAILY, + [RHSM_API_QUERY_TYPES.END_DATE]: '2019-06-26T23:59:59.999Z', + [RHSM_API_QUERY_TYPES.START_DATE]: '2019-05-25T00:00:00.000Z' + }, productId: 'lorem', graphData: { physicalSockets: [ @@ -91,7 +99,11 @@ describe('GraphCard Component', () => { id: 'thresholdLoremIpsumSockets' } ], - query: { [RHSM_API_QUERY_TYPES.GRANULARITY]: GRANULARITY_TYPES.DAILY }, + query: { + [RHSM_API_QUERY_TYPES.GRANULARITY]: GRANULARITY_TYPES.DAILY, + [RHSM_API_QUERY_TYPES.END_DATE]: '2019-06-26T23:59:59.999Z', + [RHSM_API_QUERY_TYPES.START_DATE]: '2019-05-25T00:00:00.000Z' + }, productId: 'lorem', graphData: { loremIpsumSockets: [ @@ -155,7 +167,11 @@ describe('GraphCard Component', () => { it('should return an empty render when disabled', () => { const props = { - query: { [RHSM_API_QUERY_TYPES.GRANULARITY]: GRANULARITY_TYPES.DAILY }, + query: { + [RHSM_API_QUERY_TYPES.GRANULARITY]: GRANULARITY_TYPES.DAILY, + [RHSM_API_QUERY_TYPES.END_DATE]: '2021-02-24T23:59:59.999Z', + [RHSM_API_QUERY_TYPES.START_DATE]: '2021-01-25T00:00:00.000Z' + }, isDisabled: true, productId: 'lorem' }; diff --git a/src/components/graphCard/graphCard.js b/src/components/graphCard/graphCard.js index 0dc8ad4d1..bf936dedf 100644 --- a/src/components/graphCard/graphCard.js +++ b/src/components/graphCard/graphCard.js @@ -4,7 +4,7 @@ import { Card, CardTitle, CardHeader, CardActions, CardBody, Title } from '@patt import { chart_color_green_300 as chartColorGreenDark } from '@patternfly/react-tokens'; import _isEqual from 'lodash/isEqual'; import { connect, reduxActions, reduxSelectors } from '../../redux'; -import { helpers, dateHelpers } from '../../common'; +import { helpers } from '../../common'; import { RHSM_API_QUERY_GRANULARITY_TYPES as GRANULARITY_TYPES, RHSM_API_QUERY_TYPES } from '../../types/rhsmApiTypes'; import { graphCardHelpers } from './graphCardHelpers'; import GraphCardChartTooltip from './graphCardChartTooltip'; @@ -42,16 +42,10 @@ class GraphCard extends React.Component { onUpdateGraphData = () => { const { getGraphReportsCapacity, isDisabled, productId, query } = this.props; const graphGranularity = this.getQueryGranularity(); + const { [RHSM_API_QUERY_TYPES.START_DATE]: startDate, [RHSM_API_QUERY_TYPES.END_DATE]: endDate } = query; - if (!isDisabled && graphGranularity && productId) { - const { startDate, endDate } = dateHelpers.getRangedDateTime(graphGranularity); - const graphQuery = { - [RHSM_API_QUERY_TYPES.START_DATE]: startDate.toISOString(), - [RHSM_API_QUERY_TYPES.END_DATE]: endDate.toISOString(), - ...query - }; - - getGraphReportsCapacity(productId, graphQuery); + if (!isDisabled && graphGranularity && startDate && endDate && productId) { + getGraphReportsCapacity(productId, query); } }; @@ -206,7 +200,9 @@ GraphCard.propTypes = { getGraphReportsCapacity: PropTypes.func, graphData: PropTypes.object, query: PropTypes.shape({ - [RHSM_API_QUERY_TYPES.GRANULARITY]: PropTypes.oneOf([...Object.values(GRANULARITY_TYPES)]).isRequired + [RHSM_API_QUERY_TYPES.GRANULARITY]: PropTypes.oneOf([...Object.values(GRANULARITY_TYPES)]).isRequired, + [RHSM_API_QUERY_TYPES.START_DATE]: PropTypes.string.isRequired, + [RHSM_API_QUERY_TYPES.END_DATE]: PropTypes.string.isRequired }).isRequired, isDisabled: PropTypes.bool, pending: PropTypes.bool, diff --git a/src/components/openshiftView/__tests__/__snapshots__/openshiftView.test.js.snap b/src/components/openshiftView/__tests__/__snapshots__/openshiftView.test.js.snap index 454429fde..5adad39e4 100644 --- a/src/components/openshiftView/__tests__/__snapshots__/openshiftView.test.js.snap +++ b/src/components/openshiftView/__tests__/__snapshots__/openshiftView.test.js.snap @@ -67,6 +67,8 @@ exports[`OpenshiftView Component should display an alternate graph on query-stri productLabel="OpenShift" query={ Object { + "beginning": "2019-06-20T00:00:00.000Z", + "ending": "2019-07-20T23:59:59.999Z", "granularity": "daily", } } @@ -280,6 +282,8 @@ exports[`OpenshiftView Component should have a fallback title: title 1`] = ` productLabel="OpenShift" query={ Object { + "beginning": "2019-06-20T00:00:00.000Z", + "ending": "2019-07-20T23:59:59.999Z", "granularity": "daily", } } @@ -907,6 +911,8 @@ exports[`OpenshiftView Component should render a non-connected component: non-co productLabel="OpenShift" query={ Object { + "beginning": "2019-06-20T00:00:00.000Z", + "ending": "2019-07-20T23:59:59.999Z", "granularity": "daily", } } diff --git a/src/components/openshiftView/openshiftView.js b/src/components/openshiftView/openshiftView.js index da86e6434..44241bdc2 100644 --- a/src/components/openshiftView/openshiftView.js +++ b/src/components/openshiftView/openshiftView.js @@ -24,7 +24,7 @@ import InventoryList from '../inventoryList/inventoryList'; import InventorySubscriptions from '../inventorySubscriptions/inventorySubscriptions'; import InventoryTabs, { InventoryTab } from '../inventoryTabs/inventoryTabs'; import BannerMessages from '../bannerMessages/bannerMessages'; -import { helpers } from '../../common'; +import { helpers, dateHelpers } from '../../common'; import { translate } from '../i18n/i18n'; /** @@ -148,7 +148,9 @@ class OpenshiftView extends React.Component { OpenshiftView.propTypes = { query: PropTypes.object, graphTallyQuery: PropTypes.shape({ - [RHSM_API_QUERY_TYPES.GRANULARITY]: PropTypes.oneOf([...Object.values(GRANULARITY_TYPES)]) + [RHSM_API_QUERY_TYPES.GRANULARITY]: PropTypes.oneOf([...Object.values(GRANULARITY_TYPES)]), + [RHSM_API_QUERY_TYPES.START_DATE]: PropTypes.string, + [RHSM_API_QUERY_TYPES.END_DATE]: PropTypes.string }), inventoryHostsQuery: PropTypes.shape({ [RHSM_API_QUERY_TYPES.LIMIT]: PropTypes.number, @@ -196,7 +198,9 @@ OpenshiftView.defaultProps = { [RHSM_API_QUERY_TYPES.UOM]: RHSM_API_QUERY_UOM_TYPES.CORES }, graphTallyQuery: { - [RHSM_API_QUERY_TYPES.GRANULARITY]: GRANULARITY_TYPES.DAILY + [RHSM_API_QUERY_TYPES.GRANULARITY]: GRANULARITY_TYPES.DAILY, + [RHSM_API_QUERY_TYPES.START_DATE]: dateHelpers.getRangedDateTime(GRANULARITY_TYPES.DAILY).startDate.toISOString(), + [RHSM_API_QUERY_TYPES.END_DATE]: dateHelpers.getRangedDateTime(GRANULARITY_TYPES.DAILY).endDate.toISOString() }, inventoryHostsQuery: { [RHSM_API_QUERY_TYPES.SORT]: RHSM_API_QUERY_SORT_TYPES.LAST_SEEN, diff --git a/src/components/productView/__tests__/__snapshots__/productViewRhel.test.js.snap b/src/components/productView/__tests__/__snapshots__/productViewRhel.test.js.snap index f8cd73e1c..ecf3ecbd5 100644 --- a/src/components/productView/__tests__/__snapshots__/productViewRhel.test.js.snap +++ b/src/components/productView/__tests__/__snapshots__/productViewRhel.test.js.snap @@ -5,6 +5,8 @@ exports[`ProductViewRhel Component should render a non-connected component: non- productConfig={ Object { "graphTallyQuery": Object { + "beginning": "2019-06-20T00:00:00.000Z", + "ending": "2019-07-20T23:59:59.999Z", "granularity": "daily", }, "initialGraphFilters": Array [ diff --git a/src/components/productView/__tests__/__snapshots__/productViewSatellite.test.js.snap b/src/components/productView/__tests__/__snapshots__/productViewSatellite.test.js.snap index d0d4e3040..716d919a2 100644 --- a/src/components/productView/__tests__/__snapshots__/productViewSatellite.test.js.snap +++ b/src/components/productView/__tests__/__snapshots__/productViewSatellite.test.js.snap @@ -5,6 +5,8 @@ exports[`ProductViewSatellite Component should render a non-connected component: productConfig={ Object { "graphTallyQuery": Object { + "beginning": "2019-06-20T00:00:00.000Z", + "ending": "2019-07-20T23:59:59.999Z", "granularity": "daily", }, "initialGraphFilters": Array [ diff --git a/src/components/productView/productView.js b/src/components/productView/productView.js index c22076bfe..d7e4d6b7a 100644 --- a/src/components/productView/productView.js +++ b/src/components/productView/productView.js @@ -135,7 +135,9 @@ const ProductView = ({ productConfig, routeDetail, t }) => { ProductView.propTypes = { productConfig: PropTypes.shape({ graphTallyQuery: PropTypes.shape({ - [RHSM_API_QUERY_TYPES.GRANULARITY]: PropTypes.oneOf([...Object.values(GRANULARITY_TYPES)]) + [RHSM_API_QUERY_TYPES.GRANULARITY]: PropTypes.oneOf([...Object.values(GRANULARITY_TYPES)]), + [RHSM_API_QUERY_TYPES.START_DATE]: PropTypes.string, + [RHSM_API_QUERY_TYPES.END_DATE]: PropTypes.string }), inventoryHostsQuery: PropTypes.shape({ [RHSM_API_QUERY_TYPES.LIMIT]: PropTypes.number, diff --git a/src/components/productView/productViewRhel.js b/src/components/productView/productViewRhel.js index b12221310..387dc06fd 100644 --- a/src/components/productView/productViewRhel.js +++ b/src/components/productView/productViewRhel.js @@ -20,7 +20,7 @@ import { } from '../../types/rhsmApiTypes'; import { ConnectedProductView, ProductView } from './productView'; import { translate } from '../i18n/i18n'; -import { helpers } from '../../common'; +import { dateHelpers, helpers } from '../../common'; /** * A Red Hat Enterprise Linux configured view, and related system architectures. @@ -57,7 +57,9 @@ ProductViewRhel.defaultProps = { productConfig: { query: {}, graphTallyQuery: { - [RHSM_API_QUERY_TYPES.GRANULARITY]: GRANULARITY_TYPES.DAILY + [RHSM_API_QUERY_TYPES.GRANULARITY]: GRANULARITY_TYPES.DAILY, + [RHSM_API_QUERY_TYPES.START_DATE]: dateHelpers.getRangedDateTime(GRANULARITY_TYPES.DAILY).startDate.toISOString(), + [RHSM_API_QUERY_TYPES.END_DATE]: dateHelpers.getRangedDateTime(GRANULARITY_TYPES.DAILY).endDate.toISOString() }, inventoryHostsQuery: { [RHSM_API_QUERY_TYPES.SORT]: RHSM_API_QUERY_SORT_TYPES.LAST_SEEN, diff --git a/src/components/productView/productViewSatellite.js b/src/components/productView/productViewSatellite.js index 575782683..d2e65a8ca 100644 --- a/src/components/productView/productViewSatellite.js +++ b/src/components/productView/productViewSatellite.js @@ -20,7 +20,7 @@ import { } from '../../types/rhsmApiTypes'; import { ConnectedProductView, ProductView } from './productView'; import { translate } from '../i18n/i18n'; -import { helpers } from '../../common'; +import { dateHelpers, helpers } from '../../common'; /** * A Red Hat Satellite configured view, and related system architectures. @@ -57,7 +57,9 @@ ProductViewSatellite.defaultProps = { productConfig: { query: {}, graphTallyQuery: { - [RHSM_API_QUERY_TYPES.GRANULARITY]: GRANULARITY_TYPES.DAILY + [RHSM_API_QUERY_TYPES.GRANULARITY]: GRANULARITY_TYPES.DAILY, + [RHSM_API_QUERY_TYPES.START_DATE]: dateHelpers.getRangedDateTime(GRANULARITY_TYPES.DAILY).startDate.toISOString(), + [RHSM_API_QUERY_TYPES.END_DATE]: dateHelpers.getRangedDateTime(GRANULARITY_TYPES.DAILY).endDate.toISOString() }, inventoryHostsQuery: { [RHSM_API_QUERY_TYPES.SORT]: RHSM_API_QUERY_SORT_TYPES.LAST_SEEN, diff --git a/src/components/toolbar/__tests__/__snapshots__/toolbarFieldGranularity.test.js.snap b/src/components/toolbar/__tests__/__snapshots__/toolbarFieldGranularity.test.js.snap index c7969a709..c4df334a8 100644 --- a/src/components/toolbar/__tests__/__snapshots__/toolbarFieldGranularity.test.js.snap +++ b/src/components/toolbar/__tests__/__snapshots__/toolbarFieldGranularity.test.js.snap @@ -28,11 +28,23 @@ Array [ exports[`ToolbarFieldGranularity Component should handle updating granularity through redux state: dispatch granularity 1`] = ` Array [ Array [ - Object { - "granularity": "daily", - "type": "SET_QUERY_RHSM_granularity", - "viewId": "toolbarFieldGranularity", - }, + Array [ + Object { + "granularity": "daily", + "type": "SET_QUERY_RHSM_granularity", + "viewId": "toolbarFieldGranularity", + }, + Object { + "beginning": "2019-06-20T00:00:00.000Z", + "type": "SET_QUERY_RHSM_beginning", + "viewId": "toolbarFieldGranularity", + }, + Object { + "ending": "2019-07-20T23:59:59.999Z", + "type": "SET_QUERY_RHSM_ending", + "viewId": "toolbarFieldGranularity", + }, + ], ], ] `; diff --git a/src/components/toolbar/toolbarFieldGranularity.js b/src/components/toolbar/toolbarFieldGranularity.js index 24c4b9569..af7793084 100644 --- a/src/components/toolbar/toolbarFieldGranularity.js +++ b/src/components/toolbar/toolbarFieldGranularity.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import { reduxTypes, store, useSelector } from '../../redux'; import { Select } from '../form/select'; import { RHSM_API_QUERY_GRANULARITY_TYPES as FIELD_TYPES, RHSM_API_QUERY_TYPES } from '../../types/rhsmApiTypes'; +import { dateHelpers } from '../../common'; import { translate } from '../i18n/i18n'; /** @@ -42,12 +43,26 @@ const ToolbarFieldGranularity = ({ options, t, value, viewId }) => { * @param {object} event * @returns {void} */ - const onSelect = event => - store.dispatch({ - type: reduxTypes.query.SET_QUERY_RHSM_TYPES[RHSM_API_QUERY_TYPES.GRANULARITY], - viewId, - [RHSM_API_QUERY_TYPES.GRANULARITY]: event.value - }); + const onSelect = event => { + const { startDate, endDate } = dateHelpers.getRangedDateTime(event.value); + store.dispatch([ + { + type: reduxTypes.query.SET_QUERY_RHSM_TYPES[RHSM_API_QUERY_TYPES.GRANULARITY], + viewId, + [RHSM_API_QUERY_TYPES.GRANULARITY]: event.value + }, + { + type: reduxTypes.query.SET_QUERY_RHSM_TYPES[RHSM_API_QUERY_TYPES.START_DATE], + viewId, + [RHSM_API_QUERY_TYPES.START_DATE]: startDate.toISOString() + }, + { + type: reduxTypes.query.SET_QUERY_RHSM_TYPES[RHSM_API_QUERY_TYPES.END_DATE], + viewId, + [RHSM_API_QUERY_TYPES.END_DATE]: endDate.toISOString() + } + ]); + }; return (