diff --git a/client/src/components/Settings/SearchSettings/CustomQueries/CustomQueries.module.css b/client/src/components/Settings/SearchSettings/CustomQueries/CustomQueries.module.css index 36313bf..73297cc 100644 --- a/client/src/components/Settings/SearchSettings/CustomQueries/CustomQueries.module.css +++ b/client/src/components/Settings/SearchSettings/CustomQueries/CustomQueries.module.css @@ -7,6 +7,10 @@ color: var(--color-primary); } +.QueriesGrid span:last-child { + margin-bottom: 10px; +} + .ActionIcons { display: flex; } diff --git a/client/src/components/Settings/SearchSettings/CustomQueries/CustomQueries.tsx b/client/src/components/Settings/SearchSettings/CustomQueries/CustomQueries.tsx index bc50cf4..de9d226 100644 --- a/client/src/components/Settings/SearchSettings/CustomQueries/CustomQueries.tsx +++ b/client/src/components/Settings/SearchSettings/CustomQueries/CustomQueries.tsx @@ -3,11 +3,9 @@ import { connect } from 'react-redux'; import classes from './CustomQueries.module.css'; -import ModalForm from '../../../UI/Forms/ModalForm/ModalForm'; import Modal from '../../../UI/Modal/Modal'; import Icon from '../../../UI/Icons/Icon/Icon'; import { GlobalState, Query } from '../../../../interfaces'; -import InputGroup from '../../../UI/Forms/InputGroup/InputGroup'; import QueriesForm from './QueriesForm'; import { deleteQuery } from '../../../../store/actions'; import Button from '../../../UI/Buttons/Button/Button'; @@ -21,6 +19,12 @@ const CustomQueries = (props: Props): JSX.Element => { const { customQueries, deleteQuery } = props; const [modalIsOpen, setModalIsOpen] = useState(false); + const [editableQuery, setEditableQuery] = useState(null); + + const updateHandler = (query: Query) => { + setEditableQuery(query); + setModalIsOpen(true); + }; const deleteHandler = (query: Query) => { if (window.confirm(`Are you sure you want to delete this provider?`)) { @@ -34,7 +38,14 @@ const CustomQueries = (props: Props): JSX.Element => { isOpen={modalIsOpen} setIsOpen={() => setModalIsOpen(!modalIsOpen)} > - setModalIsOpen(!modalIsOpen)} /> + {editableQuery ? ( + setModalIsOpen(!modalIsOpen)} + query={editableQuery} + /> + ) : ( + setModalIsOpen(!modalIsOpen)} /> + )}
@@ -54,7 +65,7 @@ const CustomQueries = (props: Props): JSX.Element => { {q.name} {q.prefix} - + updateHandler(q)}> deleteHandler(q)}> @@ -65,7 +76,12 @@ const CustomQueries = (props: Props): JSX.Element => { ))}
- diff --git a/client/src/components/Settings/SearchSettings/CustomQueries/QueriesForm.tsx b/client/src/components/Settings/SearchSettings/CustomQueries/QueriesForm.tsx index 8a20e05..42ad654 100644 --- a/client/src/components/Settings/SearchSettings/CustomQueries/QueriesForm.tsx +++ b/client/src/components/Settings/SearchSettings/CustomQueries/QueriesForm.tsx @@ -1,20 +1,70 @@ -import { useState } from 'react'; +import { ChangeEvent, FormEvent, useState, useEffect } from 'react'; +import { Query } from '../../../../interfaces'; import Button from '../../../UI/Buttons/Button/Button'; import InputGroup from '../../../UI/Forms/InputGroup/InputGroup'; import ModalForm from '../../../UI/Forms/ModalForm/ModalForm'; +import { connect } from 'react-redux'; +import { addQuery, updateQuery } from '../../../../store/actions'; interface Props { modalHandler: () => void; - // addApp: (formData: NewApp | FormData) => any; - // updateApp: (id: number, formData: NewApp | FormData) => any; - // app?: App; + addQuery: (query: Query) => {}; + updateQuery: (query: Query, Oldprefix: string) => {}; + query?: Query; } const QueriesForm = (props: Props): JSX.Element => { - const [formData, setFormData] = useState(); + const { modalHandler, addQuery, updateQuery, query } = props; + + const [formData, setFormData] = useState({ + name: '', + prefix: '', + template: '', + }); + + const inputChangeHandler = (e: ChangeEvent) => { + const { name, value } = e.target; + + setFormData({ + ...formData, + [name]: value, + }); + }; + + const formHandler = (e: FormEvent) => { + e.preventDefault(); + + if (query) { + updateQuery(formData, query.prefix); + } else { + addQuery(formData); + } + + // close modal + modalHandler(); + + // clear form + setFormData({ + name: '', + prefix: '', + template: '', + }); + }; + + useEffect(() => { + if (query) { + setFormData(query); + } else { + setFormData({ + name: '', + prefix: '', + template: '', + }); + } + }, [query]); return ( - {}}> + { id="name" placeholder="Google" required - // value={formData.name} - // onChange={(e) => inputChangeHandler(e)} + value={formData.name} + onChange={(e) => inputChangeHandler(e)} /> inputChangeHandler(e)} + value={formData.prefix} + onChange={(e) => inputChangeHandler(e)} /> inputChangeHandler(e)} + value={formData.template} + onChange={(e) => inputChangeHandler(e)} /> - + {query ? : } ); }; -export default QueriesForm; +export default connect(null, { addQuery, updateQuery })(QueriesForm); diff --git a/client/src/store/actions/actionTypes.ts b/client/src/store/actions/actionTypes.ts index f040016..c670b2f 100644 --- a/client/src/store/actions/actionTypes.ts +++ b/client/src/store/actions/actionTypes.ts @@ -32,6 +32,7 @@ import { AddQueryAction, DeleteQueryAction, FetchQueriesAction, + UpdateQueryAction, } from './config'; export enum ActionTypes { @@ -71,6 +72,7 @@ export enum ActionTypes { fetchQueries = 'FETCH_QUERIES', addQuery = 'ADD_QUERY', deleteQuery = 'DELETE_QUERY', + updateQuery = 'UPDATE_QUERY', } export type Action = @@ -104,4 +106,5 @@ export type Action = | UpdateConfigAction | FetchQueriesAction | AddQueryAction - | DeleteQueryAction; + | DeleteQueryAction + | UpdateQueryAction; diff --git a/client/src/store/actions/config.ts b/client/src/store/actions/config.ts index d0c8a42..29c5186 100644 --- a/client/src/store/actions/config.ts +++ b/client/src/store/actions/config.ts @@ -110,3 +110,26 @@ export const deleteQuery = console.log(err); } }; + +export interface UpdateQueryAction { + type: ActionTypes.updateQuery; + payload: Query[]; +} + +export const updateQuery = + (query: Query, oldPrefix: string) => + async (dispatch: Dispatch) => { + try { + const res = await axios.put>( + `/api/queries/${oldPrefix}`, + query + ); + + dispatch({ + type: ActionTypes.updateQuery, + payload: res.data.data, + }); + } catch (err) { + console.log(err); + } + }; diff --git a/client/src/store/reducers/config.ts b/client/src/store/reducers/config.ts index 08b68e6..ac81aeb 100644 --- a/client/src/store/reducers/config.ts +++ b/client/src/store/reducers/config.ts @@ -48,6 +48,13 @@ const deleteQuery = (state: State, action: Action): State => { }; }; +const updateQuery = (state: State, action: Action): State => { + return { + ...state, + customQueries: action.payload, + }; +}; + const configReducer = (state: State = initialState, action: Action) => { switch (action.type) { case ActionTypes.getConfig: @@ -60,6 +67,8 @@ const configReducer = (state: State = initialState, action: Action) => { return addQuery(state, action); case ActionTypes.deleteQuery: return deleteQuery(state, action); + case ActionTypes.updateQuery: + return updateQuery(state, action); default: return state; } diff --git a/controllers/queries/index.js b/controllers/queries/index.js index b68f145..ae1ccec 100644 --- a/controllers/queries/index.js +++ b/controllers/queries/index.js @@ -34,6 +34,34 @@ exports.getQueries = asyncWrapper(async (req, res, next) => { }); }); +// @desc Update query +// @route PUT /api/queries/:prefix +// @access Public +exports.updateQuery = asyncWrapper(async (req, res, next) => { + const file = new File(QUERIES_PATH); + let content = JSON.parse(file.read()); + + let queryIdx = content.queries.findIndex( + (q) => q.prefix == req.params.prefix + ); + + // query found + if (queryIdx > -1) { + content.queries = [ + ...content.queries.slice(0, queryIdx), + req.body, + ...content.queries.slice(queryIdx + 1), + ]; + } + + file.write(content, true); + + res.status(200).json({ + success: true, + data: content.queries, + }); +}); + // @desc Delete query // @route DELETE /api/queries/:prefix // @access Public diff --git a/routes/queries.js b/routes/queries.js index 0e17bc0..afacffd 100644 --- a/routes/queries.js +++ b/routes/queries.js @@ -5,9 +5,10 @@ const { getQueries, addQuery, deleteQuery, + updateQuery, } = require('../controllers/queries/'); router.route('/').post(addQuery).get(getQueries); -router.route('/:prefix').delete(deleteQuery); +router.route('/:prefix').delete(deleteQuery).put(updateQuery); module.exports = router;