frontend: create_config: use InputValue + more params

This commit is contained in:
2025-11-13 14:25:51 +03:00
parent 0978b6c702
commit 9a9f92ed95

View File

@@ -2,16 +2,23 @@ use gloo::net::http::Request;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use wasm_bindgen_futures::spawn_local; use wasm_bindgen_futures::spawn_local;
use yew::prelude::*; use yew::prelude::*;
use yewlish_checkbox::*;
use crate::{ use crate::{
api::APIEndpoints, api::APIEndpoints,
components::{alerts::ErrorAlert, pages::config::Config}, components::{alerts::ErrorAlert, input_value::InputValue, pages::config::Config},
}; };
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
struct GenerationRequest { struct GenerationRequest {
directory: String, directory: String,
common_name: String, common_name: String,
#[serde(default)]
email: String,
#[serde(default)]
days: u32,
#[serde(default)]
use_openssl: Option<bool>,
} }
#[derive(Properties, PartialEq)] #[derive(Properties, PartialEq)]
@@ -23,6 +30,10 @@ pub struct GenerateProps {
pub fn create_config(props: &GenerateProps) -> Html { pub fn create_config(props: &GenerateProps) -> Html {
let dir_name = props.dir.clone(); let dir_name = props.dir.clone();
let config_name = use_state(|| "".to_string()); let config_name = use_state(|| "".to_string());
let email = use_state(|| "".to_string());
let days: UseStateHandle<u32> = use_state(|| 0);
let use_openssl: UseStateHandle<Option<bool>> = use_state(|| None);
let result = use_state(|| "".to_string()); let result = use_state(|| "".to_string());
let error = use_state(|| "".to_string()); let error = use_state(|| "".to_string());
let done = use_state(|| false); let done = use_state(|| false);
@@ -30,6 +41,10 @@ pub fn create_config(props: &GenerateProps) -> Html {
let generate_config_request = { let generate_config_request = {
let dir_name = dir_name.clone(); let dir_name = dir_name.clone();
let config_name = config_name.clone(); let config_name = config_name.clone();
let email = email.clone();
let days = days.clone();
let use_openssl = use_openssl.clone();
let done = done.clone(); let done = done.clone();
let result = result.clone(); let result = result.clone();
let error = error.clone(); let error = error.clone();
@@ -37,6 +52,9 @@ pub fn create_config(props: &GenerateProps) -> Html {
let request_body = GenerationRequest { let request_body = GenerationRequest {
directory: dir_name.clone().to_string(), directory: dir_name.clone().to_string(),
common_name: config_name.clone().to_string(), common_name: config_name.clone().to_string(),
email: email.clone().to_string(),
days: *days.clone(),
use_openssl: *use_openssl.clone(),
}; };
let json_payload = serde_json::to_string(&request_body).unwrap(); let json_payload = serde_json::to_string(&request_body).unwrap();
let result = result.clone(); let result = result.clone();
@@ -69,21 +87,58 @@ pub fn create_config(props: &GenerateProps) -> Html {
<> <>
if !*done.clone() { if !*done.clone() {
<div class="grid place-items-center"> <div class="grid place-items-center">
<br/> <div class="w-full max-w-sm p-4 m-7 bg-white border border-gray-200 rounded-lg shadow-sm sm:p-6 md:p-8 dark:bg-gray-800 dark:border-gray-700">
<div class="w-full max-w-sm p-4 bg-white border border-gray-200 rounded-lg shadow-sm sm:p-6 md:p-8 dark:bg-gray-800 dark:border-gray-700">
<form class="space-y-6" action="#"> <form class="space-y-6" action="#">
<h5 class="text-xl font-medium text-gray-900 dark:text-white">{format!("Создание конфигурации для {}:", props.dir.clone())}</h5> <h5 class="text-xl font-medium text-gray-900 dark:text-white">{format!("Создание конфигурации для {}:", props.dir.clone())}</h5>
<div> <InputValue id="common-name" label="Имя:" placeholder="введите название" required=true oninput={
<label class="block mb-2 text-sm font-medium text-gray-900 dark:text-white" for="common-name">{"Имя:"} Callback::from({
</label>
<input type="text" id="common-name" placeholder="введите название" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white" required=true oninput={Callback::from({
let config_name = config_name.clone(); let config_name = config_name.clone();
move |e: InputEvent| { move |e: InputEvent| {
let input = e.target_dyn_into::<web_sys::HtmlInputElement>().unwrap(); let input = e.target_dyn_into::<web_sys::HtmlInputElement>().unwrap();
config_name.set(input.value()); config_name.set(input.value());
} }
})} /> })
} />
<InputValue id="email" label="Email:" placeholder="(необязательно)" oninput={
Callback::from({
let email = email.clone();
move |e: InputEvent| {
let input = e.target_dyn_into::<web_sys::HtmlInputElement>().unwrap();
email.set(input.value());
}
})
} />
<InputValue id="days" label="Дней:" placeholder="(необязательно)" _type="number" oninput={
Callback::from({
let days = days.clone();
move |e: InputEvent| {
let input = e.target_dyn_into::<web_sys::HtmlInputElement>().unwrap();
days.set(input.value().parse().unwrap_or_default());
}
})
} />
<div>
<label for={"use_openssl"} class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
{"Использовать OpenSSL "}
<Checkbox id="use_openssl" name="use_openssl" value="yes" default_checked={CheckedState::Indeterminate} on_checked_change={
Callback::from(move |new_state: CheckedState| {
let use_openssl = use_openssl.clone();
use_openssl.set(Some(new_state == CheckedState::Checked));
}) }>
<CheckboxIndicator show_when={CheckedState::Checked}>
{""}
</CheckboxIndicator>
<CheckboxIndicator show_when={CheckedState::Indeterminate}>
{""}
</CheckboxIndicator>
<CheckboxIndicator show_when={CheckedState::Unchecked}>
{""}
</CheckboxIndicator>
</Checkbox>
</label>
</div> </div>
<button type="button" onclick={generate_config_request.reform(|_| ())} <button type="button" onclick={generate_config_request.reform(|_| ())}
class="text-white bg-gradient-to-r from-red-400 via-red-500 to-red-600 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-red-300 dark:focus:ring-red-800 shadow-lg shadow-red-500/50 dark:shadow-lg dark:shadow-red-800/80 font-medium rounded-lg text-sm px-5 py-2.5 text-center me-2 mb-2"> class="text-white bg-gradient-to-r from-red-400 via-red-500 to-red-600 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-red-300 dark:focus:ring-red-800 shadow-lg shadow-red-500/50 dark:shadow-lg dark:shadow-red-800/80 font-medium rounded-lg text-sm px-5 py-2.5 text-center me-2 mb-2">
{ "Создать" } { "Создать" }