edit and delete submission refactor and handle errors

This commit is contained in:
Mateusz Tylka 2023-08-04 16:35:15 +02:00
parent 00a9a82bcb
commit aa1c1c3737
9 changed files with 202 additions and 97 deletions

View File

@ -38,7 +38,12 @@ const challengeSubmission = (
.then((data) => { .then((data) => {
dispatch({ type: SUBMIT_ACTION.TOGGLE_SUBMISSION_LOADING }); dispatch({ type: SUBMIT_ACTION.TOGGLE_SUBMISSION_LOADING });
const processUrl = API.replace('/api', ''); const processUrl = API.replace('/api', '');
window.location.replace(`${processUrl}/open-view-progress/${data}#form`); if (Number.isInteger(Number(data))) {
console.log(`${processUrl}/open-view-progress/${data}#form`);
window.location.replace(
`${processUrl}/open-view-progress/${data}#form`
);
}
// console.log(data); // console.log(data);
// fetch(`${API}/view-progress-with-web-sockets/${data}`) // fetch(`${API}/view-progress-with-web-sockets/${data}`)

View File

@ -1,12 +1,12 @@
import KeyCloakService from '../services/KeyCloakService'; import KeyCloakService from '../services/KeyCloakService';
import { API } from '../utils/globals'; import { API } from '../utils/globals';
import theme from '../utils/theme';
const deleteSubmission = async ( const deleteSubmission = async (
item, item,
deletedItems, deletedItems,
setDeletedItems, setDeletedItems,
popUpMessageHandler, popUpMessageHandler
theme
) => { ) => {
fetch(`${API}/delete-submission/${item.id}`, { fetch(`${API}/delete-submission/${item.id}`, {
method: 'POST', method: 'POST',
@ -22,6 +22,13 @@ const deleteSubmission = async (
newDeletedItems.push(item); newDeletedItems.push(item);
setDeletedItems(newDeletedItems); setDeletedItems(newDeletedItems);
popUpMessageHandler('Complete', `Submission "${item.id}" deleted`); popUpMessageHandler('Complete', `Submission "${item.id}" deleted`);
} else if (data.includes('<!doctype html>') && data.includes('Login')) {
popUpMessageHandler(
'Error',
'You have to be login in to edit submission!',
null,
theme.colors.red
);
} else { } else {
popUpMessageHandler( popUpMessageHandler(
'Error', 'Error',

View File

@ -1,25 +1,47 @@
import KeyCloakService from '../services/KeyCloakService'; import KeyCloakService from '../services/KeyCloakService';
import { API } from '../utils/globals'; import { API } from '../utils/globals';
import theme from '../utils/theme';
const editSubmission = ( const editSubmission = async (
submisssion, submisssion,
tags, tags,
description description,
popUpMessageHandler
) => { ) => {
// tags = tags.map((tag) => tag.name).join(',');
tags = tags.replaceAll(',', '%2C'); tags = tags.replaceAll(',', '%2C');
fetch(`${API}/edit-submission/${submisssion}/${tags}/${description}`, { fetch(`${API}/edit-submission/${submisssion}/${tags}/${description}`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
Authorization: `Bearer ${KeyCloakService.getToken()}`, Authorization: `Bearer ${KeyCloakService.getToken()}`,
} },
}) })
.then((resp) => resp.text()) .then((resp) => resp.text())
.then((data) => { .then((data) => {
console.log(data); console.log(data);
if (data === 'Submission changed') {
popUpMessageHandler(
'Submission changed!',
`Submission ${submisssion} edited`,
null,
theme.colors.green
);
} else if (data === 'Only owner can edit a submission!') {
popUpMessageHandler('Error', data, null, theme.colors.red);
} else if (data.includes('<!doctype html>') && data.includes('Login')) {
popUpMessageHandler(
'Error',
'You have to be login in to edit submission!',
null,
theme.colors.red
);
} else {
if (data.length > 650) {
data = `${data.slice(0, 650)}...`;
}
popUpMessageHandler('Error', data, null, theme.colors.red);
}
}); });
}; };
export default editSubmission; export default editSubmission;
// http://localhost:3000/api/edit-submission/4/1%2C2/abc

View File

@ -1,15 +1,10 @@
import React from 'react'; import React from 'react';
import TableStyle from './styles/TableStyle';
import TableHeader from './components/TableHeader';
import TableRowItems from './components/TableRowItems';
import RowsBackgroundStyle from './styles/RowsBackgroundStyle';
import TableRowFooter from './components/TableRowFooter';
import deleteSubmission from '../../../api/deleteSubmission';
import theme from '../../../utils/theme';
import DeletePopUp from './components/DeletePopUp';
import MobileTable from './components/MobileTable';
import Media from 'react-media'; import Media from 'react-media';
import theme from '../../../utils/theme';
import MobileTable from './components/MobileTable';
import DesktopTable from './components/DesktopTable';
import EditPopUp from './components/EditPopUp'; import EditPopUp from './components/EditPopUp';
import DeletePopUp from './components/DeletePopUp';
const Table = ({ const Table = ({
items, items,
@ -24,78 +19,58 @@ const Table = ({
const [deletePopUp, setDeletePopUp] = React.useState(false); const [deletePopUp, setDeletePopUp] = React.useState(false);
const [editPopUp, setEditPopUp] = React.useState(false); const [editPopUp, setEditPopUp] = React.useState(false);
const [itemToHandle, setItemToHandle] = React.useState(null); const [itemToHandle, setItemToHandle] = React.useState(null);
const itemsToRender = items.filter((item) => !deletedItems.includes(item)); const itemsToRender = items.filter((item) => !deletedItems.includes(item));
const deleteItem = async (item) => {
await deleteSubmission(
item,
deletedItems,
setDeletedItems,
popUpMessageHandler,
theme
);
};
const desktopRender = () => {
return (
<>
<DeletePopUp
item={itemToHandle}
setDeletePopUp={setDeletePopUp}
deletePopUp={deletePopUp}
deleteItem={deleteItem}
/>
<EditPopUp
item={itemToHandle}
setEditPopUp={setEditPopUp}
editPopUp={editPopUp}
/>
<TableStyle rowFooter={rowFooter}>
<TableHeader
orderedKeys={orderedKeys}
sortByUpdate={sortByUpdate}
tableUpdate={tableUpdate}
/>
{itemsToRender.map((item, i) => {
return (
<tr key={`table-row-${i}`} className="TableStyle__tr">
<TableRowItems orderedKeys={orderedKeys} item={item} i={i} />
<TableRowFooter
deleteItem={() => {
setItemToHandle(item);
setDeletePopUp(true);
}}
editItem={() => {
setItemToHandle(item);
setEditPopUp(true);
}}
rowFooter={rowFooter}
item={item}
i={i}
/>
<RowsBackgroundStyle i={i} />
</tr>
);
})}
</TableStyle>
</>
);
};
return ( return (
<> <>
<DeletePopUp
item={itemToHandle}
setDeletePopUp={setDeletePopUp}
deletePopUp={deletePopUp}
setDeletedItems={setDeletedItems}
deletedItems={deletedItems}
popUpMessageHandler={popUpMessageHandler}
/>
<EditPopUp
item={itemToHandle}
setEditPopUp={setEditPopUp}
editPopUp={editPopUp}
popUpMessageHandler={popUpMessageHandler}
/>
<Media query={theme.mobile}> <Media query={theme.mobile}>
<MobileTable <MobileTable
elements={itemsToRender} elements={itemsToRender}
setDeletePopUp={setDeletePopUp}
deletePopUp={deletePopUp} deletePopUp={deletePopUp}
deleteItem={deleteItem}
orderedKeys={orderedKeys} orderedKeys={orderedKeys}
rowFooter={rowFooter} rowFooter={rowFooter}
deletedItems={deletedItems}
popUpMessageHandler={popUpMessageHandler}
itemToHandle={itemToHandle}
sortByUpdate={sortByUpdate}
tableUpdate={tableUpdate}
setItemToHandle={setItemToHandle}
setEditPopUp={setEditPopUp}
setDeletePopUp={setDeletePopUp}
setDeletedItems={setDeletedItems}
/>
</Media>
<Media query={theme.desktop}>
<DesktopTable
elements={itemsToRender}
deletePopUp={deletePopUp}
orderedKeys={orderedKeys}
rowFooter={rowFooter}
deletedItems={deletedItems}
popUpMessageHandler={popUpMessageHandler}
itemToHandle={itemToHandle}
sortByUpdate={sortByUpdate}
tableUpdate={tableUpdate}
setItemToHandle={setItemToHandle}
setEditPopUp={setEditPopUp}
setDeletePopUp={setDeletePopUp}
setDeletedItems={setDeletedItems}
/> />
</Media> </Media>
<Media query={theme.desktop}>{desktopRender()}</Media>
</> </>
); );
}; };

View File

@ -4,8 +4,32 @@ import Button from '../../../Button';
import { Medium, H3 } from '../../../../../utils/fonts'; import { Medium, H3 } from '../../../../../utils/fonts';
import { FlexColumn, FlexRow } from '../../../../../utils/containers'; import { FlexColumn, FlexRow } from '../../../../../utils/containers';
import theme from '../../../../../utils/theme'; import theme from '../../../../../utils/theme';
import deleteSubmission from '../../../../../api/deleteSubmission';
const DeletePopUp = ({ deletePopUp, setDeletePopUp, deleteItem, item }) => { const deleteItem = async (
item,
setDeletePopUp,
deletedItems,
setDeletedItems,
popUpMessageHandler
) => {
setDeletePopUp(false);
await deleteSubmission(
item,
deletedItems,
setDeletedItems,
popUpMessageHandler
);
};
const DeletePopUp = ({
deletePopUp,
setDeletePopUp,
item,
deletedItems,
setDeletedItems,
popUpMessageHandler,
}) => {
if (deletePopUp) { if (deletePopUp) {
return createPortal( return createPortal(
<PopUp <PopUp
@ -22,10 +46,14 @@ const DeletePopUp = ({ deletePopUp, setDeletePopUp, deleteItem, item }) => {
</Medium> </Medium>
<FlexRow gap="48px"> <FlexRow gap="48px">
<Button <Button
handler={() => { handler={() =>
setDeletePopUp(false); deleteItem(
deleteItem(item); item,
}} deletedItems,
setDeletedItems,
popUpMessageHandler
)
}
> >
Yes Yes
</Button> </Button>

View File

@ -0,0 +1,41 @@
import React from 'react';
import TableStyle from '../../styles/TableStyle';
import TableHeader from '../TableHeader/TableHeader';
import TableRowItems from '../TableRowItems/TableRowItems';
import TableRowFooter from '../TableRowFooter/TableRowFooter';
import RowsBackgroundStyle from '../../styles/RowsBackgroundStyle';
const DesktopTable = (props) => {
return (
<TableStyle rowFooter={props.rowFooter}>
<TableHeader
orderedKeys={props.orderedKeys}
sortByUpdate={props.sortByUpdate}
tableUpdate={props.tableUpdate}
/>
{props.elements.map((item, i) => {
return (
<tr key={`table-row-${i}`} className="TableStyle__tr">
<TableRowItems orderedKeys={props.orderedKeys} item={item} i={i} />
<TableRowFooter
deleteItem={() => {
props.setItemToHandle(item);
props.setDeletePopUp(true);
}}
editItem={() => {
props.setItemToHandle(item);
props.setEditPopUp(true);
}}
rowFooter={props.rowFooter}
item={item}
i={i}
/>
<RowsBackgroundStyle i={i} />
</tr>
);
})}
</TableStyle>
);
};
export default DesktopTable;

View File

@ -0,0 +1 @@
export { default } from './DesktopTable';

View File

@ -10,10 +10,31 @@ import editSubmission from '../../../../../api/editSubmission';
import getTags from '../../../../../api/getTags'; import getTags from '../../../../../api/getTags';
import React from 'react'; import React from 'react';
const EditPopUp = ({ editPopUp, setEditPopUp, item }) => { const editSubmissionHandler = async (
item,
setEditPopUp,
tagsToEdit,
description,
popUpMessageHandler
) => {
setEditPopUp(false);
let tags = '';
if (tagsToEdit) {
tags = tagsToEdit.join(',');
} else {
if (item?.tags) {
tags = item.tags.map((tag) => tag.name).join(',');
}
}
await editSubmission(item.id, tags, description, popUpMessageHandler);
};
const EditPopUp = ({ editPopUp, setEditPopUp, item, popUpMessageHandler }) => {
const [tags, setTags] = React.useState([]); const [tags, setTags] = React.useState([]);
const [tagsToEdit, setTagsToEdit] = React.useState(item?.tags?.slice()); const [tagsToEdit, setTagsToEdit] = React.useState(item?.tags?.slice());
const [description, setDescription] = React.useState(item?.description?.slice()); const [description, setDescription] = React.useState(
item?.description?.slice()
);
React.useMemo(() => { React.useMemo(() => {
getTags(setTags); getTags(setTags);
@ -50,10 +71,15 @@ const EditPopUp = ({ editPopUp, setEditPopUp, item }) => {
<Button <Button
width="100px" width="100px"
height="32px" height="32px"
handler={() => { handler={() =>
setEditPopUp(false); editSubmissionHandler(
editSubmission(item.id, tagsToEdit.join(','), description); item,
}} setEditPopUp,
tagsToEdit,
description,
popUpMessageHandler
)
}
> >
Confirm Confirm
</Button> </Button>
@ -61,7 +87,7 @@ const EditPopUp = ({ editPopUp, setEditPopUp, item }) => {
width="100px" width="100px"
height="32px" height="32px"
handler={() => { handler={() => {
setTagsToEdit([]); setTagsToEdit([]);
setEditPopUp(false); setEditPopUp(false);
}} }}
backgroundColor={theme.colors.dark} backgroundColor={theme.colors.dark}

View File

@ -1,5 +1,4 @@
import React from 'react'; import React from 'react';
import DeletePopUp from '../DeletePopUp/DeletePopUp';
import TableRowItems from '../TableRowItems/TableRowItems'; import TableRowItems from '../TableRowItems/TableRowItems';
import TableRowFooter from '../TableRowFooter/TableRowFooter'; import TableRowFooter from '../TableRowFooter/TableRowFooter';
import MobileTableStyle from './MobileTableStyle'; import MobileTableStyle from './MobileTableStyle';
@ -10,15 +9,16 @@ const MobileTable = (props) => {
{props.elements.map((item, i) => { {props.elements.map((item, i) => {
return ( return (
<tr key={`table-row-${i}`} className="TableStyle__tr"> <tr key={`table-row-${i}`} className="TableStyle__tr">
<DeletePopUp
item={item}
setDeletePopUp={props.setDeletePopUp}
deletePopUp={props.deletePopUp}
deleteItem={props.deleteItem}
/>
<TableRowItems orderedKeys={props.orderedKeys} item={item} i={i} /> <TableRowItems orderedKeys={props.orderedKeys} item={item} i={i} />
<TableRowFooter <TableRowFooter
deleteItem={() => props.setDeletePopUp(true)} deleteItem={() => {
props.setItemToHandle(item);
props.setDeletePopUp(true);
}}
editItem={() => {
props.setItemToHandle(item);
props.setEditPopUp(true);
}}
rowFooter={props.rowFooter} rowFooter={props.rowFooter}
item={item} item={item}
i={i} i={i}