mirror of
https://github.com/nitnelave/lldap.git
synced 2023-04-12 14:25:13 +00:00
app: Add Bootstrap classes.
This commit is contained in:
parent
00efdb42af
commit
a952968e9f
@ -5,7 +5,18 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>LLDAP Administration</title>
|
<title>LLDAP Administration</title>
|
||||||
<script src="/pkg/bundle.js" defer></script>
|
<script src="/pkg/bundle.js" defer></script>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="preload stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous" as="style" />
|
<link
|
||||||
|
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css"
|
||||||
|
rel="preload stylesheet"
|
||||||
|
integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
as="style" />
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css"
|
||||||
|
as="style" />
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
@ -195,8 +195,9 @@ impl Component for AddUserToGroupComponent {
|
|||||||
</Select>
|
</Select>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button onclick=self.link.callback(
|
<button
|
||||||
|_| Msg::SubmitAddGroup)>
|
class="btn btn-success"
|
||||||
|
onclick=self.link.callback(|_| Msg::SubmitAddGroup)>
|
||||||
{"Add"}
|
{"Add"}
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
|
@ -93,7 +93,7 @@ impl Component for App {
|
|||||||
let link = self.link.clone();
|
let link = self.link.clone();
|
||||||
let is_admin = self.is_admin();
|
let is_admin = self.is_admin();
|
||||||
html! {
|
html! {
|
||||||
<div>
|
<div class="container">
|
||||||
<h1>{ "LLDAP" }</h1>
|
<h1>{ "LLDAP" }</h1>
|
||||||
<Router<AppRoute>
|
<Router<AppRoute>
|
||||||
render = Router::render(move |switch: AppRoute| {
|
render = Router::render(move |switch: AppRoute| {
|
||||||
@ -111,7 +111,7 @@ impl Component for App {
|
|||||||
<div>
|
<div>
|
||||||
<LogoutButton on_logged_out=link.callback(|_| Msg::Logout) />
|
<LogoutButton on_logged_out=link.callback(|_| Msg::Logout) />
|
||||||
<UserTable />
|
<UserTable />
|
||||||
<NavButton route=AppRoute::CreateUser>{"Create a user"}</NavButton>
|
<NavButton classes="btn btn-primary" route=AppRoute::CreateUser>{"Create a user"}</NavButton>
|
||||||
</div>
|
</div>
|
||||||
},
|
},
|
||||||
AppRoute::UserDetails(username) => html! {
|
AppRoute::UserDetails(username) => html! {
|
||||||
|
@ -53,9 +53,9 @@ impl CreateUserForm {
|
|||||||
email: get_element("email")
|
email: get_element("email")
|
||||||
.filter(not_empty)
|
.filter(not_empty)
|
||||||
.ok_or_else(|| anyhow!("Missing email"))?,
|
.ok_or_else(|| anyhow!("Missing email"))?,
|
||||||
displayName: get_element("displayname").filter(not_empty),
|
displayName: get_element("display-name").filter(not_empty),
|
||||||
firstName: get_element("firstname").filter(not_empty),
|
firstName: get_element("first-name").filter(not_empty),
|
||||||
lastName: get_element("lastname").filter(not_empty),
|
lastName: get_element("last-name").filter(not_empty),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
self._task = Some(HostService::graphql_query::<CreateUser>(
|
self._task = Some(HostService::graphql_query::<CreateUser>(
|
||||||
@ -175,39 +175,107 @@ impl Component for CreateUserForm {
|
|||||||
|
|
||||||
fn view(&self) -> Html {
|
fn view(&self) -> Html {
|
||||||
html! {
|
html! {
|
||||||
<form ref=self.node_ref.clone() onsubmit=self.link.callback(|e: FocusEvent| { e.prevent_default(); Msg::SubmitForm })>
|
<>
|
||||||
<div>
|
<form
|
||||||
<label for="username">{"User name:"}</label>
|
class="form"
|
||||||
<input type="text" id="username" required=true />
|
ref=self.node_ref.clone()
|
||||||
|
onsubmit=self.link.callback(|e: FocusEvent| { e.prevent_default(); Msg::SubmitForm })>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="username"
|
||||||
|
class="form-label col-sm-2 col-form-label">
|
||||||
|
{"User name*:"}
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="username"
|
||||||
|
class="form-control"
|
||||||
|
autocomplete="username"
|
||||||
|
required=true />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<label for="email">{"Email:"}</label>
|
|
||||||
<input type="email" id="email" required=true />
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="form-group row">
|
||||||
<label for="displayname">{"Display name:"}</label>
|
<label for="email"
|
||||||
<input type="text" id="displayname" />
|
class="form-label col-sm-2 col-form-label">
|
||||||
|
{"Email*:"}
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
id="email"
|
||||||
|
class="form-control"
|
||||||
|
autocomplete="email"
|
||||||
|
required=true />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<label for="firstname">{"First name:"}</label>
|
|
||||||
<input type="text" id="firstname" />
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="form-group row">
|
||||||
<label for="lastname">{"Last name:"}</label>
|
<label for="display-name"
|
||||||
<input type="text" id="lastname" />
|
class="form-label col-sm-2 col-form-label">
|
||||||
|
{"Display name*:"}
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
autocomplete="name"
|
||||||
|
class="form-control"
|
||||||
|
id="display-name" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<label for="password">{"Password:"}</label>
|
|
||||||
<input type="password" id="password" autocomplete="new-password" minlength="8" />
|
|
||||||
</div>
|
</div>
|
||||||
<button type="submit">{"Submit"}</button>
|
<div class="form-group row">
|
||||||
<div>
|
<label for="first-name"
|
||||||
{ if let Some(e) = &self.error {
|
class="form-label col-sm-2 col-form-label">
|
||||||
html! { e.to_string() }
|
{"First name:"}
|
||||||
} else { html! {} }
|
</label>
|
||||||
}
|
<div class="col-sm-10">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
autocomplete="given-name"
|
||||||
|
class="form-control"
|
||||||
|
id="first-name" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="last-name"
|
||||||
|
class="form-label col-sm-2 col-form-label">
|
||||||
|
{"Last name:"}
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
autocomplete="family-name"
|
||||||
|
class="form-control"
|
||||||
|
id="last-name" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="password"
|
||||||
|
class="form-label col-sm-2 col-form-label">
|
||||||
|
{"Password:"}
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
id="password"
|
||||||
|
class="form-control"
|
||||||
|
autocomplete="new-password"
|
||||||
|
minlength="8" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<button
|
||||||
|
class="btn btn-primary col-sm-1 col-form-label"
|
||||||
|
type="submit">{"Submit"}</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
{ if let Some(e) = &self.error {
|
||||||
|
html! {
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
{e.to_string() }
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
} else { html! {} }
|
||||||
|
}
|
||||||
|
</>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,17 +142,45 @@ impl Component for LoginForm {
|
|||||||
|
|
||||||
fn view(&self) -> Html {
|
fn view(&self) -> Html {
|
||||||
html! {
|
html! {
|
||||||
<form ref=self.node_ref.clone() onsubmit=self.link.callback(|e: FocusEvent| { e.prevent_default(); Msg::Submit })>
|
<form
|
||||||
<div>
|
ref=self.node_ref.clone()
|
||||||
<label for="username">{"User name:"}</label>
|
class="form center-block col-sm-4 col-offset-4"
|
||||||
<input type="text" id="username" required=true />
|
onsubmit=self.link.callback(|e: FocusEvent| { e.prevent_default(); Msg::Submit })>
|
||||||
|
<div class="input-group">
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<span class="input-group-text">
|
||||||
|
<i class="bi-person-fill"/>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<input
|
||||||
<label for="password">{"Password:"}</label>
|
type="text"
|
||||||
<input type="password" id="password" required=true autocomplete="current-password" />
|
class="form-control"
|
||||||
|
id="username"
|
||||||
|
placeholder="Username"
|
||||||
|
required=true />
|
||||||
</div>
|
</div>
|
||||||
<button type="submit">{"Login"}</button>
|
<div class="input-group">
|
||||||
<div>
|
<div class="input-group-prepend">
|
||||||
|
<span class="input-group-text">
|
||||||
|
<i class="bi-lock-fill"/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
class="form-control"
|
||||||
|
id="password"
|
||||||
|
required=true
|
||||||
|
placeholder="Email"
|
||||||
|
autocomplete="current-password" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="btn btn-primary">
|
||||||
|
{"Login"}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
{ if let Some(e) = &self.error {
|
{ if let Some(e) = &self.error {
|
||||||
html! { e.to_string() }
|
html! { e.to_string() }
|
||||||
} else { html! {} }
|
} else { html! {} }
|
||||||
|
@ -65,7 +65,11 @@ impl Component for LogoutButton {
|
|||||||
|
|
||||||
fn view(&self) -> Html {
|
fn view(&self) -> Html {
|
||||||
html! {
|
html! {
|
||||||
<button onclick=self.link.callback(|_| Msg::LogoutRequested)>{"Logout"}</button>
|
<button
|
||||||
|
class="btn btn-primary"
|
||||||
|
onclick=self.link.callback(|_| Msg::LogoutRequested)>
|
||||||
|
{"Logout"}
|
||||||
|
</button>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,13 @@ impl Component for RemoveUserFromGroupComponent {
|
|||||||
<>
|
<>
|
||||||
<td>{&group.display_name}</td>
|
<td>{&group.display_name}</td>
|
||||||
{ if self.props.is_admin { html! {
|
{ if self.props.is_admin { html! {
|
||||||
<td><button onclick=self.link.callback(|_| Msg::SubmitRemoveGroup)>{"-"}</button></td>
|
<td>
|
||||||
|
<button
|
||||||
|
class="btn btn-danger"
|
||||||
|
onclick=self.link.callback(|_| Msg::SubmitRemoveGroup)>
|
||||||
|
<i class="bi-x-circle-fill" aria-label="Remove user from group" />
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
}} else { html!{} }
|
}} else { html!{} }
|
||||||
}
|
}
|
||||||
</>
|
</>
|
||||||
|
@ -7,10 +7,10 @@ use yew_router::{
|
|||||||
pub enum AppRoute {
|
pub enum AppRoute {
|
||||||
#[to = "/login"]
|
#[to = "/login"]
|
||||||
Login,
|
Login,
|
||||||
#[to = "/users"]
|
|
||||||
ListUsers,
|
|
||||||
#[to = "/users/create"]
|
#[to = "/users/create"]
|
||||||
CreateUser,
|
CreateUser,
|
||||||
|
#[to = "/users"]
|
||||||
|
ListUsers,
|
||||||
#[to = "/user/{user_id}/password"]
|
#[to = "/user/{user_id}/password"]
|
||||||
ChangePassword(String),
|
ChangePassword(String),
|
||||||
#[to = "/user/{user_id}"]
|
#[to = "/user/{user_id}"]
|
||||||
|
@ -118,18 +118,33 @@ impl UserDetails {
|
|||||||
};
|
};
|
||||||
html! {
|
html! {
|
||||||
<div>
|
<div>
|
||||||
<span>{"Group memberships"}</span>
|
<h3>{"Group memberships"}</h3>
|
||||||
<table>
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
<tr key="headerRow">
|
<tr key="headerRow">
|
||||||
<th>{"Group"}</th>
|
<th>{"Group"}</th>
|
||||||
{ if self.props.is_admin { html!{ <th></th> }} else { html!{} }}
|
{ if self.props.is_admin { html!{ <th></th> }} else { html!{} }}
|
||||||
</tr>
|
</tr>
|
||||||
{u.groups.iter().map(make_group_row).collect::<Vec<_>>()}
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{if u.groups.is_empty() {
|
||||||
|
html! {
|
||||||
|
<tr key="EmptyRow">
|
||||||
|
<td>{"Not member of any group"}</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
html! {<>{u.groups.iter().map(make_group_row).collect::<Vec<_>>()}</>}
|
||||||
|
}}
|
||||||
|
<hr/>
|
||||||
<tr key="groupToAddRow">
|
<tr key="groupToAddRow">
|
||||||
{self.view_add_group_button(u)}
|
{self.view_add_group_button(u)}
|
||||||
</tr>
|
</tr>
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +208,11 @@ impl Component for UserDetails {
|
|||||||
{self.view_messages(error)}
|
{self.view_messages(error)}
|
||||||
{self.view_group_memberships(u)}
|
{self.view_group_memberships(u)}
|
||||||
<div>
|
<div>
|
||||||
<NavButton route=AppRoute::ChangePassword(u.id.clone())>{"Change password"}</NavButton>
|
<NavButton
|
||||||
|
route=AppRoute::ChangePassword(u.id.clone())
|
||||||
|
classes="btn btn-primary">
|
||||||
|
{"Change password"}
|
||||||
|
</NavButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{components::user_details::User, infra::api::HostService};
|
use crate::{components::user_details::User, infra::api::HostService};
|
||||||
use anyhow::{Error, Result};
|
use anyhow::{bail, Error, Result};
|
||||||
use graphql_client::GraphQLQuery;
|
use graphql_client::GraphQLQuery;
|
||||||
use validator_derive::Validate;
|
use validator_derive::Validate;
|
||||||
use yew::{
|
use yew::{
|
||||||
@ -101,45 +101,104 @@ impl Component for UserDetailsForm {
|
|||||||
type Field = yew_form::Field<UserModel>;
|
type Field = yew_form::Field<UserModel>;
|
||||||
html! {
|
html! {
|
||||||
<>
|
<>
|
||||||
<form>
|
<form class="form">
|
||||||
<div class="form-group">
|
<div class="form-group row">
|
||||||
<span>{"User ID: "}</span>
|
<label for="userId"
|
||||||
<span>{&self.props.user.id}</span>
|
class="form-label col-sm-2 col-form-label">
|
||||||
|
{"User ID: "}
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<span id="userId" class="form-constrol-static">{&self.props.user.id}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
</div>
|
||||||
<label for="email">{"Email: "}</label>
|
<div class="form-group row">
|
||||||
<Field form=&self.form field_name="email" oninput=self.link.callback(|_| Msg::Update) />
|
<label for="email"
|
||||||
|
class="form-label col-sm-2 col-form-label">
|
||||||
|
{"Email*: "}
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<Field
|
||||||
|
class="form-control"
|
||||||
|
class_invalid="is-invalid has-error"
|
||||||
|
class_valid="has-success"
|
||||||
|
form=&self.form
|
||||||
|
field_name="email"
|
||||||
|
autocomplete="email"
|
||||||
|
oninput=self.link.callback(|_| Msg::Update) />
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
{&self.form.field_message("email")}
|
{&self.form.field_message("email")}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
</div>
|
||||||
<label for="display_name">{"Display Name: "}</label>
|
<div class="form-group row">
|
||||||
<Field form=&self.form field_name="display_name" oninput=self.link.callback(|_| Msg::Update) />
|
<label for="display_name"
|
||||||
|
class="form-label col-sm-2 col-form-label">
|
||||||
|
{"Display Name*: "}
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<Field
|
||||||
|
class="form-control"
|
||||||
|
class_invalid="is-invalid has-error"
|
||||||
|
class_valid="has-success"
|
||||||
|
form=&self.form
|
||||||
|
field_name="display_name"
|
||||||
|
autocomplete="name"
|
||||||
|
oninput=self.link.callback(|_| Msg::Update) />
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
{&self.form.field_message("display_name")}
|
{&self.form.field_message("display_name")}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
</div>
|
||||||
<label for="first_name">{"First Name: "}</label>
|
<div class="form-group row">
|
||||||
<Field form=&self.form field_name="first_name" oninput=self.link.callback(|_| Msg::Update) />
|
<label for="first_name"
|
||||||
|
class="form-label col-sm-2 col-form-label">
|
||||||
|
{"First Name: "}
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<Field
|
||||||
|
class="form-control"
|
||||||
|
form=&self.form
|
||||||
|
field_name="first_name"
|
||||||
|
autocomplete="given-name"
|
||||||
|
oninput=self.link.callback(|_| Msg::Update) />
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
{&self.form.field_message("first_name")}
|
{&self.form.field_message("first_name")}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
</div>
|
||||||
<label for="last_name">{"Last Name: "}</label>
|
<div class="form-group row">
|
||||||
<Field form=&self.form field_name="last_name" oninput=self.link.callback(|_| Msg::Update) />
|
<label for="last_name"
|
||||||
|
class="form-label col-sm-2 col-form-label">
|
||||||
|
{"Last Name: "}
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<Field
|
||||||
|
class="form-control"
|
||||||
|
form=&self.form
|
||||||
|
field_name="last_name"
|
||||||
|
autocomplete="family-name"
|
||||||
|
oninput=self.link.callback(|_| Msg::Update) />
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
{&self.form.field_message("last_name")}
|
{&self.form.field_message("last_name")}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
|
||||||
<span>{"Creation date: "}</span>
|
|
||||||
<span>{&self.props.user.creation_date.with_timezone(&chrono::Local)}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group row">
|
||||||
<button type="button" onclick=self.link.callback(|e: MouseEvent| {e.prevent_default(); Msg::SubmitClicked})>{"Update"}</button>
|
<label for="creationDate"
|
||||||
|
class="form-label col-sm-2 col-form-label">
|
||||||
|
{"Creation date: "}
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<span id="creationDate" class="form-constrol-static">{&self.props.user.creation_date.with_timezone(&chrono::Local)}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-primary col-sm-1 col-form-label"
|
||||||
|
onclick=self.link.callback(|e: MouseEvent| {e.prevent_default(); Msg::SubmitClicked})>
|
||||||
|
<b>{"Update"}</b>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<div hidden=!self.just_updated>
|
<div hidden=!self.just_updated>
|
||||||
@ -160,6 +219,9 @@ impl UserDetailsForm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn submit_user_update_form(&mut self) -> Result<bool> {
|
fn submit_user_update_form(&mut self) -> Result<bool> {
|
||||||
|
if !self.form.validate() {
|
||||||
|
bail!("Invalid inputs");
|
||||||
|
}
|
||||||
let base_user = &self.props.user;
|
let base_user = &self.props.user;
|
||||||
let mut user_input = update_user::UpdateUserInput {
|
let mut user_input = update_user::UpdateUserInput {
|
||||||
id: self.props.user.id.clone(),
|
id: self.props.user.id.clone(),
|
||||||
|
@ -4,7 +4,6 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use graphql_client::GraphQLQuery;
|
use graphql_client::GraphQLQuery;
|
||||||
use yew::format::Json;
|
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
use yew::services::{fetch::FetchTask, ConsoleService};
|
use yew::services::{fetch::FetchTask, ConsoleService};
|
||||||
|
|
||||||
@ -65,7 +64,6 @@ impl Component for UserTable {
|
|||||||
match msg {
|
match msg {
|
||||||
Msg::ListUsersResponse(Ok(users)) => {
|
Msg::ListUsersResponse(Ok(users)) => {
|
||||||
self.users = Some(Ok(users.users.into_iter().collect()));
|
self.users = Some(Ok(users.users.into_iter().collect()));
|
||||||
ConsoleService::log(format!("Response: {:?}", Json(&self.users)).as_str());
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
Msg::ListUsersResponse(Err(e)) => {
|
Msg::ListUsersResponse(Err(e)) => {
|
||||||
@ -94,7 +92,9 @@ impl Component for UserTable {
|
|||||||
};
|
};
|
||||||
let make_table = |users: &Vec<User>| {
|
let make_table = |users: &Vec<User>| {
|
||||||
html! {
|
html! {
|
||||||
<table>
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{"User ID"}</th>
|
<th>{"User ID"}</th>
|
||||||
<th>{"Email"}</th>
|
<th>{"Email"}</th>
|
||||||
@ -103,8 +103,12 @@ impl Component for UserTable {
|
|||||||
<th>{"Last name"}</th>
|
<th>{"Last name"}</th>
|
||||||
<th>{"Creation date"}</th>
|
<th>{"Creation date"}</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
{users.iter().map(make_user_row).collect::<Vec<_>>()}
|
{users.iter().map(make_user_row).collect::<Vec<_>>()}
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match &self.users {
|
match &self.users {
|
||||||
|
Loading…
Reference in New Issue
Block a user