Skip to content

Commit

Permalink
feat: Create Experiments From Overrides
Browse files Browse the repository at this point in the history
  • Loading branch information
yuvrajjsingh0 committed Feb 25, 2025
1 parent 416f066 commit b393884
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 12 deletions.
12 changes: 12 additions & 0 deletions crates/frontend/src/components/context_card.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ pub fn context_card(
context: Context,
overrides: Map<String, Value>,
#[prop(default = true)] show_actions: bool,
#[prop(default=Callback::new(|_| {}))] handle_create_experiment: Callback<
(Context, Map<String, Value>),
(),
>,
#[prop(default=Callback::new(|_| {}))] handle_edit: Callback<
(Context, Map<String, Value>),
(),
Expand Down Expand Up @@ -65,6 +69,14 @@ pub fn context_card(
<Show when=move || actions_supported>
<div class="h-fit text-right space-x-4">
<Show when=move || !edit_unsupported>
<i
class="ri-test-tube-line ri-lg text-blue-500 cursor-pointer"
on:click=move |_| {
handle_create_experiment.call((context.get_value(), overrides.get_value()));
}
>
</i>

<i
class="ri-pencil-line ri-lg text-blue-500 cursor-pointer"
on:click=move |_| {
Expand Down
25 changes: 16 additions & 9 deletions crates/frontend/src/components/experiment_form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub mod types;
pub mod utils;

use leptos::*;
use serde_json::Value;
use superposition_types::{
database::models::experimentation::VariantType,
database::{models::cac::DefaultConfig, types::DimensionWithMandatory},
Expand All @@ -20,30 +21,35 @@ use crate::{

use crate::logic::Conditions;

fn default_variants_for_form() -> Vec<(String, VariantFormT)> {
fn default_variants_for_form(
overrides: Vec<(String, Value)>,
) -> Vec<(String, VariantFormT)> {
vec![
(
"control-variant".to_string(),
VariantFormT {
id: "control".to_string(),
variant_type: VariantType::CONTROL,
overrides: vec![],
overrides: overrides.clone(),
},
),
(
"experimental-variant".to_string(),
VariantFormT {
id: "experimental".to_string(),
variant_type: VariantType::EXPERIMENTAL,
overrides: vec![],
overrides: overrides.clone(),
},
),
]
}

fn get_init_state(variants: &VariantFormTs) -> Vec<(String, VariantFormT)> {
fn get_init_state(
variants: &[VariantFormT],
overrides: Vec<(String, Value)>,
) -> Vec<(String, VariantFormT)> {
let init_variants = if variants.is_empty() {
default_variants_for_form()
default_variants_for_form(overrides)
} else {
variants
.iter()
Expand All @@ -61,16 +67,17 @@ pub fn experiment_form<NF>(
name: String,
context: Conditions,
variants: VariantFormTs,
#[prop(default=Vec::new())] overrides: Vec<(String, Value)>,
handle_submit: NF,
default_config: Vec<DefaultConfig>,
dimensions: Vec<DimensionWithMandatory>,
#[prop(default = String::new())] description: String,
#[prop(default = String::new())] change_reason: String,
) -> impl IntoView
where
NF: Fn() + 'static + Clone,
NF: Fn(String) + 'static + Clone,
{
let init_variants = get_init_state(&variants);
let init_variants = get_init_state(&variants, overrides);
let default_config = StoredValue::new(default_config);
let tenant_rws = use_context::<RwSignal<Tenant>>().unwrap();
let org_rws = use_context::<RwSignal<OrganisationId>>().unwrap();
Expand Down Expand Up @@ -140,8 +147,8 @@ where
};

match result {
Ok(_) => {
handle_submit_clone();
Ok(res) => {
handle_submit_clone(res["experiment_id"].as_str().unwrap_or("").to_string());
let success_message = if edit {
"Experiment updated successfully!"
} else {
Expand Down
78 changes: 77 additions & 1 deletion crates/frontend/src/pages/context_override.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use futures::join;
use leptos::*;
use leptos_router::use_navigate;
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use superposition_types::{
Expand All @@ -8,12 +9,12 @@ use superposition_types::{
Config, Context,
};

use crate::components::button::Button;
use crate::components::context_card::ContextCard;
use crate::components::context_form::utils::{create_context, update_context};
use crate::components::context_form::ContextForm;
use crate::components::delete_modal::DeleteModal;
use crate::components::drawer::{close_drawer, open_drawer, Drawer, DrawerBtn};
use crate::components::experiment_form::ExperimentForm;
use crate::components::override_form::OverrideForm;
use crate::components::skeleton::{Skeleton, SkeletonVariant};
use crate::logic::{Condition, Conditions};
Expand All @@ -25,6 +26,7 @@ use crate::{
types::{OrganisationId, Tenant},
};
use crate::{components::alert::AlertType, schema::SchemaType};
use crate::{components::button::Button, types::VariantFormTs};

#[derive(Clone, Debug, Default)]
pub struct Data {
Expand Down Expand Up @@ -277,6 +279,38 @@ pub fn context_override() -> impl IntoView {
}
};
});
let handle_submit_experiment_form = move |experiment_id: String| {
page_resource.refetch();
close_drawer("create_exp_drawer");

let tenant = tenant_rws.get().0;
let org = org_rws.get().0;
let navigate = use_navigate();
let redirect_url = format!("/admin/{org}/{tenant}/experiments/{experiment_id}");
navigate(redirect_url.as_str(), Default::default())
};

let handle_create_experiment =
Callback::new(move |data: (Context, Map<String, Value>)| {
let (context, overrides) = data;

match Conditions::from_context_json(&context.condition.into()) {
Ok(conditions) => {
selected_context_ws.set(Some(Data {
context: conditions,
overrides: overrides
.into_iter()
.collect::<Vec<(String, Value)>>(),
}));

open_drawer("create_exp_drawer");
}
Err(e) => {
logging::error!("Error parsing context: {}", e);
enqueue_alert(e.to_string(), AlertType::Error, 5000);
}
};
});

let on_context_clone = Callback::new(move |data: (Context, Map<String, Value>)| {
let (context, overrides) = data;
Expand Down Expand Up @@ -342,6 +376,47 @@ pub fn context_override() -> impl IntoView {
}>
<div class="space-y-6">

{move || {
let PageResource { config: _, dimensions, default_config } = page_resource
.get()
.unwrap_or_default();
let data = selected_context_rs.get();
view! {
<Drawer
id="create_exp_drawer".to_string()
header="Create Experiment"
handle_close=move || {
close_drawer("create_exp_drawer");
selected_context_ws.set(None);
}
>

<EditorProvider>
{match data {
Some(data) => {
view! {
<ExperimentForm
name="".to_string()
context=data.context
variants=VariantFormTs::default()
overrides=data.overrides
dimensions=dimensions
default_config=default_config
handle_submit=handle_submit_experiment_form
/>
}
.into_view()
}
None => {
view! {}.into_view()
}
}}

</EditorProvider>
</Drawer>
}
}}

{move || {
let PageResource { config: _, dimensions, default_config } = page_resource
.get()
Expand Down Expand Up @@ -450,6 +525,7 @@ pub fn context_override() -> impl IntoView {
<ContextCard
context=context
overrides=overrides
handle_create_experiment=handle_create_experiment
handle_edit=on_context_edit
handle_clone=on_context_clone
handle_delete=on_context_delete
Expand Down
2 changes: 1 addition & 1 deletion crates/frontend/src/pages/experiment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ pub fn experiment_page() -> impl IntoView {
variants=FromIterator::from_iter(experiment_ef.variants)
default_config=default_config
dimensions=dimensions
handle_submit=move || { combined_resource.refetch() }
handle_submit=move |_| { combined_resource.refetch() }
/>
</EditorProvider>

Expand Down
2 changes: 1 addition & 1 deletion crates/frontend/src/pages/experiment_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ pub fn experiment_list() -> impl IntoView {
},
);

let handle_submit_experiment_form = move || {
let handle_submit_experiment_form = move |_| {
combined_resource.refetch();
set_exp_form.update(|val| {
*val += 1;
Expand Down

0 comments on commit b393884

Please sign in to comment.