mirror of
https://github.com/sigmasternchen/threadule
synced 2025-03-15 08:09:01 +00:00
feat: deleting threads now works
This commit is contained in:
parent
10e012aacb
commit
20ddede04e
9 changed files with 108 additions and 4 deletions
|
@ -28,6 +28,7 @@ type Data interface {
|
|||
|
||||
AddThread(thread *models.Thread) error
|
||||
UpdateThread(thread *models.Thread) error
|
||||
DeleteThread(id uuid.UUID) error
|
||||
GetThread(id uuid.UUID, user *models.User) (*models.Thread, error)
|
||||
GetThreads(user *models.User) ([]models.Thread, error)
|
||||
GetScheduledThreads() ([]models.Thread, error)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
uuid "github.com/satori/go.uuid"
|
||||
"net/url"
|
||||
"threadule/backend/internal/data/models"
|
||||
)
|
||||
|
@ -15,5 +16,6 @@ type Logic interface {
|
|||
|
||||
AddThread(thread *models.Thread, user *models.User) error
|
||||
UpdateThread(thread *models.Thread, user *models.User) error
|
||||
DeleteThread(id uuid.UUID) error
|
||||
GetThreads(user *models.User) ([]models.Thread, error)
|
||||
}
|
||||
|
|
|
@ -31,6 +31,10 @@ func (d *Data) UpdateThreadWithoutTweets(thread *models.Thread) error {
|
|||
Error
|
||||
}
|
||||
|
||||
func (d *Data) DeleteThread(id uuid.UUID) error {
|
||||
return d.db.Delete(&models.Thread{}, id).Error
|
||||
}
|
||||
|
||||
func (d *Data) GetThread(id uuid.UUID, user *models.User) (*models.Thread, error) {
|
||||
var thread models.Thread
|
||||
err := d.db.
|
||||
|
|
|
@ -46,6 +46,10 @@ func (l *Logic) UpdateThread(thread *models.Thread, user *models.User) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (l *Logic) DeleteThread(id uuid.UUID) error {
|
||||
return l.ctx.Data.DeleteThread(id)
|
||||
}
|
||||
|
||||
func (l *Logic) GetThreads(user *models.User) ([]models.Thread, error) {
|
||||
return l.ctx.Data.GetThreads(user)
|
||||
}
|
||||
|
|
|
@ -54,6 +54,20 @@ func UpdateThread(ctx *web.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
func DeleteThread(ctx *web.Context) {
|
||||
id, err := uuid.FromString(ctx.Params.ByName("id"))
|
||||
if err != nil {
|
||||
ErrorResponse(ctx, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = ctx.AppCtx.Logic.DeleteThread(id)
|
||||
if err != nil {
|
||||
ErrorResponse(ctx, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func GetThreads(ctx *web.Context) {
|
||||
threads, err := ctx.AppCtx.Logic.GetThreads(ctx.Session.User)
|
||||
if err != nil {
|
||||
|
|
|
@ -30,6 +30,7 @@ func Setup(ctx *app.Context) http.Handler {
|
|||
router.GET("/thread", authenticated(GetThreads))
|
||||
router.POST("/thread/", authenticated(AddThread))
|
||||
router.PUT("/thread/:id", authenticated(UpdateThread))
|
||||
router.DELETE("/thread/:id", authenticated(DeleteThread))
|
||||
|
||||
return router
|
||||
}
|
||||
|
|
|
@ -17,6 +17,10 @@ class ThreadEndpoint extends Endpoint {
|
|||
public async update(thread: Thread): Promise<Thread> {
|
||||
return await this.put<Thread, Thread>(API_PREFIX + thread.id, thread)
|
||||
}
|
||||
|
||||
public async remove(thread: Thread): Promise<void> {
|
||||
return await this.delete<void>(API_PREFIX + thread.id)
|
||||
}
|
||||
}
|
||||
|
||||
export default ThreadEndpoint
|
|
@ -82,6 +82,10 @@ const AccountCard: FunctionComponent<AccountCardProps> = (
|
|||
<ThreadList
|
||||
threads={account.threads}
|
||||
onSelect={openEditForm}
|
||||
onDelete={(thread) => {
|
||||
account.threads = account.threads.filter(t => t.id != thread.id)
|
||||
onUpdate(account)
|
||||
}}
|
||||
/>
|
||||
</CardContent>
|
||||
<CardActions disableSpacing>
|
||||
|
|
|
@ -1,16 +1,73 @@
|
|||
import {FunctionComponent} from "react";
|
||||
import {Avatar, List, ListItem, ListItemAvatar, ListItemText, Typography} from "@material-ui/core";
|
||||
import {FunctionComponent, useState} from "react";
|
||||
import {
|
||||
Avatar,
|
||||
IconButton,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemAvatar,
|
||||
ListItemSecondaryAction,
|
||||
ListItemText,
|
||||
Typography
|
||||
} from "@material-ui/core";
|
||||
import Thread from "../../api/entities/Thread";
|
||||
import CustomDate from "../../utils/CustomDate";
|
||||
import styles from "./ThreadList.module.css"
|
||||
import DeleteIcon from "@material-ui/icons/Delete";
|
||||
import {useAuth} from "../../auth/AuthProvider";
|
||||
import ThreadEndpoint from "../../api/endpoints/ThreadEndpoint";
|
||||
import {MessageBox, MessageBoxProps} from "../MessageBox";
|
||||
|
||||
|
||||
export type ThreadListProps = {
|
||||
threads: Thread[]
|
||||
onSelect: (thread: Thread) => void
|
||||
onDelete: (thread: Thread) => void
|
||||
}
|
||||
|
||||
const ThreadList: FunctionComponent<ThreadListProps> = ({threads, onSelect}) => {
|
||||
|
||||
const ThreadList: FunctionComponent<ThreadListProps> = (
|
||||
{
|
||||
threads,
|
||||
onSelect,
|
||||
onDelete
|
||||
}
|
||||
) => {
|
||||
const {client} = useAuth()
|
||||
|
||||
const [message, setMessage] = useState<MessageBoxProps>({
|
||||
open: false,
|
||||
success: false,
|
||||
message: "",
|
||||
onClose: () => {
|
||||
setMessage({
|
||||
...message,
|
||||
open: false,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const deleteThread = (thread: Thread) => {
|
||||
new ThreadEndpoint(client).remove(thread)
|
||||
.then(() => {
|
||||
onDelete(thread)
|
||||
setMessage({
|
||||
...message,
|
||||
open: true,
|
||||
success: true,
|
||||
message: "Thread was deleted successfully."
|
||||
})
|
||||
})
|
||||
.catch((errors) => {
|
||||
console.error(errors)
|
||||
setMessage({
|
||||
...message,
|
||||
open: true,
|
||||
success: false,
|
||||
message: "Thread couldn't be deleted."
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if (threads.length == 0) {
|
||||
return (
|
||||
<Typography style={{
|
||||
|
@ -21,6 +78,7 @@ const ThreadList: FunctionComponent<ThreadListProps> = ({threads, onSelect}) =>
|
|||
)
|
||||
} else {
|
||||
return (
|
||||
<>
|
||||
<List>
|
||||
{threads.map(thread => {
|
||||
return (
|
||||
|
@ -38,11 +96,23 @@ const ThreadList: FunctionComponent<ThreadListProps> = ({threads, onSelect}) =>
|
|||
</ListItemAvatar>
|
||||
<ListItemText
|
||||
primary={<span className={styles.title}>{thread.tweets[0].text}</span>}
|
||||
secondary={new CustomDate(thread.scheduled_for).toLocalISOString(false, true)}/>
|
||||
secondary={new CustomDate(thread.scheduled_for).toLocalISOString(false, true)}
|
||||
/>
|
||||
<ListItemSecondaryAction>
|
||||
<IconButton
|
||||
edge="end"
|
||||
aria-label="delete"
|
||||
onClick={() => deleteThread(thread)}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</ListItemSecondaryAction>
|
||||
</ListItem>
|
||||
)
|
||||
})}
|
||||
</List>
|
||||
<MessageBox {...message} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue