-
-
Mission List
- Create New Mission
-
-
- {missions.length ? (
-
- ) : (
-
No missions found.
- )}
+export const MissionListView = ({missions, offset, limit, total, load, deleteMission}) => {
+ const columns = [{
+ header: 'Mission Name',
+ accessor: 'missionName',
+ }, {
+ id: 'edit',
+ header: '',
+ render: (prop) =>
Edit, // eslint-disable-line react/display-name
+ }, {
+ id: 'download',
+ header: '',
+ render: (prop) =>
Download , // eslint-disable-line react/display-name
+ }, {
+ id: 'delete',
+ header: '',
+ render: (prop) => ( // eslint-disable-line react/display-name
+
{
+ event.preventDefault();
+ deleteMission(prop.row.id);
+ }}
+ >
+ Delete
+
+ ),
+ }];
+
+ return (
+
+
+
+
Mission List
+ Create New Mission
+
+
+ {missions.length ? (
+
+ ) : (
+
No missions found.
+ )}
+
-
-);
+ );
+};
MissionListView.propTypes = {
missions: PropTypes.array.isRequired,
+ load: PropTypes.func.isRequired,
+ offset: PropTypes.number.isRequired,
+ limit: PropTypes.number.isRequired,
+ total: PropTypes.number.isRequired,
deleteMission: PropTypes.func.isRequired,
};
diff --git a/src/routes/MissionList/components/MissionListView.scss b/src/routes/MissionList/components/MissionListView.scss
index 473ffc5..889e3a6 100644
--- a/src/routes/MissionList/components/MissionListView.scss
+++ b/src/routes/MissionList/components/MissionListView.scss
@@ -32,40 +32,6 @@
padding: 19px 24px;
}
-.my-request-table {
- width: 100%;
-}
-
-.thead {
- background-color: #1e526c;
-}
-
-.th {
- color: #fff;
- font-size: 14px;
- font-weight: 400;
- padding: 14px 27px 16px;
- text-align: left;
-}
-
-.tr {
- border-top: 1px solid #e7e8ea;
-
- &:first-child {
- border-top: 0;
- }
-}
-
-.td {
- font-size: 14px;
- padding: 12px 23px;
- white-space: nowrap;
-
- > a {
- color: #3b73b9;
- }
-}
-
.create-btn {
background: #315b95;
border: none;
@@ -80,3 +46,7 @@
color: #fff;
}
}
+
+.table-hidden {
+ display: none;
+}
diff --git a/src/routes/MissionList/modules/MissionList.js b/src/routes/MissionList/modules/MissionList.js
index 3e594be..d7e47fb 100644
--- a/src/routes/MissionList/modules/MissionList.js
+++ b/src/routes/MissionList/modules/MissionList.js
@@ -1,25 +1,29 @@
import {handleActions} from 'redux-actions';
import _ from 'lodash';
import APIService from 'services/APIService';
+import {toastr} from 'react-redux-toastr';
// ------------------------------------
// Constants
// ------------------------------------
export const LOADED = 'MissionList/LOADED';
-export const DELETE_MISSION = 'MissionList/DELETE_MISSION';
// ------------------------------------
// Actions
// ------------------------------------
-export const load = () => async(dispatch) => {
- const missions = await APIService.fetchMissionList();
- dispatch({type: LOADED, payload: {missions}});
+export const load = (params) => async(dispatch, getState) => {
+ const allParams = {..._.pick(getState().missionList, ['offset', 'limit']), ...params};
+
+ const respond = await APIService.fetchMissionList(allParams);
+
+ dispatch({type: LOADED, payload: {missions: respond.items, total: respond.total, ...params}});
};
export const deleteMission = (id) => async(dispatch) => {
await APIService.deleteMission(id);
+ toastr.success('Mission deleted');
- dispatch({type: DELETE_MISSION, payload: {missionId: id}});
+ dispatch(load());
};
export const actions = {
@@ -31,14 +35,10 @@ export const actions = {
// Reducer
// ------------------------------------
export default handleActions({
- [LOADED]: (state, {payload: {missions}}) => ({...state, missions}),
- [DELETE_MISSION]: (state, {payload: {missionId}}) => {
- const newState = _.cloneDeep(state);
-
- newState.missions = newState.missions.filter((mission) => mission.id !== missionId);
-
- return newState;
- },
+ [LOADED]: (state, {payload}) => ({...state, ...payload}),
}, {
+ offset: 0,
+ limit: 10,
+ total: 0,
missions: [],
});
diff --git a/src/routes/PilotChecklist/components/PilotChecklistForm/PilotChecklistForm.jsx b/src/routes/PilotChecklist/components/PilotChecklistForm/PilotChecklistForm.jsx
new file mode 100644
index 0000000..ec821f8
--- /dev/null
+++ b/src/routes/PilotChecklist/components/PilotChecklistForm/PilotChecklistForm.jsx
@@ -0,0 +1,100 @@
+import React, {PropTypes, Component} from 'react';
+import {reduxForm} from 'redux-form';
+import Button from 'components/Button';
+import Radiobox from 'components/Radiobox';
+import TextareaField from 'components/TextareaField';
+import CSSModules from 'react-css-modules';
+import styles from './PilotChecklistForm.scss';
+import _ from 'lodash';
+
+export class PilotChecklistForm extends Component {
+ constructor(props) {
+ super(props);
+
+ this.onButtonClick = this.onButtonClick.bind(this);
+ PilotChecklistForm.pressedButton = null;
+ }
+
+ onButtonClick(name) {
+ PilotChecklistForm.pressedButton = name;
+ this.props.handleSubmit((values) => this.props.save({...values, pressedButton: name}))();
+ }
+
+ render() {
+ const {questions, fields, missionStatus} = this.props;
+ const isReadonly = _.includes(['completed', 'in-progress'], missionStatus);
+ const hasErrors = _.find(fields.answers, (answerRow) => answerRow.answer.error || answerRow.note.error);
+
+ return (
+
+ );
+ }
+}
+
+PilotChecklistForm.propTypes = {
+ questions: PropTypes.array.isRequired,
+ fields: PropTypes.object.isRequired,
+ handleSubmit: PropTypes.func.isRequired,
+ missionStatus: PropTypes.string.isRequired,
+ save: PropTypes.func.isRequired,
+};
+
+const fields = [
+ 'answers[].answer',
+ 'answers[].note',
+];
+
+/**
+ * Validate function for redux form
+ * @param {Object} values values to validate
+ * @return {Object} errors
+ */
+const validate = (values) => {
+ const errors = {};
+
+ if (PilotChecklistForm.pressedButton === 'saveload') {
+ errors.answers = _.map(values.answers, (answerRow) => {
+ let err;
+
+ if (_.isNil(answerRow.answer)) {
+ err = {answer: 'Answer is required'};
+ } else if (answerRow.answer === 'no') {
+ err = {answer: 'Answer cannot be "No"'};
+ } else if (answerRow.answer === 'note' && (!_.isString(answerRow.note) || answerRow.note.trim() === '')) {
+ err = {note: 'You have to provide a "Note", when you chose "No, but proceed with caution"'};
+ }
+
+ return err;
+ });
+ }
+
+ return errors;
+};
+
+export default reduxForm({form: 'pilotChecklist', fields, validate})(CSSModules(PilotChecklistForm, styles));
diff --git a/src/routes/PilotChecklist/components/PilotChecklistForm/PilotChecklistForm.scss b/src/routes/PilotChecklist/components/PilotChecklistForm/PilotChecklistForm.scss
new file mode 100644
index 0000000..6272302
--- /dev/null
+++ b/src/routes/PilotChecklist/components/PilotChecklistForm/PilotChecklistForm.scss
@@ -0,0 +1,62 @@
+.pilot-checklist-form {
+ margin: 0 auto;
+ max-width: 1000px;
+}
+
+.question {
+ border-bottom: 1px solid #d5d5d5;
+ margin-bottom: 30px;
+ padding-bottom: 34px;
+
+ &:last-child {
+ border-bottom: 0;
+ margin-bottom: 0;
+ }
+}
+
+.radioboxes {
+ display: flex;
+}
+
+.radiobox {
+ margin-right: 50px;
+}
+
+.note {
+ margin-top: 10px;
+}
+
+.note-label {
+ display: block;
+ margin-bottom: 8px;
+}
+
+.actions {
+ border-top: 1px solid #d5d5d5;
+ padding-bottom: 30px;
+ text-align: right;
+
+ button {
+ margin-left: 12px;
+ }
+}
+
+.error {
+ color: #f00;
+ height: 40px;
+ line-height: 40px;
+}
+
+.note-label-wrap {
+ display: flex;
+
+ .error {
+ height: auto;
+ line-height: inherit;
+ margin-left: 30px;
+ }
+}
+
+.global-error {
+ height: 40px;
+}
diff --git a/src/routes/PilotChecklist/components/PilotChecklistForm/index.js b/src/routes/PilotChecklist/components/PilotChecklistForm/index.js
new file mode 100644
index 0000000..93af7bb
--- /dev/null
+++ b/src/routes/PilotChecklist/components/PilotChecklistForm/index.js
@@ -0,0 +1,3 @@
+import PilotChecklistForm from './PilotChecklistForm';
+
+export default PilotChecklistForm;
diff --git a/src/routes/PilotChecklist/components/PilotChecklistView.jsx b/src/routes/PilotChecklist/components/PilotChecklistView.jsx
new file mode 100644
index 0000000..e977a98
--- /dev/null
+++ b/src/routes/PilotChecklist/components/PilotChecklistView.jsx
@@ -0,0 +1,22 @@
+import React from 'react';
+import CSSModules from 'react-css-modules';
+import styles from './PilotChecklistView.scss';
+import PilotChecklistForm from '../containers/PilotChecklistFormContainer';
+
+export const PilotChecklistView = () => (
+
+
+
+
Flight Checklist
+
+
+
+
+);
+
+PilotChecklistView.propTypes = {
+};
+
+export default CSSModules(PilotChecklistView, styles);
diff --git a/src/routes/PilotChecklist/components/PilotChecklistView.scss b/src/routes/PilotChecklist/components/PilotChecklistView.scss
new file mode 100644
index 0000000..f9be2bd
--- /dev/null
+++ b/src/routes/PilotChecklist/components/PilotChecklistView.scss
@@ -0,0 +1,37 @@
+.pilot-checklist-view {
+ background-color: transparent;
+
+ :global {
+
+ }
+}
+
+.wrap {
+ padding: 0 30px 35px;
+}
+
+.header {
+ border-bottom: 1px solid #d5d5d5;
+ display: flex;
+ margin-bottom: 19px;
+ justify-content: space-between;
+ padding-bottom: 17px;
+ padding-top: 21px;
+ position: relative;
+}
+
+.title {
+ color: #333333;
+ font-size: 24px;
+ font-weight: 600;
+ line-height: 32px;
+ margin: 0;
+ padding: 0;
+}
+
+.panel {
+ background-color: #fff;
+ border: 1px solid #e0e0e0;
+ border-radius: 3px;
+ padding: 19px 24px;
+}
diff --git a/src/routes/PilotChecklist/containers/BreadcrumbItemContainer.js b/src/routes/PilotChecklist/containers/BreadcrumbItemContainer.js
new file mode 100644
index 0000000..206227f
--- /dev/null
+++ b/src/routes/PilotChecklist/containers/BreadcrumbItemContainer.js
@@ -0,0 +1,11 @@
+import {connect} from 'react-redux';
+
+// we use global BreadcrumbItem component to display breadcrumb item,
+// just pass a title property here
+import BreadcrumbItem from 'components/BreadcrumbItem';
+
+const mapState = (state) => ({
+ title: state.pilotChecklist.missionName,
+});
+
+export default connect(mapState, {})(BreadcrumbItem);
diff --git a/src/routes/PilotChecklist/containers/PilotChecklistContainer.js b/src/routes/PilotChecklist/containers/PilotChecklistContainer.js
new file mode 100644
index 0000000..7b65831
--- /dev/null
+++ b/src/routes/PilotChecklist/containers/PilotChecklistContainer.js
@@ -0,0 +1,12 @@
+import {asyncConnect} from 'redux-connect';
+import {actions} from '../modules/PilotChecklist';
+
+import PilotChecklistView from '../components/PilotChecklistView';
+
+const resolve = [{
+ promise: ({store, params}) => store.dispatch(actions.load(params.id)),
+}];
+
+const mapState = (state) => state.pilotChecklist;
+
+export default asyncConnect(resolve, mapState, actions)(PilotChecklistView);
diff --git a/src/routes/PilotChecklist/containers/PilotChecklistFormContainer.js b/src/routes/PilotChecklist/containers/PilotChecklistFormContainer.js
new file mode 100644
index 0000000..cb1bae3
--- /dev/null
+++ b/src/routes/PilotChecklist/containers/PilotChecklistFormContainer.js
@@ -0,0 +1,33 @@
+import {connect} from 'react-redux';
+import {actions} from '../modules/PilotChecklist';
+import _ from 'lodash';
+
+import PilotChecklistForm from '../components/PilotChecklistForm';
+
+/**
+ * Create initial values for the checklist form
+ * it takes into account that we can have not all answers,
+ * but form requires full quantity of elements, so we create empty answers when need
+ *
+ * @param {Array} questions list of all questions
+ * @param {Array} answers) list of answers, could be not for all questions
+ * @return {Object} initialValues for the form
+ */
+const answersToInitialValues = (questions, answers) => ({
+ answers: _.map(questions, (question) => (
+ {
+ ...{answer: undefined, note: undefined}, // eslint-disable-line no-undefined
+ ..._.find(answers, {question: question.id}),
+ }
+ )),
+});
+
+const mapState = (state) => ({
+ questions: state.pilotChecklist.questions,
+ initialValues: answersToInitialValues(state.pilotChecklist.questions, state.pilotChecklist.answers),
+ missionStatus: state.pilotChecklist.missionStatus,
+});
+
+export default connect(mapState, {
+ save: actions.save,
+})(PilotChecklistForm);
diff --git a/src/routes/PilotChecklist/index.js b/src/routes/PilotChecklist/index.js
new file mode 100644
index 0000000..602408e
--- /dev/null
+++ b/src/routes/PilotChecklist/index.js
@@ -0,0 +1,18 @@
+import {injectReducer} from '../../store/reducers';
+import React from 'react';
+import BreadcrumbItem from './containers/BreadcrumbItemContainer';
+
+export default (store) => ({
+ name: 'Flight Checklist',
+ path: 'pilot-checklist/:id',
+ getComponent(nextState, cb) {
+ require.ensure([], (require) => {
+ const PilotChecklist = require('./containers/PilotChecklistContainer').default;
+ const reducer = require('./modules/PilotChecklist').default;
+
+ injectReducer(store, {key: 'pilotChecklist', reducer});
+ cb(null, PilotChecklist);
+ }, 'PilotChecklist');
+ },
+ prettifyParam: () => React.createElement(BreadcrumbItem), // eslint-disable-line react/display-name
+});
diff --git a/src/routes/PilotChecklist/modules/PilotChecklist.js b/src/routes/PilotChecklist/modules/PilotChecklist.js
new file mode 100644
index 0000000..9991388
--- /dev/null
+++ b/src/routes/PilotChecklist/modules/PilotChecklist.js
@@ -0,0 +1,75 @@
+import {handleActions} from 'redux-actions';
+import APIService from 'services/APIService';
+import {toastr} from 'react-redux-toastr';
+import _ from 'lodash';
+
+// ------------------------------------
+// Constants
+// ------------------------------------
+export const LOADED = 'PilotChecklist/LOADED';
+export const UPDATED = 'PilotChecklist/UPDATED';
+
+// ------------------------------------
+// Actions
+// ------------------------------------
+export const load = (missionId) => async(dispatch) => {
+ const response = await APIService.getPilotChecklist(missionId);
+ const answers = response.pilotChecklist ? response.pilotChecklist.answers : [];
+
+ dispatch({type: LOADED, payload: {..._.pick(response, ['missionStatus', 'missionName', 'questions']), answers, missionId}});
+};
+
+export const save = (values) => async (dispatch, getState) => {
+ const questions = getState().pilotChecklist.questions;
+ // send to server only not empty answers and not empty answer properties
+ const notEmptyAnswers = [];
+ _.forEach(values.answers, (answerRow, index) => {
+ const notEmptyAnswer = {};
+ const hasAnswer = !!answerRow.answer;
+ const hasNote = _.isString(answerRow.note) && answerRow.note.trim() !== '';
+
+ if (hasAnswer || hasNote) {
+ hasAnswer && (notEmptyAnswer.answer = answerRow.answer);
+ hasNote && (notEmptyAnswer.note = answerRow.note);
+ // add question id to the answer
+ notEmptyAnswer.question = questions[index].id;
+ notEmptyAnswers.push(notEmptyAnswer);
+ }
+ });
+
+ const response = await APIService.updatePilotChecklist(getState().pilotChecklist.missionId, {
+ answers: notEmptyAnswers,
+ load: values.pressedButton === 'saveload',
+ });
+ dispatch({
+ type: UPDATED,
+ payload: {
+ missionStatus: response.missionStatus,
+ answers: response.pilotChecklist.answers,
+ },
+ });
+ if (values.pressedButton === 'saveload') {
+ toastr.success('Checklist saved and mission loaded');
+ } else {
+ toastr.success('Checklist saved');
+ }
+};
+
+export const actions = {
+ load,
+ save,
+};
+
+// ------------------------------------
+// Reducer
+// ------------------------------------
+export default handleActions({
+ [LOADED]: (state, {payload}) => ({...state, ...payload}),
+ [UPDATED]: (state, {payload}) => ({...state, ...payload}),
+}, {
+ missionId: '',
+ missionStatus: '',
+ missionName: '',
+ questions: [],
+ answers: [],
+});
diff --git a/src/routes/PilotMissions/components/PilotMissionsView.jsx b/src/routes/PilotMissions/components/PilotMissionsView.jsx
new file mode 100644
index 0000000..32a5329
--- /dev/null
+++ b/src/routes/PilotMissions/components/PilotMissionsView.jsx
@@ -0,0 +1,54 @@
+import React, {PropTypes} from 'react';
+import CSSModules from 'react-css-modules';
+import {Link} from 'react-router';
+import StatusLabel from 'components/StatusLabel';
+import Table from 'components/Table';
+import styles from './PilotMissionsView.scss';
+
+const columns = [{
+ header: 'Mission Name',
+ accessor: 'missionName',
+ render: (prop) =>
{prop.value}, // eslint-disable-line react/display-name
+ sortable: true,
+}, {
+ header: 'Status',
+ accessor: 'status',
+ render: (prop) =>
, // eslint-disable-line react/display-name
+ sortable: true,
+}];
+
+export const PilotMissionsView = ({missions, load, offset, limit, total, sortBy}) => (
+
+
+
+
Pilot Missions
+
+
+ {missions.length ? (
+
+ ) : (
+
No missions found.
+ )}
+
+
+
+);
+
+PilotMissionsView.propTypes = {
+ missions: PropTypes.array.isRequired,
+ load: PropTypes.func.isRequired,
+ offset: PropTypes.number.isRequired,
+ limit: PropTypes.number.isRequired,
+ total: PropTypes.number.isRequired,
+ sortBy: PropTypes.string.isRequired,
+};
+
+export default CSSModules(PilotMissionsView, styles);
diff --git a/src/routes/PilotMissions/components/PilotMissionsView.scss b/src/routes/PilotMissions/components/PilotMissionsView.scss
new file mode 100644
index 0000000..52c6656
--- /dev/null
+++ b/src/routes/PilotMissions/components/PilotMissionsView.scss
@@ -0,0 +1,52 @@
+.pilot-missions-view {
+ background-color: transparent;
+
+ :global {
+
+ }
+}
+
+.wrap {
+ padding: 0 30px 35px;
+}
+
+.header {
+ border-bottom: 1px solid #d5d5d5;
+ display: flex;
+ margin-bottom: 19px;
+ justify-content: space-between;
+ padding-bottom: 17px;
+ padding-top: 21px;
+ position: relative;
+}
+
+.title {
+ color: #333333;
+ font-size: 24px;
+ font-weight: 600;
+ line-height: 32px;
+ margin: 0;
+ padding: 0;
+}
+
+.panel {
+ background-color: #fff;
+ border: 1px solid #e0e0e0;
+ border-radius: 3px;
+ padding: 19px 24px;
+}
+
+.create-btn {
+ background: #315b95;
+ border: none;
+ color: white;
+ display: inline-block;
+ font-weight: bold;
+ min-width: 115px;
+ margin-left: 10px;
+ padding: 13px 10px;
+
+ &:hover {
+ color: #fff;
+ }
+}
diff --git a/src/routes/PilotMissions/containers/PilotMissionsContainer.js b/src/routes/PilotMissions/containers/PilotMissionsContainer.js
new file mode 100644
index 0000000..4fb6f8a
--- /dev/null
+++ b/src/routes/PilotMissions/containers/PilotMissionsContainer.js
@@ -0,0 +1,12 @@
+import {asyncConnect} from 'redux-connect';
+import {actions} from '../modules/PilotMissions';
+
+import PilotMissionsView from '../components/PilotMissionsView';
+
+const resolve = [{
+ promise: ({store}) => store.dispatch(actions.load()),
+}];
+
+const mapState = (state) => ({...state.pilotMissions});
+
+export default asyncConnect(resolve, mapState, actions)(PilotMissionsView);
diff --git a/src/routes/PilotMissions/index.js b/src/routes/PilotMissions/index.js
new file mode 100644
index 0000000..0da6e08
--- /dev/null
+++ b/src/routes/PilotMissions/index.js
@@ -0,0 +1,15 @@
+import {injectReducer} from '../../store/reducers';
+
+export default (store) => ({
+ name: 'Pilot Missions',
+ path: 'pilot-missions',
+ getComponent(nextState, cb) {
+ require.ensure([], (require) => {
+ const PilotMissions = require('./containers/PilotMissionsContainer').default;
+ const reducer = require('./modules/PilotMissions').default;
+
+ injectReducer(store, {key: 'pilotMissions', reducer});
+ cb(null, PilotMissions);
+ }, 'PilotMissions');
+ },
+});
diff --git a/src/routes/PilotMissions/modules/PilotMissions.js b/src/routes/PilotMissions/modules/PilotMissions.js
new file mode 100644
index 0000000..0f651b5
--- /dev/null
+++ b/src/routes/PilotMissions/modules/PilotMissions.js
@@ -0,0 +1,39 @@
+import {handleActions} from 'redux-actions';
+import APIService from 'services/APIService';
+import _ from 'lodash';
+
+// ------------------------------------
+// Constants
+// ------------------------------------
+export const LOADED = 'PilotMissions/LOADED';
+
+// ------------------------------------
+// Actions
+// ------------------------------------
+export const load = (params) => async(dispatch, getState) => {
+ const allParams = {..._.pick(getState().pilotMissions, ['offset', 'limit', 'sortBy']), ...params};
+ if (!allParams.sortBy) {
+ delete allParams.sortBy;
+ }
+
+ const respond = await APIService.fetchPilotMissions(allParams);
+
+ dispatch({type: LOADED, payload: {missions: respond.items, total: respond.total, ...params}});
+};
+
+export const actions = {
+ load,
+};
+
+// ------------------------------------
+// Reducer
+// ------------------------------------
+export default handleActions({
+ [LOADED]: (state, {payload}) => ({...state, ...payload}),
+}, {
+ offset: 0,
+ limit: 10,
+ total: 0,
+ sortBy: 'missionName',
+ missions: [],
+});
diff --git a/src/routes/index.js b/src/routes/index.js
index 8d15875..5556b6b 100644
--- a/src/routes/index.js
+++ b/src/routes/index.js
@@ -23,6 +23,8 @@ import AdminDashboard from './Admin/AdminDashboard';
import NoFlyZones from './Admin/NoFlyZones';
import ProviderDetailsRoute from './ProviderDetails';
import ResetPasswordRoute from './ResetPassword';
+import PilotMissionsRoute from './PilotMissions';
+import PilotChecklistRoute from './PilotChecklist';
import {defaultAuth0Service} from '../services/AuthService';
import {onSocialLoginSuccessAction} from 'store/modules/global';
@@ -72,6 +74,8 @@ export const createRoutes = (store) => ({
DroneDetailsRoute(store),
AvailablePackagesRoute(store),
ProviderDetailsRoute(store),
+ PilotMissionsRoute(store),
+ PilotChecklistRoute(store),
],
},
ResetPasswordRoute(store),
diff --git a/src/services/APIService.js b/src/services/APIService.js
index c797e27..fc22738 100644
--- a/src/services/APIService.js
+++ b/src/services/APIService.js
@@ -470,17 +470,20 @@ export default class APIService {
})).then(() => statusDetail[id]);
}
- static fetchMissionList() {
+ static fetchMissionList(params) {
const token = this.accessToken;
return request
.get(`${config.api.basePath}/api/v1/missions`)
.set('Authorization', `Bearer ${this.accessToken}`)
- .send()
+ .query(params)
.end()
- .then((res) => res.body.items.map((item) => ({
- ...item,
- downloadLink: `${config.api.basePath}/api/v1/missions/${item.id}/download?token=${token}`,
- })));
+ .then((res) => ({
+ total: res.body.total,
+ items: res.body.items.map((item) => ({
+ ...item,
+ downloadLink: `${config.api.basePath}/api/v1/missions/${item.id}/download?token=${token}`,
+ })),
+ }));
}
static getMission(id) {
@@ -725,4 +728,46 @@ export default class APIService {
.end()
.then((res) => res.body);
}
+
+ /**
+ * Get pilot checklist by mission id
+ * @param {String} id mission id
+ */
+ static getPilotChecklist(id) {
+ return request
+ .get(`${config.api.basePath}/api/v1/pilot/checklist/${id}/`)
+ .set('Authorization', `Bearer ${this.accessToken}`)
+ .end()
+ .then((res) => res.body);
+ }
+
+ /**
+ * Update pilot checklist by mission id
+ * @param {String} id mission id
+ * @param {Object} checklist checklist object
+ */
+ static updatePilotChecklist(id, checklist) {
+ return request
+ .put(`${config.api.basePath}/api/v1/pilot/checklist/${id}/`)
+ .set('Authorization', `Bearer ${this.accessToken}`)
+ .send(checklist)
+ .end()
+ .then((res) => res.body);
+ }
+
+ /**
+ * Fetch pilot missions
+ * @param {Object} params params
+ * @param {Number} params.limit the limit
+ * @param {Number} params.offset the offset
+ * @param {String} params.sortBy sort by property name
+ */
+ static fetchPilotMissions(params) {
+ return request
+ .get(`${config.api.basePath}/api/v1/pilot/missions`)
+ .set('Authorization', `Bearer ${this.accessToken}`)
+ .query(params)
+ .end()
+ .then((res) => res.body);
+ }
}
diff --git a/src/store/modules/global.js b/src/store/modules/global.js
index 9e34afa..5c825d5 100644
--- a/src/store/modules/global.js
+++ b/src/store/modules/global.js
@@ -16,7 +16,7 @@ const LOGIN_ACTION_SUCCESS = 'LOGIN_ACTION_SUCCESS';
const LOGIN_REDIRECT = {
admin: '/admin',
consumer: '/browse-provider',
- pilot: '/pilot',
+ pilot: '/pilot-missions',
provider: '/dashboard',
};