in packages/graph-explorer/src/workspaces/Settings/LoadConfigButton.tsx [83:166]
function ConfirmationModal({
backupData,
fileName,
onCancel,
onConfirm,
isPending,
}: {
backupData: SerializedBackup | null | undefined;
fileName?: string;
onCancel: () => void;
onConfirm: () => void;
isPending: boolean;
}) {
const [_, { close }] = useDisclosure(Boolean(backupData));
// Used to ensure the file name does not disappear while the modal is animating out
const debouncedFileName = useDebounceValue(fileName, 200);
const internalOnCancel = () => {
onCancel();
close();
};
return (
<Modal
opened={Boolean(backupData)}
onClose={internalOnCancel}
withCloseButton={false}
size="lg"
centered={true}
>
<div className="flex flex-row items-start gap-8 p-2">
<div className="py-1">
<ErrorIcon className="text-warning-main size-16" />
</div>
<div className="flex grow flex-col gap-8">
<div>
<SectionTitle>Replace {APP_NAME} Configuration</SectionTitle>
<Paragraph>
This action will replace all configuration data within {APP_NAME},
including connections and custom styles, with the contents of the
config file selected.
</Paragraph>
<Paragraph className="my-4">
<b>{fileName ?? debouncedFileName ?? "No file selected"}</b>
</Paragraph>
<Paragraph>
<i>Any connected graph databases will be unaffected.</i>
</Paragraph>
</div>
<div className="flex flex-row gap-2 self-end">
<Button
size="large"
isDisabled={isPending}
onPress={internalOnCancel}
>
Cancel
</Button>
<Button
variant="filled"
color="danger"
size="large"
onPress={onConfirm}
isDisabled={isPending}
className="relative transition-opacity"
>
<span className={cn(isPending && "opacity-0")}>
Replace {APP_NAME} Configuration
</span>
<div
className={cn(
"absolute inset-auto opacity-0",
isPending && "opacity-100"
)}
>
<LoaderIcon className="animate-spin" />
</div>
</Button>
</div>
</div>
</div>
</Modal>
);
}