2020-07-06 14:24:54 +00:00
|
|
|
import { IMessageContext } from "@saleor/components/messages";
|
|
|
|
import useNotifier from "@saleor/hooks/useNotifier";
|
2020-06-26 17:06:48 +00:00
|
|
|
import { checkOrderInvoicesStatus } from "@saleor/orders/queries";
|
2020-07-06 14:24:54 +00:00
|
|
|
import ApolloClient from "apollo-client";
|
2020-06-19 10:42:29 +00:00
|
|
|
import React from "react";
|
2020-07-06 14:24:54 +00:00
|
|
|
import { useApolloClient } from "react-apollo";
|
|
|
|
import { IntlShape, useIntl } from "react-intl";
|
2020-06-19 10:42:29 +00:00
|
|
|
|
|
|
|
import BackgroundTasksContext from "./context";
|
2020-06-26 17:06:48 +00:00
|
|
|
import { handleTask, queueCustom, queueInvoiceGenerate } from "./tasks";
|
2020-06-21 15:31:33 +00:00
|
|
|
import { QueuedTask, Task, TaskData, TaskStatus } from "./types";
|
2020-06-19 10:42:29 +00:00
|
|
|
|
|
|
|
export const backgroundTasksRefreshTime = 15 * 1000;
|
|
|
|
|
2020-07-06 14:24:54 +00:00
|
|
|
export function useBackgroundTasks(
|
2020-06-26 17:06:48 +00:00
|
|
|
apolloClient: ApolloClient<any>,
|
|
|
|
notify: IMessageContext,
|
|
|
|
intl: IntlShape
|
2020-07-06 14:24:54 +00:00
|
|
|
) {
|
2020-06-19 10:42:29 +00:00
|
|
|
const idCounter = React.useRef(0);
|
|
|
|
const tasks = React.useRef<QueuedTask[]>([]);
|
|
|
|
|
|
|
|
React.useEffect(() => {
|
|
|
|
const intervalId = setInterval(() => {
|
2020-06-21 15:31:33 +00:00
|
|
|
const queue = async () => {
|
|
|
|
try {
|
|
|
|
await Promise.all(
|
|
|
|
tasks.current.map(async task => {
|
2020-07-06 14:24:54 +00:00
|
|
|
if (task.status === TaskStatus.PENDING) {
|
|
|
|
let status: TaskStatus;
|
2020-06-21 15:31:33 +00:00
|
|
|
|
2020-07-06 14:24:54 +00:00
|
|
|
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;
|
|
|
|
}
|
2020-06-21 15:31:33 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
);
|
|
|
|
} catch (error) {
|
|
|
|
throw error;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
queue();
|
2020-06-19 10:42:29 +00:00
|
|
|
}, 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);
|
2020-07-06 14:24:54 +00:00
|
|
|
break;
|
2020-06-26 17:06:48 +00:00
|
|
|
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;
|
2020-06-19 10:42:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return idCounter.current;
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
cancel,
|
|
|
|
queue
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
const BackgroundTasksProvider: React.FC = ({ children }) => {
|
2020-07-06 14:24:54 +00:00
|
|
|
const apolloClient = useApolloClient();
|
|
|
|
const notify = useNotifier();
|
|
|
|
const intl = useIntl();
|
|
|
|
const { cancel, queue } = useBackgroundTasks(apolloClient, notify, intl);
|
2020-06-19 10:42:29 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
<BackgroundTasksContext.Provider
|
|
|
|
value={{
|
|
|
|
cancel,
|
|
|
|
queue
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
{children}
|
|
|
|
</BackgroundTasksContext.Provider>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
BackgroundTasksProvider.displayName = "BackgroundTasksProvider";
|
|
|
|
export default BackgroundTasksProvider;
|