Prettifying

Signed-off-by: Erik Engervall <erik.engervall@gmail.com>
This commit is contained in:
Erik Engervall
2021-04-20 19:04:22 +02:00
parent 725d09af25
commit cba751d504
41 changed files with 282 additions and 178 deletions
@@ -32,7 +32,7 @@ import { InfoCardPlus } from './components/InfoCardPlus';
import { isProjectValid } from './helpers/isProjectValid';
import { PluginApiClientContext } from './contexts/PluginApiClientContext';
import { ProjectContext, Project } from './contexts/ProjectContext';
import { RepoDetailsForm } from './cards/projectForm/RepoDetailsForm';
import { RepoDetailsForm } from './cards/RepoDetailsForm/RepoDetailsForm';
import { useQueryHandler } from './hooks/useQueryHandler';
import { useStyles } from './styles/styles';
@@ -20,7 +20,7 @@ import { readGitHubIntegrationConfigs } from '@backstage/integration';
import { CalverTagParts } from '../helpers/tagParts/getCalverTagParts';
import { DISABLE_CACHE } from '../constants/constants';
import { getRcGitHubInfo } from '../cards/createRc/getRcGitHubInfo';
import { getRcGitHubInfo } from '../cards/CreateRc/helpers/getRcGitHubInfo';
import { Project } from '../contexts/ProjectContext';
import { SemverTagParts } from '../helpers/tagParts/getSemverTagParts';
@@ -15,18 +15,17 @@
*/
import React, { useState } from 'react';
import { useAsync } from 'react-use';
import { ErrorBoundary } from '@backstage/core';
import { Alert } from '@material-ui/lab';
import { CenteredCircularProgress } from '../components/CenteredCircularProgress';
import { CreateRc } from './createRc/CreateRc';
import { getGitHubBatchInfo } from '../sideEffects/getGitHubBatchInfo';
import { CreateRc } from './CreateRc/CreateRc';
import { GitHubReleaseManagerProps } from '../GitHubReleaseManager';
import { Info } from './info/Info';
import { Patch } from './patchRc/Patch';
import { PromoteRc } from './promoteRc/PromoteRc';
import { Info } from './Info/Info';
import { Patch } from './Patch/Patch';
import { PromoteReleaseCandidate } from './PromoteReleaseCandidate/PromoteRc';
import { RefetchContext } from '../contexts/RefetchContext';
import { useGetGitHubBatchInfo } from '../hooks/useGetGitHubBatchInfo';
import { usePluginApiClientContext } from '../contexts/PluginApiClientContext';
import { useProjectContext } from '../contexts/ProjectContext';
import { useVersioningStrategyMatchesRepoTags } from '../hooks/useVersioningStrategyMatchesRepoTags';
@@ -39,10 +38,11 @@ export function Cards({
const pluginApiClient = usePluginApiClientContext();
const project = useProjectContext();
const [refetchTrigger, setRefetchTrigger] = useState(0);
const gitHubBatchInfo = useAsync(
getGitHubBatchInfo({ project, pluginApiClient }),
[project, refetchTrigger],
);
const { gitHubBatchInfo } = useGetGitHubBatchInfo({
pluginApiClient,
project,
refetchTrigger,
});
const { versioningStrategyMatches } = useVersioningStrategyMatchesRepoTags({
latestReleaseTagName: gitHubBatchInfo.value?.latestRelease?.tagName,
@@ -111,7 +111,7 @@ export function Cards({
)}
{!components?.promoteRc?.omit && (
<PromoteRc
<PromoteReleaseCandidate
latestRelease={gitHubBatchInfo.value.latestRelease}
successCb={components?.promoteRc?.successCb}
/>
@@ -21,8 +21,8 @@ import {
mockApiClient,
mockBumpedTag,
mockCalverProject,
mockReleaseCandidateCalver,
mockReleaseBranch,
mockReleaseCandidateCalver,
mockReleaseVersionCalver,
mockTagParts,
} from '../../test-helpers/test-helpers';
@@ -33,7 +33,7 @@ jest.mock('../../contexts/PluginApiClientContext', () => ({
jest.mock('../../contexts/ProjectContext', () => ({
useProjectContext: jest.fn(() => mockCalverProject),
}));
jest.mock('./sideEffects/usePatch', () => ({
jest.mock('./hooks/usePatch', () => ({
usePatch: () => ({
run: jest.fn(),
responseSteps: [],
@@ -40,12 +40,12 @@ import {
import { CalverTagParts } from '../../helpers/tagParts/getCalverTagParts';
import { CenteredCircularProgress } from '../../components/CenteredCircularProgress';
import { ComponentConfigPatch } from '../../types/types';
import { Dialog } from '../../components/Dialog';
import { Differ } from '../../components/Differ';
import { GitHubReleaseManagerError } from '../../errors/GitHubReleaseManagerError';
import { ResponseStepDialog } from '../../components/ResponseStepDialog/ResponseStepDialog';
import { SemverTagParts } from '../../helpers/tagParts/getSemverTagParts';
import { TEST_IDS } from '../../test-helpers/test-ids';
import { usePatch } from './sideEffects/usePatch';
import { usePatch } from './hooks/usePatch';
import { usePluginApiClientContext } from '../../contexts/PluginApiClientContext';
import { useProjectContext } from '../../contexts/ProjectContext';
import { useStyles } from '../../styles/styles';
@@ -91,7 +91,7 @@ export const PatchBody = ({
};
});
const { run, responseSteps, progress } = usePatch({
const { progress, responseSteps, run, runInvoked } = usePatch({
bumpedTag,
latestRelease,
pluginApiClient,
@@ -101,7 +101,7 @@ export const PatchBody = ({
});
if (responseSteps.length > 0) {
return (
<Dialog
<ResponseStepDialog
progress={progress}
responseSteps={responseSteps}
title="Patch Release Candidate"
@@ -190,7 +190,7 @@ export const PatchBody = ({
<ListItem
disabled={
progress > 0 || commitExistsOnReleaseBranch || hasNoParent
runInvoked || commitExistsOnReleaseBranch || hasNoParent
}
role={undefined}
dense
@@ -238,7 +238,11 @@ export const PatchBody = ({
<ListItemSecondaryAction>
<IconButton
aria-label="commit"
disabled={commitExistsOnReleaseBranch || !releaseBranch}
disabled={
runInvoked ||
commitExistsOnReleaseBranch ||
!releaseBranch
}
onClick={() => {
const repoPath = pluginApiClient.getRepoPath({
owner: project.owner,
@@ -17,13 +17,13 @@
import { useEffect, useState } from 'react';
import { useAsync, useAsyncFn } from 'react-use';
import { ComponentConfigPatch } from '../../../types/types';
import { CalverTagParts } from '../../../helpers/tagParts/getCalverTagParts';
import {
GetLatestReleaseResult,
GetRecentCommitsResultSingle,
IPluginApiClient,
} from '../../../api/PluginApiClient';
import { CalverTagParts } from '../../../helpers/tagParts/getCalverTagParts';
import { ComponentConfigPatch, CardHook } from '../../../types/types';
import { Project } from '../../../contexts/ProjectContext';
import { SemverTagParts } from '../../../helpers/tagParts/getSemverTagParts';
import { useResponseSteps } from '../../../hooks/useResponseSteps';
@@ -45,7 +45,7 @@ export function usePatch({
project,
tagParts,
successCb,
}: Patch) {
}: Patch): CardHook<GetRecentCommitsResultSingle> {
const {
responseSteps,
addStepToResponseSteps,
@@ -345,8 +345,13 @@ export function usePatch({
}, [TOTAL_STEPS, responseSteps.length]);
return {
run,
responseSteps,
progress,
responseSteps,
run,
runInvoked: Boolean(
releaseBranchRes.loading ||
releaseBranchRes.value ||
releaseBranchRes.error,
),
};
}
@@ -29,11 +29,13 @@ jest.mock('./PromoteRcBody', () => ({
),
}));
import { PromoteRc } from './PromoteRc';
import { PromoteReleaseCandidate } from './PromoteRc';
describe('PromoteRc', () => {
it('return early if no latest release present', () => {
const { getByTestId } = render(<PromoteRc latestRelease={null} />);
const { getByTestId } = render(
<PromoteReleaseCandidate latestRelease={null} />,
);
expect(
getByTestId(TEST_IDS.components.noLatestRelease),
@@ -42,7 +44,7 @@ describe('PromoteRc', () => {
it('should display not-rc warning', () => {
const { getByTestId } = render(
<PromoteRc latestRelease={mockReleaseVersionCalver} />,
<PromoteReleaseCandidate latestRelease={mockReleaseVersionCalver} />,
);
expect(getByTestId(TEST_IDS.promoteRc.notRcWarning)).toBeInTheDocument();
@@ -50,7 +52,7 @@ describe('PromoteRc', () => {
it('should display PromoteRcBody', () => {
const { getByTestId } = render(
<PromoteRc latestRelease={mockReleaseCandidateCalver} />,
<PromoteReleaseCandidate latestRelease={mockReleaseCandidateCalver} />,
);
expect(
@@ -18,20 +18,23 @@ import React from 'react';
import { Alert, AlertTitle } from '@material-ui/lab';
import { Typography } from '@material-ui/core';
import { ComponentConfigPromoteRc } from '../../types/types';
import { GetLatestReleaseResult } from '../../api/PluginApiClient';
import { InfoCardPlus } from '../../components/InfoCardPlus';
import { NoLatestRelease } from '../../components/NoLatestRelease';
import { ComponentConfigPromoteRc } from '../../types/types';
import { PromoteRcBody } from './PromoteRcBody';
import { useStyles } from '../../styles/styles';
import { TEST_IDS } from '../../test-helpers/test-ids';
import { GetLatestReleaseResult } from '../../api/PluginApiClient';
import { useStyles } from '../../styles/styles';
interface PromoteRcProps {
interface PromoteReleaseCandidateProps {
latestRelease: GetLatestReleaseResult;
successCb?: ComponentConfigPromoteRc['successCb'];
}
export const PromoteRc = ({ latestRelease, successCb }: PromoteRcProps) => {
export const PromoteReleaseCandidate = ({
latestRelease,
successCb,
}: PromoteReleaseCandidateProps) => {
const classes = useStyles();
function Body() {
@@ -30,7 +30,7 @@ jest.mock('../../contexts/PluginApiClientContext', () => ({
jest.mock('../../contexts/ProjectContext', () => ({
useProjectContext: jest.fn(() => mockCalverProject),
}));
jest.mock('./sideEffects/usePromoteRc', () => ({
jest.mock('./hooks/usePromoteRc', () => ({
usePromoteRc: () => ({
run: jest.fn(),
responseSteps: [],
@@ -18,13 +18,13 @@ import React from 'react';
import { Button, Typography } from '@material-ui/core';
import { ComponentConfigPromoteRc } from '../../types/types';
import { Dialog } from '../../components/Dialog';
import { Differ } from '../../components/Differ';
import { GetLatestReleaseResult } from '../../api/PluginApiClient';
import { ResponseStepDialog } from '../../components/ResponseStepDialog/ResponseStepDialog';
import { TEST_IDS } from '../../test-helpers/test-ids';
import { usePluginApiClientContext } from '../../contexts/PluginApiClientContext';
import { useProjectContext } from '../../contexts/ProjectContext';
import { usePromoteRc } from './sideEffects/usePromoteRc';
import { usePromoteRc } from './hooks/usePromoteRc';
import { useStyles } from '../../styles/styles';
interface PromoteRcBodyProps {
@@ -38,7 +38,7 @@ export const PromoteRcBody = ({ rcRelease, successCb }: PromoteRcBodyProps) => {
const classes = useStyles();
const releaseVersion = rcRelease.tagName.replace('rc-', 'version-');
const { run, responseSteps, progress } = usePromoteRc({
const { progress, responseSteps, run, runInvoked } = usePromoteRc({
pluginApiClient,
project,
rcRelease,
@@ -48,7 +48,7 @@ export const PromoteRcBody = ({ rcRelease, successCb }: PromoteRcBodyProps) => {
if (responseSteps.length > 0) {
return (
<Dialog
<ResponseStepDialog
progress={progress}
responseSteps={responseSteps}
title="Promote Release Candidate"
@@ -70,6 +70,7 @@ export const PromoteRcBody = ({ rcRelease, successCb }: PromoteRcBodyProps) => {
data-testid={TEST_IDS.promoteRc.cta}
variant="contained"
color="primary"
disabled={runInvoked}
onClick={() => run()}
>
Promote Release Candidate
@@ -17,11 +17,11 @@
import { useState, useEffect } from 'react';
import { useAsync, useAsyncFn } from 'react-use';
import { ComponentConfigPromoteRc } from '../../../types/types';
import {
GetLatestReleaseResult,
IPluginApiClient,
} from '../../../api/PluginApiClient';
import { CardHook, ComponentConfigPromoteRc } from '../../../types/types';
import { Project } from '../../../contexts/ProjectContext';
import { useResponseSteps } from '../../../hooks/useResponseSteps';
@@ -39,7 +39,7 @@ export function usePromoteRc({
rcRelease,
releaseVersion,
successCb,
}: PromoteRc) {
}: PromoteRc): CardHook<void> {
const {
responseSteps,
addStepToResponseSteps,
@@ -105,8 +105,13 @@ export function usePromoteRc({
}, [TOTAL_STEPS, responseSteps.length]);
return {
run,
responseSteps,
progress,
responseSteps,
run,
runInvoked: Boolean(
promotedReleaseRes.loading ||
promotedReleaseRes.value ||
promotedReleaseRes.error,
),
};
}
@@ -26,11 +26,11 @@ import {
} from '@material-ui/core';
import { CenteredCircularProgress } from '../../components/CenteredCircularProgress';
import { TEST_IDS } from '../../test-helpers/test-ids';
import { useFormClasses } from './styles';
import { usePluginApiClientContext } from '../../contexts/PluginApiClientContext';
import { useProjectContext } from '../../contexts/ProjectContext';
import { useQueryHandler } from '../../hooks/useQueryHandler';
import { TEST_IDS } from '../../test-helpers/test-ids';
export function Owner({ username }: { username: string }) {
const project = useProjectContext();
@@ -19,18 +19,18 @@ import { useAsync } from 'react-use';
import { useNavigate } from 'react-router';
import {
FormControl,
InputLabel,
Select,
MenuItem,
FormHelperText,
InputLabel,
MenuItem,
Select,
} from '@material-ui/core';
import { usePluginApiClientContext } from '../../contexts/PluginApiClientContext';
import { useFormClasses } from './styles';
import { CenteredCircularProgress } from '../../components/CenteredCircularProgress';
import { TEST_IDS } from '../../test-helpers/test-ids';
import { useFormClasses } from './styles';
import { usePluginApiClientContext } from '../../contexts/PluginApiClientContext';
import { useProjectContext } from '../../contexts/ProjectContext';
import { useQueryHandler } from '../../hooks/useQueryHandler';
import { TEST_IDS } from '../../test-helpers/test-ids';
export function Repo() {
const pluginApiClient = usePluginApiClientContext();
@@ -24,9 +24,9 @@ import {
RadioGroup,
} from '@material-ui/core';
import { TEST_IDS } from '../../test-helpers/test-ids';
import { useProjectContext } from '../../contexts/ProjectContext';
import { useQueryHandler } from '../../hooks/useQueryHandler';
import { TEST_IDS } from '../../test-helpers/test-ids';
export function VersioningStrategy() {
const navigate = useNavigate();
@@ -21,28 +21,31 @@ import {
mockApiClient,
mockCalverProject,
mockNextGitHubInfo,
mockReleaseCandidateCalver,
mockReleaseBranch,
mockReleaseCandidateCalver,
mockReleaseVersionCalver,
mockSemverProject,
} from '../../test-helpers/test-helpers';
import { TEST_IDS } from '../../test-helpers/test-ids';
import { useCreateRc } from './hooks/useCreateRc';
jest.mock('../../contexts/PluginApiClientContext', () => ({
usePluginApiClientContext: jest.fn(() => mockApiClient),
usePluginApiClientContext: () => mockApiClient,
}));
jest.mock('../../contexts/ProjectContext', () => ({
useProjectContext: jest.fn(() => mockCalverProject),
}));
jest.mock('./getRcGitHubInfo', () => ({
jest.mock('./helpers/getRcGitHubInfo', () => ({
getRcGitHubInfo: () => mockNextGitHubInfo,
}));
jest.mock('./sideEffects/useCreateRc', () => ({
useCreateRc: () => ({
run: jest.fn(),
responseSteps: [],
progress: 0,
}),
jest.mock('./hooks/useCreateRc', () => ({
useCreateRc: () =>
({
run: jest.fn(),
responseSteps: [],
progress: 0,
runLoading: false,
} as ReturnType<typeof useCreateRc>),
}));
import { useProjectContext } from '../../contexts/ProjectContext';
@@ -31,13 +31,13 @@ import {
GetRepositoryResult,
} from '../../api/PluginApiClient';
import { ComponentConfigCreateRc } from '../../types/types';
import { Dialog } from '../../components/Dialog';
import { Differ } from '../../components/Differ';
import { getRcGitHubInfo } from './getRcGitHubInfo';
import { getRcGitHubInfo } from './helpers/getRcGitHubInfo';
import { InfoCardPlus } from '../../components/InfoCardPlus';
import { ResponseStepDialog } from '../../components/ResponseStepDialog/ResponseStepDialog';
import { SEMVER_PARTS } from '../../constants/constants';
import { TEST_IDS } from '../../test-helpers/test-ids';
import { useCreateRc } from './sideEffects/useCreateRc';
import { useCreateRc } from './hooks/useCreateRc';
import { usePluginApiClientContext } from '../../contexts/PluginApiClientContext';
import { useProjectContext } from '../../contexts/ProjectContext';
import { useStyles } from '../../styles/styles';
@@ -72,7 +72,7 @@ export const CreateRc = ({
);
}, [semverBumpLevel, setNextGitHubInfo, latestRelease, project]);
const { run, responseSteps, progress } = useCreateRc({
const { progress, responseSteps, run, runInvoked } = useCreateRc({
defaultBranch,
latestRelease,
nextGitHubInfo,
@@ -82,7 +82,7 @@ export const CreateRc = ({
});
if (responseSteps.length > 0) {
return (
<Dialog
<ResponseStepDialog
progress={progress}
responseSteps={responseSteps}
title="Create Release Candidate"
@@ -139,14 +139,12 @@ export const CreateRc = ({
return (
<Button
data-testid={TEST_IDS.createRc.cta}
disabled={conflictingPreRelease || tagAlreadyExists}
disabled={conflictingPreRelease || tagAlreadyExists || runInvoked}
variant="contained"
color="primary"
onClick={async () => {
await run();
}}
onClick={() => run()}
>
Create RC
Create Release Candidate
</Button>
);
}
@@ -17,11 +17,11 @@
import { DateTime } from 'luxon';
import {
mockSemverProject,
mockCalverProject,
mockReleaseVersionCalver,
mockReleaseVersionSemver,
} from '../../test-helpers/test-helpers';
mockSemverProject,
} from '../../../test-helpers/test-helpers';
import { getRcGitHubInfo } from './getRcGitHubInfo';
describe('getRcGitHubInfo', () => {
@@ -16,11 +16,11 @@
import { DateTime } from 'luxon';
import { getBumpedSemverTagParts } from '../../helpers/getBumpedTag';
import { GetLatestReleaseResult } from '../../api/PluginApiClient';
import { getSemverTagParts } from '../../helpers/tagParts/getSemverTagParts';
import { Project } from '../../contexts/ProjectContext';
import { SEMVER_PARTS } from '../../constants/constants';
import { getBumpedSemverTagParts } from '../../../helpers/getBumpedTag';
import { GetLatestReleaseResult } from '../../../api/PluginApiClient';
import { getSemverTagParts } from '../../../helpers/tagParts/getSemverTagParts';
import { Project } from '../../../contexts/ProjectContext';
import { SEMVER_PARTS } from '../../../constants/constants';
export const getRcGitHubInfo = ({
project,
@@ -94,6 +94,7 @@ describe('useCreateRc', () => {
},
],
"run": [Function],
"runLoading": false,
}
`);
});
@@ -17,15 +17,15 @@
import { useEffect, useState } from 'react';
import { useAsync, useAsyncFn } from 'react-use';
import { getRcGitHubInfo } from '../getRcGitHubInfo';
import { ComponentConfigCreateRc } from '../../../types/types';
import {
GetLatestReleaseResult,
GetRepositoryResult,
IPluginApiClient,
} from '../../../api/PluginApiClient';
import { Project } from '../../../contexts/ProjectContext';
import { CardHook, ComponentConfigCreateRc } from '../../../types/types';
import { getRcGitHubInfo } from '../helpers/getRcGitHubInfo';
import { GitHubReleaseManagerError } from '../../../errors/GitHubReleaseManagerError';
import { Project } from '../../../contexts/ProjectContext';
import { useResponseSteps } from '../../../hooks/useResponseSteps';
interface CreateRC {
@@ -44,7 +44,7 @@ export function useCreateRc({
pluginApiClient,
project,
successCb,
}: CreateRC) {
}: CreateRC): CardHook<void> {
const {
responseSteps,
addStepToResponseSteps,
@@ -211,8 +211,11 @@ export function useCreateRc({
}, [TOTAL_STEPS, responseSteps.length]);
return {
run,
responseSteps,
progress,
responseSteps,
run,
runInvoked: Boolean(
latestCommitRes.loading || latestCommitRes.value || latestCommitRes.error,
),
};
}
@@ -1,40 +0,0 @@
/*
* Copyright 2021 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 {
Box,
LinearProgress,
LinearProgressProps,
Typography,
} from '@material-ui/core';
export function LinearProgressWithLabel(
props: LinearProgressProps & { value: number },
) {
return (
<Box display="flex" alignItems="center" width="90%" alignSelf="center">
<Box width="100%" mr={1}>
<LinearProgress variant="determinate" {...props} />
</Box>
<Box minWidth={35}>
<Typography variant="body2" color="textSecondary">{`${Math.round(
props.value,
)}%`}</Typography>
</Box>
</Box>
);
}
@@ -0,0 +1,79 @@
/*
* Copyright 2021 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 { Box, LinearProgress, Typography } from '@material-ui/core';
import { ResponseStep } from '../../types/types';
const STATUSES = {
FAILURE: 'FAILURE',
ONGOING: 'ONGOING',
SUCCESS: 'SUCCESS',
} as const;
export function LinearProgressWithLabel(props: {
progress: number;
responseSteps: ResponseStep[];
}) {
const roundedValue = Math.ceil(props.progress);
const progress = roundedValue < 100 ? roundedValue : 100;
const failure = props.responseSteps.some(
responseStep => responseStep.icon === 'failure',
);
let status: keyof typeof STATUSES = STATUSES.ONGOING;
if (!failure && progress === 100) status = STATUSES.SUCCESS;
if (failure) status = STATUSES.FAILURE;
const CompletionEmoji = () => {
if (status === STATUSES.ONGOING) return null;
if (status === STATUSES.FAILURE) return <span>{' 🔥 '}</span>;
return <span>{' 🚀 '}</span>;
};
return (
<Box
display="flex"
alignItems="center"
width="90%"
alignSelf="center"
flexDirection="column"
>
<Box width="100%">
<LinearProgress variant="determinate" value={progress} />
</Box>
<Box>
<Typography
variant="body2"
style={{
marginTop: 8,
minWidth: 35,
color: failure ? '#ff0033' : '#1DB954',
fontWeight: 'bold',
fontSize: `${125 + Math.ceil(progress / 3)}%`,
}}
>
<CompletionEmoji />
{`${progress}%`}
<CompletionEmoji />
</Typography>
</Box>
</Box>
);
}
@@ -17,19 +17,19 @@
import React from 'react';
import { render } from '@testing-library/react';
import { Dialog } from './Dialog';
import { ResponseStepDialog } from './ResponseStepDialog';
jest.mock('../contexts/RefetchContext', () => ({
jest.mock('../../contexts/RefetchContext', () => ({
useRefetchContext: () => jest.fn(),
}));
describe('Dialog', () => {
it('should render Dialog', () => {
describe('ResponseStepDialog', () => {
it('should render ResponseStepDialog', () => {
const mockTitle = 'mock_dialog_title';
const mockResponseStepMessage = 'banana';
const { baseElement } = render(
<Dialog
<ResponseStepDialog
progress={1}
responseSteps={[{ message: mockResponseStepMessage }]}
title={mockTitle}
@@ -14,18 +14,21 @@
* limitations under the License.
*/
import React from 'react';
import React, { forwardRef, Ref } from 'react';
import {
Button,
Dialog as MaterialDialog,
DialogActions,
DialogTitle,
Slide,
} from '@material-ui/core';
import { TransitionProps } from '@material-ui/core/transitions';
import RefreshIcon from '@material-ui/icons/Refresh';
import { LinearProgressWithLabel } from './LinearProgressWithLabel';
import { ResponseStep } from '../types/types';
import { ResponseStepList } from './ResponseStepList/ResponseStepList';
import { useRefetchContext } from '../contexts/RefetchContext';
import { ResponseStep } from '../../types/types';
import { ResponseStepList } from './ResponseStepList';
import { useRefetchContext } from '../../contexts/RefetchContext';
interface DialogProps {
progress: number;
@@ -33,23 +36,43 @@ interface DialogProps {
title: string;
}
export const Dialog = ({ progress, responseSteps, title }: DialogProps) => {
const Transition = forwardRef(function Transition(
props: { children?: React.ReactElement<any, any> } & TransitionProps,
ref: Ref<unknown>,
) {
return <Slide direction="up" ref={ref} {...props} />;
});
export const ResponseStepDialog = ({
progress,
responseSteps,
title,
}: DialogProps) => {
const { setRefetchTrigger } = useRefetchContext();
return (
<MaterialDialog open maxWidth="md" fullWidth>
<MaterialDialog
open
maxWidth="md"
fullWidth
TransitionComponent={Transition}
>
<DialogTitle>{title}</DialogTitle>
<ResponseStepList responseSteps={responseSteps} />
<LinearProgressWithLabel value={progress} />
<LinearProgressWithLabel
progress={progress}
responseSteps={responseSteps}
/>
<DialogActions>
<DialogActions style={{ padding: 20 }}>
<Button
onClick={() => setRefetchTrigger(Date.now())}
color="primary"
variant="contained"
size="large"
color="primary"
startIcon={<RefreshIcon />}
>
Ok
</Button>
@@ -17,8 +17,8 @@
import React from 'react';
import { render } from '@testing-library/react';
import { TEST_IDS } from '../../test-helpers/test-ids';
import { ResponseStepListItem } from './ResponseStepListItem';
import { TEST_IDS } from '../../test-helpers/test-ids';
describe('ResponseStepListItem', () => {
it('should render', () => {
@@ -28,8 +28,8 @@ import ErrorOutlineIcon from '@material-ui/icons/ErrorOutline';
import FiberManualRecordIcon from '@material-ui/icons/FiberManualRecord';
import OpenInNewIcon from '@material-ui/icons/OpenInNew';
import { TEST_IDS } from '../../test-helpers/test-ids';
import { ResponseStep } from '../../types/types';
import { TEST_IDS } from '../../test-helpers/test-ids';
interface ResponseStepListItemProps {
responseStep: ResponseStep;
@@ -14,39 +14,49 @@
* limitations under the License.
*/
import { useAsync } from 'react-use';
import { IPluginApiClient } from '../api/PluginApiClient';
import { Project } from '../contexts/ProjectContext';
interface GetGitHubBatchInfo {
project: Project;
pluginApiClient: IPluginApiClient;
refetchTrigger: number;
}
export const getGitHubBatchInfo = ({
export const useGetGitHubBatchInfo = ({
project,
pluginApiClient,
}: GetGitHubBatchInfo) => async () => {
const [repository, latestRelease] = await Promise.all([
pluginApiClient.getRepository({ ...project }),
pluginApiClient.getLatestRelease({ ...project }),
]);
refetchTrigger,
}: GetGitHubBatchInfo) => {
const gitHubBatchInfo = useAsync(async () => {
const [repository, latestRelease] = await Promise.all([
pluginApiClient.getRepository({ ...project }),
pluginApiClient.getLatestRelease({ ...project }),
]);
if (latestRelease === null) {
return {
latestRelease,
releaseBranch: null,
repository,
};
}
const releaseBranch = await pluginApiClient.getBranch({
...project,
branchName: latestRelease.targetCommitish,
});
if (latestRelease === null) {
return {
latestRelease,
releaseBranch: null,
releaseBranch,
repository,
};
}
const releaseBranch = await pluginApiClient.getBranch({
...project,
branchName: latestRelease.targetCommitish,
});
}, [project, refetchTrigger]);
return {
latestRelease,
releaseBranch,
repository,
gitHubBatchInfo,
};
};
@@ -18,37 +18,37 @@ import { useState } from 'react';
import { ResponseStep } from '../types/types';
const RESPONSE_STEP_FAILURE_ABORT: ResponseStep = {
message: 'Skipped due to error in previous step',
icon: 'failure',
};
export function useResponseSteps() {
const [responseSteps, setResponseSteps] = useState<ResponseStep[]>([]);
function abortIfError(error?: Error) {
const RESPONSE_STEP_SKIP = {
responseStep: {
message: 'Skipped due to error in previous step',
icon: 'failure',
} as ResponseStep,
};
const addStepToResponseSteps = (responseStep: ResponseStep) => {
setResponseSteps([...responseSteps, responseStep]);
};
const abortIfError = (error?: Error) => {
if (error) {
setResponseSteps([...responseSteps, RESPONSE_STEP_SKIP.responseStep]);
addStepToResponseSteps(RESPONSE_STEP_FAILURE_ABORT);
throw error;
}
}
};
function asyncCatcher(error: Error): never {
const asyncCatcher = (error?: Error): never => {
const responseStepError: ResponseStep = {
message: 'Something went wrong ',
secondaryMessage: `Error message: ${error.message}`,
message: 'Something went wrong 🔥',
secondaryMessage: `Error message: ${
error?.message ? error.message : 'unknown'
}`,
icon: 'failure',
};
setResponseSteps([...responseSteps, responseStepError]);
addStepToResponseSteps(responseStepError);
throw error;
}
function addStepToResponseSteps(responseStep: ResponseStep) {
setResponseSteps([...responseSteps, responseStep]);
}
};
return {
responseSteps,
@@ -14,15 +14,15 @@
* limitations under the License.
*/
import { CalverTagParts } from '../helpers/tagParts/getCalverTagParts';
import { getRcGitHubInfo } from '../cards/createRc/getRcGitHubInfo';
import { Project } from '../contexts/ProjectContext';
import {
GetBranchResult,
GetLatestReleaseResult,
GetRecentCommitsResultSingle,
IPluginApiClient,
} from '../api/PluginApiClient';
import { CalverTagParts } from '../helpers/tagParts/getCalverTagParts';
import { getRcGitHubInfo } from '../cards/CreateRc/helpers/getRcGitHubInfo';
import { Project } from '../contexts/ProjectContext';
const mockOwner = 'mock_owner';
const mockRepo = 'mock_repo';
@@ -54,3 +54,10 @@ export interface ResponseStep {
link?: string;
icon?: 'success' | 'failure';
}
export interface CardHook<RunArgs> {
progress: number;
responseSteps: ResponseStep[];
run: (args: RunArgs) => Promise<any>;
runInvoked: boolean;
}