Skip to content

Commit

Permalink
feat: added snapshot UI
Browse files Browse the repository at this point in the history
  • Loading branch information
sauraww committed Oct 7, 2024
1 parent 260392c commit ffa2b37
Show file tree
Hide file tree
Showing 23 changed files with 733 additions and 345 deletions.
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/snapshots"
view=move || {
view! {
<Layout>
<SnapshotList/>
</Layout>
}
}
/>

<Route
ssr=SsrMode::Async
path="/admin/:tenant/snapshots/: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

0 comments on commit ffa2b37

Please sign in to comment.