Add top panel tabs

This commit is contained in:
Brenda Sukh
2020-11-23 18:47:32 -05:00
parent b9705638e9
commit 2ca1cc32aa
2 changed files with 115 additions and 39 deletions
@@ -14,10 +14,19 @@
* limitations under the License.
*/
import React from 'react';
import { Box, Card, CardContent, Divider, useTheme } from '@material-ui/core';
import React, { useState } from 'react';
import {
Box,
Card,
CardContent,
Divider,
useTheme,
Tab,
Tabs,
} from '@material-ui/core';
import { CostGrowth } from '../CostGrowth';
import { CostOverviewChart } from './CostOverviewChart';
import { CostOverviewByProduct } from './CostOverviewByProduct';
import { CostOverviewHeader } from './CostOverviewHeader';
import { LegendItem } from '../LegendItem';
import { MetricSelect } from '../MetricSelect';
@@ -34,6 +43,7 @@ import { formatPercent } from '../../utils/formatters';
import { findAlways } from '../../utils/assert';
import { getComparedChange } from '../../utils/change';
import { Cost, CostInsightsTheme, MetricData } from '../../types';
import { useOverviewTabsStyles } from '../../utils/styles';
export type CostOverviewCardProps = {
dailyCostData: Cost;
@@ -47,6 +57,8 @@ export const CostOverviewCard = ({
const theme = useTheme<CostInsightsTheme>();
const config = useConfig();
const lastCompleteBillingDate = useLastCompleteBillingDate();
const [tabIndex, setTabIndex] = useState(0);
const { ScrollAnchor } = useScroll(DefaultNavigation.CostOverviewCard);
const { setDuration, setProject, setMetric, ...filters } = useFilters(
mapFiltersToProps,
@@ -63,53 +75,91 @@ export const CostOverviewCard = ({
lastCompleteBillingDate,
)
: null;
const styles = useOverviewTabsStyles(theme);
const tabs = [
{ id: 'overview', label: 'OVERVIEW' },
{ id: 'breakdown', label: 'BREAKDOWN BY PRODUCT' },
];
const OverviewTabs = () => {
return (
<>
<Tabs
indicatorColor="primary"
onChange={(_, index) => setTabIndex(index)}
value={tabIndex}
>
{tabs.map((tab, index) => (
<Tab
className={styles.default}
label={tab.label}
key={tab.id}
value={index}
classes={{ selected: styles.selected }}
/>
))}
</Tabs>
</>
);
};
const OverviewLegend = () => {
return (
<Box display="flex" flexDirection="row">
<Box mr={2}>
<LegendItem title="Cost Trend" markerColor={theme.palette.blue}>
{formatPercent(dailyCostData.change!.ratio)}
</LegendItem>
</Box>
{metric && metricData && comparedChange && (
<>
<Box mr={2}>
<LegendItem
title={`${metric.name} Trend`}
markerColor={theme.palette.magenta}
>
{formatPercent(metricData.change.ratio)}
</LegendItem>
</Box>
<LegendItem
title={comparedChange.ratio <= 0 ? 'Your Savings' : 'Your Excess'}
>
<CostGrowth change={comparedChange} duration={filters.duration} />
</LegendItem>
</>
)}
</Box>
);
};
return (
<Card style={{ position: 'relative' }}>
<ScrollAnchor behavior="smooth" top={-20} />
<CardContent>
<CostOverviewHeader title="Cloud Cost">
{dailyCostData.groupedCosts && <OverviewTabs />}
<CostOverviewHeader
title={tabIndex === 0 ? 'Cloud Cost' : 'Cloud Cost By Product'}
>
<PeriodSelect duration={filters.duration} onSelect={setDuration} />
</CostOverviewHeader>
<Divider />
<Box my={1} display="flex" flexDirection="column">
<Box display="flex" flexDirection="row">
<Box mr={2}>
<LegendItem title="Cost Trend" markerColor={theme.palette.blue}>
{formatPercent(dailyCostData.change.ratio)}
</LegendItem>
</Box>
{metric && metricData && comparedChange && (
<>
<Box mr={2}>
<LegendItem
title={`${metric.name} Trend`}
markerColor={theme.palette.magenta}
>
{formatPercent(metricData.change.ratio)}
</LegendItem>
</Box>
<LegendItem
title={
comparedChange.ratio <= 0 ? 'Your Savings' : 'Your Excess'
}
>
<CostGrowth
change={comparedChange}
duration={filters.duration}
/>
</LegendItem>
</>
)}
</Box>
<CostOverviewChart
dailyCostData={dailyCostData}
metric={metric}
metricData={metricData}
/>
<Box ml={2} my={1} display="flex" flexDirection="column">
{tabIndex === 0 ? (
<>
<OverviewLegend />
<CostOverviewChart
dailyCostData={dailyCostData}
metric={metric}
metricData={metricData}
/>
</>
) : (
<CostOverviewByProduct dailyCostData={dailyCostData} />
)}
</Box>
<Box display="flex" justifyContent="flex-end" alignItems="center">
{config.metrics.length && (
{config.metrics.length && tabIndex === 0 && (
<MetricSelect
metric={filters.metric}
metrics={config.metrics}
+26
View File
@@ -24,6 +24,19 @@ import {
import { BackstageTheme } from '@backstage/theme';
import { CostInsightsTheme, CostInsightsThemeOptions } from '../types';
export const DataVizColors = [
'#509BF5',
'#FF6437',
'#4B917D',
'#F573A0',
'#F59B23',
'#B49BC8',
'#C39687',
'#A0C3D2',
'#FFC864',
'#BABABA',
];
export const costInsightsLightTheme = {
palette: {
blue: '#509AF5',
@@ -87,6 +100,19 @@ export const useCostOverviewStyles = (theme: CostInsightsTheme) => ({
},
});
export const useOverviewTabsStyles = makeStyles<CostInsightsTheme>(
(theme: CostInsightsTheme) => ({
default: {
padding: theme.spacing(2, 2),
fontWeight: 'bold',
color: theme.palette.text.secondary,
},
selected: {
color: theme.palette.text.primary,
},
}),
);
export const useBarChartStyles = (theme: CostInsightsTheme) => ({
axis: {
fill: theme.palette.text.primary,