Skip to content

Commit

Permalink
Add tutorials as generic resources.
Browse files Browse the repository at this point in the history
Generalise resource loading and display.
Add a bit of a hack to handle ProjectContents and WorkflowContents.
  • Loading branch information
eatyourgreens committed Jun 14, 2017
1 parent f294e03 commit 1733091
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 16 deletions.
25 changes: 18 additions & 7 deletions src/components/ProjectDashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,23 @@ function ProjectDashboard(props) {
</ProjectContentsContainer>
<h3>Workflows</h3>
<ul>
{project.workflows.map((workflow) => {
return (
<li key={workflow.id}>
<Link to={`/project/${project.id}/workflow/${workflow.id}`}>{workflow.display_name}</Link>
</li>
);
})}
{project.workflows.map((workflow) => {
return (
<li key={workflow.id}>
<Link to={`/project/${project.id}/workflows/${workflow.id}`}>{workflow.display_name}</Link>
</li>
);
})}
</ul>
<h3>Tutorials</h3>
<ul>
{project.tutorials.map((tutorial) => {
return (
<li key={tutorial.id}>
<Link to={`/project/${project.id}/tutorials/${tutorial.id}`}>{tutorial.id}: {tutorial.display_name}</Link>
</li>
);
})}
</ul>
</div>
);
Expand All @@ -34,6 +44,7 @@ ProjectDashboard.propTypes = propTypes;

ProjectDashboard.defaultProps = {
project: {
tutorials: [],
workflows: []
}
};
Expand Down
30 changes: 30 additions & 0 deletions src/components/Resource.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import PropTypes from 'prop-types';
import fixIt, { options } from 'react-fix-it';
import Tutorial from './Tutorial';
import WorkflowContents from './WorkflowContents';

const resources = {
tutorials: Tutorial,
workflows: WorkflowContents
};

const propTypes = {
contents: PropTypes.object.isRequired,
params: PropTypes.shape({
resource_type: PropTypes.string
})
};

options.log = (test) => {
console.warn(test);
};

function Resource(props) {
const { contents } = props;
const ResourceViewer = resources[props.params.resource_type];
return (<ResourceViewer contents={contents} />);
}

Resource.propTypes = propTypes;
export default fixIt(Resource);
29 changes: 29 additions & 0 deletions src/components/Tutorial.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import PropTypes from 'prop-types';
import fixIt, { options } from 'react-fix-it';

const propTypes = {
contents: PropTypes.object.isRequired,
};

options.log = (test) => {
console.warn(test);
};

function Tutorial(props) {
const { contents } = props;
const tutorial = contents.data.length ? contents.data[0] : { steps: [] };
const steps = [];
tutorial.steps && tutorial.steps.map((step, key) => {
steps.push(<p key={key}><b>{key}</b> {step.content}</p>);
});
return (
<div>
<h2>Tutorial</h2>
{steps}
</div>
);
}

