Skip to content

Commit

Permalink
Add job cancel button (#2593)
Browse files Browse the repository at this point in the history
* Add job cancel button

* Edit types
  • Loading branch information
jamakase committed Mar 24, 2021
1 parent bf882ee commit b03b5b1
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 4 deletions.
26 changes: 25 additions & 1 deletion airbyte-webapp/src/components/JobItem/components/MainInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import { faAngleDown } from "@fortawesome/free-solid-svg-icons";
import { JobItem as JobApiItem, Attempt } from "core/resources/Job";
import { JobInfo } from "core/resources/Scheduler";
import { Row, Cell } from "components/SimpleTableComponents";
import StatusIcon from "components/StatusIcon";
import { Button, StatusIcon } from "components";
import AttemptDetails from "./AttemptDetails";
import Status from "core/statuses";
import useJob from "components/hooks/services/useJob";

type IProps = {
job: JobApiItem | JobInfo;
Expand Down Expand Up @@ -56,6 +58,12 @@ const AttemptCount = styled.div`
color: ${({ theme }) => theme.dangerColor};
`;

const CancelButton = styled(Button)`
margin-right: 10px;
padding: 3px 7px;
z-index: 1;
`;

const Arrow = styled.div<{
isOpen?: boolean;
isFailed?: boolean;
Expand Down Expand Up @@ -87,6 +95,17 @@ const MainInfo: React.FC<IProps> = ({
isFailed,
shortInfo,
}) => {
const { cancelJob } = useJob();

const onCancelJob = (event: React.SyntheticEvent) => {
event.stopPropagation();
cancelJob(job.id);
};

const isNotCompleted =
job.status &&
[Status.PENDING, Status.RUNNING, Status.INCOMPLETE].includes(job.status);

return (
<MainView isOpen={isOpen} isFailed={isFailed} onClick={onExpand}>
<Cell>
Expand All @@ -103,6 +122,11 @@ const MainInfo: React.FC<IProps> = ({
</Title>
</Cell>
<Cell>
{!shortInfo && isNotCompleted && (
<CancelButton secondary onClick={onCancelJob}>
<FormattedMessage id="form.cancel" />
</CancelButton>
)}
<FormattedTimeParts
value={job.createdAt * 1000}
hour="numeric"
Expand Down
26 changes: 26 additions & 0 deletions airbyte-webapp/src/components/hooks/services/useJob.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useFetcher } from "rest-hooks";

import JobResource, { Job } from "core/resources/Job";

type JobService = {
cancelJob: (jobId: number | string) => Promise<Job>;
};

const useJob = (): JobService => {
const cancelJobRequest = useFetcher(JobResource.cancelShape());

const cancelJob = async (jobId: number | string) => {
return await cancelJobRequest(
{
id: jobId,
},
{}
);
};

return {
cancelJob,
};
};

export default useJob;
45 changes: 42 additions & 3 deletions airbyte-webapp/src/core/resources/Job.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { Resource, FetchOptions, ReadShape, SchemaDetail } from "rest-hooks";
import {
FetchOptions,
MutateShape,
ReadShape,
Resource,
SchemaDetail,
} from "rest-hooks";
import BaseResource from "./BaseResource";
import Status from "../statuses";

export interface JobItem {
id: number | string;
Expand All @@ -8,7 +15,7 @@ export interface JobItem {
createdAt: number;
startedAt: number;
updatedAt: number;
status: string;
status: Status | null;
}

export interface Logs {
Expand Down Expand Up @@ -39,7 +46,7 @@ export default class JobResource extends BaseResource implements Job {
createdAt: 0,
startedAt: 0,
updatedAt: 0,
status: "",
status: null,
};
readonly attempts: Attempt[] = [];
readonly logsByAttempt: { [key: string]: Logs } = {};
Expand Down Expand Up @@ -109,4 +116,36 @@ export default class JobResource extends BaseResource implements Job {
schema: this,
};
}

static cancelShape<T extends typeof Resource>(
this: T
): MutateShape<SchemaDetail<Job>> {
return {
...super.partialUpdateShape(),
fetch: async (
params: Readonly<Record<string, string | number>>
): Promise<Job> => {
const jobResult: {
job: JobItem;
attempts: { attempt: Attempt; logs: Logs }[];
} = await this.fetch("post", `${this.url(params)}/cancel`, params);

const attemptsValue = jobResult.attempts.map(
(attemptItem) => attemptItem.attempt
);

return {
job: jobResult.job,
attempts: attemptsValue,
logsByAttempt: Object.fromEntries(
jobResult.attempts.map((attemptItem) => [
attemptItem.attempt.id,
attemptItem.logs,
])
),
};
},
schema: this,
};
}
}

0 comments on commit b03b5b1

Please sign in to comment.