Skip to content

Commit bca68f5

Browse files
authored
Merge pull request #320 from RRosio/pkg_actions
Split package actions from frontend components and add signals
2 parents 3f0b729 + d3a544b commit bca68f5

File tree

8 files changed

+405
-185
lines changed

8 files changed

+405
-185
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { CommandRegistry } from '@lumino/commands';
2+
import { Conda } from '../tokens';
3+
import {
4+
updateAllPackages,
5+
applyPackageChanges,
6+
refreshAvailablePackages as refreshAvailablePkgs
7+
} from '../packageActions';
8+
9+
export function registerPkgCommands(
10+
commands: CommandRegistry,
11+
pkgModel: Conda.IPackageManager
12+
) {
13+
commands.addCommand('gator-lab:update-all-packages', {
14+
label: 'Update All Packages',
15+
execute: async args => {
16+
const environment = args['environment'] as string;
17+
await updateAllPackages(pkgModel, environment);
18+
}
19+
});
20+
21+
commands.addCommand('gator-lab:apply-package-changes', {
22+
label: 'Apply Package Changes',
23+
execute: async args => {
24+
const selectedPackages = args[
25+
'selectedPackages'
26+
] as unknown as Conda.IPackage[];
27+
const environment = args['environment'] as string;
28+
await applyPackageChanges(pkgModel, selectedPackages, environment);
29+
}
30+
});
31+
commands.addCommand('gator-lab:refresh-available-packages', {
32+
label: 'Refresh Available Packages',
33+
execute: async args => {
34+
const environment = args['environment'] as string;
35+
await refreshAvailablePkgs(pkgModel, environment);
36+
}
37+
});
38+
}

packages/common/src/components/CondaPkgPanel.tsx

Lines changed: 41 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ import {
1010
PkgFilters
1111
} from './CondaPkgToolBar';
1212
import { PkgGraphWidget } from './PkgGraph';
13+
import {
14+
updateAllPackages,
15+
applyPackageChanges,
16+
refreshAvailablePackages as refreshAvailablePkgs
17+
} from '../packageActions';
1318

1419
// Minimal panel width to show package description
1520
const PANEL_SMALL_WIDTH = 500;
@@ -121,11 +126,6 @@ export class CondaPkgPanel extends React.Component<
121126
selected: []
122127
});
123128

124-
const loadingNotification = Notification.emit(
125-
`Loading packages for ${environmentName}...`,
126-
'in-progress'
127-
);
128-
129129
try {
130130
const environmentLoading =
131131
this._currentEnvironment || this._model.environment;
@@ -164,32 +164,32 @@ export class CondaPkgPanel extends React.Component<
164164
packages: available,
165165
hasUpdate
166166
});
167-
168-
Notification.update({
169-
id: loadingNotification,
170-
message: `Packages loaded successfully for ${environmentName}`,
171-
type: 'success',
172-
autoClose: 3000
173-
});
174167
} catch (error) {
175168
if ((error as any).message !== 'cancelled') {
176-
this.setState({
177-
isLoading: false
178-
});
179169
console.error(error);
180-
181-
Notification.update({
182-
id: loadingNotification,
183-
message: `Failed to load packages for ${environmentName}`,
184-
type: 'error',
185-
autoClose: 0
186-
});
187-
} else {
188-
Notification.dismiss(loadingNotification);
170+
Notification.error(`Failed to load packages for ${environmentName}`);
189171
}
172+
} finally {
173+
this.setState({
174+
isLoading: false
175+
});
190176
}
191177
}
192178

