1
0
Fork 0
mirror of https://github.com/pawelmalak/flame.git synced 2025-07-19 03:29:37 +02:00

Add and update custom queries

This commit is contained in:
unknown 2021-10-11 13:55:53 +02:00
parent a885440fef
commit 38ffdf1bff
8 changed files with 159 additions and 25 deletions

View file

@ -7,6 +7,10 @@
color: var(--color-primary); color: var(--color-primary);
} }
.QueriesGrid span:last-child {
margin-bottom: 10px;
}
.ActionIcons { .ActionIcons {
display: flex; display: flex;
} }

View file

@ -3,11 +3,9 @@ import { connect } from 'react-redux';
import classes from './CustomQueries.module.css'; import classes from './CustomQueries.module.css';
import ModalForm from '../../../UI/Forms/ModalForm/ModalForm';
import Modal from '../../../UI/Modal/Modal'; import Modal from '../../../UI/Modal/Modal';
import Icon from '../../../UI/Icons/Icon/Icon'; import Icon from '../../../UI/Icons/Icon/Icon';
import { GlobalState, Query } from '../../../../interfaces'; import { GlobalState, Query } from '../../../../interfaces';
import InputGroup from '../../../UI/Forms/InputGroup/InputGroup';
import QueriesForm from './QueriesForm'; import QueriesForm from './QueriesForm';
import { deleteQuery } from '../../../../store/actions'; import { deleteQuery } from '../../../../store/actions';
import Button from '../../../UI/Buttons/Button/Button'; import Button from '../../../UI/Buttons/Button/Button';
@ -21,6 +19,12 @@ const CustomQueries = (props: Props): JSX.Element => {
const { customQueries, deleteQuery } = props; const { customQueries, deleteQuery } = props;
const [modalIsOpen, setModalIsOpen] = useState(false); const [modalIsOpen, setModalIsOpen] = useState(false);
const [editableQuery, setEditableQuery] = useState<Query | null>(null);
const updateHandler = (query: Query) => {
setEditableQuery(query);
setModalIsOpen(true);
};
const deleteHandler = (query: Query) => { const deleteHandler = (query: Query) => {
if (window.confirm(`Are you sure you want to delete this provider?`)) { if (window.confirm(`Are you sure you want to delete this provider?`)) {
@ -34,7 +38,14 @@ const CustomQueries = (props: Props): JSX.Element => {
isOpen={modalIsOpen} isOpen={modalIsOpen}
setIsOpen={() => setModalIsOpen(!modalIsOpen)} setIsOpen={() => setModalIsOpen(!modalIsOpen)}
> >
<QueriesForm modalHandler={() => setModalIsOpen(!modalIsOpen)} /> {editableQuery ? (
<QueriesForm
modalHandler={() => setModalIsOpen(!modalIsOpen)}
query={editableQuery}
/>
) : (
<QueriesForm modalHandler={() => setModalIsOpen(!modalIsOpen)} />
)}
</Modal> </Modal>
<div> <div>
@ -54,7 +65,7 @@ const CustomQueries = (props: Props): JSX.Element => {
<span>{q.name}</span> <span>{q.name}</span>
<span>{q.prefix}</span> <span>{q.prefix}</span>
<span className={classes.ActionIcons}> <span className={classes.ActionIcons}>
<span> <span onClick={() => updateHandler(q)}>
<Icon icon="mdiPencil" /> <Icon icon="mdiPencil" />
</span> </span>
<span onClick={() => deleteHandler(q)}> <span onClick={() => deleteHandler(q)}>
@ -65,7 +76,12 @@ const CustomQueries = (props: Props): JSX.Element => {
))} ))}
</div> </div>
<Button click={() => setModalIsOpen(true)}> <Button
click={() => {
setEditableQuery(null);
setModalIsOpen(true);
}}
>
Add new search provider Add new search provider
</Button> </Button>
</div> </div>

View file

@ -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 Button from '../../../UI/Buttons/Button/Button';
import InputGroup from '../../../UI/Forms/InputGroup/InputGroup'; import InputGroup from '../../../UI/Forms/InputGroup/InputGroup';
import ModalForm from '../../../UI/Forms/ModalForm/ModalForm'; import ModalForm from '../../../UI/Forms/ModalForm/ModalForm';
import { connect } from 'react-redux';
import { addQuery, updateQuery } from '../../../../store/actions';
interface Props { interface Props {
modalHandler: () => void; modalHandler: () => void;
// addApp: (formData: NewApp | FormData) => any; addQuery: (query: Query) => {};
// updateApp: (id: number, formData: NewApp | FormData) => any; updateQuery: (query: Query, Oldprefix: string) => {};
// app?: App; query?: Query;
} }
const QueriesForm = (props: Props): JSX.Element => { const QueriesForm = (props: Props): JSX.Element => {
const [formData, setFormData] = useState(); const { modalHandler, addQuery, updateQuery, query } = props;
const [formData, setFormData] = useState<Query>({
name: '',
prefix: '',
template: '',
});
const inputChangeHandler = (e: ChangeEvent<HTMLInputElement>) => {
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 ( return (
<ModalForm modalHandler={props.modalHandler} formHandler={() => {}}> <ModalForm modalHandler={modalHandler} formHandler={formHandler}>
<InputGroup> <InputGroup>
<label htmlFor="name">Name</label> <label htmlFor="name">Name</label>
<input <input
@ -23,37 +73,37 @@ const QueriesForm = (props: Props): JSX.Element => {
id="name" id="name"
placeholder="Google" placeholder="Google"
required required
// value={formData.name} value={formData.name}
// onChange={(e) => inputChangeHandler(e)} onChange={(e) => inputChangeHandler(e)}
/> />
</InputGroup> </InputGroup>
<InputGroup> <InputGroup>
<label htmlFor="name">Prefix</label> <label htmlFor="name">Prefix</label>
<input <input
type="text" type="text"
name="name" name="prefix"
id="name" id="prefix"
placeholder="g" placeholder="g"
required required
// value={formData.name} value={formData.prefix}
// onChange={(e) => inputChangeHandler(e)} onChange={(e) => inputChangeHandler(e)}
/> />
</InputGroup> </InputGroup>
<InputGroup> <InputGroup>
<label htmlFor="name">Query Template</label> <label htmlFor="name">Query Template</label>
<input <input
type="text" type="text"
name="name" name="template"
id="name" id="template"
placeholder="https://www.google.com/search?q=" placeholder="https://www.google.com/search?q="
required required
// value={formData.name} value={formData.template}
// onChange={(e) => inputChangeHandler(e)} onChange={(e) => inputChangeHandler(e)}
/> />
</InputGroup> </InputGroup>
<Button>Add provider</Button> {query ? <Button>Update provider</Button> : <Button>Add provider</Button>}
</ModalForm> </ModalForm>
); );
}; };
export default QueriesForm; export default connect(null, { addQuery, updateQuery })(QueriesForm);

View file

@ -32,6 +32,7 @@ import {
AddQueryAction, AddQueryAction,
DeleteQueryAction, DeleteQueryAction,
FetchQueriesAction, FetchQueriesAction,
UpdateQueryAction,
} from './config'; } from './config';
export enum ActionTypes { export enum ActionTypes {
@ -71,6 +72,7 @@ export enum ActionTypes {
fetchQueries = 'FETCH_QUERIES', fetchQueries = 'FETCH_QUERIES',
addQuery = 'ADD_QUERY', addQuery = 'ADD_QUERY',
deleteQuery = 'DELETE_QUERY', deleteQuery = 'DELETE_QUERY',
updateQuery = 'UPDATE_QUERY',
} }
export type Action = export type Action =
@ -104,4 +106,5 @@ export type Action =
| UpdateConfigAction | UpdateConfigAction
| FetchQueriesAction | FetchQueriesAction
| AddQueryAction | AddQueryAction
| DeleteQueryAction; | DeleteQueryAction
| UpdateQueryAction;

View file

@ -110,3 +110,26 @@ export const deleteQuery =
console.log(err); console.log(err);
} }
}; };
export interface UpdateQueryAction {
type: ActionTypes.updateQuery;
payload: Query[];
}
export const updateQuery =
(query: Query, oldPrefix: string) =>
async (dispatch: Dispatch<UpdateQueryAction>) => {
try {
const res = await axios.put<ApiResponse<Query[]>>(
`/api/queries/${oldPrefix}`,
query
);
dispatch<UpdateQueryAction>({
type: ActionTypes.updateQuery,
payload: res.data.data,
});
} catch (err) {
console.log(err);
}
};

View file

@ -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) => { const configReducer = (state: State = initialState, action: Action) => {
switch (action.type) { switch (action.type) {
case ActionTypes.getConfig: case ActionTypes.getConfig:
@ -60,6 +67,8 @@ const configReducer = (state: State = initialState, action: Action) => {
return addQuery(state, action); return addQuery(state, action);
case ActionTypes.deleteQuery: case ActionTypes.deleteQuery:
return deleteQuery(state, action); return deleteQuery(state, action);
case ActionTypes.updateQuery:
return updateQuery(state, action);
default: default:
return state; return state;
} }

View file

@ -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 // @desc Delete query
// @route DELETE /api/queries/:prefix // @route DELETE /api/queries/:prefix
// @access Public // @access Public

View file

@ -5,9 +5,10 @@ const {
getQueries, getQueries,
addQuery, addQuery,
deleteQuery, deleteQuery,
updateQuery,
} = require('../controllers/queries/'); } = require('../controllers/queries/');
router.route('/').post(addQuery).get(getQueries); router.route('/').post(addQuery).get(getQueries);
router.route('/:prefix').delete(deleteQuery); router.route('/:prefix').delete(deleteQuery).put(updateQuery);
module.exports = router; module.exports = router;