diff --git a/public/locales/en-US.json b/public/locales/en-US.json
index 05700570b..1a3d8a3e3 100644
--- a/public/locales/en-US.json
+++ b/public/locales/en-US.json
@@ -12,6 +12,8 @@
"cardHeading": "CPU usage",
"cardHeading_cores": "CPU core usage",
"cardHeading_sockets": "CPU socket usage",
+ "cardHeading_OpenShift Container Platform": "Fixed capacity",
+ "cardHeading_OpenShift-metrics": "Flexible subscriptions",
"cardHeading_OpenShift-dedicated-metrics": "Flexible subscriptions",
"cardHeading_RHEL": "CPU socket usage",
"cardHeading_Satellite": "CPU socket usage",
@@ -83,7 +85,12 @@
"header_measurementType": "Type",
"header_inventoryId": "UUID",
"header_sockets": "Subscribed sockets",
+ "header_sockets_OpenShift Container Platform": "Sockets",
+ "header_sockets_OpenShift-metrics": "Sockets",
+ "header_sockets_OpenShift-dedicated-metrics": "Sockets",
"header_lastSeen": "Last seen",
+ "header_lastSeen_OpenShift Container Platform": "Last check-in",
+ "header_lastSeen_OpenShift-metrics": "Last check-in",
"header_lastSeen_OpenShift-dedicated-metrics": "Last check-in",
"header_productName": "Product",
"header_serviceLevel": "Service level",
@@ -152,8 +159,8 @@
"curiosity-view": {
"title": "{{appName}}",
"subtitle": "Monitor your usage based on your subscription terms. <0>Learn more about {{appName}} reporting0>",
- "title_OpenShift Container Platform": "Red Hat OpenShift",
- "subtitle_OpenShift Container Platform": "Monitor your Red Hat OpenShift usage by socket or core usage, based on your subscription terms. <0>Learn more about {{appName}} reporting0>",
+ "title_OpenShift Container Platform": "OpenShift Container Platform",
+ "subtitle_OpenShift Container Platform": "Monitor your OpenShift Container Platform usage for both fixed and flexible capacity subscriptions. <0>Learn more about {{appName}} reporting0>",
"title_OpenShift-dedicated-metrics": "OpenShift Dedicated",
"subtitle_OpenShift-dedicated-metrics": "Monitor your OpenShift Dedicated usage for flexible capacity subscriptions. <0>Learn more about {{appName}} reporting0>",
"title_RHEL": "Red Hat Enterprise Linux",
diff --git a/src/components/i18n/__tests__/__snapshots__/i18n.test.js.snap b/src/components/i18n/__tests__/__snapshots__/i18n.test.js.snap
index 73888da4b..5a25d4d65 100644
--- a/src/components/i18n/__tests__/__snapshots__/i18n.test.js.snap
+++ b/src/components/i18n/__tests__/__snapshots__/i18n.test.js.snap
@@ -149,13 +149,9 @@ Array [
Object {
"file": "./src/components/openshiftView/openshiftView.js",
"keys": Array [
- Object {
- "key": "curiosity-view.title",
- "match": "t(\`curiosity-view.title\`, { appName: helpers.UI_DISPLAY_NAME, context: productLabel })",
- },
Object {
"key": "curiosity-graph.cardHeading",
- "match": "t('curiosity-graph.cardHeading', { context: uomFilter })",
+ "match": "t('curiosity-graph.cardHeading', { context: productId })",
},
Object {
"key": "curiosity-inventory.tab",
@@ -165,6 +161,10 @@ Array [
"key": "curiosity-inventory.tab",
"match": "t('curiosity-inventory.tab', { context: 'subscriptions' })",
},
+ Object {
+ "key": "curiosity-view.title",
+ "match": "t(\`curiosity-view.title\`, { appName: helpers.UI_DISPLAY_NAME, context: productLabel })",
+ },
Object {
"key": "curiosity-inventory.header",
"match": "translate('curiosity-inventory.header', { context: 'guestsDisplayName' })",
@@ -174,12 +174,16 @@ Array [
"match": "translate('curiosity-inventory.label', { context: 'numberOfGuests', count: numberOfGuests.value }, [ ])",
},
Object {
- "key": "curiosity-inventory.measurementType",
- "match": "translate('curiosity-inventory.measurementType', { context: measurementType.value })",
+ "key": "curiosity-inventory.header",
+ "match": "translate('curiosity-inventory.header', { context: 'sockets_OpenShift Container Platform' })",
},
Object {
- "key": "curiosity-inventory.cloudProvider",
- "match": "translate('curiosity-inventory.cloudProvider', { context: cloudProvider.value })",
+ "key": "curiosity-inventory.header",
+ "match": "translate('curiosity-inventory.header', { context: 'cores_OpenShift Container Platform' })",
+ },
+ Object {
+ "key": "curiosity-inventory.label",
+ "match": "translate('curiosity-inventory.label', { context: 'numberOfGuests', count: numberOfGuests.value }, [ ])",
},
],
},
@@ -559,6 +563,10 @@ Array [
"file": "./src/components/openshiftView/openshiftView.js",
"key": "curiosity-inventory.label",
},
+ Object {
+ "file": "./src/components/openshiftView/openshiftView.js",
+ "key": "curiosity-inventory.label",
+ },
Object {
"file": "./src/components/productView/productView.js",
"key": "curiosity-inventory.tab",
diff --git a/src/components/openshiftView/__tests__/__snapshots__/openshiftView.test.js.snap b/src/components/openshiftView/__tests__/__snapshots__/openshiftView.test.js.snap
index 95ed35ab0..8770eb37f 100644
--- a/src/components/openshiftView/__tests__/__snapshots__/openshiftView.test.js.snap
+++ b/src/components/openshiftView/__tests__/__snapshots__/openshiftView.test.js.snap
@@ -4,279 +4,446 @@ exports[`OpenshiftView Component should have a fallback title: title 1`] = `
- t(curiosity-view.title, {"appName":"Subscription Watch","context":"test label"})
+ t(curiosity-view.title, {"appName":"Subscription Watch","context":"OpenShift Container Platform"})
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
`;
exports[`OpenshiftView Component should have default props that set product configuration: filteredGuestsData results 1`] = `
Object {
"cells": Array [
- Object {
- "title": "lorem",
- },
- Object {
- "title": "lorem inventory id",
- },
- Object {
- "title": ,
- },
+ "lorem",
+ "lorem inventory id",
+ "lorem subscription id",
+ "lorem date obj",
+ "hello world",
],
"columnHeaders": Array [
- Object {
- "title": "t(curiosity-inventory.header, {\\"context\\":\\"guestsDisplayName\\"})",
- "transforms": Array [],
- },
- Object {
- "title": "t(curiosity-inventory.header, {\\"context\\":\\"inventoryId\\"})",
- "transforms": Array [
- [Function],
- ],
- },
- Object {
- "title": "t(curiosity-inventory.header, {\\"context\\":\\"lastSeen\\"})",
- "transforms": Array [
- [Function],
- ],
- },
+ "t(curiosity-inventory.header, {\\"context\\":\\"displayName\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"inventoryId\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"subscriptionManagerId\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"lastSeen\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"loremIpsum\\"})",
],
"data": Object {
"displayName": Object {
@@ -306,43 +473,18 @@ Object {
exports[`OpenshiftView Component should have default props that set product configuration: filteredGuestsData results, authorized 1`] = `
Object {
"cells": Array [
- Object {
- "title": ,
- },
- Object {
- "title": "lorem inventory id",
- },
- Object {
- "title": ,
- },
+ "lorem",
+ "lorem inventory id",
+ "lorem subscription id",
+ "lorem date obj",
+ "hello world",
],
"columnHeaders": Array [
- Object {
- "title": "t(curiosity-inventory.header, {\\"context\\":\\"guestsDisplayName\\"})",
- "transforms": Array [],
- },
- Object {
- "title": "t(curiosity-inventory.header, {\\"context\\":\\"inventoryId\\"})",
- "transforms": Array [
- [Function],
- ],
- },
- Object {
- "title": "t(curiosity-inventory.header, {\\"context\\":\\"lastSeen\\"})",
- "transforms": Array [
- [Function],
- ],
- },
+ "t(curiosity-inventory.header, {\\"context\\":\\"displayName\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"inventoryId\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"subscriptionManagerId\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"lastSeen\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"loremIpsum\\"})",
],
"data": Object {
"displayName": Object {
@@ -372,61 +514,26 @@ Object {
exports[`OpenshiftView Component should have default props that set product configuration: filteredInventoryData results 1`] = `
Object {
"cells": Array [
- Object {
- "title":
- lorem
-
- t(curiosity-inventory.label, {"context":"numberOfGuests","count":3}, [object Object])
- ,
- },
- Object {
- "title":
- t(curiosity-inventory.measurementType, {"context":null})
-
-
- ,
- },
- Object {
- "title": 10,
- },
- Object {
- "title": 12,
- },
- Object {
- "title": ,
- },
+ "lorem",
+ "lorem inventory id",
+ "ipsum",
+ null,
+ 3,
+ 10,
+ 12,
+ "lorem date obj",
+ "hello world",
],
"columnHeaders": Array [
- Object {
- "title": "t(curiosity-inventory.header, {\\"context\\":\\"displayName\\"})",
- "transforms": Array [],
- },
- Object {
- "title": "t(curiosity-inventory.header, {\\"context\\":\\"measurementType\\"})",
- "transforms": Array [
- [Function],
- ],
- },
- Object {
- "title": "t(curiosity-inventory.header, {\\"context\\":\\"sockets\\"})",
- "transforms": Array [
- [Function],
- ],
- },
- Object {
- "title": "t(curiosity-inventory.header, {\\"context\\":\\"cores\\"})",
- "transforms": Array [
- [Function],
- ],
- },
- Object {
- "title": "t(curiosity-inventory.header, {\\"context\\":\\"lastSeen\\"})",
- "transforms": Array [
- [Function],
- ],
- },
+ "t(curiosity-inventory.header, {\\"context\\":\\"displayName\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"inventoryId\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"hardwareType\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"measurementType\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"numberOfGuests\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"sockets\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"cores\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"lastSeen\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"loremIpsum\\"})",
],
"data": Object {
"cores": Object {
@@ -472,69 +579,26 @@ Object {
exports[`OpenshiftView Component should have default props that set product configuration: filteredInventoryData results, authorized 1`] = `
Object {
"cells": Array [
- Object {
- "title":
-
-
- t(curiosity-inventory.label, {"context":"numberOfGuests","count":3}, [object Object])
- ,
- },
- Object {
- "title":
- t(curiosity-inventory.measurementType, {"context":null})
-
-
- ,
- },
- Object {
- "title": 10,
- },
- Object {
- "title": 12,
- },
- Object {
- "title": ,
- },
+ "lorem",
+ "lorem inventory id",
+ "ipsum",
+ null,
+ 3,
+ 10,
+ 12,
+ "lorem date obj",
+ "hello world",
],
"columnHeaders": Array [
- Object {
- "title": "t(curiosity-inventory.header, {\\"context\\":\\"displayName\\"})",
- "transforms": Array [],
- },
- Object {
- "title": "t(curiosity-inventory.header, {\\"context\\":\\"measurementType\\"})",
- "transforms": Array [
- [Function],
- ],
- },
- Object {
- "title": "t(curiosity-inventory.header, {\\"context\\":\\"sockets\\"})",
- "transforms": Array [
- [Function],
- ],
- },
- Object {
- "title": "t(curiosity-inventory.header, {\\"context\\":\\"cores\\"})",
- "transforms": Array [
- [Function],
- ],
- },
- Object {
- "title": "t(curiosity-inventory.header, {\\"context\\":\\"lastSeen\\"})",
- "transforms": Array [
- [Function],
- ],
- },
+ "t(curiosity-inventory.header, {\\"context\\":\\"displayName\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"inventoryId\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"hardwareType\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"measurementType\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"numberOfGuests\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"sockets\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"cores\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"lastSeen\\"})",
+ "t(curiosity-inventory.header, {\\"context\\":\\"loremIpsum\\"})",
],
"data": Object {
"cores": Object {
@@ -579,83 +643,10 @@ Object {
exports[`OpenshiftView Component should have default props that set product configuration: initial configuration 1`] = `
Object {
- "initialGraphFilters": Array [
- Object {
- "color": "#06c",
- "fill": "#8bc1f7",
- "id": "cores",
- "isOptional": true,
- "stroke": "#06c",
- },
- Object {
- "color": "#06c",
- "fill": "#8bc1f7",
- "id": "sockets",
- "isOptional": true,
- "stroke": "#06c",
- },
- Object {
- "id": "thresholdSockets",
- "isOptional": true,
- },
- Object {
- "id": "thresholdCores",
- "isOptional": true,
- },
- ],
- "initialGuestsFilters": Array [
- Object {
- "cell": [Function],
- "header": "t(curiosity-inventory.header, {\\"context\\":\\"guestsDisplayName\\"})",
- "id": "displayName",
- },
- Object {
- "cellWidth": 40,
- "id": "inventoryId",
- },
- Object {
- "cell": [Function],
- "cellWidth": 15,
- "id": "lastSeen",
- },
- ],
- "initialInventoryFilters": Array [
- Object {
- "cell": [Function],
- "id": "displayName",
- "isSortable": true,
- },
- Object {
- "cell": [Function],
- "cellWidth": 20,
- "id": "measurementType",
- "isSortable": true,
- },
- Object {
- "cellWidth": 15,
- "id": "sockets",
- "isOptional": true,
- "isSortable": true,
- "isWrappable": true,
- },
- Object {
- "cellWidth": 15,
- "id": "cores",
- "isOptional": true,
- "isSortable": true,
- "isWrappable": true,
- },
- Object {
- "cell": [Function],
- "cellWidth": 15,
- "id": "lastSeen",
- "isSortable": true,
- "isWrappable": true,
- },
- ],
- "query": Object {
- "uom": "cores",
- },
+ "initialGraphFilters": undefined,
+ "initialGuestsFilters": undefined,
+ "initialInventoryFilters": undefined,
+ "query": Object {},
}
`;
@@ -663,243 +654,427 @@ exports[`OpenshiftView Component should render a non-connected component: non-co
- t(curiosity-view.title, {"appName":"Subscription Watch","context":"test label"})
+ t(curiosity-view.title, {"appName":"Subscription Watch","context":"OpenShift Container Platform"})
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
`;
diff --git a/src/components/openshiftView/openshiftView.js b/src/components/openshiftView/openshiftView.js
index 28f5c1855..74c22ed42 100644
--- a/src/components/openshiftView/openshiftView.js
+++ b/src/components/openshiftView/openshiftView.js
@@ -7,8 +7,9 @@ import {
import { Button, Label as PfLabel } from '@patternfly/react-core';
import { DateFormat } from '@redhat-cloud-services/frontend-components/components/DateFormat';
import moment from 'moment';
-import { PageLayout, PageHeader, PageMessages, PageSection, PageToolbar } from '../pageLayout/pageLayout';
+import { PageLayout, PageColumns, PageHeader, PageSection, PageToolbar } from '../pageLayout/pageLayout';
import {
+ RHSM_API_PATH_ID_TYPES,
RHSM_API_QUERY_SORT_DIRECTION_TYPES as SORT_DIRECTION_TYPES,
RHSM_API_QUERY_GRANULARITY_TYPES as GRANULARITY_TYPES,
RHSM_API_QUERY_TYPES,
@@ -20,11 +21,11 @@ import { apiQueries, connect, reduxSelectors } from '../../redux';
import GraphCard from '../graphCard/graphCard';
import { ToolbarFieldUom } from '../toolbar/toolbarFieldUom';
import { ToolbarFieldGranularity } from '../toolbar/toolbarFieldGranularity';
+import { ToolbarFieldRangedMonthly } from '../toolbar/toolbarFieldRangedMonthly';
import Toolbar from '../toolbar/toolbar';
import InventoryList from '../inventoryList/inventoryList';
import InventorySubscriptions from '../inventorySubscriptions/inventorySubscriptions';
import InventoryTabs, { InventoryTab } from '../inventoryTabs/inventoryTabs';
-import BannerMessages from '../bannerMessages/bannerMessages';
import { helpers, dateHelpers } from '../../common';
import { translate } from '../i18n/i18n';
@@ -32,34 +33,35 @@ import { translate } from '../i18n/i18n';
* An OpenShift encompassing view.
*
* @augments React.Component
- * @fires onSelect
*/
class OpenshiftView extends React.Component {
componentDidMount() {}
/**
- * Render an OpenShift view.
+ * Render a product column
*
+ * @param {object} config
+ * @param {string} uomValue
* @returns {Node}
*/
- render() {
+ renderProduct(config, uomValue) {
+ const { t } = this.props;
const {
- initialGuestsFilters,
- initialToolbarFilters,
- initialInventorySettings,
- initialGraphFilters,
- initialInventoryFilters,
+ productContextFilterUom,
+ query = {},
+ graphTallyQuery = {},
+ inventoryHostsQuery = {},
+ inventorySubscriptionsQuery = {},
+ initialGraphFilters = [],
+ initialGuestsFilters = [],
+ initialInventoryFilters = [],
+ initialInventorySettings = {},
initialSubscriptionsInventoryFilters,
- initialOption,
- query,
- graphTallyQuery,
- inventoryHostsQuery,
- inventorySubscriptionsQuery,
- routeDetail,
- t,
+ initialToolbarFilters,
+ productLabel,
+ productId,
viewId
- } = this.props;
- const { pathParameter: productId, productParameter: productLabel } = routeDetail;
+ } = config;
const {
graphTallyQuery: initialGraphTallyQuery,
inventoryHostsQuery: initialInventoryHostsQuery,
@@ -67,29 +69,33 @@ class OpenshiftView extends React.Component {
toolbarQuery
} = apiQueries.parseRhsmQuery(query, { graphTallyQuery, inventoryHostsQuery, inventorySubscriptionsQuery });
- const uomFilter = query[RHSM_API_QUERY_TYPES.UOM] || initialOption;
- const filter = ({ id, isOptional }) => {
- if (!isOptional) {
- return true;
- }
- return new RegExp(uomFilter, 'i').test(id);
- };
+ let graphFilters = initialGraphFilters;
+ let inventoryFilters = initialInventoryFilters;
+ let subscriptionsInventoryFilters = initialSubscriptionsInventoryFilters;
+ let uomFilter;
+
+ if (productContextFilterUom) {
+ uomFilter = uomValue || query[RHSM_API_QUERY_TYPES.UOM];
- const graphFilters = initialGraphFilters.filter(filter);
- const inventoryFilters = initialInventoryFilters.filter(filter);
- const subscriptionsInventoryFilters = initialSubscriptionsInventoryFilters.filter(filter);
+ const filter = ({ id, isOptional }) => {
+ if (!isOptional) {
+ return true;
+ }
+ return new RegExp(uomFilter, 'i').test(id);
+ };
+
+ graphFilters = initialGraphFilters.filter(filter);
+ inventoryFilters = initialInventoryFilters.filter(filter);
+ subscriptionsInventoryFilters = initialSubscriptionsInventoryFilters.filter(filter);
+ }
return (
-
-
- {t(`curiosity-view.title`, { appName: helpers.UI_DISPLAY_NAME, context: productLabel })}
-
-
-
-
-
-
-
+
+ {initialToolbarFilters && (
+
+
+
+ )}
-
-
+ {productId === RHSM_API_PATH_ID_TYPES.OPENSHIFT && uomFilter && (
+
+ )}
+ {productId === RHSM_API_PATH_ID_TYPES.OPENSHIFT && (
+
+ )}
+ {productId === RHSM_API_PATH_ID_TYPES.OPENSHIFT_METRICS && }
@@ -111,7 +122,7 @@ class OpenshiftView extends React.Component {
title={t('curiosity-inventory.tab', { context: 'hosts' })}
>
- {!helpers.UI_DISABLED_TABLE_SUBSCRIPTIONS && (
+ {!helpers.UI_DISABLED_TABLE_SUBSCRIPTIONS && initialSubscriptionsInventoryFilters && (
+
+ );
+ }
+
+ /**
+ * Render an OpenShift view.
+ *
+ * @returns {Node}
+ */
+ render() {
+ const { productConfig, productLabel, query, t } = this.props;
+ const uomValue = query[RHSM_API_QUERY_TYPES.UOM];
+
+ return (
+
+
+ {t(`curiosity-view.title`, { appName: helpers.UI_DISPLAY_NAME, context: productLabel })}
+
+ {productConfig.map(config => this.renderProduct(config, uomValue))}
);
}
}
+/**
+ * FixMe: the viewId is used by viewSelectors.js, remove it!
+ * The viewId is used to help fire a render on UOM update,
+ * this is a hack until context and hooks can replace it.
+ */
/**
* Prop types.
*
- * @type {{initialOption: string, inventorySubscriptionsQuery: object, query: object,
- * initialSubscriptionsInventoryFilters: Array, initialInventorySettings: object, initialToolbarFilters: Array,
- * t: Function, graphTallyQuery: object, inventoryHostsQuery: object, initialGraphFilters: Array,
- * routeDetail: object, initialGuestsFilters: Array, initialInventoryFilters: Array, viewId: string}}
+ * @type {{productLabel: string, t: Function, routeDetail: object, productConfig: Array}}
*/
OpenshiftView.propTypes = {
- query: PropTypes.object,
- graphTallyQuery: PropTypes.shape({
- [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,
- [RHSM_API_QUERY_TYPES.OFFSET]: PropTypes.number,
- [RHSM_API_QUERY_TYPES.SORT]: PropTypes.oneOf([...Object.values(RHSM_API_QUERY_SORT_TYPES)]),
- [RHSM_API_QUERY_TYPES.DIRECTION]: PropTypes.oneOf([...Object.values(SORT_DIRECTION_TYPES)])
- }),
- inventorySubscriptionsQuery: PropTypes.shape({
- [RHSM_API_QUERY_TYPES.LIMIT]: PropTypes.number,
- [RHSM_API_QUERY_TYPES.OFFSET]: PropTypes.number,
- [RHSM_API_QUERY_TYPES.SORT]: PropTypes.oneOf([...Object.values(RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES)]),
- [RHSM_API_QUERY_TYPES.DIRECTION]: PropTypes.oneOf([...Object.values(SORT_DIRECTION_TYPES)])
- }),
- initialOption: PropTypes.oneOf(Object.values(RHSM_API_QUERY_UOM_TYPES)),
- initialGraphFilters: PropTypes.array,
- initialGuestsFilters: PropTypes.array,
- initialInventoryFilters: PropTypes.array,
- initialInventorySettings: PropTypes.shape({
- hasGuests: PropTypes.func
- }),
- initialSubscriptionsInventoryFilters: PropTypes.array,
- initialToolbarFilters: PropTypes.array,
+ productConfig: PropTypes.arrayOf(
+ PropTypes.shape({
+ productContextFilterUom: PropTypes.bool,
+ query: PropTypes.object,
+ graphTallyQuery: PropTypes.shape({
+ [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,
+ [RHSM_API_QUERY_TYPES.OFFSET]: PropTypes.number,
+ [RHSM_API_QUERY_TYPES.SORT]: PropTypes.oneOf([...Object.values(RHSM_API_QUERY_SORT_TYPES)]),
+ [RHSM_API_QUERY_TYPES.DIRECTION]: PropTypes.oneOf([...Object.values(SORT_DIRECTION_TYPES)])
+ }),
+ inventorySubscriptionsQuery: PropTypes.shape({
+ [RHSM_API_QUERY_TYPES.LIMIT]: PropTypes.number,
+ [RHSM_API_QUERY_TYPES.OFFSET]: PropTypes.number,
+ [RHSM_API_QUERY_TYPES.SORT]: PropTypes.oneOf([...Object.values(RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES)]),
+ [RHSM_API_QUERY_TYPES.DIRECTION]: PropTypes.oneOf([...Object.values(SORT_DIRECTION_TYPES)])
+ }),
+ initialOption: PropTypes.oneOf(Object.values(RHSM_API_QUERY_UOM_TYPES)),
+ initialGraphFilters: PropTypes.array,
+ initialGuestsFilters: PropTypes.array,
+ initialInventoryFilters: PropTypes.array,
+ initialInventorySettings: PropTypes.shape({
+ hasGuests: PropTypes.func
+ }),
+ initialSubscriptionsInventoryFilters: PropTypes.array,
+ initialToolbarFilters: PropTypes.array,
+ productLabel: PropTypes.string,
+ productId: PropTypes.string,
+ viewId: PropTypes.string
+ })
+ ),
+ productLabel: PropTypes.string,
routeDetail: PropTypes.shape({
pathParameter: PropTypes.string,
productParameter: PropTypes.string,
viewParameter: PropTypes.string
}).isRequired,
- t: PropTypes.func,
- viewId: PropTypes.string
+ query: PropTypes.object,
+ viewId: PropTypes.string, // eslint-disable-line
+ t: PropTypes.func
};
+/**
+ * FixMe: the viewId is used by viewSelectors.js, remove it!
+ * The viewId is used to help fire a render on UOM update,
+ * this is a hack until context and hooks can replace it.
+ */
/**
* Default props.
*
- * @type {{initialOption: string, inventorySubscriptionsQuery: object, query: object,
- * initialSubscriptionsInventoryFilters: Array, initialInventorySettings: object, initialToolbarFilters: Array,
- * t: translate, graphTallyQuery: object, inventoryHostsQuery: object,
- * initialGraphFilters: Array, initialGuestsFilters: Array, initialInventoryFilters: Array, viewId: string}}
+ * @type {{productLabel: string, t: Function, productConfig: Array}}
*/
OpenshiftView.defaultProps = {
- query: {
- [RHSM_API_QUERY_TYPES.UOM]: RHSM_API_QUERY_UOM_TYPES.CORES
- },
- graphTallyQuery: {
- [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,
- [RHSM_API_QUERY_TYPES.DIRECTION]: SORT_DIRECTION_TYPES.ASCENDING,
- [RHSM_API_QUERY_TYPES.LIMIT]: 100,
- [RHSM_API_QUERY_TYPES.OFFSET]: 0
- },
- inventorySubscriptionsQuery: {
- [RHSM_API_QUERY_TYPES.SORT]: RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES.UPCOMING_EVENT_DATE,
- [RHSM_API_QUERY_TYPES.DIRECTION]: SORT_DIRECTION_TYPES.ASCENDING,
- [RHSM_API_QUERY_TYPES.LIMIT]: 100,
- [RHSM_API_QUERY_TYPES.OFFSET]: 0
- },
- initialOption: RHSM_API_QUERY_UOM_TYPES.CORES,
- initialGraphFilters: [
- {
- id: 'cores',
- isOptional: true,
- fill: chartColorBlueLight.value,
- stroke: chartColorBlueDark.value,
- color: chartColorBlueDark.value
- },
+ productConfig: [
{
- id: 'sockets',
- isOptional: true,
- fill: chartColorBlueLight.value,
- stroke: chartColorBlueDark.value,
- color: chartColorBlueDark.value
- },
- { id: 'thresholdSockets', isOptional: true },
- { id: 'thresholdCores', isOptional: true }
- ],
- initialGuestsFilters: [
- {
- id: 'displayName',
- header: translate('curiosity-inventory.header', { context: 'guestsDisplayName' }),
- cell: (data, session) => {
- const { displayName, inventoryId } = data;
- const { inventory: authorized } = session?.authorized || {};
+ productContextFilterUom: true,
+ query: {
+ [RHSM_API_QUERY_TYPES.UOM]: RHSM_API_QUERY_UOM_TYPES.CORES
+ },
+ graphTallyQuery: {
+ [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,
+ [RHSM_API_QUERY_TYPES.DIRECTION]: SORT_DIRECTION_TYPES.ASCENDING,
+ [RHSM_API_QUERY_TYPES.LIMIT]: 100,
+ [RHSM_API_QUERY_TYPES.OFFSET]: 0
+ },
+ inventorySubscriptionsQuery: {
+ [RHSM_API_QUERY_TYPES.SORT]: RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES.UPCOMING_EVENT_DATE,
+ [RHSM_API_QUERY_TYPES.DIRECTION]: SORT_DIRECTION_TYPES.ASCENDING,
+ [RHSM_API_QUERY_TYPES.LIMIT]: 100,
+ [RHSM_API_QUERY_TYPES.OFFSET]: 0
+ },
+ initialOption: RHSM_API_QUERY_UOM_TYPES.CORES,
+ initialGraphFilters: [
+ {
+ id: 'cores',
+ isOptional: true,
+ fill: chartColorBlueLight.value,
+ stroke: chartColorBlueDark.value,
+ color: chartColorBlueDark.value
+ },
+ {
+ id: 'sockets',
+ isOptional: true,
+ fill: chartColorBlueLight.value,
+ stroke: chartColorBlueDark.value,
+ color: chartColorBlueDark.value
+ },
+ { id: 'thresholdSockets', isOptional: true },
+ { id: 'thresholdCores', isOptional: true }
+ ],
+ initialGuestsFilters: [
+ {
+ id: 'displayName',
+ header: translate('curiosity-inventory.header', { context: 'guestsDisplayName' }),
+ cell: (data, session) => {
+ const { displayName, inventoryId } = data;
+ const { inventory: authorized } = session?.authorized || {};
- if (!inventoryId?.value) {
- return displayName?.value;
- }
+ if (!inventoryId?.value) {
+ return displayName?.value;
+ }
- if (!authorized) {
- return displayName?.value || inventoryId?.value;
+ if (!authorized) {
+ return displayName?.value || inventoryId?.value;
+ }
+
+ return (
+
+ );
+ }
+ },
+ {
+ id: 'inventoryId',
+ cellWidth: 40
+ },
+ {
+ id: 'lastSeen',
+ cell: data => (data?.lastSeen?.value && ) || '',
+ cellWidth: 15
}
+ ],
+ initialInventoryFilters: [
+ {
+ id: 'displayName',
+ cell: (data, session) => {
+ const { displayName = {}, inventoryId = {}, numberOfGuests = {} } = data;
+ const { inventory: authorized } = session?.authorized || {};
- return (
-
- );
- }
- },
- {
- id: 'inventoryId',
- cellWidth: 40
- },
- {
- id: 'lastSeen',
- cell: data => (data?.lastSeen?.value && ) || '',
- cellWidth: 15
- }
- ],
- initialInventoryFilters: [
- {
- id: 'displayName',
- cell: (data, session) => {
- const { displayName = {}, inventoryId = {}, numberOfGuests = {} } = data;
- const { inventory: authorized } = session?.authorized || {};
+ if (!inventoryId.value) {
+ return displayName.value;
+ }
- if (!inventoryId.value) {
- return displayName.value;
- }
+ let updatedDisplayName = displayName.value || inventoryId.value;
- let updatedDisplayName = displayName.value || inventoryId.value;
+ if (authorized) {
+ updatedDisplayName = (
+
+ );
+ }
- if (authorized) {
- updatedDisplayName = (
-
- );
+ return (
+
+ {updatedDisplayName}{' '}
+ {(numberOfGuests.value &&
+ translate('curiosity-inventory.label', { context: 'numberOfGuests', count: numberOfGuests.value }, [
+
+ ])) ||
+ ''}
+
+ );
+ },
+ isSortable: true
+ },
+ {
+ id: 'sockets',
+ header: translate('curiosity-inventory.header', { context: 'sockets_OpenShift Container Platform' }),
+ isOptional: true,
+ isSortable: true,
+ isWrappable: true,
+ cellWidth: 15
+ },
+ {
+ id: 'cores',
+ header: translate('curiosity-inventory.header', { context: 'cores_OpenShift Container Platform' }),
+ isOptional: true,
+ isSortable: true,
+ isWrappable: true,
+ cellWidth: 15
+ },
+ {
+ id: 'lastSeen',
+ cell: data => (data?.lastSeen?.value && ) || '',
+ isSortable: true,
+ isWrappable: true,
+ cellWidth: 15
}
-
- return (
-
- {updatedDisplayName}{' '}
- {(numberOfGuests.value &&
- translate('curiosity-inventory.label', { context: 'numberOfGuests', count: numberOfGuests.value }, [
-
- ])) ||
- ''}
-
- );
- },
- isSortable: true
+ ],
+ initialInventorySettings: {},
+ initialSubscriptionsInventoryFilters: [
+ {
+ id: 'productName',
+ isSortable: true
+ },
+ {
+ id: 'serviceLevel',
+ isSortable: true,
+ isWrappable: true,
+ cellWidth: 15
+ },
+ {
+ id: 'upcomingEventDate',
+ cell: data =>
+ (data?.upcomingEventDate?.value && moment.utc(data?.upcomingEventDate?.value).format('YYYY-DD-MM')) || '',
+ isSortable: true,
+ isWrappable: true,
+ cellWidth: 15
+ }
+ ],
+ initialToolbarFilters: [
+ {
+ id: RHSM_API_QUERY_TYPES.SLA
+ }
+ ],
+ productLabel: 'OpenShift',
+ productId: RHSM_API_PATH_ID_TYPES.OPENSHIFT,
+ viewId: 'viewOpenShift'
},
{
- id: 'measurementType',
- cell: data => {
- const { cloudProvider = {}, measurementType = {} } = data;
- return (
-
- {translate('curiosity-inventory.measurementType', { context: measurementType.value })}{' '}
- {(cloudProvider.value && (
-
- {translate('curiosity-inventory.cloudProvider', { context: cloudProvider.value })}
-
- )) ||
- ''}
-
- );
+ query: {},
+ graphTallyQuery: {
+ [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()
},
- isSortable: true,
- cellWidth: 20
- },
- {
- id: 'sockets',
- isOptional: true,
- isSortable: true,
- isWrappable: true,
- cellWidth: 15
- },
- {
- id: 'cores',
- isOptional: true,
- isSortable: true,
- isWrappable: true,
- cellWidth: 15
- },
- {
- id: 'lastSeen',
- cell: data => (data?.lastSeen?.value && ) || '',
- isSortable: true,
- isWrappable: true,
- cellWidth: 15
- }
- ],
- initialInventorySettings: {},
- initialSubscriptionsInventoryFilters: [
- {
- id: 'productName',
- isSortable: true
- },
- {
- id: 'serviceLevel',
- isSortable: true,
- isWrappable: true,
- cellWidth: 15
- },
- {
- id: 'upcomingEventDate',
- cell: data =>
- (data?.upcomingEventDate?.value && moment.utc(data?.upcomingEventDate?.value).format('YYYY-DD-MM')) || '',
- isSortable: true,
- isWrappable: true,
- cellWidth: 15
- }
- ],
- initialToolbarFilters: [
- {
- id: RHSM_API_QUERY_TYPES.SLA
+ inventoryHostsQuery: {
+ [RHSM_API_QUERY_TYPES.SORT]: RHSM_API_QUERY_SORT_TYPES.LAST_SEEN,
+ [RHSM_API_QUERY_TYPES.DIRECTION]: SORT_DIRECTION_TYPES.ASCENDING,
+ [RHSM_API_QUERY_TYPES.LIMIT]: 100,
+ [RHSM_API_QUERY_TYPES.OFFSET]: 0
+ },
+ initialGraphFilters: [
+ {
+ id: 'coreHours',
+ fill: chartColorBlueLight.value,
+ stroke: chartColorBlueDark.value,
+ color: chartColorBlueDark.value
+ }
+ ],
+ initialInventoryFilters: [
+ {
+ id: 'displayName',
+ cell: data => {
+ const { displayName = {}, inventoryId = {}, numberOfGuests = {} } = data;
+
+ if (!inventoryId.value) {
+ return displayName.value;
+ }
+
+ const updatedDisplayName = displayName.value || inventoryId.value;
+
+ return (
+
+ {updatedDisplayName}{' '}
+ {(numberOfGuests.value &&
+ translate('curiosity-inventory.label', { context: 'numberOfGuests', count: numberOfGuests.value }, [
+
+ ])) ||
+ ''}
+
+ );
+ },
+ isSortable: true
+ },
+ {
+ id: 'coreHours',
+ isSortable: true,
+ isWrappable: true,
+ cellWidth: 15
+ },
+ {
+ id: 'lastSeen',
+ cell: data => (data?.lastSeen?.value && ) || '',
+ isSortable: true,
+ isWrappable: true,
+ cellWidth: 15
+ }
+ ],
+ initialToolbarFilters: undefined,
+ productLabel: 'OpenShift Metric',
+ productId: RHSM_API_PATH_ID_TYPES.OPENSHIFT_METRICS,
+ viewId: 'viewOpenShiftMetric'
}
],
- t: translate,
- viewId: 'viewOpenShift'
+ productLabel: RHSM_API_PATH_ID_TYPES.OPENSHIFT,
+ query: {},
+ viewId: 'viewOpenShift', // eslint-disable-line
+ t: translate
};
/**
diff --git a/src/components/productView/__tests__/__snapshots__/productView.test.js.snap b/src/components/productView/__tests__/__snapshots__/productView.test.js.snap
index e656a7b30..c793d5bcf 100644
--- a/src/components/productView/__tests__/__snapshots__/productView.test.js.snap
+++ b/src/components/productView/__tests__/__snapshots__/productView.test.js.snap
@@ -48,7 +48,7 @@ exports[`ProductView Component should allow custom toolbar components: custom to
title="t(curiosity-inventory.tab, {\\"context\\":\\"hosts\\"})"
>
`;
diff --git a/src/components/productView/__tests__/__snapshots__/productViewSatellite.test.js.snap b/src/components/productView/__tests__/__snapshots__/productViewSatellite.test.js.snap
index bb30fffd6..0838cfb31 100644
--- a/src/components/productView/__tests__/__snapshots__/productViewSatellite.test.js.snap
+++ b/src/components/productView/__tests__/__snapshots__/productViewSatellite.test.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ProductViewSatellite Component should render a non-connected component: non-connected 1`] = `
-
`;
diff --git a/src/components/productView/productView.js b/src/components/productView/productView.js
index f2c68410e..7b971d90c 100644
--- a/src/components/productView/productView.js
+++ b/src/components/productView/productView.js
@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { PageLayout, PageHeader, PageSection, PageToolbar, PageMessages } from '../pageLayout/pageLayout';
-import { apiQueries, connect, reduxSelectors } from '../../redux';
+import { apiQueries } from '../../redux';
import { ConnectedGraphCard, GraphCard } from '../graphCard/graphCard';
import { ConnectedToolbar, Toolbar } from '../toolbar/toolbar';
import { ConnectedInventoryList, InventoryList } from '../inventoryList/inventoryList';
@@ -115,7 +115,7 @@ const ProductView = ({ productConfig, routeDetail, t, toolbarGraph, toolbarProdu
{
const { [RHSM_API_QUERY_TYPES.START_DATE]: startDate } = productConfig.graphTallyQuery;
return (
- (
-
+
);
/**
diff --git a/src/components/productView/productViewSatellite.js b/src/components/productView/productViewSatellite.js
index d2e65a8ca..2d15406b3 100644
--- a/src/components/productView/productViewSatellite.js
+++ b/src/components/productView/productViewSatellite.js
@@ -18,7 +18,7 @@ import {
RHSM_API_QUERY_SORT_TYPES,
RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES
} from '../../types/rhsmApiTypes';
-import { ConnectedProductView, ProductView } from './productView';
+import { ProductView } from './productView';
import { translate } from '../i18n/i18n';
import { dateHelpers, helpers } from '../../common';
@@ -31,7 +31,7 @@ import { dateHelpers, helpers } from '../../common';
* @returns {Node}
*/
const ProductViewSatellite = ({ productConfig, routeDetail }) => (
-
+
);
/**
diff --git a/src/redux/selectors/__tests__/__snapshots__/viewSelectors.test.js.snap b/src/redux/selectors/__tests__/__snapshots__/viewSelectors.test.js.snap
index 52320ed16..fb3100af4 100644
--- a/src/redux/selectors/__tests__/__snapshots__/viewSelectors.test.js.snap
+++ b/src/redux/selectors/__tests__/__snapshots__/viewSelectors.test.js.snap
@@ -2,10 +2,6 @@
exports[`ViewSelectors should pass minimal data on missing a reducer response: missing reducer error 1`] = `
Object {
- "graphTallyQuery": Object {},
- "inventoryGuestsQuery": Object {},
- "inventoryHostsQuery": Object {},
- "inventorySubscriptionsQuery": Object {},
"query": Object {},
}
`;
diff --git a/src/redux/selectors/viewSelectors.js b/src/redux/selectors/viewSelectors.js
index a2bdc3ff6..3d8cf391f 100644
--- a/src/redux/selectors/viewSelectors.js
+++ b/src/redux/selectors/viewSelectors.js
@@ -1,25 +1,9 @@
-import { createSelectorCreator, defaultMemoize } from 'reselect';
-import _isEqual from 'lodash/isEqual';
+import { createSelector } from 'reselect';
/**
- * Create a custom "are objects equal" selector.
- *
- * @private
- * @type {Function}}
- */
-const createDeepEqualSelector = createSelectorCreator(defaultMemoize, _isEqual);
-
-/**
- * ToDo: as part of future potential upgrades consider moving reduxHelpers.setApiQuery into statePropsFilter
- * The side effect is multiple queries being dumped into the views, meaning more "configuration to handle".
- * Leaving it as a single query passed from this selector and handling the "setApiQuery" in "redux/common/apiQueries"
- * is a first step.
- * i.e.
- * queries: {
- * query: ...,
- * graph: reduxHelpers.setApiQuery(..., RHSM_API_QUERY_SET_REPORT_CAPACITY_TYPES),
- * inventory: reduxHelpers.setApiQuery(..., RHSM_API_QUERY_SET_INVENTORY_TYPES)
- * }
+ * FixMe: Remove this selector, switch fully over to context and hooks for products!
+ * This selector is currently used as a hack by the openshiftView.js to fire a component
+ * render for UOM selection. This needs to be fixed!
*/
/**
* Return a combined state, props object.
@@ -34,45 +18,23 @@ const statePropsFilter = (state = {}, props, defaultProps = {}) => ({
query: {
...defaultProps.query,
...state.view?.query?.[defaultProps.viewId]
- },
- graphTallyQuery: {
- ...defaultProps.graphTallyQuery,
- ...state.view?.graphTallyQuery?.[defaultProps.viewId]
- },
- inventoryGuestsQuery: {
- ...defaultProps.inventoryGuestsQuery,
- ...state.view?.inventoryGuestsQuery?.[defaultProps.viewId]
- },
- inventoryHostsQuery: {
- ...defaultProps.inventoryHostsQuery,
- ...state.view?.inventoryHostsQuery?.[defaultProps.viewId]
- },
- inventorySubscriptionsQuery: {
- ...defaultProps.inventorySubscriptionsQuery,
- ...state.view?.inventorySubscriptionsQuery?.[defaultProps.viewId]
}
});
/**
* Create selector, transform combined state, props into a consumable API param/query object.
*
- * @type {{query: object, graphTallyQuery: object, inventoryGuestsQuery: object, inventoryHostsQuery: object,
- * inventorySubscriptionsQuery: object}}
+ * @type {{query: object}}
*/
-const selector = createDeepEqualSelector([statePropsFilter], view => ({
- query: { ...view.query },
- graphTallyQuery: { ...view.graphTallyQuery },
- inventoryGuestsQuery: { ...view.inventoryGuestsQuery },
- inventoryHostsQuery: { ...view.inventoryHostsQuery },
- inventorySubscriptionsQuery: { ...view.inventorySubscriptionsQuery }
+const selector = createSelector([statePropsFilter], view => ({
+ query: { ...view.query }
}));
/**
* Expose selector instance. For scenarios where a selector is reused across component instances.
*
* @param {object} defaultProps
- * @returns {{query: object, graphTallyQuery: object, inventoryGuestsQuery: object, inventoryHostsQuery: object,
- * inventorySubscriptionsQuery: object}}
+ * @returns {{query: object}}
*/
const makeSelector = defaultProps => (state, props) => ({
...selector(state, props, defaultProps)