179+
/**
180+
* Cancel package changes (reset selection state)
181+
*
182+
* @param selectedPackages List of packages with pending changes
183+
*/
184+
private _cancelPackageChanges(selectedPackages: Conda.IPackage[]): void {
185+
selectedPackages.forEach(
186+
pkg =>
187+
(pkg.version_selected = pkg.version_installed
188+
? pkg.version_installed
189+
: 'none')
190+
);
191+
}
192+
193193
handleCategoryChanged(event: React.ChangeEvent<HTMLSelectElement>): void {
194194
if (this.state.isApplyingChanges) {
195195
return;
@@ -295,50 +295,15 @@ export class CondaPkgPanel extends React.Component<
295295
return;
296296
}
297297

298-
let toastId = '';
298+
// TODO: Handle the case where the user cancels the update: show a notification here rather than in the packageActions.ts file
299299
try {
300300
this.setState({
301301
searchTerm: '',
302-
activeFilter: PkgFilters.Updatable
303-
});
304-
305-
const confirmation = await showDialog({
306-
title: 'Update all',
307-
body: 'Please confirm you want to update all packages? Conda enforces environment consistency. So maybe only a subset of the available updates will be applied.'
302+
activeFilter: PkgFilters.Updatable,
303+
isApplyingChanges: true
308304
});
309305

310-
if (confirmation.button.accept) {
311-
this.setState({
312-
isApplyingChanges: true
313-
});
314-
toastId = Notification.emit('Updating packages', 'in-progress');
315-
await this._model.update(['--all'], this._currentEnvironment);
316-
317-
Notification.update({
318-
id: toastId,
319-
message: 'Package updated successfully.',
320-
type: 'success',
321-
autoClose: 5000
322-
});
323-
}
324-
} catch (error) {
325-
if (error !== 'cancelled') {
326-
console.error(error);
327-
if (toastId) {
328-
Notification.update({
329-
id: toastId,
330-
message: (error as any).message,
331-
type: 'error',
332-
autoClose: 0
333-
});
334-
} else {
335-
Notification.error((error as any).message);
336-
}
337-
} else {
338-
if (toastId) {
339-
Notification.dismiss(toastId);
340-
}
341-
}
306+
await updateAllPackages(this._model, this._currentEnvironment);
342307
} finally {
343308
this.setState({
344309
isApplyingChanges: false,
@@ -360,91 +325,19 @@ export class CondaPkgPanel extends React.Component<
360325
return;
361326
}
362327

363-
let toastId = '';
328+
// TODO: Handle the case where the user cancels the modifications: show a notification here rather than in the packageActions.ts file
364329
try {
365330
this.setState({
366331
searchTerm: '',
367-
activeFilter: PkgFilters.Selected
332+
activeFilter: PkgFilters.Selected,
333+
isApplyingChanges: true
368334
});
369335

370-
const confirmation = await showDialog({
371-
title: 'Packages actions',
372-
body: 'Please confirm you want to apply the selected actions?'
373-
});
374-
375-
if (confirmation.button.accept) {
376-
this.setState({
377-
isApplyingChanges: true
378-
});
379-
toastId = Notification.emit('Starting packages actions', 'in-progress');
380-
381-
// Get modified pkgs
382-
const toRemove: Array<string> = [];
383-
const toUpdate: Array<string> = [];
384-
const toInstall: Array<string> = [];
385-
this.state.selected.forEach(pkg => {
386-
if (pkg.version_installed && pkg.version_selected === 'none') {
387-
toRemove.push(pkg.name);
388-
} else if (pkg.updatable && pkg.version_selected === '') {
389-
toUpdate.push(pkg.name);
390-
} else {
391-
toInstall.push(
392-
pkg.version_selected
393-
? pkg.name + '=' + pkg.version_selected
394-
: pkg.name
395-
);
396-
}
397-
});
398-
399-
if (toRemove.length > 0) {
400-
Notification.update({
401-
id: toastId,
402-
message: 'Removing selected packages'
403-
});
404-
await this._model.remove(toRemove, this._currentEnvironment);
405-
}
406-
407-
if (toUpdate.length > 0) {
408-
Notification.update({
409-
id: toastId,
410-
message: 'Updating selected packages'
411-
});
412-
await this._model.update(toUpdate, this._currentEnvironment);
413-
}
414-
415-
if (toInstall.length > 0) {
416-
Notification.update({
417-
id: toastId,
418-
message: 'Installing new packages'
419-
});
420-
await this._model.install(toInstall, this._currentEnvironment);
421-
}
422-
423-
Notification.update({
424-
id: toastId,
425-
message: 'Package actions successfully done.',
426-
type: 'success',
427-
autoClose: 5000
428-
});
429-
}
430-
} catch (error) {
431-
if (error !== 'cancelled') {
432-
console.error(error);
433-
if (toastId) {
434-
Notification.update({
435-
id: toastId,
436-
message: (error as any).message,
437-
type: 'error',
438-
autoClose: 0
439-
});
440-
} else {
441-
Notification.error((error as any).message);
442-
}
443-
} else {
444-
if (toastId) {
445-
Notification.dismiss(toastId);
446-
}
447-
}
336+
await applyPackageChanges(
337+
this._model,
338+
this.state.selected,
339+
this._currentEnvironment
340+
);
448341
} finally {
449342
this.setState({
450343
isApplyingChanges: false,
@@ -460,53 +353,23 @@ export class CondaPkgPanel extends React.Component<
460353
return;
461354
}
462355

463-
this.state.selected.forEach(
464-
pkg =>
465-
(pkg.version_selected = pkg.version_installed
466-
? pkg.version_installed
467-
: 'none')
468-
);
356+
this._cancelPackageChanges(this.state.selected);
469357

470358
this.setState({
471359
selected: []
472360
});
473361
}
474362

475363
async handleRefreshPackages(): Promise<void> {
476-
const environmentName = this._currentEnvironment || this._model.environment;
477-
if (!environmentName) {
364+
if (this.state.isApplyingChanges) {
478365
return;
479366
}
480367

481-
const refreshNotification = Notification.emit(
482-
`Refreshing available packages for ${environmentName}...`,
483-
'in-progress'
484-
);
485-
486368
try {
487-
await this._model.refreshAvailablePackages();
488-
489-
Notification.update({
490-
id: refreshNotification,
491-
message: `Available packages refreshed for ${environmentName}`,
492-
type: 'success',
493-
autoClose: 3000
494-
});
495-
} catch (error) {
496-
if ((error as any).message !== 'cancelled') {
497-
console.error('Error when refreshing the available packages.', error);
498-
499-
Notification.update({
500-
id: refreshNotification,
501-
message: `Failed to refresh available packages for ${environmentName}`,
502-
type: 'error',
503-
autoClose: 0
504-
});
505-
} else {
506-
Notification.dismiss(refreshNotification);
507-
}
369+
await refreshAvailablePkgs(this._model, this._currentEnvironment);
370+
} finally {
371+
this._updatePackages();
508372
}
509-
this._updatePackages();
510373
}
511374

512375
componentDidUpdate(prevProps: IPkgPanelProps): void {

packages/common/src/index.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,5 @@ export * from './constants';
33
export * from './icon';
44
export { CondaEnvironments } from './services';
55
export { Conda, IEnvironmentManager } from './tokens';
6-
export {
7-
cloneEnvironment,
8-
exportEnvironment,
9-
removeEnvironment
10-
} from './environmentActions';
116
export { registerEnvCommands } from './commands/registerEnvCommands';
7+
export { registerPkgCommands } from './commands/registerPkgCommands';

0 commit comments

Comments
 (0)