Skip to content

Commit

Permalink
Simplify messaging for sync canceled jobs (#20999)
Browse files Browse the repository at this point in the history
* Hide stats
* Show cancelled icon when it's multiple attempts
* Update attempts count to gray
* Extract shared attempt functions into utils file
* Cleanup component export and scss imports
* Fix height glitch when opening and closing log
  • Loading branch information
edmundito authored and jbfbell committed Jan 13, 2023
1 parent ad140b5 commit 6becd86
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 53 deletions.
2 changes: 1 addition & 1 deletion airbyte-webapp/src/components/JobItem/JobItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { AttemptRead, JobStatus, SynchronousJobRead } from "../../core/request/A
import { useAttemptLink } from "./attemptLinkUtils";
import ContentWrapper from "./components/ContentWrapper";
import ErrorDetails from "./components/ErrorDetails";
import JobLogs from "./components/JobLogs";
import { JobLogs } from "./components/JobLogs";
import MainInfo from "./components/MainInfo";
import styles from "./JobItem.module.scss";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@use "../../../scss/colors";
@use "../../../scss/variables";
@use "scss/colors";
@use "scss/variables";

.container {
font-size: 12px;
Expand Down
66 changes: 32 additions & 34 deletions airbyte-webapp/src/components/JobItem/components/AttemptDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import dayjs from "dayjs";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";

import { AttemptRead, AttemptStatus } from "core/request/AirbyteClient";
import { formatBytes } from "utils/numberHelper";

import { AttemptRead, AttemptStatus } from "../../../core/request/AirbyteClient";
import { getFailureFromAttempt, isCancelledAttempt } from "../utils";
import styles from "./AttemptDetails.module.scss";

interface AttemptDetailsProps {
Expand All @@ -14,11 +15,7 @@ interface AttemptDetailsProps {
hasMultipleAttempts?: boolean;
}

const getFailureFromAttempt = (attempt: AttemptRead) => {
return attempt.failureSummary && attempt.failureSummary.failures[0];
};

const AttemptDetails: React.FC<AttemptDetailsProps> = ({ attempt, className, hasMultipleAttempts }) => {
export const AttemptDetails: React.FC<AttemptDetailsProps> = ({ attempt, className, hasMultipleAttempts }) => {
const { formatMessage } = useIntl();

if (attempt.status !== AttemptStatus.succeeded && attempt.status !== AttemptStatus.failed) {
Expand Down Expand Up @@ -48,35 +45,38 @@ const AttemptDetails: React.FC<AttemptDetailsProps> = ({ attempt, className, has
const hours = Math.abs(date2.diff(date1, "hour"));
const minutes = Math.abs(date2.diff(date1, "minute")) - hours * 60;
const seconds = Math.abs(date2.diff(date1, "second")) - minutes * 60 - hours * 3600;
const isFailed = attempt.status === AttemptStatus.failed;
const isCancelled = isCancelledAttempt(attempt);
const isFailed = attempt.status === AttemptStatus.failed && !isCancelled;

return (
<div className={classNames(styles.container, className)}>
<div className={styles.details}>
{hasMultipleAttempts && (
<strong className={classNames(styles.lastAttempt, { [styles.failed]: isFailed })}>
<FormattedMessage id="sources.lastAttempt" />
</strong>
)}
<span>{formatBytes(attempt?.totalStats?.bytesEmitted)}</span>
<span>
<FormattedMessage
id="sources.countEmittedRecords"
values={{ count: attempt.totalStats?.recordsEmitted || 0 }}
/>
</span>
<span>
<FormattedMessage
id="sources.countCommittedRecords"
values={{ count: attempt.totalStats?.recordsCommitted || 0 }}
/>
</span>
<span>
{hours ? <FormattedMessage id="sources.hour" values={{ hour: hours }} /> : null}
{hours || minutes ? <FormattedMessage id="sources.minute" values={{ minute: minutes }} /> : null}
<FormattedMessage id="sources.second" values={{ second: seconds }} />
</span>
</div>
{!isCancelled && (
<div className={styles.details}>
{hasMultipleAttempts && (
<strong className={classNames(styles.lastAttempt, { [styles.failed]: isFailed })}>
<FormattedMessage id="sources.lastAttempt" />
</strong>
)}
<span>{formatBytes(attempt?.totalStats?.bytesEmitted)}</span>
<span>
<FormattedMessage
id="sources.countEmittedRecords"
values={{ count: attempt.totalStats?.recordsEmitted || 0 }}
/>
</span>
<span>
<FormattedMessage
id="sources.countCommittedRecords"
values={{ count: attempt.totalStats?.recordsCommitted || 0 }}
/>
</span>
<span>
{hours ? <FormattedMessage id="sources.hour" values={{ hour: hours }} /> : null}
{hours || minutes ? <FormattedMessage id="sources.minute" values={{ minute: minutes }} /> : null}
<FormattedMessage id="sources.second" values={{ second: seconds }} />
</span>
</div>
)}
{isFailed && (
<div className={styles.failedMessage}>
{formatMessage(
Expand All @@ -93,5 +93,3 @@ const AttemptDetails: React.FC<AttemptDetailsProps> = ({ attempt, className, has
</div>
);
};

export default AttemptDetails;
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import styled from "styled-components";

import { AttemptRead } from "core/request/AirbyteClient";

import { getFailureFromAttempt, isCancelledAttempt } from "../utils";

interface IProps {
attempts?: AttemptRead[];
}
Expand All @@ -20,10 +22,6 @@ const FailureDateDisplay = styled.span`
font-style: italic;
`;

const getFailureFromAttempt = (attempt: AttemptRead) => {
return attempt.failureSummary?.failures[0];
};

const ErrorDetails: React.FC<IProps> = ({ attempts }) => {
const { formatMessage } = useIntl();

Expand All @@ -42,8 +40,9 @@ const ErrorDetails: React.FC<IProps> = ({ attempts }) => {

const attempt = attempts[attempts.length - 1];
const failure = getFailureFromAttempt(attempt);
const isCancelled = isCancelledAttempt(attempt);

if (!failure) {
if (!failure || isCancelled) {
return null;
}

Expand Down
12 changes: 8 additions & 4 deletions airbyte-webapp/src/components/JobItem/components/JobLogs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import { StatusIcon } from "components/ui/StatusIcon";
import { StatusIconStatus } from "components/ui/StatusIcon/StatusIcon";
import { Text } from "components/ui/Text";

import { AttemptRead, AttemptStatus, SynchronousJobRead } from "core/request/AirbyteClient";
import { JobsWithJobs } from "pages/ConnectionPage/pages/ConnectionItemPage/JobsList";
import { useGetDebugInfoJob } from "services/job/JobService";

import { AttemptRead, AttemptStatus, SynchronousJobRead } from "../../../core/request/AirbyteClient";
import { parseAttemptLink } from "../attemptLinkUtils";
import { isCancelledAttempt } from "../utils";
import styles from "./JobLogs.module.scss";
import Logs from "./Logs";
import { LogsDetails } from "./LogsDetails";
Expand All @@ -26,6 +27,11 @@ const mapAttemptStatusToIcon = (attempt: AttemptRead): StatusIconStatus => {
if (isPartialSuccess(attempt)) {
return "warning";
}

if (isCancelledAttempt(attempt)) {
return "cancelled";
}

switch (attempt.status) {
case AttemptStatus.running:
return "loading";
Expand All @@ -44,7 +50,7 @@ const jobIsSynchronousJobRead = (job: SynchronousJobRead | JobsWithJobs): job is
return !!(job as SynchronousJobRead)?.logs?.logLines;
};

const JobLogs: React.FC<JobLogsProps> = ({ jobIsFailed, job }) => {
export const JobLogs: React.FC<JobLogsProps> = ({ jobIsFailed, job }) => {
const isSynchronousJobRead = jobIsSynchronousJobRead(job);

const id: number | string = (job as JobsWithJobs).job?.id ?? (job as SynchronousJobRead).id;
Expand Down Expand Up @@ -110,5 +116,3 @@ const JobLogs: React.FC<JobLogsProps> = ({ jobIsFailed, job }) => {
</>
);
};

export default JobLogs;
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";
import styled from "styled-components";

import { AttemptRead, JobDebugInfoRead } from "../../../core/request/AirbyteClient";
import AttemptDetails from "./AttemptDetails";
import { AttemptDetails } from "./AttemptDetails";
import DownloadButton from "./DownloadButton";
import { LinkToAttemptButton } from "./LinkToAttemptButton";
import LogsTable from "./Logs";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@use "../../../scss/colors";
@use "../../../scss/variables";
@use "scss/colors";
@use "scss/variables";

.mainView {
cursor: pointer;
Expand Down Expand Up @@ -44,16 +44,18 @@
.attemptCount {
font-size: 12px;
line-height: 15px;
color: colors.$red;
color: colors.$grey;
}
}

border-bottom: variables.$border-thin solid transparent !important;

&.open:not(.failed) {
border-bottom: variables.$border-thin solid colors.$grey-100;
border-bottom: variables.$border-thin solid colors.$grey-100 !important;
}

&.open.failed {
border-bottom: variables.$border-thin solid colors.$red-50;
border-bottom: variables.$border-thin solid colors.$red-50 !important;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { AttemptRead, JobStatus, SynchronousJobRead } from "core/request/Airbyte
import { JobsWithJobs } from "pages/ConnectionPage/pages/ConnectionItemPage/JobsList";

import { getJobStatus } from "../JobItem";
import AttemptDetails from "./AttemptDetails";
import { AttemptDetails } from "./AttemptDetails";
import styles from "./MainInfo.module.scss";
import { ResetStreamsDetails } from "./ResetStreamDetails";

Expand Down
8 changes: 8 additions & 0 deletions airbyte-webapp/src/components/JobItem/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { AttemptFailureReason, AttemptFailureType, AttemptRead } from "core/request/AirbyteClient";

export const getFailureFromAttempt = (attempt: AttemptRead): AttemptFailureReason | undefined =>
attempt.failureSummary?.failures[0];

export const isCancelledAttempt = (attempt: AttemptRead): boolean =>
attempt.failureSummary?.failures.some(({ failureType }) => failureType === AttemptFailureType.manual_cancellation) ??
false;

0 comments on commit 6becd86

Please sign in to comment.