Skip to content
Merged
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
52 changes: 43 additions & 9 deletions crates/webui/src/components/component_detail.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,16 @@ fn component_file_sources(files: &[ComponentFileRef]) -> Vec<SourceView> {
return None;
}
let file = &file_ref.file;
let content = if role == ComponentFileRole::WasmComponent {
SourceContent::Binary
} else {
SourceContent::FetchFile {
digest: file.digest.clone(),
}
};
Some(SourceView {
file_name: file.path.clone(),
content: SourceContent::FetchFile {
digest: file.digest.clone(),
},
content,
metadata: Some(SourceMetadata {
role: component_file_role_label(role),
entrypoint: role == ComponentFileRole::JsEntrypoint,
Expand Down Expand Up @@ -269,6 +274,7 @@ pub fn component_detail(
let wit_state = use_state(|| None);
let wit_loaded = use_state(|| false);
let selected_tab = use_state(|| ComponentDetailTab::Exports);
let show_extensions = use_state(|| false);
let deployment_config = use_state(|| None::<Result<Option<ComponentDeploymentConfig>, String>>);

// Fetch raw WIT only when its tab is selected.
Expand Down Expand Up @@ -390,7 +396,18 @@ pub fn component_detail(
}
});

let exports = map_interfaces_to_fn_details(component.exported_fns(), InterfaceFilter::All);
let has_extensions = component
.exported_fns()
.iter()
.any(|fn_detail| fn_detail.ffqn.ifc_fqn.is_extension());
let exports = map_interfaces_to_fn_details(
component.exported_fns(),
if *show_extensions {
InterfaceFilter::All
} else {
InterfaceFilter::WithoutExtensions
},
);
let render_exported_ifc_with_fns =
|ifc_fqn: &IfcFqnName, fn_details: &[FunctionMetadataLite]| {
let exported_fn_details = fn_details
Expand Down Expand Up @@ -433,15 +450,32 @@ pub fn component_detail(
.iter()
.map(|(ifc_fqn, fn_details)| render_exported_ifc_with_fns(ifc_fqn, fn_details))
.collect::<Vec<_>>();
let exported_functions = if exported_ifcs_fns.is_empty() {
html! {
let on_show_extensions_change = {
let show_extensions = show_extensions.clone();
Callback::from(move |e: Event| {
let input: web_sys::HtmlInputElement = e.target_unchecked_into();
show_extensions.set(input.checked());
})
};
let exported_functions = html! { <>
if has_extensions {
<label class="component-show-extensions">
<input
type="checkbox"
checked={*show_extensions}
onchange={on_show_extensions_change}
/>
{" Show extension functions"}
</label>
}
if exported_ifcs_fns.is_empty() {
<p class="component-empty-state">
{"This component does not export any functions."}
</p>
} else {
{ for exported_ifcs_fns }
}
} else {
html! { <>{ for exported_ifcs_fns }</> }
};
</> };

let dependencies = || {
let connections = component_connections(component, deployment_components);
Expand Down
38 changes: 30 additions & 8 deletions crates/webui/src/components/deployment_config_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ pub enum SourceContent {
Fetch {
file: String,
},
/// A binary file such as a WASM component, listed but not displayable.
Binary,
}

const SOURCE_MARKER: &str = "(source rendered below)";
Expand Down Expand Up @@ -224,7 +226,10 @@ pub fn build_sections_from_manifest(manifest: &Value, files: &[FileRefSer]) -> V
let Some(tables) = manifest.get(toml_key).and_then(Value::as_array) else {
continue;
};
let has_backtrace = matches!(*toml_key, "workflow_wasm" | "webhook_endpoint_wasm");
let has_backtrace = matches!(
*toml_key,
"activity_wasm" | "workflow_wasm" | "webhook_endpoint_wasm"
);
let has_script = matches!(
*toml_key,
"workflow_js" | "activity_js" | "activity_exec" | "webhook_endpoint_js"
Expand Down Expand Up @@ -432,7 +437,9 @@ pub fn collapsible_source(
.as_ref()
.and_then(|result| result.as_ref().as_ref().ok())
.cloned(),
SourceContent::Oci { .. } | SourceContent::ExternalPath { .. } => None,
SourceContent::Oci { .. }
| SourceContent::ExternalPath { .. }
| SourceContent::Binary => None,
}?;
let language = PathBuf::from(&source.file_name)
.extension()
Expand All @@ -444,11 +451,20 @@ pub fn collapsible_source(
},
);

if source.content == SourceContent::Binary {
return html! {
<div class="source-block source-block-binary">
<div class="source-summary">{ source_summary_contents(source) }</div>
</div>
};
}

let body = if !*opened {
html! {}
} else {
let source_available = match &source.content {
SourceContent::Inline(_) => true,
SourceContent::Binary => unreachable!("binary sources return early"),
SourceContent::Oci { image } => {
return html! {
<details {ontoggle} class="source-block">
Expand Down Expand Up @@ -518,16 +534,22 @@ fn source_summary(source: &SourceView) -> Html {
.is_some_and(|metadata| metadata.entrypoint);
html! {
<summary class={classes!(entrypoint.then_some("entrypoint"))}>
<span class="source-file-name">{ &source.file_name }</span>
if let Some(metadata) = &source.metadata {
<span class="source-file-metadata">
<span class="source-file-role">{metadata.role}</span>
</span>
}
{ source_summary_contents(source) }
</summary>
}
}

fn source_summary_contents(source: &SourceView) -> Html {
html! { <>
<span class="source-file-name">{ &source.file_name }</span>
if let Some(metadata) = &source.metadata {
<span class="source-file-metadata">
<span class="source-file-role">{metadata.role}</span>
</span>
}
</> }
}

#[derive(Properties, PartialEq)]
pub struct DeploymentConfigViewProps {
pub sections: Vec<SectionView>,
Expand Down
1 change: 1 addition & 0 deletions crates/webui/src/components/deployment_diff_page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ async fn resolve_source(source: SourceView, component_id: Option<ComponentId>) -
SourceContent::ExternalPath { path } => ResolvedSource::Note(format!(
"Source is read at runtime from the external path `{path}`."
)),
SourceContent::Binary => ResolvedSource::Note("Binary file, not shown.".to_string()),
SourceContent::FetchFile { digest } => rest::deployments::file(&digest)
.await
.map(ResolvedSource::Text)
Expand Down
15 changes: 14 additions & 1 deletion crates/webui/styles/pages/_definitions.scss
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@
border-radius: $border-radius-lg;
background: $color-bg-primary;

> summary {
> summary,
> .source-summary {
display: flex;
align-items: center;
gap: $spacing-sm;
Expand Down Expand Up @@ -130,6 +131,18 @@
}
}

> .source-summary {
cursor: default;

&::before {
visibility: hidden;
}

&:hover {
background: $color-bg-secondary;
}
}

&[open] {
> summary {
border-bottom: 1px solid $color-border-primary;
Expand Down
7 changes: 7 additions & 0 deletions crates/webui/styles/pages/_deployment.scss
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,13 @@

.component-detail-tabs { margin-top: $spacing-sm; }
.component-detail-tab-content { min-height: 0; }

.component-show-extensions {
display: inline-flex;
align-items: center;
gap: $spacing-xs;
margin: $spacing-sm 0;
}
}

.deployment-component-search {
Expand Down
Loading