You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
3.9 KiB
Rust
138 lines
3.9 KiB
Rust
use crate::locales::trl;
|
|
use leptos::*;
|
|
use crate::app::DialogHelper;
|
|
use crate::validator::Validator;
|
|
|
|
#[derive(Copy, Clone)]
|
|
pub struct DialogOpener {
|
|
visible: ReadSignal<bool>,
|
|
set_visible: WriteSignal<bool>,
|
|
empty: ReadSignal<String>,
|
|
set_empty: WriteSignal<String>,
|
|
not_checked: ReadSignal<Option<String>>,
|
|
set_not_checked: WriteSignal<Option<String>>,
|
|
show_err: RwSignal<bool>
|
|
}
|
|
|
|
impl DialogOpener {
|
|
pub fn new() -> Self {
|
|
let (visible, set_visible) = create_signal(false);
|
|
let (empty, set_empty) = create_signal("".to_string());
|
|
let (not_checked, set_not_checked) = create_signal(None);
|
|
let show_err = create_rw_signal(false);
|
|
DialogOpener {
|
|
visible,
|
|
set_visible,
|
|
empty,
|
|
set_empty,
|
|
not_checked,
|
|
set_not_checked,
|
|
show_err
|
|
}
|
|
}
|
|
|
|
pub fn visible(&self) -> bool {
|
|
self.visible.get()
|
|
}
|
|
|
|
pub fn show(&self) {
|
|
let dlg_helper = use_context::<DialogHelper>().expect("No dialog helper");
|
|
dlg_helper.set_opened(true);
|
|
self.set_visible.update(|state| *state = true);
|
|
}
|
|
|
|
pub fn hide(&self) {
|
|
let dlg_helper = use_context::<DialogHelper>().expect("No dialog helper");
|
|
dlg_helper.set_opened(false);
|
|
self.set_visible.update(|state| *state = false);
|
|
self.set_empty.set("".to_string());
|
|
self.set_not_checked.set(None);
|
|
self.show_err.set(false);
|
|
}
|
|
|
|
pub fn empty(&self) -> String {
|
|
self.empty.get()
|
|
}
|
|
|
|
pub fn not_checked(&self) -> Option<String> {
|
|
self.not_checked.get()
|
|
}
|
|
|
|
pub fn show_err(&self) -> bool {
|
|
self.show_err.get()
|
|
}
|
|
|
|
pub fn display_err(&self) {
|
|
self.show_err.set(true);
|
|
}
|
|
}
|
|
|
|
#[component]
|
|
pub fn ModalDialog(
|
|
opener: DialogOpener,
|
|
title: &'static str,
|
|
#[prop(optional)]
|
|
validator: Option<Validator>,
|
|
children: Children,
|
|
) -> impl IntoView {
|
|
view! {
|
|
<div class={ move || if opener.visible() {"modal fade show"} else {"modal fade"}}
|
|
style={ move || if opener.visible() {"display: block;"} else {""}}
|
|
id="modalCenter" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="modalCenterTitle">{trl(title)}</h5>
|
|
<button
|
|
type="button"
|
|
class="btn-close"
|
|
data-bs-dismiss="modal"
|
|
aria-label="Close"
|
|
on:click=move |_| {
|
|
if let Some(v) = validator {
|
|
v.reset();
|
|
}
|
|
opener.hide();
|
|
}/>
|
|
</div>
|
|
{children()}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
}
|
|
|
|
#[component]
|
|
pub fn ModalBody(children: Children) -> impl IntoView {
|
|
view! {
|
|
<div class="modal-body">
|
|
{children()}
|
|
</div>
|
|
}
|
|
}
|
|
|
|
#[component]
|
|
pub fn ModalFooter(children: Children) -> impl IntoView {
|
|
view! {
|
|
<div class="modal-footer">
|
|
{children()}
|
|
</div>
|
|
}
|
|
}
|
|
|
|
#[component]
|
|
pub fn DlgNotLoaded(opener: DialogOpener, title: &'static str) -> impl IntoView {
|
|
view! {
|
|
<ModalDialog opener=opener title=title>
|
|
<ModalBody>
|
|
<div>{trl("Entity not loaded")}</div>
|
|
</ModalBody>
|
|
<ModalFooter>
|
|
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal" on:click=move |_| opener.hide()>
|
|
{trl("Close")}
|
|
</button>
|
|
</ModalFooter>
|
|
</ModalDialog>
|
|
}
|
|
}
|