updated components import
This commit is contained in:
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { makeStyles, useTheme } from '@material-ui/core';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { Circle } from 'rc-progress';
|
||||
import React, { FC } from 'react';
|
||||
|
||||
const useStyles = makeStyles<BackstageTheme>(theme => ({
|
||||
root: {
|
||||
position: 'relative',
|
||||
lineHeight: 0,
|
||||
},
|
||||
overlay: {
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -60%)',
|
||||
fontSize: 45,
|
||||
fontWeight: 'bold',
|
||||
color: theme.palette.textContrast,
|
||||
},
|
||||
circle: {
|
||||
width: '80%',
|
||||
transform: 'translate(10%, 0)',
|
||||
},
|
||||
colorUnknown: {},
|
||||
}));
|
||||
|
||||
type Props = {
|
||||
value: number;
|
||||
fractional?: boolean;
|
||||
inverse?: boolean;
|
||||
unit?: string;
|
||||
max?: number;
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
fractional: true,
|
||||
inverse: false,
|
||||
unit: '%',
|
||||
max: 100,
|
||||
};
|
||||
|
||||
export function getProgressColor(
|
||||
palette: BackstageTheme['palette'],
|
||||
value: number,
|
||||
inverse?: boolean,
|
||||
max?: number,
|
||||
) {
|
||||
if (isNaN(value)) {
|
||||
return '#ddd';
|
||||
}
|
||||
|
||||
const actualMax = max ? max : defaultProps.max;
|
||||
const actualValue = inverse ? actualMax - value : value;
|
||||
|
||||
if (actualValue < actualMax / 3) {
|
||||
return palette.status.error;
|
||||
} else if (actualValue < actualMax * (2 / 3)) {
|
||||
return palette.status.warning;
|
||||
}
|
||||
|
||||
return palette.status.ok;
|
||||
}
|
||||
|
||||
export const CircleGauge: FC<Props> = props => {
|
||||
const classes = useStyles(props);
|
||||
const theme = useTheme<BackstageTheme>();
|
||||
const { value, fractional, inverse, unit, max } = {
|
||||
...defaultProps,
|
||||
...props,
|
||||
};
|
||||
|
||||
const asPercentage = fractional ? Math.round(value * max) : value;
|
||||
const asActual = max !== 100 ? Math.round(value) : asPercentage;
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<Circle
|
||||
strokeLinecap="butt"
|
||||
percent={asPercentage}
|
||||
strokeWidth={12}
|
||||
trailWidth={12}
|
||||
strokeColor={getProgressColor(theme.palette, asActual, inverse, max)}
|
||||
className={classes.circle}
|
||||
/>
|
||||
<div className={classes.overlay}>
|
||||
{isNaN(value) ? 'N/A' : `${asActual}${unit}`}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { wrapInTestApp } from '@backstage/test-utils';
|
||||
import { CircleProgress, getProgressColor } from './CircleProgress';
|
||||
|
||||
describe('<CircleProgress />', () => {
|
||||
it('renders without exploding', () => {
|
||||
const { getByText } = render(
|
||||
wrapInTestApp(<CircleProgress value={10} fractional={false} />),
|
||||
);
|
||||
getByText('10%');
|
||||
});
|
||||
it('handles fractional prop', () => {
|
||||
const { getByText } = render(
|
||||
wrapInTestApp(<CircleProgress value={0.1} fractional />),
|
||||
);
|
||||
getByText('10%');
|
||||
});
|
||||
|
||||
it('handles max prop', () => {
|
||||
const { getByText } = render(
|
||||
wrapInTestApp(<CircleProgress value={1} max={10} fractional={false} />),
|
||||
);
|
||||
getByText('1%');
|
||||
});
|
||||
|
||||
it('handles unit prop', () => {
|
||||
const { getByText } = render(
|
||||
wrapInTestApp(<CircleProgress value={10} fractional={false} unit="m" />),
|
||||
);
|
||||
getByText('10m');
|
||||
});
|
||||
|
||||
const ok = '#111';
|
||||
const warning = '#222';
|
||||
const error = '#333';
|
||||
const palette = { status: { ok, warning, error } };
|
||||
|
||||
it('colors the progress correctly', () => {
|
||||
expect(getProgressColor(palette)).toBe('#ddd');
|
||||
expect(getProgressColor(palette, 10)).toBe(error);
|
||||
expect(getProgressColor(palette, 50)).toBe(warning);
|
||||
expect(getProgressColor(palette, 90)).toBe(ok);
|
||||
});
|
||||
|
||||
it('colors the inverse progress correctly', () => {
|
||||
expect(getProgressColor(palette)).toBe('#ddd');
|
||||
expect(getProgressColor(palette, 10, true)).toBe(ok);
|
||||
expect(getProgressColor(palette, 50, true)).toBe(warning);
|
||||
expect(getProgressColor(palette, 90, true)).toBe(error);
|
||||
});
|
||||
});
|
||||
@@ -18,7 +18,7 @@ import React, { FC } from 'react';
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import { InfoCard } from '../../layout/InfoCard';
|
||||
import { BottomLinkProps } from '../../layout/BottomLink';
|
||||
import { CircleProgress } from './CircleGauge';
|
||||
import { GaugeProgress } from './GaugeProgress';
|
||||
|
||||
type Props = {
|
||||
title: string;
|
||||
@@ -48,7 +48,7 @@ export const GaugeCard: FC<Props> = props => {
|
||||
deepLink={deepLink}
|
||||
variant={variant}
|
||||
>
|
||||
<CircleProgress value={progress} />
|
||||
<GaugeProgress value={progress} />
|
||||
</InfoCard>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { LinearGauge } from './LinearGauge';
|
||||
|
||||
const containerStyle = { width: 300 };
|
||||
|
||||
export default {
|
||||
title: 'LinearGauge',
|
||||
component: LinearGauge,
|
||||
};
|
||||
|
||||
export const Default = () => (
|
||||
<div style={containerStyle}>
|
||||
<LinearGauge value={0.8} />
|
||||
</div>
|
||||
);
|
||||
|
||||
export const MediumProgress = () => (
|
||||
<div style={containerStyle}>
|
||||
<LinearGauge value={0.5} />
|
||||
</div>
|
||||
);
|
||||
|
||||
export const LowProgress = () => (
|
||||
<div style={containerStyle}>
|
||||
<LinearGauge value={0.2} />
|
||||
</div>
|
||||
);
|
||||
@@ -19,7 +19,7 @@ import { Tooltip, useTheme } from '@material-ui/core';
|
||||
// @ts-ignore
|
||||
import { Line } from 'rc-progress';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { getProgressColor } from './CircleGauge';
|
||||
import { getProgressColor } from './GaugeProgress';
|
||||
|
||||
type Props = {
|
||||
/**
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { ProgressCard } from './GaugeCard';
|
||||
import { Grid } from '@material-ui/core';
|
||||
|
||||
const linkInfo = { title: 'Go to XYZ Location', link: '#' };
|
||||
|
||||
export default {
|
||||
title: 'Progress Card',
|
||||
component: ProgressCard,
|
||||
};
|
||||
|
||||
export const Default = () => (
|
||||
<Grid container spacing={2}>
|
||||
<Grid item>
|
||||
<ProgressCard title="Progress" progress={0.3} />
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<ProgressCard title="Progress" progress={0.57} />
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<ProgressCard title="Progress" progress={0.89} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
|
||||
export const Subhead = () => (
|
||||
<Grid container spacing={2}>
|
||||
<Grid item>
|
||||
<ProgressCard
|
||||
title="Progress"
|
||||
subheader="With a subheader"
|
||||
progress={0.3}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<ProgressCard
|
||||
title="Progress"
|
||||
subheader="With a subheader"
|
||||
progress={0.57}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<ProgressCard
|
||||
title="Progress"
|
||||
subheader="With a subheader"
|
||||
progress={0.89}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
|
||||
export const LinkInFooter = () => (
|
||||
<Grid container spacing={2}>
|
||||
<Grid item>
|
||||
<ProgressCard title="Progress" deepLink={linkInfo} progress={0.3} />
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<ProgressCard title="Progress" deepLink={linkInfo} progress={0.57} />
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<ProgressCard title="Progress" deepLink={linkInfo} progress={0.89} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { wrapInTestApp } from '@backstage/test-utils';
|
||||
|
||||
import { ProgressCard } from './ProgressCard';
|
||||
|
||||
const minProps = { title: 'Tingle upgrade', progress: 0.12 };
|
||||
|
||||
describe('<ProgressCard />', () => {
|
||||
it('renders without exploding', () => {
|
||||
const { getByText } = render(wrapInTestApp(<ProgressCard {...minProps} />));
|
||||
expect(getByText(/Tingle.*/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders progress and title', () => {
|
||||
const { getByText } = render(wrapInTestApp(<ProgressCard {...minProps} />));
|
||||
expect(getByText(/Tingle.*/)).toBeInTheDocument();
|
||||
expect(getByText(/12%.*/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not render deepLink', () => {
|
||||
const { queryByText } = render(
|
||||
wrapInTestApp(<ProgressCard {...minProps} />),
|
||||
);
|
||||
expect(queryByText('View more')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('handles invalid numbers', () => {
|
||||
const badProps = { title: 'Tingle upgrade', progress: 'hejjo' };
|
||||
const { getByText } = render(wrapInTestApp(<ProgressCard {...badProps} />));
|
||||
expect(getByText(/N\/A.*/)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -15,5 +15,5 @@
|
||||
*/
|
||||
|
||||
export { GaugeCard } from './GaugeCard';
|
||||
export { CircleGauge } from './CircleGauge';
|
||||
export { GaugeProgress } from './GaugeProgress';
|
||||
export { LinearGauge } from './LinearGauge';
|
||||
|
||||
Reference in New Issue
Block a user