import { ComponentType, useState } from 'react'; import { useMutation, UseMutationOptions } from 'react-query'; import { useNavigate } from 'react-router'; import { useTheme } from 'styled-components'; import { Icon, LargerText, Modal, SecondaryText, Stack, Wrap } from '../..'; import { Column, Table } from '../../components/tablev2/Tablev2.component'; import { Box, Button } from '../../next'; import { AttachmentAction, AttachmentOperation } from './AttachmentTypes'; type AttachmentStatus = 'Waiting for confirmation' | 'Error' | 'Success'; //The entity is the "thing" you want to attach to the resource, sorry about the naming :( export function AttachmentConfirmationModal< ENTITY_TYPE, RESOURCE_TYPE, ENTITY extends Record = Record, >({ attachmentOperations, getAttachmentMutationOptions, resourceType, resourceName, redirectUrl, EntityIcon, cancelButtonDisabled, onCancel, onExit, }: { attachmentOperations: AttachmentOperation[]; getAttachmentMutationOptions: () => UseMutationOptions< unknown, unknown, { action: AttachmentAction; type: ENTITY_TYPE; entityName: string; id: string; completeEntity?: ENTITY; } >; resourceName: string; resourceType: RESOURCE_TYPE; redirectUrl: string; EntityIcon: ComponentType< React.PropsWithChildren<{ type: ENTITY_TYPE | RESOURCE_TYPE }> >; cancelButtonDisabled?: boolean; onCancel?: () => void; onExit?: ( successfullOperations: AttachmentOperation[], failedOperations: AttachmentOperation[], ) => void; }) { const navigate = useNavigate(); const [isModalOpen, setIsModalOpen] = useState(false); const handleClose = () => { setIsModalOpen(false); }; const [attachmentOperationsStatuses, setAttachmentOperationsStatuses] = useState>({}); const attachmentMutation = useMutation({ ...getAttachmentMutationOptions(), onSettled: (_, error, flatEntity) => { setAttachmentOperationsStatuses((statuses) => ({ ...statuses, [flatEntity.id]: error ? 'Error' : 'Success', })); }, }); const attachmentOperationsFlat: { action: AttachmentAction; type: ENTITY_TYPE; entityName: string; id: string; }[] = attachmentOperations.map( (attachmentOperation: AttachmentOperation) => { return { action: attachmentOperation.action, type: attachmentOperation.entity.type, entityName: attachmentOperation.entity.name, id: attachmentOperation.entity.id, completeEntity: attachmentOperation.entity.completeEntity, }; }, ); const attach = () => { attachmentOperationsFlat.forEach((attachmentOperationFlat) => { if ( attachmentOperationsStatuses[attachmentOperationFlat.id] === 'Waiting for confirmation' || attachmentOperationsStatuses[attachmentOperationFlat.id] === 'Error' || !attachmentOperationsStatuses[attachmentOperationFlat.id] ) { setAttachmentOperationsStatuses((attachmentOperationsStatuses) => { return { ...attachmentOperationsStatuses, [attachmentOperationFlat.id]: 'Waiting for confirmation', }; }); attachmentMutation.mutate({ ...attachmentOperationFlat, }); } }); }; const isAttachNotDone = attachmentOperationsFlat.find( (attachmentOperation) => !attachmentOperationsStatuses[attachmentOperation.id], ); const handleExit = () => { if (onExit) { const successfulOperations = Object.entries(attachmentOperationsStatuses) .filter(([_, status]) => status === 'Success') .flatMap(([operationId]) => { const op = attachmentOperations.find( (op) => op.entity.id === operationId, ); if (op) return [op]; return []; }); const failedOperations = Object.entries(attachmentOperationsStatuses) .filter(([_, status]) => status === 'Error') .flatMap(([operationId]) => { const op = attachmentOperations.find( (op) => op.entity.id === operationId, ); if (op) return [op]; return []; }); onExit(successfulOperations, failedOperations); } handleClose(); navigate(redirectUrl); }; const modalFooter = () => { return (

<> {isAttachNotDone ? (