Skip to content

Commit

Permalink
Merge pull request #28 from EditVR/feat/FKED-88-delete-components
Browse files Browse the repository at this point in the history
FKED-88: Add ability to delete components
  • Loading branch information
patrickocoffeyo authored Sep 28, 2018
2 parents 5b979c2 + 5f0cf56 commit 0907912
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 6 deletions.
43 changes: 43 additions & 0 deletions src/actions/openExperience.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
OPEN_EXPERIENCE_SCENE_CREATE,
OPEN_EXPERIENCE_SCENE_EDIT,
OPEN_EXPERIENCE_COMPONENT_CREATE,
OPEN_EXPERIENCE_COMPONENT_DELETE,
OPEN_EXPERIENCE_COMPONENT_EDIT,
OPEN_EXPERIENCE_COMPONENT_FIELD_PRESAVE
} from '../constants';
Expand All @@ -21,6 +22,7 @@ import {
sceneEdit,
componentEdit,
componentCreate,
componentRemove,
sceneAttachComponent
} from '../lib/api';
import actionGenerator from '../lib/actionGenerator';
Expand Down Expand Up @@ -237,6 +239,43 @@ export function* openExperienceComponentCreate({
);
}

/**
* Delete a component.
*
* @param {object} payload
* Payload for this saga action.
* @param {object} payload.sceneSlug
* Scene slug in which this component is located.
* @param {string} payload.id
* ID of the component to be deleted.
* @param {object} payload.user
* Current user object with authentication.
* @param {function} payload.successHandler
* Function to be executed on success.
* @param {function} payload.errorHandler
* Function to be executed on error.
*/
export function* openExperienceComponentDelete({
sceneSlug,
id,
user,
successHandler = () => {},
errorHandler = () => {}
}) {
yield* actionGenerator(
OPEN_EXPERIENCE_COMPONENT_DELETE,
function* openExperienceComponentDeleteHandler() {
yield call(componentRemove, id, user);
yield put({
type: `${OPEN_EXPERIENCE_COMPONENT_DELETE}_SUCCESS`,
payload: { sceneSlug, id }
});
},
successHandler,
errorHandler
);
}

/**
* Handles pre-saving a component within the current openExperience.
*
Expand Down Expand Up @@ -311,6 +350,10 @@ export function* watchOpenExperienceActions() {
OPEN_EXPERIENCE_COMPONENT_CREATE,
openExperienceComponentCreate
);
yield takeLatest(
OPEN_EXPERIENCE_COMPONENT_DELETE,
openExperienceComponentDelete
);
yield takeLatest(
OPEN_EXPERIENCE_COMPONENT_FIELD_PRESAVE,
openExperienceComponentFieldPresave
Expand Down
44 changes: 42 additions & 2 deletions src/actions/openExperience.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@ import {
OPEN_EXPERIENCE_SCENE_EDIT,
OPEN_EXPERIENCE_COMPONENT_FIELD_PRESAVE,
OPEN_EXPERIENCE_COMPONENT_EDIT,
OPEN_EXPERIENCE_COMPONENT_CREATE
OPEN_EXPERIENCE_COMPONENT_CREATE,
OPEN_EXPERIENCE_COMPONENT_DELETE
} from '../constants';
import {
openExperienceFetchForUser,
openExperienceSceneCreate,
openExperienceSceneEdit,
openExperienceComponentFieldPresave,
openExperienceComponentEdit,
openExperienceComponentCreate
openExperienceComponentCreate,
openExperienceComponentDelete
} from './openExperience';
import {
openExperienceFetchForUser as getOpenExperienceForUser,
Expand All @@ -34,6 +36,7 @@ import {
sceneEdit,
componentEdit,
componentCreate,
componentRemove,
sceneAttachComponent
} from '../lib/api';

Expand Down Expand Up @@ -311,4 +314,41 @@ describe('actions->openExperience', () => {
.next()
.isDone();
});

it('openExperience->openExperienceComponentDelete', () => {
const successHandler = jest.fn();
const id = 10;
const sceneSlug = 'test';
const user = {
authentication: { accessToken: 'test', csrfToken: 'test' }
};

testSaga(openExperienceComponentDelete, {
id,
user,
sceneSlug,
successHandler
})
.next()
.put(resetLoading())
.next()
.put(showLoading())
.next()
.put({
type: `${OPEN_EXPERIENCE_COMPONENT_DELETE}_LOADING`
})
.next()
.call(componentRemove, id, user)
.next()
.put({
type: `${OPEN_EXPERIENCE_COMPONENT_DELETE}_SUCCESS`,
payload: { sceneSlug, id }
})
.next()
.call(successHandler)
.next()
.put(hideLoading())
.next()
.isDone();
});
});
48 changes: 46 additions & 2 deletions src/components/ComponentForm/ComponentForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ import { withStyles, TextField, Button } from '@material-ui/core';
import {
COMPONENT_SELECT,
FORM_BUTTON_INSERT_UPDATE,
FORM_BUTTON_DELETE,
FORM_MESSAGE_DELETE_CONFIRM,
OPEN_EXPERIENCE_COMPONENT_FIELD_PRESAVE,
OPEN_EXPERIENCE_COMPONENT_EDIT
OPEN_EXPERIENCE_COMPONENT_EDIT,
OPEN_EXPERIENCE_COMPONENT_DELETE
} from '../../constants';
import { Message } from '../';
import ComponentFormStyles from './ComponentForm.style';
Expand Down Expand Up @@ -58,7 +61,13 @@ class ComponentForm extends Component {
}).isRequired,
experience: PropTypes.shape({
error: PropTypes.string
})
}),
user: PropTypes.shape({
authentication: PropTypes.shape({
accessToken: PropTypes.string.isRequired,
csrfToken: PropTypes.string.isRequired
}).isRequired
}).isRequired
};

static defaultProps = {
Expand Down Expand Up @@ -104,6 +113,27 @@ class ComponentForm extends Component {
}, 200);
};

/**
* Dispatches an action to delete the selected component.
*/
removeComponent = () => {
const {
dispatch,
user,
selectedComponent,
match: {
params: { sceneSlug }
}
} = this.props;

dispatch({
type: OPEN_EXPERIENCE_COMPONENT_DELETE,
id: selectedComponent,
sceneSlug,
user
});
};

