Add top panel tabs
This commit is contained in:
@@ -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}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user