Skip to content

Commit

Permalink
feat(components): wip allow for deletion of components
Browse files Browse the repository at this point in the history
  • Loading branch information
techninja committed Sep 20, 2018
1 parent 894ebcb commit 22d586e
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 5 deletions.
40 changes: 38 additions & 2 deletions src/actions/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@
* Exports actions related to components.
*/

import { put, takeLatest } from 'redux-saga/effects';
import { call, put, takeLatest } from 'redux-saga/effects';

import { COMPONENT_SELECT } from '../constants';
import { COMPONENT_SELECT, COMPONENT_DELETE } from '../constants';

import {
componentRemove
} from '../lib/api';

import actionGenerator from '../lib/actionGenerator';

/**
* Sets the currently selected component.
Expand All @@ -22,6 +28,36 @@ export function* componentSelect({ id }) {
});
}

/**
* Delete a component.
*
* @param {object} payload - Payload for this saga action.
* @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* componentDelete({
id,
user,
successHandler = () => {},
errorHandler = () => {}
}) {
yield* actionGenerator(
COMPONENT_DELETE,
function* componentDeleteHandler() {
yield call(componentRemove, id, user);
yield put({
type: `${COMPONENT_DELETE}_SUCCESS`,
payload: { id }
});
},
successHandler,
errorHandler
);
}

export function* watchComponentActions() {
yield takeLatest(COMPONENT_SELECT, componentSelect);
yield takeLatest(COMPONENT_DELETE, componentDelete);
}
38 changes: 37 additions & 1 deletion src/components/ComponentForm/ComponentForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import { withStyles, TextField, Button } from '@material-ui/core';

import {
COMPONENT_SELECT,
COMPONENT_DELETE,
FORM_BUTTON_INSERT_UPDATE,
FORM_BUTTON_DELETE,
FORM_MESSAGE_DELETE_CONFIRM,
OPEN_EXPERIENCE_COMPONENT_FIELD_PRESAVE,
OPEN_EXPERIENCE_COMPONENT_EDIT
} from '../../constants';
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,19 @@ class ComponentForm extends Component {
}, 200);
};

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

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

/**
* Handles field changes.
*
Expand Down Expand Up @@ -228,6 +250,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
1 change: 1 addition & 0 deletions src/constants/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
*/

export const COMPONENT_SELECT = 'COMPONENT_SELECT';
export const COMPONENT_DELETE = 'COMPONENT_DELETE';
export const COMPONENT_TYPE_DIALOG = 'panelimage';
export const COMPONENT_TYPE_LINK = 'link';
2 changes: 2 additions & 0 deletions src/constants/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
*/

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
18 changes: 18 additions & 0 deletions src/lib/api/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,21 @@ 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
12 changes: 11 additions & 1 deletion src/reducers/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Exports reducers pertaining to component state.
*/

import { COMPONENT_SELECT } from '../constants';
import { COMPONENT_SELECT, COMPONENT_DELETE } from '../constants';

/**
* Default user state.
Expand All @@ -30,6 +30,16 @@ export default function component(state = defaultState, action) {
return { id };
}

/**
* Reducer that handles component selection.
*/
case `${COMPONENT_DELETE}_SUCCESS`: {
const { id } = action.payload;
// TODO: Remove component from state

return { id };
}

/**
* Default reducer that returns defaulted state.
*/
Expand Down

0 comments on commit 22d586e

Please sign in to comment.