saleor-dashboard/src/containers/BackgroundTasks/BackgroundTasksProvider.tsx
Dominik Żegleń df5aea6200
Add product export (#620)
* Add component backbone

* Make step component generic and typed

* Add step tabs

* Add settings view

* Encapsulate all dialog components in one directory

* Move types to separate file

* Add mutations

* Use gql types

* Add error handling

* Do not keep separate types file

* Allow products to be exported

* Fix types

* Update snapshots

* Update to latest schema

* Add disabled option

* Use wizard hook

* Update type definitions

* Queue export check task

* Fix bug causing jobs to be endless and duplicated

* Fix minor bugs

* Add accordion component

* Allow selection of fields  to be exported

* Add attribute export

* Update snapshots

* Update messages

* Update changelog

* Add missing key

* Add quick peek to accordioin

* Sort imports

* Remove unused files

* Add chiips to attribute selection

* Change menu positioning

* Add product counter

* Add select all option

* Update snapshots

* Update messages

* Remove unused import

* Add chips

* Add test tags

* Update snapshots

* Change number of max chips

* Add accordion tags

* Update messages
2020-07-30 11:54:16 +02:00

135 lines
3.4 KiB
TypeScript

import { IMessageContext } from "@saleor/components/messages";
import useNotifier from "@saleor/hooks/useNotifier";
import ApolloClient from "apollo-client";
import React from "react";
import { useApolloClient } from "react-apollo";
import { IntlShape, useIntl } from "react-intl";
import BackgroundTasksContext from "./context";
import { checkExportFileStatus, checkOrderInvoicesStatus } from "./queries";
import {
handleTask,
queueCustom,
queueExport,
queueInvoiceGenerate
} from "./tasks";
import { QueuedTask, Task, TaskData, TaskStatus } from "./types";
export const backgroundTasksRefreshTime = 15 * 1000;
export function useBackgroundTasks(
apolloClient: ApolloClient<any>,
notify: IMessageContext,
intl: IntlShape
) {
const idCounter = React.useRef(0);
const tasks = React.useRef<QueuedTask[]>([]);
React.useEffect(() => {
const intervalId = setInterval(() => {
const queue = async () => {
try {
await Promise.all(
tasks.current.map(async task => {
if (task.status === TaskStatus.PENDING) {
let status: TaskStatus;
try {
status = await handleTask(task);
} catch (error) {
throw error;
}
if (status !== TaskStatus.PENDING) {
const taskIndex = tasks.current.findIndex(
t => t.id === task.id
);
tasks.current[taskIndex].status = status;
}
}
})
);
} catch (error) {
throw error;
}
};
queue();
}, backgroundTasksRefreshTime);
return () => clearInterval(intervalId);
});
function cancel(id: number) {
tasks.current = tasks.current.filter(task => task.id !== id);
}
function queue(type: Task, data?: TaskData) {
idCounter.current += 1;
switch (type) {
case Task.CUSTOM:
queueCustom(idCounter.current, tasks, data);
break;
case Task.INVOICE_GENERATE:
queueInvoiceGenerate(
idCounter.current,
data.generateInvoice,
tasks,
() =>
apolloClient.query({
fetchPolicy: "network-only",
query: checkOrderInvoicesStatus,
variables: {
id: data.generateInvoice.orderId
}
}),
notify,
intl
);
break;
case Task.EXPORT:
queueExport(
idCounter.current,
tasks,
() =>
apolloClient.query({
fetchPolicy: "network-only",
query: checkExportFileStatus,
variables: {
id: data.id
}
}),
notify,
intl
);
break;
}
return idCounter.current;
}
return {
cancel,
queue
};
}
const BackgroundTasksProvider: React.FC = ({ children }) => {
const apolloClient = useApolloClient();
const notify = useNotifier();
const intl = useIntl();
const { cancel, queue } = useBackgroundTasks(apolloClient, notify, intl);
return (
<BackgroundTasksContext.Provider
value={{
cancel,
queue
}}
>
{children}
</BackgroundTasksContext.Provider>
);
};
BackgroundTasksProvider.displayName = "BackgroundTasksProvider";
export default BackgroundTasksProvider;