Update ticket status now possible
Also bugfixes and api is now called over the same url as frontend
This commit is contained in:
@@ -16,8 +16,8 @@ serde = { version = "1.0.228", features = ["derive"] }
|
||||
wasm-bindgen = "0.2.118"
|
||||
wasm-bindgen-futures = "0.4.68"
|
||||
web-sys = { version = "0.3.95", features = [
|
||||
"Window","Document","Request","Response","Headers",
|
||||
"SubmitEvent","InputEvent","HtmlInputElement","Event"
|
||||
"Window","Document","Request","Response","Headers", "HtmlSelectElement",
|
||||
"SubmitEvent","InputEvent","HtmlInputElement","Event", "HtmlFormElement"
|
||||
] }
|
||||
gloo-net = "0.7.0"
|
||||
yew-router = "0.20.0"
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
use gloo_net::http::Request;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen_futures::spawn_local;
|
||||
use web_sys::HtmlSelectElement;
|
||||
use yew::prelude::*;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
|
||||
@@ -12,6 +14,11 @@ pub struct TicketCreateScheme {
|
||||
pub room: i16,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
|
||||
pub struct TicketUpdateScheme {
|
||||
pub status: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
|
||||
pub struct Ticket {
|
||||
pub id: i32,
|
||||
@@ -32,7 +39,7 @@ pub struct TicketProps {
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct ApiError {
|
||||
message: String,
|
||||
status: String,
|
||||
_status: String,
|
||||
}
|
||||
|
||||
#[component(SubmitTicket)]
|
||||
@@ -66,7 +73,7 @@ pub fn submit_ticket_component() -> Html {
|
||||
room,
|
||||
};
|
||||
|
||||
let request = Request::post("http://localhost:8001/api/tickets/create")
|
||||
let request = Request::post("/api/tickets/create")
|
||||
.json(&payload)
|
||||
.expect("Failed to build request");
|
||||
|
||||
@@ -81,8 +88,8 @@ pub fn submit_ticket_component() -> Html {
|
||||
|
||||
let category_change = {
|
||||
let category = category.clone();
|
||||
Callback::from(move |e: InputEvent| {
|
||||
let input: web_sys::HtmlInputElement = e.target_unchecked_into();
|
||||
Callback::from(move |e: Event| {
|
||||
let input: web_sys::HtmlSelectElement = e.target_unchecked_into();
|
||||
category.set(input.value());
|
||||
})
|
||||
};
|
||||
@@ -122,7 +129,14 @@ pub fn submit_ticket_component() -> Html {
|
||||
</label>
|
||||
<br/>
|
||||
<label>{ "Kategorie:" }
|
||||
<input type="text" value={(*category).clone()} oninput={category_change}/>
|
||||
<select value={(*category).clone()} onchange={category_change}>
|
||||
<option value="Whiteboard Beamer">{ "Whiteboard Beamer" }</option>
|
||||
<option value="Internet">{ "Internet" }</option>
|
||||
<option value="iPad Koffer">{ "iPad Koffer" }</option>
|
||||
<option value="Apple TV">{ "Apple TV" }</option>
|
||||
<option value="Docu Cam">{ "Dokumenten Kamera" }</option>
|
||||
<option value="Sonstiges">{ "Sonstiges" }</option>
|
||||
</select>
|
||||
</label>
|
||||
<br/>
|
||||
<label>{ "Raum:" }
|
||||
@@ -149,6 +163,7 @@ pub fn show_ticket_by_id_component(props: &TicketProps) -> Html {
|
||||
let error = use_state(|| None::<String>);
|
||||
let loading = use_state(|| false);
|
||||
let id = props.id;
|
||||
let status = use_state(|| "".to_string());
|
||||
|
||||
{
|
||||
let ticket = ticket.clone();
|
||||
@@ -161,7 +176,7 @@ pub fn show_ticket_by_id_component(props: &TicketProps) -> Html {
|
||||
let error = error.clone();
|
||||
let id = *id_ref;
|
||||
spawn_local(async move {
|
||||
let url = format!("http://localhost:8001/api/tickets/{}", id);
|
||||
let url = format!("/api/tickets/{}", id);
|
||||
match Request::get(&url).send().await {
|
||||
Ok(response) => {
|
||||
let status = response.status();
|
||||
@@ -190,6 +205,43 @@ pub fn show_ticket_by_id_component(props: &TicketProps) -> Html {
|
||||
|| ()
|
||||
});
|
||||
}
|
||||
let onsubmit = {
|
||||
let status = status.clone();
|
||||
let id = id.clone();
|
||||
let error = error.clone();
|
||||
|
||||
Callback::from(move |e: SubmitEvent| {
|
||||
e.prevent_default();
|
||||
let form: web_sys::HtmlFormElement = e.target_unchecked_into();
|
||||
let select_element = form
|
||||
.query_selector("select[name=\"status\"]")
|
||||
.ok()
|
||||
.and_then(|opt| opt)
|
||||
.and_then(|el| el.dyn_into::<HtmlSelectElement>().ok());
|
||||
let new_status = select_element
|
||||
.map(|s| s.value())
|
||||
.unwrap_or_else(|| (*status).clone());
|
||||
status.set(new_status.clone());
|
||||
|
||||
let id = id.clone();
|
||||
let error = error.clone();
|
||||
|
||||
spawn_local(async move {
|
||||
let value = TicketUpdateScheme { status: new_status };
|
||||
|
||||
let url = format!("/api/tickets/{}", id);
|
||||
let request = Request::patch(&url)
|
||||
.json(&value)
|
||||
.expect("Failed to construct request");
|
||||
|
||||
match request.send().await {
|
||||
Ok(response) if response.status() == 200 => error.set(Some("Success".into())),
|
||||
Ok(response) => error.set(Some(format!("Error: {}", response.status()))),
|
||||
Err(err) => error.set(Some(format!("Network error: {}", err))),
|
||||
}
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
if *loading {
|
||||
html! {<p>{ "Loading" }</p>}
|
||||
@@ -204,7 +256,25 @@ pub fn show_ticket_by_id_component(props: &TicketProps) -> Html {
|
||||
<p><strong>{ "Beschreibung: " }</strong>{ &t.description }</p>
|
||||
<p><strong>{ "Raum: " }</strong>{ t.room }</p>
|
||||
<p><strong>{ "Datum: " }</strong>{ &t.date }</p>
|
||||
<p><strong>{ "Status: "}</strong>{ &t.status }</p>
|
||||
<p><strong>{ "Status: "}</strong>{ match t.status.as_str() {
|
||||
"ToDo" => "Zu tun",
|
||||
"InProgress" => "In Bearbeitung",
|
||||
"Completed" => "Erledigt",
|
||||
"Archived" => "Archiviert",
|
||||
_ => "Ungültiger Status"
|
||||
}}</p>
|
||||
|
||||
<form {onsubmit}>
|
||||
<label>{ "Status ändern" }
|
||||
<select name="status">
|
||||
<option value="ToDo">{ "Zu tun" }</option>
|
||||
<option value="InProgress">{ "In Bearbeitung" }</option>
|
||||
<option value="Completed">{ "Erledigt" }</option>
|
||||
<option value="Archived">{ "Archiviert" }</option>
|
||||
</select>
|
||||
</label>
|
||||
<button type="submit">{ "Aktualisieren" }</button>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
} else {
|
||||
@@ -226,7 +296,7 @@ pub fn all_tickets_component() -> Html {
|
||||
use_effect_with((), move |_| {
|
||||
loading.set(true);
|
||||
spawn_local(async move {
|
||||
let url = format!("http://localhost:8001/api/tickets");
|
||||
let url = format!("/api/tickets");
|
||||
match Request::get(&url).send().await {
|
||||
Ok(response) if response.status() == 200 => {
|
||||
match response.json::<Vec<Ticket>>().await {
|
||||
|
||||
Reference in New Issue
Block a user