feat(developer): add hybrid iframe integration for developer tools
All checks were successful
All checks were successful
Replace placeholder pages with ToolEmbed component that embeds LangGraph, LangFlow, and Langfuse in iframes when configured, or shows "Not Configured" placeholders when URLs are empty. Add ServiceUrlsContext for passing service URLs through Dioxus context. Add docker-compose services for local development: LangFlow, LangGraph (trial), Langfuse with full dependency stack (Postgres, ClickHouse, Redis, MinIO). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,27 +1,27 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
use crate::components::ToolEmbed;
|
||||
use crate::i18n::{t, Locale};
|
||||
use crate::models::ServiceUrlsContext;
|
||||
|
||||
/// Agents page placeholder for the LangGraph agent builder.
|
||||
/// Agents page embedding the LangGraph agent builder.
|
||||
///
|
||||
/// Shows a "Coming Soon" card with a disabled launch button.
|
||||
/// Will eventually integrate with the LangGraph framework.
|
||||
/// When `langgraph_url` is configured, embeds the service in an iframe
|
||||
/// with a pop-out button. Otherwise shows a "Not Configured" placeholder.
|
||||
#[component]
|
||||
pub fn AgentsPage() -> Element {
|
||||
let locale = use_context::<Signal<Locale>>();
|
||||
let svc = use_context::<Signal<ServiceUrlsContext>>();
|
||||
let l = *locale.read();
|
||||
let url = svc.read().langgraph_url.clone();
|
||||
|
||||
rsx! {
|
||||
section { class: "placeholder-page",
|
||||
div { class: "placeholder-card",
|
||||
div { class: "placeholder-icon", "A" }
|
||||
h2 { "{t(l, \"developer.agents_title\")}" }
|
||||
p { class: "placeholder-desc",
|
||||
"{t(l, \"developer.agents_desc\")}"
|
||||
}
|
||||
button { class: "btn-primary", disabled: true, "{t(l, \"developer.launch_agents\")}" }
|
||||
span { class: "placeholder-badge", "{t(l, \"common.coming_soon\")}" }
|
||||
}
|
||||
ToolEmbed {
|
||||
url,
|
||||
title: t(l, "developer.agents_title"),
|
||||
description: t(l, "developer.agents_desc"),
|
||||
icon: "A",
|
||||
launch_label: t(l, "developer.launch_agents"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
use crate::components::ToolEmbed;
|
||||
use crate::i18n::{t, Locale};
|
||||
use crate::models::AnalyticsMetric;
|
||||
use crate::models::{AnalyticsMetric, ServiceUrlsContext};
|
||||
|
||||
/// Analytics page placeholder for LangFuse integration.
|
||||
/// Analytics page embedding Langfuse for observability.
|
||||
///
|
||||
/// Shows a "Coming Soon" card with a disabled launch button,
|
||||
/// plus a mock stats bar showing sample metrics.
|
||||
/// Always shows a stats bar with sample metrics. Below that, when
|
||||
/// `langfuse_url` is configured, embeds the service in an iframe
|
||||
/// with a pop-out button. Otherwise shows a "Not Configured" placeholder.
|
||||
#[component]
|
||||
pub fn AnalyticsPage() -> Element {
|
||||
let locale = use_context::<Signal<Locale>>();
|
||||
let svc = use_context::<Signal<ServiceUrlsContext>>();
|
||||
let l = *locale.read();
|
||||
let url = svc.read().langfuse_url.clone();
|
||||
|
||||
let metrics = mock_metrics(l);
|
||||
|
||||
@@ -21,21 +25,24 @@ pub fn AnalyticsPage() -> Element {
|
||||
div { class: "analytics-stat",
|
||||
span { class: "analytics-stat-value", "{metric.value}" }
|
||||
span { class: "analytics-stat-label", "{metric.label}" }
|
||||
span { class: if metric.change_pct >= 0.0 { "analytics-stat-change analytics-stat-change--up" } else { "analytics-stat-change analytics-stat-change--down" },
|
||||
span {
|
||||
class: if metric.change_pct >= 0.0 {
|
||||
"analytics-stat-change analytics-stat-change--up"
|
||||
} else {
|
||||
"analytics-stat-change analytics-stat-change--down"
|
||||
},
|
||||
"{metric.change_pct:+.1}%"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
div { class: "placeholder-card",
|
||||
div { class: "placeholder-icon", "L" }
|
||||
h2 { "{t(l, \"developer.analytics_title\")}" }
|
||||
p { class: "placeholder-desc",
|
||||
"{t(l, \"developer.analytics_desc\")}"
|
||||
}
|
||||
button { class: "btn-primary", disabled: true, "{t(l, \"developer.launch_analytics\")}" }
|
||||
span { class: "placeholder-badge", "{t(l, \"common.coming_soon\")}" }
|
||||
}
|
||||
}
|
||||
ToolEmbed {
|
||||
url,
|
||||
title: t(l, "developer.analytics_title"),
|
||||
description: t(l, "developer.analytics_desc"),
|
||||
icon: "L",
|
||||
launch_label: t(l, "developer.launch_analytics"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
use crate::components::ToolEmbed;
|
||||
use crate::i18n::{t, Locale};
|
||||
use crate::models::ServiceUrlsContext;
|
||||
|
||||
/// Flow page placeholder for the LangFlow visual workflow builder.
|
||||
/// Flow page embedding the LangFlow visual workflow builder.
|
||||
///
|
||||
/// Shows a "Coming Soon" card with a disabled launch button.
|
||||
/// Will eventually integrate with LangFlow for visual flow design.
|
||||
/// When `langflow_url` is configured, embeds the service in an iframe
|
||||
/// with a pop-out button. Otherwise shows a "Not Configured" placeholder.
|
||||
#[component]
|
||||
pub fn FlowPage() -> Element {
|
||||
let locale = use_context::<Signal<Locale>>();
|
||||
let svc = use_context::<Signal<ServiceUrlsContext>>();
|
||||
let l = *locale.read();
|
||||
let url = svc.read().langflow_url.clone();
|
||||
|
||||
rsx! {
|
||||
section { class: "placeholder-page",
|
||||
div { class: "placeholder-card",
|
||||
div { class: "placeholder-icon", "F" }
|
||||
h2 { "{t(l, \"developer.flow_title\")}" }
|
||||
p { class: "placeholder-desc",
|
||||
"{t(l, \"developer.flow_desc\")}"
|
||||
}
|
||||
button { class: "btn-primary", disabled: true, "{t(l, \"developer.launch_flow\")}" }
|
||||
span { class: "placeholder-badge", "{t(l, \"common.coming_soon\")}" }
|
||||
}
|
||||
ToolEmbed {
|
||||
url,
|
||||
title: t(l, "developer.flow_title"),
|
||||
description: t(l, "developer.flow_desc"),
|
||||
icon: "F",
|
||||
launch_label: t(l, "developer.launch_flow"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user