Tutorial.propTypes = propTypes;
export default fixIt(Tutorial);
2 changes: 1 addition & 1 deletion src/containers/ProjectContentsContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class ProjectContentsContainer extends Component {

componentDidMount() {
const { actions } = this.props;
const type = this.props.routes[2].path;
const type = this.props.params.resource_type;
const id = type ? this.props.params.resource_id : this.props.params.project_id;
return actions.fetchResource(id, type);
}
Expand Down
27 changes: 27 additions & 0 deletions src/ducks/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ export const FETCH_PROJECT_ERROR = 'FETCH_PROJECT_ERROR';
export const FETCH_WORKFLOWS = 'FETCH_WORKFLOWS';
export const FETCH_WORKFLOWS_SUCCESS = 'FETCH_WORKFLOWS_SUCCESS';
export const FETCH_WORKFLOWS_ERROR = 'FETCH_WORKFLOWS_ERROR';
export const FETCH_TUTORIALS = 'FETCH_TUTORIALS';
export const FETCH_TUTORIALS_SUCCESS = 'FETCH_TUTORIALS_SUCCESS';
export const FETCH_TUTORIALS_ERROR = 'FETCH_TUTORIALS_ERROR';

// Reducer
const initialState = {
data: {
tutorials: [],
workflows: []
},
error: false,
Expand All @@ -32,6 +36,13 @@ const projectReducer = (state = initialState, action) => {
data: Object.assign(state.data, { workflows: action.payload }),
loading: false
});
case FETCH_TUTORIALS:
return Object.assign({}, state, { loading: true });
case FETCH_TUTORIALS_SUCCESS:
return Object.assign({}, state, {
data: Object.assign(state.data, { tutorials: action.payload }),
loading: false
});
default:
return state;
}
Expand All @@ -52,6 +63,7 @@ const fetchProject = (id) => {
.then(([project]) => {
project.workflows = [];
dispatch(fetchWorkflows(project));
dispatch(fetchTutorials(project))
dispatch({
type: FETCH_PROJECT_SUCCESS,
payload: project,
Expand All @@ -75,6 +87,21 @@ function fetchWorkflows(project) {
};
}

function fetchTutorials(project) {
return (dispatch) => {
dispatch({
type: FETCH_TUTORIALS,
});
apiClient.type('tutorials').get({project_id: project.id})
.then((tutorials) => {
dispatch({
type: FETCH_TUTORIALS_SUCCESS,
payload: tutorials,
});
});
};
}

// Exports
export default projectReducer;

Expand Down
40 changes: 36 additions & 4 deletions src/ducks/resource.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,55 @@ const resourceReducer = (state = initialState, action) => {

// Action Creators
const fetchResource = (id, type) => {
type = type ? type.split('/')[0] : 'project';
type = type ? type : 'projects';
return (dispatch) => {
switch (type) {
case 'projects':
case 'workflows':
dispatch(fetchResourceContents(id, type));
break;
default:
dispatch({
type: FETCH_RESOURCE,
});
apiClient.type(type).get({ id })
.then((resource) => {
dispatch({
type: FETCH_RESOURCE_SUCCESS,
payload: resource,
});
});
}
};
};

function fetchResourceContents(id, type) {
return (dispatch) => {
dispatch({
type: FETCH_RESOURCE,
});
const key = `${type}_id`;
let key = '';
switch (type) {
case 'projects':
key = 'project_id';
type = 'project_contents';
break;
case 'workflows':
key = 'workflow_id';
type = 'workflow_contents';
break;
}
const query = {};
query[key] = id;
apiClient.type(`${type}_contents`).get(query)
apiClient.type(type).get(query)
.then((resource) => {
dispatch({
type: FETCH_RESOURCE_SUCCESS,
payload: resource,
});
});
};
};
}

const createNewTranslation = (type) =>
(dispatch, getState) => {
Expand Down
7 changes: 3 additions & 4 deletions src/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ import About from './components/About';
import config from './config';
import configureStore from './store';
import ProjectContentsContainer from './containers/ProjectContentsContainer';
import ProjectContents from './components/ProjectContents';
import ProjectDashboardContainer from './containers/ProjectDashboardContainer';
import ProjectDashboard from './components/ProjectDashboard';
import ProjectList from './containers/ProjectListContainer';
import WorkflowContents from './components/WorkflowContents';
import Resource from './components/Resource';

// Todo: let's find a better way to include Styles,
// currently Styles looks like an unused var to eslint
Expand All @@ -30,8 +29,8 @@ oauth.init(config.panoptesAppId)
<IndexRoute component={ProjectList} />
<Route path="/project/:project_id" component={ProjectDashboardContainer}>
<IndexRoute component={ProjectDashboard} />
<Route path="workflow/" component={ProjectContentsContainer}>
<Route path=":resource_id" component={WorkflowContents} />
<Route path=":resource_type/" component={ProjectContentsContainer}>
<Route path=":resource_id" component={Resource} />
</Route>
</Route>
<Route path="/about" component={About} />
Expand Down

0 comments on commit 1733091

Please sign in to comment.