import { capitalize } from "es-toolkit/compat"; import { observer } from "mobx-react"; import { CrossIcon, DoneIcon, WarningIcon } from "outline-icons"; import { useMemo, useCallback } from "react"; import { useTranslation } from "react-i18next"; import { toast } from "sonner"; import { useTheme } from "styled-components"; import Spinner from "@shared/components/Spinner"; import { ImportState } from "@shared/types"; import type Import from "~/models/Import"; import { Action } from "~/components/Actions"; import ConfirmationDialog from "~/components/ConfirmationDialog"; import ListItem from "~/components/List/Item"; import Time from "~/components/Time"; import useCurrentUser from "~/hooks/useCurrentUser"; import useStores from "~/hooks/useStores"; import { ImportMenu } from "~/menus/ImportMenu"; import isCloudHosted from "~/utils/isCloudHosted"; type Props = { /** Import that's displayed as list item. */ importModel: Import; }; export const ImportListItem = observer(({ importModel }: Props) => { const { t } = useTranslation(); const { dialogs } = useStores(); const user = useCurrentUser(); const theme = useTheme(); const showProgress = importModel.state !== ImportState.Canceled && importModel.state !== ImportState.Errored; const stateMap = useMemo( () => ({ [ImportState.Created]: t("Processing"), [ImportState.InProgress]: t("Processing"), [ImportState.Processed]: t("Processing"), [ImportState.Completed]: t("Completed"), [ImportState.Errored]: t("Failed"), [ImportState.Canceled]: t("Canceled"), }), [t] ); const iconMap = useMemo( () => ({ [ImportState.Created]: , [ImportState.InProgress]: , [ImportState.Processed]: , [ImportState.Completed]: , [ImportState.Errored]: , [ImportState.Canceled]: , }), [theme] ); const handleCancel = useCallback(async () => { const onCancel = async () => { try { await importModel.cancel(); toast.success(t("Import canceled")); } catch (err) { toast.error(err.message); } }; dialogs.openModal({ title: t("Are you sure you want to cancel this import?"), content: ( {t( "Canceling this import will discard any progress made. This cannot be undone." )} ), }); }, [t, dialogs, importModel]); const handleDelete = useCallback(async () => { const onDelete = async () => { try { await importModel.delete(); toast.success(t("Import deleted")); } catch (err) { toast.error(err.message); } }; dialogs.openModal({ title: t("Are you sure you want to delete this import?"), content: ( {t( "Deleting this import will also delete all collections and documents that were created from it. This cannot be undone." )} ), }); }, [t, dialogs, importModel]); const selfHostedHelp = isCloudHosted ? "" : `. ${t("Check server logs for more details.")}`; return ( {stateMap[importModel.state]} •  {importModel.error && ( <> {importModel.error} {selfHostedHelp} •  )} {t(`{{userName}} requested`, { userName: user.id === importModel.createdBy.id ? t("You") : importModel.createdBy.name, })}