Skip to content

Commit

Permalink
🪟 🐛 Fix direct job linking to work with pagination (#16517)
Browse files Browse the repository at this point in the history
* start implementation of new persistence method

* add includingJobId and totalJobCount to job list request

* format

* update local openapi as well

* refactor queries into JOOQ and return empty list if target job cannot be found

* fix descriptions and undo changes from other branch

* switch including job to starting job

* fix job history handler tests

* rewrite jobs subqueries in jooq

* fix multiple config type querying

* remove unnecessary casts

* switch back to 'including' and return multiple of page size necessary to include job

* undo webapp changes

* fix test description

* format

* save progress

* use list job api changes to retrieve linked job if linked

* change job not found wording

* Update airbyte-webapp/src/services/job/JobService.tsx

Co-authored-by: Edmundo Ruiz Ghanem <168664+edmundito@users.noreply.github.com>

Co-authored-by: Edmundo Ruiz Ghanem <168664+edmundito@users.noreply.github.com>
  • Loading branch information
lmossman and edmundito authored Sep 14, 2022
1 parent 7822e4b commit 638a88c
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 13 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 @@ -48,7 +48,7 @@ export const JobItem: React.FC<JobItemProps> = ({ job }) => {
const didSucceed = didJobSucceed(job);

const onExpand = () => {
setIsOpen(!isOpen);
setIsOpen((prevIsOpen) => !prevIsOpen);
};

const onDetailsToggled = useCallback(() => {
Expand Down
2 changes: 2 additions & 0 deletions airbyte-webapp/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,8 @@
"connection.cancelSync": "Cancel Sync",
"connection.cancelReset": "Cancel Reset",
"connection.canceling": "Canceling...",
"connection.linkedJobNotFound": "Job not found",
"connection.returnToSyncHistory": "Return to Sync History",

"form.frequency": "Replication frequency*",
"form.cronExpression": "Cron expression*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import { faXmark } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import React, { useEffect, useState } from "react";
import { FormattedMessage } from "react-intl";
import { Link, useLocation } from "react-router-dom";

import { Button, LoadingButton } from "components";
import { Card } from "components/base/Card";
import { Tooltip } from "components/base/Tooltip";
import EmptyResource from "components/EmptyResourceBlock";
import { RotateIcon } from "components/icons/RotateIcon";
import { useAttemptLink } from "components/JobItem/attemptLinkUtils";

import { getFrequencyType } from "config/utils";
import { Action, Namespace } from "core/analytics";
Expand Down Expand Up @@ -52,15 +54,23 @@ const StatusView: React.FC<StatusViewProps> = ({ connection }) => {
const [activeJob, setActiveJob] = useState<ActiveJob>();
const [jobPageSize, setJobPageSize] = useState(JOB_PAGE_SIZE_INCREMENT);
const analyticsService = useAnalyticsService();
const { jobs, isPreviousData: isJobPageLoading } = useListJobs({
const { jobId: linkedJobId } = useAttemptLink();
const { pathname } = useLocation();
const {
jobs,
totalJobCount,
isPreviousData: isJobPageLoading,
} = useListJobs({
configId: connection.connectionId,
configTypes: ["sync", "reset_connection"],
includingJobId: linkedJobId ? Number(linkedJobId) : undefined,
pagination: {
pageSize: jobPageSize,
},
});

const moreJobPagesAvailable = jobs.length === jobPageSize;
const linkedJobNotFound = linkedJobId && jobs.length === 0;
const moreJobPagesAvailable = !linkedJobNotFound && jobPageSize < totalJobCount;

useEffect(() => {
const jobRunningOrPending = getJobRunningOrPending(jobs);
Expand All @@ -74,6 +84,9 @@ const StatusView: React.FC<StatusViewProps> = ({ connection }) => {
// We need to disable button when job is canceled but the job list still has a running job
} as ActiveJob)
);

// necessary because request to listJobs may return a result larger than the current page size if a linkedJobId is passed in
setJobPageSize((prevJobPageSize) => Math.max(prevJobPageSize, jobs.length));
}, [jobs]);

const { openConfirmationModal, closeConfirmationModal } = useConfirmationModalService();
Expand Down Expand Up @@ -171,7 +184,20 @@ const StatusView: React.FC<StatusViewProps> = ({ connection }) => {
</div>
}
>
{jobs.length ? <JobsList jobs={jobs} /> : <EmptyResource text={<FormattedMessage id="sources.noSync" />} />}
{jobs.length ? (
<JobsList jobs={jobs} />
) : linkedJobNotFound ? (
<EmptyResource
text={<FormattedMessage id="connection.linkedJobNotFound" />}
description={
<Link to={pathname}>
<FormattedMessage id="connection.returnToSyncHistory" />
</Link>
}
/>
) : (
<EmptyResource text={<FormattedMessage id="sources.noSync" />} />
)}
</Card>

{(moreJobPagesAvailable || isJobPageLoading) && (
Expand Down
24 changes: 15 additions & 9 deletions airbyte-webapp/src/services/job/JobService.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ import {
JobDebugInfoRead,
JobInfoRead,
JobListRequestBody,
JobWithAttemptsRead,
JobReadList,
Pagination,
} from "../../core/request/AirbyteClient";
import { useSuspenseQuery } from "../connector/useSuspenseQuery";

export const jobsKeys = {
all: ["jobs"] as const,
lists: () => [...jobsKeys.all, "list"] as const,
list: (filters: string, pagination?: Pagination) => [...jobsKeys.lists(), { filters, pagination }] as const,
list: (filters: string, includingJobId?: number, pagination?: Pagination) =>
[...jobsKeys.lists(), { filters, includingJobId, pagination }] as const,
detail: (jobId: number) => [...jobsKeys.all, "details", jobId] as const,
getDebugInfo: (jobId: number) => [...jobsKeys.all, "getDebugInfo", jobId] as const,
cancel: (jobId: string) => [...jobsKeys.all, "cancel", jobId] as const,
Expand All @@ -31,13 +32,18 @@ function useGetJobService() {

export const useListJobs = (listParams: JobListRequestBody) => {
const service = useGetJobService();
const result = useQuery(jobsKeys.list(listParams.configId, listParams.pagination), () => service.list(listParams), {
refetchInterval: 2500, // every 2,5 seconds,
keepPreviousData: true,
suspense: true,
});
// cast to JobWithAttemptsRead[] because (suspense: true) means we will never get undefined
return { jobs: result.data?.jobs as JobWithAttemptsRead[], isPreviousData: result.isPreviousData };
const result = useQuery(
jobsKeys.list(listParams.configId, listParams.includingJobId, listParams.pagination),
() => service.list(listParams),
{
refetchInterval: 2500, // every 2,5 seconds,
keepPreviousData: true,
suspense: true,
}
);
// cast to JobReadList because (suspense: true) means we will never get undefined
const jobReadList = result.data as JobReadList;
return { jobs: jobReadList.jobs, totalJobCount: jobReadList.totalJobCount, isPreviousData: result.isPreviousData };
};

export const useGetJob = (id: number, enabled = true) => {
Expand Down

0 comments on commit 638a88c

Please sign in to comment.