mirror of
				https://github.com/nitnelave/lldap.git
				synced 2023-04-12 14:25:13 +00:00 
			
		
		
		
	app: Add a component to delete a user
Also adds a way to hook to the bootstrap modals to show or hide them.
This commit is contained in:
		
							parent
							
								
									770cff7e4f
								
							
						
					
					
						commit
						f18d37b6e8
					
				@ -11,6 +11,10 @@
 | 
				
			|||||||
      integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x"
 | 
					      integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x"
 | 
				
			||||||
      crossorigin="anonymous"
 | 
					      crossorigin="anonymous"
 | 
				
			||||||
      as="style" />
 | 
					      as="style" />
 | 
				
			||||||
 | 
					    <script
 | 
				
			||||||
 | 
					      src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js"
 | 
				
			||||||
 | 
					      integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ"
 | 
				
			||||||
 | 
					      crossorigin="anonymous"></script>
 | 
				
			||||||
    <link
 | 
					    <link
 | 
				
			||||||
      rel="stylesheet"
 | 
					      rel="stylesheet"
 | 
				
			||||||
      href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css"
 | 
					      href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css"
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										5
									
								
								app/queries/delete_user.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								app/queries/delete_user.graphql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					mutation DeleteUserQuery($user: String!) {
 | 
				
			||||||
 | 
					  deleteUser(userId: $user) {
 | 
				
			||||||
 | 
					    ok
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										156
									
								
								app/src/components/delete_user.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								app/src/components/delete_user.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,156 @@
 | 
				
			|||||||
 | 
					use crate::infra::{api::HostService, modal::Modal};
 | 
				
			||||||
 | 
					use anyhow::{Error, Result};
 | 
				
			||||||
 | 
					use graphql_client::GraphQLQuery;
 | 
				
			||||||
 | 
					use yew::prelude::*;
 | 
				
			||||||
 | 
					use yew::services::fetch::FetchTask;
 | 
				
			||||||
 | 
					use yewtil::NeqAssign;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(GraphQLQuery)]
 | 
				
			||||||
 | 
					#[graphql(
 | 
				
			||||||
 | 
					    schema_path = "../schema.graphql",
 | 
				
			||||||
 | 
					    query_path = "queries/delete_user.graphql",
 | 
				
			||||||
 | 
					    response_derives = "Debug",
 | 
				
			||||||
 | 
					    custom_scalars_module = "crate::infra::graphql"
 | 
				
			||||||
 | 
					)]
 | 
				
			||||||
 | 
					pub struct DeleteUserQuery;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct DeleteUser {
 | 
				
			||||||
 | 
					    link: ComponentLink<Self>,
 | 
				
			||||||
 | 
					    props: DeleteUserProps,
 | 
				
			||||||
 | 
					    node_ref: NodeRef,
 | 
				
			||||||
 | 
					    modal: Option<Modal>,
 | 
				
			||||||
 | 
					    _task: Option<FetchTask>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(yew::Properties, Clone, PartialEq, Debug)]
 | 
				
			||||||
 | 
					pub struct DeleteUserProps {
 | 
				
			||||||
 | 
					    pub username: String,
 | 
				
			||||||
 | 
					    pub on_user_deleted: Callback<String>,
 | 
				
			||||||
 | 
					    pub on_error: Callback<Error>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub enum Msg {
 | 
				
			||||||
 | 
					    ClickedDeleteUser,
 | 
				
			||||||
 | 
					    ConfirmDeleteUser,
 | 
				
			||||||
 | 
					    DismissModal,
 | 
				
			||||||
 | 
					    DeleteUserResponse(Result<delete_user_query::ResponseData>),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Component for DeleteUser {
 | 
				
			||||||
 | 
					    type Message = Msg;
 | 
				
			||||||
 | 
					    type Properties = DeleteUserProps;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
 | 
				
			||||||
 | 
					        Self {
 | 
				
			||||||
 | 
					            link,
 | 
				
			||||||
 | 
					            props,
 | 
				
			||||||
 | 
					            node_ref: NodeRef::default(),
 | 
				
			||||||
 | 
					            modal: None,
 | 
				
			||||||
 | 
					            _task: None,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn rendered(&mut self, first_render: bool) {
 | 
				
			||||||
 | 
					        if first_render {
 | 
				
			||||||
 | 
					            self.modal = Some(Modal::new(
 | 
				
			||||||
 | 
					                self.node_ref
 | 
				
			||||||
 | 
					                    .cast::<web_sys::Element>()
 | 
				
			||||||
 | 
					                    .expect("Modal node is not an element"),
 | 
				
			||||||
 | 
					            ));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn update(&mut self, msg: Self::Message) -> ShouldRender {
 | 
				
			||||||
 | 
					        match msg {
 | 
				
			||||||
 | 
					            Msg::ClickedDeleteUser => {
 | 
				
			||||||
 | 
					                self.modal.as_ref().expect("modal not initialized").show();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            Msg::ConfirmDeleteUser => {
 | 
				
			||||||
 | 
					                self.update(Msg::DismissModal);
 | 
				
			||||||
 | 
					                self._task = HostService::graphql_query::<DeleteUserQuery>(
 | 
				
			||||||
 | 
					                    delete_user_query::Variables {
 | 
				
			||||||
 | 
					                        user: self.props.username.clone(),
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    self.link.callback(Msg::DeleteUserResponse),
 | 
				
			||||||
 | 
					                    "Error trying to delete user",
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                .map_err(|e| self.props.on_error.emit(e))
 | 
				
			||||||
 | 
					                .ok();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            Msg::DismissModal => {
 | 
				
			||||||
 | 
					                self.modal.as_ref().expect("modal not initialized").hide();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            Msg::DeleteUserResponse(response) => {
 | 
				
			||||||
 | 
					                if let Err(e) = response {
 | 
				
			||||||
 | 
					                    self.props.on_error.emit(e);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    self.props.on_user_deleted.emit(self.props.username.clone());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        true
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn change(&mut self, props: Self::Properties) -> ShouldRender {
 | 
				
			||||||
 | 
					        self.props.neq_assign(props)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn view(&self) -> Html {
 | 
				
			||||||
 | 
					        html! {
 | 
				
			||||||
 | 
					          <>
 | 
				
			||||||
 | 
					          <button
 | 
				
			||||||
 | 
					            class="btn btn-danger"
 | 
				
			||||||
 | 
					            onclick=self.link.callback(|_| Msg::ClickedDeleteUser)>
 | 
				
			||||||
 | 
					            <i class="bi-x-circle-fill" aria-label="Delete user" />
 | 
				
			||||||
 | 
					          </button>
 | 
				
			||||||
 | 
					          {self.show_modal()}
 | 
				
			||||||
 | 
					          </>
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl DeleteUser {
 | 
				
			||||||
 | 
					    fn show_modal(&self) -> Html {
 | 
				
			||||||
 | 
					        html! {
 | 
				
			||||||
 | 
					          <div
 | 
				
			||||||
 | 
					            class="modal fade"
 | 
				
			||||||
 | 
					            id="exampleModal".to_string() + &self.props.username
 | 
				
			||||||
 | 
					            tabindex="-1"
 | 
				
			||||||
 | 
					            //role="dialog"
 | 
				
			||||||
 | 
					            aria-labelledby="exampleModalLabel"
 | 
				
			||||||
 | 
					            aria-hidden="true"
 | 
				
			||||||
 | 
					            ref=self.node_ref.clone()>
 | 
				
			||||||
 | 
					            <div class="modal-dialog" /*role="document"*/>
 | 
				
			||||||
 | 
					              <div class="modal-content">
 | 
				
			||||||
 | 
					                <div class="modal-header">
 | 
				
			||||||
 | 
					                  <h5 class="modal-title" id="exampleModalLabel">{"Delete user?"}</h5>
 | 
				
			||||||
 | 
					                  <button
 | 
				
			||||||
 | 
					                    type="button"
 | 
				
			||||||
 | 
					                    class="btn-close"
 | 
				
			||||||
 | 
					                    aria-label="Close"
 | 
				
			||||||
 | 
					                    onclick=self.link.callback(|_| Msg::DismissModal) />
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div class="modal-body">
 | 
				
			||||||
 | 
					                <span>
 | 
				
			||||||
 | 
					                  {"Are you sure you want to delete user "}
 | 
				
			||||||
 | 
					                  <b>{&self.props.username}</b>{"?"}
 | 
				
			||||||
 | 
					                </span>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div class="modal-footer">
 | 
				
			||||||
 | 
					                  <button
 | 
				
			||||||
 | 
					                    type="button"
 | 
				
			||||||
 | 
					                    class="btn btn-secondary"
 | 
				
			||||||
 | 
					                    onclick=self.link.callback(|_| Msg::DismissModal)>
 | 
				
			||||||
 | 
					                      {"Cancel"}
 | 
				
			||||||
 | 
					                  </button>
 | 
				
			||||||
 | 
					                  <button
 | 
				
			||||||
 | 
					                    type="button"
 | 
				
			||||||
 | 
					                    onclick=self.link.callback(|_| Msg::ConfirmDeleteUser)
 | 
				
			||||||
 | 
					                    class="btn btn-danger">{"Yes, I'm sure"}</button>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -2,6 +2,7 @@ pub mod add_user_to_group;
 | 
				
			|||||||
pub mod app;
 | 
					pub mod app;
 | 
				
			||||||
pub mod change_password;
 | 
					pub mod change_password;
 | 
				
			||||||
pub mod create_user;
 | 
					pub mod create_user;
 | 
				
			||||||
 | 
					pub mod delete_user;
 | 
				
			||||||
pub mod login;
 | 
					pub mod login;
 | 
				
			||||||
pub mod logout;
 | 
					pub mod logout;
 | 
				
			||||||
pub mod remove_user_from_group;
 | 
					pub mod remove_user_from_group;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,11 @@
 | 
				
			|||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    components::router::{AppRoute, Link},
 | 
					    components::{
 | 
				
			||||||
 | 
					        delete_user::DeleteUser,
 | 
				
			||||||
 | 
					        router::{AppRoute, Link},
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    infra::api::HostService,
 | 
					    infra::api::HostService,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use anyhow::{anyhow, Result};
 | 
					use anyhow::{Error, Result};
 | 
				
			||||||
use graphql_client::GraphQLQuery;
 | 
					use graphql_client::GraphQLQuery;
 | 
				
			||||||
use yew::prelude::*;
 | 
					use yew::prelude::*;
 | 
				
			||||||
use yew::services::{fetch::FetchTask, ConsoleService};
 | 
					use yew::services::{fetch::FetchTask, ConsoleService};
 | 
				
			||||||
@ -22,13 +25,16 @@ type User = list_users_query::ListUsersQueryUsers;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
pub struct UserTable {
 | 
					pub struct UserTable {
 | 
				
			||||||
    link: ComponentLink<Self>,
 | 
					    link: ComponentLink<Self>,
 | 
				
			||||||
    users: Option<Result<Vec<User>>>,
 | 
					    users: Option<Vec<User>>,
 | 
				
			||||||
 | 
					    error: Option<Error>,
 | 
				
			||||||
    // Used to keep the request alive long enough.
 | 
					    // Used to keep the request alive long enough.
 | 
				
			||||||
    _task: Option<FetchTask>,
 | 
					    _task: Option<FetchTask>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub enum Msg {
 | 
					pub enum Msg {
 | 
				
			||||||
    ListUsersResponse(Result<ResponseData>),
 | 
					    ListUsersResponse(Result<ResponseData>),
 | 
				
			||||||
 | 
					    OnUserDeleted(String),
 | 
				
			||||||
 | 
					    OnError(Error),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl UserTable {
 | 
					impl UserTable {
 | 
				
			||||||
@ -55,21 +61,21 @@ impl Component for UserTable {
 | 
				
			|||||||
            link,
 | 
					            link,
 | 
				
			||||||
            _task: None,
 | 
					            _task: None,
 | 
				
			||||||
            users: None,
 | 
					            users: None,
 | 
				
			||||||
 | 
					            error: None,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        table.get_users(None);
 | 
					        table.get_users(None);
 | 
				
			||||||
        table
 | 
					        table
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn update(&mut self, msg: Self::Message) -> ShouldRender {
 | 
					    fn update(&mut self, msg: Self::Message) -> ShouldRender {
 | 
				
			||||||
        match msg {
 | 
					        self.error = None;
 | 
				
			||||||
            Msg::ListUsersResponse(Ok(users)) => {
 | 
					        match self.handle_msg(msg) {
 | 
				
			||||||
                self.users = Some(Ok(users.users.into_iter().collect()));
 | 
					            Err(e) => {
 | 
				
			||||||
                true
 | 
					                ConsoleService::error(&e.to_string());
 | 
				
			||||||
            }
 | 
					                self.error = Some(e);
 | 
				
			||||||
            Msg::ListUsersResponse(Err(e)) => {
 | 
					 | 
				
			||||||
                self.users = Some(Err(anyhow!("Error listing users: {}", e)));
 | 
					 | 
				
			||||||
                true
 | 
					                true
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            Ok(b) => b,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -78,18 +84,32 @@ impl Component for UserTable {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn view(&self) -> Html {
 | 
					    fn view(&self) -> Html {
 | 
				
			||||||
        let make_user_row = |user: &User| {
 | 
					 | 
				
			||||||
        html! {
 | 
					        html! {
 | 
				
			||||||
                <tr>
 | 
					            <div>
 | 
				
			||||||
                    <td><Link route=AppRoute::UserDetails(user.id.clone())>{&user.id}</Link></td>
 | 
					              {self.view_users()}
 | 
				
			||||||
                    <td>{&user.email}</td>
 | 
					              {self.view_errors()}
 | 
				
			||||||
                    <td>{&user.display_name}</td>
 | 
					            </div>
 | 
				
			||||||
                    <td>{&user.first_name}</td>
 | 
					 | 
				
			||||||
                    <td>{&user.last_name}</td>
 | 
					 | 
				
			||||||
                    <td>{&user.creation_date.with_timezone(&chrono::Local)}</td>
 | 
					 | 
				
			||||||
                </tr>
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        };
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl UserTable {
 | 
				
			||||||
 | 
					    fn handle_msg(&mut self, msg: <Self as Component>::Message) -> Result<bool> {
 | 
				
			||||||
 | 
					        match msg {
 | 
				
			||||||
 | 
					            Msg::ListUsersResponse(users) => {
 | 
				
			||||||
 | 
					                self.users = Some(users?.users.into_iter().collect());
 | 
				
			||||||
 | 
					                Ok(true)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            Msg::OnError(e) => Err(e),
 | 
				
			||||||
 | 
					            Msg::OnUserDeleted(user_id) => {
 | 
				
			||||||
 | 
					                debug_assert!(self.users.is_some());
 | 
				
			||||||
 | 
					                self.users.as_mut().unwrap().retain(|u| u.id != user_id);
 | 
				
			||||||
 | 
					                Ok(true)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn view_users(&self) -> Html {
 | 
				
			||||||
        let make_table = |users: &Vec<User>| {
 | 
					        let make_table = |users: &Vec<User>| {
 | 
				
			||||||
            html! {
 | 
					            html! {
 | 
				
			||||||
                <div class="table-responsive">
 | 
					                <div class="table-responsive">
 | 
				
			||||||
@ -102,10 +122,11 @@ impl Component for UserTable {
 | 
				
			|||||||
                        <th>{"First name"}</th>
 | 
					                        <th>{"First name"}</th>
 | 
				
			||||||
                        <th>{"Last name"}</th>
 | 
					                        <th>{"Last name"}</th>
 | 
				
			||||||
                        <th>{"Creation date"}</th>
 | 
					                        <th>{"Creation date"}</th>
 | 
				
			||||||
 | 
					                        <th>{"Delete"}</th>
 | 
				
			||||||
                      </tr>
 | 
					                      </tr>
 | 
				
			||||||
                    </thead>
 | 
					                    </thead>
 | 
				
			||||||
                    <tbody>
 | 
					                    <tbody>
 | 
				
			||||||
                      {users.iter().map(make_user_row).collect::<Vec<_>>()}
 | 
					                      {users.iter().map(|u| self.view_user(u)).collect::<Vec<_>>()}
 | 
				
			||||||
                    </tbody>
 | 
					                    </tbody>
 | 
				
			||||||
                  </table>
 | 
					                  </table>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
@ -113,8 +134,33 @@ impl Component for UserTable {
 | 
				
			|||||||
        };
 | 
					        };
 | 
				
			||||||
        match &self.users {
 | 
					        match &self.users {
 | 
				
			||||||
            None => html! {{"Loading..."}},
 | 
					            None => html! {{"Loading..."}},
 | 
				
			||||||
            Some(Err(e)) => html! {<div>{"Error: "}{e.to_string()}</div>},
 | 
					            Some(users) => make_table(users),
 | 
				
			||||||
            Some(Ok(users)) => make_table(users),
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn view_user(&self, user: &User) -> Html {
 | 
				
			||||||
 | 
					        html! {
 | 
				
			||||||
 | 
					          <tr key=user.id.clone()>
 | 
				
			||||||
 | 
					              <td><Link route=AppRoute::UserDetails(user.id.clone())>{&user.id}</Link></td>
 | 
				
			||||||
 | 
					              <td>{&user.email}</td>
 | 
				
			||||||
 | 
					              <td>{&user.display_name}</td>
 | 
				
			||||||
 | 
					              <td>{&user.first_name}</td>
 | 
				
			||||||
 | 
					              <td>{&user.last_name}</td>
 | 
				
			||||||
 | 
					              <td>{&user.creation_date.with_timezone(&chrono::Local)}</td>
 | 
				
			||||||
 | 
					              <td>
 | 
				
			||||||
 | 
					                <DeleteUser
 | 
				
			||||||
 | 
					                  username=user.id.clone()
 | 
				
			||||||
 | 
					                  on_user_deleted=self.link.callback(Msg::OnUserDeleted)
 | 
				
			||||||
 | 
					                  on_error=self.link.callback(Msg::OnError)/>
 | 
				
			||||||
 | 
					              </td>
 | 
				
			||||||
 | 
					          </tr>
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn view_errors(&self) -> Html {
 | 
				
			||||||
 | 
					        match &self.error {
 | 
				
			||||||
 | 
					            None => html! {},
 | 
				
			||||||
 | 
					            Some(e) => html! {<div>{"Error: "}{e.to_string()}</div>},
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,4 @@
 | 
				
			|||||||
pub mod api;
 | 
					pub mod api;
 | 
				
			||||||
pub mod cookies;
 | 
					pub mod cookies;
 | 
				
			||||||
pub mod graphql;
 | 
					pub mod graphql;
 | 
				
			||||||
 | 
					pub mod modal;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										16
									
								
								app/src/infra/modal.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								app/src/infra/modal.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					use wasm_bindgen::prelude::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[wasm_bindgen(module = "bootstrap")]
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					    #[wasm_bindgen]
 | 
				
			||||||
 | 
					    pub type Modal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[wasm_bindgen(constructor)]
 | 
				
			||||||
 | 
					    pub fn new(e: web_sys::Element) -> Modal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[wasm_bindgen(method)]
 | 
				
			||||||
 | 
					    pub fn show(this: &Modal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[wasm_bindgen(method)]
 | 
				
			||||||
 | 
					    pub fn hide(this: &Modal);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user