/**
* Handles field changes.
*
Expand Down Expand Up @@ -228,6 +258,20 @@ class ComponentForm extends Component {
>
{FORM_BUTTON_INSERT_UPDATE}
</Button>
<Button
onClick={e => {
e.preventDefault();
if (window.confirm(FORM_MESSAGE_DELETE_CONFIRM)) {
this.removeComponent();
}
}}
variant="raised"
color="secondary"
disabled={isSubmitting}
className={classes.button}
>
{FORM_BUTTON_DELETE}
</Button>
</form>
);
}
Expand Down
3 changes: 3 additions & 0 deletions src/constants/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
*/

export const FORM_BUTTON_INSERT_UPDATE = 'Save';
export const FORM_BUTTON_DELETE = 'Delete';
export const FORM_MESSAGE_DELETE_CONFIRM =
'Are you sure you want to delete this component?';
export const FORM_BUTTON_REGISTER = 'Register';
export const FORM_BUTTON_RESET_PASSWORD = 'Reset Password';
export const FORM_BUTTON_FORGOT_PASSWORD = 'Forgot Password';
Expand Down
2 changes: 2 additions & 0 deletions src/constants/openExperience.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ export const OPEN_EXPERIENCE_COMPONENT_FIELD_PRESAVE =
export const OPEN_EXPERIENCE_COMPONENT_EDIT = 'OPEN_EXPERIENCE_COMPONENT_EDIT';
export const OPEN_EXPERIENCE_COMPONENT_CREATE =
'OPEN_EXPERIENCE_COMPONENT_CREATE';
export const OPEN_EXPERIENCE_COMPONENT_DELETE =
'OPEN_EXPERIENCE_COMPONENT_DELETE';
17 changes: 17 additions & 0 deletions src/lib/api/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,20 @@ export const componentEdit = async (
}
}
});

/**
* Delete a given component ID via the API.
*
* @param {string} id
* ID of component being updated.
* @param {object} user
* Object containing information about the current user.
* @param {object} user.authentication
* Object containing auth data.
* @param {string} user.authentication.accessToken
* Access token for the current user.
* @param {string} user.authentication.csrfToken
* CSRF token for the current user.
*/
export const componentRemove = async (id, { authentication }) =>
axiosInstance(authentication).delete(`${API_ENDPOINT_COMPONENT}/${id}`);
3 changes: 2 additions & 1 deletion src/lib/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
} from './experiences';
import { sceneCreate, sceneEdit, sceneAttachComponent } from './scene';
import { fileImageCreate, fileVideoCreate, fileCreate } from './file';
import { componentEdit, componentCreate } from './component';
import { componentEdit, componentCreate, componentRemove } from './component';

import {
openExperienceFetchForUser,
Expand All @@ -37,6 +37,7 @@ export {
sceneAttachComponent,
componentCreate,
componentEdit,
componentRemove,
experiencesEdit,
openExperienceFetchForUser,
openExperienceAttachScene,
Expand Down
20 changes: 19 additions & 1 deletion src/reducers/openExperience.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
OPEN_EXPERIENCE_SCENE_EDIT,
OPEN_EXPERIENCE_COMPONENT_FIELD_PRESAVE,
OPEN_EXPERIENCE_COMPONENT_EDIT,
OPEN_EXPERIENCE_COMPONENT_CREATE
OPEN_EXPERIENCE_COMPONENT_CREATE,
OPEN_EXPERIENCE_COMPONENT_DELETE
} from '../constants';

/**
Expand Down Expand Up @@ -249,6 +250,23 @@ export default function openExperiences(state = defaultState, action) {
item: state.item
};
}

/**
* Reducer that handles component deletion from open experience & scene.
*/
case `${OPEN_EXPERIENCE_COMPONENT_DELETE}_SUCCESS`: {
const { id, sceneSlug } = action.payload;

// Component should be gone from server, now remove from state.
const newItem = clone(state.item);
delete newItem.scenes[sceneSlug].components[id];
return {
loading: false,
error: null,
item: newItem
};
}

default:
return state;
}
Expand Down

0 comments on commit 0907912

Please sign in to comment.