Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion web/src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ class API {
static updateProject(projectURL, onSuccess, onFailure) {
// FIXME: this really shouldn't be a GET verb
const url = `${projectURL}?update=`;
fetch(url, {'method': 'GET'}).then(response => {
return fetch(url, {'method': 'GET'}).then(response => {
const cb = response.ok ? onSuccess : onFailure;
response.json().then(body => {
cb(body);
Expand Down
4 changes: 4 additions & 0 deletions web/src/bound-project-activity.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
getProjectSummary,
getProject,
installProject,
updateAllProjects,
updateProject,
removeProject,
} from './model/project-actions';
Expand Down Expand Up @@ -59,6 +60,9 @@ const mapDispatchToProps = dispatch => ({
installProject: (catalogURL, name, onSuccess, onFailure) => {
dispatch(installProject(catalogURL, name, onSuccess, onFailure));
},
updateAllProjects: (projectList, onSuccess, onFailure) => {
dispatch(updateAllProjects(projectList, onSuccess, onFailure));
},
updateProject: (projectURL, name, onSuccess, onFailure) => {
dispatch(updateProject(projectURL, name, onSuccess, onFailure));
},
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/catalog-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const CatalogList = props => {
const catalog = props.catalogs.get(name);
return (
<li key={name}>
<Catalog catalog={catalog} installAction={props.installAction} refreshAction={props.refreshAction} />
<Catalog catalog={catalog} installedProjects={props.installedProjects} installAction={props.installAction} refreshAction={props.refreshAction} />
</li>
);
});
Expand Down
8 changes: 8 additions & 0 deletions web/src/components/catalog.css
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,12 @@

.catalog-entries > li {
margin: 0 0 4px 0;
}

.catalog-installedLabel {
font-style: italic;
font-family: monospace;
width: 10em;
text-align: center;
color: rgb(204, 204, 204);
}
19 changes: 13 additions & 6 deletions web/src/components/catalog.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,29 @@ import ProjectControl from './project-control';
import './catalog.css';

const Catalog = (props) => {
const {catalog} = props;
const {catalog, installedProjects} = props;
const catalogURL = catalog.get('url');

const entries = catalog.get('entries').map(e => {
const projectName = e.get('project_name');
const projectURL = e.get('project_url');
const key = `${projectName}-${projectURL || ""}`; // to silence warnings

return (
<li key={key}>
<ProjectControl>
<ProjectInfo project={e} />
<TextButton color="hsl(0, 0%, 59%)"
action={() => props.installAction(catalogURL, projectName)}
>
install
</TextButton>
{(installedProjects || []).indexOf(projectName) === -1 ? (
<TextButton color="hsl(0, 0%, 59%)"
action={() => props.installAction(catalogURL, projectName)}
>
install
</TextButton>
) : (
<div className='catalog-installedLabel'>
already installed
</div>
)}
</ProjectControl>
</li>
);
Expand Down
16 changes: 16 additions & 0 deletions web/src/components/project-list.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
.project-list-container {
display: flex;
flex-direction: column;
align-items: flex-end;
}

.project-listing {
width: 100%;
list-style: none;
margin: 0px;
padding: 0px;
}

.project-listing li {
margin: 0 0 4px 0;
}

.project-updateAllButton {
color: rgb(150, 150, 150);
background: rgb(249, 249, 249);
padding: 15px;
width: 20em;
margin-right: 32px;
margin-bottom: 5px;
}
8 changes: 7 additions & 1 deletion web/src/components/project-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import ProjectControl from './project-control';
import './project-list.css';

const ProjectList = props => {
const { projects, updateAction, removeAction } = props;
const { projects, updateAllAction, updateAction, removeAction } = props;
let entries = undefined;
const projectList = projects.get('projects') ? projects.get('projects').map(e => ({url: e.get('url'), name: e.get('project_name')})).toArray() : [];
if (projects && projects.has('projects')) {
entries = projects.get('projects').map(p => {
// layer project data over catalog entry (if it exists)
Expand Down Expand Up @@ -43,6 +44,11 @@ const ProjectList = props => {

return (
<div className='project-list-container'>
{projectList.length ? (<TextButton
classes='project-updateAllButton'
color='hsl(0, 0%, 59%)'
action={() => updateAllAction(projectList)}
>update all</TextButton>) : ''}
<ul className='project-listing'>
{entries}
</ul>
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/text-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class TextButton extends Component {
render() {
const style = {color: this.state.color};
return (
<button className='text-button'
<button className={`text-button ${this.props.classes ? ` ${this.props.classes}` : ''}`}
onClick={this.handleClick}
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
Expand Down
10 changes: 10 additions & 0 deletions web/src/modal-content.css
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,14 @@
font-style: italic;
color: rgb(151, 80, 49);
height: 1em;
}

.modal-content table {
width: 100%;
border-collapse: collapse;
}

.modal-content td {
padding: 5px;
border: 1px solid #ccc;
}
2 changes: 1 addition & 1 deletion web/src/modal-content.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const ModalContent = props => {
}

return (
<div className="modal-content">
<div className="modal-content" style={props.style}>
<div className="message-container">
<span className="message">{props.message}</span>
<p />
Expand Down
42 changes: 42 additions & 0 deletions web/src/model/project-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ export const PROJECT_INSTALL_REQUEST = 'PROJECT_INSTALL_REQUEST';
export const PROJECT_INSTALL_SUCCESS = 'PROJECT_INSTALL_SUCCESS';
export const PROJECT_INSTALL_FAILURE = 'PROJECT_INSTALL_FAILURE';

export const PROJECT_UPDATE_ALL_SUCCESS = 'PROJECT_UPDATE_ALL_SUCCESS';
export const PROJECT_UPDATE_ALL_FAILURE = 'PROJECT_UPDATE_ALL_FAILURE';

export const PROJECT_UPDATE_REQUEST = 'PROJECT_UPDATE_REQUEST';
export const PROJECT_UPDATE_SUCCESS = 'PROJECT_UPDATE_SUCCESS';
export const PROJECT_UPDATE_FAILURE = 'PROJECT_UPDATE_FAILURE';
Expand Down Expand Up @@ -65,6 +68,9 @@ export const projectInstallRequest = (catalog, name) => ({ type: PROJECT_INSTALL
export const projectInstallSuccess = (project, catalog, name) => ({ type: PROJECT_INSTALL_SUCCESS, project, catalog, name });
export const projectInstallFailure = (error, catalog, name) => ({ type: PROJECT_INSTALL_FAILURE, error, catalog, name });

export const projectUpdateAllSuccess = (successArr) => ({ type: PROJECT_UPDATE_ALL_SUCCESS, successArr });
export const projectUpdateAllFailure = (successArr, failureArr) => ({ type: PROJECT_UPDATE_ALL_FAILURE, successArr, failureArr });

export const projectUpdateRequest = (project, name) => ({ type: PROJECT_UPDATE_REQUEST, project, name });
export const projectUpdateSuccess = (project, name) => ({ type: PROJECT_UPDATE_SUCCESS, project, name });
export const projectUpdateFailure = (error, project, name) => ({ type: PROJECT_UPDATE_FAILURE, error, project, name });
Expand Down Expand Up @@ -181,6 +187,42 @@ export const installProject = (catalog, name, onSuccess, onFailure) => dispatch
});
};

export const updateAllProjects = (projects, onSuccess, onFailure) => dispatch => {
const successArr = [];
const failureArr = [];
const requestsArr = [];
projects.forEach(({url,name}) => {
dispatch(projectUpdateRequest(url, name));
const promise = new Promise((resolve) => {
API.updateProject(url,
successResult => {
successArr.push({successResult, url, name});
resolve('resolved');
},
failureResult => {
console.log("got here")
failureArr.push({failureResult, url, name});
resolve('resolved');
});
});
console.log(promise);
requestsArr.push(promise);
});
Promise.all(requestsArr).then(_ => {
if (failureArr.length) {
dispatch(projectUpdateAllFailure(successArr, failureArr));
if (onFailure) {
onFailure(successArr, failureArr);
}
} else {
dispatch(projectUpdateAllSuccess(successArr));
if (onSuccess) {
onSuccess(successArr);
}
}
});
};

export const updateProject = (project, name, onSuccess, onFailure) => dispatch => {
dispatch(projectUpdateRequest(project, name));
return API.updateProject(project,
Expand Down
69 changes: 69 additions & 0 deletions web/src/project-activity.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,73 @@ class ProjectActivity extends Component {
return(content);
};

handleUpdateAllAction = (projectList) => {
const modalCompletion = choice => {
if (choice === 'ok') {
this.props.updateAllProjects(projectList,
successArr => {
successArr = successArr.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
this.props.getProjectSummary();
this.props.refreshCodeDir();
this.props.showModal(<ModalContent
message='Updating all projects succeeded.'
supporting={`${successArr.length ? `The following projects were updated:\n\n${successArr.map(e => e.name).join('\n')}.` : ''}`}
style={{whiteSpace: 'pre-line'}}
buttonAction={this.modalDismiss}
confirmOnly={true}
/>)
},
(successArr, failureArr) => {
successArr = successArr.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
failureArr = failureArr.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
this.props.getProjectSummary();
this.props.refreshCodeDir();
this.props.showModal(<ModalContent
message='Updating all projects failed.'
supporting={<span>{successArr.length ? (<div>The following projects were updated:<br /><br /><table><tbody>{successArr.map(e => (<tr><td>{e.name}</td></tr>))}</tbody></table><br /><br /></div>) : ''}
<div>The following errors happened:<br /><br /><table><tbody>{failureArr.map(e => (<tr><td style={{ width: '100px' }}>{e.name}</td><td style={{ width: 'auto' }}>{e.failureResult.error}</td></tr>))}</tbody></table></div></span>}
buttonAction={this.modalDismiss}
confirmOnly={true}
/>)
});
this.props.showModal(
<ModalContent
message='Updating all projects'
supporting="please wait..."
buttonAction={this.modalDismiss}
confirmOnly={true}
/>
);
} else {
// update request canceled
this.props.hideModal();
<table>
<thead>
<tr>
<th colspan="2">The table header</th>
</tr>
</thead>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jlmitch5 - this stray table markup seems like a left over from some earlier work, correct?

<tbody>
<tr>
<td>The table body</td>
<td>with two columns</td>
</tr>
</tbody>
</table>
}
};

const modalContent = (
<ModalContent
message={`Update all projects?`}
supporting="Local modifications will be overwritten"
buttonAction={modalCompletion}
/>
);

this.props.showModal(modalContent);
};


handleUpdateAction = (url, name) => {
console.log('doing update', url);
Expand Down Expand Up @@ -179,12 +246,14 @@ class ProjectActivity extends Component {
<ProjectList
name='installed'
projects={this.props.projectSummary}
updateAllAction={this.handleUpdateAllAction}
updateAction={this.handleUpdateAction}
removeAction={this.handleRemoveAction}
/>
<CatalogList
name='available'
catalogSummary={this.props.catalogSummary}
installedProjects={this.props.projectSummary.get('projects') && this.props.projectSummary.get('projects').map(e => e.get('project_name'))}
catalogs={this.props.catalogs}
installAction={this.handleInstallAction}
refreshAction={this.handleRefreshAction}
Expand Down