Skip to content
This repository has been archived by the owner on Jun 17, 2021. It is now read-only.

Commit

Permalink
Queue and batch dependency actions (#181)
Browse files Browse the repository at this point in the history
* update redux action structure
- update dependencies reducer and tests
- add queue reducer and tests
- move snapshots to separate directory
- add `queued-` statuses

* update dependency saga for queued actions
- update depedency saga tests
- add loadProjectDependencies to read-from-disk.service

* update UI to use new queue methods

* fix flow typing

* update UI to reflect new queue/batch actions
- update tests to reflect structural changes
- exclude `queue` state from redux-storage

* add queue indicator to dependency list

* resolve review comments
  • Loading branch information
superhawk610 authored and joshwcomeau committed Sep 2, 2018
1 parent 5e48bb3 commit 280421e
Show file tree
Hide file tree
Showing 21 changed files with 1,567 additions and 570 deletions.
156 changes: 92 additions & 64 deletions src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@
import uuid from 'uuid/v1';

import { loadAllProjectDependencies } from '../services/read-from-disk.service';
import { getInternalProjectById } from '../reducers/projects.reducer';

import type { Project, ProjectsMap, Task, Dependency } from '../types';
import type {
Project,
ProjectsMap,
Task,
Dependency,
QueuedDependency,
} from '../types';

//
//
Expand All @@ -31,15 +36,18 @@ export const RECEIVE_DATA_FROM_TASK_EXECUTION =
export const LAUNCH_DEV_SERVER = 'LAUNCH_DEV_SERVER';
export const CLEAR_CONSOLE = 'CLEAR_CONSOLE';
export const LOAD_DEPENDENCY_INFO_FROM_DISK = 'LOAD_DEPENDENCY_INFO_FROM_DISK';
export const ADD_DEPENDENCY_START = 'ADD_DEPENDENCY_START';
export const ADD_DEPENDENCY_ERROR = 'ADD_DEPENDENCY_ERROR';
export const ADD_DEPENDENCY_FINISH = 'ADD_DEPENDENCY_FINISH';
export const UPDATE_DEPENDENCY_START = 'UPDATE_DEPENDENCY_START';
export const UPDATE_DEPENDENCY_ERROR = 'UPDATE_DEPENDENCY_ERROR';
export const UPDATE_DEPENDENCY_FINISH = 'UPDATE_DEPENDENCY_FINISH';
export const DELETE_DEPENDENCY_START = 'DELETE_DEPENDENCY_START';
export const DELETE_DEPENDENCY_ERROR = 'DELETE_DEPENDENCY_ERROR';
export const DELETE_DEPENDENCY_FINISH = 'DELETE_DEPENDENCY_FINISH';
export const ADD_DEPENDENCY = 'ADD_DEPENDENCY';
export const UPDATE_DEPENDENCY = 'UPDATE_DEPENDENCY';
export const DELETE_DEPENDENCY = 'DELETE_DEPENDENCY';
export const INSTALL_DEPENDENCIES_START = 'INSTALL_DEPENDENCIES_START';
export const INSTALL_DEPENDENCIES_ERROR = 'INSTALL_DEPENDENCIES_ERROR';
export const INSTALL_DEPENDENCIES_FINISH = 'INSTALL_DEPENDENCIES_FINISH';
export const UNINSTALL_DEPENDENCIES_START = 'UNINSTALL_DEPENDENCIES_START';
export const UNINSTALL_DEPENDENCIES_ERROR = 'UNINSTALL_DEPENDENCIES_ERROR';
export const UNINSTALL_DEPENDENCIES_FINISH = 'UNINSTALL_DEPENDENCIES_FINISH';
export const QUEUE_DEPENDENCY_INSTALL = 'QUEUE_DEPENDENCY_INSTALL';
export const QUEUE_DEPENDENCY_UNINSTALL = 'QUEUE_DEPENDENCY_UNINSTALL';
export const START_NEXT_ACTION_IN_QUEUE = 'START_NEXT_ACTION_IN_QUEUE';
export const SHOW_IMPORT_EXISTING_PROJECT_PROMPT =
'SHOW_IMPORT_EXISTING_PROJECT_PROMPT';
export const IMPORT_EXISTING_PROJECT_START = 'IMPORT_EXISTING_PROJECT_START';
Expand Down Expand Up @@ -87,20 +95,13 @@ export const loadDependencyInfoFromDisk = (
projectPath: string
) => {
return (dispatch: any, getState: Function) => {
// The `project` this action receives is the "fit-for-consumption" one.
// We need the internal version, `ProjectInternal`, so that we can see the
// raw dependency information.
const internalProject = getInternalProjectById(getState(), projectId);

loadAllProjectDependencies(internalProject, projectPath).then(
dependencies => {
dispatch({
type: LOAD_DEPENDENCY_INFO_FROM_DISK,
projectId,
dependencies,
});
}
);
loadAllProjectDependencies(projectPath).then(dependencies => {
dispatch({
type: LOAD_DEPENDENCY_INFO_FROM_DISK,
projectId,
dependencies,
});
});
};
};

Expand Down Expand Up @@ -182,91 +183,118 @@ export const clearConsole = (task: Task) => ({
task,
});

export const deleteDependencyStart = (
export const addDependency = (projectId: string, dependencyName: string) => ({
type: ADD_DEPENDENCY,
projectId,
dependencyName,
});

export const updateDependency = (
projectId: string,
dependencyName: string
dependencyName: string,
latestVersion: string
) => ({
type: DELETE_DEPENDENCY_START,
type: UPDATE_DEPENDENCY,
projectId,
dependencyName,
latestVersion,
});

export const deleteDependencyError = (
export const deleteDependency = (
projectId: string,
dependencyName: string
) => ({
type: DELETE_DEPENDENCY_ERROR,
type: DELETE_DEPENDENCY,
projectId,
dependencyName,
});

export const deleteDependencyFinish = (
export const installDependenciesStart = (
projectId: string,
dependencyName: string
dependencies: Array<QueuedDependency>
) => ({
type: DELETE_DEPENDENCY_FINISH,
type: INSTALL_DEPENDENCIES_START,
projectId,
dependencyName,
dependencies,
});

export const updateDependencyStart = (
export const installDependencyStart = (
projectId: string,
dependencyName: string,
latestVersion: string
name: string,
version: string,
updating?: boolean
) => installDependenciesStart(projectId, [{ name, version, updating }]);

export const installDependenciesError = (
projectId: string,
dependencies: Array<QueuedDependency>
) => ({
type: UPDATE_DEPENDENCY_START,
type: INSTALL_DEPENDENCIES_ERROR,
projectId,
dependencyName,
latestVersion,
dependencies,
});

export const updateDependencyError = (
export const installDependenciesFinish = (
projectId: string,
dependencyName: string
dependencies: Array<Dependency>
) => ({
type: UPDATE_DEPENDENCY_ERROR,
type: INSTALL_DEPENDENCIES_FINISH,
projectId,
dependencyName,
dependencies,
});

export const updateDependencyFinish = (
export const uninstallDependenciesStart = (
projectId: string,
dependencyName: string,
latestVersion: string
dependencies: Array<QueuedDependency>
) => ({
type: UPDATE_DEPENDENCY_FINISH,
type: UNINSTALL_DEPENDENCIES_START,
projectId,
dependencyName,
latestVersion,
dependencies,
});

export const addDependencyStart = (
export const uninstallDependencyStart = (projectId: string, name: string) =>
uninstallDependenciesStart(projectId, [{ name }]);

export const uninstallDependenciesError = (
projectId: string,
dependencyName: string,
version: string
dependencies: Array<QueuedDependency>
) => ({
type: ADD_DEPENDENCY_START,
type: UNINSTALL_DEPENDENCIES_ERROR,
projectId,
dependencyName,
version,
dependencies,
});

export const addDependencyError = (
export const uninstallDependenciesFinish = (
projectId: string,
dependencyName: string
dependencies: Array<QueuedDependency>
) => ({
type: ADD_DEPENDENCY_ERROR,
type: UNINSTALL_DEPENDENCIES_FINISH,
projectId,
dependencyName,
dependencies,
});

export const addDependencyFinish = (
export const queueDependencyInstall = (
projectId: string,
dependency: Dependency
name: string,
version: string,
updating?: boolean
) => ({
type: ADD_DEPENDENCY_FINISH,
type: QUEUE_DEPENDENCY_INSTALL,
projectId,
name,
version,
updating,
});

export const queueDependencyUninstall = (projectId: string, name: string) => ({
type: QUEUE_DEPENDENCY_UNINSTALL,
projectId,
name,
});

export const startNextActionInQueue = (projectId: string) => ({
type: START_NEXT_ACTION_IN_QUEUE,
projectId,
dependency,
});

export const showImportExistingProjectPrompt = () => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
getSelectedProjectId,
getDependencyMapForSelectedProject,
} from '../../reducers/projects.reducer';
import { getPackageJsonLockedForProjectId } from '../../reducers/package-json-locked.reducer';
import { COLORS } from '../../constants';

import Spacer from '../Spacer';
Expand All @@ -26,11 +25,20 @@ import CustomHighlight from '../CustomHighlight';

import type { DependencyStatus } from '../../types';

const DEPENDENCY_ACTIONS_COPY = {
idle: 'Installed',
installing: 'Installing…',
updating: 'Updating…',
deleting: 'Deleting…',
'queued-install': 'Queued for Install',
'queued-update': 'Queued for Update',
'queued-delete': 'Queued for Delete',
};

type Props = {
projectId: string,
currentStatus: ?DependencyStatus,
isPackageJsonLocked: boolean,
addDependencyStart: (
addDependency: (
projectId: string,
dependencyName: string,
version: string
Expand Down Expand Up @@ -77,23 +85,10 @@ const getColorForDownloadNumber = (num: number) => {

class AddDependencySearchResult extends PureComponent<Props> {
renderActionArea() {
const {
hit,
projectId,
currentStatus,
isPackageJsonLocked,
addDependencyStart,
} = this.props;

if (currentStatus === 'installing') {
return (
<NoActionAvailable>
<Spinner size={24} />
<Spacer size={6} />
Installing...
</NoActionAvailable>
);
} else if (typeof currentStatus === 'string') {
const { hit, projectId, currentStatus, addDependency } = this.props;
const isAlreadyInstalled = currentStatus === 'idle';

if (isAlreadyInstalled) {
return (
<NoActionAvailable>
<IconBase
Expand All @@ -105,20 +100,29 @@ class AddDependencySearchResult extends PureComponent<Props> {
Installed
</NoActionAvailable>
);
} else {
}

if (currentStatus) {
return (
<Button
size="small"
color1={COLORS.green[700]}
color2={COLORS.lightGreen[500]}
textColor={isPackageJsonLocked ? COLORS.gray[400] : COLORS.green[700]}
disabled={isPackageJsonLocked}
onClick={() => addDependencyStart(projectId, hit.name, hit.version)}
>
Add To Project
</Button>
<NoActionAvailable>
<Spinner size={24} />
<Spacer size={6} />
{DEPENDENCY_ACTIONS_COPY[currentStatus]}
</NoActionAvailable>
);
}

return (
<Button
size="small"
color1={COLORS.green[700]}
color2={COLORS.lightGreen[500]}
textColor={COLORS.green[700]}
onClick={() => addDependency(projectId, hit.name, hit.version)}
>
Add To Project
</Button>
);
}

render() {
Expand Down Expand Up @@ -273,14 +277,10 @@ const mapStateToProps = (state, ownProps) => {
return {
currentStatus,
projectId: selectedProjectId,
isPackageJsonLocked: getPackageJsonLockedForProjectId(
state,
selectedProjectId
),
};
};

const mapDispatchToProps = { addDependencyStart: actions.addDependencyStart };
const mapDispatchToProps = { addDependency: actions.addDependency };

export default connect(
mapStateToProps,
Expand Down
Loading

0 comments on commit 280421e

Please sign in to comment.