Some checks failed
Co-authored-by: Sharang Parnerkar <parnerkarsharang@gmail.com> Reviewed-on: #17
82 lines
2.9 KiB
Rust
82 lines
2.9 KiB
Rust
use dioxus::prelude::*;
|
|
|
|
use crate::i18n::{t, Locale};
|
|
|
|
/// Properties for the [`ToolEmbed`] component.
|
|
///
|
|
/// # Fields
|
|
///
|
|
/// * `url` - Service URL; when empty, a "Not Configured" placeholder is shown
|
|
/// * `title` - Display title for the tool (e.g. "Agent Builder")
|
|
/// * `description` - Description text shown in the placeholder card
|
|
/// * `icon` - Single-character icon for the placeholder card
|
|
/// * `launch_label` - Label for the disabled button in the placeholder
|
|
#[derive(Props, Clone, PartialEq)]
|
|
pub struct ToolEmbedProps {
|
|
/// Service URL. Empty string means "not configured".
|
|
pub url: String,
|
|
/// Display title shown in the toolbar / placeholder heading.
|
|
pub title: String,
|
|
/// Description shown in the "not configured" placeholder.
|
|
pub description: String,
|
|
/// Single-character icon for the placeholder card.
|
|
pub icon: &'static str,
|
|
/// Label for the disabled launch button in placeholder mode.
|
|
pub launch_label: String,
|
|
}
|
|
|
|
/// Hybrid iframe / placeholder component for developer tool pages.
|
|
///
|
|
/// When `url` is non-empty, renders a toolbar (title + pop-out button)
|
|
/// above a full-height iframe embedding the service. When `url` is
|
|
/// empty, renders the existing placeholder card with a "Not Configured"
|
|
/// badge instead of "Coming Soon".
|
|
#[component]
|
|
pub fn ToolEmbed(props: ToolEmbedProps) -> Element {
|
|
let locale = use_context::<Signal<Locale>>();
|
|
let l = *locale.read();
|
|
|
|
if props.url.is_empty() {
|
|
// Not configured -- show placeholder card
|
|
rsx! {
|
|
section { class: "placeholder-page",
|
|
div { class: "placeholder-card",
|
|
div { class: "placeholder-icon", "{props.icon}" }
|
|
h2 { "{props.title}" }
|
|
p { class: "placeholder-desc", "{props.description}" }
|
|
button {
|
|
class: "btn-primary",
|
|
disabled: true,
|
|
"{props.launch_label}"
|
|
}
|
|
span { class: "placeholder-badge",
|
|
"{t(l, \"developer.not_configured\")}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// URL is set -- render toolbar + iframe
|
|
let pop_out_url = props.url.clone();
|
|
rsx! {
|
|
div { class: "tool-embed",
|
|
div { class: "tool-embed-toolbar",
|
|
span { class: "tool-embed-title", "{props.title}" }
|
|
a {
|
|
class: "tool-embed-popout-btn",
|
|
href: "{pop_out_url}",
|
|
target: "_blank",
|
|
rel: "noopener noreferrer",
|
|
"{t(l, \"developer.open_new_tab\")}"
|
|
}
|
|
}
|
|
iframe {
|
|
class: "tool-embed-iframe",
|
|
src: "{props.url}",
|
|
title: "{props.title}",
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|