Skip to content

Commit

Permalink
dashboard style changes
Browse files Browse the repository at this point in the history
lyang2821 committed Nov 19, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 1dcc150 commit 7e74bd8
Showing 13 changed files with 362 additions and 376 deletions.
32 changes: 16 additions & 16 deletions lapdev-dashboard/src/account.rs
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ pub fn Login() -> impl IntoView {
view! {
<section class="bg-gray-50">
<div class="flex flex-col items-center justify-center px-6 py-8 mx-auto h-screen lg:py-0">
<a href="#" class="flex items-center mb-6 text-2xl font-semibold text-gray-900 dark:text-white">
<a href="#" class="flex items-center mb-6 text-2xl font-semibold text-gray-900">
<svg class="w-10 h-10 mr-4" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 1024 1024">
<path d="M512 0C390.759 0 279.426 42.2227 191.719 112.656L191.719 612L351.719 612L351.719 332L422 332L431.719 332L431.719 332.344C488.169 334.127 541.249 351.138 581.875 380.625C627.591 413.806 654.875 460.633 654.875 512C654.875 563.367 627.591 610.194 581.875 643.375C541.249 672.862 488.169 689.873 431.719 691.656L431.719 1017.69C457.88 1021.81 484.68 1024 512 1024C794.77 1024 1024 794.77 1024 512C1024 229.23 794.77 0 512 0ZM111.719 192.906C41.8539 280.432 0 391.303 0 512C0 738.766 147.487 930.96 351.719 998.25L351.719 692L151.719 692L151.719 691.844L111.719 691.844L111.719 192.906ZM738.219 372C741.597 372.107 745.042 373.02 748.312 374.812L946.281 483.312C952.311 486.616 956.692 492.393 959.188 499.156C959.821 500.874 960.317 502.641 960.688 504.469C960.764 504.834 960.841 505.196 960.906 505.562C961.12 506.807 961.225 508.071 961.312 509.344C961.378 510.235 961.498 511.112 961.5 512C961.498 512.888 961.378 513.765 961.312 514.656C961.226 515.929 961.12 517.193 960.906 518.438C960.841 518.804 960.764 519.166 960.688 519.531C960.317 521.359 959.821 523.126 959.188 524.844C956.692 531.608 952.311 537.384 946.281 540.688L748.312 649.188C735.232 656.355 719.818 649.367 713.875 633.594C707.932 617.82 713.7 599.23 726.781 592.062L872.875 512L726.781 431.938C713.7 424.771 707.932 406.18 713.875 390.406C718.332 378.576 728.085 371.678 738.219 372ZM431.719 412.344L431.719 611.656C513.56 608.208 574.875 561.985 574.875 512C574.875 462.015 513.56 415.792 431.719 412.344Z" />
<path d="M742 403.688C740.062 403.483 738.097 404.438 737.094 406.25C735.756 408.666 736.615 411.694 739.031 413.031L925.719 516.375C928.135 517.712 931.194 516.822 932.531 514.406C933.869 511.99 932.979 508.962 930.562 507.625L743.875 404.281C743.271 403.947 742.646 403.756 742 403.688Z" />
@@ -87,15 +87,15 @@ pub fn LoginWithView(auth_providers: Vec<AuthProvider>) -> impl IntoView {
class="max-w-96 w-full"
class:hidden=move || login.with(|l| l.is_none())
>
<h1 class="mb-4 text-center text-2xl font-bold leading-tight tracking-tight text-gray-900 dark:text-white">
<h1 class="mb-4 text-center text-2xl font-bold leading-tight tracking-tight text-gray-900">
Sign in to your account
</h1>
<div
class="w-full bg-white rounded-lg shadow dark:border md:mt-0 sm:max-w-md xl:p-0 dark:bg-gray-800 dark:border-gray-700"
class="w-full bg-white rounded-lg shadow md:mt-0 sm:max-w-md xl:p-0"
>
<div class="p-6 flex flex-col space-y-3">
<button type="button"
class="w-full text-gray-900 bg-white hover:bg-gray-100 border border-gray-200 focus:ring-4 focus:outline-none focus:ring-gray-100 font-medium rounded-lg text-sm px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-gray-600 dark:bg-gray-800 dark:border-gray-700 dark:text-white dark:hover:bg-gray-700"
class="w-full text-gray-900 bg-white hover:bg-gray-100 border border-gray-200 focus:ring-4 focus:outline-none focus:ring-gray-100 font-medium rounded-lg text-sm px-5 py-2.5 text-center inline-flex items-center"
class:hidden={ let auth_providers = auth_providers.clone(); move || !auth_providers.contains(&AuthProvider::Github) }
on:click=move |_| { create_action(move |_| {now_login(AuthProvider::Github)}).dispatch(()) }
>
@@ -106,7 +106,7 @@ pub fn LoginWithView(auth_providers: Vec<AuthProvider>) -> impl IntoView {
</button>

<button type="button"
class="w-full text-gray-900 bg-white hover:bg-gray-100 border border-gray-200 focus:ring-4 focus:outline-none focus:ring-gray-100 font-medium rounded-lg text-sm px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-gray-600 dark:bg-gray-800 dark:border-gray-700 dark:text-white dark:hover:bg-gray-700"
class="w-full text-gray-900 bg-white hover:bg-gray-100 border border-gray-200 focus:ring-4 focus:outline-none focus:ring-gray-100 font-medium rounded-lg text-sm px-5 py-2.5 text-center inline-flex items-center"
class:hidden=move || !auth_providers.contains(&AuthProvider::Gitlab)
on:click=move |_| { create_action(move |_| {now_login(AuthProvider::Gitlab)}).dispatch(()) }
>
@@ -137,37 +137,37 @@ pub fn NavUserControl(user_control_hidden: RwSignal<bool>) -> impl IntoView {

view! {
<div
class="absolute z-50 my-2 right-0 w-56 text-base list-none bg-white rounded divide-y divide-gray-100 shadow border dark:bg-gray-700 dark:divide-gray-600 rounded-xl"
class="absolute z-50 my-2 right-0 w-56 text-base list-none bg-white rounded divide-y divide-gray-100 shadow border rounded-xl"
class:hidden=move || user_control_hidden.get()
>
<div class="py-3 px-4">
<span class="block text-sm font-semibold text-gray-900 dark:text-white">
<span class="block text-sm font-semibold text-gray-900">
{ move || login.get().flatten().and_then(|l| l.name).unwrap_or("".to_string()) }
</span>
<span class="block text-sm text-gray-900 truncate dark:text-white">
<span class="block text-sm text-gray-900 truncate">
{ move || login.get().flatten().and_then(|l| l.email).unwrap_or("".to_string()) }
</span>
</div>
<ul
class="py-1 text-gray-700 dark:text-gray-300"
class="py-1 text-gray-700"
aria-labelledby="dropdown"
>
<li>
<a
href="/account"
class="block py-2 px-4 text-sm hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-400 dark:hover:text-white"
class="block py-2 px-4 text-sm hover:bg-gray-100"
>User settings</a
>
</li>
</ul>
<ul
class="py-1 text-gray-700 dark:text-gray-300"
class="py-1 text-gray-700"
aria-labelledby="dropdown"
>
<li>
<a
href="#"
class="block py-2 px-4 text-sm hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"
class="block py-2 px-4 text-sm hover:bg-gray-100"
on:click=logout
>Sign out</a
>
@@ -181,10 +181,10 @@ pub fn NavUserControl(user_control_hidden: RwSignal<bool>) -> impl IntoView {
pub fn AccountSettings() -> impl IntoView {
view! {
<div class="border-b pb-4">
<h5 class="mr-3 text-2xl font-semibold dark:text-white">
<h5 class="mr-3 text-2xl font-semibold">
User Settings
</h5>
<p class="text-gray-700 dark:text-gray-400">{"Manage your account settings"}</p>
<p class="text-gray-700">{"Manage your account settings"}</p>
</div>
}
}
@@ -226,8 +226,8 @@ pub fn JoinView() -> impl IntoView {
{
move || if let Some(error) = result.with(|r| r.as_ref().and_then(|r| r.as_ref().ok().cloned())).flatten() {
view! {
<div class="my-2 p-4 rounded-lg bg-red-50 dark:bg-gray-800 ">
<span class="text-sm font-medium text-red-800 dark:text-red-400">{ error.error }</span>
<div class="my-2 p-4 rounded-lg bg-red-50">
<span class="text-sm font-medium text-red-800">{ error.error }</span>
</div>
}.into_view()
} else {
77 changes: 42 additions & 35 deletions lapdev-dashboard/src/audit_log.rs
Original file line number Diff line number Diff line change
@@ -157,36 +157,36 @@ pub fn AuditLogView() -> impl IntoView {
<Datepicker value=to_date />
<button
type="button"
class="ml-4 px-4 py-2 text-sm font-medium text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800"
class="ml-4 px-4 py-2 text-sm font-medium text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 focus:outline-none"
on:click=move |_| get_action.dispatch(())
>
Search
</button>
</div>
{ move || if let Some(error) = error.get() {
view! {
<div class="my-4 p-4 rounded-lg bg-red-50 dark:bg-gray-800 ">
<span class="text-sm font-medium text-red-800 dark:text-red-400">{ error }</span>
<div class="my-4 p-4 rounded-lg bg-red-50">
<span class="text-sm font-medium text-red-800">{ error }</span>
</div>
}.into_view()
} else {
view!{}.into_view()
}}

<div class="mt-4 flex flex-row items-center justify-between">
<span class="text-sm font-normal text-gray-500 dark:text-gray-400">
<span class="text-sm font-normal text-gray-500">
{"Showing "}
<span class="font-semibold text-gray-900 dark:text-white">
<span class="font-semibold text-gray-900">
{move || format!("{}-{}", audit_logs.with(|a| if a.records.is_empty() {0} else {1} + a.page * a.page_size ), audit_logs.with(|a| if a.records.is_empty() {0} else {a.records.len() as u64} + a.page * a.page_size ))}
</span>
{" of "}
<span class="font-semibold text-gray-900 dark:text-white">{move || audit_logs.with(|a| a.total_items)}</span>
<span class="font-semibold text-gray-900">{move || audit_logs.with(|a| a.total_items)}</span>
</span>
<div class="flex flex-row items-center">
<p class="mr-2">{"rows per page"}</p>

<select
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-18 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
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-18 p-2.5"
on:change=change_page_size
>
<option selected>10</option>
@@ -220,53 +220,60 @@ pub fn AuditLogView() -> impl IntoView {
</div>
</div>

<div class="mt-2 flex items-center w-full px-4 py-2 text-gray-900 dark:text-white bg-gray-50 dark:bg-gray-700">
<span class="w-1/4 truncate">Time</span>
<span class="w-1/4 truncate">User</span>
<span class="w-1/4 truncate">Action</span>
<span class="w-1/4 truncate">Resource</span>
<div class="mt-2 overflow-x-auto w-full">
<table class="w-full text-left text-gray-700 bg-gray-50">
<thead>
<tr>
<th scope="col" class="py-2 px-4">Time</th>
<th scope="col" class="py-2 px-4">User</th>
<th scope="col" class="py-2 px-4">Action</th>
<th scope="col" class="py-2 px-4">Resource</th>
</tr>
</thead>
<tbody>
<For
each=move || audit_logs.get().records.into_iter().enumerate()
key=|(_, a)| a.id
children=move |(i, record)| {
view! {
<RecordItemView i record />
}
}
/>
</tbody>
</table>
</div>

<For
each=move || audit_logs.get().records.into_iter().enumerate()
key=|(_, a)| a.id
children=move |(i, record)| {
view! {
<RecordItemView i record />
}
}
/>
</div>
}
}

#[component]
fn RecordItemView(i: usize, record: AuditLogRecord) -> impl IntoView {
view! {
<div
class="flex items-center w-full px-4 py-2"
<tr
class="w-full bg-white"
class=("border-t", move || i > 0)
>
<div class="w-1/4 flex flex-col">
<td scope="row" class="px-4 py-2">
<DatetimeModal time=record.time />
</div>
<div class="w-1/4 flex flex-col">
<span class="truncate text-gray-900 dark:text-white flex flex-row items-center">
</td>
<td class="px-4 py-2">
<div class="text-gray-900 flex flex-row items-center">
<img
class="w-6 h-6 rounded-full mr-2"
src={ record.avatar.clone() }
alt="user photo"
/>
{record.user.clone()}
</span>
</div>
<div class="w-1/4 flex flex-col">
</div>
</td>
<td class="px-4 py-2">
<p>{record.action}</p>
</div>
<div class="w-1/4 flex flex-col">
</td>
<td class="px-4 py-2">
<p>{record.resource_kind}</p>
<p class="text-gray-500">{record.resource_name}</p>
</div>
</div>
</td>
</tr>
}
}
68 changes: 40 additions & 28 deletions lapdev-dashboard/src/cluster.rs
Original file line number Diff line number Diff line change
@@ -1561,22 +1561,30 @@ pub fn ClusterUsersView() -> impl IntoView {
</div>
</div>

<div class="mt-2 flex items-center w-full px-4 py-2 text-gray-900">
<span class="w-1/4 truncate">Oauth Provider</span>
<span class="w-1/4 truncate">User</span>
<span class="w-1/4 truncate">Created At</span>
<span class="w-1/4 truncate">Cluster Admin</span>
<div class="mt-2 overflow-x-auto w-full">
<table class="w-full text-left text-gray-700 bg-gray-50">
<thead>
<tr>
<th scope="col" class="py-2 px-4">Oauth Provider</th>
<th scope="col" class="py-2 px-4">User</th>
<th scope="col" class="py-2 px-4">Created At</th>
<th scope="col" class="py-2 px-4">Cluster Admin</th>
</tr>
</thead>

<tbody>
<For
each=move || users.get().users.into_iter().enumerate()
key=|(_, u)| (u.id, u.cluster_admin)
children=move |(i, user)| {
view! {
<ClusterUserItemView i user search_action />
}
}
/>
</tbody>
</table>
</div>

<For
each=move || users.get().users.into_iter().enumerate()
key=|(_, u)| (u.id, u.cluster_admin)
children=move |(i, user)| {
view! {
<ClusterUserItemView i user search_action />
}
}
/>
}
}

@@ -1634,15 +1642,17 @@ fn ClusterUserItemView(
},
};
view! {
<div
class="flex items-center w-full px-4 py-2"
<tr
class="w-full bg-white"
class=("border-t", move || i > 0)
>
<div class="w-1/4 flex flex-row items-center">
{icon}
<p>{user.auth_provider.to_string()}</p>
</div>
<div class="w-1/4">
<td scope="row" class="px-4 py-2">
<div class="flex flex-row items-center">
{icon}
<p>{user.auth_provider.to_string()}</p>
</div>
</td>
<td class="px-4 py-2">
<div class="flex flex-row items-center">
<img
class="w-8 h-8 rounded-full mr-2"
@@ -1654,20 +1664,22 @@ fn ClusterUserItemView(
<p>{user.email}</p>
</div>
</div>
</div>
<div class="w-1/4 flex flex-col">
</td>
<td class="px-4 py-2">
<DatetimeModal time=user.created_at />
</div>
<div class="w-1/4 flex flex-row items-center justify-between">
</td>
<td class="px-4 py-2">
<p>{user.cluster_admin}</p>
</td>
<td class="px-4 py-2">
<button
class="px-4 py-2 text-sm font-medium text-white rounded-lg bg-green-700 hover:bg-green-800 focus:ring-4 focus:ring-green-300 focus:outline-none"
on:click=move |_| update_modal_hidden.set(false)
>
Update
</button>
</div>
</div>
</td>
</tr>
<CreationModal title=format!("Update Cluster User") modal_hidden=update_modal_hidden action=update_action body=update_modal_body update_text=None updating_text=None create_button_hidden=false />
}
}
24 changes: 12 additions & 12 deletions lapdev-dashboard/src/git_provider.rs
Original file line number Diff line number Diff line change
@@ -108,18 +108,18 @@ pub fn GitProviderView() -> impl IntoView {
<div class="border-b pb-4">
<div class="flex items-end justify-between">
<div class="min-w-0 mr-4">
<h5 class="mr-3 text-2xl font-semibold dark:text-white">
<h5 class="mr-3 text-2xl font-semibold">
Git Providers
</h5>
<p class="text-gray-700 dark:text-gray-400">{"Connect to a git provider or manage your permissions of a git provider."}</p>
<p class="text-gray-700">{"Connect to a git provider or manage your permissions of a git provider."}</p>
</div>
</div>
</div>

{ move || if let Some(error) = error.get() {
view! {
<div class="w-full mt-8 p-4 rounded-lg bg-red-50 dark:bg-gray-800 ">
<span class="text-sm font-medium text-red-800 dark:text-red-400">{ error }</span>
<div class="w-full mt-8 p-4 rounded-lg bg-red-50">
<span class="text-sm font-medium text-red-800">{ error }</span>
</div>
}.into_view()
} else {
@@ -214,7 +214,7 @@ fn GitProviderControl(
on:focusout=on_focusout
>
<button
class="hover:bg-gray-100 focus:outline-none font-medium rounded-lg text-sm px-2.5 py-2.5 text-center inline-flex items-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
class="hover:bg-gray-100 focus:outline-none font-medium rounded-lg text-sm px-2.5 py-2.5 text-center inline-flex items-center"
type="button"
on:click=toggle_dropdown
>
@@ -226,11 +226,11 @@ fn GitProviderControl(
class="absolute pt-2 z-10 divide-y divide-gray-100 right-0"
class:hidden=move || dropdown_hidden.get()
>
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200 bg-white rounded-lg border shadow w-44 dark:bg-gray-700">
<ul class="py-2 text-sm text-gray-700 bg-white rounded-lg border shadow w-44">
<li>
<a
href="#"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"
class="block px-4 py-2 hover:bg-gray-100"
on:click=connect
// class:hidden=move || workspace_status != WorkspaceStatus::Running && workspace_status != WorkspaceStatus::Stopping
>
@@ -240,7 +240,7 @@ fn GitProviderControl(
<li>
<a
href="#"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"
class="block px-4 py-2 hover:bg-gray-100"
on:click=disconnect
>
Disconnect
@@ -249,7 +249,7 @@ fn GitProviderControl(
<li>
<a
href="#"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 text-red-700"
class="block px-4 py-2 hover:bg-gray-100 text-red-700"
on:click=move |_| {
dropdown_hidden.set(true);
update_scope_modal_hidden.set(false);
@@ -352,7 +352,7 @@ pub fn UpdateScopeModal(
let read_repo = create_rw_signal(read_repo);

let body = view! {
<div class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
<div class="block mb-2 text-sm font-medium text-gray-900">
Turn this option on if you want to open private repo in Lapdev
</div>
<div
@@ -363,12 +363,12 @@ pub fn UpdateScopeModal(
id={format!("read_repo_{provider}")}
type="checkbox"
value=""
class="w-4 h-4 border border-gray-300 rounded bg-gray-50 focus:ring-3 focus:ring-blue-300 dark:bg-gray-700 dark:border-gray-600 dark:focus:ring-blue-600 dark:ring-offset-gray-800"
class="w-4 h-4 border border-gray-300 rounded bg-gray-50 focus:ring-3 focus:ring-blue-300"
prop:checked=move || read_repo.get()
on:change=move |e| read_repo.set(event_target_checked(&e))
/>
</div>
<label for={format!("read_repo_{provider}")} class="ml-2 text-sm font-medium text-gray-900 dark:text-gray-300">Can read private repo</label>
<label for={format!("read_repo_{provider}")} class="ml-2 text-sm font-medium text-gray-900">Can read private repo</label>
</div>
};

10 changes: 5 additions & 5 deletions lapdev-dashboard/src/license.rs
Original file line number Diff line number Diff line change
@@ -26,10 +26,10 @@ pub fn LicenseView() -> impl IntoView {

view! {
<div class="border-b pb-4 mb-8">
<h5 class="mr-3 text-2xl font-semibold dark:text-white">
<h5 class="mr-3 text-2xl font-semibold">
Enterprise License
</h5>
<p class="text-gray-700 dark:text-gray-400">{"Manage your Lapdev Enterprise License for the cluster"}</p>
<p class="text-gray-700">{"Manage your Lapdev Enterprise License for the cluster"}</p>
</div>

<UpdateLicenseView update_counter />
@@ -112,7 +112,7 @@ pub fn UpdateLicenseView(update_counter: RwSignal<i32>) -> impl IntoView {
view! {
<button
type="button"
class="flex items-center justify-center px-4 py-2 text-sm font-medium text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800"
class="flex items-center justify-center px-4 py-2 text-sm font-medium text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 focus:outline-none"
on:click=move |_| modal_hidden.set(false)
>
Update Enterprise License
@@ -191,13 +191,13 @@ pub fn SignLicenseView() -> impl IntoView {
});
view! {
<div class="border-b pb-4 mb-8">
<h5 class="mr-3 text-2xl font-semibold dark:text-white">
<h5 class="mr-3 text-2xl font-semibold">
Sign a new Enterprise License
</h5>
</div>
<button
type="button"
class="flex items-center justify-center px-4 py-2 text-sm font-medium text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800"
class="flex items-center justify-center px-4 py-2 text-sm font-medium text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 focus:outline-none"
on:click=move |_| modal_hidden.set(false)
>
Sign New License
56 changes: 28 additions & 28 deletions lapdev-dashboard/src/modal.rs
Original file line number Diff line number Diff line change
@@ -27,11 +27,11 @@ where
pub fn CreationInput(label: String, value: RwSignal<String>, placeholder: String) -> impl IntoView {
view! {
<div>
<label class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">{ label }</label>
<label class="block mb-2 text-sm font-medium text-gray-900">{ label }</label>
<input
prop:value={move || value.get()}
on:input=move |ev| { value.set(event_target_value(&ev)); }
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"
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"
placeholder={placeholder}
/>
</div>
@@ -76,22 +76,22 @@ where
view! {
<div
tabindex="-1"
class="bg-gray-900/50 dark:bg-gray-900/80 flex overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full h-full"
class="bg-gray-900/50 flex overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full h-full"
class:hidden=move || modal_hidden.get()
on:click=move |_| modal_hidden.set(true)
>
<div
class="relative p-4 w-full max-w-2xl max-h-full"
on:click=move |e| e.stop_propagation()
>
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
<div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t dark:border-gray-600">
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">
<div class="relative bg-white rounded-lg shadow">
<div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t">
<h3 class="text-xl font-semibold text-gray-900">
{ title }
</h3>
<button
type="button"
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white" data-modal-hide="default-modal"
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center" data-modal-hide="default-modal"
on:click=move |_| modal_hidden.set(true)
>
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
@@ -103,8 +103,8 @@ where
{ move || if let Some(error) = error.get() {
view! {
<div class="p-4">
<div class="p-4 rounded-lg bg-red-50 dark:bg-gray-800 ">
<span class="text-sm font-medium text-red-800 dark:text-red-400">{ error }</span>
<div class="p-4 rounded-lg bg-red-50">
<span class="text-sm font-medium text-red-800">{ error }</span>
</div>
</div>
}.into_view()
@@ -115,10 +115,10 @@ where
<div class="p-4 md:p-5 space-y-4">
{body}
</div>
<div class="flex items-center p-4 border-t border-gray-200 rounded-b dark:border-gray-600">
<div class="flex items-center p-4 border-t border-gray-200 rounded-b">
<button
type="button"
class="mr-3 flex flex-row items-center text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
class="mr-3 flex flex-row items-center text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center"
disabled=move || create_pending.get()
class:hidden=move || create_button_hidden
on:click=handle_create
@@ -134,7 +134,7 @@ where
</button>
<button
type="button"
class="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-blue-300 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-500 dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-gray-600"
class="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-blue-300 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10"
disabled=move || create_pending.get()
on:click=move |_| modal_hidden.set(true)
>Cancel</button>
@@ -177,17 +177,17 @@ pub fn DeletionModal(

view! {
<div tabindex="-1"
class="bg-gray-900/50 dark:bg-gray-900/80 flex overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full h-full"
class="bg-gray-900/50 flex overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full h-full"
class:hidden=move || modal_hidden.get()
on:click=move |_| modal_hidden.set(true)
>
<div
class="relative p-4 w-full max-w-md max-h-full"
on:click=move |e| e.stop_propagation()
>
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
<div class="relative bg-white rounded-lg shadow">
<button type="button"
class="absolute top-3 end-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white"
class="absolute top-3 end-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center"
on:click=move |_| modal_hidden.set(true)
>
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
@@ -196,17 +196,17 @@ pub fn DeletionModal(
<span class="sr-only">Close modal</span>
</button>
<div class="p-4 md:p-5 text-center">
<svg class="mx-auto mb-4 text-gray-400 w-12 h-12 dark:text-gray-200" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
<svg class="mx-auto mb-4 text-gray-400 w-12 h-12" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 11V6m0 8h.01M19 10a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>
</svg>
<h3 class="mb-5 text-lg font-normal text-gray-500 dark:text-gray-400 flex flex-col items-center">
<h3 class="mb-5 text-lg font-normal text-gray-500 flex flex-col items-center">
<span>Are you sure you want to delete</span>
<span class="text-semibold">{ resource }</span>
</h3>
{ move || if let Some(error) = error.get() {
view! {
<div class="text-left p-4 mb-4 rounded-lg bg-red-50 dark:bg-gray-800 ">
<span class="text-sm font-medium text-red-800 dark:text-red-400">{ error }</span>
<div class="text-left p-4 mb-4 rounded-lg bg-red-50">
<span class="text-sm font-medium text-red-800">{ error }</span>
</div>
}.into_view()
} else {
@@ -215,7 +215,7 @@ pub fn DeletionModal(
}
<button
type="button"
class="text-white bg-red-600 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 dark:focus:ring-red-800 font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center me-2"
class="text-white bg-red-600 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center me-2"
disabled=move || delete_pending.get()
on:click=handle_delete
>
@@ -230,7 +230,7 @@ pub fn DeletionModal(
</button>
<button
type="button"
class="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-gray-200 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-500 dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-gray-600"
class="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-gray-200 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10"
disabled=move || delete_pending.get()
on:click=move |_| modal_hidden.set(true)
>No, cancel</button>
@@ -290,7 +290,7 @@ pub fn DatetimeModal(time: DateTime<FixedOffset>) -> impl IntoView {
class="absolute bottom-6 -left-3 z-10"
class:hidden=move || hidden.get()
>
<div class="text-nowrap px-3 py-2 text-sm font-medium text-gray-900 dark:text-white bg-white dark:bg-gray-700 border border-gray-200 rounded-lg shadow-sm">
<div class="text-nowrap px-3 py-2 text-sm font-medium text-gray-900 bg-white border border-gray-200 rounded-lg shadow-sm">
{ format!("{}", time.format("%Y-%m-%d %H:%M:%S")) }
</div>
</div>
@@ -340,14 +340,14 @@ where
if title.is_empty() {
view!{}.into_view()
} else {
view!{ <h5 class="text-lg font-semibold dark:text-white">{title}</h5> }.into_view()
view!{ <h5 class="text-lg font-semibold">{title}</h5> }.into_view()
}
}
{ body }
<div class="mt-4 flex flex-row items-center">
<button
type="button"
class="flex flex-row items-center text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
class="flex flex-row items-center text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center"
disabled=move || save_pending.get()
on:click=handle_save
>
@@ -369,8 +369,8 @@ where
}
{ move || if let Some(error) = error.get() {
view! {
<div class="ml-4 py-2 px-4 rounded-lg bg-red-50 dark:bg-gray-800 ">
<span class="text-sm font-medium text-red-800 dark:text-red-400">{ error }</span>
<div class="ml-4 py-2 px-4 rounded-lg bg-red-50">
<span class="text-sm font-medium text-red-800">{ error }</span>
</div>
}.into_view()
} else {
@@ -379,8 +379,8 @@ where
}
{ move || if let Some(success) = success.get() {
view! {
<div class="ml-4 py-2 px-4 rounded-lg bg-green-50 dark:bg-gray-800 ">
<span class="text-sm font-medium text-green-800 dark:text-green-400">{ success }</span>
<div class="ml-4 py-2 px-4 rounded-lg bg-green-50">
<span class="text-sm font-medium text-green-800">{ success }</span>
</div>
}.into_view()
} else {
34 changes: 0 additions & 34 deletions lapdev-dashboard/src/nav.rs
Original file line number Diff line number Diff line change
@@ -60,40 +60,6 @@ pub fn TopNav() -> impl IntoView {
<nav class="bg-white border-b border-gray-200 left-0 right-0 top-0 z-50">
<div class="container mx-auto px-8 py-4 flex flex-wrap justify-between items-center">
<div class="flex justify-start items-center">
<button
data-drawer-target="drawer-navigation"
data-drawer-toggle="drawer-navigation"
aria-controls="drawer-navigation"
class="p-2 mr-2 text-gray-600 rounded-lg cursor-pointer md:hidden hover:text-gray-900 hover:bg-gray-100 focus:bg-gray-100 focus:ring-2 focus:ring-gray-100"
>
<svg
aria-hidden="true"
class="w-6 h-6"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h6a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z"
clip-rule="evenodd"
></path>
</svg>
<svg
aria-hidden="true"
class="hidden w-6 h-6"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
clip-rule="evenodd"
></path>
</svg>
<span class="sr-only">Toggle sidebar</span>
</button>
<a href="/" class="flex items-center justify-between mr-4">
<svg class="w-10 h-10 mr-4" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 1024 1024">
<path d="M512 0C390.759 0 279.426 42.2227 191.719 112.656L191.719 612L351.719 612L351.719 332L422 332L431.719 332L431.719 332.344C488.169 334.127 541.249 351.138 581.875 380.625C627.591 413.806 654.875 460.633 654.875 512C654.875 563.367 627.591 610.194 581.875 643.375C541.249 672.862 488.169 689.873 431.719 691.656L431.719 1017.69C457.88 1021.81 484.68 1024 512 1024C794.77 1024 1024 794.77 1024 512C1024 229.23 794.77 0 512 0ZM111.719 192.906C41.8539 280.432 0 391.303 0 512C0 738.766 147.487 930.96 351.719 998.25L351.719 692L151.719 692L151.719 691.844L111.719 691.844L111.719 192.906ZM738.219 372C741.597 372.107 745.042 373.02 748.312 374.812L946.281 483.312C952.311 486.616 956.692 492.393 959.188 499.156C959.821 500.874 960.317 502.641 960.688 504.469C960.764 504.834 960.841 505.196 960.906 505.562C961.12 506.807 961.225 508.071 961.312 509.344C961.378 510.235 961.498 511.112 961.5 512C961.498 512.888 961.378 513.765 961.312 514.656C961.226 515.929 961.12 517.193 960.906 518.438C960.841 518.804 960.764 519.166 960.688 519.531C960.317 521.359 959.821 523.126 959.188 524.844C956.692 531.608 952.311 537.384 946.281 540.688L748.312 649.188C735.232 656.355 719.818 649.367 713.875 633.594C707.932 617.82 713.7 599.23 726.781 592.062L872.875 512L726.781 431.938C713.7 424.771 707.932 406.18 713.875 390.406C718.332 378.576 728.085 371.678 738.219 372ZM431.719 412.344L431.719 611.656C513.56 608.208 574.875 561.985 574.875 512C574.875 462.015 513.56 415.792 431.719 412.344Z" />
106 changes: 53 additions & 53 deletions lapdev-dashboard/src/organization.rs

Large diffs are not rendered by default.

91 changes: 46 additions & 45 deletions lapdev-dashboard/src/project.rs

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions lapdev-dashboard/src/quota.rs
Original file line number Diff line number Diff line change
@@ -61,13 +61,13 @@ pub fn QuotaView() -> impl IntoView {

view! {
<div class="border-b pb-4 mb-8">
<h5 class="mr-3 text-2xl font-semibold dark:text-white">
<h5 class="mr-3 text-2xl font-semibold">
Organization Quota
</h5>
<p class="text-gray-700 dark:text-gray-400">{"Manage your organization's quota settings"}</p>
<p class="text-gray-700">{"Manage your organization's quota settings"}</p>
</div>

<div class="mt-2 flex items-center w-full px-4 py-2 text-gray-900 dark:text-white bg-gray-50 dark:bg-gray-700">
<div class="mt-2 flex items-center w-full px-4 py-2 text-gray-900 bg-gray-50">
<span class="w-1/4 truncate">Quota Type</span>
<span class="w-1/4 truncate">Quota Value</span>
<div class="w-1/2 flex flex-row">
@@ -210,13 +210,13 @@ fn QuotaItemView(
</div>
<div class="w-2/3 flex flex-row items-center justify-between">
<div class="flex flex-row items-center">
<div class="w-36 bg-gray-200 rounded-full h-1.5 dark:bg-gray-700">
<div class="w-36 bg-gray-200 rounded-full h-1.5">
<div class={format!("{color} h-1.5 rounded-full")} style={format!("width: {}%", percentage.min(100))} > </div>
</div>
<span class="ml-2">{format!("{percentage}%")}</span>
</div>
<button
class="px-4 py-2 text-sm font-medium text-white rounded-lg bg-green-700 hover:bg-green-800 focus:ring-4 focus:ring-green-300 dark:bg-green-600 dark:hover:bg-green-700 focus:outline-none dark:focus:ring-green-800"
class="px-4 py-2 text-sm font-medium text-white rounded-lg bg-green-700 hover:bg-green-800 focus:ring-4 focus:ring-green-300 focus:outline-none"
on:click=move |_| update_modal_hidden.set(false)
>
Update
12 changes: 6 additions & 6 deletions lapdev-dashboard/src/ssh_key.rs
Original file line number Diff line number Diff line change
@@ -44,7 +44,7 @@ pub fn SshKeyItem(key: SshKey, update_counter: RwSignal<i32>) -> impl IntoView {
<span class="w-3/6 truncate p-2">{key.key}</span>
<span class="w-1/6 truncate p-2">{key.created_at.to_rfc2822()}</span>
<div class="w-1/6 flex justify-end items-center">
<button class="px-4 py-2 text-sm text-white rounded-lg bg-red-700 hover:bg-red-800 focus:ring-4 focus:ring-red-300 dark:bg-red-600 dark:hover:bg-red-700 focus:outline-none dark:focus:ring-red-800"
<button class="px-4 py-2 text-sm text-white rounded-lg bg-red-700 hover:bg-red-800 focus:ring-4 focus:ring-red-300 focus:outline-none"
on:click=move |_| delete_modal_hidden.set(false)
>Delete</button>
</div>
@@ -72,10 +72,10 @@ pub fn SshKeys() -> impl IntoView {
<div class="border-b pb-4">
<div class="flex items-end justify-between">
<div class="min-w-0 mr-4">
<h5 class="mr-3 text-2xl font-semibold dark:text-white">
<h5 class="mr-3 text-2xl font-semibold">
SSH Keys
</h5>
<p class="text-gray-700 dark:text-gray-400">{"Manage your SSH keys. Add your SSH public keys to your account will enable you to SSH into all your workspaces."}</p>
<p class="text-gray-700">{"Manage your SSH keys. Add your SSH public keys to your account will enable you to SSH into all your workspaces."}</p>
</div>
<NewSshKey update_counter />
</div>
@@ -139,20 +139,20 @@ pub fn NewSshKey(update_counter: RwSignal<i32>) -> impl IntoView {
let body = view! {
<CreationInput label="Name".to_string() value=name placeholder="".to_string() />
<div>
<label class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">SSH Public Key</label>
<label class="block mb-2 text-sm font-medium text-gray-900">SSH Public Key</label>
<textarea
rows=4
prop:value={move || key.get()}
on:input=move |ev| { key.set(event_target_value(&ev)); }
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"
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"
/>
</div>
};

view! {
<button
type="button"
class="flex items-center justify-center whitespace-nowrap px-4 py-2 text-sm font-medium text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800"
class="flex items-center justify-center whitespace-nowrap px-4 py-2 text-sm font-medium text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 focus:outline-none"
on:click=move |_| modal_hidden.set(false)
>
New SSH Key
79 changes: 43 additions & 36 deletions lapdev-dashboard/src/usage.rs
Original file line number Diff line number Diff line change
@@ -151,10 +151,10 @@ pub fn UsageView() -> impl IntoView {

view! {
<div class="border-b pb-4 mb-8">
<h5 class="mr-3 text-2xl font-semibold dark:text-white">
<h5 class="mr-3 text-2xl font-semibold">
Organization Usage
</h5>
<p class="text-gray-700 dark:text-gray-400">{"View your organization's usage"}</p>
<p class="text-gray-700">{"View your organization's usage"}</p>
</div>

<div class="pb-8">
@@ -164,36 +164,36 @@ pub fn UsageView() -> impl IntoView {
<Datepicker value=to_date />
<button
type="button"
class="ml-4 px-4 py-2 text-sm font-medium text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800"
class="ml-4 px-4 py-2 text-sm font-medium text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 focus:outline-none"
on:click=move |_| get_action.dispatch(())
>
Search
</button>
</div>
{ move || if let Some(error) = error.get() {
view! {
<div class="my-4 p-4 rounded-lg bg-red-50 dark:bg-gray-800 ">
<span class="text-sm font-medium text-red-800 dark:text-red-400">{ error }</span>
<div class="my-4 p-4 rounded-lg bg-red-50">
<span class="text-sm font-medium text-red-800">{ error }</span>
</div>
}.into_view()
} else {
view!{}.into_view()
}}
<div class="mt-4 flex flex-row items-center justify-between">
<span class="text-sm font-normal text-gray-500 dark:text-gray-400">
<span class="text-sm font-normal text-gray-500">
{"Showing "}
<span class="font-semibold text-gray-900 dark:text-white">
<span class="font-semibold text-gray-900">
{move || format!("{}-{}", usage.with(|u| if u.records.is_empty() {0} else {1} + u.page * u.page_size ), usage.with(|u| if u.records.is_empty() {0} else {u.records.len() as u64} + u.page * u.page_size ))}
</span>
{" of "}
<span class="font-semibold text-gray-900 dark:text-white">{move || usage.with(|u| u.total_items)}</span>
<span class="font-semibold text-gray-900">{move || usage.with(|u| u.total_items)}</span>
</span>
<p><span class="text-gray-500 mr-1">{"Total Cost:"}</span>{move || usage.with(|u| format_cost(u.total_cost))}</p>
<div class="flex flex-row items-center">
<p class="mr-2">{"rows per page"}</p>

<select
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-18 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
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-18 p-2.5"
on:change=change_page_size
>
<option selected>10</option>
@@ -227,22 +227,29 @@ pub fn UsageView() -> impl IntoView {
</div>
</div>

<div class="mt-2 flex items-center w-full px-4 py-2 text-gray-900 dark:text-white bg-gray-50 dark:bg-gray-700">
<span class="w-1/4 truncate">Resource Type</span>
<span class="w-1/4 truncate">Resource Name</span>
<span class="w-1/4 truncate">Cost</span>
<span class="w-1/4 truncate">User</span>
<div class="mt-2 overflow-x-auto w-full">
<table class="w-full text-left text-gray-700 bg-gray-50">
<thead>
<tr>
<th scope="col" class="py-2 px-4">Resource Type</th>
<th scope="col" class="py-2 px-4">Resource Name</th>
<th scope="col" class="py-2 px-4">Cost</th>
<th scope="col" class="py-2 px-4">User</th>
</tr>
</thead>
<tbody>
<For
each=move || usage.get().records.into_iter().enumerate()
key=move |(_, r)| (r.id, counter.get_untracked())
children=move |(i, record)| {
view! {
<RecordItemView i record />
}
}
/>
</tbody>
</table>
</div>

<For
each=move || usage.get().records.into_iter().enumerate()
key=move |(_, r)| (r.id, counter.get_untracked())
children=move |(i, record)| {
view! {
<RecordItemView i record />
}
}
/>
</div>
}
}
@@ -270,23 +277,23 @@ fn RecordItemView(i: usize, record: UsageRecord) -> impl IntoView {
);

view! {
<div
class="flex items-center w-full px-4 py-2"
<tr
class="w-full bg-white"
class=("border-t", move || i > 0)
>
<div class="w-1/4 flex flex-col">
<td scope="row" class="px-4 py-2">
<p>{record.resource_kind}</p>
</div>
<div class="w-1/4 flex flex-col">
</td>
<td class="px-4 py-2">
<p>{record.resource_name}</p>
<p><span class="text-gray-500 mr-1">{"Machine Type:"}</span>{record.machine_type}</p>
</div>
<div class="w-1/4 flex flex-col">
</td>
<td class="px-4 py-2">
<p><span class="text-gray-500 mr-1">{"Duration:"}</span>{duration}</p>
<p><span class="text-gray-500 mr-1">{"Cost:"}</span>{ format_cost(record.cost) }</p>
</div>
<div class="w-1/4 flex flex-col">
<span class="mb-2 truncate pr-2 text-gray-900 dark:text-white flex flex-row items-center">
</td>
<td class="px-4 py-2">
<span class="mb-2 pr-2 text-gray-900 flex flex-row items-center">
<img
class="w-6 h-6 rounded-full mr-2"
src={ record.avatar.clone() }
@@ -295,8 +302,8 @@ fn RecordItemView(i: usize, record: UsageRecord) -> impl IntoView {
{record.user.clone()}
</span>
<DatetimeModal time=record.start />
</div>
</div>
</td>
</tr>
}
}

139 changes: 66 additions & 73 deletions lapdev-dashboard/src/workspace.rs

Large diffs are not rendered by default.

0 comments on commit 7e74bd8

Please sign in to comment.