mirror of
https://github.com/sigmasternchen/threadule
synced 2025-03-15 08:09:01 +00:00
feat: added drag and drop in tweet list; mark tweets on error
This commit is contained in:
parent
5d3f35234d
commit
75fca7d41b
3 changed files with 90 additions and 42 deletions
|
@ -12,12 +12,14 @@
|
|||
"@types/jest": "^26.0.15",
|
||||
"@types/node": "^12.0.0",
|
||||
"@types/react": "^17.0.0",
|
||||
"@types/react-beautiful-dnd": "^13.1.1",
|
||||
"@types/react-dom": "^17.0.0",
|
||||
"@types/react-router-dom": "^5.1.8",
|
||||
"axios": "^0.21.1",
|
||||
"formik": "^2.2.9",
|
||||
"formik-material-ui": "^3.0.1",
|
||||
"react": "^17.0.2",
|
||||
"react-beautiful-dnd": "^13.1.0",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-scripts": "4.0.3",
|
||||
|
|
|
@ -18,7 +18,7 @@ const emptyThread = (): Thread => ({
|
|||
status: ThreadStatus.SCHEDULED,
|
||||
tweets: [
|
||||
{
|
||||
id: "",
|
||||
id: "new",
|
||||
text: "",
|
||||
status: TweetStatus.SCHEDULED,
|
||||
tweet_id: null,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {FunctionComponent, useState} from "react";
|
||||
import React, {FunctionComponent, useState} from "react";
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
|
@ -16,6 +16,7 @@ import AddIcon from "@material-ui/icons/Add";
|
|||
import {TweetStatus} from "../../api/entities/Tweet";
|
||||
import CustomDate from "../../utils/CustomDate";
|
||||
import {Alert} from "@material-ui/lab";
|
||||
import {DragDropContext, Draggable, Droppable} from "react-beautiful-dnd";
|
||||
|
||||
export type ThreadFormProps = {
|
||||
open: boolean
|
||||
|
@ -34,9 +35,15 @@ const Index: FunctionComponent<ThreadFormProps> = (
|
|||
onCancel
|
||||
}
|
||||
) => {
|
||||
const [_idCounter, _setIdCounter] = useState<number>(0)
|
||||
const getId = () => {
|
||||
_setIdCounter(_idCounter + 1)
|
||||
return _idCounter
|
||||
}
|
||||
|
||||
const [thread, setThread] = useState<Thread>(initial)
|
||||
|
||||
const [error, setError] = useState<string|null>(null)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
|
||||
return (
|
||||
<Dialog open={open}>
|
||||
|
@ -62,11 +69,39 @@ const Index: FunctionComponent<ThreadFormProps> = (
|
|||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<DragDropContext onDragEnd={() => {
|
||||
}}>
|
||||
<Droppable droppableId={"1"}>
|
||||
{(provided, snapshot) => (
|
||||
<Grid
|
||||
container
|
||||
item
|
||||
xs={12}
|
||||
{...provided.droppableProps}
|
||||
ref={provided.innerRef}
|
||||
>
|
||||
{
|
||||
thread.tweets.map((tweet, index) => (
|
||||
<>
|
||||
<Draggable draggableId={tweet.id} index={index}>
|
||||
{(provided, snapshot) => (
|
||||
<Grid
|
||||
container
|
||||
item
|
||||
xs={12}
|
||||
ref={provided.innerRef}
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
style={{
|
||||
...provided.draggableProps.style,
|
||||
background: snapshot.isDragging ? "lightgrey" : undefined
|
||||
}}
|
||||
>
|
||||
<Grid item xs={11}>
|
||||
<TextField
|
||||
error={
|
||||
thread.tweets[index].text.trim().length == 0 ||
|
||||
thread.tweets[index].text.length > 280
|
||||
}
|
||||
id="outlined-multiline-static"
|
||||
label={"Tweet " + (index + 1)}
|
||||
multiline
|
||||
|
@ -94,16 +129,23 @@ const Index: FunctionComponent<ThreadFormProps> = (
|
|||
})
|
||||
}}
|
||||
>
|
||||
<DeleteIcon fontSize="medium" />
|
||||
<DeleteIcon fontSize="medium"/>
|
||||
</IconButton>
|
||||
</Grid>
|
||||
</>
|
||||
</Grid>
|
||||
)}
|
||||
</Draggable>
|
||||
))
|
||||
}
|
||||
{provided.placeholder}
|
||||
</Grid>
|
||||
)}
|
||||
</Droppable>
|
||||
</DragDropContext>
|
||||
<Grid item xs={12}>
|
||||
<IconButton aria-label="add" onClick={() => {
|
||||
thread.tweets.push({
|
||||
id: "",
|
||||
id: "new" + getId(),
|
||||
text: "",
|
||||
status: TweetStatus.SCHEDULED,
|
||||
tweet_id: null,
|
||||
|
@ -117,7 +159,7 @@ const Index: FunctionComponent<ThreadFormProps> = (
|
|||
</IconButton>
|
||||
</Grid>
|
||||
</Grid>
|
||||
{ error && <Alert severity="error">{error}</Alert> }
|
||||
{error && <Alert severity="error">{error}</Alert>}
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={() => {
|
||||
|
@ -131,6 +173,10 @@ const Index: FunctionComponent<ThreadFormProps> = (
|
|||
setError("Empty tweets are not allowed!")
|
||||
return
|
||||
}
|
||||
if (!thread.tweets.every(t => t.text.length <= 280)) {
|
||||
setError("Tweets can't be longer than 280 characters!")
|
||||
return
|
||||
}
|
||||
setError(null)
|
||||
onSubmit(thread)
|
||||
}} color="primary">
|
||||
|
|
Loading…
Reference in a new issue