Skip to content

Commit

Permalink
Merge branch 'master' into update-copy-functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Pespiri authored Oct 17, 2023
2 parents ae71591 + 759020c commit b2a6d98
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/components/job-overview/dev.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ new Server({
this.get(`${rootPath}/:jobName`, () => new Response(404));
// Mock response for StopJob button
this.post(`${rootPath}/:jobName/stop`, () => new Response(200));
// Mock response for ReRun button
this.post(`${rootPath}/:jobName/rerun`, () => new Response(200));
},
});

Expand Down
93 changes: 91 additions & 2 deletions src/components/job-overview/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ import { Button, CircularProgress, Typography } from '@equinor/eds-core-react';
import * as PropTypes from 'prop-types';
import { FunctionComponent, useEffect, useState } from 'react';
import { Link } from 'react-router-dom';

import { ComponentList } from './component-list';
import { StepsList } from './steps-list';
import { usePollJob } from './use-poll-job';
import { useStopJob } from './use-stop-job';

import { useRerunJob } from './use-rerun-job';
import { useGetApplication } from '../application-hooks/use-get-application';
import AsyncResource from '../async-resource/simple-async-resource';
import { Breadcrumb } from '../breadcrumb';
Expand All @@ -19,6 +18,8 @@ import { useInterval } from '../../effects/use-interval';
import { RadixJobCondition } from '../../models/radix-api/jobs/radix-job-condition';
import { routes } from '../../routes';
import { RequestState } from '../../state/state-utils/request-states';
import { ScrimPopup } from '../scrim-popup';
import { errorToast, infoToast } from '../global-top-nav/styled-toaster';
import {
routeWithParams,
smallDeploymentName,
Expand Down Expand Up @@ -56,6 +57,11 @@ export const JobOverview: FunctionComponent<JobOverviewProps> = ({
appName,
jobName
);
const [rerunJobState, rerunJobFunc, rerunJobResetState] = useRerunJob(
appName,
jobName
);
const [visibleRerunScrim, setVisibleRerunScrim] = useState<boolean>(false);

const job = pollJobState.data;
const repo = applicationState.data?.registration.repository;
Expand All @@ -64,6 +70,11 @@ export const JobOverview: FunctionComponent<JobOverviewProps> = ({
const isStopping =
job?.status === RadixJobCondition.Stopping ||
stopJobState.status === RequestState.IN_PROGRESS;
const canBeRerun =
(job?.status === RadixJobCondition.Failed ||
job?.status === RadixJobCondition.Stopped) &&
!(stopJobState.status === RequestState.IN_PROGRESS);
const isRerunning = rerunJobState.status === RequestState.IN_PROGRESS;

useInterval(() => setNow(new Date()), job?.ended ? 10000000 : 1000);

Expand All @@ -74,6 +85,23 @@ export const JobOverview: FunctionComponent<JobOverviewProps> = ({
}
}, [pollJob, stopJobResetState, stopJobState.status]);

useEffect(() => {
if (rerunJobState.status === RequestState.SUCCESS) {
infoToast(
`Pipeline job '${smallJobName(jobName)}' was successfully rerun.`
);
rerunJobResetState();
} else if (rerunJobState.status === RequestState.FAILURE) {
errorToast(`Failed to rerun pipeline job '${smallJobName(jobName)}'.`);
rerunJobResetState();
}
}, [rerunJobResetState, rerunJobState.status, jobName]);

function rerunJob() {
setVisibleRerunScrim(false);
rerunJobFunc();
}

return (
<>
<Breadcrumb
Expand Down Expand Up @@ -109,6 +137,53 @@ export const JobOverview: FunctionComponent<JobOverviewProps> = ({
</div>
)}

{canBeRerun && (
<div>
<Button
onClick={() => setVisibleRerunScrim(true)}
disabled={isRerunning}
>
Rerun
</Button>
{isRerunning && (
<>
{' '}
<CircularProgress size={24} />
</>
)}

<ScrimPopup
title={`Rerun job`}
open={!!visibleRerunScrim}
onClose={() => setVisibleRerunScrim(false)}
isDismissable
>
<div className="grid grid--gap-medium grid--auto-columns rerun-job-content">
<div className="rerun-job-options">
<Typography>
Create new a job with the same attributes
</Typography>
</div>

<Button.Group>
<Button
disabled={isRerunning}
onClick={() => rerunJob()}
>
Rerun
</Button>
<Button
variant="outlined"
onClick={() => setVisibleRerunScrim(false)}
>
Cancel
</Button>
</Button.Group>
</div>
</ScrimPopup>
</div>
)}

<section className="grid grid--gap-medium">
<Typography variant="h4">Overview</Typography>
<div className="grid grid--gap-medium grid--overview-columns">
Expand All @@ -118,6 +193,20 @@ export const JobOverview: FunctionComponent<JobOverviewProps> = ({
{getExecutionState(job.status)} pipeline{' '}
<strong>{job.pipeline}</strong>
</Typography>
{job.rerunFromJob && (
<Typography>
Rerun from job{' '}
<Link
to={routeWithParams(routes.appJob, {
appName: appName,
jobName: job.rerunFromJob,
})}
className="job-ref-link"
>
{smallJobName(job.rerunFromJob)}
</Link>
</Typography>
)}
{job.pipeline === 'promote' && (
<Typography>
Deployment{' '}
Expand Down
22 changes: 22 additions & 0 deletions src/components/job-overview/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,25 @@
grid-template-columns: auto 1fr;
grid-column-end: span 2;
}

.rerun-job-content {
padding: var(--eds_spacing_medium);
padding-top: 0;
overflow: auto;
}
@media (min-width: 150rem) {
.rerun-job-content {
margin: auto;
}
}

.rerun-job-options {
margin-top: auto;
margin-bottom: auto;
}

.job-ref-link,
.job-ref-link span {
color: var(--eds_interactive_primary__resting);
text-decoration: none;
}
12 changes: 12 additions & 0 deletions src/components/job-overview/use-rerun-job.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { usePostJson } from '../../effects';
import { AsyncRequestResult } from '../../effects/use-async-request';

export const useRerunJob = (
appName: string,
jobName: string
): AsyncRequestResult<void, void> => {
const encAppName = encodeURIComponent(appName);
const encJobName = encodeURIComponent(jobName);

return usePostJson(`/applications/${encAppName}/jobs/${encJobName}/rerun`);
};
2 changes: 2 additions & 0 deletions src/models/radix-api/jobs/job/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export interface JobModel {
steps?: Array<StepModel>;
deployments?: Array<DeploymentSummaryModel>;
components?: Array<ComponentSummaryModel>;
rerunFromJob?: string;
}

/* PropTypes validation map for JobModel */
Expand Down Expand Up @@ -56,4 +57,5 @@ export const JobModelValidationMap: PropTypes.ValidationMap<JobModel> = {
ComponentSummaryModelValidationMap
) as PropTypes.Validator<ComponentSummaryModel>
),
rerunFromJob: PropTypes.string,
};
2 changes: 2 additions & 0 deletions src/models/radix-api/jobs/job/test-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const testData: TestDependencyDataType<JobModel> = [
promotedDeploymentName: 'comp-abc123',
promotedFromEnvironment: 'dev',
promotedToEnvironment: 'qa',
rerunFromJob: 'job-abc',
},
{
__testDescription: 'Valid partial object',
Expand All @@ -55,6 +56,7 @@ export const testData: TestDependencyDataType<JobModel> = [
steps: [stepData[0]],
deployments: [deploymentSummaryData[0]],
components: [componentSummaryData[0]],
rerunFromJob: 'job-abc',
},
{
__testDescription: 'Invalid partial object',
Expand Down

0 comments on commit b2a6d98

Please sign in to comment.