diff --git a/src/components/graphCard/__tests__/__snapshots__/graphCard.test.js.snap b/src/components/graphCard/__tests__/__snapshots__/graphCard.test.js.snap index e83d28362..58ab7fb2d 100644 --- a/src/components/graphCard/__tests__/__snapshots__/graphCard.test.js.snap +++ b/src/components/graphCard/__tests__/__snapshots__/graphCard.test.js.snap @@ -7,6 +7,7 @@ exports[`GraphCard Component should render a default component: default 1`] = `< exports[`GraphCard Component should setup basic settings: settings, grouped 1`] = ` - - - - - - - - t(curiosity-graph.cardHeading, {}) - <GraphCardChartTitleTooltip - t={[Function]} - useGraphCardContext={[Function]} - useProduct={[Function]} - /> - - - - + + + + t(curiosity-graph.cardHeading, {}) + <GraphCardChartTitleTooltip + t={[Function]} + useGraphCardContext={[Function]} + useProduct={[Function]} + /> + + + - - - - - t(curiosity-graph.cardHeading, {}) - <GraphCardChartTitleTooltip - t={[Function]} - useGraphCardContext={[Function]} - useProduct={[Function]} - /> - - - - + + + + t(curiosity-graph.cardHeading, {}) + <GraphCardChartTitleTooltip + t={[Function]} + useGraphCardContext={[Function]} + useProduct={[Function]} + /> + + + - - - - - t(curiosity-graph.cardHeading, {}) - <GraphCardChartTitleTooltip - t={[Function]} - useGraphCardContext={[Function]} - useProduct={[Function]} - /> - - - - + + + + t(curiosity-graph.cardHeading, {}) + <GraphCardChartTitleTooltip + t={[Function]} + useGraphCardContext={[Function]} + useProduct={[Function]} + /> + + + - - - - - t(curiosity-graph.cardHeading, {}) - <GraphCardChartTitleTooltip - t={[Function]} - useGraphCardContext={[Function]} - useProduct={[Function]} - /> - - - - + + + + t(curiosity-graph.cardHeading, {}) + <GraphCardChartTitleTooltip + t={[Function]} + useGraphCardContext={[Function]} + useProduct={[Function]} + /> + + + - - +
- - t(curiosity-graph.cardHeadingMetric, {"context":"dailyTotal"}) - - - -
- - - - -
+ + - </CardFooter> - </MinHeight> + </CardTitle> + </CardHeader> + <CardBody> + <div /> + </CardBody> + <CardFooter> + <div /> + </CardFooter> </Card> <Card className="curiosity-usage-graph__totals-column-card blur" data-test="graphMonthlyTotalCard" + isPlain={true} > - <CardTitle> - t(curiosity-graph.cardHeadingMetric, {"context":"monthlyTotal"}) - </CardTitle> - <MinHeight - key="totalMonthlyBody" - minHeight={0} - updateOnContent={false} - updateOnResize={true} - > - <CardBody> - <div /> - </CardBody> - </MinHeight> - <MinHeight - key="totalMonthlyFooter" - minHeight={0} - updateOnContent={false} - updateOnResize={true} - > - <CardFooter> - <div - className="hidden" + <CardHeader> + <CardTitle> + <Title + headingLevel="h2" + size="md" /> - </CardFooter> - </MinHeight> + </CardTitle> + </CardHeader> + <CardBody> + <div /> + </CardBody> + <CardFooter> + <div /> + </CardFooter> </Card> - </FlexItem> - </Flex> - <Flex - alignSelf={ - { - "default": "alignSelfStretch", - } - } - direction={ - { - "default": "column", - } - } - flex={ - { - "default": "flex_3", - } - } - > - <FlexItem + </div> + </div> + <div> + <div className="curiosity-usage-graph__totals-graph-column" /> - </Flex> -</Flex> + </div> +</div> `; exports[`GraphCardMetricTotals Component should handle multiple display states: fulfilled 1`] = ` -<Flex +<div className="curiosity-usage-graph__totals" data-test="graphMetricTotals-" > - <Flex - alignSelf={ - { - "default": "alignSelfStretch", - } - } - direction={ - { - "default": "column", - } - } - flex={ - { - "default": "flex_1", - } - } - > - <FlexItem + <div> + <div className="curiosity-usage-graph__totals-column" > <Card className="curiosity-usage-graph__totals-column-card " data-test="graphDailyTotalCard" + isPlain={true} > - <CardTitle> - t(curiosity-graph.cardHeadingMetric, {"context":"dailyTotal"}) - </CardTitle> - <MinHeight - key="currentBody" - minHeight={0} - updateOnContent={false} - updateOnResize={true} - > - <CardBody> - <div> - t(curiosity-graph.cardBodyMetric, {"context":"total"}, [object Object]) - </div> - </CardBody> - </MinHeight> - <MinHeight - key="currentFooter" - minHeight={0} - updateOnContent={false} - updateOnResize={true} - > - <CardFooter> - <div - className="hidden" - /> - </CardFooter> - </MinHeight> + <CardHeader> + <CardTitle> + <Title + headingLevel="h2" + size="md" + > + t(curiosity-graph.cardHeadingMetric, {"context":"dailyTotal"}) + + + + +
+ t(curiosity-graph.cardBodyMetric, {"context":"total"}, [object Object]) +
+
+ +
+ - - t(curiosity-graph.cardHeadingMetric, {"context":"monthlyTotal"}) - - - -
- t(curiosity-graph.cardBodyMetric, {"context":"total"}, [object Object]) -
-
-
- - -
- - + + + + t(curiosity-graph.cardHeadingMetric, {"context":"monthlyTotal"}) + + + + +
+ t(curiosity-graph.cardBodyMetric, {"context":"total"}, [object Object]) +
+
+ +
+ - - - - +
+
+
- - +
+
`; exports[`GraphCardMetricTotals Component should handle multiple display states: pending 1`] = ` - - - +
- - t(curiosity-graph.cardHeadingMetric, {"context":"dailyTotal"}) - - - -
+ + + <Loader skeletonProps={ { @@ -275,37 +155,48 @@ exports[`GraphCardMetricTotals Component should handle multiple display states: tableProps={{}} variant="skeleton" /> - </div> - </CardBody> - </MinHeight> - <MinHeight - key="currentFooter" - minHeight={0} - updateOnContent={false} - updateOnResize={true} - > - <CardFooter> - <div - className="hidden" + + + + +
+ +
+
+ +
+ - - +
+
- - t(curiosity-graph.cardHeadingMetric, {"context":"monthlyTotal"}) - - - -
+ + + <Loader skeletonProps={ { @@ -315,155 +206,102 @@ exports[`GraphCardMetricTotals Component should handle multiple display states: tableProps={{}} variant="skeleton" /> - </div> - </CardBody> - </MinHeight> - <MinHeight - key="totalMonthlyFooter" - minHeight={0} - updateOnContent={false} - updateOnResize={true} - > - <CardFooter> - <div - className="hidden" + + + + +
+ +
+
+ +
+ - - +
+
- - - - +
+
+
- - +
+
`; exports[`GraphCardMetricTotals Component should render a basic component: basic 1`] = ` - - - +
- - t(curiosity-graph.cardHeadingMetric, {"context":"dailyTotal"}) - - - -
- - - - -
+ + - </CardFooter> - </MinHeight> + </CardTitle> + </CardHeader> + <CardBody> + <div /> + </CardBody> + <CardFooter> + <div /> + </CardFooter> </Card> <Card className="curiosity-usage-graph__totals-column-card " data-test="graphMonthlyTotalCard" + isPlain={true} > - <CardTitle> - t(curiosity-graph.cardHeadingMetric, {"context":"monthlyTotal"}) - </CardTitle> - <MinHeight - key="totalMonthlyBody" - minHeight={0} - updateOnContent={false} - updateOnResize={true} - > - <CardBody> - <div /> - </CardBody> - </MinHeight> - <MinHeight - key="totalMonthlyFooter" - minHeight={0} - updateOnContent={false} - updateOnResize={true} - > - <CardFooter> - <div - className="hidden" + <CardHeader> + <CardTitle> + <Title + headingLevel="h2" + size="md" /> - </CardFooter> - </MinHeight> + </CardTitle> + </CardHeader> + <CardBody> + <div /> + </CardBody> + <CardFooter> + <div /> + </CardFooter> </Card> - </FlexItem> - </Flex> - <Flex - alignSelf={ - { - "default": "alignSelfStretch", - } - } - direction={ - { - "default": "column", - } - } - flex={ - { - "default": "flex_3", - } - } - > - <FlexItem + </div> + </div> + <div> + <div className="curiosity-usage-graph__totals-graph-column" /> - </Flex> -</Flex> + </div> +</div> `; diff --git a/src/components/graphCard/graphCard.js b/src/components/graphCard/graphCard.js index c2ebc0887..595d45773 100644 --- a/src/components/graphCard/graphCard.js +++ b/src/components/graphCard/graphCard.js @@ -22,14 +22,20 @@ const GraphCard = ({ isDisabled, useParseFiltersSettings: useAliasParseFiltersSe return ( <React.Fragment> - {(groupedFiltersSettings && ( - <GraphCardContext.Provider value={groupedFiltersSettings}> + {(groupedFiltersSettings?.settings?.metrics?.length && ( + <GraphCardContext.Provider + key={`graphCard_grouped-${groupedFiltersSettings?.settings?.metrics?.[0]?.id}`} + value={groupedFiltersSettings} + > <GraphCardChart /> </GraphCardContext.Provider> )) || null} {standaloneFiltersSettings?.map(filtersSettings => ( - <GraphCardContext.Provider key={`graphCard_${filtersSettings?.settings?.metric?.id}`} value={filtersSettings}> + <GraphCardContext.Provider + key={`graphCard_standalone-${filtersSettings?.settings?.metric?.id}`} + value={filtersSettings} + > <GraphCardMetricTotals> <GraphCardChart /> </GraphCardMetricTotals> diff --git a/src/components/graphCard/graphCardChart.js b/src/components/graphCard/graphCardChart.js index c33dce6fc..f1cef4083 100644 --- a/src/components/graphCard/graphCardChart.js +++ b/src/components/graphCard/graphCardChart.js @@ -52,26 +52,24 @@ const GraphCardChart = ({ const { pending, error, dataSets = [] } = useAliasGetMetrics(); return ( - <Card className="curiosity-usage-graph"> - <MinHeight key="headerMinHeight"> - <CardHeader> - <CardTitle> - <Title headingLevel="h2" size="lg"> - {t('curiosity-graph.cardHeading', { context: (isStandalone && metric?.id) || productId })} - <GraphCardChartTitleTooltip /> - - - {updatedActionDisplay && ( - - - - {updatedActionDisplay} - - - - )} - - + + + + + {t('curiosity-graph.cardHeading', { context: (isStandalone && metric?.id) || productId })} + <GraphCardChartTitleTooltip /> + + + {updatedActionDisplay && ( + + + + {updatedActionDisplay} + + + + )} +
diff --git a/src/components/graphCard/graphCardMetricTotals.js b/src/components/graphCard/graphCardMetricTotals.js index b53fdab46..9d8444798 100644 --- a/src/components/graphCard/graphCardMetricTotals.js +++ b/src/components/graphCard/graphCardMetricTotals.js @@ -1,11 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Card, CardBody, CardFooter, CardTitle, Flex, FlexItem } from '@patternfly/react-core'; +import { Card, CardBody, CardFooter, CardHeader, CardTitle, Title } from '@patternfly/react-core'; import moment from 'moment'; import _camelCase from 'lodash/camelCase'; import { useProductGraphTallyQuery } from '../productView/productViewContext'; import { useMetricsSelector } from './graphCardContext'; -import { MinHeight } from '../minHeight/minHeight'; import { Loader, SkeletonSize } from '../loader/loader'; import { dateHelpers, helpers } from '../../common'; import { toolbarFieldOptions } from '../toolbar/toolbarFieldRangedMonthly'; @@ -50,102 +49,110 @@ const GraphCardMetricTotals = ({ const dailyValue = isCurrent ? currentValue : lastValue; return ( - - - +
+
+
- - {t('curiosity-graph.cardHeadingMetric', { - context: ['dailyTotal', id], - month: selectedMonth - })} - - - -
+ + + {pending && <Loader variant="skeleton" skeletonProps={{ size: SkeletonSize.lg }} />} {fulfilled && - t( - 'curiosity-graph.cardBodyMetric', - { - context: ['total', dailyHasData && id], - total: helpers - .numberDisplay(dailyValue) - ?.format({ - average: true, - mantissa: 5, - trimMantissa: true, - lowPrecision: false - }) - ?.toUpperCase() - }, - [<strong title={dailyValue} aria-label={dailyValue} />] - )} - </div> - </CardBody> - </MinHeight> - <MinHeight key="currentFooter"> - <CardFooter> - <div className={(!dailyHasData && 'hidden') || ''}> - {fulfilled && - dailyDate && - t('curiosity-graph.cardFooterMetric', { - date: moment.utc(dailyDate).format(dateHelpers.timestampUTCTimeFormats.yearTimeShort) + t('curiosity-graph.cardHeadingMetric', { + context: ['dailyTotal', id], + month: selectedMonth })} - </div> - </CardFooter> - </MinHeight> + + + + +
+ {pending && } + {fulfilled && + t( + 'curiosity-graph.cardBodyMetric', + { + context: ['total', dailyHasData && id], + total: helpers + .numberDisplay(dailyValue) + ?.format({ + average: true, + mantissa: 5, + trimMantissa: true, + lowPrecision: false + }) + ?.toUpperCase() + }, + [] + )} +
+
+ +
+ {pending && } + {fulfilled && + dailyDate && + t('curiosity-graph.cardFooterMetric', { + date: moment.utc(dailyDate).format(dateHelpers.timestampUTCTimeFormats.yearTimeShort) + })} +
+
- - {t('curiosity-graph.cardHeadingMetric', { - context: ['monthlyTotal', id], - month: selectedMonth - })} - - - -
+ + + {pending && <Loader variant="skeleton" skeletonProps={{ size: SkeletonSize.lg }} />} {fulfilled && - t( - 'curiosity-graph.cardBodyMetric', - { - context: ['total', monthlyHasData && id], - total: helpers - .numberDisplay(monthlyValue) - ?.format({ average: true, mantissa: 5, trimMantissa: true, lowPrecision: false }) - ?.toUpperCase() - }, - [<strong title={monthlyValue} aria-label={monthlyValue} />] - )} - </div> - </CardBody> - </MinHeight> - <MinHeight key="totalMonthlyFooter"> - <CardFooter> - <div className={(!monthlyHasData && 'hidden') || ''}> - {fulfilled && - monthlyDate && - t('curiosity-graph.cardFooterMetric', { - date: moment.utc(monthlyDate).format(dateHelpers.timestampUTCTimeFormats.yearTimeShort) + t('curiosity-graph.cardHeadingMetric', { + context: ['monthlyTotal', id], + month: selectedMonth })} - </div> - </CardFooter> - </MinHeight> + + + + +
+ {pending && } + {fulfilled && + t( + 'curiosity-graph.cardBodyMetric', + { + context: ['total', monthlyHasData && id], + total: helpers + .numberDisplay(monthlyValue) + ?.format({ average: true, mantissa: 5, trimMantissa: true, lowPrecision: false }) + ?.toUpperCase() + }, + [] + )} +
+
+ +
+ {pending && } + {fulfilled && + monthlyDate && + t('curiosity-graph.cardFooterMetric', { + date: moment.utc(monthlyDate).format(dateHelpers.timestampUTCTimeFormats.yearTimeShort) + })} +
+
- - - - {children} - - +
+
+
+
{children}
+
+
); }; diff --git a/src/styles/_usage-graph.scss b/src/styles/_usage-graph.scss index 20bfe7ecb..0a006757c 100644 --- a/src/styles/_usage-graph.scss +++ b/src/styles/_usage-graph.scss @@ -1,15 +1,8 @@ .curiosity { - .curiosity-usage-graph { - .pf-c-toolbar { - padding-bottom: inherit; - padding-top: inherit; - - &__content { - padding-left: inherit; - padding-right: inherit; - } - } - + /** + * Styling for graphCard component + */ + &-usage-graph { .pf-c-card { &__header { border-bottom: var(--pf-global--BorderWidth--sm) solid var(--pf-global--BorderColor--100); @@ -21,7 +14,6 @@ &__title { flex-grow: 1; padding: 0; - padding-right: var(--pf-c-card__actions--PaddingLeft); } &__actions { @@ -40,31 +32,6 @@ } } - &__total { - padding-right: var(--pf-global--spacer--sm); - text-align: right; - white-space: normal; - word-break: break-word; - } - - &__legend-item-wrapper { - > .pf-c-button { - padding-left: 0; - padding-right: 0; - } - } - - @media (min-width: $pf-global--breakpoint--lg) { - &__legend-item-wrapper { - &:first-child { - padding-left: 0; - } - &:last-child { - padding-right: 0; - } - } - } - &__tooltip { color: var(--pf-global--Color--light-100); font-size: 0.9em; @@ -96,81 +63,158 @@ } } + &__legend-item-wrapper { + > .pf-c-button { + padding-left: 0; + padding-right: 0; + } + + @media (min-width: $pf-global--breakpoint--lg) { + &:first-child { + padding-left: 0; + } + &:last-child { + padding-right: 0; + } + } + } + &__totals { - /** - * ToDo: consider relocating margin into page-layout once margin is restored to all product layouts - */ + background-color: var(--pf-global--BackgroundColor--100); + display: flex; + flex-direction: column; + flex-wrap: wrap; + justify-content: center; margin-left: var(--pf-global--spacer--md); margin-right: var(--pf-global--spacer--md); margin-top: var(--pf-global--spacer--md); + @media (min-width: $pf-global--breakpoint--md) { + flex-direction: row; + justify-content: start; + } + &:last-child { margin-bottom: var(--pf-global--spacer--md); }; - &-column { - height: 100%; + > div { + display: flex; - > :first-child { - margin-bottom: var(--pf-global--spacer--md); + &:first-child { + @media (max-width: $pf-global--breakpoint--md) { + align-self: stretch; + } + @media (min-width: $pf-global--breakpoint--md) { + width: 25%; + min-width: 260px; + } } - &-card { - min-height: calc(50% - var(--pf-global--spacer--md) / 2); - overflow: hidden; + &:last-child { + @media (min-width: $pf-global--breakpoint--md) { + flex: 3; + } + } + } + + &-column { + margin-left: var(--pf-global--spacer--sm); + margin-right: var(--pf-global--spacer--sm); + margin-top: var(--pf-global--spacer--lg); + margin-bottom: var(--pf-global--spacer--lg); + width: 100%; + + .pf-c-card { + height: calc(50%); text-align: center; + width: 100%; + + &:first-child { + border-bottom: var(--pf-global--BorderWidth--sm) solid var(--pf-global--BorderColor--100); + padding-bottom: calc(var(--pf-global--spacer--lg) / 2); + } - .ins-c-skeleton { - width: 100%; + &:last-child { + padding-top: calc(var(--pf-global--spacer--lg) / 2); } - .pf-c-card__title { - padding: var(--pf-global--spacer--md); - padding-bottom: 0; + &__header { + display: block; + padding-top: inherit; } - .pf-c-card__body { - padding: var(--pf-global--spacer--md); + &__title { + h2, h3 { + line-height: var(--pf-global--FontSize--3xl); + } + } + &__body { strong { display: block; font-size: var(--pf-global--FontSize--3xl); } } - .pf-c-card__footer { + &__footer { color: var(--pf-global--palette--black-500); font-size: var(--pf-global--FontSize--xs); - padding: var(--pf-global--spacer--md); - padding-top: 0; } } } &-graph-column { - height: 100%; - - .curiosity-usage-graph { - height: 100%; + margin-bottom: var(--pf-global--spacer--lg); + margin-right: var(--pf-global--spacer--sm); + margin-top: var(--pf-global--spacer--lg); + padding-left: var(--pf-global--spacer--sm); + width: 100%; + + @media (min-width: $pf-global--breakpoint--md) { + padding-left: var(--pf-global--spacer--lg); + border-left: var(--pf-global--BorderWidth--sm) solid var(--pf-global--BorderColor--100); } .pf-c-card { &__header { + align-items: flex-start; border-bottom-width: 0; - padding-bottom: 0; + padding: inherit; + } + + &__title { + } + + &__actions { } &__body { - padding-top: 0; + padding: inherit; } } } } + + .pf-c-toolbar { + padding-bottom: inherit; + padding-top: inherit; + + &__content { + padding-left: inherit; + padding-right: inherit; + } + } } - .curiosity-chartarea { + + /** + * Styling for general chart component Victory wrapper. + * Pixels are used as related to SVG display dimensions. + */ + &-chartarea { &__legend { - background-color: var(--pf-global--BackgroundColor--100);; + background-color: var(--pf-global--BackgroundColor--100); margin-top: -35px; position: relative; @@ -209,7 +253,8 @@ } transition: width 1s ease-in-out, left 1s ease-in-out; - background-color: #000; + background-color: var(--pf-global--palette--black-1000); + color: var(--pf-global--Color--light-100); margin-left: 10px; margin-right: 15px; @@ -217,7 +262,7 @@ &-right:after { border-width: 10px; border-style: solid; - border-color: transparent #000 transparent transparent; + border-color: transparent var(--pf-global--palette--black-1000) transparent transparent; content: ""; left: -9px; //-10px Compensate for Firefox pixel diff, match margin-left margin-left: 0; @@ -227,7 +272,7 @@ } &-right:after { - border-color: transparent transparent transparent #000; + border-color: transparent transparent transparent var(--pf-global--palette--black-1000); left: calc(100% - 16px); //-15px Compensate for Firefox pixel diff, match margin-right margin-left: 0; } diff --git a/tests/__snapshots__/dist.test.js.snap b/tests/__snapshots__/dist.test.js.snap index d1fee1640..974d41eac 100644 --- a/tests/__snapshots__/dist.test.js.snap +++ b/tests/__snapshots__/dist.test.js.snap @@ -131,8 +131,8 @@ exports[`Build distribution should match a specific file output 1`] = ` "./dist/js/5250*txt", "./dist/js/5394*js", "./dist/js/5876*js", + "./dist/js/5925*js", "./dist/js/5993*js", - "./dist/js/608*js", "./dist/js/6402*js", "./dist/js/6706*js", "./dist/js/6706*txt", @@ -211,8 +211,8 @@ exports[`Build distribution should match a specific file output 1`] = ` "./dist/sourcemaps/5250*map", "./dist/sourcemaps/5394*map", "./dist/sourcemaps/5876*map", + "./dist/sourcemaps/5925*map", "./dist/sourcemaps/5993*map", - "./dist/sourcemaps/608*map", "./dist/sourcemaps/6402*map", "./dist/sourcemaps/6706*map", "./dist/sourcemaps/6816*map",