fix: prevent duplicate uploads and group asset commits

This commit is contained in:
Tom Boullay
2026-04-24 16:58:49 +02:00
parent fe8a6f0f54
commit 53c4c0ed60
15 changed files with 329 additions and 152 deletions
+9 -3
View File
@@ -35,6 +35,8 @@ export default function UploadZone() {
const {
isUploading,
isChecking,
isResolvingDriveError,
globalError,
setGlobalError,
overwriteConfirm,
@@ -43,6 +45,7 @@ export default function UploadZone() {
setNoChangesFolder,
driveError,
handleUpload,
handleOverwriteCancel,
handleDriveContinue,
handleDriveCancel,
handleCancel,
@@ -93,7 +96,7 @@ export default function UploadZone() {
secret={secret}
secretVisible={secretVisible}
secretError={secretError}
disabled={isUploading}
disabled={isUploading || isChecking}
onChange={handleSecretChange}
onToggleVisible={toggleSecretVisible}
/>
@@ -101,7 +104,7 @@ export default function UploadZone() {
{entries.length === 0 && (
<div>
<FolderDropzone
isUploading={isUploading}
isUploading={isUploading || isChecking}
onFolderSelected={handleFolderSelected}
onError={setGlobalError}
/>
@@ -128,6 +131,7 @@ export default function UploadZone() {
<ActionButtons
isUploading={isUploading}
isChecking={isChecking}
isSecretEmpty={isSecretEmpty}
hasPendingOrErrors={hasPendingOrErrors}
allDone={allDone}
@@ -141,8 +145,9 @@ export default function UploadZone() {
<OverwriteConfirmModal
folderName={overwriteConfirm.folderName}
diffs={overwriteConfirm.diffs}
onCancel={() => setOverwriteConfirm(null)}
onCancel={handleOverwriteCancel}
onConfirm={proceedUpload}
disabled={isUploading || isChecking || isResolvingDriveError}
/>
)}
@@ -162,6 +167,7 @@ export default function UploadZone() {
error={driveError.error}
onCancel={handleDriveCancel}
onContinue={handleDriveContinue}
disabled={isResolvingDriveError}
/>
)}
</div>
+6 -2
View File
@@ -35,6 +35,7 @@ interface ModalActionsProps {
onConfirm: () => void
/** Tailwind classes for the confirm button (default: white bg) */
confirmClassName?: string
disabled?: boolean
}
export function ModalActions({
@@ -43,20 +44,23 @@ export function ModalActions({
onCancel,
onConfirm,
confirmClassName = 'bg-white text-[#000000] hover:bg-gray-200',
disabled = false,
}: ModalActionsProps) {
return (
<div className="flex gap-3">
<button
onClick={onCancel}
disabled={disabled}
className="flex-1 bg-black-700 text-gray-300 font-medium text-sm
py-2.5 px-4 rounded-xl border border-white/10 transition-colors duration-150
py-2.5 px-4 rounded-xl border border-white/10 transition-colors duration-150 disabled:opacity-50 disabled:cursor-not-allowed
hover:bg-black-600"
>
{cancelLabel}
</button>
<button
onClick={onConfirm}
className={`flex-1 font-medium text-sm py-2.5 px-4 rounded-xl transition-colors duration-150 ${confirmClassName}`}
disabled={disabled}
className={`flex-1 font-medium text-sm py-2.5 px-4 rounded-xl transition-colors duration-150 disabled:opacity-50 disabled:cursor-not-allowed ${confirmClassName}`}
>
{confirmLabel}
</button>
+16 -12
View File
@@ -1,5 +1,6 @@
interface ActionButtonsProps {
isUploading: boolean
isChecking: boolean
isSecretEmpty: boolean
hasPendingOrErrors: boolean
allDone: boolean
@@ -11,6 +12,7 @@ interface ActionButtonsProps {
export default function ActionButtons({
isUploading,
isChecking,
isSecretEmpty,
hasPendingOrErrors,
allDone,
@@ -19,11 +21,12 @@ export default function ActionButtons({
onCancel,
onReset,
}: ActionButtonsProps) {
const cantUpload = isSecretEmpty
const cantUpload = isSecretEmpty || isChecking
const isBusy = isUploading || isChecking
return (
<div className="flex gap-3">
{!isUploading && hasPendingOrErrors && (
{!isBusy && hasPendingOrErrors && (
<button
onClick={onUpload}
disabled={cantUpload}
@@ -38,18 +41,19 @@ export default function ActionButtons({
</button>
)}
{isUploading && (
<button
onClick={onCancel}
className="flex-1 bg-black-700 text-gray-300 font-medium text-sm
py-2.5 px-6 rounded-xl border border-black-600 transition-colors duration-150
{isBusy && (
<button
onClick={onCancel}
disabled={!isUploading}
className="flex-1 bg-black-700 text-gray-300 font-medium text-sm
py-2.5 px-6 rounded-xl border border-black-600 transition-colors duration-150 disabled:opacity-50 disabled:cursor-not-allowed
hover:bg-black-600"
>
Annuler
</button>
)}
>
{isChecking ? 'Verification...' : 'Annuler'}
</button>
)}
{(allDone || hasErrors) && !isUploading && (
{(allDone || hasErrors) && !isBusy && (
<button
onClick={onReset}
className="flex-1 bg-black-700 text-gray-300 font-medium text-sm
+3
View File
@@ -5,12 +5,14 @@ interface DriveErrorModalProps {
error: string
onCancel: () => void
onContinue: () => void
disabled?: boolean
}
export default function DriveErrorModal({
error,
onCancel,
onContinue,
disabled = false,
}: DriveErrorModalProps) {
return (
<Modal ariaLabelledBy="drive-error-title">
@@ -41,6 +43,7 @@ export default function DriveErrorModal({
confirmLabel="Envoyer sur Git seulement"
onCancel={onCancel}
onConfirm={onContinue}
disabled={disabled}
/>
</Modal>
)
+2 -2
View File
@@ -2,7 +2,7 @@
// Drive/Git status sub-line for FolderCard
// ---------------------------------------------------------------------------
import { SpinnerIcon, XIcon, InfoIcon } from '@/components/ui/icons'
import { SpinnerIcon, XIcon, WarningIcon } from '@/components/ui/icons'
import type { FolderEntry } from '@/lib/client-types'
interface DriveStatusLineProps {
@@ -35,7 +35,7 @@ export default function DriveStatusLine({ driveStatus, driveError }: DriveStatus
)}
{driveStatus === 'skipped' && (
<>
<InfoIcon className="w-3 h-3 text-yellow-400" />
<WarningIcon className="w-3 h-3 text-yellow-400" />
<span className="text-xs text-yellow-400">Drive ignore</span>
</>
)}
@@ -7,6 +7,7 @@ interface OverwriteConfirmModalProps {
diffs: FileDiff[]
onCancel: () => void
onConfirm: () => void
disabled?: boolean
}
export default function OverwriteConfirmModal({
@@ -14,6 +15,7 @@ export default function OverwriteConfirmModal({
diffs,
onCancel,
onConfirm,
disabled = false,
}: OverwriteConfirmModalProps) {
return (
<Modal ariaLabelledBy="overwrite-title">
@@ -68,6 +70,7 @@ export default function OverwriteConfirmModal({
onCancel={onCancel}
onConfirm={onConfirm}
confirmClassName="bg-yellow-600 text-[#000000] hover:bg-yellow-500"
disabled={disabled}
/>
</Modal>
)