diff --git a/src/components/ProjectDashboard.jsx b/src/components/ProjectDashboard.jsx
index dfc81ef2..aa8e4825 100644
--- a/src/components/ProjectDashboard.jsx
+++ b/src/components/ProjectDashboard.jsx
@@ -18,13 +18,23 @@ function ProjectDashboard(props) {
Workflows
- {project.workflows.map((workflow) => {
- return (
- -
- {workflow.display_name}
-
- );
- })}
+ {project.workflows.map((workflow) => {
+ return (
+ -
+ {workflow.display_name}
+
+ );
+ })}
+
+ Tutorials
+
+ {project.tutorials.map((tutorial) => {
+ return (
+ -
+ {tutorial.id}: {tutorial.display_name}
+
+ );
+ })}
);
@@ -34,6 +44,7 @@ ProjectDashboard.propTypes = propTypes;
ProjectDashboard.defaultProps = {
project: {
+ tutorials: [],
workflows: []
}
};
diff --git a/src/components/Resource.jsx b/src/components/Resource.jsx
new file mode 100644
index 00000000..a1551932
--- /dev/null
+++ b/src/components/Resource.jsx
@@ -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 ();
+}
+
+Resource.propTypes = propTypes;
+export default fixIt(Resource);
diff --git a/src/components/Tutorial.jsx b/src/components/Tutorial.jsx
new file mode 100644
index 00000000..e56f4a32
--- /dev/null
+++ b/src/components/Tutorial.jsx
@@ -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({key} {step.content}
);
+ });
+ return (
+
+
Tutorial
+ {steps}
+
+ );
+}
+
+Tutorial.propTypes = propTypes;
+export default fixIt(Tutorial);
diff --git a/src/containers/ProjectContentsContainer.jsx b/src/containers/ProjectContentsContainer.jsx
index 93e22f78..256915f9 100644
--- a/src/containers/ProjectContentsContainer.jsx
+++ b/src/containers/ProjectContentsContainer.jsx
@@ -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);
}
diff --git a/src/ducks/project.js b/src/ducks/project.js
index 1e1c7fc9..0e44faf8 100644
--- a/src/ducks/project.js
+++ b/src/ducks/project.js
@@ -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,
@@ -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;
}
@@ -52,6 +63,7 @@ const fetchProject = (id) => {
.then(([project]) => {
project.workflows = [];
dispatch(fetchWorkflows(project));
+ dispatch(fetchTutorials(project))
dispatch({
type: FETCH_PROJECT_SUCCESS,
payload: project,
@@ -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;
diff --git a/src/ducks/resource.js b/src/ducks/resource.js
index 542989bd..b826e2a6 100644
--- a/src/ducks/resource.js
+++ b/src/ducks/resource.js
@@ -27,15 +27,47 @@ 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,
@@ -43,7 +75,7 @@ const fetchResource = (id, type) => {
});
});
};
-};
+}
const createNewTranslation = (type) =>
(dispatch, getState) => {
diff --git a/src/index.jsx b/src/index.jsx
index 3e7c0101..2f108778 100644
--- a/src/index.jsx
+++ b/src/index.jsx
@@ -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
@@ -30,8 +29,8 @@ oauth.init(config.panoptesAppId)
-
-
+
+