drag drop sort swap

This commit is contained in:
np.w
2020-12-13 13:08:28 -06:00
parent a912fb2836
commit ba4026c6fa
5 changed files with 99 additions and 42 deletions
+45 -13
View File
@@ -8,9 +8,12 @@ import './styles/app.css';
function App() { function App() {
const [data, setData] = useState([]); const [data, setData] = useState([]);
const [boxID, setBoxID] = useState(undefined); const [boxID, setBoxID] = useState(undefined);
const [boxName, setBoxName] = useState(''); const [boxName, setBoxName] = useState('');
const [boxDescription, setBoxDescription] = useState(''); const [boxDescription, setBoxDescription] = useState('');
const [boxSort, setBoxSort] = useState(0);
const [showModalBox, setShowModalBox] = useState(false); const [showModalBox, setShowModalBox] = useState(false);
const [showModalItem, setShowModalItem] = useState(false); const [showModalItem, setShowModalItem] = useState(false);
@@ -24,14 +27,7 @@ function App() {
const [filter, setFilter] = useState(''); const [filter, setFilter] = useState('');
const [filteredData, setFilteredData] = useState([]); const [filteredData, setFilteredData] = useState([]);
const [dragSource, setDragSource] = useState({});
const handleName = (e) => {
setItemName(e.target.value)
}
const handleDescription = (e) => {
setItemDescription(e.target.value)
}
//fetch all box data //fetch all box data
useEffect(() => { useEffect(() => {
@@ -98,6 +94,15 @@ function App() {
} }
} }
const sortBox = async (target, source) => {
try {
const response = await axios.put(`${api.baseApiUrl}/${source._id}/sort`,target);
setData(response.data);
}
catch (error) {
}
}
const handleNameBox = (e) => { const handleNameBox = (e) => {
setBoxName(e.target.value); setBoxName(e.target.value);
} }
@@ -146,13 +151,32 @@ function App() {
setBoxID(undefined); setBoxID(undefined);
} }
const handleDragStartBox = (dragSource, event) => {
setDragSource(dragSource);
event.dataTransfer.dropEffect = "move";
}
const handleDragOverBox = (event) => {
event.preventDefault();
event.dataTransfer.dropEffect = "move";
}
const handleDropBox = async (dragTarget, event) => {
event.preventDefault();
if(dragTarget._id !== dragSource._id) {
const target = dragTarget;
const source = dragSource;
await sortBox(target, source);
}
return false;
}
const boxHandler = { const boxHandler = {
handleSubmit: handleSubmitBox, handleSubmit: handleSubmitBox,
handleRemove: handleRemoveBox, handleRemove: handleRemoveBox,
handleName: handleNameBox, handleName: handleNameBox,
handleDescription: handleBoxDescription, handleDescription: handleBoxDescription,
handleEdit: handleEditBox handleEdit: handleEditBox,
handleDragStart: handleDragStartBox,
handleDragOver: handleDragOverBox,
handleDrop: handleDropBox
}; };
const handleModalCloseBox = () => { const handleModalCloseBox = () => {
@@ -245,11 +269,20 @@ function App() {
setItemDescription(''); setItemDescription('');
} }
const handleNameItem = (e) => {
setItemName(e.target.value)
}
const handleDescriptionItem = (e) => {
setItemDescription(e.target.value)
}
const itemHandler = { const itemHandler = {
handleSubmit: handleSubmitItem, handleSubmit: handleSubmitItem,
handleRemove: handleRemoveItem, handleRemove: handleRemoveItem,
handleAdd: handleAddItem, handleAdd: handleAddItem,
handleEdit: handleEditItem, handleEdit: handleEditItem,
handleName: handleNameItem,
handleDescription: handleDescriptionItem,
}; };
const handleFilterChange = (event) => { const handleFilterChange = (event) => {
@@ -277,10 +310,10 @@ function App() {
<fieldset> <fieldset>
<input id="id" name="id" value={itemID} readOnly hidden></input> <input id="id" name="id" value={itemID} readOnly hidden></input>
<label htmlFor="item-name">name <label htmlFor="item-name">name
<input autoFocus onChange={handleName} value={itemName} id="item-name" name="name" type="text"></input> <input autoFocus onChange={itemHandler.handleName} value={itemName} id="item-name" name="name" type="text"></input>
</label> </label>
<label htmlFor="item-description">description <label htmlFor="item-description">description
<input onChange={handleDescription} value={itemDescription} id="item-description" name="description" type="text"></input> <input onChange={itemHandler.handleDescription} value={itemDescription} id="item-description" name="description" type="text"></input>
</label> </label>
</fieldset> </fieldset>
<button type="submit">submit</button> <button type="submit">submit</button>
@@ -289,7 +322,6 @@ function App() {
<> <>
{<Modal show={showModalItem} edit={editItemBool} content={itemForm} handleClose={handleModalCloseItem} />} {<Modal show={showModalItem} edit={editItemBool} content={itemForm} handleClose={handleModalCloseItem} />}
{<Modal show={showModalBox} edit={editBoxBool} content={boxForm} handleClose={handleModalCloseBox} />} {<Modal show={showModalBox} edit={editBoxBool} content={boxForm} handleClose={handleModalCloseBox} />}
<label htmlFor="box-filter">filter:</label> <label htmlFor="box-filter">filter:</label>
<input type="search" id="box-filter" name="filter" value={filter} onChange={handleFilterChange} /> <input type="search" id="box-filter" name="filter" value={filter} onChange={handleFilterChange} />
<ul className="list-box"> <ul className="list-box">
+10 -5
View File
@@ -4,11 +4,14 @@ import Item from './item';
const Box = ({ boxData, boxHandler, itemHandler }) => { const Box = ({ boxData, boxHandler, itemHandler }) => {
return ( return (
<> <>
<li className="box"> <li className="box" draggable='true'
onDragStart={(event) => boxHandler.handleDragStart(boxData, event)}
onDragOver={boxHandler.handleDragOver}
onDrop={(event) => boxHandler.handleDrop(boxData, event)}>
<span>{boxData.sort}</span>
<h2 className="box-title">{boxData.name}</h2> <h2 className="box-title">{boxData.name}</h2>
<div className="box-subtitle"> <div className="box-subtitle">
<h3>{boxData.description}</h3> <h3>{boxData.description}</h3>
<button onClick={() => itemHandler.handleAdd(boxData._id)}>add item</button>
</div> </div>
<ul className="list-box-item"> <ul className="list-box-item">
{boxData.item.map(((item, index) => { {boxData.item.map(((item, index) => {
@@ -16,11 +19,13 @@ const Box = ({ boxData, boxHandler, itemHandler }) => {
key={index} key={index}
data={item} data={item}
boxID={boxData._id} boxID={boxData._id}
itemHandler={itemHandler}/> itemHandler={itemHandler} />
}))} }))}
</ul> </ul>
<button className="edit-box" onClick={() => boxHandler.handleEdit(boxData._id)}>edit</button> <button className="edit-box box-function" onClick={() => boxHandler.handleEdit(boxData._id)}>edit</button>
<button className="remove-box" onClick={() => boxHandler.handleRemove(boxData._id)}>remove</button> <button className="remove-box box-function" onClick={() => boxHandler.handleRemove(boxData._id)}>remove</button>
<button className="add-item item-function" onClick={() => itemHandler.handleAdd(boxData._id)}>add item</button>
</li> </li>
</> </>
) )
+4 -2
View File
@@ -3,8 +3,10 @@ import React from 'react';
const Item = ({ data, itemHandler, boxID }) => { const Item = ({ data, itemHandler, boxID }) => {
return (<li className="item"> return (<li className="item">
<p className="item-name">{data.name}</p> <p className="item-name">{data.name}</p>
<button onClick={() => itemHandler.handleEdit(boxID, data._id)}>edit</button> <div className="item-menu">
<button onClick={() => itemHandler.handleRemove(boxID, data._id)}>remove</button> <button className="item-function" onClick={() => itemHandler.handleEdit(boxID, data._id)}>edit</button>
<button className="item-function" onClick={() => itemHandler.handleRemove(boxID, data._id)}>remove</button>
</div>
</li>); </li>);
}; };
+13 -4
View File
@@ -25,26 +25,31 @@ h1, h2, h3, h4 {
padding: 0; padding: 0;
} }
button { button {
margin: 0.2em;
border: none; border: none;
padding: 0.4em; padding: 0.4em;
} }
button.remove-box, button.edit-box { button.box-function, button.item-function {
width: 100%; font-size: 1em;
} }
button:hover { button:hover {
cursor: pointer; cursor: pointer;
} }
.box {
box-sizing: content-box;
outline: 1px solid black;
box-shadow: 4px 4px black;
}
.box-subtitle { .box-subtitle {
margin: 0;
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
font-size: 12px; font-size: 12px;
text-transform: lowercase; text-transform: lowercase;
} }
ul.list-box { ul.list-box {
padding: 10px;
display: grid; display: grid;
grid-template-columns: repeat(5, 1fr); grid-template-columns: repeat(5, 1fr);
padding: 0 0 0 1em;
margin: 0; margin: 0;
gap: 1em; gap: 1em;
} }
@@ -55,3 +60,7 @@ ul.list-box-item {
p { p {
margin: 0; margin: 0;
} }
.drop-zone {
width: 100px;
height: 100px;
}
+14 -5
View File
@@ -22,17 +22,16 @@ db.once('open', function() {
/*------------MODELS------------*/ /*------------MODELS------------*/
//create schema //create schema
var itemSchema = new mongoose.Schema({ var itemSchema = new mongoose.Schema({
id: String,
name: String, name: String,
description: String, description: String,
quantity: Number quantity: Number
}); });
var boxSchema = new mongoose.Schema({ var boxSchema = new mongoose.Schema({
id: String,
name: String, name: String,
description: String, description: String,
item: [itemSchema], item: [itemSchema],
sort: Number,
}); });
//compile schema into model //compile schema into model
@@ -51,7 +50,9 @@ app.get('/box', async (request, response) => {
// create box // create box
app.post('/box', async (request, response) => { app.post('/box', async (request, response) => {
await Box.create(request.body); const numBoxes = await Box.countDocuments({});
const query = Object.assign({sort: numBoxes}, request.body);
await Box.create(query);
const updatedBoxes = await getAllBoxes(); const updatedBoxes = await getAllBoxes();
response.send(updatedBoxes); response.send(updatedBoxes);
}); });
@@ -68,7 +69,15 @@ app.delete('/box/:id', async (request, response) => {
const updatedBoxes = await getAllBoxes(); const updatedBoxes = await getAllBoxes();
response.send(updatedBoxes); response.send(updatedBoxes);
}); });
//change box sort
app.put('/box/:id/sort', async (request, response) => {
const source = await getBox(request.params.id);
const target = request.body;
await Box.updateOne({ _id: source._id }, { $set: { sort: target.sort } });
await Box.updateOne({ _id: target._id }, { $set: { sort: source.sort } });
const updatedBoxes = await getAllBoxes();
response.send(updatedBoxes);
})
//create item //create item
app.post('/box/:id/item', async (request, response) => { app.post('/box/:id/item', async (request, response) => {
const id = request.params.id; const id = request.params.id;
@@ -106,7 +115,7 @@ app.delete('/box/:boxId/item/:itemId', async (request, response) => {
const getAllBoxes = async (queryParameters) => { const getAllBoxes = async (queryParameters) => {
queryParameters = queryParameters ?? {}; queryParameters = queryParameters ?? {};
const data = await Box.find(queryParameters); const data = await Box.find(queryParameters).sort({sort: 1});
return data; return data;
} }