Add the ability to delete tasks.
This commit is contained in:
parent
c07df0b094
commit
d87c2e8922
|
@ -44,7 +44,12 @@ type Status a
|
|||
|
||||
init : Nav.Key -> ( Model, Cmd Msg )
|
||||
init navKey =
|
||||
( Model navKey Loading True defaultCreateTask
|
||||
reloadTasks (Model navKey Loading True defaultCreateTask)
|
||||
|
||||
|
||||
reloadTasks : Model -> ( Model, Cmd Msg )
|
||||
reloadTasks model =
|
||||
( model
|
||||
, Http.get
|
||||
{ url = "http://localhost:3000/tasks"
|
||||
, expect = Http.expectJson GotTasks (list taskDecoder)
|
||||
|
@ -55,10 +60,12 @@ init navKey =
|
|||
type Msg
|
||||
= GotTasks (Result Http.Error (List Task))
|
||||
| ToggleCreateTask
|
||||
| CreateTask
|
||||
| GotTaskCreated (Result Http.Error Task)
|
||||
| CreateTaskUpdateTitle String
|
||||
| CreateTaskUpdateDescription String
|
||||
| CreateTask
|
||||
| GotTaskCreated (Result Http.Error Task)
|
||||
| DeleteTask Int
|
||||
| GotTaskDeleted (Result Http.Error ())
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
|
@ -113,6 +120,22 @@ update msg model =
|
|||
in
|
||||
( { model | createTask = { createTask | description = description } }, Cmd.none )
|
||||
|
||||
DeleteTask id ->
|
||||
( model
|
||||
, Http.request
|
||||
{ method = "DELETE"
|
||||
, headers = []
|
||||
, url = "http://localhost:3000/tasks/" ++ String.fromInt id
|
||||
, body = Http.emptyBody
|
||||
, expect = Http.expectWhatever GotTaskDeleted
|
||||
, timeout = Nothing
|
||||
, tracker = Nothing
|
||||
}
|
||||
)
|
||||
|
||||
GotTaskDeleted _ ->
|
||||
reloadTasks model
|
||||
|
||||
|
||||
taskDecoder : Decoder Task
|
||||
taskDecoder =
|
||||
|
@ -186,6 +209,7 @@ viewTaskListItem task =
|
|||
""
|
||||
)
|
||||
)
|
||||
, button [ onClick (DeleteTask task.id) ] [ text "Delete Task" ]
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ mod routes;
|
|||
|
||||
use axum::http::{StatusCode, Uri};
|
||||
use axum::response::IntoResponse;
|
||||
use axum::routing::get;
|
||||
use axum::routing::{delete, get};
|
||||
use dotenvy::dotenv;
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
|
@ -28,6 +28,10 @@ async fn main() {
|
|||
.post(routes::tasks::create)
|
||||
.options(routes::tasks::options),
|
||||
)
|
||||
.route(
|
||||
"/tasks/:task_id",
|
||||
delete(routes::tasks::delete).options(routes::tasks::options),
|
||||
)
|
||||
.with_state(state);
|
||||
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{FromRow, SqlitePool};
|
||||
use sqlx::{sqlite::SqliteQueryResult, FromRow, SqlitePool};
|
||||
|
||||
#[derive(Serialize, Deserialize, FromRow)]
|
||||
pub struct Task {
|
||||
|
@ -32,4 +32,10 @@ impl Task {
|
|||
.fetch_one(pool)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn delete(pool: &SqlitePool, id: i64) -> Result<SqliteQueryResult, sqlx::Error> {
|
||||
sqlx::query!("DELETE FROM task WHERE id = ?1", id)
|
||||
.execute(pool)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use axum::extract::{Json, State};
|
||||
use axum::extract::{Json, Path, State};
|
||||
use axum::http::header;
|
||||
use axum::http::StatusCode;
|
||||
use axum::response::IntoResponse;
|
||||
|
@ -59,9 +57,22 @@ pub async fn options() -> impl IntoResponse {
|
|||
StatusCode::OK,
|
||||
[
|
||||
(header::ACCESS_CONTROL_ALLOW_ORIGIN, "*"),
|
||||
(header::ACCESS_CONTROL_ALLOW_METHODS, "POST, GET, OPTIONS"),
|
||||
(
|
||||
header::ACCESS_CONTROL_ALLOW_METHODS,
|
||||
"POST, GET, OPTIONS, DELETE",
|
||||
),
|
||||
(header::ACCESS_CONTROL_ALLOW_HEADERS, "Content-Type"),
|
||||
(header::ACCESS_CONTROL_MAX_AGE, "86400"),
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn delete(state: State<AppState>, Path(id): Path<i64>) -> impl IntoResponse {
|
||||
Task::delete(&state.db_pool, id).await.unwrap();
|
||||
|
||||
(
|
||||
StatusCode::OK,
|
||||
[(header::ACCESS_CONTROL_ALLOW_ORIGIN, "*")],
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue