Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added snapshot_list and single view UI #249

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions crates/frontend/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use leptos::ServerFnError;
use crate::{
types::{
Config, DefaultConfig, Dimension, ExperimentResponse, ExperimentsResponse,
FetchTypeTemplateResponse, FunctionResponse, ListFilters,
FetchTypeTemplateResponse, FunctionResponse, ListFilters, SnapshotResponse,
},
utils::{
construct_request_headers, get_host, parse_json_response, request,
Expand Down Expand Up @@ -51,6 +51,24 @@ pub async fn fetch_default_config(
Ok(response)
}

pub async fn fetch_snapshots(tenant: String) -> Result<SnapshotResponse, ServerFnError> {
let client = reqwest::Client::new();
let host = use_host_server();

let url = format!("{host}/config/versions");
let response: SnapshotResponse = client
.get(url)
.header("x-tenant", tenant)
.send()
.await
.map_err(|e| ServerFnError::new(e.to_string()))?
.json()
.await
.map_err(|e| ServerFnError::new(e.to_string()))?;

Ok(response)
}

pub async fn delete_context(
tenant: String,
context_id: String,
Expand Down Expand Up @@ -160,11 +178,17 @@ pub async fn fetch_function(
}

// #[server(GetConfig, "/fxn", "GetJson")]
pub async fn fetch_config(tenant: String) -> Result<Config, ServerFnError> {
pub async fn fetch_config(
tenant: String,
version: Option<String>,
) -> Result<Config, ServerFnError> {
let client = reqwest::Client::new();
let host = use_host_server();

let url = format!("{}/config", host);
let url = match version {
Some(version) => format!("{}/config?version={}", host, version),
None => format!("{}/config", host),
};
match client.get(url).header("x-tenant", tenant).send().await {
Ok(response) => {
let config: Config = response
Expand Down
26 changes: 26 additions & 0 deletions crates/frontend/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use crate::pages::experiment_list::ExperimentList;
use crate::pages::function::{
function_create::CreateFunctionView, function_list::FunctionList, FunctionPage,
};
use crate::pages::snapshot::Snapshot;
use crate::pages::snapshot_list::SnapshotList;
use crate::pages::{
context_override::ContextOverride, custom_types::TypesPage,
default_config::DefaultConfig, experiment::ExperimentPage, home::Home,
Expand Down Expand Up @@ -211,6 +213,30 @@ pub fn app(app_envs: Envs) -> impl IntoView {
}
/>

<Route
ssr=SsrMode::Async
path="/admin/:tenant/config_versions"
view=move || {
view! {
<Layout>
<SnapshotList/>
</Layout>
}
}
/>

<Route
ssr=SsrMode::Async
path="/admin/:tenant/config/version/:version"
view=move || {
view! {
<Layout>
<Snapshot/>
</Layout>
}
}
/>

// <Route
// path="/*any"
// view=move || {
Expand Down
15 changes: 5 additions & 10 deletions crates/frontend/src/components/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,17 @@ pub fn button<F: Fn(MouseEvent) + 'static>(
button_class = button_class + "hover:cursor-not-allowed";
}
view! {
<button
class=button_class
id=id
on:click=on_click
disabled=loading
>
<button class=button_class id=id on:click=on_click disabled=loading>
{if loading {
view! { <><span class="loading loading-dots loading-sm"></span></> }
} else {
view! {
<>
{text}
<i class="ri-edit-2-line ml-2"></i>
<span class="loading loading-dots loading-sm"></span>
</>
}
} else {
view! { <>{text} <i class="ri-edit-2-line ml-2"></i></> }
}}

</button>
}
}
108 changes: 58 additions & 50 deletions crates/frontend/src/components/condition_pills.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,32 +59,39 @@ pub fn condition_expression(
} else {
("condition-item-collapsed", "condition-value-collapsed")
};

// Destructure the condition
let Condition { left_operand: dimension, operator, right_operand: value } = condition.get_value();

// Filter and convert values to strings for rendering
let filtered_vals: Vec<String> = value.into_iter().filter_map(|v|
if v.is_object() && v.get("var").is_some() {
None
} else {
match v {
Value::String(s) => Some(s.to_string()),
Value::Number(n) => Some(n.to_string()),
Value::Bool(b) => Some(b.to_string()),
Value::Array(arr) => {
Some(arr.iter().map(|v| v.to_string()).collect::<Vec<String>>().join(","))
}
Value::Object(o) => {
serde_json::to_string_pretty(&o).ok()
let Condition { left_operand: dimension, operator, right_operand: value } = condition
.get_value();
let filtered_vals: Vec<String> = value
.into_iter()
.filter_map(|v| {
if v.is_object() && v.get("var").is_some() {
None
} else {
match v {
Value::String(s) => Some(s.to_string()),
Value::Number(n) => Some(n.to_string()),
Value::Bool(b) => Some(b.to_string()),
Value::Array(arr) => {
Some(
arr
.iter()
.map(|v| v.to_string())
.collect::<Vec<String>>()
.join(","),
)
}
Value::Object(o) => serde_json::to_string_pretty(&o).ok(),
_ => None,
}
}
_ => None,
}
}
).collect();

// Render based on the operator type
})
.collect();
view! {
// Destructure the condition

// Filter and convert values to strings for rendering

// Render based on the operator type
<li
id=id.get_value()
class=list_item_class
Expand All @@ -102,37 +109,38 @@ pub fn condition_expression(
{operator.to_string()}
</span>

{
match operator {
ConditionOperator::Between => {
if filtered_vals.len() == 2 {
view! {
<>
<span class="font-mono font-semibold context_condition">
{&filtered_vals[0]}
</span>
<span class="font-mono font-medium text-gray-650 context_condition">
{"and"}
</span>
<span class="font-mono font-semibold context_condition">
{&filtered_vals[1]}
</span>
</>
}.into_view()
} else {
view! { <span class="font-mono text-red-500">"Invalid between values"</span> }.into_view()
{match operator {
ConditionOperator::Between => {
if filtered_vals.len() == 2 {
view! {
<>
<span class="font-mono font-semibold context_condition">
{&filtered_vals[0]}
</span>
<span class="font-mono font-medium text-gray-650 context_condition">
{"and"}
</span>
<span class="font-mono font-semibold context_condition">
{&filtered_vals[1]}
</span>
</>
}
},
_ => {
let rendered_value = filtered_vals.join(", ");
.into_view()
} else {
view! {
<span class=value_class>
{rendered_value}
<span class="font-mono text-red-500">
"Invalid between values"
</span>
}.into_view()
}
.into_view()
}
}
}
_ => {
let rendered_value = filtered_vals.join(", ");
view! { <span class=value_class>{rendered_value}</span> }.into_view()
}
}}

</li>
}
}}
Expand Down
9 changes: 6 additions & 3 deletions crates/frontend/src/components/context_card.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,16 @@ pub fn context_card(
on:click=move |_| {
handle_edit.call((context.get_value(), overrides.get_value()));
}
></i>
>
</i>

<i
class="ri-file-copy-line ri-lg text-blue-500 cursor-pointer"
on:click=move |_| {
handle_clone.call((context.get_value(), overrides.get_value()));
}
></i>
>
</i>

</Show>
<Show when=move || edit_unsupported>
Expand All @@ -91,7 +93,8 @@ pub fn context_card(
let context_id = context_id.get_value();
handle_delete.call(context_id);
}
></i>
>
</i>

</div>
</Show>
Expand Down
23 changes: 12 additions & 11 deletions crates/frontend/src/components/dimension_form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,17 +273,18 @@ where
</Suspense>

<div class="form-control grid w-full justify-start">
{ move || {
let loading = req_inprogess_rs.get();
view! {
<Button
class="pl-[70px] pr-[70px] w-48 h-12".to_string()
text="Submit".to_string()
on_click=on_submit.clone()
loading
/>
}
}}
{move || {
let loading = req_inprogess_rs.get();
view! {
<Button
class="pl-[70px] pr-[70px] w-48 h-12".to_string()
text="Submit".to_string()
on_click=on_submit.clone()
loading
/>
}
}}

</div>

{
Expand Down
28 changes: 13 additions & 15 deletions crates/frontend/src/components/experiment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,36 +162,34 @@ where
for token in contexts.clone() {
let (dimension, values) = (token.left_operand, token.right_operand);
let mut value_views = Vec::new();

for value in values.iter() {
if value.is_object() && value.get("var").is_some() {
continue;
}

let value_str = match value {
Value::String(s) => s.clone(),
Value::Number(n) => n.to_string(),
Value::Bool(b) => b.to_string(),
Value::Null => String::from("null"),
_ => format!("{}", value),
};

value_views.push(
view! {
value_views
.push(
view! {
<div class="stat-value text-base">
{&value_str.replace('"', "")}
</div>
},
);

},
);
}
view.push(view! {
<div class="stat w-3/12">
<div class="stat-title">{dimension}</div>
{value_views}
</div>
});

view.push(
view! {
<div class="stat w-3/12">
<div class="stat-title">{dimension}</div>
{value_views}
</div>
},
);
}
view
}}
Expand Down
26 changes: 14 additions & 12 deletions crates/frontend/src/components/experiment_form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ where
let context = f_context.get();
view! {
<ContextForm
dimensions=dimensions.get_value() // dimensions will now be a Vec<Dimension>
// dimensions will now be a Vec<Dimension>
dimensions=dimensions.get_value()
context=context
handle_change=handle_context_form_change
is_standalone=false
Expand Down Expand Up @@ -181,17 +182,18 @@ where
}}

<div class="flex justify-start mt-8">
{ move || {
let loading = req_inprogess_rs.get();
view! {
<Button
class="pl-[70px] pr-[70px] w-48 h-12".to_string()
text="Submit".to_string()
on_click=on_submit.clone()
loading
/>
}
}}
{move || {
let loading = req_inprogess_rs.get();
view! {
<Button
class="pl-[70px] pr-[70px] w-48 h-12".to_string()
text="Submit".to_string()
on_click=on_submit.clone()
loading
/>
}
}}

</div>
</div>
}
Expand Down
Loading
Loading