1 import type { ReactNode } from 'react';
2 import React, { useState } from 'react';
4 import { c } from 'ttag';
6 import { Button } from '@proton/atoms';
7 import type { ModalStateProps } from '@proton/components';
18 } from '@proton/components';
20 import { TransferConflictStrategy } from '../../store/_uploads/interface';
22 interface ConflictModalProps {
25 originalIsDraft?: boolean;
26 originalIsFolder?: boolean;
27 isForPhotos?: boolean;
28 apply: (strategy: TransferConflictStrategy, all: boolean) => void;
29 cancelAll: () => void;
30 onConfirm?: () => void;
39 noTitleEllipsis?: boolean;
45 export default function ConflictModal({
48 originalIsDraft = false,
49 originalIsFolder = false,
55 }: ConflictModalProps & ModalStateProps) {
56 const [strategy, setStrategy] = useState(TransferConflictStrategy.Replace);
57 const [applyAll, setApplyAll] = useState(false);
59 const isSameType = originalIsFolder === isFolder;
62 <strong className="text-break" key="filename">
67 const replaceFile = <strong key="replaceFile">{c('Action').t`Replace file`}</strong>;
69 const handleSubmit = (e: React.FormEvent) => {
71 apply(strategy, applyAll);
75 const closeAndCancel = () => {
81 <ModalTwo as="form" onClose={closeAndCancel} onSubmit={handleSubmit} size="small" {...modalProps}>
85 <>{isFolder ? c('Title').t`Duplicate folder found` : c('Title').t`Duplicate file found`}</>
87 <>{c('Label').t`Duplicate found`}</>
96 .jt`It looks like you recently tried to upload ${uploadName}. If the upload failed, please ${replaceFile}. If the upload is still in progress, replacing it will cancel the ongoing upload.`
97 : c('Info').jt`${uploadName} already exists in this location.`}
99 {c('Info').t`What do you want to do?`}
103 id={TransferConflictStrategy.Replace}
104 checked={strategy === TransferConflictStrategy.Replace}
105 onChange={() => setStrategy(TransferConflictStrategy.Replace)}
107 className="inline-flex flex-nowrap"
109 <div data-testid="replace-existing">
112 ? c('Label').t`Replace existing folder`
113 : c('Label').t`Replace existing file`}
116 <span className="color-weak">
117 {isSameType && !isForPhotos ? (
120 ? c('Info').t`This will upload a new version of the folder`
121 : c('Info').t`This will upload a new version of the file`}
126 ? c('Info').t`This will replace the existing folder with the file`
127 : c('Info').t`This will replace the existing file with the folder`}
136 id={TransferConflictStrategy.Rename}
137 checked={strategy === TransferConflictStrategy.Rename}
138 onChange={() => setStrategy(TransferConflictStrategy.Rename)}
140 className="inline-flex flex-nowrap"
142 <div data-testid="keep-both">
147 ? c('Label').t`Keep both folders`
148 : c('Label').t`Keep both files`}
151 <>{c('Label').t`Keep both`}</>
155 <span className="color-weak">
157 ? c('Info').t`A number will be added to the folder name`
158 : c('Info').t`A number will be added to the filename`}
165 id={TransferConflictStrategy.Skip}
166 checked={strategy === TransferConflictStrategy.Skip}
167 onChange={() => setStrategy(TransferConflictStrategy.Skip)}
169 className="inline-flex flex-nowrap"
171 <div data-testid="skip-upload">
172 <strong>{isFolder ? c('Label').t`Skip folder` : c('Label').t`Skip file`}</strong>
174 <span className="color-weak">
176 ? c('Info').t`Folder will not be uploaded`
177 : c('Info').t`File will not be updated`}
184 <Checkbox data-testid="apply-to-all" onChange={() => setApplyAll((value) => !value)}>
186 ? c('Label').t`Apply to all duplicated folders`
187 : c('Label').t`Apply to all duplicated files`}
192 <Button type="button" onClick={closeAndCancel}>
193 {c('Action').t`Cancel all uploads`}
195 <PrimaryButton type="submit">{c('Action').t`Continue`}</PrimaryButton>
201 export const useConflictModal = () => {
202 return useModalTwoStatic(ConflictModal);