diff --git a/packages/common/src/packageActions.ts b/packages/common/src/packageActions.ts index efc2c2d3..7fc93bd6 100644 --- a/packages/common/src/packageActions.ts +++ b/packages/common/src/packageActions.ts @@ -253,10 +253,37 @@ export async function applyPackageChanges( return false; } + let previewAllNotification: string | undefined; + try { if (!skipConfirmation) { const previewJobs: IPreviewJob[] = []; + // Emit notification about the preview jobs + previewAllNotification = Notification.emit( + 'Previewing package changes', + 'in-progress', + { + autoClose: false + } + ); + + const removePreview = await pkgModel.dry_run_preview( + toRemove, + 'remove', + theEnvironment + ); + const updatePreview = await pkgModel.dry_run_preview( + toUpdate, + 'update', + theEnvironment + ); + const installPreview = await pkgModel.dry_run_preview( + toInstall, + 'install', + theEnvironment + ); + if (toRemove.length > 0) { previewJobs.push({ section: { @@ -264,7 +291,7 @@ export async function applyPackageChanges( title: 'Remove packages', requestedPackages: toRemove.map(specBaseName) }, - promise: pkgModel.dry_run_preview(toRemove, 'remove', theEnvironment) + promise: Promise.resolve(removePreview) }); } if (toUpdate.length > 0) { @@ -274,7 +301,7 @@ export async function applyPackageChanges( title: 'Update packages', requestedPackages: toUpdate.map(specBaseName) }, - promise: pkgModel.dry_run_preview(toUpdate, 'update', theEnvironment) + promise: Promise.resolve(updatePreview) }); } if (toInstall.length > 0) { @@ -284,22 +311,40 @@ export async function applyPackageChanges( title: 'Install packages', requestedPackages: toInstall.map(specBaseName) }, - promise: pkgModel.dry_run_preview( - toInstall, - 'install', - theEnvironment - ) + promise: Promise.resolve(installPreview) }); } - const confirmed = await openPackagePreviewDialog({ - title: 'Preview package changes', - jobs: previewJobs, - acceptLabel: 'Apply' - }); + if ( + !removePreview.has_side_effects && + !updatePreview.has_side_effects && + !installPreview.has_side_effects + ) { + Notification.update({ + id: previewAllNotification, + message: 'No additional changes needed, applying changes...', + type: 'success', + autoClose: 2000 + }); + } - if (!confirmed) { - return false; + if ( + removePreview.has_side_effects || + updatePreview.has_side_effects || + installPreview.has_side_effects + ) { + const confirmed = await openPackagePreviewDialog({ + title: 'Preview package changes', + jobs: previewJobs, + acceptLabel: 'Apply' + }); + + if (!confirmed) { + if (previewAllNotification) { + Notification.dismiss(previewAllNotification); + } + return false; + } } } @@ -313,6 +358,9 @@ export async function applyPackageChanges( } }); + if (previewAllNotification) { + Notification.dismiss(previewAllNotification); + } toastId = Notification.emit('Starting packages actions', 'in-progress'); if (toRemove.length > 0) { @@ -361,17 +409,43 @@ export async function applyPackageChanges( return true; } catch (error) { + console.error('Error when applying package changes: ', error); + const fullError = formatPreviewErrorForDialog(error); + const firstNewLine = fullError.indexOf('\n'); + const firstLine = + firstNewLine === -1 ? fullError : fullError.slice(0, firstNewLine); + if (error !== 'cancelled') { - console.error(error); if (toastId) { + if (previewAllNotification) { + Notification.dismiss(previewAllNotification); + } Notification.update({ id: toastId, - message: (error as any).message, + message: firstLine, type: 'error', - autoClose: 0 + autoClose: false, + actions: [ + { + label: 'Show details', + callback: () => { + openPreviewErrorDialog(fullError); + } + } + ] }); } else { - Notification.error((error as any).message); + Notification.emit(firstLine, 'error', { + autoClose: false, + actions: [ + { + label: 'Show details', + callback: () => { + openPreviewErrorDialog(fullError); + } + } + ] + }); } // Emit failed signal @@ -381,13 +455,16 @@ export async function applyPackageChanges( status: 'failed', details: { packagesAffected: selectedPackages.length, - error: (error as any).message + error: firstLine } }); } else { if (toastId) { Notification.dismiss(toastId); } + if (previewAllNotification) { + Notification.dismiss(previewAllNotification); + } } return false; diff --git a/yarn.lock b/yarn.lock index c9db72fe..0b5b07e0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15478,21 +15478,21 @@ __metadata: "typescript@patch:typescript@>=3 < 6#~builtin": version: 5.9.3 - resolution: "typescript@patch:typescript@npm%3A5.9.3#~builtin::version=5.9.3&hash=5786d5" + resolution: "typescript@patch:typescript@npm%3A5.9.3#~builtin::version=5.9.3&hash=85af82" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: a5a6dc399d3761ded54192031f11d3ad5df8001c7febe3fbbc8098efcb552cdf8f2f402b3618c56dafcd04fef63dee005f4900f608e185404caedc46480539ed + checksum: 8bb8d86819ac86a498eada254cad7fb69c5f74778506c700c2a712daeaff21d3a6f51fd0d534fe16903cb010d1b74f89437a3d02d4d0ff5ca2ba9a4660de8497 languageName: node linkType: hard "typescript@patch:typescript@~5.0.2#~builtin": version: 5.0.4 - resolution: "typescript@patch:typescript@npm%3A5.0.4#~builtin::version=5.0.4&hash=b5f058" + resolution: "typescript@patch:typescript@npm%3A5.0.4#~builtin::version=5.0.4&hash=85af82" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: d26b6ba97b6d163c55dbdffd9bbb4c211667ebebc743accfeb2c8c0154aace7afd097b51165a72a5bad2cf65a4612259344ff60f8e642362aa1695c760d303ac + checksum: bb309d320c59a26565fb3793dba550576ab861018ff3fd1b7fccabbe46ae4a35546bc45f342c0a0b6f265c801ccdf64ffd68f548f117ceb7f0eac4b805cd52a9 languageName: node linkType: hard